diff options
Diffstat (limited to 'src')
250 files changed, 4535 insertions, 1774 deletions
diff --git a/src/3rdparty/phonon/ds9/videowidget.cpp b/src/3rdparty/phonon/ds9/videowidget.cpp index 091be16..95423c6 100644 --- a/src/3rdparty/phonon/ds9/videowidget.cpp +++ b/src/3rdparty/phonon/ds9/videowidget.cpp @@ -218,6 +218,9 @@ namespace Phonon if (toNative && m_noNativeRendererSupported) return current; //no switch here + if (!mediaObject()) + return current; + //firt we delete the renderer //initialization of the widgets for(int i = 0; i < FILTER_COUNT; ++i) { diff --git a/src/3rdparty/phonon/mmf/environmentalreverb.cpp b/src/3rdparty/phonon/mmf/environmentalreverb.cpp index 89f8d60..d4f5223 100644 --- a/src/3rdparty/phonon/mmf/environmentalreverb.cpp +++ b/src/3rdparty/phonon/mmf/environmentalreverb.cpp @@ -139,57 +139,68 @@ bool EnvironmentalReverb::getParameters(CMdaAudioOutputStream *stream, TInt32 min, max; TUint32 umin, umax; - // DecayHFRatio effect->DecayHFRatioRange(umin, umax); + //: DecayHFRatio: Ratio of high-frequency decay time to the value specified by + //: DecayTime. parameters.append(createParameter( DecayHFRatio, tr("Decay HF ratio (%)"), effect->DecayHFRatio(), umin, umax)); - // DecayTime effect->DecayTimeRange(umin, umax); + //: DecayTime: Time over which reverberation is diminished. parameters.append(createParameter( DecayTime, tr("Decay time (ms)"), effect->DecayTime(), umin, umax)); - // Density + //: Density Delay between first and subsequent reflections. + //: Note that the S60 platform documentation does not make clear + //: the distinction between this value and the Diffusion value. parameters.append(createParameter( Density, tr("Density (%)"), effect->Density(), 0, 100)); - // Diffusion + //: Diffusion: Delay between first and subsequent reflections. + //: Note that the S60 platform documentation does not make clear + //: the distinction between this value and the Density value. parameters.append(createParameter( Diffusion, tr("Diffusion (%)"), effect->Diffusion(), 0, 100)); - // ReflectionsDelay + //: ReflectionsDelay: Amount of delay between the arrival the direct + //: path from the source and the arrival of the first reflection. parameters.append(createParameter( ReflectionsDelay, tr("Reflections delay (ms)"), effect->ReflectionsDelay(), 0, effect->ReflectionsDelayMax())); - // ReflectionsLevel effect->ReflectionLevelRange(min, max); + //: ReflectionsLevel: Amplitude of reflections. This value is + //: corrected by the RoomLevel to give the final reflection amplitude. parameters.append(createParameter( ReflectionsLevel, tr("Reflections level (mB)"), effect->ReflectionsLevel(), min, max, EffectParameter::LogarithmicHint)); - // ReverbDelay + //: ReverbDelay: Amount of time between arrival of the first + //: reflection and start of the late reverberation. parameters.append(createParameter( ReverbDelay, tr("Reverb delay (ms)"), effect->ReverbDelay(), 0, effect->ReverbDelayMax())); - // ReverbLevel effect->ReverbLevelRange(min, max); + //: ReverbLevel Amplitude of reverberations. This value is + //: corrected by the RoomLevel to give the final reverberation + //: amplitude. parameters.append(createParameter( ReverbLevel, tr("Reverb level (mB)"), effect->ReverbLevel(), min, max, EffectParameter::LogarithmicHint)); - // RoomHFLevel effect->RoomHFLevelRange(min, max); + //: RoomHFLevel: Amplitude of low-pass filter used to attenuate the + //: high frequency component of reflected sound. parameters.append(createParameter( RoomHFLevel, tr("Room HF level"), effect->RoomHFLevel(), min, max)); - // RoomLevel effect->RoomLevelRange(min, max); + //: RoomLevel: Master volume control for all reflected sound. parameters.append(createParameter( RoomLevel, tr("Room level (mB)"), effect->RoomLevel(), min, max, EffectParameter::LogarithmicHint)); diff --git a/src/3rdparty/phonon/mmf/utils.h b/src/3rdparty/phonon/mmf/utils.h index 56ccafc..acad55a 100644 --- a/src/3rdparty/phonon/mmf/utils.h +++ b/src/3rdparty/phonon/mmf/utils.h @@ -44,7 +44,7 @@ enum PanicCode { class Utils { - Q_DECLARE_TR_FUNCTIONS(Utils) + Q_DECLARE_TR_FUNCTIONS(Phonon::MMF) public: /** diff --git a/src/3rdparty/s60/eiksoftkeyimage.h b/src/3rdparty/s60/eiksoftkeyimage.h new file mode 100644 index 0000000..a658421 --- /dev/null +++ b/src/3rdparty/s60/eiksoftkeyimage.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef EIKSOFTKEYIMAGE_H +#define EIKSOFTKEYIMAGE_H + +// FORWARD DECLARATIONS +class CEikButtonGroupContainer; + +// CLASS DECLARATION + +/** +* Changes cba button's label to image. +* +* @lib EIKCOCTL +* @since 2.0 +*/ +class EikSoftkeyImage + { + public: + + /** + * Set image to cba button by replacing label + * @since 2.0 + * @param aButtonGroupContainer Button container + * @param aImage Image to button, + * Takes Images ownership + * @param aLeft Boolean: left or right button. + * If true, then change left, + * if false, change right + */ + IMPORT_C static void SetImage(CEikButtonGroupContainer* aButtonGroupContainer, CEikImage& aImage, TBool aLeft); + + /** + * Change to cba button image back to label + * @since 2.0 + * @param aButtonGroupContainer Button container + * @param aLeft Boolean: left or right button. + * If true, then change left, + * if false, change right + */ + IMPORT_C static void SetLabel(CEikButtonGroupContainer* aButtonGroupContainer, TBool aLeft); + + private: + + /** + * C++ default constructor. + */ + EikSoftkeyImage() {}; + + + }; + +#endif // EIKSOFTKEYIMAGE_H + +// End of File + diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index b943840..6446773 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,16 @@ +2010-02-09 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Laszlo Gombos. + + [Qt] use nanval() for Symbian as nonInlineNaN + https://bugs.webkit.org/show_bug.cgi?id=34170 + + numeric_limits<double>::quiet_NaN is broken in Symbian + causing NaN to be evaluated as a number. + + * runtime/JSValue.cpp: + (JSC::nonInlineNaN): + 2010-01-07 Norbert Leser <norbert.leser@nokia.com> Reviewed by NOBODY (OOPS!). diff --git a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp index 699c1cd..bafb85b 100644 --- a/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp +++ b/src/3rdparty/webkit/JavaScriptCore/runtime/JSValue.cpp @@ -174,7 +174,11 @@ uint32_t toUInt32SlowCase(double d, bool& ok) NEVER_INLINE double nonInlineNaN() { +#if PLATFORM(SYMBIAN) + return nanval(); +#else return std::numeric_limits<double>::quiet_NaN(); +#endif } } // namespace JSC diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 6fe71d6..cc0e04f 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 - 8f5ca3ba5da63a47d4f90bbd867d3e8453443dd3 + ffae5e11181a3961193fa21ea405851cad714d4b diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 8e1c965..61c2227 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,147 @@ +2010-01-14 Diego Gonzalez <diego.gonzalez@openbossa.org> + + Reviewed by Kenneth Christiansen. + + [Qt] Missing fileSystemPath() method in Qt KURL implementation + https://bugs.webkit.org/show_bug.cgi?id=33614 + + No new tests. + + * platform/qt/KURLQt.cpp: + (WebCore::KURL::fileSystemPath): + +2010-02-01 Andreas Kling <andreas.kling@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] In the StyledPainter determine the style from the Render and Scrollbar theme instead of from the paint device + https://bugs.webkit.org/show_bug.cgi?id=34054 + + Getting the style from the painter's paint device is a hack that breaks when + the paint device's style is different than the style that is used when + calculating the metries earlier when there is no painter available. + + This change moves us closer to always using the same style. + + * platform/qt/RenderThemeQt.cpp: + (WebCore::StylePainter::StylePainter): + (WebCore::StylePainter::init): + (WebCore::RenderThemeQt::paintButton): + (WebCore::RenderThemeQt::paintTextField): + (WebCore::RenderThemeQt::paintMenuList): + (WebCore::RenderThemeQt::paintMenuListButton): + (WebCore::RenderThemeQt::paintSliderTrack): + (WebCore::RenderThemeQt::paintMediaMuteButton): + (WebCore::RenderThemeQt::paintMediaPlayButton): + (WebCore::RenderThemeQt::paintMediaSliderTrack): + (WebCore::RenderThemeQt::paintMediaSliderThumb): + * platform/qt/RenderThemeQt.h: + * platform/qt/ScrollbarThemeQt.cpp: + (WebCore::ScrollbarThemeQt::paint): + (WebCore::ScrollbarThemeQt::hitTest): + (WebCore::ScrollbarThemeQt::shouldCenterOnThumb): + (WebCore::ScrollbarThemeQt::scrollbarThickness): + (WebCore::ScrollbarThemeQt::thumbLength): + (WebCore::ScrollbarThemeQt::trackPosition): + (WebCore::ScrollbarThemeQt::trackLength): + (WebCore::ScrollbarThemeQt::paintScrollCorner): + (WebCore::ScrollbarThemeQt::style): + * platform/qt/ScrollbarThemeQt.h: + +2010-01-25 Simon Hausmann <hausmann@webkit.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Use the fallback style on Maemo 5 + + https://bugs.webkit.org/show_bug.cgi?id=34376 + + * platform/qt/RenderThemeQt.cpp: + (WebCore::RenderThemeQt::RenderThemeQt): + (WebCore::RenderThemeQt::fallbackStyle): + (WebCore::RenderThemeQt::qStyle): + (WebCore::RenderThemeQt::setPaletteFromPageClientIfExists): + * platform/qt/RenderThemeQt.h: + +2010-01-29 Oswald Buddenhagen <oswald.buddenhagen@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Speed up the WebCore::String -> QString conversion + + Use QString(const QChar *, int len) constructor instead of QString::fromUtf16 to + avoid BOM checks and byteswapping. + + * bridge/qt/qt_class.cpp: + (JSC::Bindings::QtClass::fieldNamed): + * bridge/qt/qt_runtime.cpp: + (JSC::Bindings::convertValueToQVariant): + +2010-01-14 Andreas Kling <andreas.kling@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Enable scrolling optimization for pages with embedded widgets + + https://bugs.webkit.org/show_bug.cgi?id=33373 + + Added a basic manual test for scrolling of embedded QWidgets. + + * manual-tests/qt/qtplugin-scrolling.html: Added. + * platform/ScrollView.cpp: + (WebCore::ScrollView::scrollContents): + (WebCore::ScrollView::setParent): + * platform/ScrollView.h: + * platform/qt/ScrollViewQt.cpp: + (WebCore::ScrollView::platformInit): + (WebCore::ScrollView::platformAddChild): + (WebCore::ScrollView::platformRemoveChild): + * plugins/qt/PluginViewQt.cpp: + (WebCore::PluginView::updatePluginWidget): + (WebCore::PluginView::invalidateRect): + +2010-01-29 Laszlo Gombos <laszlo.1.gombos@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Turn off websocket support by default for Qt 4.6.x + https://bugs.webkit.org/show_bug.cgi?id=34284 + + * WebCore.pro: + +2010-01-26 Holger Hans Peter Freyther <zecke@selfish.org> + + Reviewed by Simon Hausmann. + + [Qt] JavaScript prompt is currently broken. + https://bugs.webkit.org/show_bug.cgi?id=30914 + + Remove the manual test case in favor of an automated + test case in WebKit/qt/tests/qwebpage. + + * manual-tests/qt/java-script-prompt.html: Removed. + +2010-01-25 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Simon Hausmann. + + [Qt] Phone backup support for QtWebkit for Symbian devices. + https://bugs.webkit.org/show_bug.cgi?id=34077 + + * WebCore.pro: + +2010-01-21 Thiago Macieira <thiago.macieira@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix incorrect dependency to QtXmlPatterns in generated include/QtWebKit/QtWebKit header + + The generated file includes QtXmlPatterns/QtXmlPatterns, which is neither used/required by + the public QtWebKit API nor will it be available if Qt is configured with -no-xmlpatterns. + + * WebCore.pro: Trick syncqt to believe that xmlpatterns is not a dependency, so that it's not + included in the generated file. It'll still be used and linked to with this trick. + 2010-01-17 Srinidhi Shreedhara <srinidhi.shreedhara@nokia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index 7f2a17d..c7e5655 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -6,6 +6,7 @@ symbian: { TARGET.EPOCALLOWDLLDATA=1 TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 // Min 128kB, Max 32MB TARGET.CAPABILITY = All -Tcb + TARGET.UID3 = 0x200267C2 webkitlibs.sources = QtWebKit.dll webkitlibs.path = /sys/bin @@ -18,9 +19,11 @@ symbian: { " " webkitlibs.pkg_prerules = vendorinfo - DEPLOYMENT += webkitlibs + webkitbackup.sources = ../WebKit/qt/symbian/backup_registration.xml + webkitbackup.path = /private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,) + + DEPLOYMENT += webkitlibs webkitbackup - TARGET.UID3 = 0x200267C2 # RO text (code) section in qtwebkit.dll exceeds allocated space for gcce udeb target. # Move RW-section base address to start from 0xE00000 instead of the toolchain default 0x400000. QMAKE_LFLAGS.ARMCC += --rw-base 0xE00000 @@ -182,7 +185,7 @@ contains(DEFINES, ENABLE_SINGLE_THREADED=1) { } # Web Socket support. -!contains(DEFINES, ENABLE_WEB_SOCKETS=.): DEFINES += ENABLE_WEB_SOCKETS=1 +!contains(DEFINES, ENABLE_WEB_SOCKETS=.): DEFINES += ENABLE_WEB_SOCKETS=0 # XSLT support with QtXmlPatterns !contains(DEFINES, ENABLE_XSLT=.) { @@ -2779,7 +2782,7 @@ unix:!mac:CONFIG += link_pkgconfig contains(DEFINES, ENABLE_XSLT=1) { FEATURE_DEFINES_JAVASCRIPT += ENABLE_XSLT=1 - QT += xmlpatterns + tobe|!tobe: QT += xmlpatterns SOURCES += \ bindings/js/JSXSLTProcessorConstructor.cpp \ @@ -3414,14 +3417,8 @@ CONFIG(QTDIR_build):isEqual(QT_MAJOR_VERSION, 4):greaterThan(QT_MINOR_VERSION, 4 symbian { shared { - contains(MMP_RULES, defBlock) { - MMP_RULES -= defBlock - - MMP_RULES += "$${LITERAL_HASH}ifdef WINSCW" \ - "DEFFILE ../WebKit/qt/symbian/bwins/$${TARGET}.def" \ - "$${LITERAL_HASH}elif defined EABI" \ - "DEFFILE ../WebKit/qt/symbian/eabi/$${TARGET}.def" \ - "$${LITERAL_HASH}endif" + contains(CONFIG, def_files) { + defFilePath=../WebKit/qt/symbian } } } diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_class.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_class.cpp index c39b3af..09a1544 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_class.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_class.cpp @@ -127,7 +127,7 @@ Field* QtClass::fieldNamed(const Identifier& identifier, Instance* instance) con QObject* obj = qtinst->getObject(); UString ustring = identifier.ustring(); - QString objName(QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size())); + QString objName((const QChar*)ustring.rep()->data(), ustring.size()); QByteArray ba = objName.toAscii(); // First check for a cached field diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp index 6887325..ee7aa1a 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp @@ -305,7 +305,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type return QString(); } else { UString ustring = value.toString(exec); - ret = QVariant(QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size())); + ret = QVariant(QString((const QChar*)ustring.rep()->data(), ustring.size())); if (type == String) dist = 0; else @@ -329,7 +329,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type QVariant v = convertValueToQVariant(exec, val, QMetaType::Void, &objdist, visitedObjects); if (objdist >= 0) { UString ustring = (*it).ustring(); - QString id = QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size()); + QString id = QString((const QChar*)ustring.rep()->data(), ustring.size()); result.insert(id, v); } } @@ -404,7 +404,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type for (int i = 0; i < len; ++i) { JSValue val = rtarray->getConcreteArray()->valueAt(exec, i); UString ustring = val.toString(exec); - QString qstring = QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size()); + QString qstring = QString((const QChar*)ustring.rep()->data(), ustring.size()); result.append(qstring); } @@ -418,7 +418,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type for (int i = 0; i < len; ++i) { JSValue val = array->get(exec, i); UString ustring = val.toString(exec); - QString qstring = QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size()); + QString qstring = QString((const QChar*)ustring.rep()->data(), ustring.size()); result.append(qstring); } @@ -427,7 +427,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type } else { // Make a single length array UString ustring = value.toString(exec); - QString qstring = QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size()); + QString qstring = QString((const QChar*)ustring.rep()->data(), ustring.size()); QStringList result; result.append(qstring); ret = QVariant(result); @@ -443,7 +443,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type dist = 0; } else { UString ustring = value.toString(exec); - ret = QVariant(QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size()).toLatin1()); + ret = QVariant(QString((const QChar*)ustring.rep()->data(), ustring.size()).toLatin1()); if (type == String) dist = 5; else @@ -485,7 +485,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type } } else if (type == String) { UString ustring = value.toString(exec); - QString qstring = QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size()); + QString qstring = QString((const QChar*)ustring.rep()->data(), ustring.size()); if (hint == QMetaType::QDateTime) { QDateTime dt = QDateTime::fromString(qstring, Qt::ISODate); @@ -534,7 +534,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type */ // Attempt to convert.. a bit risky UString ustring = value.toString(exec); - QString qstring = QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size()); + QString qstring = QString((const QChar*)ustring.rep()->data(), ustring.size()); // this is of the form '/xxxxxx/i' int firstSlash = qstring.indexOf(QLatin1Char('/')); @@ -554,7 +554,7 @@ QVariant convertValueToQVariant(ExecState* exec, JSValue value, QMetaType::Type } } else if (type == String) { UString ustring = value.toString(exec); - QString qstring = QString::fromUtf16((const ushort*)ustring.rep()->data(),ustring.size()); + QString qstring = QString((const QChar*)ustring.rep()->data(), ustring.size()); QRegExp re(qstring); if (re.isValid()) { diff --git a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp index 12edc42..d270e37 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.cpp @@ -216,7 +216,6 @@ #include "JSWebKitCSSTransformValue.h" #include "JSWebKitPoint.h" #include "JSWebKitTransitionEvent.h" -#include "JSWebSocket.h" #include "JSWheelEvent.h" #include "JSWorker.h" #include "JSXMLHttpRequest.h" @@ -247,7 +246,7 @@ ASSERT_CLASS_FITS_IN_CELL(JSDOMWindow); /* Hash table */ -static const HashTableValue JSDOMWindowTableValues[297] = +static const HashTableValue JSDOMWindowTableValues[296] = { { "screen", DontDelete|ReadOnly, (intptr_t)jsDOMWindowScreen, (intptr_t)0 }, { "history", DontDelete|ReadOnly, (intptr_t)jsDOMWindowHistory, (intptr_t)0 }, @@ -540,7 +539,6 @@ static const HashTableValue JSDOMWindowTableValues[297] = { "MessageChannel", DontDelete, (intptr_t)jsDOMWindowMessageChannelConstructor, (intptr_t)setJSDOMWindowMessageChannelConstructor }, { "Worker", DontDelete, (intptr_t)jsDOMWindowWorkerConstructor, (intptr_t)setJSDOMWindowWorkerConstructor }, { "SharedWorker", DontDelete, (intptr_t)jsDOMWindowSharedWorkerConstructor, (intptr_t)setJSDOMWindowSharedWorkerConstructor }, - { "WebSocket", DontDelete, (intptr_t)jsDOMWindowWebSocketConstructor, (intptr_t)setJSDOMWindowWebSocketConstructor }, { "Plugin", DontDelete, (intptr_t)jsDOMWindowPluginConstructor, (intptr_t)setJSDOMWindowPluginConstructor }, { "PluginArray", DontDelete, (intptr_t)jsDOMWindowPluginArrayConstructor, (intptr_t)setJSDOMWindowPluginArrayConstructor }, { "MimeType", DontDelete, (intptr_t)jsDOMWindowMimeTypeConstructor, (intptr_t)setJSDOMWindowMimeTypeConstructor }, @@ -588,7 +586,7 @@ static JSC_CONST_HASHTABLE HashTable JSDOMWindowTable = #if ENABLE(PERFECT_HASH_SIZE) { 65535, JSDOMWindowTableValues, 0 }; #else - { 1068, 1023, JSDOMWindowTableValues, 0 }; + { 1067, 1023, JSDOMWindowTableValues, 0 }; #endif /* Hash table for prototype */ @@ -3275,14 +3273,6 @@ JSValue jsDOMWindowSharedWorkerConstructor(ExecState* exec, const Identifier&, c return castedThis->sharedWorker(exec); } -JSValue jsDOMWindowWebSocketConstructor(ExecState* exec, const Identifier&, const PropertySlot& slot) -{ - JSDOMWindow* castedThis = static_cast<JSDOMWindow*>(asObject(slot.slotBase())); - if (!castedThis->allowsAccessFrom(exec)) - return jsUndefined(); - return castedThis->webSocket(exec); -} - JSValue jsDOMWindowPluginConstructor(ExecState* exec, const Identifier&, const PropertySlot& slot) { JSDOMWindow* castedThis = static_cast<JSDOMWindow*>(asObject(slot.slotBase())); @@ -5678,14 +5668,6 @@ void setJSDOMWindowSharedWorkerConstructor(ExecState* exec, JSObject* thisObject static_cast<JSDOMWindow*>(thisObject)->putDirect(Identifier(exec, "SharedWorker"), value); } -void setJSDOMWindowWebSocketConstructor(ExecState* exec, JSObject* thisObject, JSValue value) -{ - if (!static_cast<JSDOMWindow*>(thisObject)->allowsAccessFrom(exec)) - return; - // Shadowing a built-in constructor - static_cast<JSDOMWindow*>(thisObject)->putDirect(Identifier(exec, "WebSocket"), value); -} - void setJSDOMWindowPluginConstructor(ExecState* exec, JSObject* thisObject, JSValue value) { if (!static_cast<JSDOMWindow*>(thisObject)->allowsAccessFrom(exec)) diff --git a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.h b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.h index afc8106..5a087e7 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.h +++ b/src/3rdparty/webkit/WebCore/generated/JSDOMWindow.h @@ -82,7 +82,6 @@ public: JSC::JSValue messageChannel(JSC::ExecState*) const; JSC::JSValue worker(JSC::ExecState*) const; JSC::JSValue sharedWorker(JSC::ExecState*) const; - JSC::JSValue webSocket(JSC::ExecState*) const; JSC::JSValue audio(JSC::ExecState*) const; // Custom functions @@ -679,8 +678,6 @@ JSC::JSValue jsDOMWindowWorkerConstructor(JSC::ExecState*, const JSC::Identifier void setJSDOMWindowWorkerConstructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsDOMWindowSharedWorkerConstructor(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); void setJSDOMWindowSharedWorkerConstructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); -JSC::JSValue jsDOMWindowWebSocketConstructor(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); -void setJSDOMWindowWebSocketConstructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsDOMWindowPluginConstructor(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); void setJSDOMWindowPluginConstructor(JSC::ExecState*, JSC::JSObject*, JSC::JSValue); JSC::JSValue jsDOMWindowPluginArrayConstructor(JSC::ExecState*, const JSC::Identifier&, const JSC::PropertySlot&); diff --git a/src/3rdparty/webkit/WebCore/platform/PopupMenu.h b/src/3rdparty/webkit/WebCore/platform/PopupMenu.h index f2fffb5..c150a94 100644 --- a/src/3rdparty/webkit/WebCore/platform/PopupMenu.h +++ b/src/3rdparty/webkit/WebCore/platform/PopupMenu.h @@ -44,7 +44,9 @@ typedef struct HBITMAP__* HBITMAP; namespace WebCore { class QWebPopup; } +QT_BEGIN_NAMESPACE class QGraphicsProxyWidget; +QT_END_NAMESPACE #elif PLATFORM(GTK) typedef struct _GtkMenu GtkMenu; typedef struct _GtkMenuItem GtkMenuItem; diff --git a/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp b/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp index ee8726a..e67daf9 100644 --- a/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp +++ b/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp @@ -507,7 +507,7 @@ void ScrollView::scrollContents(const IntSize& scrollDelta) hostWindow()->repaint(panScrollIconDirtyRect, true); } - if (canBlitOnScroll() && !rootPreventsBlitting()) { // The main frame can just blit the WebView window + if (canBlitOnScroll()) { // The main frame can just blit the WebView window // FIXME: Find a way to blit subframes without blitting overlapping content hostWindow()->scroll(-scrollDelta, scrollViewRect, clipRect); } else { @@ -597,14 +597,6 @@ void ScrollView::setParent(ScrollView* parentView) if (m_scrollbarsAvoidingResizer && parent()) parent()->adjustScrollbarsAvoidingResizerCount(-m_scrollbarsAvoidingResizer); -#if PLATFORM(QT) - if (m_widgetsPreventingBlitting && parent()) - parent()->adjustWidgetsPreventingBlittingCount(-m_widgetsPreventingBlitting); - - if (m_widgetsPreventingBlitting && parentView) - parentView->adjustWidgetsPreventingBlittingCount(m_widgetsPreventingBlitting); -#endif - Widget::setParent(parentView); if (m_scrollbarsAvoidingResizer && parent()) diff --git a/src/3rdparty/webkit/WebCore/platform/ScrollView.h b/src/3rdparty/webkit/WebCore/platform/ScrollView.h index 1950a54..5dacff5 100644 --- a/src/3rdparty/webkit/WebCore/platform/ScrollView.h +++ b/src/3rdparty/webkit/WebCore/platform/ScrollView.h @@ -305,16 +305,6 @@ private: NSScrollView<WebCoreFrameScrollView>* scrollView() const; #endif -#if PLATFORM(QT) -public: - void adjustWidgetsPreventingBlittingCount(int delta); -private: - bool rootPreventsBlitting() const { return root()->m_widgetsPreventingBlitting > 0; } - unsigned m_widgetsPreventingBlitting; -#else - bool rootPreventsBlitting() const { return false; } -#endif - #if PLATFORM(GTK) public: void setGtkAdjustments(GtkAdjustment* hadj, GtkAdjustment* vadj); diff --git a/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp index 0763fe0..1f62006 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/KURLQt.cpp @@ -95,8 +95,10 @@ KURL::operator QUrl() const String KURL::fileSystemPath() const { - notImplemented(); - return String(); + if (!isValid() || !protocolIs("file")) + return String(); + + return String(path()); } } diff --git a/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp index 989b34c..714cac9 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/PopupMenuQt.cpp @@ -39,6 +39,7 @@ #include <QGraphicsProxyWidget> #include <QGraphicsScene> #include <QGraphicsView> +#include <QGraphicsWebView> #include <QListWidget> #include <QListWidgetItem> #include <QMenu> @@ -57,8 +58,10 @@ PopupMenu::PopupMenu(PopupMenuClient* client) PopupMenu::~PopupMenu() { - delete m_popup; - delete m_proxy; + // If we create a proxy, then the deletion of the proxy and the + // combo will be done by the proxy's parent (QGraphicsWebView) + if (!m_proxy) + delete m_popup; } void PopupMenu::clear() @@ -100,9 +103,8 @@ void PopupMenu::show(const IntRect& r, FrameView* v, int index) if (QGraphicsView* view = qobject_cast<QGraphicsView*>(client->ownerWidget())) { if (!m_proxy) { - m_proxy = new QGraphicsProxyWidget; + m_proxy = new QGraphicsProxyWidget(qobject_cast<QGraphicsWebView*>(client->pluginParent())); m_proxy->setWidget(m_popup); - view->scene()->addItem(m_proxy); } else m_proxy->setVisible(true); m_proxy->setGeometry(rect); diff --git a/src/3rdparty/webkit/WebCore/platform/qt/QWebPopup.cpp b/src/3rdparty/webkit/WebCore/platform/qt/QWebPopup.cpp index f7ebbc7..48bca19 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/QWebPopup.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/QWebPopup.cpp @@ -36,7 +36,9 @@ QWebPopup::QWebPopup(PopupMenuClient* client) { Q_ASSERT(m_client); +#if !defined(Q_WS_S60) && !defined(Q_WS_MAEMO_5) setFont(m_client->menuStyle().font().font()); +#endif connect(this, SIGNAL(activated(int)), SLOT(activeChanged(int)), Qt::QueuedConnection); } @@ -44,9 +46,16 @@ QWebPopup::QWebPopup(PopupMenuClient* client) void QWebPopup::exec() { + // QCursor::pos() is not a great idea for a touch screen, but we don't need the coordinates + // as comboboxes with Qt on Maemo 5 come up in their full width on the screen. + // On the other platforms it's okay to use QCursor::pos(). +#if defined(Q_WS_MAEMO_5) + showPopup(); +#else QMouseEvent event(QEvent::MouseButtonPress, QCursor::pos(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); QCoreApplication::sendEvent(this, &event); +#endif } void QWebPopup::showPopup() diff --git a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp index 501a28b..37a6408 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp @@ -44,6 +44,7 @@ #include "Page.h" #include "RenderBox.h" #include "RenderTheme.h" +#include "ScrollbarThemeQt.h" #include "UserAgentStyleSheets.h" #include "QWebPageClient.h" #include "qwebpage.h" @@ -66,17 +67,17 @@ namespace WebCore { using namespace HTMLNames; -StylePainter::StylePainter(const RenderObject::PaintInfo& paintInfo) +StylePainter::StylePainter(RenderThemeQt* theme, const RenderObject::PaintInfo& paintInfo) { - init(paintInfo.context ? paintInfo.context : 0); + init(paintInfo.context ? paintInfo.context : 0, theme->qStyle()); } -StylePainter::StylePainter(GraphicsContext* context) +StylePainter::StylePainter(ScrollbarThemeQt* theme, GraphicsContext* context) { - init(context); + init(context, theme->style()); } -void StylePainter::init(GraphicsContext* context) +void StylePainter::init(GraphicsContext* context, QStyle* themeStyle) { painter = static_cast<QPainter*>(context->platformContext()); widget = 0; @@ -85,7 +86,7 @@ void StylePainter::init(GraphicsContext* context) dev = painter->device(); if (dev && dev->devType() == QInternal::Widget) widget = static_cast<QWidget*>(dev); - style = (widget ? widget->style() : QApplication::style()); + style = themeStyle; if (painter) { // the styles often assume being called with a pristine painter where no brush is set, @@ -125,7 +126,6 @@ PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page) RenderThemeQt::RenderThemeQt(Page* page) : RenderTheme() , m_page(page) - , m_fallbackStyle(0) { QPushButton button; button.setAttribute(Qt::WA_MacSmallSize); @@ -135,6 +135,8 @@ RenderThemeQt::RenderThemeQt(Page* page) #ifdef Q_WS_MAC m_buttonFontPixelSize = fontInfo.pixelSize(); #endif + + m_fallbackStyle = QStyleFactory::create(QLatin1String("windows")); } RenderThemeQt::~RenderThemeQt() @@ -143,19 +145,17 @@ RenderThemeQt::~RenderThemeQt() } // for some widget painting, we need to fallback to Windows style -QStyle* RenderThemeQt::fallbackStyle() +QStyle* RenderThemeQt::fallbackStyle() const { - if (!m_fallbackStyle) - m_fallbackStyle = QStyleFactory::create(QLatin1String("windows")); - - if (!m_fallbackStyle) - m_fallbackStyle = QApplication::style(); - - return m_fallbackStyle; + return (m_fallbackStyle) ? m_fallbackStyle : QApplication::style(); } QStyle* RenderThemeQt::qStyle() const { +#ifdef Q_WS_MAEMO_5 + return fallbackStyle(); +#endif + if (m_page) { ChromeClientQt* client = static_cast<ChromeClientQt*>(m_page->chrome()->client()); @@ -465,7 +465,7 @@ void RenderThemeQt::setButtonPadding(RenderStyle* style) const bool RenderThemeQt::paintButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { - StylePainter p(i); + StylePainter p(this, i); if (!p.isValid()) return true; @@ -498,7 +498,7 @@ void RenderThemeQt::adjustTextFieldStyle(CSSStyleSelector*, RenderStyle* style, bool RenderThemeQt::paintTextField(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { - StylePainter p(i); + StylePainter p(this, i); if (!p.isValid()) return true; @@ -567,7 +567,7 @@ void RenderThemeQt::setPopupPadding(RenderStyle* style) const bool RenderThemeQt::paintMenuList(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { - StylePainter p(i); + StylePainter p(this, i); if (!p.isValid()) return true; @@ -607,7 +607,7 @@ void RenderThemeQt::adjustMenuListButtonStyle(CSSStyleSelector*, RenderStyle* st bool RenderThemeQt::paintMenuListButton(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { - StylePainter p(i); + StylePainter p(this, i); if (!p.isValid()) return true; @@ -758,6 +758,10 @@ ControlPart RenderThemeQt::applyTheme(QStyleOption& option, RenderObject* o) con if (result == RadioPart || result == CheckboxPart) option.state |= (isChecked(o) ? QStyle::State_On : QStyle::State_Off); +#ifdef Q_WS_MAEMO_5 + static QPalette lightGrayPalette(Qt::lightGray); + option.palette = lightGrayPalette; +#else // If the owner widget has a custom palette, use it Page* page = o->document()->page(); if (page) { @@ -766,6 +770,7 @@ ControlPart RenderThemeQt::applyTheme(QStyleOption& option, RenderObject* o) con if (pageClient) option.palette = pageClient->palette(); } +#endif return result; } @@ -833,7 +838,7 @@ bool RenderThemeQt::paintMediaMuteButton(RenderObject* o, const RenderObject::Pa if (!mediaElement) return false; - StylePainter p(paintInfo); + StylePainter p(this, paintInfo); if (!p.isValid()) return true; @@ -862,7 +867,7 @@ bool RenderThemeQt::paintMediaPlayButton(RenderObject* o, const RenderObject::Pa if (!mediaElement) return false; - StylePainter p(paintInfo); + StylePainter p(this, paintInfo); if (!p.isValid()) return true; @@ -901,7 +906,7 @@ bool RenderThemeQt::paintMediaSliderTrack(RenderObject* o, const RenderObject::P if (!mediaElement) return false; - StylePainter p(paintInfo); + StylePainter p(this, paintInfo); if (!p.isValid()) return true; @@ -928,7 +933,7 @@ bool RenderThemeQt::paintMediaSliderThumb(RenderObject* o, const RenderObject::P if (!mediaElement) return false; - StylePainter p(paintInfo); + StylePainter p(this, paintInfo); if (!p.isValid()) return true; diff --git a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h index 617c875..13fb42f 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h +++ b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.h @@ -35,6 +35,7 @@ namespace WebCore { class RenderStyle; class HTMLMediaElement; +class ScrollbarThemeQt; class RenderThemeQt : public RenderTheme { private: @@ -75,6 +76,8 @@ public: virtual String extraMediaControlsStyleSheet(); #endif + QStyle* qStyle() const; + protected: virtual bool paintCheckbox(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r); virtual void setCheckboxSize(RenderStyle*) const; @@ -137,8 +140,7 @@ private: void setButtonPadding(RenderStyle*) const; void setPopupPadding(RenderStyle*) const; - QStyle* qStyle() const; - QStyle* fallbackStyle(); + QStyle* fallbackStyle() const; Page* m_page; @@ -152,8 +154,8 @@ private: class StylePainter { public: - explicit StylePainter(const RenderObject::PaintInfo& paintInfo); - explicit StylePainter(GraphicsContext* context); + explicit StylePainter(RenderThemeQt*, const RenderObject::PaintInfo&); + explicit StylePainter(ScrollbarThemeQt*, GraphicsContext*); ~StylePainter(); bool isValid() const { return painter && style; } @@ -170,7 +172,7 @@ public: { style->drawComplexControl(cc, &opt, painter, widget); } private: - void init(GraphicsContext* context); + void init(GraphicsContext* context, QStyle*); QBrush oldBrush; bool oldAntialiasing; diff --git a/src/3rdparty/webkit/WebCore/platform/qt/ScrollViewQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/ScrollViewQt.cpp index ccbd751..17ad253 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/ScrollViewQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/ScrollViewQt.cpp @@ -36,32 +36,19 @@ namespace WebCore { void ScrollView::platformInit() { - m_widgetsPreventingBlitting = 0; } void ScrollView::platformDestroy() { } -// Windowed plugins are using native windows and are thus preventing -// us from doing any kind of scrolling optimization. - -void ScrollView::adjustWidgetsPreventingBlittingCount(int delta) -{ - m_widgetsPreventingBlitting += delta; - if (parent()) - parent()->adjustWidgetsPreventingBlittingCount(delta); -} - void ScrollView::platformAddChild(Widget*) { - adjustWidgetsPreventingBlittingCount(1); } void ScrollView::platformRemoveChild(Widget* child) { child->hide(); - adjustWidgetsPreventingBlittingCount(-1); } } diff --git a/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.cpp index 561e55f..c0692ca 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.cpp @@ -140,7 +140,7 @@ bool ScrollbarThemeQt::paint(Scrollbar* scrollbar, GraphicsContext* graphicsCont return false; } - StylePainter p(graphicsContext); + StylePainter p(this, graphicsContext); if (!p.isValid()) return true; @@ -172,14 +172,14 @@ ScrollbarPart ScrollbarThemeQt::hitTest(Scrollbar* scrollbar, const PlatformMous QStyleOptionSlider* opt = styleOptionSlider(scrollbar); const QPoint pos = scrollbar->convertFromContainingWindow(evt.pos()); opt->rect.moveTo(QPoint(0, 0)); - QStyle::SubControl sc = QApplication::style()->hitTestComplexControl(QStyle::CC_ScrollBar, opt, pos, 0); + QStyle::SubControl sc = style()->hitTestComplexControl(QStyle::CC_ScrollBar, opt, pos, 0); return scrollbarPart(sc); } bool ScrollbarThemeQt::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& evt) { // Middle click centers slider thumb (if supported) - return QApplication::style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition) && evt.button() == MiddleButton; + return style()->styleHint(QStyle::SH_ScrollBar_MiddleClickAbsolutePosition) && evt.button() == MiddleButton; } void ScrollbarThemeQt::invalidatePart(Scrollbar* scrollbar, ScrollbarPart) @@ -190,13 +190,12 @@ void ScrollbarThemeQt::invalidatePart(Scrollbar* scrollbar, ScrollbarPart) int ScrollbarThemeQt::scrollbarThickness(ScrollbarControlSize controlSize) { - QStyle* s = QApplication::style(); QStyleOptionSlider o; o.orientation = Qt::Vertical; o.state &= ~QStyle::State_Horizontal; if (controlSize != RegularScrollbar) o.state |= QStyle::State_Mini; - return s->pixelMetric(QStyle::PM_ScrollBarExtent, &o, 0); + return style()->pixelMetric(QStyle::PM_ScrollBarExtent, &o, 0); } int ScrollbarThemeQt::thumbPosition(Scrollbar* scrollbar) @@ -209,21 +208,21 @@ int ScrollbarThemeQt::thumbPosition(Scrollbar* scrollbar) int ScrollbarThemeQt::thumbLength(Scrollbar* scrollbar) { QStyleOptionSlider* opt = styleOptionSlider(scrollbar); - IntRect thumb = QApplication::style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarSlider, 0); + IntRect thumb = style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarSlider, 0); return scrollbar->orientation() == HorizontalScrollbar ? thumb.width() : thumb.height(); } int ScrollbarThemeQt::trackPosition(Scrollbar* scrollbar) { QStyleOptionSlider* opt = styleOptionSlider(scrollbar); - IntRect track = QApplication::style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0); + IntRect track = style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0); return scrollbar->orientation() == HorizontalScrollbar ? track.x() - scrollbar->x() : track.y() - scrollbar->y(); } int ScrollbarThemeQt::trackLength(Scrollbar* scrollbar) { QStyleOptionSlider* opt = styleOptionSlider(scrollbar); - IntRect track = QApplication::style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0); + IntRect track = style()->subControlRect(QStyle::CC_ScrollBar, opt, QStyle::SC_ScrollBarGroove, 0); return scrollbar->orientation() == HorizontalScrollbar ? track.width() : track.height(); } @@ -237,7 +236,7 @@ void ScrollbarThemeQt::paintScrollCorner(ScrollView* scrollView, GraphicsContext #if QT_VERSION < 0x040500 context->fillRect(rect, QApplication::palette().color(QPalette::Normal, QPalette::Window)); #else - StylePainter p(context); + StylePainter p(this, context); if (!p.isValid()) return; @@ -247,5 +246,10 @@ void ScrollbarThemeQt::paintScrollCorner(ScrollView* scrollView, GraphicsContext #endif } +QStyle* ScrollbarThemeQt::style() const +{ + return QApplication::style(); +} + } diff --git a/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.h b/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.h index 6ca44ea..cf4882d 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.h +++ b/src/3rdparty/webkit/WebCore/platform/qt/ScrollbarThemeQt.h @@ -28,6 +28,12 @@ #include "ScrollbarTheme.h" +#include <QtCore/qglobal.h> + +QT_BEGIN_NAMESPACE +class QStyle; +QT_END_NAMESPACE + namespace WebCore { class ScrollbarThemeQt : public ScrollbarTheme { @@ -49,6 +55,8 @@ public: virtual int trackLength(Scrollbar*); virtual int scrollbarThickness(ScrollbarControlSize = RegularScrollbar); + + QStyle* style() const; }; } diff --git a/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp b/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp index e61736b..476ab8a 100644 --- a/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/qt/PluginViewQt.cpp @@ -126,6 +126,10 @@ void PluginView::updatePluginWidget() // scroll, we need to move/resize immediately. if (!m_windowRect.intersects(frameView->frameRect())) setNPWindowIfNeeded(); + + // Make sure we get repainted afterwards. This is necessary for downward + // scrolling to move the plugin widget properly. + invalidate(); } void PluginView::setFocus() @@ -657,7 +661,8 @@ NPError PluginView::getValue(NPNVariable variable, void* value) void PluginView::invalidateRect(const IntRect& rect) { if (m_isWindowed) { - platformWidget()->update(rect); + if (platformWidget()) + platformWidget()->update(rect); return; } diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp index 29bde0d..e4c2afc 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebframe.cpp @@ -1369,6 +1369,11 @@ void QWebFrame::print(QPrinter *printer) const // paranoia check fromPage = qMax(1, fromPage); toPage = qMin(printContext.pageCount(), toPage); + if (toPage < fromPage) { + // if the user entered a page range outside the actual number + // of printable pages, just return + return; + } if (printer->pageOrder() == QPrinter::LastPageFirst) { int tmp = fromPage; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp index 1d4b46f..79538ff 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp @@ -57,6 +57,106 @@ void QWebViewPrivate::_q_pageDestroyed() view->setPage(0); } +#ifdef Q_WS_MAEMO_5 +#include "qabstractkineticscroller.h" + +class QWebViewKineticScroller : public QAbstractKineticScroller { +public: + QWebViewKineticScroller() : QAbstractKineticScroller() {} + // remember the frame where the button was pressed + bool eventFilter(QObject* o, QEvent* ev) + { + switch (ev->type()) { + case QEvent::MouseButtonPress: { + QWebFrame* hitFrame = scrollingFrameAt(static_cast<QMouseEvent*>(ev)->pos()); + if (hitFrame) + m_frame = hitFrame; + break; + } + default: + break; + } + return QAbstractKineticScroller::eventFilter(o, ev); + } + +protected: + QWebFrame* currentFrame() const + { + if (!m_frame.isNull()) + return m_frame.data(); + + QWebView* view = static_cast<QWebView*>(widget()); + QWebFrame* frame = view->page()->mainFrame(); + return frame; + } + + // Returns the innermost frame at the given position that can scroll. + QWebFrame* scrollingFrameAt(const QPoint& pos) const + { + QWebView* view = static_cast<QWebView*>(widget()); + QWebFrame* mainFrame = view->page()->mainFrame(); + QWebFrame* hitFrame = mainFrame->hitTestContent(pos).frame(); + QSize range = hitFrame->contentsSize() - hitFrame->geometry().size(); + + while (hitFrame && range.width() <= 1 && range.height() <= 1) + hitFrame = hitFrame->parentFrame(); + + return hitFrame; + } + + void attachToWidget() + { + QWebView* view = static_cast<QWebView*>(widget()); + QWebFrame* mainFrame = view->page()->mainFrame(); + m_oldHorizontalScrollBarPolicy = mainFrame->scrollBarPolicy(Qt::Horizontal); + m_oldVerticalScrollBarPolicy = mainFrame->scrollBarPolicy(Qt::Vertical); + mainFrame->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); + mainFrame->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff); + view->installEventFilter(this); + } + + void removeFromWidget() + { + QWebView* view = static_cast<QWebView*>(widget()); + view->removeEventFilter(this); + QWebFrame* mainFrame = view->page()->mainFrame(); + mainFrame->setScrollBarPolicy(Qt::Vertical, m_oldVerticalScrollBarPolicy); + mainFrame->setScrollBarPolicy(Qt::Horizontal, m_oldHorizontalScrollBarPolicy); + } + + QRect positionRange() const + { + QRect r; + QWebFrame* frame = currentFrame(); + r.setSize(frame->contentsSize() - frame->geometry().size()); + return r; + } + + QPoint position() const + { + QWebFrame* frame = currentFrame(); + return frame->scrollPosition(); + } + + QSize viewportSize() const + { + return static_cast<QWebView*>(widget())->page()->viewportSize(); + } + + void setPosition(const QPoint& point, const QPoint& /* overShootDelta */) + { + QWebFrame* frame = currentFrame(); + frame->setScrollPosition(point); + } + + QPointer<QWebFrame> m_frame; + Qt::ScrollBarPolicy m_oldVerticalScrollBarPolicy; + Qt::ScrollBarPolicy m_oldHorizontalScrollBarPolicy; +}; + +#endif // Q_WS_MAEMO_5 + + /*! \class QWebView \since 4.4 @@ -153,6 +253,10 @@ QWebView::QWebView(QWidget *parent) setAttribute(Qt::WA_InputMethodEnabled); #endif +#if defined(Q_WS_MAEMO_5) + QAbstractKineticScroller* scroller = new QWebViewKineticScroller(); + scroller->setWidget(this); +#endif setAcceptDrops(true); setMouseTracking(true); diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index ee555f3..1026ac5 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,107 @@ +2010-01-28 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann. + + Do not set the combobox font on Maemo5 and S60; use the + default instead. + + * WebCoreSupport/QtFallbackWebPopup.cpp: + (WebCore::QtFallbackWebPopup::populate): + +2010-01-28 Andreas Kling <andreas.kling@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Support kinetic scrolling on Maemo 5 + + https://bugs.webkit.org/show_bug.cgi?id=34267 + + Patch by Ralf Engels <ralf.engels@nokia.com> and + Robert Griebl <rgriebl@trolltech.com> + + * Api/qwebview.cpp: + (QWebViewKineticScroller::QWebViewKineticScroller): + (QWebViewKineticScroller::eventFilter): + (QWebViewKineticScroller::currentFrame): + (QWebViewKineticScroller::scrollingFrameAt): + (QWebViewKineticScroller::attachToWidget): + (QWebViewKineticScroller::removeFromWidget): + (QWebViewKineticScroller::positionRange): + (QWebViewKineticScroller::position): + (QWebViewKineticScroller::viewportSize): + (QWebViewKineticScroller::setPosition): + (QWebView::QWebView): + +2010-01-29 Kenneth Rohde Christiansen <kenneth@webkit.org> + + Reviewed by Simon Hausmann + + Disable auto-uppercase and predictive text on Maemo5, just like the + build-in MicroB Browser. + + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::EditorClientQt::setInputMethodState): + +2010-01-28 Trond Kjernåsen <trond@trolltech.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix for endless print loop when printing web pages + + * Api/qwebframe.cpp: + (QWebFrame::print): + +2010-01-26 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Show comboboxes on Maemo 5 + https://bugs.webkit.org/show_bug.cgi?id=34088 + + Don't try to show the combobox by simulating a mouse event from QCursor::pos() to + get the combobox position right. The position on Maemo 5 is independent from the mouse + and there's no QCursor::pos(). + + * WebCoreSupport/QtFallbackWebPopup.cpp: + (WebCore::QtFallbackWebPopup::show): + +2010-01-26 Holger Hans Peter Freyther <zecke@selfish.org> + + Reviewed by Simon Hausmann. + + [Qt] JavaScript prompt is currently broken + https://bugs.webkit.org/show_bug.cgi?id=30914 + + In r52152 a patch was landed to convert a null QString + to an empty WebCore::String in case the prompt was accepted + but the default implementation returned the null QString. + + The patch tried to avoid assign to result twice and + was not checking the QString if it is null but the default + value. This lead to always returning an empty string on + successful prompts. Fix it by checking the variable 'x' + for isNull. + + The manual test case used didn't cover the case of non + empty input, replace it with an automatic test case that + should cover all cases. + + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::runJavaScriptPrompt): Fix the bug. + * tests/qwebpage/tst_qwebpage.cpp: Add automatic test case + (JSPromptPage::JSPromptPage): + (JSPromptPage::javaScriptPrompt): + (tst_QWebPage::testJSPrompt): + +2010-01-25 Janne Koskinen <janne.p.koskinen@digia.com> + + Reviewed by Simon Hausmann. + + [Qt] Phone backup support for QtWebkit for Symbian devices. + https://bugs.webkit.org/show_bug.cgi?id=34077 + + * symbian/backup_registration.xml: Added. + 2009-11-19 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> Reviewed by Kenneth Rohde Christiansen. diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp index c5d2792..0c5df4a 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp @@ -281,7 +281,7 @@ bool ChromeClientQt::runJavaScriptPrompt(Frame* f, const String& message, const // Fix up a quirk in the QInputDialog class. If no input happened the string should be empty // but it is null. See https://bugs.webkit.org/show_bug.cgi?id=30914. - if (rc && result.isNull()) + if (rc && x.isNull()) result = String(""); else result = x; diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp index 34241f0..2d1a1eb 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp @@ -615,7 +615,12 @@ void EditorClientQt::setInputMethodState(bool active) } } webPageClient->setInputMethodHint(Qt::ImhHiddenText, isPasswordField); -#endif +#ifdef Q_WS_MAEMO_5 + // Maemo 5 MicroB Browser disables auto-uppercase and predictive text, thus, so do we. + webPageClient->setInputMethodHint(Qt::ImhNoAutoUppercase, true); + webPageClient->setInputMethodHint(Qt::ImhNoPredictiveText, true); +#endif // Q_WS_MAEMO_5 +#endif // QT_VERSION check webPageClient->setInputMethodEnabled(active); } emit m_page->microFocusChanged(); diff --git a/src/3rdparty/webkit/WebKit/qt/symbian/backup_registration.xml b/src/3rdparty/webkit/WebKit/qt/symbian/backup_registration.xml new file mode 100644 index 0000000..e026140 --- /dev/null +++ b/src/3rdparty/webkit/WebKit/qt/symbian/backup_registration.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" standalone="yes"?> +<backup_registration> + <system_backup/> + <restore requires_reboot = "no"/> +</backup_registration> 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 ee1969d..0e04acc 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -1,6 +1,7 @@ /* Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in> + Copyright (C) 2010 Holger Hans Peter Freyther This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -154,6 +155,7 @@ private slots: void screenshot(); void originatingObjectInNetworkRequests(); + void testJSPrompt(); private: QWebView* m_view; @@ -1781,5 +1783,72 @@ void tst_QWebPage::originatingObjectInNetworkRequests() #endif } +/** + * Test fixups for https://bugs.webkit.org/show_bug.cgi?id=30914 + * + * From JS we test the following conditions. + * + * OK + QString() => SUCCESS, empty string (but not null) + * OK + "text" => SUCCESS, "text" + * CANCEL + QString() => CANCEL, null string + * CANCEL + "text" => CANCEL, null string + */ +class JSPromptPage : public QWebPage { + Q_OBJECT +public: + JSPromptPage() + {} + + bool javaScriptPrompt(QWebFrame* frame, const QString& msg, const QString& defaultValue, QString* result) + { + if (msg == QLatin1String("test1")) { + *result = QString(); + return true; + } else if (msg == QLatin1String("test2")) { + *result = QLatin1String("text"); + return true; + } else if (msg == QLatin1String("test3")) { + *result = QString(); + return false; + } else if (msg == QLatin1String("test4")) { + *result = QLatin1String("text"); + return false; + } + + qFatal("Unknown msg."); + return QWebPage::javaScriptPrompt(frame, msg, defaultValue, result); + } +}; + +void tst_QWebPage::testJSPrompt() +{ + JSPromptPage page; + bool res; + + // OK + QString() + res = page.mainFrame()->evaluateJavaScript( + "var retval = prompt('test1');" + "retval=='' && retval.length == 0;").toBool(); + QVERIFY(res); + + // OK + "text" + res = page.mainFrame()->evaluateJavaScript( + "var retval = prompt('test2');" + "retval=='text' && retval.length == 4;").toBool(); + QVERIFY(res); + + // Cancel + QString() + res = page.mainFrame()->evaluateJavaScript( + "var retval = prompt('test3');" + "retval===null;").toBool(); + QVERIFY(res); + + // Cancel + "text" + res = page.mainFrame()->evaluateJavaScript( + "var retval = prompt('test4');" + "retval===null;").toBool(); + QVERIFY(res); +} + QTEST_MAIN(tst_QWebPage) #include "tst_qwebpage.moc" diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 2b4ab47..cedb43f 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -299,8 +299,6 @@ void QUnifiedTimer::registerRunningAnimation(QAbstractAnimation *animation) return; if (QAbstractAnimationPrivate::get(animation)->isPause) { - if (animation->duration() == -1) - qDebug() << "toto"; runningPauseAnimations << animation; } else runningLeafAnimations++; diff --git a/src/corelib/arch/sparc/arch.pri b/src/corelib/arch/sparc/arch.pri index 3113dd3..9bb3a88 100644 --- a/src/corelib/arch/sparc/arch.pri +++ b/src/corelib/arch/sparc/arch.pri @@ -1,7 +1,7 @@ # # SPARC architecture # -*-64 { +*-64* { SOURCES += $$QT_ARCH_CPP/qatomic64.s } else { diff --git a/src/corelib/codecs/qsimplecodec.cpp b/src/corelib/codecs/qsimplecodec.cpp index 445565a..4cc7912 100644 --- a/src/corelib/codecs/qsimplecodec.cpp +++ b/src/corelib/codecs/qsimplecodec.cpp @@ -681,7 +681,7 @@ QByteArray QSimpleTextCodec::convertFromUnicode(const QChar *in, int length, Con int u; const QChar* ucp = in; unsigned char* rp = (unsigned char *)r.data(); - const unsigned char* rmp = (const unsigned char *)reverseMap->data(); + const unsigned char* rmp = (const unsigned char *)reverseMap->constData(); int rmsize = (int) reverseMap->size(); while(i--) { diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 698ca9e..ff40af5 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -79,7 +79,7 @@ # endif #endif // QT_NO_CODECS #include "qlocale.h" -#include "private/qmutexpool_p.h" +#include "qmutex.h" #include <stdlib.h> #include <ctype.h> @@ -659,13 +659,13 @@ static void setupLocaleMapper() #endif } - -static void setup() -{ #ifndef QT_NO_THREAD - QMutexLocker locker(QMutexPool::globalInstanceGet(&all)); +Q_GLOBAL_STATIC_WITH_ARGS(QMutex, textCodecsMutex, (QMutex::Recursive)); #endif +// textCodecsMutex need to be locked to enter this function +static void setup() +{ if (all) return; @@ -903,8 +903,6 @@ QTextCodec::ConverterState::~ConverterState() */ /*! - \nonreentrant - Constructs a QTextCodec, and gives it the highest precedence. The QTextCodec should always be constructed on the heap (i.e. with \c new). Qt takes ownership and will delete it when the application @@ -912,6 +910,9 @@ QTextCodec::ConverterState::~ConverterState() */ QTextCodec::QTextCodec() { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); all->prepend(this); } @@ -929,8 +930,12 @@ QTextCodec::~QTextCodec() if (!destroying_is_ok) qWarning("QTextCodec::~QTextCodec: Called by application"); #endif - if (all) + if (all) { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif all->removeAll(this); + } } /*! @@ -951,6 +956,9 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name) if (name.isEmpty()) return 0; +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); for (int i = 0; i < all->size(); ++i) { @@ -958,8 +966,8 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name) if (nameMatch(cursor->name(), name)) return cursor; QList<QByteArray> aliases = cursor->aliases(); - for (int i = 0; i < aliases.size(); ++i) - if (nameMatch(aliases.at(i), name)) + for (int y = 0; y < aliases.size(); ++y) + if (nameMatch(aliases.at(y), name)) return cursor; } @@ -973,6 +981,9 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name) */ QTextCodec* QTextCodec::codecForMib(int mib) { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); // Qt 3 used 1000 (mib for UCS2) as its identifier for the utf16 codec. Map @@ -1001,6 +1012,9 @@ QTextCodec* QTextCodec::codecForMib(int mib) */ QList<QByteArray> QTextCodec::availableCodecs() { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); QList<QByteArray> codecs; @@ -1008,6 +1022,11 @@ QList<QByteArray> QTextCodec::availableCodecs() codecs += all->at(i)->name(); codecs += all->at(i)->aliases(); } + +#ifndef QT_NO_THREAD + locker.unlock(); +#endif + #ifndef QT_NO_TEXTCODECPLUGIN QFactoryLoader *l = loader(); QStringList keys = l->keys(); @@ -1031,11 +1050,19 @@ QList<QByteArray> QTextCodec::availableCodecs() */ QList<int> QTextCodec::availableMibs() { +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); QList<int> codecs; for (int i = 0; i < all->size(); ++i) codecs += all->at(i)->mibEnum(); + +#ifndef QT_NO_THREAD + locker.unlock(); +#endif + #ifndef QT_NO_TEXTCODECPLUGIN QFactoryLoader *l = loader(); QStringList keys = l->keys(); @@ -1082,6 +1109,9 @@ QTextCodec* QTextCodec::codecForLocale() if (localeMapper) return localeMapper; +#ifndef QT_NO_THREAD + QMutexLocker locker(textCodecsMutex()); +#endif setup(); return localeMapper; diff --git a/src/corelib/codecs/qutfcodec.cpp b/src/corelib/codecs/qutfcodec.cpp index f7d3b06..7655c51 100644 --- a/src/corelib/codecs/qutfcodec.cpp +++ b/src/corelib/codecs/qutfcodec.cpp @@ -326,11 +326,11 @@ QString QUtf16::convertToUnicode(const char *chars, int len, QTextCodec::Convert ch.setCell(*chars++); } if (!headerdone) { + headerdone = true; if (endian == DetectEndianness) { - if (ch == QChar::ByteOrderSwapped && endian != BigEndianness) { + if (ch == QChar::ByteOrderSwapped) { endian = LittleEndianness; - } else if (ch == QChar::ByteOrderMark && endian != LittleEndianness) { - // ignore BOM + } else if (ch == QChar::ByteOrderMark) { endian = BigEndianness; } else { if (QSysInfo::ByteOrder == QSysInfo::BigEndian) { @@ -344,7 +344,6 @@ QString QUtf16::convertToUnicode(const char *chars, int len, QTextCodec::Convert } else if (ch != QChar::ByteOrderMark) { *qch++ = ch; } - headerdone = true; } else { *qch++ = ch; } diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 20e5609..dfa2c17 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1999,7 +1999,6 @@ void qt_check_pointer(const char *n, int l) qWarning("In file %s, line %d: Out of memory", n, l); } -#ifndef QT_NO_EXCEPTIONS /* \internal Allows you to throw an exception without including <new> Called internally from Q_CHECK_PTR on certain OS combinations @@ -2008,7 +2007,6 @@ void qBadAlloc() { QT_THROW(std::bad_alloc()); } -#endif /* The Q_ASSERT macro calls this function when the test fails. diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index abdafc3..f51849b 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1674,10 +1674,7 @@ Q_CORE_EXPORT void qt_assert_x(const char *where, const char *what, const char * #endif Q_CORE_EXPORT void qt_check_pointer(const char *, int); - -#ifndef QT_NO_EXCEPTIONS Q_CORE_EXPORT void qBadAlloc(); -#endif #ifdef QT_NO_EXCEPTIONS # if defined(QT_NO_DEBUG) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 38e1886..177bee4 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -497,6 +497,9 @@ public: WA_WState_AcceptedTouchBeginEvent = 122, WA_TouchPadAcceptSingleTouchEvents = 123, + WA_MergeSoftkeys = 124, + WA_MergeSoftkeysRecursively = 125, + // Add new attributes before this line WA_AttributeCount }; diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 871dd5c..6627c76 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -524,11 +524,11 @@ receiver are in the same thread. Same as QueuedConnection, if the emitter and receiver are in different threads. - \value DirectConnection + \value DirectConnection The slot is invoked immediately, when the signal is emitted. - \value QueuedConnection + \value QueuedConnection The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread. @@ -1243,6 +1243,17 @@ \value WA_TouchPadAcceptSingleTouchEvents Allows touchpad single touch events to be sent to the widget. + \value WA_MergeSoftkeys Allows widget to merge softkeys with parent widget, + i.e. widget can set only one softkeys and request softkey implementation + to take rest of the softkeys from the parent. Note parents are traversed until + WA_MergeSoftkeys is not set. See also Qt::WA_MergeSoftkeysRecursively + This attribute currently has effect only on Symbian platforms + + \value WA_MergeSoftkeysRecursively Allows widget to merge softkeys recursively + with all parents. If this attribute is set, the widget parents are traversed until + window boundary (widget without parent or dialog) is found. + This attribute currently has effect only on Symbian platforms + \omitvalue WA_SetLayoutDirection \omitvalue WA_InputMethodTransparent \omitvalue WA_WState_CompressKeys diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index 1c68716..bc68599 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -83,7 +83,7 @@ public: if(stream->message_output) { QT_TRY { qt_message_output(stream->type, stream->buffer.toLocal8Bit().data()); - } QT_CATCH(std::bad_alloc) { /* We're out of memory - give up. */ } + } QT_CATCH(std::bad_alloc&) { /* We're out of memory - give up. */ } } delete stream; } diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index 43e978f..606941e 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -98,7 +98,7 @@ static inline QByteArray openModeToFopenMode(QIODevice::OpenMode flags, const QS if (!fileName.isEmpty() && QT_STAT(QFile::encodeName(fileName), &statBuf) == 0 && (statBuf.st_mode & S_IFMT) == S_IFREG) { - mode += "+"; + mode += '+'; } else { mode = "wb+"; } diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp index a1f2047..972b0e0 100644 --- a/src/corelib/io/qprocess_symbian.cpp +++ b/src/corelib/io/qprocess_symbian.cpp @@ -919,34 +919,41 @@ bool QProcessPrivate::waitForFinished(int msecs) Q_Q(QProcess); QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished(%d)", msecs); - TRequestStatus timerStatus = 0; - TRequestStatus logonStatus = 0; + TRequestStatus timerStatus = KErrNone; + TRequestStatus logonStatus = KErrNone; bool timeoutOccurred = false; // Logon to process to observe its death if (qt_rprocess_running(symbianProcess)) { symbianProcess->Logon(logonStatus); - // Create timer - RTimer timer; - timer.CreateLocal(); - TTimeIntervalMicroSeconds32 interval(msecs*1000); - timer.After(timerStatus, interval); + if (msecs < 0) { + // If timeout is negative, there is no timeout + QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished() - Waiting (just logon)..."); + User::WaitForRequest(logonStatus); + QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished() - Wait completed"); + } else { + // Create timer + RTimer timer; + timer.CreateLocal(); + TTimeIntervalMicroSeconds32 interval(msecs*1000); + timer.After(timerStatus, interval); - QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished() - Waiting..."); - User::WaitForRequest(logonStatus, timerStatus); - QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished() - Wait completed"); + QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished() - Waiting (logon + timer)..."); + User::WaitForRequest(logonStatus, timerStatus); + QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished() - Wait completed"); - if (timerStatus == KErrNone) - timeoutOccurred = true; + if (timerStatus == KErrNone) + timeoutOccurred = true; - timer.Cancel(); - timer.Close(); + timer.Cancel(); + timer.Close(); - symbianProcess->LogonCancel(logonStatus); + symbianProcess->LogonCancel(logonStatus); - // Eat cancel request completion so that it won't mess up main thread scheduling later - User::WaitForRequest(logonStatus, timerStatus); + // Eat cancel request completion so that it won't mess up main thread scheduling later + User::WaitForRequest(logonStatus, timerStatus); + } } else { QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForFinished(), qt_rprocess_running returned false"); } diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 0bf7d3f..5119ec0 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -783,7 +783,7 @@ bool QProcessPrivate::processStarted() // did we read an error message? if (i > 0) - q_func()->setErrorString(QString::fromUtf16(buf, i / sizeof(QChar))); + q_func()->setErrorString(QString((const QChar *)buf, i / sizeof(QChar))); return i <= 0; } diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 2c31509..64015ce 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -1091,30 +1091,23 @@ static inline int pathHashKey(QSettings::Format format, QSettings::Scope scope) return int((uint(format) << 1) | uint(scope == QSettings::SystemScope)); } -static QString getPath(QSettings::Format format, QSettings::Scope scope) +static void initDefaultPaths(QMutexLocker *locker) { - Q_ASSERT((int)QSettings::NativeFormat == 0); - Q_ASSERT((int)QSettings::IniFormat == 1); - + PathHash *pathHash = pathHashFunc(); QString homePath = QDir::homePath(); QString systemPath; - QMutexLocker locker(globalMutex()); - PathHash *pathHash = pathHashFunc(); - bool loadSystemPath = pathHash->isEmpty(); - locker.unlock(); - - if (loadSystemPath) { - /* - QLibraryInfo::location() uses QSettings, so in order to - avoid a dead-lock, we can't hold the global mutex while - calling it. - */ - systemPath = QLibraryInfo::location(QLibraryInfo::SettingsPath); - systemPath += QLatin1Char('/'); - } + locker->unlock(); + + /* + QLibraryInfo::location() uses QSettings, so in order to + avoid a dead-lock, we can't hold the global mutex while + calling it. + */ + systemPath = QLibraryInfo::location(QLibraryInfo::SettingsPath); + systemPath += QLatin1Char('/'); - locker.relock(); + locker->relock(); if (pathHash->isEmpty()) { /* Lazy initialization of pathHash. We initialize the @@ -1155,6 +1148,17 @@ static QString getPath(QSettings::Format format, QSettings::Scope scope) #endif #endif } +} + +static QString getPath(QSettings::Format format, QSettings::Scope scope) +{ + Q_ASSERT((int)QSettings::NativeFormat == 0); + Q_ASSERT((int)QSettings::IniFormat == 1); + + QMutexLocker locker(globalMutex()); + PathHash *pathHash = pathHashFunc(); + if (pathHash->isEmpty()) + initDefaultPaths(&locker); QString result = pathHash->value(pathHashKey(format, scope)); if (!result.isEmpty()) @@ -3455,6 +3459,8 @@ void QSettings::setPath(Format format, Scope scope, const QString &path) { QMutexLocker locker(globalMutex()); PathHash *pathHash = pathHashFunc(); + if (pathHash->isEmpty()) + initDefaultPaths(&locker); pathHash->insert(pathHashKey(format, scope), path + QDir::separator()); } diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index a131d6c..076cc33 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -3241,8 +3241,11 @@ static QString qt_ACE_do(const QString &domain, AceOperation op) while (1) { int idx = nextDotDelimiter(domain, lastIdx); int labelLength = idx - lastIdx; - if (labelLength == 0) + if (labelLength == 0) { + if (idx == domain.length()) + break; return QString(); // two delimiters in a row -- empty label not allowed + } // RFC 3490 says, about the ToASCII operation: // 3. If the UseSTD3ASCIIRules flag is set, then perform these checks: diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp index dbf422e..36e4af9 100644 --- a/src/corelib/kernel/qabstractitemmodel.cpp +++ b/src/corelib/kernel/qabstractitemmodel.cpp @@ -1006,6 +1006,9 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent, Returns the child of the model index that is stored in the given \a row and \a column. + \note This function does not work for an invalid model index which is often + used as the root index. + \sa parent(), sibling() */ diff --git a/src/corelib/kernel/qcore_symbian_p.cpp b/src/corelib/kernel/qcore_symbian_p.cpp index 5d2a6a5..0257ac4 100644 --- a/src/corelib/kernel/qcore_symbian_p.cpp +++ b/src/corelib/kernel/qcore_symbian_p.cpp @@ -71,7 +71,7 @@ Q_CORE_EXPORT QString qt_TDesC2QString(const TDesC& aDescriptor) #ifdef QT_NO_UNICODE return QString::fromLocal8Bit(aDescriptor.Ptr(), aDescriptor.Length()); #else - return QString::fromUtf16(aDescriptor.Ptr(), aDescriptor.Length()); + return QString(reinterpret_cast<const QChar *>(aDescriptor.Ptr()), aDescriptor.Length()); #endif } diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 005dedc..2da5a7d 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -2219,7 +2219,8 @@ QStringList QCoreApplication::libraryPaths() TFindFile finder(fs); TInt err = finder.FindByDir(tempPathPtr, tempPathPtr); while (err == KErrNone) { - QString foundDir = QString::fromUtf16(finder.File().Ptr(), finder.File().Length()); + QString foundDir(reinterpret_cast<const QChar *>(finder.File().Ptr()), + finder.File().Length()); foundDir = QDir(foundDir).canonicalPath(); if (!app_libpaths->contains(foundDir)) app_libpaths->append(foundDir); @@ -2267,6 +2268,10 @@ QStringList QCoreApplication::libraryPaths() \a paths. All existing paths will be deleted and the path list will consist of the paths given in \a paths. + In Symbian this function is only useful for setting paths for + finding Qt extension plugin stubs, since the OS can only + load libraries from the \c{/sys/bin} directory. + \sa libraryPaths(), addLibraryPath(), removeLibraryPath(), QLibrary */ void QCoreApplication::setLibraryPaths(const QStringList &paths) @@ -2290,6 +2295,10 @@ void QCoreApplication::setLibraryPaths(const QStringList &paths) is \c INSTALL/plugins, where \c INSTALL is the directory where Qt was installed. + In Symbian this function is only useful for adding paths for + finding Qt extension plugin stubs, since the OS can only + load libraries from the \c{/sys/bin} directory. + \sa removeLibraryPath(), libraryPaths(), setLibraryPaths() */ void QCoreApplication::addLibraryPath(const QString &path) diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 3f69b4f..3500b63 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -133,10 +133,10 @@ QT_BEGIN_NAMESPACE \value GrabKeyboard Item gains keyboard grab (QGraphicsItem only). \value GrabMouse Item gains mouse grab (QGraphicsItem only). \value GraphicsSceneContextMenu Context popup menu over a graphics scene (QGraphicsSceneContextMenuEvent). - \value GraphicsSceneDragEnter The cursor enters a graphics scene during a drag and drop operation. - \value GraphicsSceneDragLeave The cursor leaves a graphics scene during a drag and drop operation. - \value GraphicsSceneDragMove A drag and drop operation is in progress over a scene. - \value GraphicsSceneDrop A drag and drop operation is completed over a scene. + \value GraphicsSceneDragEnter The cursor enters a graphics scene during a drag and drop operation (QGraphicsSceneDragDropEvent). + \value GraphicsSceneDragLeave The cursor leaves a graphics scene during a drag and drop operation (QGraphicsSceneDragDropEvent). + \value GraphicsSceneDragMove A drag and drop operation is in progress over a scene (QGraphicsSceneDragDropEvent). + \value GraphicsSceneDrop A drag and drop operation is completed over a scene (QGraphicsSceneDragDropEvent). \value GraphicsSceneHelp The user requests help for a graphics scene (QHelpEvent). \value GraphicsSceneHoverEnter The mouse cursor enters a hover item in a graphics scene (QGraphicsSceneHoverEvent). \value GraphicsSceneHoverLeave The mouse cursor leaves a hover item in a graphics scene (QGraphicsSceneHoverEvent). diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index b7e6ea0..7d1e1d3 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -633,7 +633,7 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context, end: if (!tn) return QString(); - QString str = QString::fromUtf16((const ushort *)tn, tn_length/2); + QString str = QString((const QChar *)tn, tn_length/2); if (QSysInfo::ByteOrder == QSysInfo::LittleEndian) { for (int i = 0; i < str.length(); ++i) str[i] = QChar((str.at(i).unicode() >> 8) + ((str.at(i).unicode() << 8) & 0xff00)); diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 7112043..f2c2384 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -539,6 +539,7 @@ bool QLibraryPrivate::loadPlugin() \row \i AIX \i \c .a \row \i HP-UX \i \c .sl, \c .so (HP-UXi) \row \i Mac OS X \i \c .dylib, \c .bundle, \c .so + \row \i Symbian \i \c .dll \endtable Trailing versioning numbers on Unix are ignored. diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index b276f0a..37d5b87 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -40,7 +40,9 @@ ****************************************************************************/ //#define WINVER 0x0500 +#if _WIN32_WINNT < 0x0400 #define _WIN32_WINNT 0x0400 +#endif #include "qthread.h" diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp index 0ef92d9..b6a2df4 100644 --- a/src/corelib/tools/qeasingcurve.cpp +++ b/src/corelib/tools/qeasingcurve.cpp @@ -125,7 +125,7 @@ \value OutCubic \inlineimage qeasingcurve-outcubic.png \br Easing curve for a cubic (t^3) function: - decelerating from zero velocity. + decelerating to zero velocity. \value InOutCubic \inlineimage qeasingcurve-inoutcubic.png \br Easing curve for a cubic (t^3) function: @@ -141,7 +141,7 @@ \value OutQuart \inlineimage qeasingcurve-outquart.png \br Easing curve for a cubic (t^4) function: - decelerating from zero velocity. + decelerating to zero velocity. \value InOutQuart \inlineimage qeasingcurve-inoutquart.png \br Easing curve for a cubic (t^4) function: @@ -157,7 +157,7 @@ \value OutQuint \inlineimage qeasingcurve-outquint.png \br Easing curve for a cubic (t^5) function: - decelerating from zero velocity. + decelerating to zero velocity. \value InOutQuint \inlineimage qeasingcurve-inoutquint.png \br Easing curve for a cubic (t^5) function: diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index d758325..6231471 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -68,8 +68,8 @@ static uint hash(const uchar *p, int n) while (n--) { h = (h << 4) + *p++; - if ((g = (h & 0xf0000000)) != 0) - h ^= g >> 23; + g = h & 0xf0000000; + h ^= g >> 23; h &= ~g; } return h; @@ -82,8 +82,8 @@ static uint hash(const QChar *p, int n) while (n--) { h = (h << 4) + (*p++).unicode(); - if ((g = (h & 0xf0000000)) != 0) - h ^= g >> 23; + g = h & 0xf0000000; + h ^= g >> 23; h &= ~g; } return h; diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp index f1df9bd..c302857 100644 --- a/src/corelib/tools/qlist.cpp +++ b/src/corelib/tools/qlist.cpp @@ -208,7 +208,7 @@ void **QListData::append2(const QListData& l) int n = l.d->end - l.d->begin; if (n) { if (e + n > d->alloc) - realloc(grow(e + l.d->end - l.d->begin)); + realloc(grow(e + n)); d->end += n; } return d->array + e; diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index 21816b9..1b4b356 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -130,7 +130,7 @@ multiple- or virtual-inheritance (that is, in cases where two different pointer addresses can refer to the same object). In that case, if a pointer is cast to a different type and its value changes, - QSharedPointer's pointer tracking mechanism mail fail to detect that the + QSharedPointer's pointer tracking mechanism may fail to detect that the object being tracked is the same. \omit diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index b9dd4d1..3ef0e66 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -885,7 +885,7 @@ int QString::grow(int size) QString QString::fromWCharArray(const wchar_t *string, int size) { if (sizeof(wchar_t) == sizeof(QChar)) { - return fromUtf16((ushort *)string, size); + return fromUtf16((const ushort *)string, size); } else { return fromUcs4((uint *)string, size); } @@ -3857,6 +3857,12 @@ QString QString::fromUtf8(const char *str, int size) If \a size is -1 (default), \a unicode must be terminated with a 0. + This function checks for a Byte Order Mark (BOM). If it is missing, + host byte order is assumed. + + This function is comparatively slow. + Use QString(const ushort *, int) if possible. + QString makes a deep copy of the Unicode data. \sa utf16(), setUtf16() @@ -3923,6 +3929,9 @@ QString& QString::setUnicode(const QChar *unicode, int size) If \a unicode is 0, nothing is copied, but the string is still resized to \a size. + Note that unlike fromUtf16(), this function does not consider BOMs and + possibly differing byte ordering. + \sa utf16(), setUnicode() */ @@ -4669,6 +4678,8 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1, Returns the QString as a '\\0\'-terminated array of unsigned shorts. The result remains valid until the string is modified. + The returned string is in host byte order. + \sa unicode() */ @@ -7740,7 +7751,7 @@ QString QStringRef::toString() const { return QString(); if (m_size && m_position == 0 && m_size == m_string->size()) return *m_string; - return QString::fromUtf16(reinterpret_cast<const ushort*>(m_string->unicode() + m_position), m_size); + return QString(m_string->unicode() + m_position, m_size); } diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index ddb5c7d..74661c2 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -71,7 +71,7 @@ public: private: const int m_size; - const char *m_data; + const char * const m_data; }; struct Q_CORE_EXPORT QAbstractConcatenable diff --git a/src/dbus/qdbusargument.cpp b/src/dbus/qdbusargument.cpp index 3466d90..7defc9a 100644 --- a/src/dbus/qdbusargument.cpp +++ b/src/dbus/qdbusargument.cpp @@ -535,7 +535,6 @@ QDBusArgument &QDBusArgument::operator<<(const QByteArray &arg) /*! \internal - Returns the type signature of the D-Bus type this QDBusArgument \since 4.5 Appends the variant \a v. diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 30fa0b6..44abf7b 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1660,9 +1660,6 @@ void QDBusConnectionPrivate::setConnection(DBusConnection *dbc, const QDBusError } QString busService = QLatin1String(DBUS_SERVICE_DBUS); - WatchedServicesHash::mapped_type &bus = watchedServices[busService]; - bus.refcount = 1; - bus.owner = getNameOwnerNoCache(busService); connectSignal(busService, QString(), QString(), QLatin1String("NameAcquired"), QStringList(), QString(), this, SLOT(registerService(QString))); connectSignal(busService, QString(), QString(), QLatin1String("NameLost"), QStringList(), QString(), @@ -2004,7 +2001,8 @@ bool QDBusConnectionPrivate::connectSignal(const QString &service, entry.path == hook.path && entry.signature == hook.signature && entry.obj == hook.obj && - entry.midx == hook.midx) { + entry.midx == hook.midx && + entry.argumentMatch == hook.argumentMatch) { // no need to compare the parameters if it's the same slot return true; // already there } @@ -2046,10 +2044,7 @@ void QDBusConnectionPrivate::connectSignal(const QString &key, const SignalHook // Do we need to watch for this name? if (shouldWatchService(hook.service)) { WatchedServicesHash::mapped_type &data = watchedServices[hook.service]; - if (data.refcount) { - // already watching - ++data.refcount; - } else { + if (++data.refcount == 1) { // we need to watch for this service changing QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); connectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), @@ -2089,7 +2084,8 @@ bool QDBusConnectionPrivate::disconnectSignal(const QString &service, entry.path == hook.path && entry.signature == hook.signature && entry.obj == hook.obj && - entry.midx == hook.midx) { + entry.midx == hook.midx && + entry.argumentMatch == hook.argumentMatch) { // no need to compare the parameters if it's the same slot disconnectSignal(it); return true; // it was there @@ -2105,19 +2101,6 @@ QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it) { const SignalHook &hook = it.value(); - WatchedServicesHash::Iterator sit = watchedServices.find(hook.service); - if (sit != watchedServices.end()) { - if (sit.value().refcount == 1) { - watchedServices.erase(sit); - QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); - disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), - QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), - this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); - } else { - --sit.value().refcount; - } - } - bool erase = false; MatchRefCountHash::iterator i = matchRefCounts.find(hook.matchRule); if (i == matchRefCounts.end()) { @@ -2136,6 +2119,20 @@ QDBusConnectionPrivate::disconnectSignal(SignalHookHash::Iterator &it) if (connection && erase) { qDBusDebug("Removing rule: %s", hook.matchRule.constData()); q_dbus_bus_remove_match(connection, hook.matchRule, NULL); + + // Successfully disconnected the signal + // Were we watching for this name? + WatchedServicesHash::Iterator sit = watchedServices.find(hook.service); + if (sit != watchedServices.end()) { + if (--sit.value().refcount == 0) { + watchedServices.erase(sit); + QString dbusServerService = QLatin1String(DBUS_SERVICE_DBUS); + disconnectSignal(dbusServerService, QString(), QLatin1String(DBUS_INTERFACE_DBUS), + QLatin1String("NameOwnerChanged"), QStringList() << hook.service, QString(), + this, SLOT(_q_serviceOwnerChanged(QString,QString,QString))); + } + } + } return signalHooks.erase(it); diff --git a/src/dbus/qdbusmarshaller.cpp b/src/dbus/qdbusmarshaller.cpp index f156e04..8ec328e 100644 --- a/src/dbus/qdbusmarshaller.cpp +++ b/src/dbus/qdbusmarshaller.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qdbusargument_p.h" +#include "qdbusmetatype_p.h" #include "qdbusutil_p.h" QT_BEGIN_NAMESPACE @@ -167,7 +168,7 @@ inline bool QDBusMarshaller::append(const QDBusVariant &arg) QByteArray tmpSignature; const char *signature = 0; - if (int(id) == qMetaTypeId<QDBusArgument>()) { + if (int(id) == QDBusMetaTypeId::argument) { // take the signature from the QDBusArgument object we're marshalling tmpSignature = qvariant_cast<QDBusArgument>(value).currentSignature().toLatin1(); @@ -353,7 +354,7 @@ bool QDBusMarshaller::appendVariantInternal(const QVariant &arg) } // intercept QDBusArgument parameters here - if (id == qMetaTypeId<QDBusArgument>()) { + if (id == QDBusMetaTypeId::argument) { QDBusArgument dbusargument = qvariant_cast<QDBusArgument>(arg); QDBusArgumentPrivate *d = QDBusArgumentPrivate::d(dbusargument); if (!d->message) diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index 21650bb..089e04a 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -229,11 +229,10 @@ Q_GUI_EXPORT _qt_filedialog_save_filename_hook qt_filedialog_save_filename_hook \value ReadOnly Indicates that the model is readonly. \value HideNameFilterDetails Indicates if the is hidden or not. - This value is obsolete and does nothing since Qt 4.5: \value DontUseSheet In previous versions of Qt, the static functions would create a sheet by default if the static function - was given a parent. This is no longer supported in Qt 4.5, The + was given a parent. This is no longer supported and does nothing in Qt 4.5, The static functions will always be an application modal dialog. If you want to use sheets, use QFileDialog::open() instead. diff --git a/src/gui/dialogs/qprintdialog.h b/src/gui/dialogs/qprintdialog.h index 390a4a0..ecd50c1 100644 --- a/src/gui/dialogs/qprintdialog.h +++ b/src/gui/dialogs/qprintdialog.h @@ -97,9 +97,9 @@ public: void done(int result); #if defined (Q_OS_UNIX) && defined (QT3_SUPPORT) - void setPrinter(QPrinter *, bool = false); - QPrinter *printer() const; - void addButton(QPushButton *button); + QT3_SUPPORT void setPrinter(QPrinter *, bool = false); + QT3_SUPPORT QPrinter *printer() const; + QT3_SUPPORT void addButton(QPushButton *button); #endif void setOption(PrintDialogOption option, bool on = true); diff --git a/src/gui/dialogs/qprintpreviewdialog.cpp b/src/gui/dialogs/qprintpreviewdialog.cpp index 42be780..6723b53 100644 --- a/src/gui/dialogs/qprintpreviewdialog.cpp +++ b/src/gui/dialogs/qprintpreviewdialog.cpp @@ -207,6 +207,9 @@ public: QActionGroup *printerGroup; QAction *printAction; QAction *pageSetupAction; +#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) + QAction *closeAction; +#endif QPointer<QObject> receiverToDisconnectOnClose; QByteArray memberToDisconnectOnClose; @@ -287,6 +290,9 @@ void QPrintPreviewDialogPrivate::init(QPrinter *_printer) toolbar->addSeparator(); toolbar->addAction(pageSetupAction); toolbar->addAction(printAction); +#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) + toolbar->addAction(closeAction); +#endif // Cannot use the actions' triggered signal here, since it doesn't autorepeat QToolButton *zoomInButton = static_cast<QToolButton *>(toolbar->widgetForAction(zoomInAction)); @@ -406,6 +412,10 @@ void QPrintPreviewDialogPrivate::setupActions() qt_setupActionIcon(pageSetupAction, QLatin1String("page-setup")); QObject::connect(printAction, SIGNAL(triggered(bool)), q, SLOT(_q_print())); QObject::connect(pageSetupAction, SIGNAL(triggered(bool)), q, SLOT(_q_pageSetup())); +#if defined(Q_WS_MAC) && !defined(QT_MAC_USE_COCOA) + closeAction = printerGroup->addAction(QCoreApplication::translate("QPrintPreviewDialog", "Close")); + QObject::connect(closeAction, SIGNAL(triggered(bool)), q, SLOT(reject())); +#endif // Initial state: fitPageAction->setChecked(true); diff --git a/src/gui/effects/qgraphicseffect.cpp b/src/gui/effects/qgraphicseffect.cpp index ad23df3..10ef5ea 100644 --- a/src/gui/effects/qgraphicseffect.cpp +++ b/src/gui/effects/qgraphicseffect.cpp @@ -383,9 +383,9 @@ void QGraphicsEffectSourcePrivate::invalidateCache(InvalidateReason reason) cons { if (m_cachedMode != QGraphicsEffect::PadToEffectiveBoundingRect && (reason == EffectRectChanged - || reason == TransformChanged - && m_cachedSystem == Qt::LogicalCoordinates)) + || (reason == TransformChanged && m_cachedSystem == Qt::LogicalCoordinates))) { return; + } QPixmapCache::remove(m_cacheKey); } diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 1361a89..39c41c4 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -268,6 +268,17 @@ */ /*! + \variable QGraphicsItem::Type + + The type value returned by the virtual type() function in standard + graphics item classes in Qt. All such standard graphics item + classes in Qt are associated with a unique value for Type, + e.g. the value returned by QGraphicsPathItem::type() is 2. + + \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 18 +*/ + +/*! \variable QGraphicsItem::UserType The lowest permitted type value for custom items (subclasses @@ -276,6 +287,8 @@ and declaring a Type enum value. Example: \snippet doc/src/snippets/code/src_gui_graphicsview_qgraphicsitem.cpp 1 + + \note UserType = 65536 */ /*! @@ -798,8 +811,36 @@ void QGraphicsItemPrivate::updateAncestorFlag(QGraphicsItem::GraphicsItemFlag ch return; } - foreach (QGraphicsItem *child, children) - child->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false); + for (int i = 0; i < children.size(); ++i) + children.at(i)->d_ptr->updateAncestorFlag(childFlag, flag, enabled, false); +} + +void QGraphicsItemPrivate::updateAncestorFlags() +{ + int flags = 0; + if (parent) { + // Inherit the parent's ancestor flags. + QGraphicsItemPrivate *pd = parent->d_ptr.data(); + flags = pd->ancestorFlags; + + // Add in flags from the parent. + if (pd->filtersDescendantEvents) + flags |= AncestorFiltersChildEvents; + if (pd->handlesChildEvents) + flags |= AncestorHandlesChildEvents; + if (pd->flags & QGraphicsItem::ItemClipsChildrenToShape) + flags |= AncestorClipsChildren; + if (pd->flags & QGraphicsItem::ItemIgnoresTransformations) + flags |= AncestorIgnoresTransformations; + } + + if (ancestorFlags == flags) + return; // No change; stop propagation. + ancestorFlags = flags; + + // Propagate to children recursively. + for (int i = 0; i < children.size(); ++i) + children.at(i)->d_ptr->updateAncestorFlags(); } /*! @@ -984,25 +1025,17 @@ QVariant QGraphicsItemPrivate::inputMethodQueryHelper(Qt::InputMethodQuery query prepareGeometryChange) if the item is in its destructor, i.e. inDestructor is 1. */ -void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) +void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const QVariant *newParentVariant, + const QVariant *thisPointerVariant) { Q_Q(QGraphicsItem); - if (newParent == q) { - qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this); - return; - } - if (newParent == parent) - return; - - const QVariant newParentVariant(q->itemChange(QGraphicsItem::ItemParentChange, - qVariantFromValue<QGraphicsItem *>(newParent))); - newParent = qVariantValue<QGraphicsItem *>(newParentVariant); if (newParent == parent) return; if (scene) { // Deliver the change to the index - scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParentVariant); + if (scene->d_func()->indexMethod != QGraphicsScene::NoIndex) + scene->d_func()->index->itemChange(q, QGraphicsItem::ItemParentChange, newParent); // Disable scene pos notifications for old ancestors if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) @@ -1020,11 +1053,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) if (!inDestructor) q_ptr->prepareGeometryChange(); - const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(q)); if (parent) { // Remove from current parent parent->d_ptr->removeChild(q); - parent->itemChange(QGraphicsItem::ItemChildRemovedChange, thisPointerVariant); + if (thisPointerVariant) + parent->itemChange(QGraphicsItem::ItemChildRemovedChange, *thisPointerVariant); } // Update toplevelitem list. If this item is being deleted, its parent @@ -1042,7 +1075,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) QGraphicsItem *p = parent; QGraphicsItem *parentFocusScopeItem = 0; while (p) { - if (p->flags() & QGraphicsItem::ItemIsFocusScope) { + if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) { // If this item's focus scope's focus scope item points // to this item or a descendent, then clear it. QGraphicsItem *fsi = p->d_ptr->focusScopeItem; @@ -1055,6 +1088,10 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) p = p->d_ptr->parent; } + // Update graphics effect optimization flag + if (newParent && (graphicsEffect || mayHaveChildWithGraphicsEffect)) + newParent->d_ptr->updateChildWithGraphicsEffectFlagRecursively(); + // Update focus scope item ptr in new scope. QGraphicsItem *newFocusScopeItem = subFocusItem ? subFocusItem : parentFocusScopeItem; if (newFocusScopeItem && newParent) { @@ -1063,11 +1100,11 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) QGraphicsItem *ancestorScope = 0; QGraphicsItem *p = subFocusItem->d_ptr->parent; while (p) { - if (p->flags() & QGraphicsItem::ItemIsFocusScope) + if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) ancestorScope = p; - if (p->isPanel()) + if (p->d_ptr->flags & QGraphicsItem::ItemIsPanel) break; - p = p->parentItem(); + p = p->d_ptr->parent; } if (ancestorScope) newFocusScopeItem = ancestorScope; @@ -1075,7 +1112,7 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) QGraphicsItem *p = newParent; while (p) { - if (p->flags() & QGraphicsItem::ItemIsFocusScope) { + if (p->d_ptr->flags & QGraphicsItem::ItemIsFocusScope) { p->d_ptr->focusScopeItem = newFocusScopeItem; // Ensure the new item is no longer the subFocusItem. The // only way to set focus on a child of a focus scope is @@ -1089,52 +1126,45 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) } if ((parent = newParent)) { - bool implicitUpdate = false; if (parent->d_func()->scene && parent->d_func()->scene != scene) { // Move this item to its new parent's scene parent->d_func()->scene->addItem(q); - implicitUpdate = true; } else if (!parent->d_func()->scene && scene) { // Remove this item from its former scene scene->removeItem(q); } parent->d_ptr->addChild(q); - parent->itemChange(QGraphicsItem::ItemChildAddedChange, thisPointerVariant); + if (thisPointerVariant) + parent->itemChange(QGraphicsItem::ItemChildAddedChange, *thisPointerVariant); if (scene) { - if (!implicitUpdate) - scene->d_func()->markDirty(q_ptr); - // Re-enable scene pos notifications for new ancestors if (scenePosDescendants || (flags & QGraphicsItem::ItemSendsScenePositionChanges)) scene->d_func()->setScenePosItemEnabled(q, true); } + // Propagate dirty flags to the new parent + markParentDirty(/*updateBoundingRect=*/true); + // Inherit ancestor flags from the new parent. - updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); - updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); - updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); - updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); + updateAncestorFlags(); // Update item visible / enabled. - if (parent->isVisible() != visible) { - if (!parent->isVisible() || !explicitlyHidden) - setVisibleHelper(parent->isVisible(), /* explicit = */ false, /* update = */ !implicitUpdate); + if (parent->d_ptr->visible != visible) { + if (!parent->d_ptr->visible || !explicitlyHidden) + setVisibleHelper(parent->d_ptr->visible, /* explicit = */ false, /* update = */ false); } if (parent->isEnabled() != enabled) { - if (!parent->isEnabled() || !explicitlyDisabled) - setEnabledHelper(parent->isEnabled(), /* explicit = */ false, /* update = */ !implicitUpdate); + if (!parent->d_ptr->enabled || !explicitlyDisabled) + setEnabledHelper(parent->d_ptr->enabled, /* explicit = */ false, /* update = */ false); } // Auto-activate if visible and the parent is active. - if (q->isVisible() && parent->isActive()) + if (visible && parent->isActive()) q->setActive(true); } else { // Inherit ancestor flags from the new parent. - updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-2)); - updateAncestorFlag(QGraphicsItem::GraphicsItemFlag(-1)); - updateAncestorFlag(QGraphicsItem::ItemClipsChildrenToShape); - updateAncestorFlag(QGraphicsItem::ItemIgnoresTransformations); + updateAncestorFlags(); if (!inDestructor) { // Update item visible / enabled. @@ -1142,10 +1172,6 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) setVisibleHelper(true, /* explicit = */ false); if (!enabled && !explicitlyDisabled) setEnabledHelper(true, /* explicit = */ false); - - // If the item is being deleted, the whole scene will be updated. - if (scene) - scene->d_func()->markDirty(q_ptr); } } @@ -1161,7 +1187,8 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent) } // Deliver post-change notification - q->itemChange(QGraphicsItem::ItemParentHasChanged, newParentVariant); + if (newParentVariant) + q->itemChange(QGraphicsItem::ItemParentHasChanged, *newParentVariant); if (isObject) emit static_cast<QGraphicsObject *>(q)->parentChanged(); @@ -1350,7 +1377,7 @@ QGraphicsItem::~QGraphicsItem() d_ptr->scene->d_func()->removeItemHelper(this); } else { d_ptr->resetFocusProxy(); - d_ptr->setParentItemHelper(0); + setParentItem(0); } #ifndef QT_NO_GRAPHICSEFFECT @@ -1365,7 +1392,8 @@ QGraphicsItem::~QGraphicsItem() } delete d_ptr->transformData; - qt_dataStore()->data.remove(this); + if (QGraphicsItemCustomDataStore *dataStore = qt_dataStore()) + dataStore->data.remove(this); } /*! @@ -1543,21 +1571,36 @@ const QGraphicsObject *QGraphicsItem::toGraphicsObject() const } /*! - Sets this item's parent item to \a parent. If this item already has a - parent, it is first removed from the previous parent. If \a parent is 0, - this item will become a top-level item. + Sets this item's parent item to \a newParent. If this item already + has a parent, it is first removed from the previous parent. If \a + newParent is 0, this item will become a top-level item. - Note that this implicitly adds this graphics item to the scene of - the parent. You should not \l{QGraphicsScene::addItem()}{add} the - item to the scene yourself. + Note that this implicitly adds this graphics item to the scene of + the parent. You should not \l{QGraphicsScene::addItem()}{add} the + item to the scene yourself. - Calling this function on an item that is an ancestor of \a parent have undefined behaviour. + Calling this function on an item that is an ancestor of \a newParent + have undefined behaviour. - \sa parentItem(), childItems() + \sa parentItem(), childItems() */ -void QGraphicsItem::setParentItem(QGraphicsItem *parent) +void QGraphicsItem::setParentItem(QGraphicsItem *newParent) { - d_ptr->setParentItemHelper(parent); + if (newParent == this) { + qWarning("QGraphicsItem::setParentItem: cannot assign %p as a parent of itself", this); + return; + } + if (newParent == d_ptr->parent) + return; + + const QVariant newParentVariant(itemChange(QGraphicsItem::ItemParentChange, + qVariantFromValue<QGraphicsItem *>(newParent))); + newParent = qVariantValue<QGraphicsItem *>(newParentVariant); + if (newParent == d_ptr->parent) + return; + + const QVariant thisPointerVariant(qVariantFromValue<QGraphicsItem *>(this)); + d_ptr->setParentItemHelper(newParent, &newParentVariant, &thisPointerVariant); } /*! @@ -1607,7 +1650,7 @@ bool QGraphicsItem::isWidget() const */ bool QGraphicsItem::isWindow() const { - return isWidget() && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window); + return d_ptr->isWidget && (static_cast<const QGraphicsWidget *>(this)->windowType() & Qt::Window); } /*! @@ -1644,9 +1687,9 @@ QGraphicsItem::GraphicsItemFlags QGraphicsItem::flags() const void QGraphicsItem::setFlag(GraphicsItemFlag flag, bool enabled) { if (enabled) - setFlags(flags() | flag); + setFlags(GraphicsItemFlags(d_ptr->flags) | flag); else - setFlags(flags() & ~flag); + setFlags(GraphicsItemFlags(d_ptr->flags) & ~flag); } /*! @@ -1693,8 +1736,8 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) flags = GraphicsItemFlags(itemChange(ItemFlagsChange, quint32(flags)).toUInt()); if (quint32(d_ptr->flags) == quint32(flags)) return; - if (d_ptr->scene) - d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, quint32(flags)); + if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) + d_ptr->scene->d_func()->index->itemChange(this, ItemFlagsChange, &flags); // Flags that alter the geometry of the item (or its children). const quint32 geomChangeFlagsMask = (ItemClipsChildrenToShape | ItemClipsToShape | ItemIgnoresTransformations | ItemIsSelectable); @@ -1703,7 +1746,7 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->paintedViewBoundingRectsNeedRepaint = 1; // Keep the old flags to compare the diff. - GraphicsItemFlags oldFlags = this->flags(); + GraphicsItemFlags oldFlags = GraphicsItemFlags(d_ptr->flags); // Update flags. d_ptr->flags = flags; @@ -1732,7 +1775,23 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->updateAncestorFlag(ItemIgnoresTransformations); } + if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) { + // NB! We change the flags directly here, so we must also update d_ptr->flags. + // Note that this has do be done before the ItemStacksBehindParent check + // below; otherwise we will loose the change. + + // Update stack-behind. + if (d_ptr->z < qreal(0.0)) + flags |= ItemStacksBehindParent; + else + flags &= ~ItemStacksBehindParent; + d_ptr->flags = flags; + } + if ((flags & ItemStacksBehindParent) != (oldFlags & ItemStacksBehindParent)) { + // NB! This check has to come after the ItemNegativeZStacksBehindParent + // check above. Be careful. + // Ensure child item sorting is up to date when toggling this flag. if (d_ptr->parent) d_ptr->parent->d_ptr->needSortChildren = 1; @@ -1746,10 +1805,6 @@ void QGraphicsItem::setFlags(GraphicsItemFlags flags) d_ptr->scene->d_func()->updateInputMethodSensitivityInViews(); } - if ((flags & ItemNegativeZStacksBehindParent) != (oldFlags & ItemNegativeZStacksBehindParent)) { - // Update stack-behind. - setFlag(ItemStacksBehindParent, d_ptr->z < qreal(0.0)); - } if ((d_ptr->panelModality != NonModal) && d_ptr->scene @@ -2515,6 +2570,7 @@ void QGraphicsItem::setOpacity(qreal opacity) if (newOpacity == d_ptr->opacity) return; + bool wasFullyTransparent = d_ptr->isOpacityNull(); d_ptr->opacity = newOpacity; // Notify change. @@ -2523,12 +2579,16 @@ void QGraphicsItem::setOpacity(qreal opacity) // Update. if (d_ptr->scene) { #ifndef QT_NO_GRAPHICSEFFECT - d_ptr->invalidateGraphicsEffectsRecursively(); + d_ptr->invalidateParentGraphicsEffectsRecursively(); + if (!(d_ptr->flags & ItemDoesntPropagateOpacityToChildren)) + d_ptr->invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::OpacityChanged); #endif //QT_NO_GRAPHICSEFFECT d_ptr->scene->d_func()->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false, - /*ignoreOpacity=*/true); + /*ignoreOpacity=*/d_ptr->isOpacityNull()); + if (wasFullyTransparent) + d_ptr->paintedViewBoundingRectsNeedRepaint = 1; } if (d_ptr->isObject) @@ -2568,6 +2628,8 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect) if (d_ptr->graphicsEffect) { delete d_ptr->graphicsEffect; d_ptr->graphicsEffect = 0; + } else if (d_ptr->parent) { + d_ptr->parent->d_ptr->updateChildWithGraphicsEffectFlagRecursively(); } if (effect) { @@ -2581,6 +2643,19 @@ void QGraphicsItem::setGraphicsEffect(QGraphicsEffect *effect) } #endif //QT_NO_GRAPHICSEFFECT +void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively() +{ +#ifndef QT_NO_GRAPHICSEFFECT + QGraphicsItemPrivate *itemPrivate = this; + do { + // parent chain already notified? + if (itemPrivate->mayHaveChildWithGraphicsEffect) + return; + itemPrivate->mayHaveChildWithGraphicsEffect = 1; + } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); +#endif +} + /*! \internal \since 4.6 @@ -4264,9 +4339,9 @@ void QGraphicsItem::setZValue(qreal z) if (newZ == d_ptr->z) return; - if (d_ptr->scene) { + if (d_ptr->scene && d_ptr->scene->d_func()->indexMethod != QGraphicsScene::NoIndex) { // Z Value has changed, we have to notify the index. - d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, newZVariant); + d_ptr->scene->d_func()->index->itemChange(this, ItemZValueChange, &newZ); } d_ptr->z = newZ; @@ -5033,7 +5108,7 @@ int QGraphicsItemPrivate::depth() const \internal */ #ifndef QT_NO_GRAPHICSEFFECT -void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively() +void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively() { QGraphicsItemPrivate *itemPrivate = this; do { @@ -5045,6 +5120,24 @@ void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively() } } while ((itemPrivate = itemPrivate->parent ? itemPrivate->parent->d_ptr.data() : 0)); } + +void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(QGraphicsItemPrivate::InvalidateReason reason) +{ + if (!mayHaveChildWithGraphicsEffect) + return; + + for (int i = 0; i < children.size(); ++i) { + QGraphicsItemPrivate *childPrivate = children.at(i)->d_ptr.data(); + if (reason == OpacityChanged && (childPrivate->flags & QGraphicsItem::ItemIgnoresParentOpacity)) + continue; + if (childPrivate->graphicsEffect) { + childPrivate->notifyInvalidated = 1; + static_cast<QGraphicsItemEffectSourcePrivate *>(childPrivate->graphicsEffect->d_func()->source->d_func())->invalidateCache(); + } + + childPrivate->invalidateChildGraphicsEffectsRecursively(reason); + } +} #endif //QT_NO_GRAPHICSEFFECT /*! @@ -5289,7 +5382,7 @@ void QGraphicsItem::update(const QRectF &rect) // Make sure we notify effects about invalidated source. #ifndef QT_NO_GRAPHICSEFFECT - d_ptr->invalidateGraphicsEffectsRecursively(); + d_ptr->invalidateParentGraphicsEffectsRecursively(); #endif //QT_NO_GRAPHICSEFFECT if (CacheMode(d_ptr->cacheMode) != NoCache) { @@ -7165,7 +7258,9 @@ void QGraphicsItem::prepareGeometryChange() QGraphicsScenePrivate *scenePrivate = d_ptr->scene->d_func(); scenePrivate->index->prepareBoundingRectChange(this); - scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true); + scenePrivate->markDirty(this, QRectF(), /*invalidateChildren=*/true, /*force=*/false, + /*ignoreOpacity=*/ false, /*removingItemFromScene=*/ false, + /*updateBoundingRect=*/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. @@ -7182,19 +7277,7 @@ void QGraphicsItem::prepareGeometryChange() } } - QGraphicsItem *parent = this; - while ((parent = parent->d_ptr->parent)) { - QGraphicsItemPrivate *parentp = parent->d_ptr.data(); - parentp->dirtyChildrenBoundingRect = 1; - // ### Only do this if the parent's effect applies to the entire subtree. - parentp->notifyBoundingRectChanged = 1; -#ifndef QT_NO_GRAPHICSEFFECT - if (parentp->scene && parentp->graphicsEffect) { - parentp->notifyInvalidated = 1; - static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()->source->d_func())->invalidateCache(); - } -#endif - } + d_ptr->markParentDirty(/*updateBoundingRect=*/true); } /*! diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 2d34b80..b3ca3b5 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -153,7 +153,7 @@ public: dirtyChildren(0), localCollisionHack(0), inSetPosHelper(0), - needSortChildren(1), // ### can be 0 by default? + needSortChildren(0), allChildrenDirty(0), fullUpdatePending(0), flags(0), @@ -178,6 +178,8 @@ public: sequentialOrdering(1), updateDueToGraphicsEffect(0), scenePosDescendants(0), + pendingPolish(0), + mayHaveChildWithGraphicsEffect(0), globalStackingOrder(-1), q_ptr(0) { @@ -195,8 +197,10 @@ public: return item->d_ptr.data(); } + void updateChildWithGraphicsEffectFlagRecursively(); void updateAncestorFlag(QGraphicsItem::GraphicsItemFlag childFlag, AncestorFlag flag = NoFlag, bool enabled = false, bool root = true); + void updateAncestorFlags(); void setIsMemberOfGroup(bool enabled); void remapItemPos(QEvent *event, QGraphicsItem *item); QPointF genericMapFromScene(const QPointF &pos, const QWidget *viewport) const; @@ -223,13 +227,18 @@ public: bool ignoreDirtyBit = false, bool ignoreOpacity = false) const; int depth() const; #ifndef QT_NO_GRAPHICSEFFECT - void invalidateGraphicsEffectsRecursively(); + enum InvalidateReason { + OpacityChanged + }; + void invalidateParentGraphicsEffectsRecursively(); + void invalidateChildGraphicsEffectsRecursively(InvalidateReason reason); #endif //QT_NO_GRAPHICSEFFECT void invalidateDepthRecursively(); void resolveDepth(); void addChild(QGraphicsItem *child); void removeChild(QGraphicsItem *child); - void setParentItemHelper(QGraphicsItem *parent); + void setParentItemHelper(QGraphicsItem *parent, const QVariant *newParentVariant, + const QVariant *thisPointerVariant); void childrenBoundingRectHelper(QTransform *x, QRectF *rect); void initStyleOption(QStyleOptionGraphicsItem *option, const QTransform &worldTransform, const QRegion &exposedRegion, bool allItems = false) const; @@ -349,14 +358,20 @@ public: return o; } + inline bool isOpacityNull() const + { return (opacity < qreal(0.001)); } + + static inline bool isOpacityNull(qreal opacity) + { return (opacity < qreal(0.001)); } + inline bool isFullyTransparent() const { - if (opacity < 0.001) + if (isOpacityNull()) return true; if (!parent) return false; - return calcEffectiveOpacity() < 0.001; + return isOpacityNull(calcEffectiveOpacity()); } inline qreal effectiveOpacity() const { @@ -397,6 +412,8 @@ public: return !visible || (childrenCombineOpacity() && isFullyTransparent()); } + inline void markParentDirty(bool updateBoundingRect = false); + void setFocusHelper(Qt::FocusReason focusReason, bool climb); void setSubFocus(QGraphicsItem *rootItem = 0); void clearSubFocus(QGraphicsItem *rootItem = 0); @@ -484,6 +501,8 @@ public: quint32 sequentialOrdering : 1; quint32 updateDueToGraphicsEffect : 1; quint32 scenePosDescendants : 1; + quint32 pendingPolish : 1; + quint32 mayHaveChildWithGraphicsEffect : 1; // Optional stacking order int globalStackingOrder; @@ -721,11 +740,13 @@ inline QTransform QGraphicsItemPrivate::transformToParent() const inline void QGraphicsItemPrivate::ensureSortedChildren() { if (needSortChildren) { - qSort(children.begin(), children.end(), qt_notclosestLeaf); needSortChildren = 0; sequentialOrdering = 1; + if (children.isEmpty()) + return; + qSort(children.begin(), children.end(), qt_notclosestLeaf); for (int i = 0; i < children.size(); ++i) { - if (children[i]->d_ptr->siblingIndex != i) { + if (children.at(i)->d_ptr->siblingIndex != i) { sequentialOrdering = 0; break; } @@ -741,6 +762,37 @@ inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem return a->d_ptr->siblingIndex < b->d_ptr->siblingIndex; } +/*! + \internal +*/ +inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect) +{ + QGraphicsItemPrivate *parentp = this; + while (parentp->parent) { + parentp = parentp->parent->d_ptr.data(); + parentp->dirtyChildren = 1; + + if (updateBoundingRect) { + parentp->dirtyChildrenBoundingRect = 1; + // ### Only do this if the parent's effect applies to the entire subtree. + parentp->notifyBoundingRectChanged = 1; + } +#ifndef QT_NO_GRAPHICSEFFECT + if (parentp->graphicsEffect) { + if (updateBoundingRect) { + parentp->notifyInvalidated = 1; + static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func() + ->source->d_func())->invalidateCache(); + } + if (parentp->graphicsEffect->isEnabled()) { + parentp->dirty = 1; + parentp->fullUpdatePending = 1; + } + } +#endif + } +} + QT_END_NAMESPACE #endif // QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index cea723c..66707fc 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -251,6 +251,7 @@ #endif #include <private/qgraphicseffect_p.h> #include <private/qgesturemanager_p.h> +#include <private/qpathclipper_p.h> // #define GESTURE_DEBUG #ifndef GESTURE_DEBUG @@ -292,7 +293,6 @@ QGraphicsScenePrivate::QGraphicsScenePrivate() processDirtyItemsEmitted(false), selectionChanging(0), needSortTopLevelItems(true), - unpolishedItemsModified(true), holesInTopLevelSiblingIndex(false), topLevelSequentialOrdering(true), scenePosDescendantsUpdatePending(false), @@ -373,7 +373,10 @@ void QGraphicsScenePrivate::_q_emitUpdated() } } } else { - updateAll = false; + if (views.isEmpty()) { + updateAll = false; + return; + } for (int i = 0; i < views.size(); ++i) views.at(i)->d_func()->processPendingUpdates(); // It's important that we update all views before we dispatch, hence two for-loops. @@ -429,22 +432,38 @@ void QGraphicsScenePrivate::unregisterTopLevelItem(QGraphicsItem *item) */ void QGraphicsScenePrivate::_q_polishItems() { - QSet<QGraphicsItem *>::Iterator it = unpolishedItems.begin(); + if (unpolishedItems.isEmpty()) + return; + const QVariant booleanTrueVariant(true); - while (!unpolishedItems.isEmpty()) { - QGraphicsItem *item = *it; - it = unpolishedItems.erase(it); - unpolishedItemsModified = false; - if (!item->d_ptr->explicitlyHidden) { + QGraphicsItem *item = 0; + QGraphicsItemPrivate *itemd = 0; + const int oldUnpolishedCount = unpolishedItems.count(); + + for (int i = 0; i < oldUnpolishedCount; ++i) { + item = unpolishedItems.at(i); + if (!item) + continue; + itemd = item->d_ptr.data(); + itemd->pendingPolish = false; + if (!itemd->explicitlyHidden) { item->itemChange(QGraphicsItem::ItemVisibleChange, booleanTrueVariant); item->itemChange(QGraphicsItem::ItemVisibleHasChanged, booleanTrueVariant); } - if (item->isWidget()) { + if (itemd->isWidget) { QEvent event(QEvent::Polish); QApplication::sendEvent((QGraphicsWidget *)item, &event); } - if (unpolishedItemsModified) - it = unpolishedItems.begin(); + } + + if (unpolishedItems.count() == oldUnpolishedCount) { + // No new items were added to the vector. + unpolishedItems.clear(); + } else { + // New items were appended; keep them and remove the old ones. + unpolishedItems.remove(0, oldUnpolishedCount); + unpolishedItems.squeeze(); + QMetaObject::invokeMethod(q_ptr, "_q_polishItems", Qt::QueuedConnection); } } @@ -599,7 +618,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) if (parentItem->scene()) { Q_ASSERT_X(parentItem->scene() == q, "QGraphicsScene::removeItem", "Parent item's scene is different from this item's scene"); - item->d_ptr->setParentItemHelper(0); + item->setParentItem(0); } } else { unregisterTopLevelItem(item); @@ -638,8 +657,12 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) selectedItems.remove(item); hoverItems.removeAll(item); cachedItemsUnderMouse.removeAll(item); - unpolishedItems.remove(item); - unpolishedItemsModified = true; + if (item->d_ptr->pendingPolish) { + const int unpolishedIndex = unpolishedItems.indexOf(item); + if (unpolishedIndex != -1) + unpolishedItems[unpolishedIndex] = 0; + item->d_ptr->pendingPolish = false; + } resetDirtyItem(item); //We remove all references of item from the sceneEventFilter arrays @@ -1936,7 +1959,7 @@ QList<QGraphicsItem *> QGraphicsScene::items(const QRectF &rectangle, Qt::ItemSe \since 4.3 This convenience function is equivalent to calling items(QRectF(\a x, \a y, \a w, \a h), \a mode). - + This function is deprecated and returns incorrect results if the scene contains items that ignore transformations. Use the overload that takes a QTransform instead. @@ -2482,12 +2505,12 @@ void QGraphicsScene::addItem(QGraphicsItem *item) qWarning("QGraphicsScene::addItem: cannot add null item"); return; } - if (item->scene() == this) { + if (item->d_ptr->scene == this) { qWarning("QGraphicsScene::addItem: item has already been added to this scene"); return; } // Remove this item from its existing scene - if (QGraphicsScene *oldScene = item->scene()) + if (QGraphicsScene *oldScene = item->d_ptr->scene) oldScene->removeItem(item); // Notify the item that its scene is changing, and allow the item to @@ -2496,15 +2519,20 @@ void QGraphicsScene::addItem(QGraphicsItem *item) qVariantFromValue<QGraphicsScene *>(this))); QGraphicsScene *targetScene = qVariantValue<QGraphicsScene *>(newSceneVariant); if (targetScene != this) { - if (targetScene && item->scene() != targetScene) + if (targetScene && item->d_ptr->scene != targetScene) targetScene->addItem(item); return; } + if (d->unpolishedItems.isEmpty()) + QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); + d->unpolishedItems.append(item); + item->d_ptr->pendingPolish = true; + // Detach this item from its parent if the parent's scene is different // from this scene. - if (QGraphicsItem *itemParent = item->parentItem()) { - if (itemParent->scene() != this) + if (QGraphicsItem *itemParent = item->d_ptr->parent) { + if (itemParent->d_ptr->scene != this) item->setParentItem(0); } @@ -2534,7 +2562,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) d->enableMouseTrackingOnViews(); } #ifndef QT_NO_CURSOR - if (d->allItemsUseDefaultCursor && item->hasCursor()) { + if (d->allItemsUseDefaultCursor && item->d_ptr->hasCursor) { d->allItemsUseDefaultCursor = false; if (d->allItemsIgnoreHoverEvents) // already enabled otherwise d->enableMouseTrackingOnViews(); @@ -2542,7 +2570,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) #endif //QT_NO_CURSOR // Enable touch events if the item accepts touch events. - if (d->allItemsIgnoreTouchEvents && item->acceptTouchEvents()) { + if (d->allItemsIgnoreTouchEvents && item->d_ptr->acceptTouchEvents) { d->allItemsIgnoreTouchEvents = false; d->enableTouchEventsOnViews(); } @@ -2575,17 +2603,14 @@ void QGraphicsScene::addItem(QGraphicsItem *item) } // Add all children recursively - foreach (QGraphicsItem *child, item->children()) - addItem(child); + item->d_ptr->ensureSortedChildren(); + for (int i = 0; i < item->d_ptr->children.size(); ++i) + addItem(item->d_ptr->children.at(i)); // Resolve font and palette. item->d_ptr->resolveFont(d->font.resolve()); item->d_ptr->resolvePalette(d->palette.resolve()); - if (d->unpolishedItems.isEmpty()) - QMetaObject::invokeMethod(this, "_q_polishItems", Qt::QueuedConnection); - d->unpolishedItems.insert(item); - d->unpolishedItemsModified = true; // Reenable selectionChanged() for individual items --d->selectionChanging; @@ -2619,7 +2644,7 @@ void QGraphicsScene::addItem(QGraphicsItem *item) } } - if (item->flags() & QGraphicsItem::ItemSendsScenePositionChanges) + if (item->d_ptr->flags & QGraphicsItem::ItemSendsScenePositionChanges) d->registerScenePosItem(item); // Ensure that newly added items that have subfocus set, gain @@ -3766,10 +3791,10 @@ void QGraphicsScene::helpEvent(QGraphicsSceneHelpEvent *helpEvent) bool QGraphicsScenePrivate::itemAcceptsHoverEvents_helper(const QGraphicsItem *item) const { - return (!item->isBlockedByModalPanel() && - (item->acceptHoverEvents() - || (item->isWidget() - && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration()))); + return (item->d_ptr->acceptsHover + || (item->d_ptr->isWidget + && static_cast<const QGraphicsWidget *>(item)->d_func()->hasDecoration())) + && !item->isBlockedByModalPanel(); } /*! @@ -4582,6 +4607,7 @@ void QGraphicsScenePrivate::drawItems(QPainter *painter, const QTransform *const if (!unpolishedItems.isEmpty()) _q_polishItems(); + updateAll = false; QRectF exposedSceneRect; if (exposedRegion && indexMethod != QGraphicsScene::NoIndex) { exposedSceneRect = exposedRegion->boundingRect().adjusted(-1, -1, 1, 1); @@ -4609,7 +4635,7 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter * return; // Item has neither contents nor children!(?) const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); - const bool itemIsFullyTransparent = (opacity < 0.0001); + const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity); if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) return; @@ -4729,7 +4755,7 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q qreal opacity, const QTransform *effectTransform, bool wasDirtyParentSceneTransform, bool drawItem) { - const bool itemIsFullyTransparent = (opacity < 0.0001); + const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity); const bool itemClipsChildrenToShape = (item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); const bool itemHasChildren = !item->d_ptr->children.isEmpty(); @@ -4744,7 +4770,12 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q painter->setWorldTransform(*transformPtr * *effectTransform); else painter->setWorldTransform(*transformPtr); - painter->setClipPath(item->shape(), Qt::IntersectClip); + QRectF clipRect; + const QPainterPath clipPath(item->shape()); + if (QPathClipper::pathToRect(clipPath, &clipRect)) + painter->setClipRect(clipRect, Qt::IntersectClip); + else + painter->setClipPath(clipPath, Qt::IntersectClip); } // Draw children behind @@ -4780,8 +4811,14 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q painter->setWorldTransform(*transformPtr); } - if (itemClipsToShape) - painter->setClipPath(item->shape(), Qt::IntersectClip); + if (itemClipsToShape) { + QRectF clipRect; + const QPainterPath clipPath(item->shape()); + if (QPathClipper::pathToRect(clipPath, &clipRect)) + painter->setClipRect(clipRect, Qt::IntersectClip); + else + painter->setClipPath(clipPath, Qt::IntersectClip); + } painter->setOpacity(opacity); if (!item->d_ptr->cacheMode && !item->d_ptr->isWidget) @@ -4811,7 +4848,8 @@ void QGraphicsScenePrivate::draw(QGraphicsItem *item, QPainter *painter, const Q } void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, bool invalidateChildren, - bool force, bool ignoreOpacity, bool removingItemFromScene) + bool force, bool ignoreOpacity, bool removingItemFromScene, + bool updateBoundingRect) { Q_ASSERT(item); if (updateAll) @@ -4882,17 +4920,8 @@ void QGraphicsScenePrivate::markDirty(QGraphicsItem *item, const QRectF &rect, b if (ignoreOpacity) item->d_ptr->ignoreOpacity = 1; - QGraphicsItem *p = item->d_ptr->parent; - while (p) { - p->d_ptr->dirtyChildren = 1; -#ifndef QT_NO_GRAPHICSEFFECT - if (p->d_ptr->graphicsEffect && p->d_ptr->graphicsEffect->isEnabled()) { - p->d_ptr->dirty = 1; - p->d_ptr->fullUpdatePending = 1; - } -#endif //QT_NO_GRAPHICSEFFECT - p = p->d_ptr->parent; - } + if (!updateBoundingRect) + item->d_ptr->markParentDirty(); } static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate *item, @@ -4967,7 +4996,8 @@ void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool } const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); - const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity && opacity < 0.0001; + const bool itemIsFullyTransparent = !item->d_ptr->ignoreOpacity + && QGraphicsItemPrivate::isOpacityNull(opacity); if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) { resetDirtyItem(item, /*recursive=*/itemHasChildren); return; @@ -5140,6 +5170,7 @@ void QGraphicsScene::drawItems(QPainter *painter, if (!d->unpolishedItems.isEmpty()) d->_q_polishItems(); + d->updateAll = false; QTransform viewTransform = painter->worldTransform(); Q_UNUSED(options); diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index d10811c..04ffe0f 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -108,10 +108,9 @@ public: QPainterPath selectionArea; int selectionChanging; QSet<QGraphicsItem *> selectedItems; - QSet<QGraphicsItem *> unpolishedItems; + QVector<QGraphicsItem *> unpolishedItems; QList<QGraphicsItem *> topLevelItems; bool needSortTopLevelItems; - bool unpolishedItemsModified; bool holesInTopLevelSiblingIndex; bool topLevelSequentialOrdering; @@ -223,7 +222,8 @@ public: QRegion *, QWidget *, qreal, const QTransform *const, bool, bool); void markDirty(QGraphicsItem *item, const QRectF &rect = QRectF(), bool invalidateChildren = false, - bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false); + bool force = false, bool ignoreOpacity = false, bool removingItemFromScene = false, + bool updateBoundingRect = false); void processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren = false, qreal parentOpacity = qreal(1.0)); diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 2e92b87..2a91348 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -635,16 +635,17 @@ void QGraphicsSceneBspTreeIndex::updateSceneRect(const QRectF &rect) This method react to the \a change of the \a item and use the \a value to update the BSP tree if necessary. */ -void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value) { Q_D(QGraphicsSceneBspTreeIndex); switch (change) { case QGraphicsItem::ItemFlagsChange: { // Handle ItemIgnoresTransformations + QGraphicsItem::GraphicsItemFlags newFlags = *static_cast<const QGraphicsItem::GraphicsItemFlags *>(value); bool ignoredTransform = item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations; - bool willIgnoreTransform = value.toUInt() & QGraphicsItem::ItemIgnoresTransformations; + bool willIgnoreTransform = newFlags & QGraphicsItem::ItemIgnoresTransformations; bool clipsChildren = item->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape; - bool willClipChildren = value.toUInt() & QGraphicsItem::ItemClipsChildrenToShape; + bool willClipChildren = newFlags & QGraphicsItem::ItemClipsChildrenToShape; if ((ignoredTransform != willIgnoreTransform) || (clipsChildren != willClipChildren)) { QGraphicsItem *thatItem = const_cast<QGraphicsItem *>(item); // Remove item and its descendants from the index and append @@ -661,7 +662,7 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics case QGraphicsItem::ItemParentChange: { d->invalidateSortCache(); // Handle ItemIgnoresTransformations - QGraphicsItem *newParent = qVariantValue<QGraphicsItem *>(value); + const QGraphicsItem *newParent = static_cast<const QGraphicsItem *>(value); bool ignoredTransform = item->d_ptr->itemIsUntransformable(); bool willIgnoreTransform = (item->d_ptr->flags & QGraphicsItem::ItemIgnoresTransformations) || (newParent && newParent->d_ptr->itemIsUntransformable()); @@ -682,7 +683,6 @@ void QGraphicsSceneBspTreeIndex::itemChange(const QGraphicsItem *item, QGraphics default: break; } - return QGraphicsSceneIndex::itemChange(item, change, value); } /*! \reimp diff --git a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h index 119571b..f671fd9 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex_p.h @@ -97,7 +97,7 @@ protected: void removeItem(QGraphicsItem *item); void prepareBoundingRectChange(const QGraphicsItem *item); - void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value); + void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value); private : Q_DECLARE_PRIVATE(QGraphicsSceneBspTreeIndex) diff --git a/src/gui/graphicsview/qgraphicssceneindex.cpp b/src/gui/graphicsview/qgraphicssceneindex.cpp index bc8a7dc..707c71f 100644 --- a/src/gui/graphicsview/qgraphicssceneindex.cpp +++ b/src/gui/graphicsview/qgraphicssceneindex.cpp @@ -279,7 +279,7 @@ void QGraphicsSceneIndexPrivate::recursive_items_helper(QGraphicsItem *item, QRe return; const qreal opacity = item->d_ptr->combineOpacityFromParent(parentOpacity); - const bool itemIsFullyTransparent = (opacity < 0.0001); + const bool itemIsFullyTransparent = QGraphicsItemPrivate::isOpacityNull(opacity); const bool itemHasChildren = !item->d_ptr->children.isEmpty(); if (itemIsFullyTransparent && (!itemHasChildren || item->d_ptr->childrenCombineOpacity())) return; @@ -554,7 +554,7 @@ QList<QGraphicsItem *> QGraphicsSceneIndex::estimateTopLevelItems(const QRectF & /*! \fn QList<QGraphicsItem *> QGraphicsSceneIndex::items(Qt::SortOrder order = Qt::DescendingOrder) const - + This pure virtual function all items in the index and sort them using \a order. */ @@ -624,7 +624,7 @@ void QGraphicsSceneIndex::deleteItem(QGraphicsItem *item) \sa QGraphicsItem::GraphicsItemChange */ -void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const QVariant &value) +void QGraphicsSceneIndex::itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange change, const void *const value) { Q_UNUSED(item); Q_UNUSED(change); diff --git a/src/gui/graphicsview/qgraphicssceneindex_p.h b/src/gui/graphicsview/qgraphicssceneindex_p.h index def58f0..597a229 100644 --- a/src/gui/graphicsview/qgraphicssceneindex_p.h +++ b/src/gui/graphicsview/qgraphicssceneindex_p.h @@ -110,7 +110,7 @@ protected: virtual void removeItem(QGraphicsItem *item) = 0; virtual void deleteItem(QGraphicsItem *item); - virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const QVariant &value); + virtual void itemChange(const QGraphicsItem *item, QGraphicsItem::GraphicsItemChange, const void *const value); virtual void prepareBoundingRectChange(const QGraphicsItem *item); QGraphicsSceneIndex(QGraphicsSceneIndexPrivate &dd, QGraphicsScene *scene); diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 451f183..96b9373 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -2748,7 +2748,6 @@ bool QGraphicsView::viewportEvent(QEvent *event) } } } - d->scene->d_func()->updateAll = false; } break; case QEvent::TouchBegin: diff --git a/src/gui/gui.pro b/src/gui/gui.pro index 4215f97..8ad3bac 100644 --- a/src/gui/gui.pro +++ b/src/gui/gui.pro @@ -54,4 +54,5 @@ DEFINES += Q_INTERNAL_QAPP_SRC symbian:TARGET.UID3=0x2001B2DD # ro-section in gui can exceed default allocated space, so more rw-section little further -symbian-sbsv2: QMAKE_LFLAGS.ARMCC += --rw-base 0x800000" +symbian-sbsv2: QMAKE_LFLAGS.ARMCC += --rw-base 0x800000 +symbian: QMAKE_LFLAGS.GCCE += -Tdata 0xC00000 diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 854be2e..42e19b8 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -144,7 +144,7 @@ static QDataStream &operator<<(QDataStream &s, const BMP_INFOHDR &bi) static int calc_shift(int mask) { int result = 0; - while (!(mask & 1)) { + while (mask && !(mask & 1)) { result++; mask >>= 1; } diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp index ac1d303..bf6eb8d 100644 --- a/src/gui/image/qicon.cpp +++ b/src/gui/image/qicon.cpp @@ -104,6 +104,15 @@ QT_BEGIN_NAMESPACE static QBasicAtomicInt serialNumCounter = Q_BASIC_ATOMIC_INITIALIZER(1); +static void qt_cleanup_icon_cache(); +typedef QCache<QString, QIcon> IconCache; +Q_GLOBAL_STATIC_WITH_INITIALIZER(IconCache, qtIconCache, qAddPostRoutine(qt_cleanup_icon_cache)) + +static void qt_cleanup_icon_cache() +{ + qtIconCache()->clear(); +} + QIconPrivate::QIconPrivate() : engine(0), ref(1), serialNum(serialNumCounter.fetchAndAddRelaxed(1)), @@ -963,15 +972,13 @@ QString QIcon::themeName() */ QIcon QIcon::fromTheme(const QString &name, const QIcon &fallback) { - static QCache <QString, QIcon> iconCache; - QIcon icon; - if (iconCache.contains(name)) { - icon = *iconCache.object(name); + if (qtIconCache()->contains(name)) { + icon = *qtIconCache()->object(name); } else { QIcon *cachedIcon = new QIcon(new QIconLoaderEngine(name)); - iconCache.insert(name, cachedIcon); + qtIconCache()->insert(name, cachedIcon); icon = *cachedIcon; } diff --git a/src/gui/image/qimagepixmapcleanuphooks.cpp b/src/gui/image/qimagepixmapcleanuphooks.cpp index 61d538f..ace4bb6 100644 --- a/src/gui/image/qimagepixmapcleanuphooks.cpp +++ b/src/gui/image/qimagepixmapcleanuphooks.cpp @@ -62,12 +62,12 @@ QImagePixmapCleanupHooks *QImagePixmapCleanupHooks::instance() return qt_image_and_pixmap_cleanup_hooks(); } -void QImagePixmapCleanupHooks::addPixmapModificationHook(_qt_pixmap_cleanup_hook_pm hook) +void QImagePixmapCleanupHooks::addPixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd hook) { pixmapModificationHooks.append(hook); } -void QImagePixmapCleanupHooks::addPixmapDestructionHook(_qt_pixmap_cleanup_hook_pm hook) +void QImagePixmapCleanupHooks::addPixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd hook) { pixmapDestructionHooks.append(hook); } @@ -78,12 +78,12 @@ void QImagePixmapCleanupHooks::addImageHook(_qt_image_cleanup_hook_64 hook) imageHooks.append(hook); } -void QImagePixmapCleanupHooks::removePixmapModificationHook(_qt_pixmap_cleanup_hook_pm hook) +void QImagePixmapCleanupHooks::removePixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd hook) { pixmapModificationHooks.removeAll(hook); } -void QImagePixmapCleanupHooks::removePixmapDestructionHook(_qt_pixmap_cleanup_hook_pm hook) +void QImagePixmapCleanupHooks::removePixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd hook) { pixmapDestructionHooks.removeAll(hook); } @@ -93,24 +93,24 @@ void QImagePixmapCleanupHooks::removeImageHook(_qt_image_cleanup_hook_64 hook) imageHooks.removeAll(hook); } -void QImagePixmapCleanupHooks::executePixmapModificationHooks(QPixmap* pm) +void QImagePixmapCleanupHooks::executePixmapDataModificationHooks(QPixmapData* pmd) { QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks(); for (int i = 0; i < h->pixmapModificationHooks.count(); ++i) - h->pixmapModificationHooks[i](pm); + h->pixmapModificationHooks[i](pmd); if (qt_pixmap_cleanup_hook_64) - qt_pixmap_cleanup_hook_64(pm->cacheKey()); + qt_pixmap_cleanup_hook_64(pmd->cacheKey()); } -void QImagePixmapCleanupHooks::executePixmapDestructionHooks(QPixmap* pm) +void QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(QPixmapData* pmd) { QImagePixmapCleanupHooks *h = qt_image_and_pixmap_cleanup_hooks(); for (int i = 0; i < h->pixmapDestructionHooks.count(); ++i) - h->pixmapDestructionHooks[i](pm); + h->pixmapDestructionHooks[i](pmd); if (qt_pixmap_cleanup_hook_64) - qt_pixmap_cleanup_hook_64(pm->cacheKey()); + qt_pixmap_cleanup_hook_64(pmd->cacheKey()); } void QImagePixmapCleanupHooks::executeImageHooks(qint64 key) diff --git a/src/gui/image/qimagepixmapcleanuphooks_p.h b/src/gui/image/qimagepixmapcleanuphooks_p.h index 7176044..88dd3a6 100644 --- a/src/gui/image/qimagepixmapcleanuphooks_p.h +++ b/src/gui/image/qimagepixmapcleanuphooks_p.h @@ -58,7 +58,8 @@ QT_BEGIN_NAMESPACE typedef void (*_qt_image_cleanup_hook_64)(qint64); -typedef void (*_qt_pixmap_cleanup_hook_pm)(QPixmap*); +typedef void (*_qt_pixmap_cleanup_hook_pmd)(QPixmapData*); + class QImagePixmapCleanupHooks; @@ -71,27 +72,27 @@ public: static void enableCleanupHooks(const QPixmap &pixmap); static void enableCleanupHooks(QPixmapData *pixmapData); - // Gets called when a pixmap is about to be modified: - void addPixmapModificationHook(_qt_pixmap_cleanup_hook_pm); + // Gets called when a pixmap data is about to be modified: + void addPixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd); - // Gets called when a pixmap is about to be destroyed: - void addPixmapDestructionHook(_qt_pixmap_cleanup_hook_pm); + // Gets called when a pixmap data is about to be destroyed: + void addPixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd); // Gets called when an image is about to be modified or destroyed: void addImageHook(_qt_image_cleanup_hook_64); - void removePixmapModificationHook(_qt_pixmap_cleanup_hook_pm); - void removePixmapDestructionHook(_qt_pixmap_cleanup_hook_pm); + void removePixmapDataModificationHook(_qt_pixmap_cleanup_hook_pmd); + void removePixmapDataDestructionHook(_qt_pixmap_cleanup_hook_pmd); void removeImageHook(_qt_image_cleanup_hook_64); - static void executePixmapModificationHooks(QPixmap*); - static void executePixmapDestructionHooks(QPixmap*); + static void executePixmapDataModificationHooks(QPixmapData*); + static void executePixmapDataDestructionHooks(QPixmapData*); static void executeImageHooks(qint64 key); private: QList<_qt_image_cleanup_hook_64> imageHooks; - QList<_qt_pixmap_cleanup_hook_pm> pixmapModificationHooks; - QList<_qt_pixmap_cleanup_hook_pm> pixmapDestructionHooks; + QList<_qt_pixmap_cleanup_hook_pmd> pixmapModificationHooks; + QList<_qt_pixmap_cleanup_hook_pmd> pixmapDestructionHooks; }; QT_END_NAMESPACE diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp index c9e015c..9320cfc 100644 --- a/src/gui/image/qimagereader.cpp +++ b/src/gui/image/qimagereader.cpp @@ -263,25 +263,37 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device, device->seek(pos); } - if (!handler && !testFormat.isEmpty() && autoDetectImageFormat && !ignoresFormatAndExtension) { + if (!handler && !testFormat.isEmpty() && !ignoresFormatAndExtension) { // check if any plugin supports the format (they are not allowed to // read from the device yet). const qint64 pos = device ? device->pos() : 0; - for (int i = 0; i < keys.size(); ++i) { - if (i != suffixPluginIndex) { - QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i))); - if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) { + + if (autoDetectImageFormat) { + for (int i = 0; i < keys.size(); ++i) { + if (i != suffixPluginIndex) { + QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i))); + if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) { #ifdef QIMAGEREADER_DEBUG - qDebug() << "QImageReader::createReadHandler: the" << keys.at(i) << "plugin can read this format"; + qDebug() << "QImageReader::createReadHandler: the" << keys.at(i) << "plugin can read this format"; #endif - handler = plugin->create(device, testFormat); - break; + handler = plugin->create(device, testFormat); + break; + } } } + } else { + QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(QLatin1String(testFormat))); + if (plugin && plugin->capabilities(device, testFormat) & QImageIOPlugin::CanRead) { +#ifdef QIMAGEREADER_DEBUG + qDebug() << "QImageReader::createReadHandler: the" << testFormat << "plugin can read this format"; +#endif + handler = plugin->create(device, testFormat); + } } if (device && !device->isSequential()) device->seek(pos); } + #endif // QT_NO_LIBRARY // if we don't have a handler yet, check if we have built-in support for diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index f823fdc..d1e5c40 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -320,8 +320,6 @@ QPixmap::QPixmap(const char * const xpm[]) QPixmap::~QPixmap() { Q_ASSERT(!data || data->ref >= 1); // Catch if ref-counting changes again - if (data && data->is_cached && data->ref == 1) // ref will be decrememnted after destructor returns - QImagePixmapCleanupHooks::executePixmapDestructionHooks(this); } /*! @@ -1025,12 +1023,8 @@ qint64 QPixmap::cacheKey() const if (isNull()) return 0; - int classKey = data->classId(); - if (classKey >= 1024) - classKey = -(classKey >> 10); - return ((((qint64) classKey) << 56) - | (((qint64) data->serialNumber()) << 32) - | ((qint64) (data->detach_no))); + Q_ASSERT(data); + return data->cacheKey(); } static void sendResizeEvents(QWidget *target) @@ -1943,7 +1937,7 @@ void QPixmap::detach() } if (data->is_cached && data->ref == 1) - QImagePixmapCleanupHooks::executePixmapModificationHooks(this); + QImagePixmapCleanupHooks::executePixmapDataModificationHooks(data.data()); #if defined(Q_WS_MAC) QMacPixmapData *macData = id == QPixmapData::MacClass ? static_cast<QMacPixmapData*>(data.data()) : 0; diff --git a/src/gui/image/qpixmap_x11.cpp b/src/gui/image/qpixmap_x11.cpp index 0e66e09..e1e8a0d 100644 --- a/src/gui/image/qpixmap_x11.cpp +++ b/src/gui/image/qpixmap_x11.cpp @@ -68,6 +68,7 @@ #include "qx11info_x11.h" #include <private/qdrawhelper_p.h> #include <private/qimage_p.h> +#include <private/qimagepixmapcleanuphooks_p.h> #include <stdlib.h> @@ -1228,6 +1229,12 @@ void QX11PixmapData::fill(const QColor &fillColor) QX11PixmapData::~QX11PixmapData() { + // Cleanup hooks have to be called before the handles are freed + if (is_cached) { + QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(this); + is_cached = false; + } + release(); } @@ -1236,8 +1243,13 @@ void QX11PixmapData::release() delete pengine; pengine = 0; - if (!X11) + if (!X11) { +#ifndef QT_NO_DEBUG + qWarning("~QX11PixmapData(): QPixmap objects must be destroyed before the QApplication" + " object, otherwise the native pixmap object will be leaked."); +#endif return; + } if (x11_mask) { #ifndef QT_NO_XRENDER diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp index 65032da..ea4fe6b 100644 --- a/src/gui/image/qpixmapdata.cpp +++ b/src/gui/image/qpixmapdata.cpp @@ -45,6 +45,7 @@ #include <QtGui/qimagereader.h> #include <private/qgraphicssystem_p.h> #include <private/qapplication_p.h> +#include <private/qimagepixmapcleanuphooks_p.h> QT_BEGIN_NAMESPACE @@ -80,6 +81,16 @@ QPixmapData::QPixmapData(PixelType pixelType, int objectId) QPixmapData::~QPixmapData() { + // Sometimes the pixmap cleanup hooks will be called from derrived classes, which will + // then set is_cached to false. For example, on X11 QtOpenGL needs to delete the GLXPixmap + // or EGL Pixmap Surface for a given pixmap _before_ the native X11 pixmap is deleted, + // otherwise some drivers will leak the GL surface. In this case, QX11PixmapData will + // call the cleanup hooks itself before deleting the native pixmap and set is_cached to + // false. + if (is_cached) { + QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(this); + is_cached = false; + } } QPixmapData *QPixmapData::createCompatiblePixmapData() const diff --git a/src/gui/image/qpixmapdata_p.h b/src/gui/image/qpixmapdata_p.h index 1125515..827fa18 100644 --- a/src/gui/image/qpixmapdata_p.h +++ b/src/gui/image/qpixmapdata_p.h @@ -117,6 +117,14 @@ public: inline int colorCount() const { return metric(QPaintDevice::PdmNumColors); } inline int depth() const { return d; } inline bool isNull() const { return is_null; } + inline qint64 cacheKey() const { + int classKey = id; + if (classKey >= 1024) + classKey = -(classKey >> 10); + return ((((qint64) classKey) << 56) + | (((qint64) ser_no) << 32) + | ((qint64) detach_no)); + } #if defined(Q_OS_SYMBIAN) virtual void* toNativeType(NativeType type); diff --git a/src/gui/image/qpixmapfilter.cpp b/src/gui/image/qpixmapfilter.cpp index 37a6a18..2792e45 100644 --- a/src/gui/image/qpixmapfilter.cpp +++ b/src/gui/image/qpixmapfilter.cpp @@ -422,6 +422,9 @@ void QPixmapConvolutionFilter::draw(QPainter *painter, const QPointF &p, const Q if(d->kernelWidth<=0 || d->kernelHeight <= 0) return; + if (src.isNull()) + return; + QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ? static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0; QPixmapConvolutionFilter *convolutionFilter = static_cast<QPixmapConvolutionFilter*>(filter); @@ -710,7 +713,8 @@ void expblur(QImage &img, qreal radius, bool improvedQuality = false, int transp radius *= qreal(0.5); Q_ASSERT(img.format() == QImage::Format_ARGB32_Premultiplied - || img.format() == QImage::Format_RGB32); + || img.format() == QImage::Format_RGB32 + || img.format() == QImage::Format_Indexed8); // choose the alpha such that pixels at radius distance from a fully // saturated pixel will have an alpha component of no greater than @@ -902,6 +906,9 @@ void QPixmapBlurFilter::draw(QPainter *painter, const QPointF &p, const QPixmap if (!painter->isActive()) return; + if (src.isNull()) + return; + QRectF srcRect = rect; if (srcRect.isNull()) srcRect = src.rect(); @@ -1082,6 +1089,10 @@ void QPixmapColorizeFilter::setStrength(qreal strength) void QPixmapColorizeFilter::draw(QPainter *painter, const QPointF &dest, const QPixmap &src, const QRectF &srcRect) const { Q_D(const QPixmapColorizeFilter); + + if (src.isNull()) + return; + QPixmapFilter *filter = painter->paintEngine() && painter->paintEngine()->isExtended() ? static_cast<QPaintEngineEx *>(painter->paintEngine())->pixmapFilter(type(), this) : 0; QPixmapColorizeFilter *colorizeFilter = static_cast<QPixmapColorizeFilter*>(filter); @@ -1312,6 +1323,10 @@ void QPixmapDropShadowFilter::draw(QPainter *p, const QRectF &src) const { Q_D(const QPixmapDropShadowFilter); + + if (px.isNull()) + return; + QPixmapFilter *filter = p->paintEngine() && p->paintEngine()->isExtended() ? static_cast<QPaintEngineEx *>(p->paintEngine())->pixmapFilter(type(), this) : 0; QPixmapDropShadowFilter *dropShadowFilter = static_cast<QPixmapDropShadowFilter*>(filter); diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h index f5034fc..d5243c3 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_p.h +++ b/src/gui/inputmethod/qcoefepinputcontext_p.h @@ -96,7 +96,7 @@ protected: void timerEvent(QTimerEvent *timerEvent); private: - void commitCurrentString(bool triggeredBySymbian); + void commitCurrentString(bool cancelFepTransaction); void updateHints(bool mustUpdateInputCapabilities); void applyHints(Qt::InputMethodHints hints); void applyFormat(QList<QInputMethodEvent::Attribute> *attributes); @@ -127,7 +127,7 @@ public: private: void DoCommitFepInlineEditL(); MCoeFepAwareTextEditor_Extension1* Extension1(TBool& aSetToTrue); - void ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType); + void ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType); // From MCoeFepAwareTextEditor_Extension1 public: @@ -151,7 +151,6 @@ private: int m_inlinePosition; MFepInlineTextFormatRetriever *m_formatRetriever; MFepPointerEventHandlerDuringInlineEdit *m_pointerHandler; - int m_longPress; int m_cursorPos; QBasicTimer m_tempPreeditStringTimeout; bool m_hasTempPreeditString; diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 793bcde..2b91711 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -71,7 +71,6 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent) m_inlinePosition(0), m_formatRetriever(0), m_pointerHandler(0), - m_longPress(0), m_cursorPos(0), m_hasTempPreeditString(false) { @@ -101,11 +100,7 @@ QCoeFepInputContext::~QCoeFepInputContext() void QCoeFepInputContext::reset() { - commitTemporaryPreeditString(); - - CCoeFep* fep = CCoeEnv::Static()->Fep(); - if (fep) - fep->CancelTransaction(); + commitCurrentString(true); } void QCoeFepInputContext::ReportAknEdStateEvent(MAknEdStateObserver::EAknEdwinStateEvent aEventType) @@ -130,7 +125,7 @@ void QCoeFepInputContext::update() void QCoeFepInputContext::setFocusWidget(QWidget *w) { - commitCurrentString(false); + commitCurrentString(true); QInputContext::setFocusWidget(w); @@ -223,7 +218,7 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) break; case Qt::Key_Select: if (!m_preeditString.isEmpty()) { - commitCurrentString(false); + commitCurrentString(true); return true; } break; @@ -235,10 +230,11 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) && focusWidget()->inputMethodHints() & Qt::ImhHiddenText && !keyEvent->text().isEmpty()) { // Send some temporary preedit text in order to make text visible for a moment. + m_cursorPos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt(); m_preeditString = keyEvent->text(); QList<QInputMethodEvent::Attribute> attributes; QInputMethodEvent imEvent(m_preeditString, attributes); - QApplication::sendEvent(focusWidget(), &imEvent); + sendEvent(imEvent); m_tempPreeditStringTimeout.start(1000, this); m_hasTempPreeditString = true; update(); @@ -290,7 +286,6 @@ void QCoeFepInputContext::commitTemporaryPreeditString() return; commitCurrentString(false); - m_hasTempPreeditString = false; } void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event) @@ -298,7 +293,7 @@ void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event) Q_ASSERT(focusWidget()); if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::LeftButton) { - commitCurrentString(false); + commitCurrentString(true); int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt(); QList<QInputMethodEvent::Attribute> attributes; @@ -744,30 +739,33 @@ void QCoeFepInputContext::GetScreenCoordinatesForFepL(TPoint& aLeftSideOfBaseLin void QCoeFepInputContext::DoCommitFepInlineEditL() { - commitCurrentString(true); + commitCurrentString(false); } -void QCoeFepInputContext::commitCurrentString(bool triggeredBySymbian) +void QCoeFepInputContext::commitCurrentString(bool cancelFepTransaction) { + int longPress = 0; + if (m_preeditString.size() == 0) { QWidget *w = focusWidget(); - if (triggeredBySymbian && w) { + if (!cancelFepTransaction && w) { // We must replace the last character only if the input box has already accepted one if (w->inputMethodQuery(Qt::ImCursorPosition).toInt() != m_cursorPos) - m_longPress = 1; + longPress = 1; } return; } QList<QInputMethodEvent::Attribute> attributes; QInputMethodEvent event(QLatin1String(""), attributes); - event.setCommitString(m_preeditString, 0-m_longPress, m_longPress); + event.setCommitString(m_preeditString, 0-longPress, longPress); m_preeditString.clear(); sendEvent(event); - m_longPress = 0; + m_hasTempPreeditString = false; + longPress = 0; - if (!triggeredBySymbian) { + if (cancelFepTransaction) { CCoeFep* fep = CCoeEnv::Static()->Fep(); if (fep) fep->CancelTransaction(); diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp index 360ed14..fcc61e5 100644 --- a/src/gui/itemviews/qfileiconprovider.cpp +++ b/src/gui/itemviews/qfileiconprovider.cpp @@ -65,6 +65,7 @@ #ifndef SHGFI_ADDOVERLAYS # define SHGFI_ADDOVERLAYS 0x000000020 +# define SHGFI_OVERLAYINDEX 0x000000040 #endif QT_BEGIN_NAMESPACE @@ -248,7 +249,7 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const //Get the small icon #ifndef Q_OS_WINCE val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, - sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS); + sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX); #else val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, sizeof(SHFILEINFO), SHGFI_SMALLICON|SHGFI_SYSICONINDEX); @@ -287,7 +288,7 @@ QIcon QFileIconProviderPrivate::getWinIcon(const QFileInfo &fileInfo) const //Get the big icon #ifndef Q_OS_WINCE val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, - sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS); + sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_LARGEICON|SHGFI_SYSICONINDEX|SHGFI_ADDOVERLAYS|SHGFI_OVERLAYINDEX); #else val = SHGetFileInfo((const wchar_t *)QDir::toNativeSeparators(fileInfo.filePath()).utf16(), 0, &info, sizeof(SHFILEINFO), SHGFI_LARGEICON|SHGFI_SYSICONINDEX); diff --git a/src/gui/itemviews/qitemdelegate.cpp b/src/gui/itemviews/qitemdelegate.cpp index 6fd26a7..9069ce4 100644 --- a/src/gui/itemviews/qitemdelegate.cpp +++ b/src/gui/itemviews/qitemdelegate.cpp @@ -1033,7 +1033,7 @@ static QString qPixmapSerial(quint64 i, bool enabled) i >>= 4; } - return QString::fromUtf16(ptr, int(&arr[sizeof(arr) / sizeof(ushort)] - ptr)); + return QString((const QChar *)ptr, int(&arr[sizeof(arr) / sizeof(ushort)] - ptr)); } /*! diff --git a/src/gui/itemviews/qlistview.cpp b/src/gui/itemviews/qlistview.cpp index 19b1e8c..b2def39 100644 --- a/src/gui/itemviews/qlistview.cpp +++ b/src/gui/itemviews/qlistview.cpp @@ -2160,7 +2160,7 @@ void QListModeViewBase::scrollContentsBy(int dx, int dy, bool scrollElasticBand) } else { if (flowPositions.isEmpty()) return; - const int max = flowPositions.count() - 1; + const int max = scrollValueMap.count() - 1; if (vertical && flow() == QListView::TopToBottom && dy != 0) { int currentValue = qBound(0, verticalValue, max); int previousValue = qBound(0, currentValue + dy, max); diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index 7eefb0b..3111896 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -114,7 +114,9 @@ void QSpanCollection::updateSpan(QSpanCollection::Span *span, int old_height) } } else if (old_height > span->height()) { //remove the span from all the subspans lists that intersect the columns not covered anymore - Index::iterator it_y = index.lowerBound(qMin(-span->bottom(), 0)); + Index::iterator it_y = index.lowerBound(-span->bottom()); + if (it_y == index.end()) + it_y = index.find(-span->top()); // This is the only span remaining and we are deleting it. Q_ASSERT(it_y != index.end()); //it_y must exist since the span is in the list while (-it_y.key() <= span->top() + old_height -1) { if (-it_y.key() > span->bottom()) { diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index f2bd288..0993b86 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -7,7 +7,7 @@ PRECOMPILED_HEADER = kernel/qt_gui_pch.h KERNEL_P= kernel HEADERS += \ kernel/qaction.h \ - kernel/qaction_p.h \ + kernel/qaction_p.h \ kernel/qactiongroup.h \ kernel/qapplication.h \ kernel/qapplication_p.h \ @@ -37,8 +37,8 @@ HEADERS += \ kernel/qstackedlayout.h \ kernel/qtooltip.h \ kernel/qwhatsthis.h \ - kernel/qwidget.h \ - kernel/qwidget_p.h \ + kernel/qwidget.h \ + kernel/qwidget_p.h \ kernel/qwidgetaction.h \ kernel/qwidgetaction_p.h \ kernel/qwindowdefs.h \ @@ -49,6 +49,7 @@ HEADERS += \ kernel/qgesturerecognizer.h \ kernel/qgesturemanager_p.h \ kernel/qsoftkeymanager_p.h \ + kernel/qsoftkeymanager_common_p.h \ kernel/qguiplatformplugin_p.h SOURCES += \ @@ -84,14 +85,14 @@ SOURCES += \ kernel/qgesturerecognizer.cpp \ kernel/qgesturemanager.cpp \ kernel/qsoftkeymanager.cpp \ - kernel/qdesktopwidget.cpp \ + kernel/qdesktopwidget.cpp \ kernel/qguiplatformplugin.cpp win32 { DEFINES += QT_NO_DIRECTDRAW - HEADERS += \ - kernel/qwinnativepangesturerecognizer_win_p.h + HEADERS += \ + kernel/qwinnativepangesturerecognizer_win_p.h SOURCES += \ kernel/qapplication_win.cpp \ @@ -103,30 +104,34 @@ win32 { kernel/qsound_win.cpp \ kernel/qwidget_win.cpp \ kernel/qole_win.cpp \ - kernel/qkeymapper_win.cpp \ - kernel/qwinnativepangesturerecognizer_win.cpp + kernel/qkeymapper_win.cpp \ + kernel/qwinnativepangesturerecognizer_win.cpp - !contains(DEFINES, QT_NO_DIRECTDRAW):LIBS += ddraw.lib + !contains(DEFINES, QT_NO_DIRECTDRAW):LIBS += ddraw.lib } symbian { - SOURCES += \ - kernel/qapplication_s60.cpp \ - kernel/qeventdispatcher_s60.cpp \ - kernel/qwidget_s60.cpp \ - kernel/qcursor_s60.cpp \ - kernel/qdesktopwidget_s60.cpp \ - kernel/qkeymapper_s60.cpp\ - kernel/qclipboard_s60.cpp\ - kernel/qdnd_s60.cpp \ - kernel/qsound_s60.cpp + SOURCES += \ + kernel/qapplication_s60.cpp \ + kernel/qeventdispatcher_s60.cpp \ + kernel/qwidget_s60.cpp \ + kernel/qcursor_s60.cpp \ + kernel/qdesktopwidget_s60.cpp \ + kernel/qkeymapper_s60.cpp\ + kernel/qclipboard_s60.cpp\ + kernel/qdnd_s60.cpp \ + kernel/qsound_s60.cpp \ + kernel/qsoftkeymanager_s60.cpp - HEADERS += \ - kernel/qt_s60_p.h \ - kernel/qeventdispatcher_s60_p.h - LIBS += -lbafl -lestor + HEADERS += \ + kernel/qt_s60_p.h \ + kernel/qeventdispatcher_s60_p.h \ + kernel/qsoftkeymanager_s60_p.h + + LIBS += -lbafl -lestor - INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE + INCLUDEPATH += $$MW_LAYER_SYSTEMINCLUDE + INCLUDEPATH += ../3rdparty/s60 } diff --git a/src/gui/kernel/qaction.cpp b/src/gui/kernel/qaction.cpp index 4b7d949..8ddd051 100644 --- a/src/gui/kernel/qaction.cpp +++ b/src/gui/kernel/qaction.cpp @@ -715,6 +715,10 @@ QActionGroup *QAction::actionGroup() const it is displayed to the left of the menu text. There is no default icon. + On Symbian the icons which are passed to softkeys, i.e. to actions with + softkey role, need to have pixmap alpha channel correctly set otherwise + drawing artifacts will appear when softkey is pressed down. + If a null icon (QIcon::isNull() is passed into this function, the icon of the action is cleared. */ diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 12fe797..4fe3900 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -121,8 +121,10 @@ extern bool qt_wince_is_pocket_pc(); //qguifunctions_wince.cpp static void initResources() { -#ifdef Q_WS_WINCE +#if defined(Q_WS_WINCE) Q_INIT_RESOURCE(qstyle_wince); +#elif defined(Q_OS_SYMBIAN) + Q_INIT_RESOURCE(qstyle_s60); #else Q_INIT_RESOURCE(qstyle); #endif diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index 6aebef5..54a4901 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -227,8 +227,29 @@ void onApplicationChangedActivation( bool activated ); static void qt_mac_read_fontsmoothing_settings() { - NSInteger appleFontSmoothing = [[NSUserDefaults standardUserDefaults] integerForKey:@"AppleFontSmoothing"]; - qt_applefontsmoothing_enabled = (appleFontSmoothing > 0); + qt_applefontsmoothing_enabled = true; + int w = 10, h = 10; + QImage image(w, h, QImage::Format_RGB32); + image.fill(0xffffffff); + QPainter p(&image); + p.drawText(0, h, "X\\"); + p.end(); + + const int *bits = (const int *) ((const QImage &) image).bits(); + int bpl = image.bytesPerLine() / 4; + for (int y=0; y<w; ++y) { + for (int x=0; x<h; ++x) { + int r = qRed(bits[x]); + int g = qGreen(bits[x]); + int b = qBlue(bits[x]); + if (r != g || r != b) { + qt_applefontsmoothing_enabled = true; + return; + } + } + bits += bpl; + } + qt_applefontsmoothing_enabled = false; } Q_GUI_EXPORT bool qt_mac_execute_apple_script(const char *script, long script_len, AEDesc *ret) { @@ -772,11 +793,11 @@ static void qt_mac_update_intersected_gl_widgets(QWidget *widget) qt_post_window_change_event(glWidget); it->lastUpdateWidget = widget; } else if (it->lastUpdateWidget == widget) { - // Update the gl wigets that the widget intersected the last time around, - // and that we are not intersecting now. This prevents paint errors when the + // Update the gl wigets that the widget intersected the last time around, + // and that we are not intersecting now. This prevents paint errors when the // intersecting widget leaves a gl widget. qt_post_window_change_event(glWidget); - it->lastUpdateWidget = 0; + it->lastUpdateWidget = 0; } } #else @@ -808,8 +829,8 @@ Q_GUI_EXPORT void qt_event_request_window_change(QWidget *widget) // Post a kEventQtRequestWindowChange event. This event is semi-public, // don't remove this line! qt_event_request_window_change(); - - // Post update request on gl widgets unconditionally. + + // Post update request on gl widgets unconditionally. if (qt_widget_private(widget)->isGLWidget == true) { qt_post_window_change_event(widget); return; @@ -1214,8 +1235,6 @@ void qt_init(QApplicationPrivate *priv, int) if (QApplication::desktopSettingsAware()) QApplicationPrivate::qt_mac_apply_settings(); - qt_mac_read_fontsmoothing_settings(); - // Cocoa application delegate #ifdef QT_MAC_USE_COCOA NSApplication *cocoaApp = [NSApplication sharedApplication]; @@ -1253,6 +1272,7 @@ void qt_init(QApplicationPrivate *priv, int) } priv->native_modal_dialog_active = false; + qt_mac_read_fontsmoothing_settings(); } void qt_release_apple_event_handler() @@ -1705,7 +1725,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event // kEventMouseWheelMoved events if we dont eat this event // (actually two events; one for horizontal and one for vertical). // As a results of this, and to make sure we dont't receive duplicate events, - // we try to detect when this happend by checking the 'compatibilityEvent'. + // we try to detect when this happend by checking the 'compatibilityEvent'. SInt32 mdelt = 0; GetEventParameter(event, kEventParamMouseWheelSmoothHorizontalDelta, typeSInt32, 0, sizeof(mdelt), 0, &mdelt); @@ -2123,6 +2143,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event } if (wheel_deltaX || wheel_deltaY) { +#ifndef QT_NO_WHEELEVENT if (wheel_deltaX) { QWheelEvent qwe(plocal, p, wheel_deltaX, buttons, modifiers, Qt::Horizontal); QApplication::sendSpontaneousEvent(widget, &qwe); @@ -2145,6 +2166,7 @@ QApplicationPrivate::globalEventProcessor(EventHandlerCallRef er, EventRef event handled_event = false; } } +#endif // QT_NO_WHEELEVENT } else { #ifdef QMAC_SPEAK_TO_ME const int speak_keys = Qt::AltModifier | Qt::ShiftModifier; @@ -2576,7 +2598,7 @@ void QApplicationPrivate::closePopup(QWidget *popup) if (QApplicationPrivate::popupWidgets->isEmpty()) { // this was the last popup delete QApplicationPrivate::popupWidgets; QApplicationPrivate::popupWidgets = 0; - + // Special case for Tool windows: since they are activated and deactived together // with a normal window they never become the QApplicationPrivate::active_window. QWidget *appFocusWidget = QApplication::focusWidget(); @@ -2697,6 +2719,7 @@ int QApplication::keyboardInputInterval() return QApplicationPrivate::keyboard_input_time; } +#ifndef QT_NO_WHEELEVENT void QApplication::setWheelScrollLines(int n) { QApplicationPrivate::wheel_scroll_lines = n; @@ -2706,6 +2729,7 @@ int QApplication::wheelScrollLines() { return QApplicationPrivate::wheel_scroll_lines; } +#endif void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) { @@ -2868,9 +2892,11 @@ bool QApplicationPrivate::qt_mac_apply_settings() QApplication::cursorFlashTime()).toInt(); QApplication::setCursorFlashTime(num); +#ifndef QT_NO_WHEELEVENT num = settings.value(QLatin1String("wheelScrollLines"), QApplication::wheelScrollLines()).toInt(); QApplication::setWheelScrollLines(num); +#endif QString colorspec = settings.value(QLatin1String("colorSpec"), QVariant(QLatin1String("default"))).toString(); diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 9c001ab..b3ec732 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -427,7 +427,9 @@ public: static int cursor_flash_time; static int mouse_double_click_time; static int keyboard_input_time; +#ifndef QT_NO_WHEELEVENT static int wheel_scroll_lines; +#endif static bool animate_ui; static bool animate_menu; diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index d9cf45d..cc12a65 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -809,12 +809,15 @@ TCoeInputCapabilities QSymbianControl::InputCapabilities() const void QSymbianControl::Draw(const TRect& controlRect) const { // Set flag to avoid calling DrawNow in window surface - QWExtra *extra = qwidget->d_func()->extraData(); - if (extra && !extra->inExpose) { - extra->inExpose = true; + QWidget *window = qwidget->window(); + Q_ASSERT(window); + QTLWExtra *topExtra = window->d_func()->maybeTopData(); + Q_ASSERT(topExtra); + if (!topExtra->inExpose) { + topExtra->inExpose = true; QRect exposeRect = qt_TRect2QRect(controlRect); qwidget->d_func()->syncBackingStore(exposeRect); - extra->inExpose = false; + topExtra->inExpose = false; } QWindowSurface *surface = qwidget->windowSurface(); @@ -924,8 +927,8 @@ void QSymbianControl::PositionChanged() cr.moveTopLeft(newPos); qwidget->data->crect = cr; QTLWExtra *top = qwidget->d_func()->maybeTopData(); - if (top) - top->normalGeometry = cr; + if (top && (qwidget->windowState() & (~Qt::WindowActive)) == Qt::WindowNoState) + top->normalGeometry.moveTopLeft(newPos); if (qwidget->isVisible()) { QMoveEvent e(newPos, oldPos); qt_sendSpontaneousEvent(qwidget, &e); @@ -960,15 +963,14 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */) qwidget->d_func()->setWindowIcon_sys(true); qwidget->d_func()->setWindowTitle_sys(qwidget->windowTitle()); #ifdef Q_WS_S60 - // If widget is fullscreen, hide status pane and button container - // otherwise show them. + // If widget is fullscreen/minimized, hide status pane and button container otherwise show them. CEikStatusPane* statusPane = S60->statusPane(); CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer(); - bool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen; - if (statusPane && (bool)statusPane->IsVisible() == isFullscreen) - statusPane->MakeVisible(!isFullscreen); - if (buttonGroup && (bool)buttonGroup->IsVisible() == isFullscreen) - buttonGroup->MakeVisible(!isFullscreen); + TBool visible = !(qwidget->windowState() & (Qt::WindowFullScreen | Qt::WindowMinimized)); + if (statusPane) + statusPane->MakeVisible(visible); + if (buttonGroup) + buttonGroup->MakeVisible(visible); #endif } else if (QApplication::activeWindow() == qwidget->window()) { if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) { @@ -1649,6 +1651,9 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) { delete w->d_func()->topData()->backingStore; w->d_func()->topData()->backingStore = 0; + // In order to ensure that any resources used by the window surface + // are immediately freed, we flush the WSERV command buffer. + S60->wsSession().Flush(); } else if ((visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible) && !w->d_func()->maybeBackingStore()) { w->d_func()->topData()->backingStore = new QWidgetBackingStore(w); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 3355272..0a4869b 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -928,7 +928,11 @@ const QString qt_reg_winclass(QWidget *w) // register window class uint style; bool icon; QString cname; - if (flags & Qt::MSWindowsOwnDC) { + if (qt_widget_private(w)->isGLWidget) { + cname = QLatin1String("QGLWidget"); + style = CS_DBLCLKS; + icon = true; + } else if (flags & Qt::MSWindowsOwnDC) { cname = QLatin1String("QWidgetOwnDC"); style = CS_DBLCLKS; #ifndef Q_WS_WINCE @@ -1021,7 +1025,7 @@ const QString qt_reg_winclass(QWidget *w) // register window class } wc.hCursor = 0; #ifndef Q_WS_WINCE - wc.hbrBackground = (HBRUSH)GetSysColorBrush(COLOR_WINDOW); + wc.hbrBackground = qt_widget_private(w)->isGLWidget ? 0 : (HBRUSH)GetSysColorBrush(COLOR_WINDOW); #else wc.hbrBackground = 0; #endif @@ -3616,13 +3620,19 @@ bool QETWidget::translatePaintEvent(const MSG &msg) return true; setAttribute(Qt::WA_PendingUpdate, false); - const QRegion dirtyInBackingStore(qt_dirtyRegion(this)); - // Make sure the invalidated region contains the region we're about to repaint. - // BeginPaint will set the clip to the invalidated region and it is impossible - // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient - // as it may return an invalid context (especially on Windows Vista). - if (!dirtyInBackingStore.isEmpty()) - InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false); + + if (d_func()->isGLWidget) { + if (d_func()->usesDoubleBufferedGLContext) + InvalidateRect(internalWinId(), 0, false); + } else { + const QRegion dirtyInBackingStore(qt_dirtyRegion(this)); + // Make sure the invalidated region contains the region we're about to repaint. + // BeginPaint will set the clip to the invalidated region and it is impossible + // to enlarge it afterwards (only shrink it). Using GetDCEx is not suffient + // as it may return an invalid context (especially on Windows Vista). + if (!dirtyInBackingStore.isEmpty()) + InvalidateRgn(internalWinId(), dirtyInBackingStore.handle(), false); + } PAINTSTRUCT ps; d_func()->hd = BeginPaint(internalWinId(), &ps); diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 2a1f655..afd927b 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -944,10 +944,12 @@ bool QApplicationPrivate::x11_apply_settings() QApplication::cursorFlashTime()).toInt(); QApplication::setCursorFlashTime(num); +#ifndef QT_NO_WHEELEVENT num = settings.value(QLatin1String("wheelScrollLines"), QApplication::wheelScrollLines()).toInt(); QApplication::setWheelScrollLines(num); +#endif QString colorspec = settings.value(QLatin1String("colorSpec"), QVariant(QLatin1String("default"))).toString(); @@ -4401,8 +4403,10 @@ bool QETWidget::translateWheelEvent(int global_x, int global_y, int delta, QWidget* popup = qApp->activePopupWidget(); if (popup && window() != popup) popup->close(); +#ifndef QT_NO_WHEELEVENT QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient); if (QApplication::sendSpontaneousEvent(widget, &e)) +#endif return true; } @@ -4413,8 +4417,10 @@ bool QETWidget::translateWheelEvent(int global_x, int global_y, int delta, QWidget* popup = qApp->activePopupWidget(); if (popup && widget != popup) popup->hide(); +#ifndef QT_NO_WHEELEVENT QWheelEvent e(pos, globalPos, delta, buttons, modifiers, orient); if (QApplication::sendSpontaneousEvent(widget, &e)) +#endif return true; } return false; @@ -5313,6 +5319,7 @@ int QApplication::keyboardInputInterval() return QApplicationPrivate::keyboard_input_time; } +#ifndef QT_NO_WHEELEVENT void QApplication::setWheelScrollLines(int n) { QApplicationPrivate::wheel_scroll_lines = n; @@ -5322,6 +5329,7 @@ int QApplication::wheelScrollLines() { return QApplicationPrivate::wheel_scroll_lines; } +#endif void QApplication::setEffectEnabled(Qt::UIEffect effect, bool enable) { diff --git a/src/gui/kernel/qclipboard_mac.cpp b/src/gui/kernel/qclipboard_mac.cpp index f3a971d..49a6cc8 100644 --- a/src/gui/kernel/qclipboard_mac.cpp +++ b/src/gui/kernel/qclipboard_mac.cpp @@ -388,6 +388,18 @@ QMacPasteboard::setMimeData(QMimeData *mime_src) clear_helper(); QStringList formats = mime_src->formats(); +#ifdef QT_MAC_USE_COCOA + // QMimeData sub classes reimplementing the formats() might not expose the + // temporary "application/x-qt-mime-type-name" mimetype. So check the existence + // of this mime type while doing drag and drop. + QString dummyMimeType(QLatin1String("application/x-qt-mime-type-name")); + if (!formats.contains(dummyMimeType)) { + QByteArray dummyType = mime_src->data(dummyMimeType); + if (!dummyType.isEmpty()) { + formats.append(dummyMimeType); + } + } +#endif for(int f = 0; f < formats.size(); ++f) { QString mimeType = formats.at(f); for (QList<QMacPasteboardMime *>::Iterator it = availableConverters.begin(); it != availableConverters.end(); ++it) { diff --git a/src/gui/kernel/qclipboard_s60.cpp b/src/gui/kernel/qclipboard_s60.cpp index 71c355b..f07e066 100644 --- a/src/gui/kernel/qclipboard_s60.cpp +++ b/src/gui/kernel/qclipboard_s60.cpp @@ -164,7 +164,8 @@ void readFromStreamLX(QMimeData* aData,RReadStream& aStream) TCardinality mimeTypeSize; aStream >> mimeTypeSize; HBufC* mimeTypeBuf = HBufC::NewLC(aStream,mimeTypeSize); - QString mimeType = QString::fromUtf16(mimeTypeBuf->Des().Ptr(),mimeTypeBuf->Length()); + QString mimeType = QString(reinterpret_cast<const QChar *>(mimeTypeBuf->Des().Ptr()), + mimeTypeBuf->Length()); CleanupStack::PopAndDestroy(mimeTypeBuf); // mime data TCardinality dataSize; diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm index 9f90cec..18b3772 100644 --- a/src/gui/kernel/qcocoamenuloader_mac.mm +++ b/src/gui/kernel/qcocoamenuloader_mac.mm @@ -110,6 +110,12 @@ QT_USE_NAMESPACE } } +- (void)removeActionsFromAppMenu +{ + for (NSMenuItem *item in [appMenu itemArray]) + [item setTag:nil]; +} + - (void)dealloc { [lastAppSpecificItem release]; diff --git a/src/gui/kernel/qcocoamenuloader_mac_p.h b/src/gui/kernel/qcocoamenuloader_mac_p.h index 432a7a6..81c136e 100644 --- a/src/gui/kernel/qcocoamenuloader_mac_p.h +++ b/src/gui/kernel/qcocoamenuloader_mac_p.h @@ -70,6 +70,7 @@ } - (void)ensureAppMenuInMenu:(NSMenu *)menu; +- (void)removeActionsFromAppMenu; - (NSMenu *)applicationMenu; - (NSMenu *)menu; - (NSMenuItem *)quitMenuItem; diff --git a/src/gui/kernel/qcocoapanel_mac.mm b/src/gui/kernel/qcocoapanel_mac.mm index e535aac..5e24c84 100644 --- a/src/gui/kernel/qcocoapanel_mac.mm +++ b/src/gui/kernel/qcocoapanel_mac.mm @@ -46,6 +46,9 @@ #import <private/qcocoawindowdelegate_mac_p.h> #import <private/qcocoaview_mac_p.h> #import <private/qcocoawindowcustomthemeframe_mac_p.h> +#include <private/qapplication_p.h> +#include <private/qbackingstore_p.h> + #include <QtGui/QWidget> diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h index 1a265d0..d2b74d7 100644 --- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h +++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h @@ -51,6 +51,9 @@ NSPanel, while QCocoaWindow needs to inherit NSWindow rather than NSPanel). ****************************************************************************/ +// WARNING: Don't include any header files from within this file. Put them +// directly into qcocoawindow_mac_p.h and qcocoapanel_mac_p.h + QT_BEGIN_NAMESPACE extern Qt::MouseButton cocoaButton2QtButton(NSInteger buttonNum); // qcocoaview.mm extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp @@ -185,3 +188,20 @@ QT_END_NAMESPACE return [super frameViewClassForStyleMask:styleMask]; } +- (void)displayIfNeeded +{ + + QWidget *qwidget = [[QT_MANGLE_NAMESPACE(QCocoaWindowDelegate) sharedDelegate] qt_qwidgetForWindow:self]; + if (qwidget == 0) { + [super displayIfNeeded]; + return; + } + + if (QApplicationPrivate::graphicsSystem() != 0) { + if (QWidgetBackingStore *bs = qt_widget_private(qwidget)->maybeBackingStore()) + bs->sync(qwidget, qwidget->rect()); + } + [super displayIfNeeded]; +} + + diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index f61d2fe..ad64a91 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -520,10 +520,11 @@ extern "C" { - (void)drawRect:(NSRect)aRect { if (QApplicationPrivate::graphicsSystem() != 0) { - if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore()) - bs->markDirty(qwidget->rect(), qwidget); - qwidgetprivate->syncBackingStore(qwidget->rect()); - return; + if (QWidgetBackingStore *bs = qwidgetprivate->maybeBackingStore()) { + // Drawing is handled on the window level + // See qcocoasharedwindowmethods_mac_p. + return; + } } CGContextRef cg = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; qwidgetprivate->hd = cg; @@ -644,6 +645,8 @@ extern "C" { - (void)mouseEntered:(NSEvent *)event { + if (qwidgetprivate->data.in_destructor) + return; QEvent enterEvent(QEvent::Enter); NSPoint windowPoint = [event locationInWindow]; NSPoint globalPoint = [[event window] convertBaseToScreen:windowPoint]; @@ -825,6 +828,7 @@ extern "C" { deltaZ = qBound(-120, int([theEvent deltaZ] * 10000), 120); } +#ifndef QT_NO_WHEELEVENT if (deltaX != 0) { QWheelEvent qwe(qlocal, qglobal, deltaX, buttons, keyMods, Qt::Horizontal); qt_sendSpontaneousEvent(widgetToGetMouse, &qwe); @@ -865,6 +869,8 @@ extern "C" { wheelOK = qwe2.isAccepted(); } } +#endif //QT_NO_WHEELEVENT + if (!wheelOK) { return [super scrollWheel:theEvent]; } @@ -1401,7 +1407,7 @@ Qt::DropAction QDragManager::drag(QDrag *o) // setup the data QMacPasteboard dragBoard((CFStringRef) NSDragPboard, QMacPasteboardMime::MIME_DND); - dragPrivate()->data->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray()); + dragPrivate()->data->setData(QLatin1String("application/x-qt-mime-type-name"), QByteArray("dummy")); dragBoard.setMimeData(dragPrivate()->data); // create the image diff --git a/src/gui/kernel/qcocoawindow_mac_p.h b/src/gui/kernel/qcocoawindow_mac_p.h index c0d8252..0474882 100644 --- a/src/gui/kernel/qcocoawindow_mac_p.h +++ b/src/gui/kernel/qcocoawindow_mac_p.h @@ -53,6 +53,9 @@ #ifdef QT_MAC_USE_COCOA #include "qmacdefines_mac.h" #import <Cocoa/Cocoa.h> +#include <private/qapplication_p.h> +#include <private/qbackingstore_p.h> + enum { QtMacCustomizeWindow = 1 << 21 }; // This will one day be run over by diff --git a/src/gui/kernel/qdesktopwidget_s60.cpp b/src/gui/kernel/qdesktopwidget_s60.cpp index 77745ea..84e3c5d 100644 --- a/src/gui/kernel/qdesktopwidget_s60.cpp +++ b/src/gui/kernel/qdesktopwidget_s60.cpp @@ -88,24 +88,20 @@ QDesktopWidgetPrivate::~QDesktopWidgetPrivate() void QDesktopWidgetPrivate::init(QDesktopWidget *that) { - int screenCount=0; +// int screenCount=0; - if (HAL::Get(0, HALData::EDisplayNumberOfScreens, screenCount) == KErrNone) - QDesktopWidgetPrivate::screenCount = screenCount; - else - QDesktopWidgetPrivate::screenCount = 0; + // ### TODO: Implement proper multi-display support + QDesktopWidgetPrivate::screenCount = 1; +// if (HAL::Get(0, HALData::EDisplayNumberOfScreens, screenCount) == KErrNone) +// QDesktopWidgetPrivate::screenCount = screenCount; +// else +// QDesktopWidgetPrivate::screenCount = 0; rects = new QVector<QRect>(); workrects = new QVector<QRect>(); rects->resize(QDesktopWidgetPrivate::screenCount); workrects->resize(QDesktopWidgetPrivate::screenCount); - - // ### TODO: Implement proper multi-display support - rects->resize(1); - rects->replace(0, that->rect()); - workrects->resize(1); - workrects->replace(0, that->rect()); } void QDesktopWidgetPrivate::cleanup() diff --git a/src/gui/kernel/qdnd_x11.cpp b/src/gui/kernel/qdnd_x11.cpp index edab6a0..33968bd 100644 --- a/src/gui/kernel/qdnd_x11.cpp +++ b/src/gui/kernel/qdnd_x11.cpp @@ -617,7 +617,7 @@ QVariant QX11Data::xdndMimeConvertToFormat(Atom a, const QByteArray &data, const // so it should be safe to check that the second char is 0 // to verify that it is utf16 if (data.size() > 1 && data.at(1) == 0) - return QString::fromUtf16(reinterpret_cast<const ushort *>(data.constData()), + return QString::fromRawData((const QChar *)data.constData(), data.size() / 2).split(QLatin1Char('\n')).first().toLatin1(); } } diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm index eda75db..c7c7caf 100644 --- a/src/gui/kernel/qeventdispatcher_mac.mm +++ b/src/gui/kernel/qeventdispatcher_mac.mm @@ -569,7 +569,7 @@ bool QEventDispatcherMac::processEvents(QEventLoop::ProcessEventsFlags flags) // in cocoa. [NSApp run] should be called at least once for any cocoa app. if (NSModalSession session = d->currentModalSession()) { QBoolBlocker execGuard(d->currentExecIsNSAppRun, false); - while (!d->interrupt && [NSApp runModalSession:session] == NSRunContinuesResponse) + while ([NSApp runModalSession:session] == NSRunContinuesResponse && !d->interrupt) qt_mac_waitForMoreModalSessionEvents(); if (!d->interrupt && session == d->currentModalSessionCached) { // INVARIANT: Someone called e.g. [NSApp stopModal:] from outside the event diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/gui/kernel/qkeymapper_x11.cpp index 70574e7..4e6c847 100644 --- a/src/gui/kernel/qkeymapper_x11.cpp +++ b/src/gui/kernel/qkeymapper_x11.cpp @@ -360,6 +360,13 @@ QList<int> QKeyMapperPrivate::possibleKeysXKB(QKeyEvent *event) if (code && code < 0xfffe) code = QChar(code).toUpper().unicode(); + + if (code == Qt::Key_Tab && (baseModifiers & Qt::ShiftModifier)) { + // map shift+tab to shift+backtab + code = Qt::Key_Backtab; + text = QString(); + } + if (code == baseCode) continue; @@ -448,6 +455,13 @@ QList<int> QKeyMapperPrivate::possibleKeysCore(QKeyEvent *event) if (code && code < 0xfffe) code = QChar(code).toUpper().unicode(); + + if (code == Qt::Key_Tab && (baseModifiers & Qt::ShiftModifier)) { + // map shift+tab to shift+backtab + code = Qt::Key_Backtab; + text = QString(); + } + if (code == baseCode) continue; diff --git a/src/gui/kernel/qmime_mac.cpp b/src/gui/kernel/qmime_mac.cpp index 0431f2f..071f80d 100644 --- a/src/gui/kernel/qmime_mac.cpp +++ b/src/gui/kernel/qmime_mac.cpp @@ -431,8 +431,8 @@ QVariant QMacPasteboardMimeUnicodeText::convertToMime(const QString &mimetype, Q firstData.size(), CFStringGetSystemEncoding(), false)); ret = QString(str); } else if (flavor == QLatin1String("public.utf16-plain-text")) { - ret = QString::fromUtf16(reinterpret_cast<const ushort *>(firstData.constData()), - firstData.size() / sizeof(ushort)); + ret = QString(reinterpret_cast<const QChar *>(firstData.constData()), + firstData.size() / sizeof(QChar)); } else { qWarning("QMime::convertToMime: unhandled mimetype: %s", qPrintable(mimetype)); } diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index 354f90b..6d108b0 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -41,34 +41,18 @@ #include "qapplication.h" #include "qevent.h" -#ifdef Q_WS_S60 -#include "qstyle.h" -#include "private/qt_s60_p.h" -#endif +#include "qbitmap.h" #include "private/qsoftkeymanager_p.h" #include "private/qobject_p.h" - -#ifndef QT_NO_SOFTKEYMANAGER -QT_BEGIN_NAMESPACE +#include "private/qsoftkeymanager_common_p.h" #ifdef Q_WS_S60 -static const int s60CommandStart = 6000; +#include "private/qsoftkeymanager_s60_p.h" #endif -class QSoftKeyManagerPrivate : public QObjectPrivate -{ - Q_DECLARE_PUBLIC(QSoftKeyManager) - -public: - static void updateSoftKeys_sys(const QList<QAction*> &softKeys); - -private: - QHash<QAction*, Qt::Key> keyedActions; - static QSoftKeyManager *self; - static QWidget *softKeySource; -}; +#ifndef QT_NO_SOFTKEYMANAGER +QT_BEGIN_NAMESPACE -QWidget *QSoftKeyManagerPrivate::softKeySource = 0; QSoftKeyManager *QSoftKeyManagerPrivate::self = 0; const char *QSoftKeyManager::standardSoftKeyText(StandardSoftKey standardKey) @@ -105,7 +89,12 @@ QSoftKeyManager *QSoftKeyManager::instance() return QSoftKeyManagerPrivate::self; } -QSoftKeyManager::QSoftKeyManager() : QObject(*(new QSoftKeyManagerPrivate), 0) +QSoftKeyManager::QSoftKeyManager() : +#ifdef Q_WS_S60 + QObject(*(new QSoftKeyManagerPrivateS60), 0) +#else + QObject(*(new QSoftKeyManagerPrivate), 0) +#endif { } @@ -115,10 +104,11 @@ QAction *QSoftKeyManager::createAction(StandardSoftKey standardKey, QWidget *act QAction *action = new QAction(QSoftKeyManager::tr(text), actionWidget); QAction::SoftKeyRole softKeyRole = QAction::NoSoftKey; switch (standardKey) { + case MenuSoftKey: // FALL-THROUGH + action->setProperty(MENU_ACTION_PROPERTY, QVariant(true)); // TODO: can be refactored away to use _q_action_menubar case OkSoftKey: case SelectSoftKey: case DoneSoftKey: - case MenuSoftKey: softKeyRole = QAction::PositiveSoftKey; break; case CancelSoftKey: @@ -147,7 +137,7 @@ QAction *QSoftKeyManager::createKeyedAction(StandardSoftKey standardKey, Qt::Key #endif //QT_NO_ACTION } -void QSoftKeyManager::cleanupHash(QObject* obj) +void QSoftKeyManager::cleanupHash(QObject *obj) { Q_D(QSoftKeyManager); QAction *action = qobject_cast<QAction*>(obj); @@ -175,137 +165,78 @@ void QSoftKeyManager::updateSoftKeys() QApplication::postEvent(QSoftKeyManager::instance(), event); } -bool QSoftKeyManager::event(QEvent *e) +bool QSoftKeyManager::appendSoftkeys(const QWidget &source, int level) { -#ifndef QT_NO_ACTION - if (e->type() == QEvent::UpdateSoftKeys) { - QList<QAction*> softKeys; - QWidget *source = QApplication::focusWidget(); - do { - if (source) { - QList<QAction*> actions = source->actions(); - for (int i = 0; i < actions.count(); ++i) { - if (actions.at(i)->softKeyRole() != QAction::NoSoftKey) - softKeys.append(actions.at(i)); - } - - QWidget *parent = source->parentWidget(); - if (parent && softKeys.isEmpty() && !source->isWindow()) - source = parent; - else - break; - } else { - source = QApplication::activeWindow(); - } - } while (source); - - QSoftKeyManagerPrivate::softKeySource = source; - QSoftKeyManagerPrivate::updateSoftKeys_sys(softKeys); - return true; + Q_D(QSoftKeyManager); + bool ret = false; + QList<QAction*> actions = source.actions(); + for (int i = 0; i < actions.count(); ++i) { + if (actions.at(i)->softKeyRole() != QAction::NoSoftKey) { + d->requestedSoftKeyActions.insert(level, actions.at(i)); + ret = true; + } } -#endif //QT_NO_ACTION - return false; + return ret; } -#ifdef Q_WS_S60 -void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys) +QWidget *QSoftKeyManager::softkeySource(QWidget *previousSource, bool& recursiveMerging) { - // lets not update softkeys if s60 native dialog or menu is shown - if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes) - || CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog()) - return; - - CEikButtonGroupContainer* nativeContainer = S60->buttonGroupContainer(); - nativeContainer->DrawableWindow()->SetOrdinalPosition(0); - nativeContainer->DrawableWindow()->SetPointerCapturePriority(1); //keep softkeys available in modal dialog - nativeContainer->DrawableWindow()->SetFaded(EFalse, RWindowTreeNode::EFadeIncludeChildren); - - int position = -1; - bool needsExitButton = true; - QT_TRAP_THROWING( - //Using -1 instead of EAknSoftkeyEmpty to avoid flickering. - nativeContainer->SetCommandL(0, -1, KNullDesC); - nativeContainer->SetCommandL(2, -1, KNullDesC); - ); - - for (int index = 0; index < softkeys.count(); index++) { - const QAction* softKeyAction = softkeys.at(index); - switch (softKeyAction->softKeyRole()) { - // Positive Actions on the LSK - case QAction::PositiveSoftKey: - position = 0; - break; - case QAction::SelectSoftKey: - position = 0; - break; - // Negative Actions on the RSK - case QAction::NegativeSoftKey: - needsExitButton = false; - position = 2; - break; - default: - break; - } - - int command = (softKeyAction->objectName().contains(QLatin1String("_q_menuSoftKeyAction"))) - ? EAknSoftkeyOptions - : s60CommandStart + index; - - // _q_menuSoftKeyAction action is set to "invisible" and all invisible actions are by default - // disabled. However we never want to dim options softkey, even it is set to "invisible" - bool dimmed = (command == EAknSoftkeyOptions) ? false : !softKeyAction->isEnabled(); - - if (position != -1) { - const int underlineShortCut = QApplication::style()->styleHint(QStyle::SH_UnderlineShortcut); - QString iconText = softKeyAction->iconText(); - TPtrC text = qt_QString2TPtrC( underlineShortCut ? softKeyAction->text() : iconText); - QT_TRAP_THROWING( - nativeContainer->SetCommandL(position, command, text); - nativeContainer->DimCommand(command, dimmed); - ); - } + Q_D(QSoftKeyManager); + QWidget *source = NULL; + if (!previousSource) { + // Initial source is primarily focuswidget and secondarily activeWindow + source = QApplication::focusWidget(); + if (!source) + source = QApplication::activeWindow(); + } else { + // Softkey merging is based on four criterias + // 1. Implicit merging is used whenever focus widget does not specify any softkeys + bool implicitMerging = d->requestedSoftKeyActions.isEmpty(); + // 2. Explicit merging with parent is used whenever WA_MergeSoftkeys widget attribute is set + bool explicitMerging = previousSource->testAttribute(Qt::WA_MergeSoftkeys); + // 3. Explicit merging with all parents + recursiveMerging |= previousSource->testAttribute(Qt::WA_MergeSoftkeysRecursively); + // 4. Implicit and explicit merging always stops at window boundary + bool merging = (implicitMerging || explicitMerging || recursiveMerging) && !previousSource->isWindow(); + + source = merging ? previousSource->parentWidget() : NULL; } - - const Qt::WindowType sourceWindowType = QSoftKeyManagerPrivate::softKeySource - ? QSoftKeyManagerPrivate::softKeySource->window()->windowType() - : Qt::Widget; - - if (needsExitButton && sourceWindowType != Qt::Dialog && sourceWindowType != Qt::Popup) - QT_TRAP_THROWING( - nativeContainer->SetCommandL(2, EAknSoftkeyExit, qt_QString2TPtrC(QSoftKeyManager::tr("Exit")))); - - nativeContainer->DrawDeferred(); // 3.1 needs an extra invitation + return source; } -bool QSoftKeyManager::handleCommand(int command) +bool QSoftKeyManager::handleUpdateSoftKeys() { - if (command >= s60CommandStart && QSoftKeyManagerPrivate::softKeySource) { - int index = command - s60CommandStart; - const QList<QAction*>& softKeys = QSoftKeyManagerPrivate::softKeySource->actions(); - for (int i = 0, j = 0; i < softKeys.count(); ++i) { - QAction *action = softKeys.at(i); - if (action->softKeyRole() != QAction::NoSoftKey) { - if (j == index) { - QWidget *parent = action->parentWidget(); - if (parent && parent->isEnabled()) { - action->activate(QAction::Trigger); - return true; - } - } - j++; - } + Q_D(QSoftKeyManager); + int level = 0; + d->requestedSoftKeyActions.clear(); + bool recursiveMerging = false; + QWidget *source = softkeySource(NULL, recursiveMerging); + do { + if (source) { + bool added = appendSoftkeys(*source, level); + source = softkeySource(source, recursiveMerging); + level = added ? ++level : level; } - } + } while (source); - return false; + d->updateSoftKeys_sys(); + return true; } -#else - -void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &) +bool QSoftKeyManager::event(QEvent *e) { +#ifndef QT_NO_ACTION + if (e->type() == QEvent::UpdateSoftKeys) + return handleUpdateSoftKeys(); +#endif //QT_NO_ACTION + return false; } +#ifdef Q_WS_S60 +bool QSoftKeyManager::handleCommand(int command) +{ + return static_cast<QSoftKeyManagerPrivateS60*>(QSoftKeyManager::instance()->d_func())->handleCommand(command); +} #endif QT_END_NAMESPACE diff --git a/src/gui/kernel/qsoftkeymanager_common_p.h b/src/gui/kernel/qsoftkeymanager_common_p.h new file mode 100644 index 0000000..460d0dc --- /dev/null +++ b/src/gui/kernel/qsoftkeymanager_common_p.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSOFTKEYMANAGER_COMMON_P_H +#define QSOFTKEYMANAGER_COMMON_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +QT_BEGIN_HEADER + +#ifndef QT_NO_SOFTKEYMANAGER + +QT_BEGIN_NAMESPACE + +class QSoftKeyManagerPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QSoftKeyManager) + +public: + virtual void updateSoftKeys_sys() {}; + +protected: + static QSoftKeyManager *self; + QHash<QAction*, Qt::Key> keyedActions; + QMultiHash<int, QAction*> requestedSoftKeyActions; + +}; + +QT_END_NAMESPACE + +#endif //QT_NO_SOFTKEYMANAGER + +QT_END_HEADER + +#endif // QSOFTKEYMANAGER_COMMON_P_H
\ No newline at end of file diff --git a/src/gui/kernel/qsoftkeymanager_p.h b/src/gui/kernel/qsoftkeymanager_p.h index c901a29..ce902fe 100644 --- a/src/gui/kernel/qsoftkeymanager_p.h +++ b/src/gui/kernel/qsoftkeymanager_p.h @@ -63,6 +63,8 @@ QT_BEGIN_NAMESPACE class QSoftKeyManagerPrivate; +const char MENU_ACTION_PROPERTY[] = "_q_menuaction"; + class Q_AUTOTEST_EXPORT QSoftKeyManager : public QObject { Q_OBJECT @@ -79,26 +81,30 @@ public: }; static void updateSoftKeys(); - static QAction *createAction(StandardSoftKey standardKey, QWidget *actionWidget); - static QAction *createKeyedAction(StandardSoftKey standardKey, Qt::Key key, QWidget *actionWidget); - #ifdef Q_WS_S60 static bool handleCommand(int); #endif -private: - QSoftKeyManager(); - static QSoftKeyManager *instance(); - static const char *standardSoftKeyText(StandardSoftKey standardKey); + static QAction *createAction(StandardSoftKey standardKey, QWidget *actionWidget); + static QAction *createKeyedAction(StandardSoftKey standardKey, Qt::Key key, QWidget *actionWidget); protected: bool event(QEvent *e); - Q_DISABLE_COPY(QSoftKeyManager) +private: + QSoftKeyManager(); + static QSoftKeyManager *instance(); + static const char *standardSoftKeyText(StandardSoftKey standardKey); + bool appendSoftkeys(const QWidget &source, int level); + QWidget *softkeySource(QWidget *previousSource, bool& recursiveMerging); + bool handleUpdateSoftKeys(); private Q_SLOTS: void cleanupHash(QObject* obj); void sendKeyEvent(); + +private: + Q_DISABLE_COPY(QSoftKeyManager) }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qsoftkeymanager_s60.cpp b/src/gui/kernel/qsoftkeymanager_s60.cpp new file mode 100644 index 0000000..af84a8f --- /dev/null +++ b/src/gui/kernel/qsoftkeymanager_s60.cpp @@ -0,0 +1,404 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qapplication.h" +#include "qevent.h" +#include "qbitmap.h" +#include "qstyle.h" +#include "qmenubar.h" +#include "private/qt_s60_p.h" +#include "private/qmenu_p.h" +#include "private/qsoftkeymanager_p.h" +#include "private/qsoftkeymanager_s60_p.h" +#include "private/qobject_p.h" +#include <eiksoftkeyimage.h> +#include <eikcmbut.h> + +#ifndef QT_NO_SOFTKEYMANAGER +QT_BEGIN_NAMESPACE + +const int S60_COMMAND_START = 6000; +const int LSK_POSITION = 0; +const int MSK_POSITION = 3; +const int RSK_POSITION = 2; + +QSoftKeyManagerPrivateS60::QSoftKeyManagerPrivateS60() +{ + cachedCbaIconSize[0] = QSize(0,0); + cachedCbaIconSize[1] = QSize(0,0); + cachedCbaIconSize[2] = QSize(0,0); + cachedCbaIconSize[3] = QSize(0,0); + skipNextUpdate = false; +} + +bool QSoftKeyManagerPrivateS60::skipCbaUpdate() +{ + // lets not update softkeys if + // 1. We don't have application panes, i.e. cba + // 2. S60 native dialog or menu is shown + if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes) || + CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || skipNextUpdate) { + skipNextUpdate = false; + return true; + } + return false; +} + +void QSoftKeyManagerPrivateS60::ensureCbaVisibilityAndResponsiviness(CEikButtonGroupContainer &cba) +{ + RDrawableWindow *cbaWindow = cba.DrawableWindow(); + Q_ASSERT_X(cbaWindow, Q_FUNC_INFO, "Native CBA does not have window!"); + // Make sure CBA is visible, i.e. CBA window is on top + cbaWindow->SetOrdinalPosition(0); + // Qt shares same CBA instance between top-level widgets, + // make sure we are not faded by underlying window. + cbaWindow->SetFaded(EFalse, RWindowTreeNode::EFadeIncludeChildren); + // Modal dialogs capture pointer events, but shared cba instance + // shall stay responsive. Raise pointer capture priority to keep + // softkeys responsive in modal dialogs + cbaWindow->SetPointerCapturePriority(1); +} + +void QSoftKeyManagerPrivateS60::clearSoftkeys(CEikButtonGroupContainer &cba) +{ + QT_TRAP_THROWING( + //Using -1 instead of EAknSoftkeyEmpty to avoid flickering. + cba.SetCommandL(0, -1, KNullDesC); + // TODO: Should we clear also middle SK? + cba.SetCommandL(2, -1, KNullDesC); + ); + realSoftKeyActions.clear(); +} + +QString QSoftKeyManagerPrivateS60::softkeyText(QAction &softkeyAction) +{ + // In S60 softkeys and menu items do not support key accelerators (i.e. + // CTRL+X). Therefore, removing the accelerator characters from both softkey + // and menu item texts. + const int underlineShortCut = QApplication::style()->styleHint(QStyle::SH_UnderlineShortcut); + QString iconText = softkeyAction.iconText(); + return underlineShortCut ? softkeyAction.text() : iconText; +} + +QAction *QSoftKeyManagerPrivateS60::highestPrioritySoftkey(QAction::SoftKeyRole role) +{ + QAction *ret = NULL; + // Priority look up is two level + // 1. First widget with softkeys always has highest priority + for (int level = 0; !ret; level++) { + // 2. Highest priority action within widget + QList<QAction*> actions = requestedSoftKeyActions.values(level); + if (actions.isEmpty()) + break; + qSort(actions.begin(), actions.end(), QSoftKeyManagerPrivateS60::actionPriorityMoreThan); + foreach (QAction *action, actions) { + if (action->softKeyRole() == role) { + ret = action; + break; + } + } + } + return ret; +} + +bool QSoftKeyManagerPrivateS60::actionPriorityMoreThan(const QAction *firstItem, const QAction *secondItem) +{ + return firstItem->priority() > secondItem->priority(); +} + +void QSoftKeyManagerPrivateS60::setNativeSoftkey(CEikButtonGroupContainer &cba, + TInt position, TInt command, const TDesC &text) +{ + // Calling SetCommandL causes CBA redraw + QT_TRAP_THROWING(cba.SetCommandL(position, command, text)); +} + +QPoint QSoftKeyManagerPrivateS60::softkeyIconPosition(int position, QSize sourceSize, QSize targetSize) +{ + QPoint iconPosition(0,0); + switch( AknLayoutUtils::CbaLocation() ) + { + case AknLayoutUtils::EAknCbaLocationBottom: + // RSK must be moved to right, LSK in on correct position by default + if (position == RSK_POSITION) + iconPosition.setX(targetSize.width() - sourceSize.width()); + break; + case AknLayoutUtils::EAknCbaLocationRight: + case AknLayoutUtils::EAknCbaLocationLeft: + // Already in correct position + default: + break; + } + + // Align horizontally to center + iconPosition.setY((targetSize.height() - sourceSize.height()) >> 1); + return iconPosition; +} + +QPixmap QSoftKeyManagerPrivateS60::prepareSoftkeyPixmap(QPixmap src, int position, QSize targetSize) +{ + QPixmap target(targetSize); + target.fill(Qt::transparent); + QPainter p; + p.begin(&target); + p.drawPixmap(softkeyIconPosition(position, src.size(), targetSize), src); + p.end(); + return target; +} + +bool QSoftKeyManagerPrivateS60::isOrientationLandscape() +{ + // Hard to believe that there is no public API in S60 to + // get current orientation. This workaround works with currently supported resolutions + return S60->screenHeightInPixels < S60->screenWidthInPixels; +} + +QSize QSoftKeyManagerPrivateS60::cbaIconSize(CEikButtonGroupContainer *cba, int position) +{ + + int index = position; + index += isOrientationLandscape() ? 0 : 1; + if(cachedCbaIconSize[index].isNull()) { + // Only way I figured out to get CBA icon size without RnD SDK, was + // to set some dummy icon to CBA first and then ask CBA button CCoeControl::Size() + // The returned value is cached to avoid unnecessary icon setting every time. + const bool left = (position == LSK_POSITION); + if(position == LSK_POSITION || position == RSK_POSITION) { + CEikImage* tmpImage = NULL; + QT_TRAP_THROWING(tmpImage = new (ELeave) CEikImage); + EikSoftkeyImage::SetImage(cba, *tmpImage, left); // Takes myimage ownership + int command = S60_COMMAND_START + position; + setNativeSoftkey(*cba, position, command, KNullDesC()); + cachedCbaIconSize[index] = qt_TSize2QSize(cba->ControlOrNull(command)->Size()); + EikSoftkeyImage::SetLabel(cba, left); + + if(cachedCbaIconSize[index] == QSize(138,72)) { + // Hack for S60 5.0 (5800) landscape orientation, which return wrong icon size + cachedCbaIconSize[index] = QSize(60,60); + } + } + } + + return cachedCbaIconSize[index]; +} + +bool QSoftKeyManagerPrivateS60::setSoftkeyImage(CEikButtonGroupContainer *cba, + QAction &action, int position) +{ + bool ret = false; + + const bool left = (position == LSK_POSITION); + if(position == LSK_POSITION || position == RSK_POSITION) { + QIcon icon = action.icon(); + if (!icon.isNull()) { + // Get size of CBA icon area based on button position and orientation + QSize requiredIconSize = cbaIconSize(cba, position); + // Get pixmap out of icon based on preferred size, the aspect ratio is kept + QPixmap pmWihtAspectRatio = icon.pixmap(requiredIconSize); + // Native softkeys require that pixmap size is exactly the same as requiredIconSize + // prepareSoftkeyPixmap creates a new pixmap with requiredIconSize and blits the 'pmWihtAspectRatio' + // to correct location of it + QPixmap softkeyPixmap = prepareSoftkeyPixmap(pmWihtAspectRatio, position, requiredIconSize); + + QPixmap softkeyAlpha = softkeyPixmap.alphaChannel(); + // Alpha channel in 5.1 and older devices need to be inverted + // TODO: Switch to use toSymbianCFbsBitmap with invert when available + if(QSysInfo::s60Version() <= QSysInfo::SV_S60_5_1) { + QImage alphaImage = softkeyAlpha.toImage(); + alphaImage.invertPixels(); + softkeyAlpha = QPixmap::fromImage(alphaImage); + } + + CFbsBitmap* nBitmap = softkeyPixmap.toSymbianCFbsBitmap(); + CFbsBitmap* nMask = softkeyAlpha.toSymbianCFbsBitmap(); + + CEikImage* myimage = new (ELeave) CEikImage; + myimage->SetPicture( nBitmap, nMask ); // nBitmap and nMask ownership transfered + + EikSoftkeyImage::SetImage(cba, *myimage, left); // Takes myimage ownership + ret = true; + } else { + // Restore softkey to text based + EikSoftkeyImage::SetLabel(cba, left); + } + } + return ret; +} + +bool QSoftKeyManagerPrivateS60::setSoftkey(CEikButtonGroupContainer &cba, + QAction::SoftKeyRole role, int position) +{ + QAction *action = highestPrioritySoftkey(role); + if (action) { + setSoftkeyImage(&cba, *action, position); + QString text = softkeyText(*action); + TPtrC nativeText = qt_QString2TPtrC(text); + int command = S60_COMMAND_START + position; + setNativeSoftkey(cba, position, command, nativeText); + cba.DimCommand(command, !action->isEnabled()); + realSoftKeyActions.insert(command, action); + return true; + } + return false; +} + +bool QSoftKeyManagerPrivateS60::setLeftSoftkey(CEikButtonGroupContainer &cba) +{ + return setSoftkey(cba, QAction::PositiveSoftKey, LSK_POSITION); +} + +bool QSoftKeyManagerPrivateS60::setMiddleSoftkey(CEikButtonGroupContainer &cba) +{ + // Note: In order to get MSK working, application has to have EAknEnableMSK flag set + // Currently it is not possible very easily) + // For more information see: http://wiki.forum.nokia.com/index.php/Middle_softkey_usage + return setSoftkey(cba, QAction::SelectSoftKey, MSK_POSITION); +} + +bool QSoftKeyManagerPrivateS60::setRightSoftkey(CEikButtonGroupContainer &cba) +{ + if (!setSoftkey(cba, QAction::NegativeSoftKey, RSK_POSITION)) { + Qt::WindowType windowType = Qt::Window; + QAction *action = requestedSoftKeyActions.value(0); + if (action) { + QWidget *actionParent = action->parentWidget(); + Q_ASSERT_X(actionParent, Q_FUNC_INFO, "No parent set for softkey action!"); + + QWidget *actionWindow = actionParent->window(); + Q_ASSERT_X(actionWindow, Q_FUNC_INFO, "Softkey action does not have window!"); + windowType = actionWindow->windowType(); + } + + if (windowType != Qt::Dialog && windowType != Qt::Popup) { + QString text(QSoftKeyManager::tr("Exit")); + TPtrC nativeText = qt_QString2TPtrC(text); + EikSoftkeyImage::SetLabel(&cba, false); + setNativeSoftkey(cba, RSK_POSITION, EAknSoftkeyExit, nativeText); + return true; + } + } + return false; +} + +void QSoftKeyManagerPrivateS60::setSoftkeys(CEikButtonGroupContainer &cba) +{ + int requestedSoftkeyCount = requestedSoftKeyActions.count(); + const int maxSoftkeyCount = 2; // TODO: differs based on orientation ans S60 versions (some have MSK) + if (requestedSoftkeyCount > maxSoftkeyCount) { + // We have more softkeys than available slots + // Put highest priority negative action to RSK and Options menu with rest of softkey actions to LSK + // TODO: Build menu + setLeftSoftkey(cba); + if(AknLayoutUtils::MSKEnabled()) + setMiddleSoftkey(cba); + setRightSoftkey(cba); + } else { + // We have less softkeys than available slots + // Put softkeys to request slots based on role + setLeftSoftkey(cba); + if(AknLayoutUtils::MSKEnabled()) + setMiddleSoftkey(cba); + setRightSoftkey(cba); + } +} + +void QSoftKeyManagerPrivateS60::updateSoftKeys_sys() +{ + if (skipCbaUpdate()) + return; + + CEikButtonGroupContainer *nativeContainer = S60->buttonGroupContainer(); + Q_ASSERT_X(nativeContainer, Q_FUNC_INFO, "Native CBA does not exist!"); + ensureCbaVisibilityAndResponsiviness(*nativeContainer); + clearSoftkeys(*nativeContainer); + setSoftkeys(*nativeContainer); + + nativeContainer->DrawDeferred(); // 3.1 needs an extra invitation +} + +bool QSoftKeyManagerPrivateS60::handleCommand(int command) +{ + QAction *action = realSoftKeyActions.value(command); + if (action) { + QVariant property = action->property(MENU_ACTION_PROPERTY); + if (property.isValid() && property.toBool()) { + QT_TRAP_THROWING(S60->menuBar()->TryDisplayMenuBarL()); + } else if (action->menu()) { + // TODO: This is hack, in order to use exising QMenuBar implementation for Symbian + // menubar needs to have widget to which it is associated. Since we want to associate + // menubar to action (which is inherited from QObejct), we create and associate QWidget + // to action and pass that for QMenuBar. This associates the menubar to action, and we + // can have own menubar for each action. + QWidget *actionContainer = action->property("_q_action_widget").value<QWidget*>(); + if(!actionContainer) { + actionContainer = new QWidget(action->parentWidget()); + QMenuBar *menuBar = new QMenuBar(actionContainer); + foreach(QAction *menuAction, action->menu()->actions()) { + QMenu *menu = menuAction->menu(); + if(menu) + menuBar->addMenu(action->menu()); + else + menuBar->addAction(menuAction); + } + QVariant v; + v.setValue(actionContainer); + action->setProperty("_q_action_widget", v); + } + qt_symbian_next_menu_from_action(actionContainer); + QT_TRAP_THROWING(S60->menuBar()->TryDisplayMenuBarL()); + // TODO: hack remove, it can happen that IsDisplayingMenuOrDialog return false + // in updateSoftKeys_sys, and we will override menu CBA with our own + skipNextUpdate = true; + } else { + Q_ASSERT(action->softKeyRole() != QAction::NoSoftKey); + QWidget *actionParent = action->parentWidget(); + Q_ASSERT_X(actionParent, Q_FUNC_INFO, "No parent set for softkey action!"); + if (actionParent->isEnabled()) { + action->activate(QAction::Trigger); + return true; + } + } + } + return false; +} + +QT_END_NAMESPACE +#endif //QT_NO_SOFTKEYMANAGER diff --git a/src/gui/kernel/qsoftkeymanager_s60_p.h b/src/gui/kernel/qsoftkeymanager_s60_p.h new file mode 100644 index 0000000..f8bd6d9 --- /dev/null +++ b/src/gui/kernel/qsoftkeymanager_s60_p.h @@ -0,0 +1,111 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSOFTKEYMANAGER_S60_P_H +#define QSOFTKEYMANAGER_S60_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "private/qobject_p.h" +#include "private/qsoftkeymanager_common_p.h" + +QT_BEGIN_HEADER + +#ifndef QT_NO_SOFTKEYMANAGER + +QT_BEGIN_NAMESPACE + +class CEikButtonGroupContainer; +class QAction; + +class QSoftKeyManagerPrivateS60 : public QSoftKeyManagerPrivate +{ + Q_DECLARE_PUBLIC(QSoftKeyManager) + +public: + QSoftKeyManagerPrivateS60(); + +public: + void updateSoftKeys_sys(); + bool handleCommand(int command); + +private: + bool skipCbaUpdate(); + void ensureCbaVisibilityAndResponsiviness(CEikButtonGroupContainer &cba); + void clearSoftkeys(CEikButtonGroupContainer &cba); + QString softkeyText(QAction &softkeyAction); + QAction *highestPrioritySoftkey(QAction::SoftKeyRole role); + static bool actionPriorityMoreThan(const QAction* item1, const QAction* item2); + void setNativeSoftkey(CEikButtonGroupContainer &cba, TInt position, TInt command, const TDesC& text); + QPoint softkeyIconPosition(int position, QSize sourceSize, QSize targetSize); + QPixmap prepareSoftkeyPixmap(QPixmap src, int position, QSize targetSize); + bool isOrientationLandscape(); + QSize cbaIconSize(CEikButtonGroupContainer *cba, int position); + bool setSoftkeyImage(CEikButtonGroupContainer *cba, QAction &action, int position); + bool setSoftkey(CEikButtonGroupContainer &cba, QAction::SoftKeyRole role, int position); + bool setLeftSoftkey(CEikButtonGroupContainer &cba); + bool setMiddleSoftkey(CEikButtonGroupContainer &cba); + bool setRightSoftkey(CEikButtonGroupContainer &cba); + void setSoftkeys(CEikButtonGroupContainer &cba); + +private: + QHash<int, QAction*> realSoftKeyActions; + QSize cachedCbaIconSize[4]; + bool skipNextUpdate; +}; + + +QT_END_NAMESPACE + +#endif //QT_NO_SOFTKEYMANAGER + +QT_END_HEADER + +#endif // QSOFTKEYMANAGER_S60_P_H diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm index e36ab9b..65c04e5 100644 --- a/src/gui/kernel/qt_cocoa_helpers_mac.mm +++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm @@ -143,6 +143,9 @@ extern QPointer<QWidget> qt_button_down; //qapplication_mac.cpp void macWindowFade(void * /*OSWindowRef*/ window, float durationSeconds) { +#ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; +#endif OSWindowRef wnd = static_cast<OSWindowRef>(window); if (wnd) { QWidget *widget; @@ -1159,7 +1162,7 @@ CGContextRef qt_mac_graphicsContextFor(QWidget *widget) CGrafPtr port = GetWindowPort(qt_mac_window_for(widget)); QDBeginCGContext(port, &context); #else - CGContextRef context = (CGContextRef)[[NSGraphicsContext graphicsContextWithWindow:qt_mac_window_for(widget)] graphicsPort]; + CGContextRef context = reinterpret_cast<CGContextRef>([[qt_mac_window_for(widget) graphicsContext] graphicsPort]); #endif return context; } @@ -1278,4 +1281,17 @@ void qt_cocoaChangeOverrideCursor(const QCursor &cursor) } #endif +QMacCocoaAutoReleasePool::QMacCocoaAutoReleasePool() +{ +#ifndef QT_MAC_USE_COCOA + NSApplicationLoad(); +#endif + pool = (void*)[[NSAutoreleasePool alloc] init]; +} + +QMacCocoaAutoReleasePool::~QMacCocoaAutoReleasePool() +{ + [(NSAutoreleasePool*)pool release]; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 1163055..735ca7a 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -128,6 +128,7 @@ public: static inline RWindowGroup& windowGroup(); static inline CWsScreenDevice* screenDevice(); static inline CCoeAppUi* appUi(); + static inline CEikMenuBar* menuBar(); #ifdef Q_WS_S60 static inline CEikStatusPane* statusPane(); static inline CCoeControl* statusPaneSubPane(TInt aPaneId); @@ -270,6 +271,11 @@ inline CCoeAppUi* QS60Data::appUi() return CCoeEnv::Static()-> AppUi(); } +inline CEikMenuBar* QS60Data::menuBar() +{ + return CEikonEnv::Static()->AppUiFactory()->MenuBar(); +} + #ifdef Q_WS_S60 inline CEikStatusPane* QS60Data::statusPane() { diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index ede87de..2a19d23 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -192,6 +192,7 @@ QWidgetPrivate::QWidgetPrivate(int version) , inDirtyList(0) , isScrolled(0) , isMoved(0) + , isGLWidget(0) , usesDoubleBufferedGLContext(0) #if defined(Q_WS_X11) , picture(0) @@ -200,7 +201,6 @@ QWidgetPrivate::QWidgetPrivate(int version) , nativeGesturePanEnabled(0) #elif defined(Q_WS_MAC) , needWindowChange(0) - , isGLWidget(0) , window_event(0) , qd_hd(0) #endif @@ -1439,6 +1439,18 @@ QWidget::~QWidget() } #endif +#ifdef Q_OS_SYMBIAN + if (d->extra && d->extra->topextra && d->extra->topextra->backingStore) { + // Okay, we are about to destroy the top-level window that owns + // the backing store. Make sure we delete the backing store right away + // before the window handle is invalid. This is important because + // the backing store will delete its window surface, which may or may + // not have a reference to this widget that will be used later to + // notify the window it no longer has a surface. + delete d->extra->topextra->backingStore; + d->extra->topextra->backingStore = 0; + } +#endif if (QWidgetBackingStore *bs = d->maybeBackingStore()) { bs->removeDirtyWidget(this); if (testAttribute(Qt::WA_StaticContents)) @@ -1660,7 +1672,13 @@ void QWidgetPrivate::syncBackingStore() repaint_sys(dirty); dirty = QRegion(); } else if (QWidgetBackingStore *bs = maybeBackingStore()) { +#ifdef QT_MAC_USE_COCOA + Q_UNUSED(bs); + void qt_mac_set_needs_display(QWidget *, QRegion); + qt_mac_set_needs_display(q_func(), QRegion()); +#else bs->sync(); +#endif } } @@ -1668,8 +1686,15 @@ void QWidgetPrivate::syncBackingStore(const QRegion ®ion) { if (paintOnScreen()) repaint_sys(region); - else if (QWidgetBackingStore *bs = maybeBackingStore()) + else if (QWidgetBackingStore *bs = maybeBackingStore()) { +#ifdef QT_MAC_USE_COCOA + Q_UNUSED(bs); + void qt_mac_set_needs_display(QWidget *, QRegion); + qt_mac_set_needs_display(q_func(), region); +#else bs->sync(q_func(), region); +#endif + } } void QWidgetPrivate::setUpdatesEnabled_helper(bool enable) @@ -3352,7 +3377,7 @@ QPoint QWidget::pos() const \note Setting the size to \c{QSize(0, 0)} will cause the widget to not appear on screen. This also applies to windows. - \sa pos, geometry, minimumSize, maximumSize, resizeEvent() + \sa pos, geometry, minimumSize, maximumSize, resizeEvent(), adjustSize() */ /*! @@ -6414,6 +6439,8 @@ void QWidget::setTabOrder(QWidget* first, QWidget *second) first = fp; } + if (fp == second) + return; if (QWidget *sp = second->focusProxy()) second = sp; diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 3dbc843..9e7517f 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -404,7 +404,7 @@ inline static void qt_mac_set_fullscreen_mode(bool b) return; qt_mac_app_fullscreen = b; if (b) { - SetSystemUIMode(kUIModeAllSuppressed, 0); + SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar); } else { SetSystemUIMode(kUIModeNormal, 0); } @@ -565,6 +565,25 @@ inline static void qt_mac_set_window_group_to_popup(OSWindowRef window) } #endif +#ifdef QT_MAC_USE_COCOA +void qt_mac_set_needs_display(QWidget *widget, QRegion region) +{ + NSView *theNSView = qt_mac_nativeview_for(widget); + if (region.isEmpty()) { + [theNSView setNeedsDisplay:YES]; + return; + } + + QVector<QRect> rects = region.rects(); + for (int i = 0; i<rects.count(); ++i) { + const QRect &rect = rects.at(i); + NSRect nsrect = NSMakeRect(rect.x(), rect.y(), rect.width(), rect.height()); + [theNSView setNeedsDisplayInRect:nsrect]; + } + +} +#endif + inline static bool updateRedirectedToGraphicsProxyWidget(QWidget *widget, const QRect &rect) { if (!widget) @@ -3510,6 +3529,8 @@ void QWidgetPrivate::hide_sys() if (!QWidget::mouseGrabber()){ QWidget *enterWidget = QApplication::widgetAt(QCursor::pos()); + if (enterWidget && enterWidget->data->in_destructor) + enterWidget = 0; QApplicationPrivate::dispatchEnterLeave(enterWidget, qt_mouseover); qt_mouseover = enterWidget; } diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index b1eb3c3..b421d30 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -173,6 +173,8 @@ struct QTLWExtra { #ifndef QT_NO_QWS_MANAGER QWSManager *qwsManager; #endif +#elif defined(Q_OS_SYMBIAN) + uint inExpose : 1; // Prevents drawing recursion #endif }; @@ -229,7 +231,6 @@ struct QWExtra { #endif #elif defined(Q_OS_SYMBIAN) // <----------------------------------------------------- Symbian uint activated : 1; // RWindowBase::Activated has been called - uint inExpose : 1; // Prevents drawing recursion /** * Defines the behaviour of QSymbianControl::Draw. @@ -682,6 +683,7 @@ public: uint inDirtyList : 1; uint isScrolled : 1; uint isMoved : 1; + uint isGLWidget : 1; uint usesDoubleBufferedGLContext : 1; // *************************** Platform specific ************************************ @@ -713,7 +715,6 @@ public: #elif defined(Q_WS_MAC) // <--------------------------------------------------------- MAC // This is new stuff uint needWindowChange : 1; - uint isGLWidget : 1; // Each wiget keeps a list of all its child and grandchild OpenGL widgets. // This list is used to update the gl context whenever a parent and a granparent diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 00f2213..ebd289c 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -878,6 +878,7 @@ void QWidgetPrivate::registerDropSite(bool /* on */) void QWidgetPrivate::createTLSysExtra() { extra->topextra->backingStore = 0; + extra->topextra->inExpose = 0; } void QWidgetPrivate::deleteTLSysExtra() @@ -891,7 +892,6 @@ void QWidgetPrivate::createSysExtra() extra->activated = 0; extra->nativePaintMode = QWExtra::Default; extra->receiveNativePaintEvents = 0; - extra->inExpose = 0; } void QWidgetPrivate::deleteSysExtra() @@ -1046,96 +1046,48 @@ void QWidget::setWindowState(Qt::WindowStates newstate) return; if (isWindow()) { -#ifdef Q_WS_S60 - // Change window decoration visibility if switching to or from fullsccreen - // In addition decoration visibility is changed when the initial has been - // WindowNoState. - // The window decoration visibility has to be changed before doing actual - // window state change since in that order the availableGeometry will return - // directly the right size and we will avoid unnecessarty redraws - if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen) || - oldstate == Qt::WindowNoState) { - CEikStatusPane* statusPane = S60->statusPane(); - CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer(); - if (newstate & Qt::WindowFullScreen) { - if (statusPane) - statusPane->MakeVisible(false); - if (buttonGroup) - buttonGroup->MakeVisible(false); - } else { - if (statusPane) - statusPane->MakeVisible(true); - if (buttonGroup) - buttonGroup->MakeVisible(true); - } + QSymbianControl *window = static_cast<QSymbianControl *>(effectiveWinId()); + if (window && newstate & Qt::WindowMinimized) { + window->setFocusSafely(false); + window->MakeVisible(false); + } else if (window && oldstate & Qt::WindowMinimized) { + window->setFocusSafely(true); + window->MakeVisible(true); } + +#ifdef Q_WS_S60 + // Hide window decoration when switching to fullsccreen / minimized otherwise show decoration. + // The window decoration visibility has to be changed before doing actual window state + // change since in that order the availableGeometry will return directly the right size and + // we will avoid unnecessarty redraws + CEikStatusPane* statusPane = S60->statusPane(); + CEikButtonGroupContainer* buttonGroup = S60->buttonGroupContainer(); + TBool visible = !(newstate & (Qt::WindowFullScreen | Qt::WindowMinimized)); + if (statusPane) + statusPane->MakeVisible(visible); + if (buttonGroup) + buttonGroup->MakeVisible(visible); #endif // Q_WS_S60 createWinId(); Q_ASSERT(testAttribute(Qt::WA_WState_Created)); - QTLWExtra *top = d->topData(); - // Ensure the initial size is valid, since we store it as normalGeometry below. if (!testAttribute(Qt::WA_Resized) && !isVisible()) adjustSize(); - if ((oldstate & Qt::WindowMaximized) != (newstate & Qt::WindowMaximized)) { - if ((newstate & Qt::WindowMaximized)) { - const QRect normalGeometry = geometry(); + QTLWExtra *top = d->topData(); + const QRect normalGeometry = (top->normalGeometry.width() < 0) ? geometry() : top->normalGeometry; - const QRect r = top->normalGeometry; - setGeometry(qApp->desktop()->availableGeometry(this)); - top->normalGeometry = r; + if (newstate & Qt::WindowFullScreen) + setGeometry(qApp->desktop()->screenGeometry(this)); + else if (newstate & Qt::WindowMaximized) + setGeometry(qApp->desktop()->availableGeometry(this)); + else + setGeometry(normalGeometry); - if (top->normalGeometry.width() < 0) - top->normalGeometry = normalGeometry; - } else { - // restore original geometry - setGeometry(top->normalGeometry); - } - } - if ((oldstate & Qt::WindowFullScreen) != (newstate & Qt::WindowFullScreen)) { - if (newstate & Qt::WindowFullScreen) { - const QRect normalGeometry = geometry(); - const QRect r = top->normalGeometry; - setGeometry(qApp->desktop()->screenGeometry(this)); - - top->normalGeometry = r; - if (top->normalGeometry.width() < 0) - top->normalGeometry = normalGeometry; - } else { - if (newstate & Qt::WindowMaximized) { - const QRect r = top->normalGeometry; - setGeometry(qApp->desktop()->availableGeometry(this)); - top->normalGeometry = r; - } else { - setGeometry(top->normalGeometry); - } - } - } - if ((oldstate & Qt::WindowMinimized) != (newstate & Qt::WindowMinimized)) { - if (newstate & Qt::WindowMinimized) { - if (isVisible()) { - QSymbianControl *id = static_cast<QSymbianControl *>(effectiveWinId()); - if (id->IsFocused()) // Avoid unnecessary calls to FocusChanged() - id->setFocusSafely(false); - id->MakeVisible(false); - } - } else { - if (isVisible()) { - QSymbianControl *id = static_cast<QSymbianControl *>(effectiveWinId()); - id->MakeVisible(true); - if (!id->IsFocused()) // Avoid unnecessary calls to FocusChanged() - id->setFocusSafely(true); - } - const QRect normalGeometry = geometry(); - const QRect r = top->normalGeometry; - top->normalGeometry = r; - if (top->normalGeometry.width() < 0) - top->normalGeometry = normalGeometry; - } - } + //restore normal geometry + top->normalGeometry = normalGeometry; } data->window_state = newstate; @@ -1195,6 +1147,10 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) if (destroyWindow) { delete id; + // At this point the backing store should already be destroyed + // so we flush the command buffer to ensure that the freeing of + // those resources and deleting the window can happen "atomically" + S60->wsSession().Flush(); } } diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 4684bc1..10fb009 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -346,11 +346,6 @@ Q_GUI_EXPORT void qt_x11_enforce_cursor(QWidget * w) qt_x11_enforce_cursor(w, false); } -static Bool checkForConfigureAndExpose(Display *, XEvent *e, XPointer) -{ - return e->type == ConfigureNotify || e->type == Expose; -} - Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w) { if (!w || (!w->isWindow() && !w->internalWinId())) @@ -363,38 +358,60 @@ Q_GUI_EXPORT void qt_x11_wait_for_window_manager(QWidget* w) if (!w->testAttribute(Qt::WA_WState_Created)) return; - if (!(w->windowFlags() & Qt::X11BypassWindowManagerHint)) { - // if the window is not override-redirect, then the window manager - // will reparent us to the frame decoration window. - while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), ReparentNotify, &ev)) { - if (t.elapsed() > maximumWaitTime) - return; - qApp->syncX(); // non-busy wait - } - } + WId winid = w->internalWinId(); - while (!XCheckTypedWindowEvent(X11->display, w->effectiveWinId(), MapNotify, &ev)) { - if (t.elapsed() > maximumWaitTime) - return; - qApp->syncX(); // non-busy wait - } + // first deliver events that are already in the local queue + QApplication::sendPostedEvents(); - qApp->x11ProcessEvent(&ev); + // the normal sequence is: + // ... ConfigureNotify ... ReparentNotify ... MapNotify ... Expose + // with X11BypassWindowManagerHint: + // ConfigureNotify ... MapNotify ... Expose - // ok, seems like the window manager successfully reparented us, we'll wait - // for the first paint event to arrive, while handling ConfigureNotify in - // the arrival order - while(1) - { - if (XCheckIfEvent(X11->display, &ev, checkForConfigureAndExpose, 0)) { + enum State { + Initial, Reparented, Mapped + } state = Initial; + + do { + if (XEventsQueued(X11->display, QueuedAlready)) { + XNextEvent(X11->display, &ev); qApp->x11ProcessEvent(&ev); - if (ev.type == Expose) - return; + + if (w->windowFlags() & Qt::X11BypassWindowManagerHint) { + switch (state) { + case Initial: + case Reparented: + if (ev.type == MapNotify && ev.xany.window == winid) + state = Mapped; + break; + case Mapped: + if (ev.type == Expose && ev.xany.window == winid) + return; + break; + } + } else { + switch (state) { + case Initial: + if (ev.type == ReparentNotify && ev.xany.window == winid) + state = Reparented; + break; + case Reparented: + if (ev.type == MapNotify && ev.xany.window == winid) + state = Mapped; + break; + case Mapped: + if (ev.type == Expose && ev.xany.window == winid) + return; + break; + } + } + } else { + if (!XEventsQueued(X11->display, QueuedAfterFlush)) + qApp->syncX(); // non-busy wait } if (t.elapsed() > maximumWaitTime) return; - qApp->syncX(); // non-busy wait - } + } while(1); } void qt_change_net_wm_state(const QWidget* w, bool set, Atom one, Atom two = 0) diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index f51dc36..d6d288e 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -934,8 +934,7 @@ void QColor::setRgb(int r, int g, int b, int a) /*! \fn QRgb QColor::rgba() const - Returns the RGB value of the color. Unlike rgb(), the alpha is not - stripped. + Returns the RGB value of the color, including its alpha. For an invalid color, the alpha value of the returned color is unspecified. @@ -950,8 +949,7 @@ QRgb QColor::rgba() const } /*! - Sets the RGBA value to \a rgba. Unlike setRgb(QRgb rgb), this function does - not ignore the alpha. + Sets the RGB value to \a rgba, including its alpha. \sa rgba(), rgb() */ @@ -968,8 +966,7 @@ void QColor::setRgba(QRgb rgba) /*! \fn QRgb QColor::rgb() const - Returns the RGB value of the color. The alpha is stripped for - compatibility. + Returns the RGB value of the color. The alpha value is opaque. \sa getRgb(), rgba() */ @@ -983,7 +980,7 @@ QRgb QColor::rgb() const /*! \overload - Sets the RGB value to \a rgb, ignoring the alpha. + Sets the RGB value to \a rgb. The alpha value is set to opaque. */ void QColor::setRgb(QRgb rgb) { diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 194dda3..7a3da20 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -1267,32 +1267,28 @@ static const uint L2CacheLineLengthInInts = L2CacheLineLength/sizeof(uint); result = 0 d = d * cia */ +#define comp_func_Clear_impl(dest, length, const_alpha)\ +{\ + if (const_alpha == 255) {\ + QT_MEMFILL_UINT(dest, length, 0);\ + } else {\ + int ialpha = 255 - const_alpha;\ + PRELOAD_INIT(dest)\ + for (int i = 0; i < length; ++i) {\ + PRELOAD_COND(dest)\ + dest[i] = BYTE_MUL(dest[i], ialpha);\ + }\ + }\ +} + static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha) { - if (const_alpha == 255) { - QT_MEMFILL_UINT(dest, length, 0); - } else { - int ialpha = 255 - const_alpha; - PRELOAD_INIT(dest) - for (int i = 0; i < length; ++i) { - PRELOAD_COND(dest) - dest[i] = BYTE_MUL(dest[i], ialpha); - } - } + comp_func_Clear_impl(dest, length, const_alpha); } static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha) { - if (const_alpha == 255) { - QT_MEMFILL_UINT(dest, length, 0); - } else { - int ialpha = 255 - const_alpha; - PRELOAD_INIT(dest) - for (int i = 0; i < length; ++i) { - PRELOAD_COND(dest) - dest[i] = BYTE_MUL(dest[i], ialpha); - } - } + comp_func_Clear_impl(dest, length, const_alpha); } /* @@ -2408,7 +2404,11 @@ static inline int soft_light_op(int dst, int src, int da, int sa) else if (4 * dst <= da) return (dst * sa * 255 + da * (src2 - sa) * ((((16 * dst_np - 12 * 255) * dst_np + 3 * 65025) * dst_np) / 65025) + temp) / 65025; else { +# ifdef Q_CC_RVCT // needed to avoid compiler crash in RVCT 2.2 + return (dst * sa * 255 + da * (src2 - sa) * (qIntSqrtInt(dst_np * 255) - dst_np) + temp) / 65025; +# else return (dst * sa * 255 + da * (src2 - sa) * (int(sqrt(qreal(dst_np * 255))) - dst_np) + temp) / 65025; +# endif } } diff --git a/src/gui/painting/qdrawhelper_mmx_p.h b/src/gui/painting/qdrawhelper_mmx_p.h index 8482262..59b3804 100644 --- a/src/gui/painting/qdrawhelper_mmx_p.h +++ b/src/gui/painting/qdrawhelper_mmx_p.h @@ -146,36 +146,30 @@ struct QMMXCommonIntrinsics result = 0 d = d * cia */ +#define comp_func_Clear_impl(dest, length, const_alpha)\ +{\ + if (const_alpha == 255) {\ + qt_memfill(static_cast<quint32*>(dest), quint32(0), length);\ + } else {\ + C_FF; C_80; C_00;\ + m64 ia = MM::negate(MM::load_alpha(const_alpha));\ + for (int i = 0; i < length; ++i) {\ + dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia));\ + }\ + MM::end();\ + }\ +} + template <class MM> static void QT_FASTCALL comp_func_solid_Clear(uint *dest, int length, uint, uint const_alpha) { - if (!length) - return; - - if (const_alpha == 255) { - qt_memfill(static_cast<quint32*>(dest), quint32(0), length); - } else { - C_FF; C_80; C_00; - m64 ia = MM::negate(MM::load_alpha(const_alpha)); - for (int i = 0; i < length; ++i) { - dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia)); - } - } - MM::end(); + comp_func_Clear_impl(dest, length, const_alpha); } template <class MM> static void QT_FASTCALL comp_func_Clear(uint *dest, const uint *, int length, uint const_alpha) { - if (const_alpha == 255) { - qt_memfill(static_cast<quint32*>(dest), quint32(0), length); - } else { - C_FF; C_80; C_00; - m64 ia = MM::negate(MM::load_alpha(const_alpha)); - for (int i = 0; i < length; ++i) - dest[i] = MM::store(MM::byte_mul(MM::load(dest[i]), ia)); - } - MM::end(); + comp_func_Clear_impl(dest, length, const_alpha); } /* @@ -246,7 +240,10 @@ static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int le C_FF; C_80; C_00; if (const_alpha == 255) { for (int i = 0; i < length; ++i) { - if ((0xff000000 & src[i]) == 0xff000000) { + const uint alphaMaskedSource = 0xff000000 & src[i]; + if (alphaMaskedSource == 0) + continue; + if (alphaMaskedSource == 0xff000000) { dest[i] = src[i]; } else { m64 s = MM::load(src[i]); @@ -257,6 +254,8 @@ static void QT_FASTCALL comp_func_SourceOver(uint *dest, const uint *src, int le } else { m64 ca = MM::load_alpha(const_alpha); for (int i = 0; i < length; ++i) { + if ((0xff000000 & src[i]) == 0) + continue; m64 s = MM::byte_mul(MM::load(src[i]), ca); m64 ia = MM::negate(MM::alpha(s)); dest[i] = MM::store(MM::add(s, MM::byte_mul(MM::load(dest[i]), ia))); diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index 6c47aac..cb0db4f 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -1549,6 +1549,9 @@ template<> inline void qt_memfill(quint8 *dest, quint8 color, int count) template <class T> inline void qt_memfill(T *dest, T value, int count) { + if (!count) + return; + int n = (count + 7) / 8; switch (count & 0x07) { diff --git a/src/gui/painting/qmath_p.h b/src/gui/painting/qmath_p.h index cd9f5ea..8a5f5ab 100644 --- a/src/gui/painting/qmath_p.h +++ b/src/gui/painting/qmath_p.h @@ -54,6 +54,7 @@ // #include <math.h> +#include <qmath.h> QT_BEGIN_NAMESPACE @@ -61,6 +62,11 @@ static const qreal Q_PI = qreal(3.14159265358979323846); // pi static const qreal Q_2PI = qreal(6.28318530717958647693); // 2*pi static const qreal Q_PI2 = qreal(1.57079632679489661923); // pi/2 +inline int qIntSqrtInt(int v) +{ + return static_cast<int>(qSqrt(static_cast<qreal>(v))); +} + QT_END_NAMESPACE #endif // QMATH_P_H diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 3f2322e..bc56ed0 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -3081,6 +3081,8 @@ void QRasterPaintEngine::drawGlyphsS60(const QPointF &p, const QTextItemInt &ti) QVarLengthArray<glyph_t> glyphs; QTransform matrix = s->matrix; matrix.translate(p.x(), p.y()); + if (matrix.type() == QTransform::TxScale) + fe->setFontScale(matrix.m11()); ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions); const QFixed aliasDelta = QFixed::fromReal(aliasedCoordinateDelta); @@ -3097,6 +3099,9 @@ void QRasterPaintEngine::drawGlyphsS60(const QPointF &p, const QTextItemInt &ti) alphaPenBlt(glyphBitmapBytes, glyphBitmapSize.iWidth, 8, x, y, glyphBitmapSize.iWidth, glyphBitmapSize.iHeight); } + if (matrix.type() == QTransform::TxScale) + fe->setFontScale(1.0); + return; } #endif // Q_OS_SYMBIAN && QT_NO_FREETYPE @@ -3269,7 +3274,9 @@ void QRasterPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textIte } #elif defined (Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE) // Q_WS_WIN || Q_WS_MAC - if (s->matrix.type() <= QTransform::TxTranslate) { + if (s->matrix.type() <= QTransform::TxTranslate + || (s->matrix.type() == QTransform::TxScale + && (qFuzzyCompare(s->matrix.m11(), s->matrix.m22())))) { drawGlyphsS60(p, ti); return; } diff --git a/src/gui/painting/qpaintengine_raster_p.h b/src/gui/painting/qpaintengine_raster_p.h index b937f66..a1c73cc 100644 --- a/src/gui/painting/qpaintengine_raster_p.h +++ b/src/gui/painting/qpaintengine_raster_p.h @@ -264,13 +264,13 @@ private: #endif // Q_OS_SYMBIAN && QT_NO_FREETYPE inline void ensureBrush(const QBrush &brush) { - if (!qbrush_fast_equals(state()->lastBrush, brush) || state()->fillFlags) + if (!qbrush_fast_equals(state()->lastBrush, brush) || (brush.style() != Qt::NoBrush && state()->fillFlags)) updateBrush(brush); } inline void ensureBrush() { ensureBrush(state()->brush); } inline void ensurePen(const QPen &pen) { - if (!qpen_fast_equals(state()->lastPen, pen) || state()->strokeFlags) + if (!qpen_fast_equals(state()->lastPen, pen) || (pen.style() != Qt::NoPen && state()->strokeFlags)) updatePen(pen); } inline void ensurePen() { ensurePen(state()->pen); } diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 147491e..da48fcb 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -1989,6 +1989,9 @@ void QX11PaintEngine::drawPixmap(const QRectF &r, const QPixmap &px, const QRect } XFillRectangle(d->dpy, d->hd, d->gc, x, y, sw, sh); restore_clip = true; + } else if (mono_dst && !mono_src) { + QBitmap bitmap(pixmap); + XCopyArea(d->dpy, bitmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y); } else { XCopyArea(d->dpy, pixmap.handle(), d->hd, d->gc, sx, sy, sw, sh, x, y); } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 31132d9..3bcaf8c 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1986,12 +1986,25 @@ QPaintEngine *QPainter::paintEngine() const endNativePainting(). Note that only the states the underlying paint engine changes will be reset - to their respective default states. If, for example, the OpenGL polygon - mode is changed by the user inside a beginNativePaint()/endNativePainting() - block, it will not be reset to the default state by endNativePainting(). + to their respective default states. The states we reset may change from + release to release. The following states are currently reset in the OpenGL + 2 engine: - Here is an example that shows intermixing of painter commands - and raw OpenGL commands: + \list + \i blending is disabled + \i the depth, stencil and scissor tests are disabled + \i the active texture unit is reset to 0 + \i the depth mask, depth function and the clear depth are reset to their + default values + \i the stencil mask, stencil operation and stencil function are reset to + their default values + \i the current color is reset to solid white + \endlist + + If, for example, the OpenGL polygon mode is changed by the user inside a + beginNativePaint()/endNativePainting() block, it will not be reset to the + default state by endNativePainting(). Here is an example that shows + intermixing of painter commands and raw OpenGL commands: \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 21 @@ -7382,10 +7395,15 @@ struct QPaintDeviceRedirection typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList; Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections) Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex) +Q_GLOBAL_STATIC(QAtomicInt, globalRedirectionAtomic) /*! \threadsafe + \obsolete + + Please use QWidget::render() instead. + Redirects all paint commands for the given paint \a device, to the \a replacement device. The optional point \a offset defines an offset within the source device. @@ -7395,9 +7413,10 @@ Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex) device's painter (if any) before redirecting. Call restoreRedirected() to restore the previous redirection. - In general, you'll probably find that calling - QPixmap::grabWidget() or QPixmap::grabWindow() is an easier - solution. + \warning Making use of redirections in the QPainter API implies + that QPainter::begin() and QPaintDevice destructors need to hold + a mutex for a short period. This can impact performance. Use of + QWidget::render is strongly encouraged. \sa redirected(), restoreRedirected() */ @@ -7429,14 +7448,24 @@ void QPainter::setRedirected(const QPaintDevice *device, Q_ASSERT(redirections != 0); *redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset, hadInternalWidgetRedirection ? redirections->size() - 1 : -1); + globalRedirectionAtomic()->ref(); } /*! \threadsafe + \obsolete + + Using QWidget::render() obsoletes the use of this function. + Restores the previous redirection for the given \a device after a call to setRedirected(). + \warning Making use of redirections in the QPainter API implies + that QPainter::begin() and QPaintDevice destructors need to hold + a mutex for a short period. This can impact performance. Use of + QWidget::render is strongly encouraged. + \sa redirected() */ void QPainter::restoreRedirected(const QPaintDevice *device) @@ -7447,6 +7476,7 @@ void QPainter::restoreRedirected(const QPaintDevice *device) Q_ASSERT(redirections != 0); for (int i = redirections->size()-1; i >= 0; --i) { if (redirections->at(i) == device) { + globalRedirectionAtomic()->deref(); const int internalWidgetRedirectionIndex = redirections->at(i).internalWidgetRedirectionIndex; redirections->removeAt(i); // Restore the internal widget redirection, i.e. remove it from the global @@ -7468,9 +7498,18 @@ void QPainter::restoreRedirected(const QPaintDevice *device) /*! \threadsafe + \obsolete + + Using QWidget::render() obsoletes the use of this function. + Returns the replacement for given \a device. The optional out parameter \a offset returns the offset within the replaced device. + \warning Making use of redirections in the QPainter API implies + that QPainter::begin() and QPaintDevice destructors need to hold + a mutex for a short period. This can impact performance. Use of + QWidget::render is strongly encouraged. + \sa setRedirected(), restoreRedirected() */ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) @@ -7483,6 +7522,9 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) return widgetPrivate->redirected(offset); } + if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0) + return 0; + QMutexLocker locker(globalRedirectionsMutex()); QPaintDeviceRedirectionList *redirections = globalRedirections(); Q_ASSERT(redirections != 0); @@ -7500,6 +7542,9 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) void qt_painter_removePaintDevice(QPaintDevice *dev) { + if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0) + return; + QMutex *mutex = 0; QT_TRY { mutex = globalRedirectionsMutex(); diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp index 7997e77..bc81514 100644 --- a/src/gui/painting/qpathclipper.cpp +++ b/src/gui/painting/qpathclipper.cpp @@ -90,8 +90,6 @@ static QPointF normalize(const QPointF &p) return p / qSqrt(p.x() * p.x() + p.y() * p.y()); } -static bool pathToRect(const QPainterPath &path, QRectF *rect = 0); - struct QIntersection { qreal alphaA; @@ -1660,7 +1658,7 @@ static bool fuzzyCompare(qreal a, qreal b) return qFuzzyCompare(a, b); } -static bool pathToRect(const QPainterPath &path, QRectF *rect) +bool QPathClipper::pathToRect(const QPainterPath &path, QRectF *rect) { if (path.elementCount() != 5) return false; @@ -1693,7 +1691,7 @@ static bool pathToRect(const QPainterPath &path, QRectF *rect) return false; if (rect) - *rect = QRectF(QPointF(x1, y1), QPointF(x2, y2)); + rect->setCoords(x1, y1, x2, y2); return true; } diff --git a/src/gui/painting/qpathclipper_p.h b/src/gui/painting/qpathclipper_p.h index 0d2c049..b900862 100644 --- a/src/gui/painting/qpathclipper_p.h +++ b/src/gui/painting/qpathclipper_p.h @@ -86,6 +86,8 @@ public: bool intersect(); bool contains(); + static bool pathToRect(const QPainterPath &path, QRectF *rect = 0); + private: Q_DISABLE_COPY(QPathClipper) diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp index a0d2b9b..eee6bef 100644 --- a/src/gui/painting/qwindowsurface_raster.cpp +++ b/src/gui/painting/qwindowsurface_raster.cpp @@ -295,10 +295,8 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi CGContextRestoreGState(context); #ifndef QT_MAC_USE_COCOA QDEndCGContext(port, &context); -#else - CGContextFlush(context); -#endif #endif +#endif // Q_WS_MAC #ifdef Q_OS_SYMBIAN Q_UNUSED(widget); diff --git a/src/gui/painting/qwindowsurface_s60.cpp b/src/gui/painting/qwindowsurface_s60.cpp index 82b2dfb..b01a515 100644 --- a/src/gui/painting/qwindowsurface_s60.cpp +++ b/src/gui/painting/qwindowsurface_s60.cpp @@ -145,12 +145,15 @@ QImage* QS60WindowSurface::buffer(const QWidget *widget) void QS60WindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &) { - QWExtra *extra = widget->d_func()->extraData(); - if (extra && !extra->inExpose) { - extra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again + QWidget *window = widget->window(); + Q_ASSERT(window); + QTLWExtra *topExtra = window->d_func()->maybeTopData(); + Q_ASSERT(topExtra); + if (!topExtra->inExpose) { + topExtra->inExpose = true; // Prevent DrawNow() from calling syncBackingStore() again TRect tr = qt_QRect2TRect(region.boundingRect()); widget->winId()->DrawNow(tr); - extra->inExpose = false; + topExtra->inExpose = false; } } diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 739a70b..b1924e7 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -1149,10 +1149,10 @@ void QCommonStylePrivate::tabLayout(const QStyleOptionTabV3 *opt, const QWidget int vpadding = proxyStyle->pixelMetric(QStyle::PM_TabBarTabVSpace, opt, widget) / 2; if (opt->shape == QTabBar::RoundedSouth || opt->shape == QTabBar::TriangularSouth) verticalShift = -verticalShift; - tr.adjust(hpadding, vpadding, horizontalShift - hpadding, verticalShift - vpadding); + tr.adjust(hpadding, verticalShift - vpadding, horizontalShift - hpadding, vpadding); bool selected = opt->state & QStyle::State_Selected; if (selected) { - tr.setBottom(tr.bottom() - verticalShift); + tr.setTop(tr.top() - verticalShift); tr.setRight(tr.right() - horizontalShift); } @@ -1608,7 +1608,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt, if (toolbutton->toolButtonStyle == Qt::ToolButtonTextUnderIcon) { pr.setHeight(pmSize.height() + 6); - tr.adjust(0, pr.height() - 1, 0, -3); + tr.adjust(0, pr.height() - 1, 0, -2); pr.translate(shiftX, shiftY); if (!hasArrow) { proxy()->drawItemPixmap(p, pr, Qt::AlignCenter, pm); diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index 97d69b2..78074c7 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -667,32 +667,47 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg switch (ct) { case QStyle::CT_PushButton: { - const QPushButton *psh = static_cast<const QPushButton *>(widg); - QString buttonText = qt_mac_removeMnemonics(psh->text()); - if (buttonText.contains(QLatin1Char('\n'))) - ret = QSize(-1, -1); - else if (sz == QAquaSizeLarge) - ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight)); - else if (sz == QAquaSizeSmall) - ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight)); - else if (sz == QAquaSizeMini) - ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight)); - - if (!psh->icon().isNull()){ - // If the button got an icon, and the icon is larger than the - // button, we can't decide on a default size - ret.setWidth(-1); - if (ret.height() < psh->iconSize().height()) - ret.setHeight(-1); - } - else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){ - // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels. - // However, this doesn't work for German, therefore only do it for English, - // I suppose it would be better to do some sort of lookups for languages - // that like to have really long words. - ret.setWidth(77 - 8); - } - + const QPushButton *psh = qobject_cast<const QPushButton *>(widg); + // If this comparison is false, then the widget was not a push button. + // This is bad and there's very little we can do since we were requested to find a + // sensible size for a widget that pretends to be a QPushButton but is not. + if(psh) { + QString buttonText = qt_mac_removeMnemonics(psh->text()); + if (buttonText.contains(QLatin1Char('\n'))) + ret = QSize(-1, -1); + else if (sz == QAquaSizeLarge) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight)); + else if (sz == QAquaSizeSmall) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight)); + else if (sz == QAquaSizeMini) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight)); + + if (!psh->icon().isNull()){ + // If the button got an icon, and the icon is larger than the + // button, we can't decide on a default size + ret.setWidth(-1); + if (ret.height() < psh->iconSize().height()) + ret.setHeight(-1); + } + else if (buttonText == QLatin1String("OK") || buttonText == QLatin1String("Cancel")){ + // Aqua Style guidelines restrict the size of OK and Cancel buttons to 68 pixels. + // However, this doesn't work for German, therefore only do it for English, + // I suppose it would be better to do some sort of lookups for languages + // that like to have really long words. + ret.setWidth(77 - 8); + } + } else { + // The only sensible thing to do is to return whatever the style suggests... + if (sz == QAquaSizeLarge) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight)); + else if (sz == QAquaSizeSmall) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricSmallPushButtonHeight)); + else if (sz == QAquaSizeMini) + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricMiniPushButtonHeight)); + else + // Since there's no default size we return the large size... + ret = QSize(-1, qt_mac_aqua_get_metric(kThemeMetricPushButtonHeight)); + } #if 0 //Not sure we are applying the rules correctly for RadioButtons/CheckBoxes --Sam } else if (ct == QStyle::CT_RadioButton) { QRadioButton *rdo = static_cast<QRadioButton *>(widg); @@ -749,23 +764,30 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg if (sz == QAquaSizeSmall) { int width = 0, height = 0; if (szHint == QSize(-1, -1)) { //just 'guess'.. - const QToolButton *bt = static_cast<const QToolButton *>(widg); - if (!bt->icon().isNull()) { - QSize iconSize = bt->iconSize(); - QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal); - width = qMax(width, qMax(iconSize.width(), pmSize.width())); - height = qMax(height, qMax(iconSize.height(), pmSize.height())); - } - if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) { - int text_width = bt->fontMetrics().width(bt->text()), - text_height = bt->fontMetrics().height(); - if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) { - width = qMax(width, text_width); - height += text_height; - } else { - width += text_width; - width = qMax(height, text_height); + const QToolButton *bt = qobject_cast<const QToolButton *>(widg); + // If this conversion fails then the widget was not what it claimed to be. + if(bt) { + if (!bt->icon().isNull()) { + QSize iconSize = bt->iconSize(); + QSize pmSize = bt->icon().actualSize(QSize(32, 32), QIcon::Normal); + width = qMax(width, qMax(iconSize.width(), pmSize.width())); + height = qMax(height, qMax(iconSize.height(), pmSize.height())); } + if (!bt->text().isNull() && bt->toolButtonStyle() != Qt::ToolButtonIconOnly) { + int text_width = bt->fontMetrics().width(bt->text()), + text_height = bt->fontMetrics().height(); + if (bt->toolButtonStyle() == Qt::ToolButtonTextUnderIcon) { + width = qMax(width, text_width); + height += text_height; + } else { + width += text_width; + width = qMax(height, text_height); + } + } + } else { + // Let's return the size hint... + width = szHint.width(); + height = szHint.height(); } } else { width = szHint.width(); @@ -778,37 +800,47 @@ static QSize qt_aqua_get_known_size(QStyle::ContentsType ct, const QWidget *widg break; case QStyle::CT_Slider: { int w = -1; - const QSlider *sld = static_cast<const QSlider *>(widg); - if (sz == QAquaSizeLarge) { - if (sld->orientation() == Qt::Horizontal) { - w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight); - } else { - w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth); - } - } else if (sz == QAquaSizeSmall) { - if (sld->orientation() == Qt::Horizontal) { - w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight); - } else { - w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth); - } - } else if (sz == QAquaSizeMini) { - if (sld->orientation() == Qt::Horizontal) { - w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight); - } else { - w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth); - if (sld->tickPosition() != QSlider::NoTicks) - w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth); + const QSlider *sld = qobject_cast<const QSlider *>(widg); + // If this conversion fails then the widget was not what it claimed to be. + if(sld) { + if (sz == QAquaSizeLarge) { + if (sld->orientation() == Qt::Horizontal) { + w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight); + } else { + w = qt_mac_aqua_get_metric(kThemeMetricVSliderWidth); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricVSliderTickWidth); + } + } else if (sz == QAquaSizeSmall) { + if (sld->orientation() == Qt::Horizontal) { + w = qt_mac_aqua_get_metric(kThemeMetricSmallHSliderHeight); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricSmallHSliderTickHeight); + } else { + w = qt_mac_aqua_get_metric(kThemeMetricSmallVSliderWidth); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricSmallVSliderTickWidth); + } + } else if (sz == QAquaSizeMini) { + if (sld->orientation() == Qt::Horizontal) { + w = qt_mac_aqua_get_metric(kThemeMetricMiniHSliderHeight); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricMiniHSliderTickHeight); + } else { + w = qt_mac_aqua_get_metric(kThemeMetricMiniVSliderWidth); + if (sld->tickPosition() != QSlider::NoTicks) + w += qt_mac_aqua_get_metric(kThemeMetricMiniVSliderTickWidth); + } } + } else { + // This is tricky, we were requested to find a size for a slider which is not + // a slider. We don't know if this is vertical or horizontal or if we need to + // have tick marks or not. + // For this case we will return an horizontal slider without tick marks. + w = qt_mac_aqua_get_metric(kThemeMetricHSliderHeight); + w += qt_mac_aqua_get_metric(kThemeMetricHSliderTickHeight); } if (sld->orientation() == Qt::Horizontal) ret.setHeight(w); @@ -2379,7 +2411,12 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW ret = 0; break; case PM_ToolBarFrameWidth: - ret = 0; + ret = 1; + if (widget) { + if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent())) + if (mainWindow->unifiedTitleAndToolBarOnMac()) + ret = 0; + } break; default: ret = QWindowsStyle::pixelMetric(metric, opt, widget); @@ -3343,8 +3380,14 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter if (tb->toolButtonStyle != Qt::ToolButtonIconOnly) { needText = true; if (tb->toolButtonStyle == Qt::ToolButtonTextUnderIcon) { - pr.setHeight(pixmap.size().height()); - cr.adjust(0, pr.bottom() + 1, 0, 1); + QMainWindow *mw = qobject_cast<QMainWindow *>(w->window()); + if (mw && mw->unifiedTitleAndToolBarOnMac()) { + pr.setHeight(pixmap.size().height()); + cr.adjust(0, pr.bottom() + 1, 0, 1); + } else { + pr.setHeight(pixmap.size().height() + 6); + cr.adjust(0, pr.bottom(), 0, -3); + } alignment |= Qt::AlignCenter; } else { pr.setWidth(pixmap.width() + 8); @@ -4309,8 +4352,6 @@ QRect QMacStyle::subElementRect(SubElement sr, const QStyleOption *opt, rect.setY(0); rect.setHeight(widget->height()); } - if (opt->direction == Qt::RightToLeft) - rect.adjust(15, 0, -20, 0); } break; case SE_ProgressBarGroove: @@ -5685,12 +5726,16 @@ QSize QMacStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt, break; case CT_ToolButton: if (widget && qobject_cast<const QToolBar *>(widget->parentWidget())) { - sz.rwidth() += 4; - if (sz.height() <= 32) { - // Workaround strange HIToolBar bug when getting constraints. - sz.rheight() += 1; + if (QMainWindow * mainWindow = qobject_cast<QMainWindow *>(widget->parent())) { + if (mainWindow->unifiedTitleAndToolBarOnMac()) { + sz.rwidth() += 4; + if (sz.height() <= 32) { + // Workaround strange HIToolBar bug when getting constraints. + sz.rheight() += 1; + } + return sz; + } } - return sz; } sz.rwidth() += 10; sz.rheight() += 10; diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index 3f4f190..9025e5b 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -92,10 +92,10 @@ static const qreal goldenRatio = 1.618; const layoutHeader QS60StylePrivate::m_layoutHeaders[] = { // *** generated layout data *** -{240,320,1,15,"QVGA Landscape"}, -{320,240,1,15,"QVGA Portrait"}, -{360,640,1,15,"NHD Landscape"}, -{640,360,1,15,"NHD Portrait"}, +{240,320,1,16,"QVGA Landscape"}, +{320,240,1,16,"QVGA Portrait"}, +{360,640,1,16,"NHD Landscape"}, +{640,360,1,16,"NHD Portrait"}, {352,800,1,12,"E90 Landscape"} // *** End of generated data *** }; @@ -104,10 +104,10 @@ const int QS60StylePrivate::m_numberOfLayouts = const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = { // *** generated pixel metrics *** -{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,3,3,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1}, -{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,4,4,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1}, -{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,5,5,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, -{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,5,5,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, +{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,-909,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1}, +{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,-909,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1}, +{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,-909,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,13,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, +{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,-909,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,12,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1}, {7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,-909,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1} // *** End of generated data *** }; @@ -985,7 +985,7 @@ void QS60Style::drawComplexControl(ComplexControl control, const QStyleOptionCom //Handle graphics const QRect sliderHandle = subControlRect(control, optionSlider, SC_SliderHandle, widget); QS60StylePrivate::SkinElements handleElement; - if (optionSlider->state & QStyle::State_Sunken) + if (optionSlider->state & State_Sunken) handleElement = horizontal ? QS60StylePrivate::SE_SliderHandleSelectedHorizontal : QS60StylePrivate::SE_SliderHandleSelectedVertical; else @@ -1985,7 +1985,6 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, */ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const { - Q_D(const QS60Style); const QS60StylePrivate::SkinElementFlags flags = (option->state & State_Enabled) ? QS60StylePrivate::SF_StateEnabled : QS60StylePrivate::SF_StateDisabled; bool commonStyleDraws = false; @@ -2021,8 +2020,8 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti QS60StyleEnums::SP_QgnIndiCheckboxOn : QS60StyleEnums::SP_QgnIndiCheckboxOff; painter->save(); - QColor themeColor = QS60StylePrivate::themePalette()->windowText().color(); - QColor windowTextColor = option->palette.windowText().color(); + const QColor themeColor = QS60StylePrivate::themePalette()->windowText().color(); + const QColor windowTextColor = option->palette.windowText().color(); if (themeColor != windowTextColor) painter->setPen(windowTextColor); @@ -2069,8 +2068,8 @@ void QS60Style::drawPrimitive(PrimitiveElement element, const QStyleOption *opti buttonRect.adjust(0, -newY, -1, -newY); painter->save(); - QColor themeColor = d->s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option); - QColor buttonTextColor = option->palette.buttonText().color(); + const QColor themeColor = QS60StylePrivate::s60Color(QS60StyleEnums::CL_QsnTextColors, 6, option); + const QColor buttonTextColor = option->palette.buttonText().color(); if (themeColor != buttonTextColor) painter->setPen(buttonTextColor); else @@ -2400,22 +2399,15 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt, sz.setHeight(sz.height() + 2 * pixelMetric(PM_FocusFrameVMargin)); break; #ifndef QT_NO_COMBOBOX - case CT_ComboBox: - if (const QStyleOptionComboBox *cmb = qstyleoption_cast<const QStyleOptionComboBox *>(opt)) { - const int frameWidth = cmb->frame ? pixelMetric(PM_ComboBoxFrameWidth, opt, widget) * 2 : 0; - const int textMargins = 2*(pixelMetric(PM_FocusFrameHMargin) + 1); - const int smallestExtraWidth = 23; - // QItemDelegate::sizeHint expands the textMargins two times, thus the 2*textMargins... - const int extra = - qMax(smallestExtraWidth, 2*textMargins + pixelMetric(PM_ScrollBarExtent, opt, widget)); - sz = QSize(sz.width() + frameWidth + extra, sz.height() + frameWidth); - int maxScreenWidth = QApplication::desktop()->availableGeometry().size().width(); - if (sz.width() > maxScreenWidth) { - maxScreenWidth = maxScreenWidth - (extra + frameWidth); - sz.setWidth(maxScreenWidth); - } - } - break; + case CT_ComboBox: { + // Fixing Ui design issues with too wide QComboBoxes and greedy SizeHints + // Make sure, that the combobox says within the screen. + const QSize desktopContentSize = QApplication::desktop()->availableGeometry().size() + -QSize(pixelMetric(PM_LayoutLeftMargin) + pixelMetric(PM_LayoutRightMargin), 0); + sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget). + boundedTo(desktopContentSize); + } + break; #endif default: sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget); @@ -2621,29 +2613,31 @@ QRect QS60Style::subControlRect(ComplexControl control, const QStyleOptionComple // lets use spinbox frame here as well, as no combobox specific value available. const int frameThickness = cmb->frame ? pixelMetric(PM_SpinBoxFrameWidth, cmb, widget) : 0; const int buttonWidth = qMax(cmb->rect.height(), buttonIconSize); - const int xposMod = (cmb->rect.x()) + width - buttonMargin - buttonWidth; - const int ypos = cmb->rect.y(); QSize buttonSize; buttonSize.setWidth(buttonWidth + 2 * buttonMargin); buttonSize.setHeight(qMax(8, (cmb->rect.height() >> 1) - frameThickness)); //buttons should be squares buttonSize = buttonSize.expandedTo(QApplication::globalStrut()); switch (scontrol) { - case SC_ComboBoxArrow: + case SC_ComboBoxArrow: { + const int xposMod = cmb->rect.x() + width - buttonMargin - buttonWidth; + const int ypos = cmb->rect.y(); ret.setRect(xposMod, ypos + buttonMargin, buttonWidth, height - 2 * buttonMargin); + } break; case SC_ComboBoxEditField: { - const int withFrameX = cmb->rect.x() + cmb->rect.width() - frameThickness - buttonSize.width(); + const int withFrameX = cmb->rect.x() + width - frameThickness - buttonSize.width(); ret = QRect( frameThickness, frameThickness, withFrameX - frameThickness, - cmb->rect.height() - 2 * frameThickness); + height - 2 * frameThickness); } break; default: break; } + ret = visualRect(cmb->direction, cmb->rect, ret); } break; case CC_GroupBox: @@ -2964,11 +2958,13 @@ void QS60Style::unpolish(QWidget *widget) if (widget) widget->setPalette(QPalette()); -#ifndef QT_NO_PROGRESSBAR +#if defined(Q_WS_S60) && !defined(QT_NO_PROGRESSBAR) if (QProgressBar *bar = qobject_cast<QProgressBar *>(widget)) { widget->removeEventFilter(this); d->m_bars.removeAll(bar); } +#else + Q_UNUSED(d) #endif QCommonStyle::unpolish(widget); } @@ -3000,9 +2996,8 @@ void QS60Style::unpolish(QApplication *application) */ bool QS60Style::event(QEvent *e) { - Q_D(QS60Style); - #ifdef QT_KEYPAD_NAVIGATION + Q_D(QS60Style); const QEvent::Type eventType = e->type(); if ((eventType == QEvent::FocusIn || eventType == QEvent::FocusOut || @@ -3166,6 +3161,10 @@ bool QS60Style::eventFilter(QObject *object, QEvent *event) return QStyle::eventFilter(object, event); } +/*! + \internal + Handle the timer \a event. +*/ void QS60Style::timerEvent(QTimerEvent *event) { #ifdef Q_WS_S60 diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index 2cd238f..eae2291 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -74,7 +74,6 @@ typedef struct { unsigned short width; int major_version; int minor_version; - bool mirroring; // TODO: (nice to have) Use Qt::LayoutDirection const char* layoutName; } layoutHeader; @@ -353,12 +352,12 @@ public: int timerId() const {return m_currentData->m_timerId;} int currentFrame() const {return m_currentData->m_currentFrame;} - void setFrameCount(const int &frameCount) {m_currentData->m_frames = frameCount;} - void setInterval(const int &interval) {m_currentData->m_interval = interval;} + void setFrameCount(int frameCount) {m_currentData->m_frames = frameCount;} + void setInterval(int interval) {m_currentData->m_interval = interval;} void setAnimationObject(CAknBitmapAnimation* animation); void setResourceBased(bool resourceBased) {m_currentData->m_resourceBased = resourceBased;} - void setTimerId(const int &timerId) {m_currentData->m_timerId = timerId;} - void setCurrentFrame(const int ¤tFrame) {m_currentData->m_currentFrame = currentFrame;} + void setTimerId(int timerId) {m_currentData->m_timerId = timerId;} + void setCurrentFrame(int currentFrame) {m_currentData->m_currentFrame = currentFrame;} void resetToDefaults(); diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index a3bb169..872bc2b 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -105,7 +105,7 @@ AnimationData::AnimationData(const QS60StyleEnums::SkinParts part, int frames, i } AnimationDataV2::AnimationDataV2(const AnimationData &data) : AnimationData(data.m_id, data.m_frames, data.m_interval), - m_resourceBased(false), m_animation(0), m_timerId(0) + m_animation(0), m_currentFrame(0), m_resourceBased(false), m_timerId(0) { } AnimationDataV2::~AnimationDataV2() diff --git a/src/gui/styles/qstyle_s60.qrc b/src/gui/styles/qstyle_s60.qrc new file mode 100644 index 0000000..dbee38b --- /dev/null +++ b/src/gui/styles/qstyle_s60.qrc @@ -0,0 +1,137 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource prefix="/trolltech/styles/commonstyle"> +<!-- <file>images/filelink-16.png</file> --> +<file>images/filelink-32.png</file> +<!-- <file>images/filelink-128.png</file> --> +<!-- <file>images/file-16.png</file> --> +<file>images/file-32.png</file> +<!-- <file>images/file-128.png</file> --> +<!-- <file>images/newdirectory-16.png</file> --> +<file>images/newdirectory-32.png</file> +<!-- <file>images/newdirectory-128.png</file> --> +<!-- <file>images/parentdir-16.png</file> --> +<file>images/parentdir-32.png</file> +<!-- <file>images/parentdir-128.png</file> --> +<!-- <file>images/dvd-16.png</file> --> +<!-- <file>images/dvd-32.png</file> --> +<!-- <file>images/dvd-128.png</file> --> +<!-- <file>images/cdr-16.png</file> --> +<!-- <file>images/cdr-32.png</file> --> +<!-- <file>images/cdr-128.png</file> --> +<!-- <file>images/floppy-16.png</file> --> +<!-- <file>images/floppy-32.png</file> --> +<!-- <file>images/floppy-128.png</file> --> +<!-- <file>images/harddrive-16.png</file> --> +<file>images/harddrive-32.png</file> +<!-- <file>images/harddrive-128.png</file> --> +<!-- <file>images/trash-16.png</file> --> +<!-- <file>images/trash-32.png</file> --> +<!-- <file>images/trash-128.png</file> --> +<!-- <file>images/networkdrive-16.png</file> --> +<!-- <file>images/networkdrive-32.png</file> --> +<!-- <file>images/networkdrive-128.png</file> --> +<!-- <file>images/computer-16.png</file> --> +<!-- <file>images/computer-32.png</file> --> +<!-- <file>images/desktop-16.png</file> --> +<file>images/desktop-32.png</file> +<!-- <file>images/dirclosed-16.png</file> --> +<file>images/dirclosed-32.png</file> +<!-- <file>images/dirclosed-128.png</file> --> +<!-- <file>images/dirlink-16.png</file> --> +<file>images/dirlink-32.png</file> +<!-- <file>images/dirlink-128.png</file> --> +<!-- <file>images/diropen-16.png</file> --> +<file>images/diropen-32.png</file> +<!-- <file>images/diropen-128.png</file> --> +<!-- <file>images/left-16.png</file> --> +<file>images/left-32.png</file> +<!-- <file>images/left-128.png</file> --> +<!-- <file>images/right-16.png</file> --> +<file>images/right-32.png</file> +<!-- <file>images/right-128.png</file> --> +<!-- <file>images/up-16.png</file> --> +<file>images/up-32.png</file> +<!-- <file>images/up-128.png</file> --> +<!-- <file>images/down-16.png</file> --> +<file>images/down-32.png</file> +<!-- <file>images/down-128.png</file> --> +<!-- <file>images/filecontents-16.png</file> --> +<file>images/filecontents-32.png</file> +<!-- <file>images/filecontents-128.png</file> --> +<!-- <file>images/fileinfo-16.png</file> --> +<file>images/fileinfo-32.png</file> +<!-- <file>images/fileinfo-128.png</file> --> +<!-- <file>images/viewdetailed-16.png</file> --> +<file>images/viewdetailed-32.png</file> +<!-- <file>images/viewdetailed-128.png</file> --> +<!-- <file>images/viewlist-16.png</file> --> +<file>images/viewlist-32.png</file> +<!-- <file>images/viewlist-128.png</file> --> +<file>images/fontbitmap-16.png</file> +<file>images/fonttruetype-16.png</file> +<!-- <file>images/standardbutton-apply-128.png</file> --> +<!-- <file>images/standardbutton-apply-16.png</file> --> +<file>images/standardbutton-apply-32.png</file> +<!-- <file>images/standardbutton-cancel-128.png</file> --> +<!-- <file>images/standardbutton-cancel-16.png</file> --> +<file>images/standardbutton-cancel-32.png</file> +<!-- <file>images/standardbutton-clear-128.png</file> --> +<!-- <file>images/standardbutton-clear-16.png</file> --> +<file>images/standardbutton-clear-32.png</file> +<!-- <file>images/standardbutton-close-128.png</file> --> +<!-- <file>images/standardbutton-close-16.png</file> --> +<file>images/standardbutton-close-32.png</file> +<!-- <file>images/standardbutton-delete-128.png</file> --> +<!-- <file>images/standardbutton-delete-16.png</file> --> +<file>images/standardbutton-delete-32.png</file> +<!-- <file>images/standardbutton-help-128.png</file> --> +<!-- <file>images/standardbutton-help-16.png</file> --> +<file>images/standardbutton-help-32.png</file> +<!-- <file>images/standardbutton-no-128.png</file> --> +<!-- <file>images/standardbutton-no-16.png</file> --> +<file>images/standardbutton-no-32.png</file> +<!-- <file>images/standardbutton-ok-128.png</file> --> +<!-- <file>images/standardbutton-ok-16.png</file> --> +<file>images/standardbutton-ok-32.png</file> +<!-- <file>images/standardbutton-open-128.png</file> --> +<!-- <file>images/standardbutton-open-16.png</file> --> +<file>images/standardbutton-open-32.png</file> +<!-- <file>images/standardbutton-save-128.png</file> --> +<!-- <file>images/standardbutton-save-16.png</file> --> +<file>images/standardbutton-save-32.png</file> +<!-- <file>images/standardbutton-yes-128.png</file> --> +<!-- <file>images/standardbutton-yes-16.png</file> --> +<file>images/standardbutton-yes-32.png</file> +<file>images/standardbutton-closetab-16.png</file> +<file>images/standardbutton-closetab-down-16.png</file> +<file>images/standardbutton-closetab-hover-16.png</file> +<!-- <file>images/refresh-24.png</file> --> +<file>images/refresh-32.png</file> +<!-- <file>images/stop-24.png</file> --> +<file>images/stop-32.png</file> +<!-- <file>images/media-stop-16.png</file> --> +<file>images/media-stop-32.png</file> +<!-- <file>images/media-play-16.png</file> --> +<file>images/media-play-32.png</file> +<!-- <file>images/media-pause-16.png</file> --> +<file>images/media-pause-32.png</file> +<!-- <file>images/media-seek-forward-16.png</file> --> +<file>images/media-seek-forward-32.png</file> +<!-- <file>images/media-seek-backward-16.png</file> --> +<file>images/media-seek-backward-32.png</file> +<!-- <file>images/media-skip-forward-16.png</file> --> +<file>images/media-skip-forward-32.png</file> +<!-- <file>images/media-skip-backward-16.png</file> --> +<file>images/media-skip-backward-32.png</file> +<file>images/media-volume-16.png</file> +<file>images/media-volume-muted-16.png</file> +</qresource> +<!-- +<qresource prefix="/trolltech/styles/macstyle"> +<file>images/closedock-16.png</file> +<file>images/closedock-down-16.png</file> +<file>images/dockdock-16.png</file> +<file>images/dockdock-down-16.png</file> +</qresource> +--> +</RCC> diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index 498313b..b36294a 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -1125,6 +1125,7 @@ void QRenderRule::fixupBorder(int nativeWidth) void QRenderRule::drawBorderImage(QPainter *p, const QRect& rect) { + setClip(p, rect); static const Qt::TileRule tileMode2TileRule[] = { Qt::StretchTile, Qt::RoundTile, Qt::StretchTile, Qt::RepeatTile, Qt::StretchTile }; @@ -1142,6 +1143,7 @@ void QRenderRule::drawBorderImage(QPainter *p, const QRect& rect) QRect(QPoint(), borderImageData->pixmap.size()), sourceMargins, QTileRules(tileMode2TileRule[borderImageData->horizStretch], tileMode2TileRule[borderImageData->vertStretch])); p->setRenderHint(QPainter::SmoothPixmapTransform, wasSmoothPixmapTransform); + unsetClip(p); } QRect QRenderRule::originRect(const QRect &rect, Origin origin) const diff --git a/src/gui/styles/styles.pri b/src/gui/styles/styles.pri index f30f5af..676f59e 100644 --- a/src/gui/styles/styles.pri +++ b/src/gui/styles/styles.pri @@ -23,10 +23,12 @@ SOURCES += \ styles/qstylesheetstyle.cpp \ styles/qstylesheetstyle_default.cpp -!wince* { - RESOURCES += styles/qstyle.qrc +wince* { + RESOURCES += styles/qstyle_wince.qrc +} else:symbian { + RESOURCES += styles/qstyle_s60.qrc } else { - RESOURCES += styles/qstyle_wince.qrc + RESOURCES += styles/qstyle.qrc } contains( styles, all ) { diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 3b5b7d7..9b85c04 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -629,8 +629,9 @@ QFontEngineData::~QFontEngineData() Returns the name of the font within the underlying window system. - Only on X11 when Qt was built without FontConfig support the XLFD (X Logical Font Description) - is returned; otherwise an empty string. + On X11, this function will return an empty string if Qt is built with + FontConfig support; otherwise the XLFD (X Logical Font Description) is + returned. Using the return value of this function is usually \e not \e portable. diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 4b678ed..621f666 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -246,8 +246,8 @@ static void initializeDb() QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces(); - const QFontDatabaseS60StoreImplementation *store = dynamic_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store); - Q_ASSERT(store); + const QFontDatabaseS60StoreImplementation *store = + static_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store); bool fontAdded = false; for (int i = 0; i < numTypeFaces; i++) { TTypefaceSupport typefaceSupport; @@ -258,8 +258,7 @@ static void initializeDb() continue; if (font->TypeUid() == KCFbsFontUid) { TOpenFontFaceAttrib faceAttrib; - const CFbsFont *cfbsFont = dynamic_cast<const CFbsFont *>(font); - Q_ASSERT(cfbsFont); + const CFbsFont *cfbsFont = static_cast<const CFbsFont *>(font); cfbsFont->GetFaceAttrib(faceAttrib); QtFontStyle::Key styleKey; @@ -390,8 +389,8 @@ QFontEngine *QFontDatabase::findFont(int script, const QFontPrivate *, const QFo QFontDef request = req; request.family = fontFamily; #if defined(QT_NO_FREETYPE) - const QFontDatabaseS60StoreImplementation *store = dynamic_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store); - Q_ASSERT(store); + const QFontDatabaseS60StoreImplementation *store = + static_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store); const QFontEngineS60Extensions *extension = store->extension(fontFamily); fe = new QFontEngineS60(request, extension); #else diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 9343cb7..c000457 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -357,9 +357,6 @@ void QFontEngine::getGlyphPositions(const QGlyphLayout &glyphs, const QTransform ++i; } } else { - positions.resize(glyphs.numGlyphs); - glyphs_out.resize(glyphs.numGlyphs); - int i = 0; while (i < glyphs.numGlyphs) { if (!glyphs.attributes[i].dontPrint) { QFixed gpos_x = xpos + glyphs.offsets[i].x; diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp index 4625667..3ea084b 100644 --- a/src/gui/text/qfontengine_s60.cpp +++ b/src/gui/text/qfontengine_s60.cpp @@ -44,7 +44,7 @@ #include "qglobal.h" #include <private/qapplication_p.h> #include "qimage.h" -#include "qt_s60_p.h" +#include <private/qt_s60_p.h> #include <e32base.h> #include <e32std.h> @@ -129,26 +129,62 @@ static inline unsigned int getChar(const QChar *str, int &i, const int len) return uc; } +CFont *QFontEngineS60::fontWithSize(qreal size) const +{ + CFont *result = 0; + TFontSpec fontSpec(qt_QString2TPtrC(QFontEngine::fontDef.family), TInt(size)); + fontSpec.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap); + fontSpec.iFontStyle.SetPosture(QFontEngine::fontDef.style == QFont::StyleNormal?EPostureUpright:EPostureItalic); + fontSpec.iFontStyle.SetStrokeWeight(QFontEngine::fontDef.weight > QFont::Normal?EStrokeWeightBold:EStrokeWeightNormal); + const TInt errorCode = S60->screenDevice()->GetNearestFontToDesignHeightInPixels(result, fontSpec); + Q_ASSERT(result && (errorCode == 0)); + return result; +} + +void QFontEngineS60::setFontScale(qreal scale) +{ + if (qFuzzyCompare(scale, qreal(1))) { + if (!m_originalFont) + m_originalFont = fontWithSize(m_originalFontSizeInPixels); + m_activeFont = m_originalFont; + } else { + const qreal scaledFontSizeInPixels = m_originalFontSizeInPixels * scale; + if (!m_scaledFont || + (TInt(scaledFontSizeInPixels) != TInt(m_scaledFontSizeInPixels))) { + releaseFont(m_scaledFont); + m_scaledFontSizeInPixels = scaledFontSizeInPixels; + m_scaledFont = fontWithSize(m_scaledFontSizeInPixels); + } + m_activeFont = m_scaledFont; + } +} + +void QFontEngineS60::releaseFont(CFont *&font) +{ + if (font) { + S60->screenDevice()->ReleaseFont(font); + font = 0; + } +} + QFontEngineS60::QFontEngineS60(const QFontDef &request, const QFontEngineS60Extensions *extensions) : m_extensions(extensions) + , m_originalFont(0) + , m_originalFontSizeInPixels((request.pixelSize >= 0)? + request.pixelSize:pointsToPixels(request.pointSize)) + , m_scaledFont(0) + , m_scaledFontSizeInPixels(0) + , m_activeFont(0) { QFontEngine::fontDef = request; - m_fontSizeInPixels = (request.pixelSize >= 0)? - request.pixelSize:pointsToPixels(request.pointSize); - - TFontSpec fontSpec(qt_QString2TPtrC(request.family), m_fontSizeInPixels); - fontSpec.iFontStyle.SetBitmapType(EAntiAliasedGlyphBitmap); - fontSpec.iFontStyle.SetPosture(request.style == QFont::StyleNormal?EPostureUpright:EPostureItalic); - fontSpec.iFontStyle.SetStrokeWeight(request.weight > QFont::Normal?EStrokeWeightBold:EStrokeWeightNormal); - const TInt errorCode = S60->screenDevice()->GetNearestFontToDesignHeightInPixels(m_font, fontSpec); - Q_ASSERT(errorCode == 0); - + setFontScale(1.0); cache_cost = sizeof(QFontEngineS60); } QFontEngineS60::~QFontEngineS60() { - S60->screenDevice()->ReleaseFont(m_font); + releaseFont(m_originalFont); + releaseFont(m_scaledFont); } bool QFontEngineS60::stringToCMap(const QChar *characters, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const @@ -251,12 +287,12 @@ glyph_metrics_t QFontEngineS60::boundingBox(glyph_t glyph) QFixed QFontEngineS60::ascent() const { - return m_font->FontMaxAscent(); + return m_originalFont->FontMaxAscent(); } QFixed QFontEngineS60::descent() const { - return m_font->FontMaxDescent(); + return m_originalFont->FontMaxDescent(); } QFixed QFontEngineS60::leading() const @@ -266,7 +302,7 @@ QFixed QFontEngineS60::leading() const qreal QFontEngineS60::maxCharWidth() const { - return m_font->MaxCharWidthInPixels(); + return m_originalFont->MaxCharWidthInPixels(); } const char *QFontEngineS60::name() const @@ -302,11 +338,11 @@ void QFontEngineS60::getCharacterData(glyph_t glyph, TOpenFontCharMetrics& metri const TUint specialCode = (TUint)glyph | 0x80000000; const CFont::TCharacterDataAvailability availability = - m_font->GetCharacterData(specialCode, metrics, bitmap, bitmapSize); + m_activeFont->GetCharacterData(specialCode, metrics, bitmap, bitmapSize); const glyph_t fallbackGlyph = '?'; if (availability != CFont::EAllCharacterData) { const CFont::TCharacterDataAvailability fallbackAvailability = - m_font->GetCharacterData(fallbackGlyph, metrics, bitmap, bitmapSize); + m_activeFont->GetCharacterData(fallbackGlyph, metrics, bitmap, bitmapSize); Q_ASSERT(fallbackAvailability == CFont::EAllCharacterData); } } diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h index 6d47b9d..5834cc4 100644 --- a/src/gui/text/qfontengine_s60_p.h +++ b/src/gui/text/qfontengine_s60_p.h @@ -58,9 +58,6 @@ #include "qsize.h" #include <openfont.h> -class CFbsBitmap; -class CFbsBitmapDevice; -class CFbsBitGc; class CFont; QT_BEGIN_NAMESPACE @@ -120,15 +117,21 @@ public: Type type() const; void getCharacterData(glyph_t glyph, TOpenFontCharMetrics& metrics, const TUint8*& bitmap, TSize& bitmapSize) const; + void setFontScale(qreal scale); private: friend class QFontPrivate; QFixed glyphAdvance(HB_Glyph glyph) const; + CFont *fontWithSize(qreal size) const; + static void releaseFont(CFont *&font); - CFont* m_font; const QFontEngineS60Extensions *m_extensions; - qreal m_fontSizeInPixels; + CFont* m_originalFont; + const qreal m_originalFontSizeInPixels; + CFont* m_scaledFont; + qreal m_scaledFontSizeInPixels; + CFont* m_activeFont; }; class QFontEngineMultiS60 : public QFontEngineMulti diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 26c7c1e..af91603 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -1331,7 +1331,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition QTextLine l(line, d); const QScriptLine &sl = d->lines[line]; - const qreal x = position.x() + l.cursorToX(cursorPosition); + qreal x = position.x() + l.cursorToX(cursorPosition); int itm = d->findItem(cursorPosition - 1); QFixed base = sl.base(); @@ -1350,6 +1350,10 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition && (p->transform().type() > QTransform::TxTranslate); if (toggleAntialiasing) p->setRenderHint(QPainter::Antialiasing); +#if defined(QT_MAC_USE_COCOA) + // Always draw the cursor aligned to pixel boundary. + x = qRound(x); +#endif p->fillRect(QRectF(x, y, qreal(width), (base + descent + 1).toReal()), p->pen().brush()); if (toggleAntialiasing) p->setRenderHint(QPainter::Antialiasing, false); diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp index 0c8aeec..c1e254c 100644 --- a/src/gui/text/qtextoption.cpp +++ b/src/gui/text/qtextoption.cpp @@ -52,6 +52,9 @@ struct QTextOptionPrivate /*! Constructs a text option with default properties for text. + The text alignment property is set to Qt::AlignLeft. The + word wrap property is set to QTextOption::WordWrap. The + using of design metrics flag is set to false. */ QTextOption::QTextOption() : align(Qt::AlignLeft), @@ -67,6 +70,8 @@ QTextOption::QTextOption() /*! Constructs a text option with the given \a alignment for text. + The word wrap property is set to QTextOption::WordWrap. The using + of design metrics flag is set to false. */ QTextOption::QTextOption(Qt::Alignment alignment) : align(alignment), diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp index 2fc1940..d30c996 100644 --- a/src/gui/text/qzip.cpp +++ b/src/gui/text/qzip.cpp @@ -54,10 +54,13 @@ #include <zlib.h> #if defined(Q_OS_WIN) -#undef S_IFREG -#define S_IFREG 0100000 +# undef S_IFREG +# define S_IFREG 0100000 +# ifndef S_IFDIR +# define S_IFDIR 0040000 +# endif # ifndef S_ISDIR -# define S_ISDIR(x) ((x) & 0040000) > 0 +# define S_ISDIR(x) ((x) & S_IFDIR) > 0 # endif # ifndef S_ISREG # define S_ISREG(x) ((x) & 0170000) == S_IFREG diff --git a/src/gui/text/qzipreader_p.h b/src/gui/text/qzipreader_p.h index 1086464..67a2ace 100644 --- a/src/gui/text/qzipreader_p.h +++ b/src/gui/text/qzipreader_p.h @@ -49,7 +49,7 @@ // ------------- // // This file is not part of the Qt API. It exists for the convenience -// of the QLibrary class. This header file may change from +// of the QZipReader class. This header file may change from // version to version without notice, or even be removed. // // We mean it. diff --git a/src/gui/text/qzipwriter_p.h b/src/gui/text/qzipwriter_p.h index 7b97937..9322f4a 100644 --- a/src/gui/text/qzipwriter_p.h +++ b/src/gui/text/qzipwriter_p.h @@ -47,7 +47,7 @@ // ------------- // // This file is not part of the Qt API. It exists for the convenience -// of the QLibrary class. This header file may change from +// of the QZipWriter class. This header file may change from // version to version without notice, or even be removed. // // We mean it. diff --git a/src/gui/util/qsystemtrayicon_mac.mm b/src/gui/util/qsystemtrayicon_mac.mm index ae805f6..0265a83 100644 --- a/src/gui/util/qsystemtrayicon_mac.mm +++ b/src/gui/util/qsystemtrayicon_mac.mm @@ -569,16 +569,3 @@ private: } @end - -/* Done here because this is the only .mm for now! -Sam */ -QMacCocoaAutoReleasePool::QMacCocoaAutoReleasePool() -{ - NSApplicationLoad(); - pool = (void*)[[NSAutoreleasePool alloc] init]; -} - -QMacCocoaAutoReleasePool::~QMacCocoaAutoReleasePool() -{ - [(NSAutoreleasePool*)pool release]; -} - diff --git a/src/gui/util/qsystemtrayicon_p.h b/src/gui/util/qsystemtrayicon_p.h index b881f68..e8bf197 100644 --- a/src/gui/util/qsystemtrayicon_p.h +++ b/src/gui/util/qsystemtrayicon_p.h @@ -164,7 +164,9 @@ protected: bool x11Event(XEvent *event); void mousePressEvent(QMouseEvent *event); void mouseDoubleClickEvent(QMouseEvent *event); +#ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent *event); +#endif bool event(QEvent *e); private: diff --git a/src/gui/util/qsystemtrayicon_x11.cpp b/src/gui/util/qsystemtrayicon_x11.cpp index a645050..82b4325 100644 --- a/src/gui/util/qsystemtrayicon_x11.cpp +++ b/src/gui/util/qsystemtrayicon_x11.cpp @@ -308,10 +308,12 @@ void QSystemTrayIconSys::mouseDoubleClickEvent(QMouseEvent *ev) emit q->activated(QSystemTrayIcon::DoubleClick); } +#ifndef QT_NO_WHEELEVENT void QSystemTrayIconSys::wheelEvent(QWheelEvent *e) { QApplication::sendEvent(q, e); } +#endif bool QSystemTrayIconSys::event(QEvent *e) { diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 87f6c83..1d496d5 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -1134,13 +1134,10 @@ void QAbstractScrollArea::mouseMoveEvent(QMouseEvent *e) void QAbstractScrollArea::wheelEvent(QWheelEvent *e) { Q_D(QAbstractScrollArea); - QScrollBar *const bars[2] = { d->hbar, d->vbar }; - int idx = (e->orientation() == Qt::Vertical) ? 1 : 0; - int other = (idx + 1) % 2; - if (!bars[idx]->isVisible() && bars[other]->isVisible()) - idx = other; // If the scrollbar of the event orientation is hidden, fallback to the other. - - QApplication::sendEvent(bars[idx], e); + if (static_cast<QWheelEvent*>(e)->orientation() == Qt::Horizontal) + QApplication::sendEvent(d->hbar, e); + else + QApplication::sendEvent(d->vbar, e); } #endif diff --git a/src/gui/widgets/qabstractslider.cpp b/src/gui/widgets/qabstractslider.cpp index 2874647..4bd7b5a 100644 --- a/src/gui/widgets/qabstractslider.cpp +++ b/src/gui/widgets/qabstractslider.cpp @@ -214,8 +214,8 @@ QT_BEGIN_NAMESPACE */ QAbstractSliderPrivate::QAbstractSliderPrivate() - : minimum(0), maximum(99), singleStep(1), pageStep(10), - value(0), position(0), pressValue(-1), offset_accumulated(0), tracking(true), + : minimum(0), maximum(99), pageStep(10), value(0), position(0), pressValue(-1), + singleStep(1), offset_accumulated(0), tracking(true), blocktracking(false), pressed(false), invertedAppearance(false), invertedControls(false), orientation(Qt::Horizontal), repeatAction(QAbstractSlider::SliderNoAction) @@ -688,51 +688,66 @@ void QAbstractSlider::sliderChange(SliderChange) update(); } - -/*! - \reimp -*/ -#ifndef QT_NO_WHEELEVENT -void QAbstractSlider::wheelEvent(QWheelEvent * e) +bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::KeyboardModifiers modifiers, int delta) { - Q_D(QAbstractSlider); - e->ignore(); - + Q_Q(QAbstractSlider); int stepsToScroll = 0; - qreal offset = qreal(e->delta()) / 120; + // in Qt scrolling to the right gives negative values. + if (orientation == Qt::Horizontal) + delta = -delta; + qreal offset = qreal(delta) / 120; - if ((e->modifiers() & Qt::ControlModifier) || (e->modifiers() & Qt::ShiftModifier)) { + if ((modifiers & Qt::ControlModifier) || (modifiers & Qt::ShiftModifier)) { // Scroll one page regardless of delta: - stepsToScroll = qBound(-d->pageStep, int(offset * d->pageStep), d->pageStep); - d->offset_accumulated = 0; + stepsToScroll = qBound(-pageStep, int(offset * pageStep), pageStep); + offset_accumulated = 0; } else { // Calculate how many lines to scroll. Depending on what delta is (and // offset), we might end up with a fraction (e.g. scroll 1.3 lines). We can // only scroll whole lines, so we keep the reminder until next event. - qreal stepsToScrollF = offset * QApplication::wheelScrollLines() * d->effectiveSingleStep(); + qreal stepsToScrollF = +#ifndef QT_NO_WHEELEVENT + QApplication::wheelScrollLines() * +#endif + offset * effectiveSingleStep(); // Check if wheel changed direction since last event: - if (d->offset_accumulated != 0 && (offset / d->offset_accumulated) < 0) - d->offset_accumulated = 0; + if (offset_accumulated != 0 && (offset / offset_accumulated) < 0) + offset_accumulated = 0; - d->offset_accumulated += stepsToScrollF; - stepsToScroll = qBound(-d->pageStep, int(d->offset_accumulated), d->pageStep); - d->offset_accumulated -= int(d->offset_accumulated); + offset_accumulated += stepsToScrollF; + stepsToScroll = qBound(-pageStep, int(offset_accumulated), pageStep); + offset_accumulated -= int(offset_accumulated); if (stepsToScroll == 0) - return; + return false; } - if (d->invertedControls) + if (invertedControls) stepsToScroll = -stepsToScroll; - int prevValue = d->value; - d->position = d->overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction() - triggerAction(SliderMove); + int prevValue = value; + position = overflowSafeAdd(stepsToScroll); // value will be updated by triggerAction() + q->triggerAction(QAbstractSlider::SliderMove); - if (prevValue == d->value) - d->offset_accumulated = 0; - else + if (prevValue == value) { + offset_accumulated = 0; + return false; + } + return true; +} + +/*! + \reimp +*/ +#ifndef QT_NO_WHEELEVENT +void QAbstractSlider::wheelEvent(QWheelEvent * e) +{ + Q_D(QAbstractSlider); + e->ignore(); + int delta = e->delta(); + if (d->scrollByDelta(e->orientation(), e->modifiers(), delta)) e->accept(); } + #endif #ifdef QT_KEYPAD_NAVIGATION /*! diff --git a/src/gui/widgets/qabstractslider_p.h b/src/gui/widgets/qabstractslider_p.h index 6cde468..6e6ff6e 100644 --- a/src/gui/widgets/qabstractslider_p.h +++ b/src/gui/widgets/qabstractslider_p.h @@ -138,6 +138,7 @@ public: } q->triggerAction(repeatAction); } + bool scrollByDelta(Qt::Orientation orientation, Qt::KeyboardModifiers modifiers, int delta); }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qabstractspinbox.h b/src/gui/widgets/qabstractspinbox.h index 059943a..6c062c0 100644 --- a/src/gui/widgets/qabstractspinbox.h +++ b/src/gui/widgets/qabstractspinbox.h @@ -137,7 +137,9 @@ protected: void resizeEvent(QResizeEvent *event); void keyPressEvent(QKeyEvent *event); void keyReleaseEvent(QKeyEvent *event); +#ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent *event); +#endif void focusInEvent(QFocusEvent *event); void focusOutEvent(QFocusEvent *event); void contextMenuEvent(QContextMenuEvent *event); diff --git a/src/gui/widgets/qcombobox.h b/src/gui/widgets/qcombobox.h index f332d31..9b19a66 100644 --- a/src/gui/widgets/qcombobox.h +++ b/src/gui/widgets/qcombobox.h @@ -245,7 +245,9 @@ protected: void mouseReleaseEvent(QMouseEvent *e); void keyPressEvent(QKeyEvent *e); void keyReleaseEvent(QKeyEvent *e); +#ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent *e); +#endif void contextMenuEvent(QContextMenuEvent *e); void inputMethodEvent(QInputMethodEvent *); QVariant inputMethodQuery(Qt::InputMethodQuery) const; diff --git a/src/gui/widgets/qdialogbuttonbox.cpp b/src/gui/widgets/qdialogbuttonbox.cpp index 48d7022..6a0e363 100644 --- a/src/gui/widgets/qdialogbuttonbox.cpp +++ b/src/gui/widgets/qdialogbuttonbox.cpp @@ -1017,6 +1017,8 @@ void QDialogButtonBox::removeButton(QAbstractButton *button) If the button has already been added, it is removed and added again with the new role. + \note The button box takes ownership of the button. + \sa removeButton(), clear() */ void QDialogButtonBox::addButton(QAbstractButton *button, ButtonRole role) diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index 414c2ed..db099e8 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -524,8 +524,11 @@ void QLineControl::draw(QPainter *painter, const QPoint &offset, const QRect &cl m_textLayout.draw(painter, offset, selections, clip); if (flags & DrawCursor){ + int cursor = m_cursor; + if (m_preeditCursor != -1) + cursor += m_preeditCursor; if(!m_blinkPeriod || m_blinkStatus) - m_textLayout.drawCursor(painter, offset, m_cursor, m_cursorWidth); + m_textLayout.drawCursor(painter, offset, cursor, m_cursorWidth); } } @@ -1368,6 +1371,8 @@ bool QLineControl::processEvent(QEvent* ev) processInputMethodEvent(static_cast<QInputMethodEvent*>(ev)); break; #ifndef QT_NO_SHORTCUT case QEvent::ShortcutOverride:{ + if (isReadOnly()) + return false; QKeyEvent* ke = static_cast<QKeyEvent*>(ev); if (ke == QKeySequence::Copy || ke == QKeySequence::Paste diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 301ff72..d6f2705 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -549,7 +549,10 @@ inline qreal QLineControl::cursorToX(int cursor) const inline qreal QLineControl::cursorToX() const { - return cursorToX(m_cursor); + int cursor = m_cursor; + if (m_preeditCursor != -1) + cursor += m_preeditCursor; + return cursorToX(cursor); } inline bool QLineControl::isReadOnly() const diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 1622191..269cd12 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -119,8 +119,6 @@ void QMainWindowPrivate::init() q->setAttribute(Qt::WA_Hover); #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/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index d1e7285..fc75c92 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -1627,6 +1627,13 @@ void QMainWindowLayout::animationFinished(QWidget *widget) tb->d_func()->plug(currentGapRect); #endif + savedState.clear(); + currentGapPos.clear(); + pluggingWidget = 0; + //applying the state will make sure that the currentGap is updated correctly + //and all the geometries (especially the one from the central widget) is correct + layoutState.apply(false); + #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR if (qobject_cast<QDockWidget*>(widget) != 0) { @@ -1637,13 +1644,6 @@ void QMainWindowLayout::animationFinished(QWidget *widget) } #endif #endif - - savedState.clear(); - currentGapPos.clear(); - pluggingWidget = 0; - //applying the state will make sure that the currentGap is updated correctly - //and all the geometries (especially the one from the central widget) is correct - layoutState.apply(false); } if (!widgetAnimator.animating()) { diff --git a/src/gui/widgets/qmainwindowlayout_mac.mm b/src/gui/widgets/qmainwindowlayout_mac.mm index ee79f5a..d92168a 100644 --- a/src/gui/widgets/qmainwindowlayout_mac.mm +++ b/src/gui/widgets/qmainwindowlayout_mac.mm @@ -472,14 +472,20 @@ void QMainWindowLayout::removeFromMacToolbar(QToolBar *toolbar) void QMainWindowLayout::cleanUpMacToolbarItems() { - for (int i = 0; i < toolbarItemsCopy.size(); ++i) +#ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; +#endif + for (int i = 0; i < toolbarItemsCopy.size(); ++i) { +#ifdef QT_MAC_USE_COCOA + NSToolbarItem *item = static_cast<NSToolbarItem *>(toolbarItemsCopy.at(i)); + [item setView:0]; +#endif CFRelease(toolbarItemsCopy.at(i)); + } toolbarItemsCopy.clear(); unifiedToolbarHash.clear(); #ifdef QT_MAC_USE_COCOA - QMacCocoaAutoReleasePool pool; - OSWindowRef window = qt_mac_window_for(layoutState.mainWindow); NSToolbar *macToolbar = [window toolbar]; if (macToolbar) { diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index 5031d88..8ce7cc0 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -1588,10 +1588,9 @@ QAction *QMenu::insertSeparator(QAction *before) } /*! - This will set the default action to \a act. The default action may - have a visual queue depending on the current QStyle. A default - action is usually meant to indicate what will defaultly happen on a - drop, as shown in a context menu. + This sets the default action to \a act. The default action may have + a visual cue, depending on the current QStyle. A default action + usually indicates what will happen by default when a drop occurs. \sa defaultAction() */ diff --git a/src/gui/widgets/qmenu.h b/src/gui/widgets/qmenu.h index 5a6a5c7..47dff2b 100644 --- a/src/gui/widgets/qmenu.h +++ b/src/gui/widgets/qmenu.h @@ -162,7 +162,9 @@ protected: void mouseReleaseEvent(QMouseEvent *); void mousePressEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); +#ifndef QT_NO_WHEELEVENT void wheelEvent(QWheelEvent *); +#endif void enterEvent(QEvent *); void leaveEvent(QEvent *); void hideEvent(QHideEvent *); diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm index cd7f9bd..7e4bbb5 100644 --- a/src/gui/widgets/qmenu_mac.mm +++ b/src/gui/widgets/qmenu_mac.mm @@ -175,6 +175,22 @@ static quint32 constructModifierMask(quint32 accel_key) return ret; } +static void cancelAllMenuTracking() +{ +#ifdef QT_MAC_USE_COCOA + QMacCocoaAutoReleasePool pool; + NSMenu *mainMenu = [NSApp mainMenu]; + [mainMenu cancelTracking]; + for (NSMenuItem *item in [mainMenu itemArray]) { + if ([item submenu]) { + [[item submenu] cancelTracking]; + } + } +#else + CancelMenuTracking(AcquireRootMenu(), true, 0); +#endif +} + static bool actualMenuItemVisibility(const QMenuBarPrivate::QMacMenuBarPrivate *mbp, const QMacMenuAction *action) { @@ -1830,6 +1846,12 @@ void QMenuBarPrivate::macDestroyMenuBar() mac_menubar = 0; if (qt_mac_current_menubar.qmenubar == q) { +#ifdef QT_MAC_USE_COCOA + QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader(); + [loader removeActionsFromAppMenu]; +#else + cancelAllMenuTracking(); +#endif extern void qt_event_request_menubarupdate(); //qapplication_mac.cpp qt_event_request_menubarupdate(); } @@ -1933,20 +1955,6 @@ static bool qt_mac_should_disable_menu(QMenuBar *menuBar, QWidget *modalWidget) return qt_mac_is_ancestor(menuBar->parentWidget(), modalWidget); } -static void cancelAllMenuTracking() -{ -#ifdef QT_MAC_USE_COCOA - QMacCocoaAutoReleasePool pool; - NSMenu *mainMenu = [NSApp mainMenu]; - [mainMenu cancelTracking]; - for (NSMenuItem *item in [mainMenu itemArray]) { - if ([item submenu]) { - [[item submenu] cancelTracking]; - } - } -#endif -} - /*! \internal diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index b7272f7..aaed6b1 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -71,6 +71,7 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_MENU #ifdef Q_WS_S60 +void qt_symbian_next_menu_from_action(QWidget* actionContainer); void qt_symbian_show_toplevel(CEikMenuPane* menuPane); void qt_symbian_show_submenu(CEikMenuPane* menuPane, int id); #endif // Q_WS_S60 @@ -87,7 +88,7 @@ QT_BEGIN_NAMESPACE typedef void NSMenuItem; # endif //__OBJC__ struct QMacMenuAction { - QMacMenuAction() + QMacMenuAction() #ifndef QT_MAC_USE_COCOA : command(0) #else @@ -124,7 +125,7 @@ typedef QList<QMenuMergeItem> QMenuMergeList; #ifdef Q_WS_WINCE struct QWceMenuAction { - uint command; + uint command; QPointer<QAction> action; HMENU menuHandle; QWceMenuAction() : menuHandle(0), command(0) {} @@ -340,7 +341,7 @@ public: QList<QWceMenuAction*> actionItems; HMENU menuHandle; QWceMenuPrivate(); - ~QWceMenuPrivate(); + ~QWceMenuPrivate(); void addAction(QAction *, QWceMenuAction* =0); void addAction(QWceMenuAction *, QWceMenuAction* =0); void syncAction(QWceMenuAction *); diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp index b8370ec..c064791 100644 --- a/src/gui/widgets/qmenu_symbian.cpp +++ b/src/gui/widgets/qmenu_symbian.cpp @@ -81,6 +81,7 @@ static QList<QMenuBar*> nativeMenuBars; static uint qt_symbian_menu_static_cmd_id = QT_SYMBIAN_FIRST_MENU_ITEM; static QPointer<QWidget> widgetWithContextMenu; static QList<QAction*> contextMenuActionList; +static QWidget* actionMenu = NULL; static int contexMenuCommand=0; bool menuExists() @@ -224,8 +225,26 @@ static void rebuildMenu() } #ifdef Q_WS_S60 +void qt_symbian_next_menu_from_action(QWidget *actionContainer) +{ + actionMenu = actionContainer; +} + void qt_symbian_show_toplevel( CEikMenuPane* menuPane) { + if (actionMenu) { + QMenuBarPrivate *mb = 0; + mb = menubars()->value(actionMenu); + qt_symbian_menu_static_cmd_id = QT_SYMBIAN_FIRST_MENU_ITEM; + deleteAll( &symbianMenus ); + Q_ASSERT(mb); + mb->symbian_menubar->rebuild(); + for (int i = 0; i < symbianMenus.count(); ++i) + QT_TRAP_THROWING(menuPane->AddMenuItemL(symbianMenus.at(i)->menuItemData)); + actionMenu = NULL; + return; + } + if (!menuExists()) return; rebuildMenu(); @@ -271,10 +290,16 @@ int QMenuBarPrivate::symbianCommands(int command) void QMenuBarPrivate::symbianCreateMenuBar(QWidget *parent) { Q_Q(QMenuBar); - if (parent && parent->isWindow()){ - menubars()->insert(q->window(), this); - symbian_menubar = new QSymbianMenuBarPrivate(this); - nativeMenuBars.append(q); + if (parent) { + if(parent->isWindow()) { + menubars()->insert(q->window(), this); + symbian_menubar = new QSymbianMenuBarPrivate(this); + nativeMenuBars.append(q); + } else { + menubars()->insert(q->parentWidget(), this); + symbian_menubar = new QSymbianMenuBarPrivate(this); + nativeMenuBars.append(q); + } } } @@ -284,6 +309,7 @@ void QMenuBarPrivate::symbianDestroyMenuBar() int index = nativeMenuBars.indexOf(q); nativeMenuBars.removeAt(index); menubars()->remove(q->window(), this); + menubars()->remove(q->parentWidget(), this); rebuildMenu(); if (symbian_menubar) delete symbian_menubar; diff --git a/src/gui/widgets/qmenubar.cpp b/src/gui/widgets/qmenubar.cpp index 0e14385..9caadb7 100644 --- a/src/gui/widgets/qmenubar.cpp +++ b/src/gui/widgets/qmenubar.cpp @@ -667,7 +667,7 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti \i Application Menu | About <application name> \i The application name is fetched from the \c {Info.plist} file (see note below). If this entry is not found no About item - will appear in the Application Menu. + will appear in the Application Menu. \row \i config, options, setup, settings or preferences \i Application Menu | Preferences \i If this entry is not found the Settings item will be disabled diff --git a/src/gui/widgets/qprintpreviewwidget.cpp b/src/gui/widgets/qprintpreviewwidget.cpp index 747a227..45b15ef 100644 --- a/src/gui/widgets/qprintpreviewwidget.cpp +++ b/src/gui/widgets/qprintpreviewwidget.cpp @@ -151,7 +151,11 @@ class GraphicsView : public QGraphicsView public: GraphicsView(QWidget* parent = 0) : QGraphicsView(parent) - {} + { +#ifdef Q_WS_MAC + setFrameStyle(QFrame::NoFrame); +#endif + } signals: void resized(); diff --git a/src/gui/widgets/qscrollbar.cpp b/src/gui/widgets/qscrollbar.cpp index 73ce122..4eff260 100644 --- a/src/gui/widgets/qscrollbar.cpp +++ b/src/gui/widgets/qscrollbar.cpp @@ -521,6 +521,24 @@ bool QScrollBar::event(QEvent *event) if (const QHoverEvent *he = static_cast<const QHoverEvent *>(event)) d_func()->updateHoverControl(he->pos()); break; +#ifndef QT_NO_WHEELEVENT + case QEvent::Wheel: { + // override wheel event without adding virtual function override + QWheelEvent *ev = static_cast<QWheelEvent *>(event); + int delta = ev->delta(); + // scrollbar is a special case - in vertical mode it reaches minimum + // value in the upper position, however QSlider's minimum value is on + // the bottom. So we need to invert a value, but since the scrollbar is + // inverted by default, we need to inverse the delta value for the + // horizontal orientation. + if (ev->orientation() == Qt::Horizontal) + delta = -delta; + Q_D(QScrollBar); + if (d->scrollByDelta(ev->orientation(), ev->modifiers(), delta)) + event->accept(); + return true; + } +#endif default: break; } diff --git a/src/gui/widgets/qtoolbar.cpp b/src/gui/widgets/qtoolbar.cpp index 53050ac..8beda55 100644 --- a/src/gui/widgets/qtoolbar.cpp +++ b/src/gui/widgets/qtoolbar.cpp @@ -441,8 +441,7 @@ void QToolBarPrivate::plug(const QRect &r) When a QToolBar is not a child of a QMainWindow, it looses the ability to populate the extension pop up with widgets added to the toolbar using addWidget(). Please use widget actions created by inheriting QWidgetAction - and implementing QWidgetAction::createWidget() instead. This is a known - issue which will be fixed in a future release. + and implementing QWidgetAction::createWidget() instead. \sa QToolButton, QMenu, QAction, {Application Example} */ diff --git a/src/network/access/qfilenetworkreply.cpp b/src/network/access/qfilenetworkreply.cpp index 8c5065c..4ac9a8c 100644 --- a/src/network/access/qfilenetworkreply.cpp +++ b/src/network/access/qfilenetworkreply.cpp @@ -49,10 +49,15 @@ QT_BEGIN_NAMESPACE QFileNetworkReplyPrivate::QFileNetworkReplyPrivate() - : QNetworkReplyPrivate(), realFileSize(0) + : QNetworkReplyPrivate(), fileEngine(0), fileSize(0), filePos(0) { } +QFileNetworkReplyPrivate::~QFileNetworkReplyPrivate() +{ + delete fileEngine; +} + QFileNetworkReply::~QFileNetworkReply() { } @@ -94,9 +99,8 @@ QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req if (fileName.isEmpty()) { fileName = url.toString(QUrl::RemoveAuthority | QUrl::RemoveFragment | QUrl::RemoveQuery); } - d->realFile.setFileName(fileName); - QFileInfo fi(d->realFile); + QFileInfo fi(fileName); if (fi.isDir()) { QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Cannot open %1: Path is a directory").arg(url.toString()); setError(QNetworkReply::ContentOperationNotPermittedError, msg); @@ -106,14 +110,15 @@ QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req return; } - bool opened = d->realFile.open(QIODevice::ReadOnly | QIODevice::Unbuffered); + d->fileEngine = QAbstractFileEngine::create(fileName); + bool opened = d->fileEngine->open(QIODevice::ReadOnly | QIODevice::Unbuffered); // could we open the file? if (!opened) { QString msg = QCoreApplication::translate("QNetworkAccessFileBackend", "Error opening %1: %2") - .arg(d->realFile.fileName(), d->realFile.errorString()); + .arg(fileName, d->fileEngine->errorString()); - if (d->realFile.exists()) { + if (fi.exists()) { setError(QNetworkReply::ContentAccessDenied, msg); QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ContentAccessDenied)); @@ -126,13 +131,13 @@ QFileNetworkReply::QFileNetworkReply(QObject *parent, const QNetworkRequest &req return; } - d->realFileSize = fi.size(); + d->fileSize = fi.size(); setHeader(QNetworkRequest::LastModifiedHeader, fi.lastModified()); - setHeader(QNetworkRequest::ContentLengthHeader, d->realFileSize); + setHeader(QNetworkRequest::ContentLengthHeader, d->fileSize); QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "downloadProgress", Qt::QueuedConnection, - Q_ARG(qint64, d->realFileSize), Q_ARG(qint64, d->realFileSize)); + Q_ARG(qint64, d->fileSize), Q_ARG(qint64, d->fileSize)); QMetaObject::invokeMethod(this, "readyRead", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); } @@ -146,20 +151,25 @@ void QFileNetworkReply::close() { Q_D(QFileNetworkReply); QNetworkReply::close(); - d->realFile.close(); + if (d->fileEngine) + d->fileEngine->close(); } void QFileNetworkReply::abort() { Q_D(QFileNetworkReply); QNetworkReply::close(); - d->realFile.close(); + if (d->fileEngine) + d->fileEngine->close(); } qint64 QFileNetworkReply::bytesAvailable() const { Q_D(const QFileNetworkReply); - return QNetworkReply::bytesAvailable() + d->realFile.bytesAvailable(); + if (!d->fileEngine) + return 0; + + return QNetworkReply::bytesAvailable() + d->fileSize - d->filePos; } bool QFileNetworkReply::isSequential () const @@ -170,7 +180,7 @@ bool QFileNetworkReply::isSequential () const qint64 QFileNetworkReply::size() const { Q_D(const QFileNetworkReply); - return d->realFileSize; + return d->fileSize; } /*! @@ -179,11 +189,17 @@ qint64 QFileNetworkReply::size() const qint64 QFileNetworkReply::readData(char *data, qint64 maxlen) { Q_D(QFileNetworkReply); - qint64 ret = d->realFile.read(data, maxlen); - if (ret == 0 && bytesAvailable() == 0) + if (!d->fileEngine) + return -1; + + qint64 ret = d->fileEngine->read(data, maxlen); + if (ret == 0 && bytesAvailable() == 0) { return -1; // everything had been read - else - return ret; + } else if (ret > 0) { + d->filePos += ret; + } + + return ret; } diff --git a/src/network/access/qfilenetworkreply_p.h b/src/network/access/qfilenetworkreply_p.h index 125fa2e..710ec9f 100644 --- a/src/network/access/qfilenetworkreply_p.h +++ b/src/network/access/qfilenetworkreply_p.h @@ -57,6 +57,7 @@ #include "qnetworkreply_p.h" #include "qnetworkaccessmanager.h" #include <QFile> +#include <QAbstractFileEngine> QT_BEGIN_NAMESPACE @@ -85,9 +86,11 @@ class QFileNetworkReplyPrivate: public QNetworkReplyPrivate { public: QFileNetworkReplyPrivate(); + ~QFileNetworkReplyPrivate(); - QFile realFile; - qint64 realFileSize; + QAbstractFileEngine *fileEngine; + qint64 fileSize; + qint64 filePos; virtual bool isFinished() const; diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index fff7097..cc6a1c8 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -688,8 +688,14 @@ void QHttpNetworkConnectionPrivate::_q_startNextRequest() if (channels[i].resendCurrent) { channels[i].resendCurrent = false; channels[i].state = QHttpNetworkConnectionChannel::IdleState; - if (channels[i].reply) + if (channels[i].reply) { + + // if this is not possible, error will be emitted and connection terminated + if (!channels[i].resetUploadData()) + continue; + channels[i].sendRequest(); + } } } diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index b80ae9a..b0e632a 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -286,7 +286,6 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() if (!socket->bytesAvailable()) { if (reply && reply->d_func()->state == QHttpNetworkReplyPrivate::ReadingDataState) { reply->d_func()->state = QHttpNetworkReplyPrivate::AllDoneState; - this->state = QHttpNetworkConnectionChannel::IdleState; allDone(); } else { // try to reconnect/resend before sending an error. @@ -305,9 +304,12 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() while (socket->bytesAvailable()) { QHttpNetworkReplyPrivate::ReplyState state = reply ? reply->d_func()->state : QHttpNetworkReplyPrivate::AllDoneState; switch (state) { - case QHttpNetworkReplyPrivate::NothingDoneState: - case QHttpNetworkReplyPrivate::ReadingStatusState: { + case QHttpNetworkReplyPrivate::NothingDoneState: { + // only eat whitespace on the first call eatWhitespace(); + state = reply->d_func()->state = QHttpNetworkReplyPrivate::ReadingStatusState; + } + case QHttpNetworkReplyPrivate::ReadingStatusState: { qint64 statusBytes = reply->d_func()->readStatus(socket); if (statusBytes == -1 && reconnectAttempts <= 0) { // too many errors reading/receiving/parsing the status, close the socket and emit error @@ -344,7 +346,6 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() emit reply->headerChanged(); if (!replyPrivate->expectContent()) { replyPrivate->state = QHttpNetworkReplyPrivate::AllDoneState; - this->state = QHttpNetworkConnectionChannel::IdleState; allDone(); return; } @@ -421,7 +422,6 @@ void QHttpNetworkConnectionChannel::_q_receiveReply() // everything done, fall through } case QHttpNetworkReplyPrivate::AllDoneState: - this->state = QHttpNetworkConnectionChannel::IdleState; allDone(); break; default: @@ -567,6 +567,9 @@ void QHttpNetworkConnectionChannel::allDone() // in case of failures, each channel will attempt two reconnects before emitting error. reconnectAttempts = 2; + // now the channel can be seen as free/idle again, all signal emissions for the reply have been done + this->state = QHttpNetworkConnectionChannel::IdleState; + detectPipeliningSupport(); // move next from pipeline to current request @@ -607,19 +610,19 @@ void QHttpNetworkConnectionChannel::allDone() void QHttpNetworkConnectionChannel::detectPipeliningSupport() { // detect HTTP Pipelining support - QByteArray serverHeaderField = reply->headerField("Server"); + QByteArray serverHeaderField; if ( - // check for broken servers in server reply header - // this is adapted from http://mxr.mozilla.org/firefox/ident?i=SupportsPipelining - (!serverHeaderField.contains("Microsoft-IIS/4.")) - && (!serverHeaderField.contains("Microsoft-IIS/5.")) - && (!serverHeaderField.contains("Netscape-Enterprise/3.")) // check for HTTP/1.1 - && (reply->d_func()->majorVersion == 1 && reply->d_func()->minorVersion == 1) + (reply->d_func()->majorVersion == 1 && reply->d_func()->minorVersion == 1) // check for not having connection close && (!reply->d_func()->isConnectionCloseEnabled()) // check if it is still connected && (socket->state() == QAbstractSocket::ConnectedState) + // check for broken servers in server reply header + // this is adapted from http://mxr.mozilla.org/firefox/ident?i=SupportsPipelining + && (serverHeaderField = reply->headerField("Server"), !serverHeaderField.contains("Microsoft-IIS/4.")) + && (!serverHeaderField.contains("Microsoft-IIS/5.")) + && (!serverHeaderField.contains("Netscape-Enterprise/3.")) ) { pipeliningSupported = QHttpNetworkConnectionChannel::PipeliningProbablySupported; } else { @@ -674,15 +677,8 @@ void QHttpNetworkConnectionChannel::handleStatus() case 407: // proxy auth required if (connection->d_func()->handleAuthenticateChallenge(socket, reply, (statusCode == 407), resend)) { if (resend) { - QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice(); - if (uploadByteDevice) { - if (uploadByteDevice->reset()) { - written = 0; - } else { - connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ContentReSendError); - break; - } - } + if (!resetUploadData()) + break; reply->d_func()->eraseData(); @@ -712,6 +708,22 @@ void QHttpNetworkConnectionChannel::handleStatus() } } +bool QHttpNetworkConnectionChannel::resetUploadData() +{ + QNonContiguousByteDevice* uploadByteDevice = request.uploadByteDevice(); + if (!uploadByteDevice) + return true; + + if (uploadByteDevice->reset()) { + written = 0; + return true; + } else { + connection->d_func()->emitReplyError(socket, reply, QNetworkReply::ContentReSendError); + return false; + } +} + + void QHttpNetworkConnectionChannel::pipelineInto(HttpMessagePair &pair) { // this is only called for simple GET diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h index c30c236..75ab50d 100644 --- a/src/network/access/qhttpnetworkconnectionchannel_p.h +++ b/src/network/access/qhttpnetworkconnectionchannel_p.h @@ -151,6 +151,8 @@ public: void allDone(); // reply header + body have been read void handleStatus(); // called from allDone() + bool resetUploadData(); // return true if resetting worked or there is no upload data + void pipelineInto(HttpMessagePair &pair); void requeueCurrentlyPipelinedRequests(); void detectPipeliningSupport(); diff --git a/src/network/access/qhttpnetworkheader.cpp b/src/network/access/qhttpnetworkheader.cpp index c2cc69c..669f9cf 100644 --- a/src/network/access/qhttpnetworkheader.cpp +++ b/src/network/access/qhttpnetworkheader.cpp @@ -80,7 +80,7 @@ QByteArray QHttpNetworkHeaderPrivate::headerField(const QByteArray &name, const QByteArray result; bool first = true; - foreach (QByteArray value, allValues) { + foreach (const QByteArray &value, allValues) { if (!first) result += ", "; first = false; diff --git a/src/network/access/qhttpnetworkreply.cpp b/src/network/access/qhttpnetworkreply.cpp index a5223d1..512c045 100644 --- a/src/network/access/qhttpnetworkreply.cpp +++ b/src/network/access/qhttpnetworkreply.cpp @@ -423,13 +423,26 @@ int QHttpNetworkReplyPrivate::gunzipBodyPartially(QByteArray &compressed, QByteA qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) { + if (fragment.isEmpty()) { + // reserve bytes for the status line. This is better than always append() which reallocs the byte array + fragment.reserve(32); + } + qint64 bytes = 0; char c; + qint64 haveRead = 0; + + do { + haveRead = socket->read(&c, 1); + if (haveRead == -1) + return -1; // unexpected EOF + else if (haveRead == 0) + break; // read more later + + bytes++; - while (socket->bytesAvailable()) { // allow both CRLF & LF (only) line endings - if (socket->peek(&c, 1) == 1 && c == '\n') { - bytes += socket->read(&c, 1); // read the "n" + if (c == '\n') { // remove the CR at the end if (fragment.endsWith('\r')) { fragment.truncate(fragment.length()-1); @@ -442,11 +455,6 @@ qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) } break; } else { - c = 0; - int haveRead = socket->read(&c, 1); - if (haveRead == -1) - return -1; - bytes += haveRead; fragment.append(c); } @@ -456,8 +464,7 @@ qint64 QHttpNetworkReplyPrivate::readStatus(QAbstractSocket *socket) fragment.clear(); return -1; } - - } + } while (haveRead == 1); return bytes; } @@ -500,20 +507,41 @@ bool QHttpNetworkReplyPrivate::parseStatus(const QByteArray &status) qint64 QHttpNetworkReplyPrivate::readHeader(QAbstractSocket *socket) { + if (fragment.isEmpty()) { + // according to http://dev.opera.com/articles/view/mama-http-headers/ the average size of the header + // block is 381 bytes. + // reserve bytes. This is better than always append() which reallocs the byte array. + fragment.reserve(512); + } + qint64 bytes = 0; char c = 0; bool allHeaders = false; - while (!allHeaders && socket->bytesAvailable()) { - if (socket->peek(&c, 1) == 1 && c == '\n') { - // check for possible header endings. As per HTTP rfc, - // the header endings will be marked by CRLFCRLF. But - // we will allow CRLFLF, LFLF & CRLFCRLF - if (fragment.endsWith("\n\r") || fragment.endsWith('\n')) - allHeaders = true; + qint64 haveRead = 0; + do { + haveRead = socket->read(&c, 1); + if (haveRead == 0) { + // read more later + break; + } else if (haveRead == -1) { + // connection broke down + return -1; + } else { + fragment.append(c); + bytes++; + + if (c == '\n') { + // check for possible header endings. As per HTTP rfc, + // the header endings will be marked by CRLFCRLF. But + // we will allow CRLFCRLF, CRLFLF, LFLF + if (fragment.endsWith("\r\n\r\n") + || fragment.endsWith("\r\n\n") + || fragment.endsWith("\n\n")) + allHeaders = true; + } } - bytes += socket->read(&c, 1); - fragment.append(c); - } + } while (!allHeaders && haveRead > 0); + // we received all headers now parse them if (allHeaders) { parseHeader(fragment); diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index 58123b2..61a95fe 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -753,7 +753,7 @@ void QNetworkAccessHttpBackend::replyHeaderChanged() QByteArray value = rawHeader(it->first); if (!value.isEmpty()) { if (qstricmp(it->first.constData(), "set-cookie") == 0) - value += "\n"; + value += '\n'; else value += ", "; } diff --git a/src/network/access/qnetworkcookie.h b/src/network/access/qnetworkcookie.h index f34396f..3cc4cee 100644 --- a/src/network/access/qnetworkcookie.h +++ b/src/network/access/qnetworkcookie.h @@ -114,7 +114,7 @@ Q_NETWORK_EXPORT QDebug operator<<(QDebug, const QNetworkCookie &); QT_END_NAMESPACE // ### Qt5 remove this include -#include "qnetworkcookiejar.h" +#include <QtNetwork/QNetworkCookieJar> Q_DECLARE_METATYPE(QNetworkCookie) Q_DECLARE_METATYPE(QList<QNetworkCookie>) diff --git a/src/network/access/qnetworkcookiejar.h b/src/network/access/qnetworkcookiejar.h index 813bf3e..8086f38 100644 --- a/src/network/access/qnetworkcookiejar.h +++ b/src/network/access/qnetworkcookiejar.h @@ -46,7 +46,7 @@ #include <QtCore/QUrl> // ### Qt5 remove this include -#include "qnetworkcookie.h" +#include <QtNetwork/QNetworkCookie> QT_BEGIN_HEADER diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 6dcd05d..a2bef67 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -649,7 +649,7 @@ static QVariant parseCookieHeader(const QByteArray &raw) { QList<QNetworkCookie> result; QList<QByteArray> cookieList = raw.split(';'); - foreach (QByteArray cookie, cookieList) { + foreach (const QByteArray &cookie, cookieList) { QList<QNetworkCookie> parsed = QNetworkCookie::parseCookies(cookie.trimmed()); if (parsed.count() != 1) return QVariant(); // invalid Cookie: header diff --git a/src/network/kernel/qauthenticator.cpp b/src/network/kernel/qauthenticator.cpp index 193a043..e4023c8 100644 --- a/src/network/kernel/qauthenticator.cpp +++ b/src/network/kernel/qauthenticator.cpp @@ -270,7 +270,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QHttpResponseHeader &header, break; case Ntlm: // #### extract from header - realm = QString(); + realm.clear(); break; case DigestMd5: { realm = QString::fromLatin1(options.value("realm")); @@ -281,7 +281,7 @@ void QAuthenticatorPrivate::parseHttpResponse(const QHttpResponseHeader &header, break; } default: - realm = QString(); + realm.clear(); challenge = QByteArray(); phase = Invalid; } diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp index 367e3c4..1115c63 100644 --- a/src/network/kernel/qnetworkinterface.cpp +++ b/src/network/kernel/qnetworkinterface.cpp @@ -541,7 +541,7 @@ QList<QNetworkInterface> QNetworkInterface::allInterfaces() { QList<QSharedDataPointer<QNetworkInterfacePrivate> > privs = manager()->allInterfaces(); QList<QNetworkInterface> result; - foreach (QSharedDataPointer<QNetworkInterfacePrivate> p, privs) { + foreach (const QSharedDataPointer<QNetworkInterfacePrivate> &p, privs) { QNetworkInterface item; item.d = p; result << item; @@ -560,7 +560,7 @@ QList<QHostAddress> QNetworkInterface::allAddresses() { QList<QSharedDataPointer<QNetworkInterfacePrivate> > privs = manager()->allInterfaces(); QList<QHostAddress> result; - foreach (const QSharedDataPointer<QNetworkInterfacePrivate> p, privs) { + foreach (const QSharedDataPointer<QNetworkInterfacePrivate> &p, privs) { foreach (const QNetworkAddressEntry &entry, p->addressEntries) result += entry.ip(); } diff --git a/src/network/socket/qlocalserver.cpp b/src/network/socket/qlocalserver.cpp index ede3c89..ef7fc02 100644 --- a/src/network/socket/qlocalserver.cpp +++ b/src/network/socket/qlocalserver.cpp @@ -122,9 +122,9 @@ void QLocalServer::close() qDeleteAll(d->pendingConnections); d->pendingConnections.clear(); d->closeServer(); - d->serverName = QString(); - d->fullServerName = QString(); - d->errorString = QString(); + d->serverName.clear(); + d->fullServerName.clear(); + d->errorString.clear(); d->error = QAbstractSocket::UnknownSocketError; } @@ -226,8 +226,8 @@ bool QLocalServer::listen(const QString &name) } if (!d->listen(name)) { - d->serverName = QString(); - d->fullServerName = QString(); + d->serverName.clear(); + d->fullServerName.clear(); return false; } diff --git a/src/network/socket/qlocalsocket_tcp.cpp b/src/network/socket/qlocalsocket_tcp.cpp index 9f574d4..5b5e84f 100644 --- a/src/network/socket/qlocalsocket_tcp.cpp +++ b/src/network/socket/qlocalsocket_tcp.cpp @@ -102,8 +102,8 @@ void QLocalSocketPrivate::_q_stateChanged(QAbstractSocket::SocketState newState) switch(newState) { case QAbstractSocket::UnconnectedState: state = QLocalSocket::UnconnectedState; - serverName = QString(); - fullServerName = QString(); + serverName.clear(); + fullServerName.clear(); break; case QAbstractSocket::ConnectingState: state = QLocalSocket::ConnectingState; @@ -218,7 +218,7 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) || state() == ConnectingState) return; - d->errorString = QString(); + d->errorString.clear(); d->state = ConnectingState; emit stateChanged(d->state); @@ -333,8 +333,8 @@ void QLocalSocket::close() { Q_D(QLocalSocket); d->tcpSocket->close(); - d->serverName = QString(); - d->fullServerName = QString(); + d->serverName.clear(); + d->fullServerName.clear(); QIODevice::close(); } diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp index 73c2465..1ca11d8 100644 --- a/src/network/socket/qlocalsocket_unix.cpp +++ b/src/network/socket/qlocalsocket_unix.cpp @@ -109,8 +109,8 @@ void QLocalSocketPrivate::_q_stateChanged(QAbstractSocket::SocketState newState) switch(newState) { case QAbstractSocket::UnconnectedState: state = QLocalSocket::UnconnectedState; - serverName = QString(); - fullServerName = QString(); + serverName.clear(); + fullServerName.clear(); break; case QAbstractSocket::ConnectingState: state = QLocalSocket::ConnectingState; @@ -225,7 +225,7 @@ void QLocalSocket::connectToServer(const QString &name, OpenMode openMode) || state() == ConnectingState) return; - d->errorString = QString(); + d->errorString.clear(); d->unixSocket.setSocketState(QAbstractSocket::ConnectingState); d->state = ConnectingState; emit stateChanged(d->state); @@ -341,7 +341,7 @@ void QLocalSocketPrivate::_q_connectToSocket() errorOccurred(QLocalSocket::UnknownSocketError, function); } connectingSocket = -1; - connectingName = QString(); + connectingName.clear(); connectingOpenMode = 0; } @@ -438,10 +438,10 @@ void QLocalSocket::close() if (d->connectingSocket != -1) ::close(d->connectingSocket); d->connectingSocket = -1; - d->connectingName = QString(); + d->connectingName.clear(); d->connectingOpenMode = 0; - d->serverName = QString(); - d->fullServerName = QString(); + d->serverName.clear(); + d->fullServerName.clear(); QIODevice::close(); } diff --git a/src/network/socket/qnativesocketengine.cpp b/src/network/socket/qnativesocketengine.cpp index 6e1df93..a890b3b 100644 --- a/src/network/socket/qnativesocketengine.cpp +++ b/src/network/socket/qnativesocketengine.cpp @@ -778,6 +778,14 @@ qint64 QNativeSocketEngine::read(char *data, qint64 maxSize) QNativeSocketEnginePrivate::RemoteHostClosedErrorString); close(); return -1; + } else if (readBytes == -1) { + if (!d->hasSetSocketError) { + d->hasSetSocketError = true; + d->socketError = QAbstractSocket::NetworkError; + d->socketErrorString = qt_error_string(); + } + close(); + return -1; } return readBytes; } diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index d3b0fe5..9a2c349 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -903,7 +903,7 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxSize) case EBADF: case EINVAL: case EIO: - setError(QAbstractSocket::NetworkError, ReadErrorString); + //error string is now set in read(), not here in nativeRead() break; #ifdef Q_OS_SYMBIAN case EPIPE: diff --git a/src/network/socket/qnativesocketengine_win.cpp b/src/network/socket/qnativesocketengine_win.cpp index 7088a57..8177b4f 100644 --- a/src/network/socket/qnativesocketengine_win.cpp +++ b/src/network/socket/qnativesocketengine_win.cpp @@ -1068,7 +1068,7 @@ qint64 QNativeSocketEnginePrivate::nativeRead(char *data, qint64 maxLength) break; case WSAEBADF: case WSAEINVAL: - setError(QAbstractSocket::NetworkError, ReadErrorString); + //error string is now set in read(), not here in nativeRead() break; case WSAECONNRESET: case WSAECONNABORTED: @@ -1199,8 +1199,10 @@ void QNativeSocketEnginePrivate::nativeClose() #if defined (QTCPSOCKETENGINE_DEBUG) qDebug("QNativeSocketEnginePrivate::nativeClose()"); #endif - linger l = {1, 0}; - ::setsockopt(socketDescriptor, SOL_SOCKET, SO_DONTLINGER, (char*)&l, sizeof(l)); + // We were doing a setsockopt here before with SO_DONTLINGER. (However with kind of wrong + // usage of parameters, it wants a BOOL but we used a struct and pretended it to be bool). + // We don't think setting this option should be done here, if a user wants it she/he can + // do it manually with socketDescriptor()/setSocketDescriptor(); ::closesocket(socketDescriptor); } diff --git a/src/network/socket/qtcpserver.cpp b/src/network/socket/qtcpserver.cpp index 47a998c..404eee7 100644 --- a/src/network/socket/qtcpserver.cpp +++ b/src/network/socket/qtcpserver.cpp @@ -513,6 +513,10 @@ bool QTcpServer::hasPendingConnections() const 0 is returned if this function is called when there are no pending connections. + \note The returned QTcpSocket object cannot be used from another + thread. If you want to use an incoming connection from another thread, + you need to override incomingConnection(). + \sa hasPendingConnections() */ QTcpSocket *QTcpServer::nextPendingConnection() @@ -543,6 +547,11 @@ QTcpSocket *QTcpServer::nextPendingConnection() may not be usable with native socket functions, and should only be used with QTcpSocket::setSocketDescriptor(). + \note If you want to handle an incoming connection as a new QTcpSocket + object in another thread you have to pass the socketDescriptor + to the other thread and create the QTcpSocket object there and + use its setSocketDescriptor() method. + \sa newConnection(), nextPendingConnection() */ void QTcpServer::incomingConnection(int socketDescriptor) diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 9a9b1b5..fd647e2 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -634,11 +634,11 @@ QByteArray QSslCertificatePrivate::QByteArray_from_X509(X509 *x509, QSsl::Encodi QByteArray tmp; for (int i = 0; i <= array.size() - 64; i += 64) { tmp += QByteArray::fromRawData(array.data() + i, 64); - tmp += "\n"; + tmp += '\n'; } if (int remainder = array.size() % 64) { tmp += QByteArray::fromRawData(array.data() + array.size() - remainder, remainder); - tmp += "\n"; + tmp += '\n'; } return BEGINCERTSTRING "\n" + tmp + ENDCERTSTRING "\n"; diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 6947aa7..9623570 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1109,7 +1109,7 @@ void QSslSocket::setCiphers(const QString &ciphers) { Q_D(QSslSocket); d->configuration.ciphers.clear(); - foreach (QString cipherName, ciphers.split(QLatin1String(":"),QString::SkipEmptyParts)) { + foreach (const QString &cipherName, ciphers.split(QLatin1String(":"),QString::SkipEmptyParts)) { for (int i = 0; i < 3; ++i) { // ### Crude QSslCipher cipher(cipherName, QSsl::SslProtocol(i)); diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp index 892d330..ce2aee1 100644 --- a/src/network/ssl/qsslsocket_openssl.cpp +++ b/src/network/ssl/qsslsocket_openssl.cpp @@ -818,7 +818,7 @@ bool QSslSocketBackendPrivate::startHandshake() QRegExp regexp(commonName, Qt::CaseInsensitive, QRegExp::Wildcard); if (!regexp.exactMatch(peerName)) { bool matched = false; - foreach (QString altName, configuration.peerCertificate + foreach (const QString &altName, configuration.peerCertificate .alternateSubjectNames().values(QSsl::DnsEntry)) { regexp.setPattern(altName); if (regexp.exactMatch(peerName)) { diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 556b888..8183f08 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -184,6 +184,9 @@ QGLEngineSharedShaders::QGLEngineSharedShaders(const QGLContext* context) simpleShaderProg->addShader(vertexShader); simpleShaderProg->addShader(fragShader); simpleShaderProg->bindAttributeLocation("vertexCoordsArray", QT_VERTEX_COORDS_ATTR); + simpleShaderProg->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); + simpleShaderProg->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); + simpleShaderProg->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); simpleShaderProg->link(); if (!simpleShaderProg->isLinked()) { qCritical() << "Errors linking simple shader:" @@ -324,6 +327,11 @@ QGLEngineShaderProg *QGLEngineSharedShaders::findProgramInCache(const QGLEngineS newProg->program->bindAttributeLocation("textureCoordArray", QT_TEXTURE_COORDS_ATTR); if (newProg->useOpacityAttribute) newProg->program->bindAttributeLocation("opacityArray", QT_OPACITY_ATTR); + if (newProg->usePmvMatrix) { + newProg->program->bindAttributeLocation("pmvMatrix1", QT_PMV_MATRIX_1_ATTR); + newProg->program->bindAttributeLocation("pmvMatrix2", QT_PMV_MATRIX_2_ATTR); + newProg->program->bindAttributeLocation("pmvMatrix3", QT_PMV_MATRIX_3_ATTR); + } newProg->program->link(); if (!newProg->program->isLinked()) { @@ -424,7 +432,6 @@ GLuint QGLEngineShaderManager::getUniformLocation(Uniform id) "patternColor", "globalOpacity", "depth", - "pmvMatrix", "maskTexture", "fragmentColor", "linearData", @@ -743,6 +750,7 @@ bool QGLEngineShaderManager::useCorrectShaderProg() } requiredProgram.useTextureCoords = texCoords; requiredProgram.useOpacityAttribute = (opacityMode == AttributeOpacity); + requiredProgram.usePmvMatrix = true; // At this point, requiredProgram is fully populated so try to find the program in the cache currentShaderProg = sharedShaders->findProgramInCache(requiredProgram); diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index c52e5c0..3ab4ebe 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -253,6 +253,9 @@ struct QGLEngineCachedShaderProg static const GLuint QT_VERTEX_COORDS_ATTR = 0; static const GLuint QT_TEXTURE_COORDS_ATTR = 1; static const GLuint QT_OPACITY_ATTR = 2; +static const GLuint QT_PMV_MATRIX_1_ATTR = 3; +static const GLuint QT_PMV_MATRIX_2_ATTR = 4; +static const GLuint QT_PMV_MATRIX_3_ATTR = 5; class QGLEngineShaderProg; @@ -397,6 +400,7 @@ public: bool useTextureCoords; bool useOpacityAttribute; + bool usePmvMatrix; bool operator==(const QGLEngineShaderProg& other) { // We don't care about the program @@ -431,7 +435,6 @@ public: PatternColor, GlobalOpacity, Depth, - PmvMatrix, MaskTexture, FragmentColor, LinearData, diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index d9a61e9..ee04166 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -63,210 +63,229 @@ QT_BEGIN_NAMESPACE QT_MODULE(OpenGL) -static const char* const qglslMainVertexShader = "\ - uniform highp float depth;\ - void setPosition();\ - void main(void)\ - {\ - setPosition();\ - gl_Position.z = depth * gl_Position.w;\ - }"; - -static const char* const qglslMainWithTexCoordsVertexShader = "\ - attribute highp vec2 textureCoordArray; \ - varying highp vec2 textureCoords; \ - uniform highp float depth;\ - void setPosition();\ - void main(void) \ - {\ - setPosition();\ - gl_Position.z = depth * gl_Position.w;\ - textureCoords = textureCoordArray; \ - }"; - -static const char* const qglslMainWithTexCoordsAndOpacityVertexShader = "\ - attribute highp vec2 textureCoordArray; \ - attribute lowp float opacityArray; \ - varying highp vec2 textureCoords; \ - varying lowp float opacity; \ - uniform highp float depth; \ - void setPosition(); \ - void main(void) \ - { \ - setPosition(); \ - gl_Position.z = depth * gl_Position.w; \ - textureCoords = textureCoordArray; \ - opacity = opacityArray; \ - }"; +static const char* const qglslMainVertexShader = "\n\ + void setPosition(); \n\ + void main(void) \n\ + { \n\ + setPosition(); \n\ + }\n"; + +static const char* const qglslMainWithTexCoordsVertexShader = "\n\ + attribute highp vec2 textureCoordArray; \n\ + varying highp vec2 textureCoords; \n\ + void setPosition(); \n\ + void main(void) \n\ + { \n\ + setPosition(); \n\ + textureCoords = textureCoordArray; \n\ + }\n"; + +static const char* const qglslMainWithTexCoordsAndOpacityVertexShader = "\n\ + attribute highp vec2 textureCoordArray; \n\ + attribute lowp float opacityArray; \n\ + varying highp vec2 textureCoords; \n\ + varying lowp float opacity; \n\ + void setPosition(); \n\ + void main(void) \n\ + { \n\ + setPosition(); \n\ + textureCoords = textureCoordArray; \n\ + opacity = opacityArray; \n\ + }\n"; // NOTE: We let GL do the perspective correction so texture lookups in the fragment // shader are also perspective corrected. -static const char* const qglslPositionOnlyVertexShader = "\ - attribute highp vec2 vertexCoordsArray;\ - uniform highp mat3 pmvMatrix;\ - void setPosition(void)\ - {\ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ - gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \ - }"; - -static const char* const qglslUntransformedPositionVertexShader = "\ - attribute highp vec4 vertexCoordsArray;\ - void setPosition(void)\ - {\ - gl_Position = vertexCoordsArray;\ - }"; +static const char* const qglslPositionOnlyVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + void setPosition(void) \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position = vec4(transformedPos.xy, 0.0, transformedPos.z); \n\ + }\n"; + +static const char* const qglslUntransformedPositionVertexShader = "\n\ + attribute highp vec4 vertexCoordsArray; \n\ + void setPosition(void) \n\ + { \n\ + gl_Position = vertexCoordsArray; \n\ + }\n"; // Pattern Brush - This assumes the texture size is 8x8 and thus, the inverted size is 0.125 -static const char* const qglslPositionWithPatternBrushVertexShader = "\ - attribute highp vec2 vertexCoordsArray; \ - uniform highp mat3 pmvMatrix; \ - uniform mediump vec2 halfViewportSize; \ - uniform highp vec2 invertedTextureSize; \ - uniform highp mat3 brushTransform; \ - varying highp vec2 patternTexCoords; \ - void setPosition(void) { \ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ - gl_Position.xy = transformedPos.xy / transformedPos.z; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \ - }"; +static const char* const qglslPositionWithPatternBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp vec2 invertedTextureSize; \n\ + uniform highp mat3 brushTransform; \n\ + varying highp vec2 patternTexCoords; \n\ + void setPosition(void) \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1.0); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + patternTexCoords.xy = (hTexCoords.xy * 0.125) * invertedHTexCoordsZ; \n\ + }\n"; static const char* const qglslAffinePositionWithPatternBrushVertexShader = qglslPositionWithPatternBrushVertexShader; -static const char* const qglslPatternBrushSrcFragmentShader = "\ - uniform lowp sampler2D brushTexture;\ - uniform lowp vec4 patternColor; \ - varying highp vec2 patternTexCoords;\ - lowp vec4 srcPixel() { \ - return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \ +static const char* const qglslPatternBrushSrcFragmentShader = "\n\ + uniform lowp sampler2D brushTexture; \n\ + uniform lowp vec4 patternColor; \n\ + varying highp vec2 patternTexCoords;\n\ + lowp vec4 srcPixel() \n\ + { \n\ + return patternColor * (1.0 - texture2D(brushTexture, patternTexCoords).r); \n\ }\n"; // Linear Gradient Brush -static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\ - attribute highp vec2 vertexCoordsArray; \ - uniform highp mat3 pmvMatrix; \ - uniform mediump vec2 halfViewportSize; \ - uniform highp vec3 linearData; \ - uniform highp mat3 brushTransform; \ - varying mediump float index; \ - void setPosition() { \ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ - gl_Position.xy = transformedPos.xy / transformedPos.z; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \ - }"; +static const char* const qglslPositionWithLinearGradientBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp vec3 linearData; \n\ + uniform highp mat3 brushTransform; \n\ + varying mediump float index; \n\ + void setPosition() \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + index = (dot(linearData.xy, hTexCoords.xy) * linearData.z) * invertedHTexCoordsZ; \n\ + }\n"; static const char* const qglslAffinePositionWithLinearGradientBrushVertexShader = qglslPositionWithLinearGradientBrushVertexShader; -static const char* const qglslLinearGradientBrushSrcFragmentShader = "\ - uniform lowp sampler2D brushTexture; \ - varying mediump float index; \ - lowp vec4 srcPixel() { \ - mediump vec2 val = vec2(index, 0.5); \ - return texture2D(brushTexture, val); \ +static const char* const qglslLinearGradientBrushSrcFragmentShader = "\n\ + uniform lowp sampler2D brushTexture; \n\ + varying mediump float index; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + mediump vec2 val = vec2(index, 0.5); \n\ + return texture2D(brushTexture, val); \n\ }\n"; // Conical Gradient Brush -static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\ - attribute highp vec2 vertexCoordsArray;\ - uniform highp mat3 pmvMatrix;\ - uniform mediump vec2 halfViewportSize; \ - uniform highp mat3 brushTransform; \ - varying highp vec2 A; \ - void setPosition(void)\ - {\ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ - gl_Position.xy = transformedPos.xy / transformedPos.z; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - A = hTexCoords.xy * invertedHTexCoordsZ; \ - }"; +static const char* const qglslPositionWithConicalGradientBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp mat3 brushTransform; \n\ + varying highp vec2 A; \n\ + void setPosition(void) \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + A = hTexCoords.xy * invertedHTexCoordsZ; \n\ + }\n"; static const char* const qglslAffinePositionWithConicalGradientBrushVertexShader = qglslPositionWithConicalGradientBrushVertexShader; static const char* const qglslConicalGradientBrushSrcFragmentShader = "\n\ #define INVERSE_2PI 0.1591549430918953358 \n\ - uniform lowp sampler2D brushTexture; \n\ - uniform mediump float angle; \ - varying highp vec2 A; \ - lowp vec4 srcPixel() { \ - highp float t; \ - if (abs(A.y) == abs(A.x)) \ - t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \ - else \ - t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \ - return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \ - }"; + uniform lowp sampler2D brushTexture; \n\ + uniform mediump float angle; \n\ + varying highp vec2 A; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + highp float t; \n\ + if (abs(A.y) == abs(A.x)) \n\ + t = (atan(-A.y + 0.002, A.x) + angle) * INVERSE_2PI; \n\ + else \n\ + t = (atan(-A.y, A.x) + angle) * INVERSE_2PI; \n\ + return texture2D(brushTexture, vec2(t - floor(t), 0.5)); \n\ + }\n"; // Radial Gradient Brush -static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\ - attribute highp vec2 vertexCoordsArray;\ - uniform highp mat3 pmvMatrix;\ - uniform mediump vec2 halfViewportSize; \ - uniform highp mat3 brushTransform; \ - uniform highp vec2 fmp; \ - varying highp float b; \ - varying highp vec2 A; \ - void setPosition(void) \ - {\ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ - gl_Position.xy = transformedPos.xy / transformedPos.z; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - A = hTexCoords.xy * invertedHTexCoordsZ; \ - b = 2.0 * dot(A, fmp); \ - }"; +static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray;\n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp mat3 brushTransform; \n\ + uniform highp vec2 fmp; \n\ + varying highp float b; \n\ + varying highp vec2 A; \n\ + void setPosition(void) \n\ + {\n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + A = hTexCoords.xy * invertedHTexCoordsZ; \n\ + b = 2.0 * dot(A, fmp); \n\ + }\n"; static const char* const qglslAffinePositionWithRadialGradientBrushVertexShader = qglslPositionWithRadialGradientBrushVertexShader; -static const char* const qglslRadialGradientBrushSrcFragmentShader = "\ - uniform lowp sampler2D brushTexture; \ - uniform highp float fmp2_m_radius2; \ - uniform highp float inverse_2_fmp2_m_radius2; \ - varying highp float b; \ - varying highp vec2 A; \ - lowp vec4 srcPixel() { \ - highp float c = -dot(A, A); \ - highp vec2 val = vec2((-b + sqrt(b*b - 4.0*fmp2_m_radius2*c)) * inverse_2_fmp2_m_radius2, 0.5); \ - return texture2D(brushTexture, val); \ - }"; +static const char* const qglslRadialGradientBrushSrcFragmentShader = "\n\ + uniform lowp sampler2D brushTexture; \n\ + uniform highp float fmp2_m_radius2; \n\ + uniform highp float inverse_2_fmp2_m_radius2; \n\ + varying highp float b; \n\ + varying highp vec2 A; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + highp float c = -dot(A, A); \n\ + highp vec2 val = vec2((-b + sqrt(b*b - 4.0*fmp2_m_radius2*c)) * inverse_2_fmp2_m_radius2, 0.5); \n\ + return texture2D(brushTexture, val); \n\ + }\n"; // Texture Brush -static const char* const qglslPositionWithTextureBrushVertexShader = "\ - attribute highp vec2 vertexCoordsArray; \ - uniform highp mat3 pmvMatrix; \ - uniform mediump vec2 halfViewportSize; \ - uniform highp vec2 invertedTextureSize; \ - uniform highp mat3 brushTransform; \ - varying highp vec2 textureCoords; \ - void setPosition(void) { \ - vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \ - gl_Position.xy = transformedPos.xy / transformedPos.z; \ - mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \ - mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \ - mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \ - gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \ - textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \ - }"; +static const char* const qglslPositionWithTextureBrushVertexShader = "\n\ + attribute highp vec2 vertexCoordsArray; \n\ + attribute highp vec3 pmvMatrix1; \n\ + attribute highp vec3 pmvMatrix2; \n\ + attribute highp vec3 pmvMatrix3; \n\ + uniform mediump vec2 halfViewportSize; \n\ + uniform highp vec2 invertedTextureSize; \n\ + uniform highp mat3 brushTransform; \n\ + varying highp vec2 textureCoords; \n\ + void setPosition(void) \n\ + { \n\ + highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\ + vec3 transformedPos = pmvMatrix * vec3(vertexCoordsArray.xy, 1.0); \n\ + gl_Position.xy = transformedPos.xy / transformedPos.z; \n\ + mediump vec2 viewportCoords = (gl_Position.xy + 1.0) * halfViewportSize; \n\ + mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\ + mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ + gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ + textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\ + }\n"; static const char* const qglslAffinePositionWithTextureBrushVertexShader = qglslPositionWithTextureBrushVertexShader; @@ -275,148 +294,165 @@ static const char* const qglslAffinePositionWithTextureBrushVertexShader // OpenGL ES does not support GL_REPEAT wrap modes for NPOT textures. So instead, // we emulate GL_REPEAT by only taking the fractional part of the texture coords. // TODO: Special case POT textures which don't need this emulation -static const char* const qglslTextureBrushSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D brushTexture; \ - lowp vec4 srcPixel() { \ - return texture2D(brushTexture, fract(textureCoords)); \ - }"; +static const char* const qglslTextureBrushSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D brushTexture; \n\ + lowp vec4 srcPixel() { \n\ + return texture2D(brushTexture, fract(textureCoords)); \n\ + }\n"; #else -static const char* const qglslTextureBrushSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D brushTexture; \ - lowp vec4 srcPixel() { \ - return texture2D(brushTexture, textureCoords); \ - }"; +static const char* const qglslTextureBrushSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D brushTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return texture2D(brushTexture, textureCoords); \n\ + }\n"; #endif -static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp vec4 patternColor; \ - uniform lowp sampler2D brushTexture; \ - lowp vec4 srcPixel() { \ - return patternColor * (1.0 - texture2D(brushTexture, textureCoords).r); \ - }"; +static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp vec4 patternColor; \n\ + uniform lowp sampler2D brushTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return patternColor * (1.0 - texture2D(brushTexture, textureCoords).r); \n\ + }\n"; // Solid Fill Brush -static const char* const qglslSolidBrushSrcFragmentShader = "\ - uniform lowp vec4 fragmentColor; \ - lowp vec4 srcPixel() { \ - return fragmentColor; \ - }"; - -static const char* const qglslImageSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D imageTexture; \ - lowp vec4 srcPixel() { \ - return texture2D(imageTexture, textureCoords); \ - }"; - -static const char* const qglslCustomSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D imageTexture; \ - lowp vec4 customShader(lowp sampler2D texture, highp vec2 coords); \ - lowp vec4 srcPixel() { \ - return customShader(imageTexture, textureCoords); \ - }"; - -static const char* const qglslImageSrcWithPatternFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp vec4 patternColor; \ - uniform lowp sampler2D imageTexture; \ - lowp vec4 srcPixel() { \ - return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \ - }\n"; - -static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\ - varying highp vec2 textureCoords; \ - uniform lowp sampler2D imageTexture; \ - lowp vec4 srcPixel() { \ - lowp vec4 sample = texture2D(imageTexture, textureCoords); \ - sample.rgb = sample.rgb * sample.a; \ - return sample; \ - }"; - -static const char* const qglslShockingPinkSrcFragmentShader = "\ - lowp vec4 srcPixel() { \ - return vec4(0.98, 0.06, 0.75, 1.0); \ - }"; - -static const char* const qglslMainFragmentShader_ImageArrays = "\ - varying lowp float opacity; \ - lowp vec4 srcPixel(); \ - void main() { \ - gl_FragColor = srcPixel() * opacity; \ - }"; - -static const char* const qglslMainFragmentShader_CMO = "\ - uniform lowp float globalOpacity; \ - lowp vec4 srcPixel(); \ - lowp vec4 applyMask(lowp vec4); \ - lowp vec4 compose(lowp vec4); \ - void main() { \ - gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \ - }"; - -static const char* const qglslMainFragmentShader_CM = "\ - lowp vec4 srcPixel(); \ - lowp vec4 applyMask(lowp vec4); \ - lowp vec4 compose(lowp vec4); \ - void main() { \ - gl_FragColor = applyMask(compose(srcPixel())); \ - }"; - -static const char* const qglslMainFragmentShader_MO = "\ - uniform lowp float globalOpacity; \ - lowp vec4 srcPixel(); \ - lowp vec4 applyMask(lowp vec4); \ - void main() { \ - gl_FragColor = applyMask(srcPixel()*globalOpacity); \ - }"; - -static const char* const qglslMainFragmentShader_M = "\ - lowp vec4 srcPixel(); \ - lowp vec4 applyMask(lowp vec4); \ - void main() { \ - gl_FragColor = applyMask(srcPixel()); \ - }"; - -static const char* const qglslMainFragmentShader_CO = "\ - uniform lowp float globalOpacity; \ - lowp vec4 srcPixel(); \ - lowp vec4 compose(lowp vec4); \ - void main() { \ - gl_FragColor = compose(srcPixel()*globalOpacity); \ - }"; - -static const char* const qglslMainFragmentShader_C = "\ - lowp vec4 srcPixel(); \ - lowp vec4 compose(lowp vec4); \ - void main() { \ - gl_FragColor = compose(srcPixel()); \ - }"; - -static const char* const qglslMainFragmentShader_O = "\ - uniform lowp float globalOpacity; \ - lowp vec4 srcPixel(); \ - void main() { \ - gl_FragColor = srcPixel()*globalOpacity; \ - }"; - -static const char* const qglslMainFragmentShader = "\ - lowp vec4 srcPixel(); \ - void main() { \ - gl_FragColor = srcPixel(); \ - }"; - -static const char* const qglslMaskFragmentShader = "\ - varying highp vec2 textureCoords;\ - uniform lowp sampler2D maskTexture;\ - lowp vec4 applyMask(lowp vec4 src) \ - {\ - lowp vec4 mask = texture2D(maskTexture, textureCoords); \ - return src * mask.a; \ - }"; +static const char* const qglslSolidBrushSrcFragmentShader = "\n\ + uniform lowp vec4 fragmentColor; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return fragmentColor; \n\ + }\n"; + +static const char* const qglslImageSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D imageTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return texture2D(imageTexture, textureCoords); \n\ + }\n"; + +static const char* const qglslCustomSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D imageTexture; \n\ + lowp vec4 customShader(lowp sampler2D texture, highp vec2 coords); \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return customShader(imageTexture, textureCoords); \n\ + }\n"; + +static const char* const qglslImageSrcWithPatternFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp vec4 patternColor; \n\ + uniform lowp sampler2D imageTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + return patternColor * (1.0 - texture2D(imageTexture, textureCoords).r); \n\ + }\n"; + +static const char* const qglslNonPremultipliedImageSrcFragmentShader = "\n\ + varying highp vec2 textureCoords; \n\ + uniform lowp sampler2D imageTexture; \n\ + lowp vec4 srcPixel() \n\ + { \n\ + lowp vec4 sample = texture2D(imageTexture, textureCoords); \n\ + sample.rgb = sample.rgb * sample.a; \n\ + return sample; \n\ + }\n"; + +static const char* const qglslShockingPinkSrcFragmentShader = "\n\ + lowp vec4 srcPixel() \n\ + { \n\ + return vec4(0.98, 0.06, 0.75, 1.0); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_ImageArrays = "\n\ + varying lowp float opacity; \n\ + lowp vec4 srcPixel(); \n\ + void main() \n\ + { \n\ + gl_FragColor = srcPixel() * opacity; \n\ + }\n"; + +static const char* const qglslMainFragmentShader_CMO = "\n\ + uniform lowp float globalOpacity; \n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 applyMask(lowp vec4); \n\ + lowp vec4 compose(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = applyMask(compose(srcPixel()*globalOpacity))); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_CM = "\n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 applyMask(lowp vec4); \n\ + lowp vec4 compose(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = applyMask(compose(srcPixel())); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_MO = "\n\ + uniform lowp float globalOpacity; \n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 applyMask(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = applyMask(srcPixel()*globalOpacity); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_M = "\n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 applyMask(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = applyMask(srcPixel()); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_CO = "\n\ + uniform lowp float globalOpacity; \n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 compose(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = compose(srcPixel()*globalOpacity); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_C = "\n\ + lowp vec4 srcPixel(); \n\ + lowp vec4 compose(lowp vec4); \n\ + void main() \n\ + { \n\ + gl_FragColor = compose(srcPixel()); \n\ + }\n"; + +static const char* const qglslMainFragmentShader_O = "\n\ + uniform lowp float globalOpacity; \n\ + lowp vec4 srcPixel(); \n\ + void main() \n\ + { \n\ + gl_FragColor = srcPixel()*globalOpacity; \n\ + }\n"; + +static const char* const qglslMainFragmentShader = "\n\ + lowp vec4 srcPixel(); \n\ + void main() \n\ + { \n\ + gl_FragColor = srcPixel(); \n\ + }\n"; + +static const char* const qglslMaskFragmentShader = "\n\ + varying highp vec2 textureCoords;\n\ + uniform lowp sampler2D maskTexture;\n\ + lowp vec4 applyMask(lowp vec4 src) \n\ + {\n\ + lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\ + return src * mask.a; \n\ + }\n"; // For source over with subpixel antialiasing, the final color is calculated per component as follows // (.a is alpha component, .c is red, green or blue component): @@ -433,23 +469,23 @@ static const char* const qglslMaskFragmentShader = "\ // dest.c = dest.c * (1 - mask.c) + src.c * alpha // -static const char* const qglslRgbMaskFragmentShaderPass1 = "\ - varying highp vec2 textureCoords;\ - uniform lowp sampler2D maskTexture;\ - lowp vec4 applyMask(lowp vec4 src) \ - {\ - lowp vec4 mask = texture2D(maskTexture, textureCoords); \ - return src.a * mask; \ - }"; - -static const char* const qglslRgbMaskFragmentShaderPass2 = "\ - varying highp vec2 textureCoords;\ - uniform lowp sampler2D maskTexture;\ - lowp vec4 applyMask(lowp vec4 src) \ - {\ - lowp vec4 mask = texture2D(maskTexture, textureCoords); \ - return src * mask; \ - }"; +static const char* const qglslRgbMaskFragmentShaderPass1 = "\n\ + varying highp vec2 textureCoords;\n\ + uniform lowp sampler2D maskTexture;\n\ + lowp vec4 applyMask(lowp vec4 src) \n\ + { \n\ + lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\ + return src.a * mask; \n\ + }\n"; + +static const char* const qglslRgbMaskFragmentShaderPass2 = "\n\ + varying highp vec2 textureCoords;\n\ + uniform lowp sampler2D maskTexture;\n\ + lowp vec4 applyMask(lowp vec4 src) \n\ + { \n\ + lowp vec4 mask = texture2D(maskTexture, textureCoords); \n\ + return src * mask; \n\ + }\n"; /* Left to implement: diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index caa679b..07f3159 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -168,12 +168,6 @@ void QGL2PaintEngineExPrivate::useSimpleShader() if (matrixDirty) updateMatrix(); - - if (simpleShaderMatrixUniformDirty) { - const GLuint location = shaderManager->simpleProgram()->uniformLocation("pmvMatrix"); - glUniformMatrix3fv(location, 1, GL_FALSE, (GLfloat*)pmvMatrix); - simpleShaderMatrixUniformDirty = false; - } } void QGL2PaintEngineExPrivate::updateBrushTexture() @@ -392,9 +386,11 @@ void QGL2PaintEngineExPrivate::updateMatrix() matrixDirty = false; - // The actual data has been updated so both shader program's uniforms need updating - simpleShaderMatrixUniformDirty = true; - shaderMatrixUniformDirty = true; + // Set the PMV matrix attribute. As we use an attributes rather than uniforms, we only + // need to do this once for every matrix change and persists across all shader programs. + glVertexAttrib3fv(QT_PMV_MATRIX_1_ATTR, pmvMatrix[0]); + glVertexAttrib3fv(QT_PMV_MATRIX_2_ATTR, pmvMatrix[1]); + glVertexAttrib3fv(QT_PMV_MATRIX_3_ATTR, pmvMatrix[2]); dasher.setInvScale(inverseScale); stroker.setInvScale(inverseScale); @@ -562,6 +558,12 @@ void QGL2PaintEngineExPrivate::resetGLState() glStencilMask(0xff); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilFunc(GL_ALWAYS, 0, 0xff); + glDisableVertexAttribArray(QT_TEXTURE_COORDS_ATTR); + glDisableVertexAttribArray(QT_VERTEX_COORDS_ATTR); + glDisableVertexAttribArray(QT_OPACITY_ATTR); +#ifndef QT_OPENGL_ES_2 + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); // color may have been changed by glVertexAttrib() +#endif } void QGL2PaintEngineEx::endNativePainting() @@ -932,18 +934,12 @@ bool QGL2PaintEngineExPrivate::prepareForDraw(bool srcPixelsAreOpaque) if (changed) { // The shader program has changed so mark all uniforms as dirty: brushUniformsDirty = true; - shaderMatrixUniformDirty = true; opacityUniformDirty = true; } if (brushUniformsDirty && mode != ImageDrawingMode && mode != ImageArrayDrawingMode) updateBrushUniforms(); - if (shaderMatrixUniformDirty) { - glUniformMatrix3fv(location(QGLEngineShaderManager::PmvMatrix), 1, GL_FALSE, (GLfloat*)pmvMatrix); - shaderMatrixUniformDirty = false; - } - if (opacityMode == QGLEngineShaderManager::UniformOpacity && opacityUniformDirty) { shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::GlobalOpacity), (GLfloat)q->state()->opacity); opacityUniformDirty = false; @@ -1955,11 +1951,8 @@ void QGL2PaintEngineEx::setState(QPainterState *new_state) if (old_state == s || old_state->renderHintsChanged) renderHintsChanged(); - if (old_state == s || old_state->matrixChanged) { + if (old_state == s || old_state->matrixChanged) d->matrixDirty = true; - d->simpleShaderMatrixUniformDirty = true; - d->shaderMatrixUniformDirty = true; - } if (old_state == s || old_state->compositionModeChanged) d->compositionModeDirty = true; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index ce1b538..8fa0eff 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -252,8 +252,6 @@ public: bool compositionModeDirty; bool brushTextureDirty; bool brushUniformsDirty; - bool simpleShaderMatrixUniformDirty; - bool shaderMatrixUniformDirty; bool opacityUniformDirty; bool stencilClean; // Has the stencil not been used for clipping so far? diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index fed1658..6cb76ee 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -42,6 +42,8 @@ #include "qtextureglyphcache_gl_p.h" #include "qpaintengineex_opengl2_p.h" +QT_BEGIN_NAMESPACE + #ifdef Q_WS_WIN extern Q_GUI_EXPORT bool qt_cleartype_enabled; #endif @@ -243,3 +245,5 @@ int QGLTextureGlyphCache::glyphMargin() const return m_type == QFontEngineGlyphCache::Raster_RGBMask ? 2 : 0; #endif } + +QT_END_NAMESPACE diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 3f32cf3..0a89412 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -104,6 +104,10 @@ QT_BEGIN_NAMESPACE QGLExtensionFuncs QGLContextPrivate::qt_extensionFuncs; #endif +#ifdef Q_WS_X11 +extern const QX11Info *qt_x11Info(const QPaintDevice *pd); +#endif + struct QGLThreadContext { QGLContext *context; }; @@ -1590,10 +1594,8 @@ QGLTextureCache::QGLTextureCache() Q_ASSERT(qt_gl_texture_cache == 0); qt_gl_texture_cache = this; - QImagePixmapCleanupHooks::instance()->addPixmapModificationHook(cleanupTextures); -#ifdef Q_WS_X11 - QImagePixmapCleanupHooks::instance()->addPixmapDestructionHook(cleanupPixmapSurfaces); -#endif + QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(cleanupTextures); + QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(cleanupBeforePixmapDestruction); QImagePixmapCleanupHooks::instance()->addImageHook(imageCleanupHook); } @@ -1601,10 +1603,8 @@ QGLTextureCache::~QGLTextureCache() { qt_gl_texture_cache = 0; - QImagePixmapCleanupHooks::instance()->removePixmapModificationHook(cleanupTextures); -#ifdef Q_WS_X11 - QImagePixmapCleanupHooks::instance()->removePixmapDestructionHook(cleanupPixmapSurfaces); -#endif + QImagePixmapCleanupHooks::instance()->removePixmapDataModificationHook(cleanupTextures); + QImagePixmapCleanupHooks::instance()->removePixmapDataDestructionHook(cleanupBeforePixmapDestruction); QImagePixmapCleanupHooks::instance()->removeImageHook(imageCleanupHook); } @@ -1672,30 +1672,29 @@ void QGLTextureCache::imageCleanupHook(qint64 cacheKey) } -void QGLTextureCache::cleanupTextures(QPixmap* pixmap) +void QGLTextureCache::cleanupTextures(QPixmapData* pmd) { // ### remove when the GL texture cache becomes thread-safe if (qApp->thread() == QThread::currentThread()) { - const qint64 cacheKey = pixmap->cacheKey(); + const qint64 cacheKey = pmd->cacheKey(); QGLTexture *texture = instance()->getTexture(cacheKey); if (texture && texture->options & QGLContext::MemoryManagedBindOption) instance()->remove(cacheKey); } } -#if defined(Q_WS_X11) -void QGLTextureCache::cleanupPixmapSurfaces(QPixmap* pixmap) +void QGLTextureCache::cleanupBeforePixmapDestruction(QPixmapData* pmd) { // Remove any bound textures first: - cleanupTextures(pixmap); + cleanupTextures(pmd); - QPixmapData *pd = pixmap->data_ptr().data(); - if (pd->classId() == QPixmapData::X11Class) { - Q_ASSERT(pd->ref == 1); // Make sure reference counting isn't broken - QGLContextPrivate::destroyGlSurfaceForPixmap(pd); +#if defined(Q_WS_X11) + if (pmd->classId() == QPixmapData::X11Class) { + Q_ASSERT(pmd->ref == 0); // Make sure reference counting isn't broken + QGLContextPrivate::destroyGlSurfaceForPixmap(pmd); } -} #endif +} void QGLTextureCache::deleteIfEmpty() { @@ -2355,7 +2354,10 @@ QGLTexture *QGLContextPrivate::bindTexture(const QPixmap &pixmap, GLenum target, #if defined(Q_WS_X11) // Try to use texture_from_pixmap - if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType) { + const QX11Info *xinfo = qt_x11Info(paintDevice); + if (pd->classId() == QPixmapData::X11Class && pd->pixelType() == QPixmapData::PixmapType + && xinfo && xinfo->screen() == pixmap.x11Info().screen()) + { texture = bindTextureFromNativePixmap(pd, key, options); if (texture) { texture->options |= QGLContext::MemoryManagedBindOption; @@ -4393,6 +4395,13 @@ static void qt_gl_draw_text(QPainter *p, int x, int y, const QString &str, \note This function temporarily disables depth-testing when the text is drawn. + \note This function can only be used inside a + QPainter::beginNativePainting()/QPainter::endNativePainting() block + if the default OpenGL paint engine is QPaintEngine::OpenGL. To make + QPaintEngine::OpenGL the default GL engine, call + QGL::setPreferredPaintEngine(QPaintEngine::OpenGL) before the + QApplication constructor. + \l{Overpainting Example}{Overpaint} with QPainter::drawText() instead. */ @@ -4412,8 +4421,17 @@ void QGLWidget::renderText(int x, int y, const QString &str, const QFont &font, bool auto_swap = autoBufferSwap(); QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine(); - qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); + QPaintEngine *engine = paintEngine(); + if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) { + qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is" + " active on the same device is not allowed."); + return; + } + + // this changes what paintEngine() returns + qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); + engine = paintEngine(); QPainter *p; bool reuse_painter = false; if (engine->isActive()) { @@ -4506,8 +4524,17 @@ void QGLWidget::renderText(double x, double y, double z, const QString &str, con win_y = height - win_y; // y is inverted QPaintEngine::Type oldEngineType = qgl_engine_selector()->preferredPaintEngine(); - qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); QPaintEngine *engine = paintEngine(); + + if (engine && (oldEngineType == QPaintEngine::OpenGL2) && engine->isActive()) { + qWarning("QGLWidget::renderText(): Calling renderText() while a GL 2 paint engine is" + " active on the same device is not allowed."); + return; + } + + // this changes what paintEngine() returns + qgl_engine_selector()->setPreferredPaintEngine(QPaintEngine::OpenGL); + engine = paintEngine(); QPainter *p; bool reuse_painter = false; bool use_depth_testing = glIsEnabled(GL_DEPTH_TEST); diff --git a/src/opengl/qgl_mac.mm b/src/opengl/qgl_mac.mm index c01575b..4d7532e 100644 --- a/src/opengl/qgl_mac.mm +++ b/src/opengl/qgl_mac.mm @@ -951,8 +951,6 @@ void QGLWidgetPrivate::init(QGLContext *context, const QGLWidget *shareWidget) break; current = current->parentWidget(); } - - isGLWidget = 1; } bool QGLWidgetPrivate::renderCxPm(QPixmap*) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 0104f07..da0887e 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -179,7 +179,9 @@ public: #if defined(Q_WS_X11) && defined(QT_OPENGL_ES) , eglSurfaceWindowId(0) #endif - {} + { + isGLWidget = 1; + } ~QGLWidgetPrivate() {} @@ -522,7 +524,7 @@ public: QSize bindCompressedTexturePVR(const char *buf, int len); }; -class QGLTextureCache { +class Q_AUTOTEST_EXPORT QGLTextureCache { public: QGLTextureCache(); ~QGLTextureCache(); @@ -539,11 +541,8 @@ public: static QGLTextureCache *instance(); static void deleteIfEmpty(); static void imageCleanupHook(qint64 cacheKey); - static void cleanupTextures(QPixmap* pixmap); -#ifdef Q_WS_X11 - // X11 needs to catch pixmap data destruction to delete EGL/GLX pixmap surfaces - static void cleanupPixmapSurfaces(QPixmap* pixmap); -#endif + static void cleanupTextures(QPixmapData* pixmap); + static void cleanupBeforePixmapDestruction(QPixmapData* pixmap); private: QCache<qint64, QGLTexture> m_cache; diff --git a/src/opengl/qglpixelbuffer_x11.cpp b/src/opengl/qglpixelbuffer_x11.cpp index 5b34cbb..32a42a2 100644 --- a/src/opengl/qglpixelbuffer_x11.cpp +++ b/src/opengl/qglpixelbuffer_x11.cpp @@ -181,7 +181,11 @@ bool QGLPixelBufferPrivate::init(const QSize &size, const QGLFormat &f, QGLWidge qt_format_to_attrib_list(f, attribs); - GLXFBConfig *configs = glXChooseFBConfig(X11->display, X11->defaultScreen, attribs, &num_configs); + int screen = X11->defaultScreen; + if (shareWidget) + screen = shareWidget->x11Info().screen(); + + GLXFBConfig *configs = glXChooseFBConfig(X11->display, screen, attribs, &num_configs); if (configs && num_configs) { int res; glXGetFBConfigAttrib(X11->display, configs[0], GLX_LEVEL, &res); diff --git a/src/opengl/qglpixmapfilter.cpp b/src/opengl/qglpixmapfilter.cpp index 11011ee..d5a11d9 100644 --- a/src/opengl/qglpixmapfilter.cpp +++ b/src/opengl/qglpixmapfilter.cpp @@ -319,14 +319,14 @@ public: ~QGLBlurTextureCache(); QGLBlurTextureInfo *takeBlurTextureInfo(const QPixmap &pixmap); - bool hasBlurTextureInfo(const QPixmap &pixmap) const; + bool hasBlurTextureInfo(quint64 cacheKey) const; void insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info); - void clearBlurTextureInfo(const QPixmap &pixmap); + void clearBlurTextureInfo(quint64 cacheKey); void timerEvent(QTimerEvent *event); private: - static void pixmapDestroyed(QPixmap *pixmap); + static void pixmapDestroyed(QPixmapData *pixmap); QCache<quint64, QGLBlurTextureInfo > cache; @@ -379,21 +379,22 @@ QGLBlurTextureInfo *QGLBlurTextureCache::takeBlurTextureInfo(const QPixmap &pixm return cache.take(pixmap.cacheKey()); } -void QGLBlurTextureCache::clearBlurTextureInfo(const QPixmap &pixmap) +void QGLBlurTextureCache::clearBlurTextureInfo(quint64 cacheKey) { - cache.remove(pixmap.cacheKey()); + cache.remove(cacheKey); } -bool QGLBlurTextureCache::hasBlurTextureInfo(const QPixmap &pixmap) const +bool QGLBlurTextureCache::hasBlurTextureInfo(quint64 cacheKey) const { - return cache.contains(pixmap.cacheKey()); + return cache.contains(cacheKey); } void QGLBlurTextureCache::insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info) { static bool hookAdded = false; if (!hookAdded) { - QImagePixmapCleanupHooks::instance()->addPixmapDestructionHook(pixmapDestroyed); + QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(pixmapDestroyed); + QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(pixmapDestroyed); hookAdded = true; } @@ -406,11 +407,11 @@ void QGLBlurTextureCache::insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTe timerId = startTimer(8000); } -void QGLBlurTextureCache::pixmapDestroyed(QPixmap *pixmap) +void QGLBlurTextureCache::pixmapDestroyed(QPixmapData *pmd) { foreach (QGLBlurTextureCache *cache, blurTextureCaches) { - if (cache->hasBlurTextureInfo(*pixmap)) - cache->clearBlurTextureInfo(*pixmap); + if (cache->hasBlurTextureInfo(pmd->cacheKey())) + cache->clearBlurTextureInfo(pmd->cacheKey()); } } diff --git a/src/opengl/qglshaderprogram.cpp b/src/opengl/qglshaderprogram.cpp index 5e2f1f5..79484fa 100644 --- a/src/opengl/qglshaderprogram.cpp +++ b/src/opengl/qglshaderprogram.cpp @@ -106,6 +106,19 @@ QT_BEGIN_NAMESPACE \snippet doc/src/snippets/code/src_opengl_qglshaderprogram.cpp 2 + \section1 Binary shaders and programs + + Binary shaders may be specified using \c{glShaderBinary()} on + the return value from QGLShader::shaderId(). The QGLShader instance + containing the binary can then be added to the shader program with + addShader() and linked in the usual fashion with link(). + + Binary programs may be specified using \c{glProgramBinaryOES()} + on the return value from programId(). Then the application should + call link(), which will notice that the program has already been + specified and linked, allowing other operations to be performed + on the shader program. + \sa QGLShader */ @@ -632,8 +645,6 @@ bool QGLShaderProgram::addShader(QGLShader *shader) qWarning("QGLShaderProgram::addShader: Program and shader are not associated with same context."); return false; } - if (!shader->d_func()->compiled) - return false; if (!shader->d_func()->shaderGuard.id()) return false; glAttachShader(d->programGuard.id(), shader->d_func()->shaderGuard.id()); @@ -820,8 +831,20 @@ bool QGLShaderProgram::link() GLuint program = d->programGuard.id(); if (!program) return false; + GLint value; + if (d->shaders.isEmpty()) { + // If there are no explicit shaders, then it is possible that the + // application added a program binary with glProgramBinaryOES(), + // or otherwise populated the shaders itself. Check to see if the + // program is already linked and bail out if so. + value = 0; + glGetProgramiv(program, GL_LINK_STATUS, &value); + d->linked = (value != 0); + if (d->linked) + return true; + } glLinkProgram(program); - GLint value = 0; + value = 0; glGetProgramiv(program, GL_LINK_STATUS, &value); d->linked = (value != 0); value = 0; @@ -928,6 +951,15 @@ void QGLShaderProgram::release() GLuint QGLShaderProgram::programId() const { Q_D(const QGLShaderProgram); + GLuint id = d->programGuard.id(); + if (id) + return id; + + // Create the identifier if we don't have one yet. This is for + // applications that want to create the attached shader configuration + // themselves, particularly those using program binaries. + if (!const_cast<QGLShaderProgram *>(this)->init()) + return 0; return d->programGuard.id(); } diff --git a/src/opengl/qpixmapdata_gl.cpp b/src/opengl/qpixmapdata_gl.cpp index 6d47687..aa80664 100644 --- a/src/opengl/qpixmapdata_gl.cpp +++ b/src/opengl/qpixmapdata_gl.cpp @@ -252,10 +252,6 @@ QGLPixmapData::QGLPixmapData(PixelType type) { setSerialNumber(++qt_gl_pixmap_serial); m_glDevice.setPixmapData(this); - - // Set InteralBindOptions minus the memory managed, since this - // QGLTexture is not managed as part of the internal texture cache - m_texture.options = QGLContext::PremultipliedAlphaBindOption; } QGLPixmapData::~QGLPixmapData() @@ -344,18 +340,18 @@ void QGLPixmapData::ensureCreated() const } if (!m_source.isNull()) { - glBindTexture(target, m_texture.id); if (external_format == GL_RGB) { - const QImage tx = m_source.convertToFormat(QImage::Format_RGB888); + const QImage tx = m_source.convertToFormat(QImage::Format_RGB888).mirrored(false, true); + + glBindTexture(target, m_texture.id); glTexSubImage2D(target, 0, 0, 0, w, h, external_format, GL_UNSIGNED_BYTE, tx.bits()); } else { const QImage tx = ctx->d_func()->convertToGLFormat(m_source, true, external_format); + + glBindTexture(target, m_texture.id); glTexSubImage2D(target, 0, 0, 0, w, h, external_format, GL_UNSIGNED_BYTE, tx.bits()); - // convertToGLFormat will flip the Y axis, so it needs to - // be drawn upside down - m_texture.options |= QGLContext::InvertedYBindOption; } if (useFramebufferObjects()) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index cc9ba77..6813d2f 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -188,6 +188,7 @@ public: bool maskValid; // True if vgMask() contains valid data. bool maskIsSet; // True if mask would be fully set if it was valid. + bool scissorMask; // True if scissor is used in place of the mask. bool rawVG; // True if processing a raw VG escape. QRect maskRect; // Rectangle version of mask if it is simple. @@ -355,6 +356,7 @@ void QVGPaintEnginePrivate::init() maskValid = false; maskIsSet = false; + scissorMask = false; rawVG = false; scissorActive = false; @@ -1542,7 +1544,28 @@ void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen) static inline bool clipTransformIsSimple(const QTransform& transform) { QTransform::TransformationType type = transform.type(); - return (type == QTransform::TxNone || type == QTransform::TxTranslate); + if (type == QTransform::TxNone || type == QTransform::TxTranslate) + return true; + if (type == QTransform::TxRotate) { + // Check for 0, 90, 180, and 270 degree rotations. + // (0 might happen after 4 rotations of 90 degrees). + qreal m11 = transform.m11(); + qreal m12 = transform.m12(); + qreal m21 = transform.m21(); + qreal m22 = transform.m22(); + if (m11 == 0.0f && m22 == 0.0f) { + if (m12 == 1.0f && m21 == -1.0f) + return true; // 90 degrees. + else if (m12 == -1.0f && m21 == 1.0f) + return true; // 270 degrees. + } else if (m12 == 0.0f && m21 == 0.0f) { + if (m11 == -1.0f && m22 == -1.0f) + return true; // 180 degrees. + else if (m11 == 1.0f && m22 == 1.0f) + return true; // 0 degrees. + } + } + return false; } #if defined(QVG_SCISSOR_CLIP) @@ -1664,12 +1687,12 @@ void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) if (op == Qt::NoClip) { d->maskValid = false; d->maskIsSet = true; + d->scissorMask = false; d->maskRect = QRect(); vgSeti(VG_MASKING, VG_FALSE); return; } -#if defined(QVG_NO_RENDER_TO_MASK) // We don't have vgRenderToMask(), so handle simple QRectF's only. if (path.shape() == QVectorPath::RectangleHint && path.elementCount() == 4 && clipTransformIsSimple(d->transform)) { @@ -1679,8 +1702,10 @@ void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) QRectF rect(points[0], points[1], points[2] - points[0], points[5] - points[1]); clip(rect.toRect(), op); + return; } -#else + +#if !defined(QVG_NO_RENDER_TO_MASK) QPaintDevice *pdev = paintDevice(); int width = pdev->width(); int height = pdev->height(); @@ -1711,6 +1736,7 @@ void QVGPaintEngine::clip(const QVectorPath &path, Qt::ClipOperation op) vgSeti(VG_MASKING, VG_TRUE); d->maskValid = true; d->maskIsSet = false; + d->scissorMask = false; #endif } @@ -1731,6 +1757,7 @@ void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) { d->maskValid = false; d->maskIsSet = true; + d->scissorMask = false; d->maskRect = QRect(); vgSeti(VG_MASKING, VG_FALSE); } @@ -1746,6 +1773,7 @@ void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) vgSeti(VG_MASKING, VG_FALSE); d->maskValid = false; d->maskIsSet = true; + d->scissorMask = false; d->maskRect = QRect(); } else { // Special case: if the intersection of the system @@ -1763,6 +1791,7 @@ void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) if (clip.rectCount() != 1) { d->maskValid = false; d->maskIsSet = false; + d->scissorMask = false; d->maskRect = QRect(); d->modifyMask(this, VG_FILL_MASK, r); break; @@ -1771,6 +1800,7 @@ void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) } d->maskValid = false; d->maskIsSet = false; + d->scissorMask = true; d->maskRect = clipRect; vgSeti(VG_MASKING, VG_FALSE); updateScissor(); @@ -1781,13 +1811,30 @@ void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) case Qt::IntersectClip: { QRect r = d->transform.mapRect(rect); - if (d->maskIsSet && isDefaultClipRect(r)) { + if (!d->maskValid) { + // Mask has not been used yet, so intersect with + // the previous scissor-based region in maskRect. + if (d->scissorMask) + r = r.intersect(d->maskRect); + if (isDefaultClipRect(r)) { + // The clip is the full window, so turn off clipping. + d->maskIsSet = true; + d->maskRect = QRect(); + } else { + // Activate the scissor on a smaller maskRect. + d->maskIsSet = false; + d->maskRect = r; + } + d->scissorMask = true; + updateScissor(); + } else if (d->maskIsSet && isDefaultClipRect(r)) { // Intersecting a full-window clip with a full-window // region is the same as turning off clipping. if (d->maskValid) vgSeti(VG_MASKING, VG_FALSE); d->maskValid = false; d->maskIsSet = true; + d->scissorMask = false; d->maskRect = QRect(); } else { d->modifyMask(this, VG_INTERSECT_MASK, r); @@ -1829,6 +1876,7 @@ void QVGPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) { d->maskValid = false; d->maskIsSet = true; + d->scissorMask = false; d->maskRect = QRect(); vgSeti(VG_MASKING, VG_FALSE); } @@ -1844,6 +1892,7 @@ void QVGPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) vgSeti(VG_MASKING, VG_FALSE); d->maskValid = false; d->maskIsSet = true; + d->scissorMask = false; d->maskRect = QRect(); } else { // Special case: if the intersection of the system @@ -1857,12 +1906,14 @@ void QVGPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) if (clip.rectCount() == 1) { d->maskValid = false; d->maskIsSet = false; + d->scissorMask = true; d->maskRect = clip.boundingRect(); vgSeti(VG_MASKING, VG_FALSE); updateScissor(); } else { d->maskValid = false; d->maskIsSet = false; + d->scissorMask = false; d->maskRect = QRect(); d->modifyMask(this, VG_FILL_MASK, r); } @@ -1887,6 +1938,7 @@ void QVGPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) vgSeti(VG_MASKING, VG_FALSE); d->maskValid = false; d->maskIsSet = true; + d->scissorMask = false; d->maskRect = QRect(); } else { d->modifyMask(this, VG_INTERSECT_MASK, r); @@ -1965,6 +2017,7 @@ void QVGPaintEngine::clip(const QPainterPath &path, Qt::ClipOperation op) if (op == Qt::NoClip) { d->maskValid = false; d->maskIsSet = true; + d->scissorMask = false; d->maskRect = QRect(); vgSeti(VG_MASKING, VG_FALSE); return; @@ -2000,6 +2053,7 @@ void QVGPaintEngine::clip(const QPainterPath &path, Qt::ClipOperation op) vgSeti(VG_MASKING, VG_TRUE); d->maskValid = true; d->maskIsSet = false; + d->scissorMask = false; #else QPaintEngineEx::clip(path, op); #endif @@ -2043,6 +2097,7 @@ void QVGPaintEnginePrivate::modifyMask vgSeti(VG_MASKING, VG_TRUE); maskValid = true; maskIsSet = false; + scissorMask = false; } void QVGPaintEnginePrivate::modifyMask @@ -2064,6 +2119,7 @@ void QVGPaintEnginePrivate::modifyMask vgSeti(VG_MASKING, VG_TRUE); maskValid = true; maskIsSet = false; + scissorMask = false; } #endif // !QVG_SCISSOR_CLIP @@ -2096,7 +2152,7 @@ void QVGPaintEngine::updateScissor() { #if !defined(QVG_SCISSOR_CLIP) // Combine the system clip with the simple mask rectangle. - if (!d->maskRect.isNull()) { + if (d->scissorMask) { if (region.isEmpty()) region = d->maskRect; else @@ -2187,6 +2243,7 @@ void QVGPaintEngine::clipEnabledChanged() // Replay the entire clip stack to put the mask into the right state. d->maskValid = false; d->maskIsSet = true; + d->scissorMask = false; d->maskRect = QRect(); s->clipRegion = defaultClipRegion(); d->replayClipOperations(); @@ -2196,6 +2253,7 @@ void QVGPaintEngine::clipEnabledChanged() vgSeti(VG_MASKING, VG_FALSE); d->maskValid = false; d->maskIsSet = false; + d->scissorMask = false; d->maskRect = QRect(); } #endif @@ -2314,12 +2372,7 @@ bool QVGPaintEngine::clearRect(const QRectF &rect, const QColor &color) Q_D(QVGPaintEngine); QVGPainterState *s = state(); if (!s->clipEnabled || s->clipOperation == Qt::NoClip) { - // The transform will either be identity or a simple translation, - // so do a simpler version of "r = d->transform.map(rect).toRect()". - QRect r = QRect(qRound(rect.x() + d->transform.dx()), - qRound(rect.y() + d->transform.dy()), - qRound(rect.width()), - qRound(rect.height())); + QRect r = d->transform.mapRect(rect).toRect(); int height = paintDevice()->height(); if (d->clearColor != color || d->clearOpacity != s->opacity) { VGfloat values[4]; @@ -3398,6 +3451,7 @@ void QVGPaintEngine::restoreState(QPaintEngine::DirtyFlags dirty) QPaintEngine::DirtyClipEnabled)) != 0) { d->maskValid = false; d->maskIsSet = false; + d->scissorMask = false; d->maskRect = QRect(); clipEnabledChanged(); } diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index cc0e5a1..3087b77 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -46,11 +46,13 @@ #include "qvgimagepool_p.h" #ifdef QT_SYMBIAN_SUPPORTS_SGIMAGE +#include <private/qt_s60_p.h> +#include <fbs.h> #include <graphics/sgimage.h> typedef EGLImageKHR (*pfnEglCreateImageKHR)(EGLDisplay, EGLContext, EGLenum, EGLClientBuffer, EGLint*); typedef EGLBoolean (*pfnEglDestroyImageKHR)(EGLDisplay, EGLImageKHR); typedef VGImage (*pfnVgCreateEGLImageTargetKHR)(VGeglImageKHR); -#endif +#endif // QT_SYMBIAN_SUPPORTS_SGIMAGE QT_BEGIN_NAMESPACE @@ -425,6 +427,34 @@ Q_OPENVG_EXPORT VGImage qPixmapToVGImage(const QPixmap& pixmap) } #if defined(Q_OS_SYMBIAN) + +static CFbsBitmap* createBlitCopy(CFbsBitmap* bitmap) +{ + CFbsBitmap *copy = q_check_ptr(new CFbsBitmap); + if(!copy) + return 0; + + if (copy->Create(bitmap->SizeInPixels(), bitmap->DisplayMode()) != KErrNone) { + delete copy; + copy = 0; + + return 0; + } + + CFbsBitmapDevice* bitmapDevice = 0; + CFbsBitGc *bitmapGc = 0; + QT_TRAP_THROWING(bitmapDevice = CFbsBitmapDevice::NewL(copy)); + QT_TRAP_THROWING(bitmapGc = CFbsBitGc::NewL()); + bitmapGc->Activate(bitmapDevice); + + bitmapGc->BitBlt(TPoint(), bitmap); + + delete bitmapGc; + delete bitmapDevice; + + return copy; +} + void QVGPixmapData::cleanup() { is_null = w = h = 0; @@ -510,7 +540,49 @@ void QVGPixmapData::fromNativeType(void* pixmap, NativeType type) eglDestroyImageKHR(context->display(), eglImage); SgDriver::Close(); } else if (type == QPixmapData::FbsBitmap) { + CFbsBitmap *bitmap = reinterpret_cast<CFbsBitmap*>(pixmap); + + bool deleteSourceBitmap = false; + +#ifdef Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE + + // Rasterize extended bitmaps + + TUid extendedBitmapType = bitmap->ExtendedBitmapType(); + if (extendedBitmapType != KNullUid) { + bitmap = createBlitCopy(bitmap); + deleteSourceBitmap = true; + } +#endif + + if (bitmap->IsCompressedInRAM()) { + bitmap = createBlitCopy(bitmap); + deleteSourceBitmap = true; + } + + TDisplayMode displayMode = bitmap->DisplayMode(); + QImage::Format format = qt_TDisplayMode2Format(displayMode); + + TSize size = bitmap->SizeInPixels(); + + bitmap->BeginDataAccess(); + uchar *bytes = (uchar*)bitmap->DataAddress(); + QImage img = QImage(bytes, size.iWidth, size.iHeight, format); + img = img.copy(); + bitmap->EndDataAccess(); + + if(displayMode == EGray2) { + //Symbian thinks set pixels are white/transparent, Qt thinks they are foreground/solid + //So invert mono bitmaps so that masks work correctly. + img.invertPixels(); + } else if(displayMode == EColor16M) { + img = img.rgbSwapped(); // EColor16M is BGR + } + + fromImage(img, Qt::AutoColor); + if(deleteSourceBitmap) + delete bitmap; } #else Q_UNUSED(pixmap); @@ -593,7 +665,25 @@ void* QVGPixmapData::toNativeType(NativeType type) SgDriver::Close(); return reinterpret_cast<void*>(sgImage); } else if (type == QPixmapData::FbsBitmap) { - return 0; + CFbsBitmap *bitmap = q_check_ptr(new CFbsBitmap); + + if (bitmap) { + if (bitmap->Create(TSize(source.width(), source.height()), + EColor16MAP) == KErrNone) { + const uchar *sptr = qt_vg_imageBits(source); + bitmap->BeginDataAccess(); + + uchar *dptr = (uchar*)bitmap->DataAddress(); + Mem::Copy(dptr, sptr, source.byteCount()); + + bitmap->EndDataAccess(); + } else { + delete bitmap; + bitmap = 0; + } + } + + return reinterpret_cast<void*>(bitmap); } #else Q_UNUSED(type); diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp index 1cbfdaf..ba50329 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.cpp @@ -552,6 +552,34 @@ QImage *QDirectFBPixmapData::buffer() return &lockedImage; } + +bool QDirectFBPixmapData::scroll(int dx, int dy, const QRect &rect) +{ + if (!dfbSurface) { + return false; + } + unlockSurface(); + DFBResult result = dfbSurface->SetBlittingFlags(dfbSurface, DSBLIT_NOFX); + if (result != DFB_OK) { + DirectFBError("QDirectFBPixmapData::scroll", result); + return false; + } + result = dfbSurface->SetPorterDuff(dfbSurface, DSPD_NONE); + if (result != DFB_OK) { + DirectFBError("QDirectFBPixmapData::scroll", result); + return false; + } + + const DFBRectangle source = { rect.x(), rect.y(), rect.width(), rect.height() }; + result = dfbSurface->Blit(dfbSurface, dfbSurface, &source, source.x + dx, source.y + dy); + if (result != DFB_OK) { + DirectFBError("QDirectFBPixmapData::scroll", result); + return false; + } + + return true; +} + void QDirectFBPixmapData::invalidate() { if (dfbSurface) { @@ -565,9 +593,17 @@ void QDirectFBPixmapData::invalidate() imageFormat = QImage::Format_Invalid; } +#ifndef QT_DIRECTFB_PLUGIN +Q_GUI_EXPORT IDirectFBSurface *qt_directfb_surface_for_pixmap(const QPixmap &pixmap) +{ + const QPixmapData *data = pixmap.pixmapData(); + if (!data || data->classId() != QPixmapData::DirectFBClass) + return 0; + const QDirectFBPixmapData *dfbData = static_cast<const QDirectFBPixmapData*>(data); + return dfbData->directFBSurface(); +} +#endif + QT_END_NAMESPACE #endif // QT_NO_QWS_DIRECTFB - - - diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h index f9b14a9..da6edc6 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h +++ b/src/plugins/gfxdrivers/directfb/qdirectfbpixmap.h @@ -81,6 +81,7 @@ public: virtual QImage toImage() const; virtual QPaintEngine *paintEngine() const; virtual QImage *buffer(); + virtual bool scroll(int dx, int dy, const QRect &rect); // Pure virtual in QPixmapData, so re-implement here and delegate to QDirectFBPaintDevice virtual int metric(QPaintDevice::PaintDeviceMetric m) const { return QDirectFBPaintDevice::metric(m); } diff --git a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp index 6b251c7..cd4d5c2 100644 --- a/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp +++ b/src/plugins/gfxdrivers/directfb/qdirectfbscreen.cpp @@ -921,7 +921,7 @@ void QDirectFBScreenPrivate::setFlipFlags(const QStringList &args) qPrintable(flip)); } } else { - flipFlags = DSFLIP_BLIT; + flipFlags = DSFLIP_BLIT|DSFLIP_ONSYNC; } } diff --git a/src/plugins/imageformats/gif/qgifhandler.cpp b/src/plugins/imageformats/gif/qgifhandler.cpp index 6f049be..25d3dfa 100644 --- a/src/plugins/imageformats/gif/qgifhandler.cpp +++ b/src/plugins/imageformats/gif/qgifhandler.cpp @@ -71,7 +71,8 @@ public: ~QGIFFormat(); int decode(QImage *image, const uchar* buffer, int length, - int *nextFrameDelay, int *loopCount, QSize *nextSize); + int *nextFrameDelay, int *loopCount); + static void scan(QIODevice *device, QVector<QSize> *imageSizes, int *loopCount); bool newFrame; bool partialNewFrame; @@ -229,7 +230,7 @@ void QGIFFormat::disposePrevious(QImage *image) Returns the number of bytes consumed. */ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, - int *nextFrameDelay, int *loopCount, QSize *nextSize) + int *nextFrameDelay, int *loopCount) { // We are required to state that // "The Graphics Interchange Format(c) is the Copyright property of @@ -346,10 +347,6 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, bpl = image->bytesPerLine(); bits = image->bits(); memset(bits, 0, image->byteCount()); - - // ### size of the upcoming frame, should rather - // be known before decoding it. - *nextSize = QSize(swidth, sheight); } disposePrevious(image); @@ -645,6 +642,273 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length, return initial-length; } +/*! + Scans through the data stream defined by \a device and returns the image + sizes found in the stream in the \a imageSizes vector. +*/ +void QGIFFormat::scan(QIODevice *device, QVector<QSize> *imageSizes, int *loopCount) +{ + if (!device) + return; + + qint64 oldPos = device->pos(); + if (!device->seek(0)) + return; + + int colorCount = 0; + int localColorCount = 0; + int globalColorCount = 0; + int colorReadCount = 0; + bool localColormap = false; + bool globalColormap = false; + int count = 0; + int blockSize = 0; + int imageWidth = 0; + int imageHeight = 0; + bool done = false; + uchar hold[16]; + State state = Header; + + const int readBufferSize = 40960; // 40k read buffer + QByteArray readBuffer(device->read(readBufferSize)); + + if (readBuffer.isEmpty()) { + device->seek(oldPos); + return; + } + + // This is a specialized version of the state machine from decode(), + // which doesn't do any image decoding or mallocing, and has an + // optimized way of skipping SkipBlocks, ImageDataBlocks and + // Global/LocalColorMaps. + + while (!readBuffer.isEmpty()) { + int length = readBuffer.size(); + const uchar *buffer = (const uchar *) readBuffer.constData(); + while (!done && length) { + length--; + uchar ch = *buffer++; + switch (state) { + case Header: + hold[count++] = ch; + if (count == 6) { + state = LogicalScreenDescriptor; + count = 0; + } + break; + case LogicalScreenDescriptor: + hold[count++] = ch; + if (count == 7) { + imageWidth = LM(hold[0], hold[1]); + imageHeight = LM(hold[2], hold[3]); + globalColormap = !!(hold[4] & 0x80); + globalColorCount = 2 << (hold[4] & 0x7); + count = 0; + colorCount = globalColorCount; + if (globalColormap) { + int colorTableSize = 3 * globalColorCount; + if (length >= colorTableSize) { + // skip the global color table in one go + length -= colorTableSize; + buffer += colorTableSize; + state = Introducer; + } else { + colorReadCount = 0; + state = GlobalColorMap; + } + } else { + state=Introducer; + } + } + break; + case GlobalColorMap: + case LocalColorMap: + hold[count++] = ch; + if (count == 3) { + if (++colorReadCount >= colorCount) { + if (state == LocalColorMap) + state = TableImageLZWSize; + else + state = Introducer; + } + count = 0; + } + break; + case Introducer: + hold[count++] = ch; + switch (ch) { + case 0x2c: + state = ImageDescriptor; + break; + case 0x21: + state = ExtensionLabel; + break; + case 0x3b: + state = Done; + break; + default: + done = true; + state = Error; + } + break; + case ImageDescriptor: + hold[count++] = ch; + if (count == 10) { + int newLeft = LM(hold[1], hold[2]); + int newTop = LM(hold[3], hold[4]); + int newWidth = LM(hold[5], hold[6]); + int newHeight = LM(hold[7], hold[8]); + + if (imageWidth/10 > qMax(newWidth,200)) + imageWidth = -1; + if (imageHeight/10 > qMax(newHeight,200)) + imageHeight = -1; + + if (imageWidth <= 0) + imageWidth = newLeft + newWidth; + if (imageHeight <= 0) + imageHeight = newTop + newHeight; + + *imageSizes << QSize(imageWidth, imageHeight); + + localColormap = !!(hold[9] & 0x80); + localColorCount = localColormap ? (2 << (hold[9] & 0x7)) : 0; + if (localColorCount) + colorCount = localColorCount; + else + colorCount = globalColorCount; + + count = 0; + if (localColormap) { + int colorTableSize = 3 * localColorCount; + if (length >= colorTableSize) { + // skip the local color table in one go + length -= colorTableSize; + buffer += colorTableSize; + state = TableImageLZWSize; + } else { + colorReadCount = 0; + state = LocalColorMap; + } + } else { + state = TableImageLZWSize; + } + } + break; + case TableImageLZWSize: + if (ch > max_lzw_bits) + state = Error; + else + state = ImageDataBlockSize; + count = 0; + break; + case ImageDataBlockSize: + blockSize = ch; + if (blockSize) { + if (length >= blockSize) { + // we can skip the block in one go + length -= blockSize; + buffer += blockSize; + count = 0; + } else { + state = ImageDataBlock; + } + } else { + state = Introducer; + } + break; + case ImageDataBlock: + ++count; + if (count == blockSize) { + count = 0; + state = ImageDataBlockSize; + } + break; + case ExtensionLabel: + switch (ch) { + case 0xf9: + state = GraphicControlExtension; + break; + case 0xff: + state = ApplicationExtension; + break; + default: + state = SkipBlockSize; + } + count = 0; + break; + case ApplicationExtension: + if (count < 11) + hold[count] = ch; + ++count; + if (count == hold[0] + 1) { + if (qstrncmp((char*)(hold+1), "NETSCAPE", 8) == 0) + state=NetscapeExtensionBlockSize; + else + state=SkipBlockSize; + count = 0; + } + break; + case GraphicControlExtension: + if (count < 5) + hold[count] = ch; + ++count; + if (count == hold[0] + 1) { + count = 0; + state = SkipBlockSize; + } + break; + case NetscapeExtensionBlockSize: + blockSize = ch; + count = 0; + if (blockSize) + state = NetscapeExtensionBlock; + else + state = Introducer; + break; + case NetscapeExtensionBlock: + if (count < 3) + hold[count] = ch; + count++; + if (count == blockSize) { + *loopCount = LM(hold[1], hold[2]); + state = SkipBlockSize; + } + break; + case SkipBlockSize: + blockSize = ch; + count = 0; + if (blockSize) { + if (length >= blockSize) { + // we can skip the block in one go + length -= blockSize; + buffer += blockSize; + } else { + state = SkipBlock; + } + } else { + state = Introducer; + } + break; + case SkipBlock: + ++count; + if (count == blockSize) + state = SkipBlockSize; + break; + case Done: + done = true; + break; + case Error: + device->seek(oldPos); + return; + } + } + readBuffer = device->read(readBufferSize); + } + device->seek(oldPos); + return; +} + void QGIFFormat::fillRect(QImage *image, int col, int row, int w, int h, QRgb color) { if (w>0) { @@ -763,9 +1027,9 @@ QGifHandler::QGifHandler() { gifFormat = new QGIFFormat; nextDelay = 0; - loopCnt = 0; + loopCnt = 1; frameNumber = -1; - nextSize = QSize(); + scanIsCached = false; } QGifHandler::~QGifHandler() @@ -787,7 +1051,7 @@ bool QGifHandler::imageIsComing() const } int decoded = gifFormat->decode(&lastImage, (const uchar *)buffer.constData(), buffer.size(), - &nextDelay, &loopCnt, &nextSize); + &nextDelay, &loopCnt); if (decoded == -1) break; buffer.remove(0, decoded); @@ -831,7 +1095,7 @@ bool QGifHandler::read(QImage *image) } int decoded = gifFormat->decode(&lastImage, (const uchar *)buffer.constData(), buffer.size(), - &nextDelay, &loopCnt, &nextSize); + &nextDelay, &loopCnt); if (decoded == -1) break; buffer.remove(0, decoded); @@ -862,8 +1126,18 @@ bool QGifHandler::supportsOption(ImageOption option) const QVariant QGifHandler::option(ImageOption option) const { if (option == Size) { - if (imageIsComing()) - return nextSize; + if (!scanIsCached) { + QGIFFormat::scan(device(), &imageSizes, &loopCnt); + scanIsCached = true; + } + // before the first frame is read, or we have an empty data stream + if (frameNumber == -1) + return (imageSizes.count() > 0) ? QVariant(imageSizes.at(0)) : QVariant(); + // after the last frame has been read, the next size is undefined + if (frameNumber >= imageSizes.count() - 1) + return QVariant(); + // and the last case: the size of the next frame + return imageSizes.at(frameNumber + 1); } else if (option == Animation) { return true; } @@ -883,11 +1157,19 @@ int QGifHandler::nextImageDelay() const int QGifHandler::imageCount() const { - return 0; // Don't know + if (!scanIsCached) { + QGIFFormat::scan(device(), &imageSizes, &loopCnt); + scanIsCached = true; + } + return imageSizes.count(); } int QGifHandler::loopCount() const { + if (!scanIsCached) { + QGIFFormat::scan(device(), &imageSizes, &loopCnt); + scanIsCached = true; + } return loopCnt-1; // In GIF, loop count is iteration count, so subtract one } diff --git a/src/plugins/imageformats/gif/qgifhandler.h b/src/plugins/imageformats/gif/qgifhandler.h index a6e520f..8e07aff 100644 --- a/src/plugins/imageformats/gif/qgifhandler.h +++ b/src/plugins/imageformats/gif/qgifhandler.h @@ -87,7 +87,8 @@ private: mutable int nextDelay; mutable int loopCnt; int frameNumber; - mutable QSize nextSize; + mutable QVector<QSize> imageSizes; + mutable bool scanIsCached; }; QT_END_NAMESPACE diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp index 4f49476..4edb87a 100644 --- a/src/plugins/imageformats/ico/qicohandler.cpp +++ b/src/plugins/imageformats/ico/qicohandler.cpp @@ -53,6 +53,7 @@ #include <QtGui/QImage> #include <QtCore/QFile> #include <QtCore/QBuffer> +#include <qvariant.h> // These next two structs represent how the icon information is stored // in an ICO file. typedef struct @@ -556,7 +557,11 @@ QImage ICOReader::iconAt(int index) else // # colors used icoAttrib.ncolors = header.biClrUsed ? header.biClrUsed : 1 << icoAttrib.nbits; icoAttrib.w = iconEntry.bWidth; + if (icoAttrib.w == 0) + icoAttrib.w = header.biWidth; icoAttrib.h = iconEntry.bHeight; + if (icoAttrib.h == 0) + icoAttrib.h = header.biHeight/2; QImage::Format format = QImage::Format_ARGB32; if (icoAttrib.nbits == 24) @@ -768,6 +773,29 @@ QtIcoHandler::~QtIcoHandler() delete m_pICOReader; } +QVariant QtIcoHandler::option(ImageOption option) const +{ + if (option == Size) { + QIODevice *device = QImageIOHandler::device(); + qint64 oldPos = device->pos(); + ICONDIRENTRY iconEntry; + if (device->seek(oldPos + ICONDIR_SIZE + (m_currentIconIndex * ICONDIRENTRY_SIZE))) { + if (readIconDirEntry(device, &iconEntry)) { + device->seek(oldPos); + return QSize(iconEntry.bWidth, iconEntry.bHeight); + } + } + if (!device->isSequential()) + device->seek(oldPos); + } + return QVariant(); +} + +bool QtIcoHandler::supportsOption(ImageOption option) const +{ + return option == Size; +} + /*! * Verifies if some values (magic bytes) are set as expected in the header of the file. * If the magic bytes were found, it is assumed that the QtIcoHandler can read the file. diff --git a/src/plugins/imageformats/ico/qicohandler.h b/src/plugins/imageformats/ico/qicohandler.h index b9ef27e..394a5eb 100644 --- a/src/plugins/imageformats/ico/qicohandler.h +++ b/src/plugins/imageformats/ico/qicohandler.h @@ -62,6 +62,9 @@ public: static bool canRead(QIODevice *device); + bool supportsOption(ImageOption option) const; + QVariant option(ImageOption option) const; + private: int m_currentIconIndex; ICOReader *m_pICOReader; diff --git a/src/plugins/kbddrivers/linuxinput/main.cpp b/src/plugins/kbddrivers/linuxinput/main.cpp index 19a3145..db5167e 100644 --- a/src/plugins/kbddrivers/linuxinput/main.cpp +++ b/src/plugins/kbddrivers/linuxinput/main.cpp @@ -69,7 +69,7 @@ QWSKeyboardHandler* QLinuxInputKbdDriver::create(const QString &driver, Q_UNUSED(device); if (driver.compare(QLatin1String("LinuxInput"), Qt::CaseInsensitive)) return 0; - return new QWSLinuxInputKeyboardHandler(driver, device); + return new QWSLinuxInputKeyboardHandler(device); } Q_EXPORT_PLUGIN2(qwslinuxinputkbddriver, QLinuxInputKbdDriver) diff --git a/src/qbase.pri b/src/qbase.pri index 3307ae3..710a2b6 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -103,7 +103,7 @@ symbian { # of Qt, and the only compatibility will be between this build of Qt and anything # built in this exact environment. *Never* use this when building a version # for release. - contains(QT_CONFIG, def_files) { + contains(CONFIG, def_files) { defFilePath=../s60installs } } diff --git a/src/qt3support/dialogs/q3filedialog.cpp b/src/qt3support/dialogs/q3filedialog.cpp index 9b8e4d3..35f7890 100644 --- a/src/qt3support/dialogs/q3filedialog.cpp +++ b/src/qt3support/dialogs/q3filedialog.cpp @@ -475,9 +475,17 @@ static int sortFilesBy = (int)QDir::Name; static bool sortAscending = true; static bool detailViewMode = false; -static Q3CleanupHandler<QPixmap> qfd_cleanup_pixmap; static Q3CleanupHandler<QString> qfd_cleanup_string; +static void qt_cleanup_fd_pixmaps(); +typedef QList<QPixmap *> FDPixmaps; +Q_GLOBAL_STATIC_WITH_INITIALIZER(FDPixmaps, qfd_pixmaps, qAddPostRoutine(qt_cleanup_fd_pixmaps)) + +static void qt_cleanup_fd_pixmaps() +{ + qDeleteAll(*qfd_pixmaps()); +} + static QString toRootIfNotExists( const QString &path ) { if ( !path.isEmpty() ) @@ -533,37 +541,37 @@ static void makeVariables() { qfd_cleanup_string.add(&workingDirectory); openFolderIcon = new QPixmap((const char **)open_xpm); - qfd_cleanup_pixmap.add(&openFolderIcon); + qfd_pixmaps()->append(openFolderIcon); symLinkDirIcon = new QPixmap((const char **)link_dir_xpm); - qfd_cleanup_pixmap.add(&symLinkDirIcon); + qfd_pixmaps()->append(symLinkDirIcon); symLinkFileIcon = new QPixmap((const char **)link_file_xpm); - qfd_cleanup_pixmap.add(&symLinkFileIcon); + qfd_pixmaps()->append(symLinkFileIcon); fileIcon = new QPixmap((const char **)file_xpm); - qfd_cleanup_pixmap.add(&fileIcon); + qfd_pixmaps()->append(fileIcon); closedFolderIcon = new QPixmap((const char **)closed_xpm); - qfd_cleanup_pixmap.add(&closedFolderIcon); + qfd_pixmaps()->append(closedFolderIcon); detailViewIcon = new QPixmap((const char **)detailedview_xpm); - qfd_cleanup_pixmap.add(&detailViewIcon); + qfd_pixmaps()->append(detailViewIcon); multiColumnListViewIcon = new QPixmap((const char **)mclistview_xpm); - qfd_cleanup_pixmap.add(&multiColumnListViewIcon); + qfd_pixmaps()->append(multiColumnListViewIcon); cdToParentIcon = new QPixmap((const char **)cdtoparent_xpm); - qfd_cleanup_pixmap.add(&cdToParentIcon); + qfd_pixmaps()->append(cdToParentIcon); newFolderIcon = new QPixmap((const char **)newfolder_xpm); - qfd_cleanup_pixmap.add(&newFolderIcon); + qfd_pixmaps()->append(newFolderIcon); previewInfoViewIcon = new QPixmap((const char **)previewinfoview_xpm); - qfd_cleanup_pixmap.add(&previewInfoViewIcon); + qfd_pixmaps()->append(previewInfoViewIcon); previewContentsViewIcon = new QPixmap((const char **)previewcontentsview_xpm); - qfd_cleanup_pixmap.add(&previewContentsViewIcon); + qfd_pixmaps()->append(previewContentsViewIcon); startCopyIcon = new QPixmap((const char **)start_xpm); - qfd_cleanup_pixmap.add(&startCopyIcon); + qfd_pixmaps()->append(startCopyIcon); endCopyIcon = new QPixmap((const char **)end_xpm); - qfd_cleanup_pixmap.add(&endCopyIcon); + qfd_pixmaps()->append(endCopyIcon); goBackIcon = new QPixmap((const char **)back_xpm); - qfd_cleanup_pixmap.add(&goBackIcon); + qfd_pixmaps()->append(goBackIcon); fifteenTransparentPixels = new QPixmap(closedFolderIcon->width(), 1); - qfd_cleanup_pixmap.add(&fifteenTransparentPixels); + qfd_pixmaps()->append(fifteenTransparentPixels); QBitmap m(fifteenTransparentPixels->width(), 1); m.fill(Qt::color0); fifteenTransparentPixels->setMask(m); diff --git a/src/qt3support/itemviews/q3iconview.cpp b/src/qt3support/itemviews/q3iconview.cpp index 67c956e..683e3d6 100644 --- a/src/qt3support/itemviews/q3iconview.cpp +++ b/src/qt3support/itemviews/q3iconview.cpp @@ -132,14 +132,21 @@ static QPixmap *qiv_selection = 0; #endif static bool optimize_layout = false; -static Q3CleanupHandler<QPixmap> qiv_cleanup_pixmap; +static void qt_cleanup_iv_pixmaps(); +typedef QList<QPixmap *> IVPixmaps; +Q_GLOBAL_STATIC_WITH_INITIALIZER(IVPixmaps, qiv_pixmaps, qAddPostRoutine(qt_cleanup_iv_pixmaps)) + +static void qt_cleanup_iv_pixmaps() +{ + qDeleteAll(*qiv_pixmaps()); +} static QPixmap *get_qiv_buffer_pixmap(const QSize &s) { if (!qiv_buffer_pixmap) { qiv_buffer_pixmap = new QPixmap(s); - qiv_cleanup_pixmap.add(&qiv_buffer_pixmap); + qiv_pixmaps()->append(qiv_buffer_pixmap); return qiv_buffer_pixmap; } @@ -2580,7 +2587,7 @@ Q3IconView::Q3IconView(QWidget *parent, const char *name, Qt::WindowFlags f) { if (!unknown_icon) { unknown_icon = new QPixmap((const char **)unknown_xpm); - qiv_cleanup_pixmap.add(&unknown_icon); + qiv_pixmaps()->append(unknown_icon); } d = new Q3IconViewPrivate; diff --git a/src/qt3support/itemviews/q3listview.cpp b/src/qt3support/itemviews/q3listview.cpp index 2c15ad0..12dad84 100644 --- a/src/qt3support/itemviews/q3listview.cpp +++ b/src/qt3support/itemviews/q3listview.cpp @@ -70,9 +70,6 @@ QT_BEGIN_NAMESPACE const int Unsorted = 16383; -static Q3CleanupHandler<QBitmap> qlv_cleanup_bitmap; - - struct Q3ListViewPrivate { // classes that are here to avoid polluting the global name space diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index da65230..4f30cb5 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -2081,8 +2081,8 @@ EXPORTS ?addPixmap@QGraphicsScene@@QAEPAVQGraphicsPixmapItem@@ABVQPixmap@@@Z @ 2080 NONAME ; class QGraphicsPixmapItem * QGraphicsScene::addPixmap(class QPixmap const &) ?addPixmap@QIcon@@QAEXABVQPixmap@@W4Mode@1@W4State@1@@Z @ 2081 NONAME ; void QIcon::addPixmap(class QPixmap const &, enum QIcon::Mode, enum QIcon::State) ?addPixmap@QIconEngine@@UAEXABVQPixmap@@W4Mode@QIcon@@W4State@4@@Z @ 2082 NONAME ; void QIconEngine::addPixmap(class QPixmap const &, enum QIcon::Mode, enum QIcon::State) - ?addPixmapDestructionHook@QImagePixmapCleanupHooks@@QAEXP6AXPAVQPixmap@@@Z@Z @ 2083 NONAME ; void QImagePixmapCleanupHooks::addPixmapDestructionHook(void (*)(class QPixmap *)) - ?addPixmapModificationHook@QImagePixmapCleanupHooks@@QAEXP6AXPAVQPixmap@@@Z@Z @ 2084 NONAME ; void QImagePixmapCleanupHooks::addPixmapModificationHook(void (*)(class QPixmap *)) + ?addPixmapDestructionHook@QImagePixmapCleanupHooks@@QAEXP6AXPAVQPixmap@@@Z@Z @ 2083 NONAME ABSENT ; void QImagePixmapCleanupHooks::addPixmapDestructionHook(void (*)(class QPixmap *)) + ?addPixmapModificationHook@QImagePixmapCleanupHooks@@QAEXP6AXPAVQPixmap@@@Z@Z @ 2084 NONAME ABSENT ; void QImagePixmapCleanupHooks::addPixmapModificationHook(void (*)(class QPixmap *)) ?addPolygon@QGraphicsScene@@QAEPAVQGraphicsPolygonItem@@ABVQPolygonF@@ABVQPen@@ABVQBrush@@@Z @ 2085 NONAME ; class QGraphicsPolygonItem * QGraphicsScene::addPolygon(class QPolygonF const &, class QPen const &, class QBrush const &) ?addPolygon@QPainterPath@@QAEXABVQPolygonF@@@Z @ 2086 NONAME ; void QPainterPath::addPolygon(class QPolygonF const &) ?addRect@QGraphicsScene@@QAEPAVQGraphicsRectItem@@ABVQRectF@@ABVQPen@@ABVQBrush@@@Z @ 2087 NONAME ; class QGraphicsRectItem * QGraphicsScene::addRect(class QRectF const &, class QPen const &, class QBrush const &) @@ -4283,8 +4283,8 @@ EXPORTS ?executeDelayedItemsLayout@QAbstractItemView@@IAEXXZ @ 4282 NONAME ; void QAbstractItemView::executeDelayedItemsLayout(void) ?executeImageHooks@QImagePixmapCleanupHooks@@SAX_J@Z @ 4283 NONAME ; void QImagePixmapCleanupHooks::executeImageHooks(long long) ?executePendingSort@QTreeWidgetItem@@ABEXXZ @ 4284 NONAME ; void QTreeWidgetItem::executePendingSort(void) const - ?executePixmapDestructionHooks@QImagePixmapCleanupHooks@@SAXPAVQPixmap@@@Z @ 4285 NONAME ; void QImagePixmapCleanupHooks::executePixmapDestructionHooks(class QPixmap *) - ?executePixmapModificationHooks@QImagePixmapCleanupHooks@@SAXPAVQPixmap@@@Z @ 4286 NONAME ; void QImagePixmapCleanupHooks::executePixmapModificationHooks(class QPixmap *) + ?executePixmapDestructionHooks@QImagePixmapCleanupHooks@@SAXPAVQPixmap@@@Z @ 4285 NONAME ABSENT ; void QImagePixmapCleanupHooks::executePixmapDestructionHooks(class QPixmap *) + ?executePixmapModificationHooks@QImagePixmapCleanupHooks@@SAXPAVQPixmap@@@Z @ 4286 NONAME ABSENT ; void QImagePixmapCleanupHooks::executePixmapModificationHooks(class QPixmap *) ?expand@QTreeView@@QAEXABVQModelIndex@@@Z @ 4287 NONAME ; void QTreeView::expand(class QModelIndex const &) ?expandAll@QTreeView@@QAEXXZ @ 4288 NONAME ; void QTreeView::expandAll(void) ?expandItem@QTreeWidget@@QAEXPBVQTreeWidgetItem@@@Z @ 4289 NONAME ; void QTreeWidget::expandItem(class QTreeWidgetItem const *) @@ -5527,7 +5527,7 @@ EXPORTS ?invalidateChildrenSceneTransform@QGraphicsItemPrivate@@QAEXXZ @ 5526 NONAME ; void QGraphicsItemPrivate::invalidateChildrenSceneTransform(void) ?invalidateDepthRecursively@QGraphicsItemPrivate@@QAEXXZ @ 5527 NONAME ; void QGraphicsItemPrivate::invalidateDepthRecursively(void) ?invalidateFilter@QSortFilterProxyModel@@IAEXXZ @ 5528 NONAME ; void QSortFilterProxyModel::invalidateFilter(void) - ?invalidateGraphicsEffectsRecursively@QGraphicsItemPrivate@@QAEXXZ @ 5529 NONAME ; void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively(void) + ?invalidateGraphicsEffectsRecursively@QGraphicsItemPrivate@@QAEXXZ @ 5529 NONAME ABSENT ; void QGraphicsItemPrivate::invalidateGraphicsEffectsRecursively(void) ?invalidateGraphicsEffectsRecursively@QWidgetPrivate@@QAEXXZ @ 5530 NONAME ; void QWidgetPrivate::invalidateGraphicsEffectsRecursively(void) ?invalidateScene@QGraphicsView@@QAEXABVQRectF@@V?$QFlags@W4SceneLayer@QGraphicsScene@@@@@Z @ 5531 NONAME ; void QGraphicsView::invalidateScene(class QRectF const &, class QFlags<enum QGraphicsScene::SceneLayer>) ?invalidateSizeCache@QWidgetItemV2@@AAEXXZ @ 5532 NONAME ; void QWidgetItemV2::invalidateSizeCache(void) @@ -7927,8 +7927,8 @@ EXPORTS ?removeItemWidget@QTreeWidget@@QAEXPAVQTreeWidgetItem@@H@Z @ 7926 NONAME ; void QTreeWidget::removeItemWidget(class QTreeWidgetItem *, int) ?removeMapping@QDataWidgetMapper@@QAEXPAVQWidget@@@Z @ 7927 NONAME ; void QDataWidgetMapper::removeMapping(class QWidget *) ?removePage@QWizard@@QAEXH@Z @ 7928 NONAME ; void QWizard::removePage(int) - ?removePixmapDestructionHook@QImagePixmapCleanupHooks@@QAEXP6AXPAVQPixmap@@@Z@Z @ 7929 NONAME ; void QImagePixmapCleanupHooks::removePixmapDestructionHook(void (*)(class QPixmap *)) - ?removePixmapModificationHook@QImagePixmapCleanupHooks@@QAEXP6AXPAVQPixmap@@@Z@Z @ 7930 NONAME ; void QImagePixmapCleanupHooks::removePixmapModificationHook(void (*)(class QPixmap *)) + ?removePixmapDestructionHook@QImagePixmapCleanupHooks@@QAEXP6AXPAVQPixmap@@@Z@Z @ 7929 NONAME ABSENT ; void QImagePixmapCleanupHooks::removePixmapDestructionHook(void (*)(class QPixmap *)) + ?removePixmapModificationHook@QImagePixmapCleanupHooks@@QAEXP6AXPAVQPixmap@@@Z@Z @ 7930 NONAME ABSENT ; void QImagePixmapCleanupHooks::removePixmapModificationHook(void (*)(class QPixmap *)) ?removeRow@QStandardItem@@QAEXH@Z @ 7931 NONAME ; void QStandardItem::removeRow(int) ?removeRow@QTableWidget@@QAEXH@Z @ 7932 NONAME ; void QTableWidget::removeRow(int) ?removeRows@QSortFilterProxyModel@@UAE_NHHABVQModelIndex@@@Z @ 7933 NONAME ; bool QSortFilterProxyModel::removeRows(int, int, class QModelIndex const &) @@ -9555,7 +9555,7 @@ EXPORTS ?setParent@QWidget@@QAEXPAV1@@Z @ 9554 NONAME ; void QWidget::setParent(class QWidget *) ?setParent@QWidget@@QAEXPAV1@V?$QFlags@W4WindowType@Qt@@@@@Z @ 9555 NONAME ; void QWidget::setParent(class QWidget *, class QFlags<enum Qt::WindowType>) ?setParentItem@QGraphicsItem@@QAEXPAV1@@Z @ 9556 NONAME ; void QGraphicsItem::setParentItem(class QGraphicsItem *) - ?setParentItemHelper@QGraphicsItemPrivate@@QAEXPAVQGraphicsItem@@@Z @ 9557 NONAME ; void QGraphicsItemPrivate::setParentItemHelper(class QGraphicsItem *) + ?setParentItemHelper@QGraphicsItemPrivate@@QAEXPAVQGraphicsItem@@@Z @ 9557 NONAME ABSENT ; void QGraphicsItemPrivate::setParentItemHelper(class QGraphicsItem *) ?setParentLayoutItem@QGraphicsLayoutItem@@QAEXPAV1@@Z @ 9558 NONAME ; void QGraphicsLayoutItem::setParentLayoutItem(class QGraphicsLayoutItem *) ?setParent_sys@QWidgetPrivate@@QAEXPAVQWidget@@V?$QFlags@W4WindowType@Qt@@@@@Z @ 9559 NONAME ; void QWidgetPrivate::setParent_sys(class QWidget *, class QFlags<enum Qt::WindowType>) ?setPasswordCharacter@QLineControl@@QAEXABVQChar@@@Z @ 9560 NONAME ; void QLineControl::setPasswordCharacter(class QChar const &) @@ -12533,4 +12533,72 @@ EXPORTS ?symbianHandleCommand@QApplicationPrivate@@QAEHPBVQSymbianEvent@@@Z @ 12532 NONAME ; int QApplicationPrivate::symbianHandleCommand(class QSymbianEvent const *) ?symbianProcessWsEvent@QApplicationPrivate@@QAEHPBVQSymbianEvent@@@Z @ 12533 NONAME ; int QApplicationPrivate::symbianProcessWsEvent(class QSymbianEvent const *) ?symbianResourceChange@QApplicationPrivate@@QAEHPBVQSymbianEvent@@@Z @ 12534 NONAME ; int QApplicationPrivate::symbianResourceChange(class QSymbianEvent const *) + ?addPixmapDataDestructionHook@QImagePixmapCleanupHooks@@QAEXP6AXPAVQPixmapData@@@Z@Z @ 12535 NONAME ; void QImagePixmapCleanupHooks::addPixmapDataDestructionHook(void (*)(class QPixmapData *)) + ?addPixmapDataModificationHook@QImagePixmapCleanupHooks@@QAEXP6AXPAVQPixmapData@@@Z@Z @ 12536 NONAME ; void QImagePixmapCleanupHooks::addPixmapDataModificationHook(void (*)(class QPixmapData *)) + ?cacheKey@QPixmapData@@QBE_JXZ @ 12537 NONAME ; long long QPixmapData::cacheKey(void) const + ?eventFilter@QS60Style@@MAE_NPAVQObject@@PAVQEvent@@@Z @ 12538 NONAME ; bool QS60Style::eventFilter(class QObject *, class QEvent *) + ?executePixmapDataDestructionHooks@QImagePixmapCleanupHooks@@SAXPAVQPixmapData@@@Z @ 12539 NONAME ; void QImagePixmapCleanupHooks::executePixmapDataDestructionHooks(class QPixmapData *) + ?executePixmapDataModificationHooks@QImagePixmapCleanupHooks@@SAXPAVQPixmapData@@@Z @ 12540 NONAME ; void QImagePixmapCleanupHooks::executePixmapDataModificationHooks(class QPixmapData *) + ?invalidateChildGraphicsEffectsRecursively@QGraphicsItemPrivate@@QAEXW4InvalidateReason@1@@Z @ 12541 NONAME ; void QGraphicsItemPrivate::invalidateChildGraphicsEffectsRecursively(enum QGraphicsItemPrivate::InvalidateReason) + ?invalidateParentGraphicsEffectsRecursively@QGraphicsItemPrivate@@QAEXXZ @ 12542 NONAME ; void QGraphicsItemPrivate::invalidateParentGraphicsEffectsRecursively(void) + ?markParentDirty@QGraphicsItemPrivate@@QAEX_N@Z @ 12543 NONAME ; void QGraphicsItemPrivate::markParentDirty(bool) + ?removePixmapDataDestructionHook@QImagePixmapCleanupHooks@@QAEXP6AXPAVQPixmapData@@@Z@Z @ 12544 NONAME ; void QImagePixmapCleanupHooks::removePixmapDataDestructionHook(void (*)(class QPixmapData *)) + ?removePixmapDataModificationHook@QImagePixmapCleanupHooks@@QAEXP6AXPAVQPixmapData@@@Z@Z @ 12545 NONAME ; void QImagePixmapCleanupHooks::removePixmapDataModificationHook(void (*)(class QPixmapData *)) + ?setParentItemHelper@QGraphicsItemPrivate@@QAEXPAVQGraphicsItem@@PBVQVariant@@1@Z @ 12546 NONAME ; void QGraphicsItemPrivate::setParentItemHelper(class QGraphicsItem *, class QVariant const *, class QVariant const *) + ?timerEvent@QS60Style@@MAEXPAVQTimerEvent@@@Z @ 12547 NONAME ; void QS60Style::timerEvent(class QTimerEvent *) + ?updateAncestorFlags@QGraphicsItemPrivate@@QAEXXZ @ 12548 NONAME ; void QGraphicsItemPrivate::updateAncestorFlags(void) + ?updateChildWithGraphicsEffectFlagRecursively@QGraphicsItemPrivate@@QAEXXZ @ 12549 NONAME ; void QGraphicsItemPrivate::updateChildWithGraphicsEffectFlagRecursively(void) + ?isOpacityNull@QGraphicsItemPrivate@@SA_NM@Z @ 12550 NONAME ; bool QGraphicsItemPrivate::isOpacityNull(float) + ?isOpacityNull@QGraphicsItemPrivate@@QBE_NXZ @ 12551 NONAME ; bool QGraphicsItemPrivate::isOpacityNull(void) const + ?api@QEglContext@@QBE?AW4API@QEgl@@XZ @ 12552 NONAME ABSENT ; enum QEgl::API QEglContext::api(void) const + ?chooseConfig@QEglContext@@QAE_NABVQEglProperties@@W4PixelFormatMatch@QEgl@@@Z @ 12553 NONAME ABSENT ; bool QEglContext::chooseConfig(class QEglProperties const &, enum QEgl::PixelFormatMatch) + ?destroySurface@QEglContext@@QAEXH@Z @ 12554 NONAME ABSENT ; void QEglContext::destroySurface(int) + ?lazyDoneCurrent@QEglContext@@QAE_NXZ @ 12555 NONAME ABSENT ; bool QEglContext::lazyDoneCurrent(void) + ?waitNative@QEglContext@@QAEXXZ @ 12556 NONAME ABSENT ; void QEglContext::waitNative(void) + ?context@QEglContext@@QBEHXZ @ 12557 NONAME ABSENT ; int QEglContext::context(void) const + ?configAttrib@QEglContext@@QBE_NHPAH@Z @ 12558 NONAME ABSENT ; bool QEglContext::configAttrib(int, int *) const + ??0QEglProperties@@QAE@ABV0@@Z @ 12559 NONAME ABSENT ; QEglProperties::QEglProperties(class QEglProperties const &) + ?config@QEglContext@@QBEHXZ @ 12560 NONAME ABSENT ; int QEglContext::config(void) const + ?openDisplay@QEglContext@@QAE_NPAVQPaintDevice@@@Z @ 12561 NONAME ABSENT ; bool QEglContext::openDisplay(class QPaintDevice *) + ?error@QEglContext@@SAHXZ @ 12562 NONAME ABSENT ; int QEglContext::error(void) + ?swapBuffers@QEglContext@@QAE_NH@Z @ 12563 NONAME ABSENT ; bool QEglContext::swapBuffers(int) + ?setApi@QEglContext@@QAEXW4API@QEgl@@@Z @ 12564 NONAME ABSENT ; void QEglContext::setApi(enum QEgl::API) + ?makeCurrent@QEglContext@@QAE_NH@Z @ 12565 NONAME ABSENT ; bool QEglContext::makeCurrent(int) + ?createSurface@QEglContext@@QAEHPAVQPaintDevice@@PBVQEglProperties@@@Z @ 12566 NONAME ABSENT ; int QEglContext::createSurface(class QPaintDevice *, class QEglProperties const *) + ?dumpAllConfigs@QEglContext@@QAEXXZ @ 12567 NONAME ABSENT ; void QEglContext::dumpAllConfigs(void) + ?reduceConfiguration@QEglProperties@@QAE_NXZ @ 12568 NONAME ABSENT ; bool QEglProperties::reduceConfiguration(void) + ?removeValue@QEglProperties@@QAE_NH@Z @ 12569 NONAME ABSENT ; bool QEglProperties::removeValue(int) + ?toString@QEglProperties@@QBE?AVQString@@XZ @ 12570 NONAME ABSENT ; class QString QEglProperties::toString(void) const + ?dumpAllConfigs@QEglProperties@@SAXXZ @ 12571 NONAME ABSENT ; void QEglProperties::dumpAllConfigs(void) + ?defaultDisplay@QEglContext@@SAHPAVQPaintDevice@@@Z @ 12572 NONAME ABSENT ; int QEglContext::defaultDisplay(class QPaintDevice *) + ?configProperties@QEglContext@@QBE?AVQEglProperties@@H@Z @ 12573 NONAME ABSENT ; class QEglProperties QEglContext::configProperties(int) const + ?properties@QEglProperties@@QBEPBHXZ @ 12574 NONAME ABSENT ; int const * QEglProperties::properties(void) const + ??0QEglContext@@QAE@XZ @ 12575 NONAME ABSENT ; QEglContext::QEglContext(void) + ??1QEglContext@@QAE@XZ @ 12576 NONAME ABSENT ; QEglContext::~QEglContext(void) + ?isValid@QEglContext@@QBE_NXZ @ 12577 NONAME ABSENT ; bool QEglContext::isValid(void) const + ?value@QEglProperties@@QBEHH@Z @ 12578 NONAME ABSENT ; int QEglProperties::value(int) const + ?clearError@QEglContext@@SAXXZ @ 12579 NONAME ABSENT ; void QEglContext::clearError(void) + ??0QEglProperties@@QAE@H@Z @ 12580 NONAME ABSENT ; QEglProperties::QEglProperties(int) + ?setValue@QEglProperties@@QAEXHH@Z @ 12581 NONAME ABSENT ; void QEglProperties::setValue(int, int) + ?setPaintDeviceFormat@QEglProperties@@QAEXPAVQPaintDevice@@@Z @ 12582 NONAME ABSENT ; void QEglProperties::setPaintDeviceFormat(class QPaintDevice *) + ?destroy@QEglContext@@QAEXXZ @ 12583 NONAME ABSENT ; void QEglContext::destroy(void) + ?setRenderableType@QEglProperties@@QAEXW4API@QEgl@@@Z @ 12584 NONAME ABSENT ; void QEglProperties::setRenderableType(enum QEgl::API) + ?setContext@QEglContext@@QAEXH@Z @ 12585 NONAME ABSENT ; void QEglContext::setContext(int) + ?waitClient@QEglContext@@QAEXXZ @ 12586 NONAME ABSENT ; void QEglContext::waitClient(void) + ?isEmpty@QEglProperties@@QBE_NXZ @ 12587 NONAME ABSENT ; bool QEglProperties::isEmpty(void) const + ?getDisplay@QEglContext@@CAHPAVQPaintDevice@@@Z @ 12588 NONAME ABSENT ; int QEglContext::getDisplay(class QPaintDevice *) + ?isSharing@QEglContext@@QBE_NXZ @ 12589 NONAME ABSENT ; bool QEglContext::isSharing(void) const + ?isCurrent@QEglContext@@QBE_NXZ @ 12590 NONAME ABSENT ; bool QEglContext::isCurrent(void) const + ??0QEglProperties@@QAE@XZ @ 12591 NONAME ABSENT ; QEglProperties::QEglProperties(void) + ?extensions@QEglContext@@SA?AVQString@@XZ @ 12592 NONAME ABSENT ; class QString QEglContext::extensions(void) + ?setCurrentContext@QEglContext@@CAXW4API@QEgl@@PAV1@@Z @ 12593 NONAME ABSENT ; void QEglContext::setCurrentContext(enum QEgl::API, class QEglContext *) + ??1QEglProperties@@QAE@XZ @ 12594 NONAME ABSENT ; QEglProperties::~QEglProperties(void) + ?createContext@QEglContext@@QAE_NPAV1@PBVQEglProperties@@@Z @ 12595 NONAME ABSENT ; bool QEglContext::createContext(class QEglContext *, class QEglProperties const *) + ?setConfig@QEglContext@@QAEXH@Z @ 12596 NONAME ABSENT ; void QEglContext::setConfig(int) + ?hasExtension@QEglContext@@SA_NPBD@Z @ 12597 NONAME ABSENT ; bool QEglContext::hasExtension(char const *) + ?doneCurrent@QEglContext@@QAE_NXZ @ 12598 NONAME ABSENT ; bool QEglContext::doneCurrent(void) + ?display@QEglContext@@QBEHXZ @ 12599 NONAME ABSENT ; int QEglContext::display(void) const + ?setPixelFormat@QEglProperties@@QAEXW4Format@QImage@@@Z @ 12600 NONAME ABSENT ; void QEglProperties::setPixelFormat(enum QImage::Format) + ?currentContext@QEglContext@@CAPAV1@W4API@QEgl@@@Z @ 12601 NONAME ABSENT ; class QEglContext * QEglContext::currentContext(enum QEgl::API) + ?errorString@QEglContext@@SA?AVQString@@H@Z @ 12602 NONAME ABSENT ; class QString QEglContext::errorString(int) diff --git a/src/s60installs/bwins/QtOpenVGu.def b/src/s60installs/bwins/QtOpenVGu.def index 88e724f..26ee862 100644 --- a/src/s60installs/bwins/QtOpenVGu.def +++ b/src/s60installs/bwins/QtOpenVGu.def @@ -48,7 +48,7 @@ EXPORTS ?paintEngine@QVGWindowSurface@@UBEPAVQPaintEngine@@XZ @ 47 NONAME ; class QPaintEngine * QVGWindowSurface::paintEngine(void) const ??0QVGPainterState@@QAE@XZ @ 48 NONAME ; QVGPainterState::QVGPainterState(void) ?d_func@QVGPaintEngine@@ABEPBVQVGPaintEnginePrivate@@XZ @ 49 NONAME ; class QVGPaintEnginePrivate const * QVGPaintEngine::d_func(void) const - ?qt_vg_create_context@@YAPAVQEglContext@@PAVQPaintDevice@@@Z @ 50 NONAME ; class QEglContext * qt_vg_create_context(class QPaintDevice *) + ?qt_vg_create_context@@YAPAVQEglContext@@PAVQPaintDevice@@@Z @ 50 NONAME ABSENT ; class QEglContext * qt_vg_create_context(class QPaintDevice *) ?clip@QVGPaintEngine@@UAEXABVQRegion@@W4ClipOperation@Qt@@@Z @ 51 NONAME ; void QVGPaintEngine::clip(class QRegion const &, enum Qt::ClipOperation) ?endNativePainting@QVGPaintEngine@@UAEXXZ @ 52 NONAME ; void QVGPaintEngine::endNativePainting(void) ?brushChanged@QVGPaintEngine@@UAEXXZ @ 53 NONAME ; void QVGPaintEngine::brushChanged(void) @@ -78,7 +78,7 @@ EXPORTS ?beginPaint@QVGEGLWindowSurfaceVGImage@@UAEXPAVQWidget@@@Z @ 77 NONAME ; void QVGEGLWindowSurfaceVGImage::beginPaint(class QWidget *) ?createState@QVGPaintEngine@@UBEPAVQPainterState@@PAV2@@Z @ 78 NONAME ; class QPainterState * QVGPaintEngine::createState(class QPainterState *) const ?buffer@QVGPixmapData@@UAEPAVQImage@@XZ @ 79 NONAME ; class QImage * QVGPixmapData::buffer(void) - ?qt_vg_destroy_context@@YAXPAVQEglContext@@@Z @ 80 NONAME ; void qt_vg_destroy_context(class QEglContext *) + ?qt_vg_destroy_context@@YAXPAVQEglContext@@@Z @ 80 NONAME ABSENT ; void qt_vg_destroy_context(class QEglContext *) ?clip@QVGPaintEngine@@UAEXABVQVectorPath@@W4ClipOperation@Qt@@@Z @ 81 NONAME ; void QVGPaintEngine::clip(class QVectorPath const &, enum Qt::ClipOperation) ?drawPolygon@QVGPaintEngine@@UAEXPBVQPoint@@HW4PolygonDrawMode@QPaintEngine@@@Z @ 82 NONAME ; void QVGPaintEngine::drawPolygon(class QPoint const *, int, enum QPaintEngine::PolygonDrawMode) ?fromImage@QVGPixmapData@@UAEXABVQImage@@V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 83 NONAME ; void QVGPixmapData::fromImage(class QImage const &, class QFlags<enum Qt::ImageConversionFlag>) @@ -139,4 +139,29 @@ EXPORTS ??_EQVGPaintEngine@@UAE@I@Z @ 138 NONAME ; QVGPaintEngine::~QVGPaintEngine(unsigned int) ?clip@QVGPaintEngine@@UAEXABVQPainterPath@@W4ClipOperation@Qt@@@Z @ 139 NONAME ; void QVGPaintEngine::clip(class QPainterPath const &, enum Qt::ClipOperation) ?vgPrivate@QVGPaintEngine@@QAEPAVQVGPaintEnginePrivate@@XZ @ 140 NONAME ; class QVGPaintEnginePrivate * QVGPaintEngine::vgPrivate(void) + ?removeFromLRU@QVGImagePool@@IAEXPAVQVGPixmapData@@@Z @ 141 NONAME ; void QVGImagePool::removeFromLRU(class QVGPixmapData *) + ?releaseImage@QVGImagePool@@UAEXPAVQVGPixmapData@@K@Z @ 142 NONAME ; void QVGImagePool::releaseImage(class QVGPixmapData *, unsigned long) + ?d_func@QVGImagePool@@AAEPAVQVGImagePoolPrivate@@XZ @ 143 NONAME ; class QVGImagePoolPrivate * QVGImagePool::d_func(void) + ?detachImageFromPool@QVGPixmapData@@UAEXXZ @ 144 NONAME ; void QVGPixmapData::detachImageFromPool(void) + ?createImageForPixmap@QVGImagePool@@UAEKW4VGImageFormat@@JJKPAVQVGPixmapData@@@Z @ 145 NONAME ; unsigned long QVGImagePool::createImageForPixmap(enum VGImageFormat, long, long, unsigned long, class QVGPixmapData *) + ?destroyImageAndContext@QVGPixmapData@@IAEXXZ @ 146 NONAME ; void QVGPixmapData::destroyImageAndContext(void) + ?moveToHeadOfLRU@QVGImagePool@@IAEXPAVQVGPixmapData@@@Z @ 147 NONAME ; void QVGImagePool::moveToHeadOfLRU(class QVGPixmapData *) + ?instance@QVGImagePool@@SAPAV1@XZ @ 148 NONAME ; class QVGImagePool * QVGImagePool::instance(void) + ?useImage@QVGImagePool@@UAEXPAVQVGPixmapData@@@Z @ 149 NONAME ; void QVGImagePool::useImage(class QVGPixmapData *) + ??1QVGImagePool@@UAE@XZ @ 150 NONAME ; QVGImagePool::~QVGImagePool(void) + ?destroyImages@QVGPixmapData@@IAEXXZ @ 151 NONAME ; void QVGPixmapData::destroyImages(void) + ?reclaimSpace@QVGImagePool@@UAE_NW4VGImageFormat@@JJPAVQVGPixmapData@@@Z @ 152 NONAME ; bool QVGImagePool::reclaimSpace(enum VGImageFormat, long, long, class QVGPixmapData *) + ?detachImage@QVGImagePool@@UAEXPAVQVGPixmapData@@@Z @ 153 NONAME ; void QVGImagePool::detachImage(class QVGPixmapData *) + ?createPermanentImage@QVGImagePool@@UAEKW4VGImageFormat@@JJK@Z @ 154 NONAME ; unsigned long QVGImagePool::createPermanentImage(enum VGImageFormat, long, long, unsigned long) + ?d_func@QVGImagePool@@ABEPBVQVGImagePoolPrivate@@XZ @ 155 NONAME ; class QVGImagePoolPrivate const * QVGImagePool::d_func(void) const + ?createTemporaryImage@QVGImagePool@@UAEKW4VGImageFormat@@JJKPAVQVGPixmapData@@@Z @ 156 NONAME ; unsigned long QVGImagePool::createTemporaryImage(enum VGImageFormat, long, long, unsigned long, class QVGPixmapData *) + ??_EQVGImagePool@@UAE@I@Z @ 157 NONAME ; QVGImagePool::~QVGImagePool(unsigned int) + ?hibernate@QVGImagePool@@UAEXXZ @ 158 NONAME ; void QVGImagePool::hibernate(void) + ?qt_vg_destroy_context@@YAXPAVQEglContext@@H@Z @ 159 NONAME ; void qt_vg_destroy_context(class QEglContext *, int) + ??0QVGImagePool@@QAE@XZ @ 160 NONAME ; QVGImagePool::QVGImagePool(void) + ?setImagePool@QVGImagePool@@SAXPAV1@@Z @ 161 NONAME ; void QVGImagePool::setImagePool(class QVGImagePool *) + ?pixmapLRU@QVGImagePool@@IAEPAVQVGPixmapData@@XZ @ 162 NONAME ; class QVGPixmapData * QVGImagePool::pixmapLRU(void) + ?qt_vg_create_context@@YAPAVQEglContext@@PAVQPaintDevice@@H@Z @ 163 NONAME ; class QEglContext * qt_vg_create_context(class QPaintDevice *, int) + ?reclaimImages@QVGPixmapData@@UAEXXZ @ 164 NONAME ; void QVGPixmapData::reclaimImages(void) + ?hibernate@QVGPixmapData@@UAEXXZ @ 165 NONAME ; void QVGPixmapData::hibernate(void) diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 05f620c..5cf700b 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -4671,7 +4671,7 @@ EXPORTS _ZN20QGraphicsItemPrivate18setTransformHelperERK10QTransform @ 4670 NONAME _ZN20QGraphicsItemPrivate18subFocusItemChangeEv @ 4671 NONAME _ZN20QGraphicsItemPrivate18updateAncestorFlagEN13QGraphicsItem16GraphicsItemFlagENS_12AncestorFlagEbb @ 4672 NONAME - _ZN20QGraphicsItemPrivate19setParentItemHelperEP13QGraphicsItem @ 4673 NONAME + _ZN20QGraphicsItemPrivate19setParentItemHelperEP13QGraphicsItem @ 4673 NONAME ABSENT _ZN20QGraphicsItemPrivate20removeExtraItemCacheEv @ 4674 NONAME _ZN20QGraphicsItemPrivate23appendGraphicsTransformEP18QGraphicsTransform @ 4675 NONAME _ZN20QGraphicsItemPrivate25movableAncestorIsSelectedEPK13QGraphicsItem @ 4676 NONAME @@ -11639,7 +11639,7 @@ EXPORTS _ZN19QGraphicsBlurEffect4drawEP8QPainter @ 11638 NONAME _ZN19QKeyEventTransition15setModifierMaskE6QFlagsIN2Qt16KeyboardModifierEE @ 11639 NONAME _ZN20QGraphicsItemPrivate18siblingOrderChangeEv @ 11640 NONAME - _ZN20QGraphicsItemPrivate36invalidateGraphicsEffectsRecursivelyEv @ 11641 NONAME + _ZN20QGraphicsItemPrivate36invalidateGraphicsEffectsRecursivelyEv @ 11641 NONAME ABSENT _ZN21QMouseEventTransition14setHitTestPathERK12QPainterPath @ 11642 NONAME _ZN21QMouseEventTransition15setModifierMaskE6QFlagsIN2Qt16KeyboardModifierEE @ 11643 NONAME _ZN22QGraphicsOpacityEffect4drawEP8QPainter @ 11644 NONAME @@ -11648,12 +11648,12 @@ EXPORTS _ZN24QImagePixmapCleanupHooks18enableCleanupHooksEP11QPixmapData @ 11647 NONAME _ZN24QImagePixmapCleanupHooks18enableCleanupHooksERK6QImage @ 11648 NONAME _ZN24QImagePixmapCleanupHooks18enableCleanupHooksERK7QPixmap @ 11649 NONAME - _ZN24QImagePixmapCleanupHooks24addPixmapDestructionHookEPFvP7QPixmapE @ 11650 NONAME - _ZN24QImagePixmapCleanupHooks25addPixmapModificationHookEPFvP7QPixmapE @ 11651 NONAME - _ZN24QImagePixmapCleanupHooks27removePixmapDestructionHookEPFvP7QPixmapE @ 11652 NONAME - _ZN24QImagePixmapCleanupHooks28removePixmapModificationHookEPFvP7QPixmapE @ 11653 NONAME - _ZN24QImagePixmapCleanupHooks29executePixmapDestructionHooksEP7QPixmap @ 11654 NONAME - _ZN24QImagePixmapCleanupHooks30executePixmapModificationHooksEP7QPixmap @ 11655 NONAME + _ZN24QImagePixmapCleanupHooks24addPixmapDestructionHookEPFvP7QPixmapE @ 11650 NONAME ABSENT + _ZN24QImagePixmapCleanupHooks25addPixmapModificationHookEPFvP7QPixmapE @ 11651 NONAME ABSENT + _ZN24QImagePixmapCleanupHooks27removePixmapDestructionHookEPFvP7QPixmapE @ 11652 NONAME ABSENT + _ZN24QImagePixmapCleanupHooks28removePixmapModificationHookEPFvP7QPixmapE @ 11653 NONAME ABSENT + _ZN24QImagePixmapCleanupHooks29executePixmapDestructionHooksEP7QPixmap @ 11654 NONAME ABSENT + _ZN24QImagePixmapCleanupHooks30executePixmapModificationHooksEP7QPixmap @ 11655 NONAME ABSENT _ZN25QGraphicsDropShadowEffect13setBlurRadiusEf @ 11656 NONAME _ZN25QGraphicsDropShadowEffect17blurRadiusChangedEf @ 11657 NONAME _ZN25QGraphicsDropShadowEffect4drawEP8QPainter @ 11658 NONAME @@ -11792,4 +11792,17 @@ EXPORTS _ZN19QApplicationPrivate20symbianHandleCommandEPK13QSymbianEvent @ 11791 NONAME _ZN19QApplicationPrivate21symbianProcessWsEventEPK13QSymbianEvent @ 11792 NONAME _ZN19QApplicationPrivate21symbianResourceChangeEPK13QSymbianEvent @ 11793 NONAME + _ZN20QGraphicsItemPrivate19setParentItemHelperEP13QGraphicsItemPK8QVariantS4_ @ 11794 NONAME + _ZN20QGraphicsItemPrivate19updateAncestorFlagsEv @ 11795 NONAME + _ZN20QGraphicsItemPrivate41invalidateChildGraphicsEffectsRecursivelyENS_16InvalidateReasonE @ 11796 NONAME + _ZN20QGraphicsItemPrivate42invalidateParentGraphicsEffectsRecursivelyEv @ 11797 NONAME + _ZN20QGraphicsItemPrivate44updateChildWithGraphicsEffectFlagRecursivelyEv @ 11798 NONAME + _ZN24QImagePixmapCleanupHooks28addPixmapDataDestructionHookEPFvP11QPixmapDataE @ 11799 NONAME + _ZN24QImagePixmapCleanupHooks29addPixmapDataModificationHookEPFvP11QPixmapDataE @ 11800 NONAME + _ZN24QImagePixmapCleanupHooks31removePixmapDataDestructionHookEPFvP11QPixmapDataE @ 11801 NONAME + _ZN24QImagePixmapCleanupHooks32removePixmapDataModificationHookEPFvP11QPixmapDataE @ 11802 NONAME + _ZN24QImagePixmapCleanupHooks33executePixmapDataDestructionHooksEP11QPixmapData @ 11803 NONAME + _ZN24QImagePixmapCleanupHooks34executePixmapDataModificationHooksEP11QPixmapData @ 11804 NONAME + _ZN9QS60Style10timerEventEP11QTimerEvent @ 11805 NONAME + _ZN9QS60Style11eventFilterEP7QObjectP6QEvent @ 11806 NONAME diff --git a/src/s60installs/eabi/QtOpenVGu.def b/src/s60installs/eabi/QtOpenVGu.def index 7526632..eb4caef 100644 --- a/src/s60installs/eabi/QtOpenVGu.def +++ b/src/s60installs/eabi/QtOpenVGu.def @@ -173,4 +173,27 @@ EXPORTS _Z21qt_vg_destroy_contextP11QEglContexti @ 172 NONAME _ZN13QVGPixmapData22destroyImageAndContextEv @ 173 NONAME _ZN13QVGPixmapData9hibernateEv @ 174 NONAME + _ZN12QVGImagePool11detachImageEP13QVGPixmapData @ 175 NONAME + _ZN12QVGImagePool12reclaimSpaceE13VGImageFormatllP13QVGPixmapData @ 176 NONAME + _ZN12QVGImagePool12releaseImageEP13QVGPixmapDatam @ 177 NONAME + _ZN12QVGImagePool12setImagePoolEPS_ @ 178 NONAME + _ZN12QVGImagePool13removeFromLRUEP13QVGPixmapData @ 179 NONAME + _ZN12QVGImagePool15moveToHeadOfLRUEP13QVGPixmapData @ 180 NONAME + _ZN12QVGImagePool20createImageForPixmapE13VGImageFormatllmP13QVGPixmapData @ 181 NONAME + _ZN12QVGImagePool20createPermanentImageE13VGImageFormatllm @ 182 NONAME + _ZN12QVGImagePool20createTemporaryImageE13VGImageFormatllmP13QVGPixmapData @ 183 NONAME + _ZN12QVGImagePool8instanceEv @ 184 NONAME + _ZN12QVGImagePool8useImageEP13QVGPixmapData @ 185 NONAME + _ZN12QVGImagePool9hibernateEv @ 186 NONAME + _ZN12QVGImagePool9pixmapLRUEv @ 187 NONAME + _ZN12QVGImagePoolC1Ev @ 188 NONAME + _ZN12QVGImagePoolC2Ev @ 189 NONAME + _ZN12QVGImagePoolD0Ev @ 190 NONAME + _ZN12QVGImagePoolD1Ev @ 191 NONAME + _ZN12QVGImagePoolD2Ev @ 192 NONAME + _ZN13QVGPixmapData13destroyImagesEv @ 193 NONAME + _ZN13QVGPixmapData13reclaimImagesEv @ 194 NONAME + _ZN13QVGPixmapData19detachImageFromPoolEv @ 195 NONAME + _ZTI12QVGImagePool @ 196 NONAME + _ZTV12QVGImagePool @ 197 NONAME diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index cff8426..60676ab 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -128,6 +128,10 @@ symbian: { graphicssystems_plugins.sources += $$QT_BUILD_TREE/plugins/graphicssystems/qvggraphicssystem.dll } + contains(QT_CONFIG, multimedia) { + qtlibraries.sources += QtMultimedia.dll + } + BLD_INF_RULES.prj_exports += "qt.iby $$CORE_MW_LAYER_IBY_EXPORT_PATH(qt.iby)" BLD_INF_RULES.prj_exports += "qtdemoapps.iby $$CORE_APP_LAYER_IBY_EXPORT_PATH(qtdemoapps.iby)" } diff --git a/src/s60installs/sqlite3.sis b/src/s60installs/sqlite3.sis Binary files differindex 1785365..11e069e 100644 --- a/src/s60installs/sqlite3.sis +++ b/src/s60installs/sqlite3.sis diff --git a/src/s60installs/sqlite3_selfsigned.sis b/src/s60installs/sqlite3_selfsigned.sis Binary files differnew file mode 100644 index 0000000..a025ac5 --- /dev/null +++ b/src/s60installs/sqlite3_selfsigned.sis diff --git a/src/s60main/s60main.pro b/src/s60main/s60main.pro index 05a045b..1ba105d 100644 --- a/src/s60main/s60main.pro +++ b/src/s60main/s60main.pro @@ -22,6 +22,9 @@ symbian { # staticlib should not have any lib depencies in s60 # This seems not to work, some hard coded libs are still added as dependency LIBS = + + # Workaround for abld toolchain problem to make ARMV6 qtmain.lib link with GCCE apps + symbian-abld: QMAKE_CXXFLAGS.ARMCC += --dllimport_runtime } else { error("$$_FILE_ is intended only for Symbian!") } diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp index 1db2e1b..5bfe46a 100644 --- a/src/script/api/qscriptvalue.cpp +++ b/src/script/api/qscriptvalue.cpp @@ -1148,10 +1148,15 @@ bool QScriptValue::strictlyEquals(const QScriptValue &other) const } if (d->type != other.d_ptr->type) { - if (d->type == QScriptValuePrivate::JavaScriptCore) - return JSC::JSValue::strictEqual(d->jscValue, d->engine->scriptValueToJSCValue(other)); - else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) - return JSC::JSValue::strictEqual(other.d_ptr->engine->scriptValueToJSCValue(*this), other.d_ptr->jscValue); + if (d->type == QScriptValuePrivate::JavaScriptCore) { + QScriptEnginePrivate *eng_p = d->engine ? d->engine : other.d_ptr->engine; + if (eng_p) + return JSC::JSValue::strictEqual(d->jscValue, eng_p->scriptValueToJSCValue(other)); + } else if (other.d_ptr->type == QScriptValuePrivate::JavaScriptCore) { + QScriptEnginePrivate *eng_p = other.d_ptr->engine ? other.d_ptr->engine : d->engine; + if (eng_p) + return JSC::JSValue::strictEqual(eng_p->scriptValueToJSCValue(*this), other.d_ptr->jscValue); + } return false; } diff --git a/src/sql/drivers/sqlite/qsql_sqlite.cpp b/src/sql/drivers/sqlite/qsql_sqlite.cpp index 9dbefaf..d3be304 100644 --- a/src/sql/drivers/sqlite/qsql_sqlite.cpp +++ b/src/sql/drivers/sqlite/qsql_sqlite.cpp @@ -245,9 +245,9 @@ bool QSQLiteResultPrivate::fetchNext(QSqlCachedResult::ValueCache &values, int i values[i + idx] = QVariant(QVariant::String); break; default: - values[i + idx] = QString::fromUtf16(static_cast<const ushort *>( + values[i + idx] = QString(reinterpret_cast<const QChar *>( sqlite3_column_text16(stmt, i)), - sqlite3_column_bytes16(stmt, i) / sizeof(ushort)); + sqlite3_column_bytes16(stmt, i) / sizeof(QChar)); break; } } @@ -500,32 +500,6 @@ bool QSQLiteDriver::hasFeature(DriverFeature f) const return false; } -static int qGetSqliteTimeout(QString opts) -{ - enum { DefaultTimeout = 5000 }; - - opts.remove(QLatin1Char(' ')); - foreach(QString option, opts.split(QLatin1Char(';'))) { - if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) { - bool ok; - int nt = option.mid(21).toInt(&ok); - if (ok) - return nt; - } - } - return DefaultTimeout; -} - -static int qGetSqliteOpenMode(QString opts) -{ - opts.remove(QLatin1Char(' ')); - foreach(QString option, opts.split(QLatin1Char(';'))) { - if (option == QLatin1String("QSQLITE_OPEN_READONLY")) - return SQLITE_OPEN_READONLY; - } - return SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; -} - /* SQLite dbs have no user name, passwords, hosts or ports. just file names. @@ -537,9 +511,26 @@ bool QSQLiteDriver::open(const QString & db, const QString &, const QString &, c if (db.isEmpty()) return false; + bool sharedCache = false; + int openMode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, timeOut=5000; + QStringList opts=QString(conOpts).remove(QLatin1Char(' ')).split(QLatin1Char(';')); + foreach(const QString &option, opts) { + if (option.startsWith(QLatin1String("QSQLITE_BUSY_TIMEOUT="))) { + bool ok; + int nt = option.mid(21).toInt(&ok); + if (ok) + timeOut = nt; + } + if (option == QLatin1String("QSQLITE_OPEN_READONLY")) + openMode = SQLITE_OPEN_READONLY; + if (option == QLatin1String("QSQLITE_ENABLE_SHARED_CACHE")) + sharedCache = true; + } + + sqlite3_enable_shared_cache(sharedCache); - if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, qGetSqliteOpenMode(conOpts), NULL) == SQLITE_OK) { - sqlite3_busy_timeout(d->access, qGetSqliteTimeout(conOpts)); + if (sqlite3_open_v2(db.toUtf8().constData(), &d->access, openMode, NULL) == SQLITE_OK) { + sqlite3_busy_timeout(d->access, timeOut); setOpen(true); setOpenError(false); return true; diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp index 031261d..1416ee3 100644 --- a/src/sql/kernel/qsqldatabase.cpp +++ b/src/sql/kernel/qsqldatabase.cpp @@ -1267,6 +1267,7 @@ QSqlRecord QSqlDatabase::record(const QString& tablename) const \list \i QSQLITE_BUSY_TIMEOUT \i QSQLITE_OPEN_READONLY + \i QSQLITE_ENABLE_SHARED_CACHE \endlist \i diff --git a/src/sql/kernel/qsqlresult.cpp b/src/sql/kernel/qsqlresult.cpp index 5f12b55..3d63f88 100644 --- a/src/sql/kernel/qsqlresult.cpp +++ b/src/sql/kernel/qsqlresult.cpp @@ -136,7 +136,7 @@ static QString qFieldSerial(int i) i >>= 4; } - return QString::fromUtf16(arr, int(ptr - arr) + 1); + return QString(reinterpret_cast<const QChar *>(arr), int(ptr - arr) + 1); } static bool qIsAlnum(QChar ch) diff --git a/src/src.pro b/src/src.pro index 92101d6..2ce5642 100644 --- a/src/src.pro +++ b/src/src.pro @@ -109,6 +109,7 @@ src_declarative.target = sub-declarative contains(QT_CONFIG, webkit) { src_webkit.depends = src_gui src_sql src_network src_xml contains(QT_CONFIG, phonon):src_webkit.depends += src_phonon + contains(QT_CONFIG, xmlpatterns): src_webkit.depends += src_xmlpatterns contains(QT_CONFIG, declarative):src_declarative.depends += src_webkit #exists($$QT_SOURCE_TREE/src/3rdparty/webkit/JavaScriptCore/JavaScriptCore.pro): src_webkit.depends += src_javascriptcore } diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp index e41cd55..1f6e58f 100644 --- a/src/tools/rcc/rcc.cpp +++ b/src/tools/rcc/rcc.cpp @@ -544,6 +544,8 @@ bool RCCResourceLibrary::addFile(const QString &alias, const RCCFileInfo &file) const QString filename = nodes.at(nodes.size()-1); RCCFileInfo *s = new RCCFileInfo(file); s->m_parent = parent; + if (parent->m_children.contains(filename)) + qWarning("potential duplicate alias detected: '%s'", qPrintable(filename)); parent->m_children.insertMulti(filename, s); return true; } diff --git a/src/tools/uic/cpp/cppwriteinitialization.cpp b/src/tools/uic/cpp/cppwriteinitialization.cpp index d9aff1b..dc1d181 100644 --- a/src/tools/uic/cpp/cppwriteinitialization.cpp +++ b/src/tools/uic/cpp/cppwriteinitialization.cpp @@ -721,8 +721,9 @@ void WriteInitialization::acceptWidget(DomWidget *node) m_output << m_indent << parentWidget << "->addDockWidget(" << area << varName << ");\n"; } else if (m_uic->customWidgetsInfo()->extends(className, QLatin1String("QStatusBar"))) { m_output << m_indent << parentWidget << "->setStatusBar(" << varName << ");\n"; - } else { - m_output << m_indent << parentWidget << "->setCentralWidget(" << varName << ");\n"; + } else if (!m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3DockWindow")) + && !m_uic->customWidgetsInfo()->extends(className, QLatin1String("Q3ToolBar"))) { + m_output << m_indent << parentWidget << "->setCentralWidget(" << varName << ");\n"; } } @@ -2787,8 +2788,8 @@ static void generateMultiDirectiveBegin(QTextStream &outputStream, const QSet<QS return; QMap<QString, bool> map; // bool is dummy. The idea is to sort that (always generate in the same order) by putting a set into a map - foreach (QString str, directives) - map[str] = true; + foreach (const QString &str, directives) + map.insert(str, true); if (map.size() == 1) { outputStream << "#ifndef " << map.constBegin().key() << endl; @@ -2797,7 +2798,7 @@ static void generateMultiDirectiveBegin(QTextStream &outputStream, const QSet<QS outputStream << "#if"; bool doOr = false; - foreach (QString str, map.keys()) { + foreach (const QString &str, map.keys()) { if (doOr) outputStream << " ||"; outputStream << " !defined(" << str << ')'; diff --git a/src/tools/uic3/converter.cpp b/src/tools/uic3/converter.cpp index 2bf293d..e1b4b38 100644 --- a/src/tools/uic3/converter.cpp +++ b/src/tools/uic3/converter.cpp @@ -401,7 +401,7 @@ DomUI *Ui3Reader::generateUi4(const QDomElement &widget) bool resolved = false; if (objName == receiver) { // see if it's a custom slot - foreach (QString cs, ui_custom_slots) { + foreach (const QString &cs, ui_custom_slots) { if (cs == slot) { resolved = true; break; @@ -1122,7 +1122,7 @@ void Ui3Reader::createProperties(const QDomElement &n, QList<DomProperty*> *prop if (prop->kind() == DomProperty::Set) { QStringList flags = prop->elementSet().split(QLatin1Char('|')); QStringList v; - foreach (QString fl, flags) { + foreach (const QString &fl, flags) { QString e = WidgetInfo::resolveEnumerator(className, fl); if (e.isEmpty()) { e = m_porting->renameEnumerator(className + QLatin1String("::") + fl); @@ -1283,7 +1283,7 @@ QString Ui3Reader::fixType(const QString &t) const QString newText = t; //split type name on <>*& and whitespace QStringList typeNames = t.split(QRegExp(QLatin1String("<|>|\\*|&| ")), QString::SkipEmptyParts); - foreach(QString typeName , typeNames) { + foreach(const QString &typeName , typeNames) { QString newName = fixClassName(typeName); if( newName != typeName ) { newText.replace(typeName, newName); diff --git a/src/tools/uic3/main.cpp b/src/tools/uic3/main.cpp index 6acc94f..1ebb76a 100644 --- a/src/tools/uic3/main.cpp +++ b/src/tools/uic3/main.cpp @@ -338,10 +338,10 @@ int runUic3(int argc, char * argv[]) QStringList globalIncludes, localIncludes; ui3.computeDeps(e, globalIncludes, localIncludes, impl); - foreach (QString i, globalIncludes) + foreach (const QString &i, globalIncludes) printf("%s\n", i.toLatin1().constData()); - foreach (QString i, localIncludes) + foreach (const QString &i, localIncludes) printf("%s\n", i.toLatin1().constData()); if (impl) diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index cae959b..8d9ae4f 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -2973,7 +2973,7 @@ QDomElement QDomNode::lastChildElement(const QString &tagName) const } /*! - Returns the next sibilng element with tag name \a tagName if \a tagName + Returns the next sibling element with tag name \a tagName if \a tagName is non-empty; otherwise returns any next sibling element. Returns a null element if no such sibling exists. diff --git a/src/xmlpatterns/data/qatomicvalue.cpp b/src/xmlpatterns/data/qatomicvalue.cpp index 6858e27..c4f3578 100644 --- a/src/xmlpatterns/data/qatomicvalue.cpp +++ b/src/xmlpatterns/data/qatomicvalue.cpp @@ -226,6 +226,8 @@ ItemType::Ptr AtomicValue::qtToXDMType(const QXmlItem &item) /* Fallthrough. */ case QVariant::Time: return BuiltinTypes::xsDateTime; + case QMetaType::Float: + return BuiltinTypes::xsFloat; case QVariant::Double: return BuiltinTypes::xsDouble; default: diff --git a/src/xmlpatterns/schema/qxsdschemaparser.cpp b/src/xmlpatterns/schema/qxsdschemaparser.cpp index 6d878e8..6ed28af 100644 --- a/src/xmlpatterns/schema/qxsdschemaparser.cpp +++ b/src/xmlpatterns/schema/qxsdschemaparser.cpp @@ -4832,7 +4832,7 @@ XsdTerm::Ptr XsdSchemaParser::parseLocalElement(const XsdParticle::Ptr &particle if (isSchemaTag(XsdSchemaToken::Annotation, token, namespaceToken)) { const XsdAnnotation::Ptr annotation = parseAnnotation(); - element->addAnnotation(annotation); + term->addAnnotation(annotation); } else if (isSchemaTag(XsdSchemaToken::SimpleType, token, namespaceToken)) { if (hasRefAttribute) { error(QtXmlPatterns::tr("%1 element with %2 child element must not have a %3 attribute.") |