diff options
author | Geir Vattekar <geir.vattekar@nokia.com> | 2010-06-15 12:02:32 (GMT) |
---|---|---|
committer | Geir Vattekar <geir.vattekar@nokia.com> | 2010-06-15 12:02:32 (GMT) |
commit | ac3c3b3a19207328ffbcbdada10ef61291caba15 (patch) | |
tree | a33f216d62aa506448f7fb6cbdf7640f5f223fe0 /src | |
parent | c5b06919a8fb5d20aae41f0edf9e2ffa99eb1a8a (diff) | |
parent | a041e4eca3467c1baa6245b6fb47def127f30f41 (diff) | |
download | Qt-ac3c3b3a19207328ffbcbdada10ef61291caba15.zip Qt-ac3c3b3a19207328ffbcbdada10ef61291caba15.tar.gz Qt-ac3c3b3a19207328ffbcbdada10ef61291caba15.tar.bz2 |
Merge branch '4.7' of git@scm.dev.nokia.troll.no:qt/oslo-staging-2 into 4.7
Diffstat (limited to 'src')
295 files changed, 5325 insertions, 1928 deletions
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp index 022689b..b3c229e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/jit/JITStubs.cpp @@ -1094,6 +1094,10 @@ RVCT() #define DEFINE_STUB_FUNCTION(rtype, op) rtype JIT_STUB cti_##op(STUB_ARGS_DECLARATION) #endif +#if COMPILER(GCC) +#pragma GCC visibility push(hidden) +#endif + DEFINE_STUB_FUNCTION(EncodedJSValue, op_convert_this) { STUB_INIT_STACK_FRAME(stackFrame); @@ -3205,6 +3209,10 @@ DEFINE_STUB_FUNCTION(EncodedJSValue, to_object) return JSValue::encode(stackFrame.args[0].jsValue().toObject(callFrame)); } +#if COMPILER(GCC) +#pragma GCC visibility pop +#endif + } // namespace JSC #endif // ENABLE(JIT) diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp index 6cfeb76..9b64ab3 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.cpp @@ -184,6 +184,8 @@ int AbstractAudioEffect::effectParameterChanged( const EffectParameter ¶m, const QVariant &value) { // Default implementation + Q_UNUSED(param) + Q_UNUSED(value) Q_ASSERT_X(false, Q_FUNC_INFO, "Effect has no parameters"); return 0; } diff --git a/src/3rdparty/phonon/mmf/abstractaudioeffect.h b/src/3rdparty/phonon/mmf/abstractaudioeffect.h index d71993b..70adcf6 100644 --- a/src/3rdparty/phonon/mmf/abstractaudioeffect.h +++ b/src/3rdparty/phonon/mmf/abstractaudioeffect.h @@ -118,6 +118,10 @@ private: // for each of the effects. Using this reduces repetition of boilerplate // in the implementations of the backend effect nodes. +#ifdef Q_CC_NOKIAX86 +# pragma warn_illtokenpasting off +#endif + #define PHONON_MMF_DEFINE_EFFECT_FUNCTIONS(Effect) \ \ void Effect##::createEffect(AudioPlayer::NativePlayer *player) \ diff --git a/src/3rdparty/phonon/mmf/audiooutput.cpp b/src/3rdparty/phonon/mmf/audiooutput.cpp index c6be20b..3588683 100644 --- a/src/3rdparty/phonon/mmf/audiooutput.cpp +++ b/src/3rdparty/phonon/mmf/audiooutput.cpp @@ -78,6 +78,9 @@ bool MMF::AudioOutput::setOutputDevice(int index) { Q_ASSERT_X(index == AudioOutputDeviceID, Q_FUNC_INFO, "We only support one output device, with id 0"); +#ifdef QT_NO_DEBUG + Q_UNUSED(index) +#endif return true; } diff --git a/src/3rdparty/phonon/mmf/bassboost.cpp b/src/3rdparty/phonon/mmf/bassboost.cpp index c7af939..67076f6 100644 --- a/src/3rdparty/phonon/mmf/bassboost.cpp +++ b/src/3rdparty/phonon/mmf/bassboost.cpp @@ -49,6 +49,7 @@ const char* BassBoost::description() bool BassBoost::getParameters(CMdaAudioOutputStream *stream, QList<EffectParameter> ¶meters) { + Q_UNUSED(parameters) QScopedPointer<CBassBoost> effect; TRAPD(err, effect.reset(CBassBoost::NewL(*stream))); return (KErrNone == err); diff --git a/src/3rdparty/phonon/mmf/effectfactory.cpp b/src/3rdparty/phonon/mmf/effectfactory.cpp index c5e33d5..4643978 100644 --- a/src/3rdparty/phonon/mmf/effectfactory.cpp +++ b/src/3rdparty/phonon/mmf/effectfactory.cpp @@ -183,8 +183,9 @@ EffectFactory::EffectData EffectFactory::getData() /* defaultValue */ QVariant(bool(true))); data.m_parameters.append(param); - if (data.m_supported = BackendNode::getParameters - (stream.data(), data.m_parameters)) { + data.m_supported = BackendNode::getParameters(stream.data(), + data.m_parameters); + if (data.m_supported) { const QString description = QCoreApplication::translate ("Phonon::MMF::EffectFactory", BackendNode::description()); data.m_descriptions.insert("name", description); diff --git a/src/3rdparty/phonon/mmf/loudness.cpp b/src/3rdparty/phonon/mmf/loudness.cpp index 1079a35..ca05ab0 100644 --- a/src/3rdparty/phonon/mmf/loudness.cpp +++ b/src/3rdparty/phonon/mmf/loudness.cpp @@ -49,6 +49,7 @@ const char* Loudness::description() bool Loudness::getParameters(CMdaAudioOutputStream *stream, QList<EffectParameter> ¶meters) { + Q_UNUSED(parameters) QScopedPointer<CLoudness> effect; TRAPD(err, effect.reset(CLoudness::NewL(*stream))); return (KErrNone == err); diff --git a/src/3rdparty/webkit/.tag b/src/3rdparty/webkit/.tag index 49b1cbe..125e175 100644 --- a/src/3rdparty/webkit/.tag +++ b/src/3rdparty/webkit/.tag @@ -1 +1 @@ -c58dc2f491a824ac56e31c440fcf7fe16dab09c4 +0f8941d0dd5f947530e1dc55b859d810bba14764 diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog index 016e0dd..d9b2987 100644 --- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog +++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog @@ -1,3 +1,18 @@ +2010-06-07 Benjamin Poulain <benjamin.poulain@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Crash when compiling on Snow Leopard and running on Leopard + https://bugs.webkit.org/show_bug.cgi?id=31403 + + Disable the use of pthread_setname_np and other symbols + when targetting Leopard. + + Use the defines TARGETING_XX instead of BUILDING_ON_XX + for features that cannot be used before Snow Leopard. + + * wtf/Platform.h: + 2010-04-20 Csaba Osztrogonác <ossy@webkit.org> [Qt] Unreviewed speculative buildfix for WinCE after r57882 diff --git a/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h b/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h index fac477e..876e60e 100644 --- a/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h +++ b/src/3rdparty/webkit/JavaScriptCore/wtf/Platform.h @@ -700,11 +700,11 @@ #define HAVE_SYS_TIME_H 1 #define HAVE_SYS_TIMEB_H 1 -#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) +#if !defined(TARGETING_TIGER) && !defined(TARGETING_LEOPARD) #define HAVE_DISPATCH_H 1 -#if !PLATFORM(IPHONE) && !PLATFORM(QT) +#if !PLATFORM(IPHONE) #define HAVE_MADV_FREE_REUSE 1 #define HAVE_MADV_FREE 1 #define HAVE_PTHREAD_SETNAME_NP 1 diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index 1db0c55..6aaae4f 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -4,4 +4,4 @@ This is a snapshot of the Qt port of WebKit from and has the sha1 checksum - 531b0d7cd2af830f0d17b83b6e4a489794481539 + f943ead2759537527faa7f3cb057d995291663b9 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index daf10fa..e04729d 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,351 @@ +2010-06-13 Noam Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Eric Seidel. + + [Qt] GraphicsLayer: recaching images creates an unnecessary deep copy + https://bugs.webkit.org/show_bug.cgi?id=40535 + + Made sure the painter ends its operation before copying the pixmap. + + No new tests: this is an optimization. + + * platform/graphics/qt/GraphicsLayerQt.cpp: + (WebCore::GraphicsLayerQtImpl::recache): + +2010-03-24 Dumitru Daniliuc <dumi@chromium.org> + + Reviewed by Dimitri Glazkov. + + Changing the V8 and JSC implementations of + SQLStatementErrorCallback to interpret as false all results that + could be converted to a false boolean. Pretty much a revert of + r54981. + + https://bugs.webkit.org/show_bug.cgi?id=36569 + + * bindings/js/JSCustomSQLStatementErrorCallback.cpp: + (WebCore::JSCustomSQLStatementErrorCallback::handleEvent): + * bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp: + (WebCore::V8CustomSQLStatementErrorCallback::handleEvent): + * bindings/v8/custom/V8CustomVoidCallback.cpp: + (WebCore::invokeCallback): + * bindings/v8/custom/V8CustomVoidCallback.h: + +2010-06-13 Noam Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] tests/hybridPixmap fails + https://bugs.webkit.org/show_bug.cgi?id=37316 + + The problem was that JSC::Instance::createRuntimeObject was never called. + This is fixed by overloading newRuntimeObject and calling Instance::createRuntimeObject + in between, instead of creating the runtime object directly inside the static function + QtPixmapInstance::createRuntimeObject, which had to be renamed as to not overshadow the virtual function. + + This fixes an existing test, tests/hybridPixmap + + * bridge/qt/qt_pixmapruntime.cpp: + (JSC::Bindings::QtPixmapInstance::newRuntimeObject): + (JSC::Bindings::QtPixmapInstance::createPixmapRuntimeObject): + * bridge/qt/qt_pixmapruntime.h: + * bridge/qt/qt_runtime.cpp: + (JSC::Bindings::convertQVariantToValue): + +2010-06-07 Mahesh Kulakrni <mahesh.kulkarni@nokia.com> + + Reviewed by Simon Hausmann. + + [QT] QT_BEARER flag is not enabled on S60 properly + https://bugs.webkit.org/show_bug.cgi?id=39357 + + enable QT_BEARER for all platform based on qtmobility + + bearer module availability or for qt 4.7+ + + * WebCore.pri: + +2010-06-09 Csaba Osztrogonác <ossy@webkit.org> + + Reviewed by Dirk Schulze. + + [Qt] Imperfect dependency for generated SVGNames.cpp + https://bugs.webkit.org/show_bug.cgi?id=40359 + + * WebCore.pri: Missing dependency added. + +2010-06-08 Kenneth Rohde Christiansen <kenneth.christiansen@openbossa.org> + + Unreviewed Buildbot fix. + + Reset the Qt TextBreakIterator when reusing it. + + * platform/text/qt/TextBreakIteratorQt.cpp: + (WebCore::setUpIterator): + +2010-06-08 Kenneth Rohde Christiansen <kenneth.christiansen@openbossa.org> + + Reviewed by Antti Koivisto. + + [Qt] TextBreakIterator Qt performance + https://bugs.webkit.org/show_bug.cgi?id=39958 + + Rework TextBreakIteratorQt to be more in line with the ICU version. + + We now reuse iterators where ever possible. The string data is compared + with memcmp, which should be faster than using a hash, as you need + to traverse the full buffer in the case the strings don't match, + where as the compare would fail quickly. + + * platform/text/qt/TextBreakIteratorQt.cpp: + (WebCore::TextBreakIterator::TextBreakIterator): + (WebCore::setUpIterator): + (WebCore::wordBreakIterator): + (WebCore::characterBreakIterator): + (WebCore::lineBreakIterator): + (WebCore::sentenceBreakIterator): + +2010-06-07 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix text selection drawing. + https://bugs.webkit.org/show_bug.cgi?id=40221 + + The regression was introduced in r60169. + + * platform/graphics/qt/FontQt.cpp: + (WebCore::drawTextCommon): + +2010-06-04 No'am Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Fix compilation with QT_NO_FEATURE + https://bugs.webkit.org/show_bug.cgi?id=38324 + + The #ifdef QT_NO_GRAPHICSEFFECT was in the wrong place, would have + made AC not work at all. + + No new tests. + + * platform/graphics/qt/GraphicsLayerQt.cpp: + (WebCore::GraphicsLayerQtImpl::flushChanges): + +2010-05-24 Tasuku Suzuki <tasuku.suzuki@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Fix compilation with QT_NO_TEMPORARYFILE + https://bugs.webkit.org/show_bug.cgi?id=38324 + + * platform/qt/FileSystemQt.cpp: + (WebCore::openTemporaryFile): + +2010-05-21 Tasuku Suzuki <tasuku.suzuki@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix compilation with QT_NO_GRAPHICSEFFECT + https://bugs.webkit.org/show_bug.cgi?id=38324 + + * platform/graphics/qt/GraphicsLayerQt.cpp: + (WebCore::GraphicsLayerQtImpl::flushChanges): + +2010-05-02 Tasuku Suzuki <tasuku.suzuki@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix compilation with QT_NO_BEARERMANAGEMENT + https://bugs.webkit.org/show_bug.cgi?id=38324 + + * platform/network/NetworkStateNotifier.h: + * platform/network/qt/NetworkStateNotifierQt.cpp: + +2010-05-02 Tasuku Suzuki <tasuku.suzuki@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix compilation with QT_NO_LINEEDIT + https://bugs.webkit.org/show_bug.cgi?id=38324 + + * platform/qt/RenderThemeQt.cpp: + (WebCore::RenderThemeQt::~RenderThemeQt): + (WebCore::RenderThemeQt::findFrameLineWidth): + +2010-06-04 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Tor Arne Vestbø. + + [Qt] Compilation fails when compiling against Qt 4.7 and Qt Mobility is installed + https://bugs.webkit.org/show_bug.cgi?id=40116 + + CONFIG += mobility has the side-effect of pulling in mobility includes, which conflict + with Qt 4.7's bearer managenent includes and break the build. + + * WebCore.pro: + +2010-06-03 Tor Arne Vestbø <tor.arne.vestbo@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix NPAPI support on Mac OS X/Cocoa-32 + + qt_mac_window_for() returns a NSWindow on Cocoa, so we were + passing in a NSWindow instead of a WindowRef as part of the + NP_CGContext. + + https://bugs.webkit.org/show_bug.cgi?id=38762 + + * WebCore.gypi: Reflect rename + * WebCore.pro: Reflect rename + * plugins/mac/PluginViewMac.cpp: Renamed to PluginViewMac.mm + and fix bug by getting the Carbon windowRef from the NSWindow. + * wscript: Reflect rename + +2010-06-02 Nico Weber <thakis@chromium.org> + + Reviewed by Simon Fraser. + + Scroll events are sent twice per keypress for ports that don't have a platformWidget scrollbar + https://bugs.webkit.org/show_bug.cgi?id=39918 + + This was regressed by http://trac.webkit.org/changeset/58615 . Fix this by slightly tweaking + that patch. + + Test: editing/input/page-up-down-scrolls.html + + * page/FrameView.cpp: + (WebCore::FrameView::scrollPositionChanged): + * page/FrameView.h: + * platform/ScrollView.cpp: + (WebCore::ScrollView::valueChanged): + * platform/ScrollView.h: + (WebCore::ScrollView::repaintFixedElementsAfterScrolling): + +2010-06-02 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix make install on Symbian for headers in package builds when INSTALL_HEADERS is not defined + + First we wrote inst_headers.output with $$[QT_INSTALL_HEADERS] and then + overwrote it with the $$INSTALL_HEADERS variant without checking if the + variable was set. + + Fixed and cleaned up the logic of falling back to $$[QT_INSTALL_HEADERS]. + + * WebCore.pro: + +2010-06-01 No'am Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] GraphicsLayer: warnings when reloading page + https://bugs.webkit.org/show_bug.cgi?id=39694 + + Made sure recaching and masks aren't attempted on zero-size layers. + + No new tests. Old tests (e.g. LayoutTests/compositing/masks) show the problem. + + * platform/graphics/qt/GraphicsLayerQt.cpp: + (WebCore::MaskEffectQt::draw): + (WebCore::GraphicsLayerQtImpl::recache): + +2010-05-10 Rodrigo Belem <rodrigo.belem@openbossa.org> + + Reviewed by Kenneth Christiansen , Simon Hausmann and Gustavo Noronha. + + [Qt, Gtk] Allows build-webkit script to receive an install prefix as parameter + https://bugs.webkit.org/show_bug.cgi?id=26224 + + This patch adds the ability, in the QtWebkit build system, to change + the installation path. + + * WebCore.pro: + +2010-06-01 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Laszlo Gombos. + + [Qt] Fix installation of the QtWebKit module .pri file when building inside of Qt + + * WebCore.pro: + +2010-06-01 Jocelyn Turcotte <jocelyn.turcotte@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix a QtWebKit.pc corruption problem. + https://bugs.webkit.org/show_bug.cgi?id=36826 + + The problem occurs while installing QtWebKit from trunk + or a source package. + + * WebCore.pro: + +2010-06-01 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Laszlo Gombos. + + [Qt] Fix Symbian package dependencies of apps against QtWebKit when installing into Qt + + Install the versioning qt_webkit_version.pri into $$[QMAKE_MKSPECS]/modules, which is + where mkspecs/features/qt.prf expects it. + + * WebCore.pro: + +2010-05-17 Andreas Kling <andreas.kling@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + Bring CanvasRenderingContext2D's createImageData() in line with HTML5 spec + Added createImageData(ImageData) which returns a new ImageData with the same size as the one passed. + Changed createImageData(width, height) to use the absolute values of width and height. + + https://bugs.webkit.org/show_bug.cgi?id=39189 + + Spec link: + http://www.whatwg.org/specs/web-apps/current-work/#dom-context-2d-createimagedata + + Test: fast/canvas/canvas-createImageData.html + + * bindings/js/JSCanvasRenderingContext2DCustom.cpp: + (WebCore::JSCanvasRenderingContext2D::createImageData): + * html/canvas/CanvasRenderingContext2D.cpp: + (WebCore::CanvasRenderingContext2D::createImageData): + * html/canvas/CanvasRenderingContext2D.h: + * html/canvas/CanvasRenderingContext2D.idl: + +2010-05-16 Andreas Kling <andreas.kling@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + Properly handle invalid arguments to CanvasRenderingContext2D's getImageData() and putImageData(). + Both should throw NOT_SUPPORTED_ERR when called with nonfinite arguments. + getImageData() should throw INDEX_SIZE_ERR if either width or height is 0. + + https://bugs.webkit.org/show_bug.cgi?id=39175 + + Spec link: + http://www.whatwg.org/specs/web-apps/current-work/#pixel-manipulation + + Test: fast/canvas/canvas-getImageData-invalid.html + + * html/canvas/CanvasRenderingContext2D.cpp: + (WebCore::CanvasRenderingContext2D::createImageData): + (WebCore::CanvasRenderingContext2D::getImageData): + (WebCore::CanvasRenderingContext2D::putImageData): + +2010-05-31 Oswald Buddenhagen <oswald.buddenhagen@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Escape backslashes in the .pro files + + qmake in Qt 4.7 warns about unescaped backspaces and deprecates them. + + * WebCore.pro: + 2010-05-28 Antti Koivisto <koivisto@iki.fi> Reviewed by Kenneth Rohde Christiansen. diff --git a/src/3rdparty/webkit/WebCore/WebCore.gypi b/src/3rdparty/webkit/WebCore/WebCore.gypi index 1e92f1f..94a6052 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.gypi +++ b/src/3rdparty/webkit/WebCore/WebCore.gypi @@ -2920,7 +2920,7 @@ 'plugins/gtk/xembed.h', 'plugins/mac/PluginDataMac.mm', 'plugins/mac/PluginPackageMac.cpp', - 'plugins/mac/PluginViewMac.cpp', + 'plugins/mac/PluginViewMac.mm', 'plugins/qt/PluginDataQt.cpp', 'plugins/qt/PluginPackageQt.cpp', 'plugins/qt/PluginViewQt.cpp', diff --git a/src/3rdparty/webkit/WebCore/WebCore.pri b/src/3rdparty/webkit/WebCore/WebCore.pri index 5f5987f..9debd6a 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pri +++ b/src/3rdparty/webkit/WebCore/WebCore.pri @@ -101,18 +101,19 @@ greaterThan(QT_MINOR_VERSION, 5) { DEFINES += ENABLE_XSLT=0 } -!CONFIG(QTDIR_build):!contains(DEFINES, ENABLE_QT_BEARER=.) { - symbian: { - exists($${EPOCROOT}epoc32/release/winscw/udeb/QtBearer.lib)| \ - exists($${EPOCROOT}epoc32/release/armv5/lib/QtBearer.lib) { +# Bearer management is part of Qt 4.7 +# for older version, check for mobility with bearer +!contains(DEFINES, ENABLE_QT_BEARER=.) { + !lessThan(QT_MINOR_VERSION, 7) { + DEFINES += ENABLE_QT_BEARER=1 + } else { + load(mobilityconfig) + contains(MOBILITY_CONFIG, bearer) { DEFINES += ENABLE_QT_BEARER=1 } } } -# Bearer management is part of Qt 4.7 -!lessThan(QT_MINOR_VERSION, 7):!contains(DEFINES, ENABLE_QT_BEARER=.):DEFINES += ENABLE_QT_BEARER=1 - # Enable touch event support with Qt 4.6 !lessThan(QT_MINOR_VERSION, 6): DEFINES += ENABLE_TOUCH_EVENTS=1 @@ -593,6 +594,7 @@ contains(DEFINES, ENABLE_SVG=1) { # GENERATOR 5-C: svgnames.output = $${WC_GENERATED_SOURCES_DIR}/SVGNames.cpp svgnames.input = SVG_NAMES + svgnames.depends = $$PWD/svg/svgattrs.in svgnames.wkScript = $$PWD/dom/make_names.pl svgnames.commands = perl -I$$PWD/bindings/scripts $$svgnames.wkScript --tags $$PWD/svg/svgtags.in --attrs $$PWD/svg/svgattrs.in --extraDefines \"$${DEFINES}\" --preprocessor \"$${QMAKE_MOC} -E\" --factory --wrapperFactory --outputDir $$WC_GENERATED_SOURCES_DIR svgnames.wkExtraSources = $${WC_GENERATED_SOURCES_DIR}/SVGElementFactory.cpp $${WC_GENERATED_SOURCES_DIR}/JSSVGElementWrapperFactory.cpp diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro index 5def728..048fc93 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pro +++ b/src/3rdparty/webkit/WebCore/WebCore.pro @@ -74,7 +74,8 @@ CONFIG(QTDIR_build) { !static: DEFINES += QT_MAKEDLL symbian: TARGET =$$TARGET$${QT_LIBINFIX} } -include($$PWD/../WebKit/qt/qtwebkit_version.pri) +moduleFile=$$PWD/../WebKit/qt/qt_webkit_version.pri +include($$moduleFile) VERSION = $${QT_WEBKIT_MAJOR_VERSION}.$${QT_WEBKIT_MINOR_VERSION}.$${QT_WEBKIT_PATCH_VERSION} unix { @@ -159,7 +160,7 @@ defineTest(addExtraCompiler) { for(file,input) { base = $$basename(file) - base ~= s/\..+// + base ~= s/\\..+// newfile=$$replace(outputRule,\\$\\{QMAKE_FILE_BASE\\},$$base) SOURCES += $$newfile } @@ -2165,7 +2166,7 @@ contains(DEFINES, ENABLE_NETSCAPE_PLUGIN_API=1) { mac { SOURCES += \ plugins/mac/PluginPackageMac.cpp \ - plugins/mac/PluginViewMac.cpp + plugins/mac/PluginViewMac.mm OBJECTIVE_SOURCES += \ platform/text/mac/StringImplMac.mm \ platform/mac/WebCoreNSStringExtras.mm @@ -2495,8 +2496,12 @@ contains(DEFINES, ENABLE_QT_BEARER=1) { SOURCES += \ platform/network/qt/NetworkStateNotifierQt.cpp - CONFIG += mobility - MOBILITY += bearer + # Bearer management is part of Qt 4.7, so don't accidentially + # pull in Qt Mobility when building against >= 4.7 + !greaterThan(QT_MINOR_VERSION, 6) { + CONFIG += mobility + MOBILITY += bearer + } } contains(DEFINES, ENABLE_SVG=1) { @@ -2840,24 +2845,45 @@ contains(DEFINES, ENABLE_SYMBIAN_DIALOG_PROVIDERS) { include($$PWD/../WebKit/qt/Api/headers.pri) HEADERS += $$WEBKIT_API_HEADERS -!CONFIG(QTDIR_build) { +CONFIG(QTDIR_build) { + modfile.files = $$moduleFile + modfile.path = $$[QMAKE_MKSPECS]/modules + + INSTALLS += modfile +} else { exists($$OUTPUT_DIR/include/QtWebKit/classheaders.pri): include($$OUTPUT_DIR/include/QtWebKit/classheaders.pri) WEBKIT_INSTALL_HEADERS = $$WEBKIT_API_HEADERS $$WEBKIT_CLASS_HEADERS !symbian { headers.files = $$WEBKIT_INSTALL_HEADERS - headers.path = $$[QT_INSTALL_HEADERS]/QtWebKit - target.path = $$[QT_INSTALL_LIBS] - INSTALLS += target headers + !isEmpty(INSTALL_HEADERS): headers.path = $$INSTALL_HEADERS/QtWebKit + else: headers.path = $$[QT_INSTALL_HEADERS]/QtWebKit + + !isEmpty(INSTALL_LIBS): target.path = $$INSTALL_LIBS + else: target.path = $$[QT_INSTALL_LIBS] + + modfile.files = $$moduleFile + modfile.path = $$[QMAKE_MKSPECS]/modules + + INSTALLS += target headers modfile } else { # INSTALLS is not implemented in qmake's s60 generators, copy headers manually inst_headers.commands = $$QMAKE_COPY ${QMAKE_FILE_NAME} ${QMAKE_FILE_OUT} inst_headers.input = WEBKIT_INSTALL_HEADERS - inst_headers.output = $$[QT_INSTALL_HEADERS]/QtWebKit/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT} + + !isEmpty(INSTALL_HEADERS): inst_headers.output = $$INSTALL_HEADERS/QtWebKit/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT} + else: inst_headers.output = $$[QT_INSTALL_HEADERS]/QtWebKit/${QMAKE_FILE_BASE}${QMAKE_FILE_EXT} + QMAKE_EXTRA_COMPILERS += inst_headers - install.depends += compiler_inst_headers_make_all + inst_modfile.commands = $$inst_headers.commands + inst_modfile.input = moduleFile + inst_modfile.output = $$[QMAKE_MKSPECS]/modules + + QMAKE_EXTRA_COMPILERS += inst_modfile + + install.depends += compiler_inst_headers_make_all compiler_inst_modfile_make_all QMAKE_EXTRA_TARGETS += install } @@ -2875,7 +2901,7 @@ HEADERS += $$WEBKIT_API_HEADERS QMAKE_PKGCONFIG_LIBDIR = $$target.path QMAKE_PKGCONFIG_INCDIR = $$headers.path QMAKE_PKGCONFIG_DESTDIR = pkgconfig - lib_replace.match = $$DESTDIR + lib_replace.match = $$re_escape($$DESTDIR) lib_replace.replace = $$[QT_INSTALL_LIBS] QMAKE_PKGCONFIG_INSTALL_REPLACE += lib_replace } diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp index a271923..0254d0f 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp @@ -361,6 +361,24 @@ JSValue JSCanvasRenderingContext2D::createPattern(ExecState* exec, const ArgList return jsUndefined(); } +JSValue JSCanvasRenderingContext2D::createImageData(ExecState* exec, const ArgList& args) +{ + // createImageData has two variants + // createImageData(ImageData) + // createImageData(width, height) + CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>(impl()); + RefPtr<ImageData> imageData = 0; + + ExceptionCode ec = 0; + if (args.size() == 1) + imageData = context->createImageData(toImageData(args.at(0)), ec); + else if (args.size() == 2) + imageData = context->createImageData(args.at(0).toFloat(exec), args.at(1).toFloat(exec), ec); + + setDOMException(exec, ec); + return toJS(exec, globalObject(), WTF::getPtr(imageData)); +} + JSValue JSCanvasRenderingContext2D::putImageData(ExecState* exec, const ArgList& args) { // putImageData has two variants diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp index 4d5de79..6178509 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp @@ -77,7 +77,7 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, // Therefore an exception and returning true are the same thing - so, return true on an exception return true; } - return !result.isFalse(); + return result.toBoolean(exec); } } diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.cpp index 803316d..3e6197f 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.cpp @@ -346,10 +346,17 @@ returnEmptyVariant: return QVariant::fromValue<QImage>(QImage()); return QVariant(); } -JSObject* QtPixmapInstance::createRuntimeObject(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& data) + +RuntimeObject* QtPixmapInstance::newRuntimeObject(ExecState* exec) +{ + return new(exec) QtPixmapRuntimeObject(exec, this); +} + +JSObject* QtPixmapInstance::createPixmapRuntimeObject(ExecState* exec, PassRefPtr<RootObject> root, const QVariant& data) { JSLock lock(SilenceAssertionsOnly); - return new(exec) QtPixmapRuntimeObject(exec, new QtPixmapInstance(root, data)); + QtPixmapInstance* instance = new QtPixmapInstance(root, data); + return instance->createRuntimeObject(exec); } bool QtPixmapInstance::canHandle(QMetaType::Type hint) diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.h b/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.h index a0e0e26..de1bcee 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.h +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.h @@ -42,7 +42,8 @@ public: int height() const; QPixmap toPixmap(); QImage toImage(); - static JSObject* createRuntimeObject(ExecState*, PassRefPtr<RootObject>, const QVariant&); + RuntimeObject* newRuntimeObject(ExecState* exec); + static JSObject* createPixmapRuntimeObject(ExecState*, PassRefPtr<RootObject>, const QVariant&); static QVariant variantFromObject(JSObject*, QMetaType::Type hint); static bool canHandle(QMetaType::Type hint); }; diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp index 4524d97..a39dc7a 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp @@ -877,7 +877,7 @@ JSValue convertQVariantToValue(ExecState* exec, PassRefPtr<RootObject> root, con } if (QtPixmapInstance::canHandle(static_cast<QMetaType::Type>(variant.type()))) - return QtPixmapInstance::createRuntimeObject(exec, root, variant); + return QtPixmapInstance::createPixmapRuntimeObject(exec, root, variant); if (type == qMetaTypeId<QWebElement>()) { if (!root->globalObject()->inherits(&JSDOMWindow::s_info)) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCanvasRenderingContext2D.cpp b/src/3rdparty/webkit/WebCore/generated/JSCanvasRenderingContext2D.cpp index a991e8d..d97b54a 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCanvasRenderingContext2D.cpp +++ b/src/3rdparty/webkit/WebCore/generated/JSCanvasRenderingContext2D.cpp @@ -165,7 +165,7 @@ static const HashTableValue JSCanvasRenderingContext2DPrototypeTableValues[45] = { "drawImageFromRect", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsCanvasRenderingContext2DPrototypeFunctionDrawImageFromRect), (intptr_t)0 }, { "setShadow", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsCanvasRenderingContext2DPrototypeFunctionSetShadow), (intptr_t)0 }, { "createPattern", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsCanvasRenderingContext2DPrototypeFunctionCreatePattern), (intptr_t)0 }, - { "createImageData", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsCanvasRenderingContext2DPrototypeFunctionCreateImageData), (intptr_t)2 }, + { "createImageData", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsCanvasRenderingContext2DPrototypeFunctionCreateImageData), (intptr_t)0 }, { "getImageData", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsCanvasRenderingContext2DPrototypeFunctionGetImageData), (intptr_t)4 }, { "putImageData", DontDelete|Function, (intptr_t)static_cast<NativeFunction>(jsCanvasRenderingContext2DPrototypeFunctionPutImageData), (intptr_t)0 }, { 0, 0, 0, 0 } @@ -1018,15 +1018,7 @@ JSValue JSC_HOST_CALL jsCanvasRenderingContext2DPrototypeFunctionCreateImageData if (!thisValue.inherits(&JSCanvasRenderingContext2D::s_info)) return throwError(exec, TypeError); JSCanvasRenderingContext2D* castedThisObj = static_cast<JSCanvasRenderingContext2D*>(asObject(thisValue)); - CanvasRenderingContext2D* imp = static_cast<CanvasRenderingContext2D*>(castedThisObj->impl()); - ExceptionCode ec = 0; - float sw = args.at(0).toFloat(exec); - float sh = args.at(1).toFloat(exec); - - - JSC::JSValue result = toJS(exec, castedThisObj->globalObject(), WTF::getPtr(imp->createImageData(sw, sh, ec))); - setDOMException(exec, ec); - return result; + return castedThisObj->createImageData(exec, args); } JSValue JSC_HOST_CALL jsCanvasRenderingContext2DPrototypeFunctionGetImageData(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args) diff --git a/src/3rdparty/webkit/WebCore/generated/JSCanvasRenderingContext2D.h b/src/3rdparty/webkit/WebCore/generated/JSCanvasRenderingContext2D.h index 218e455..92fabb7 100644 --- a/src/3rdparty/webkit/WebCore/generated/JSCanvasRenderingContext2D.h +++ b/src/3rdparty/webkit/WebCore/generated/JSCanvasRenderingContext2D.h @@ -61,6 +61,7 @@ public: JSC::JSValue drawImageFromRect(JSC::ExecState*, const JSC::ArgList&); JSC::JSValue setShadow(JSC::ExecState*, const JSC::ArgList&); JSC::JSValue createPattern(JSC::ExecState*, const JSC::ArgList&); + JSC::JSValue createImageData(JSC::ExecState*, const JSC::ArgList&); JSC::JSValue putImageData(JSC::ExecState*, const JSC::ArgList&); protected: static const unsigned StructureFlags = JSC::OverridesGetOwnPropertySlot | Base::StructureFlags; diff --git a/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.cpp index 398e4d8..9cec7a9 100644 --- a/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.cpp +++ b/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.cpp @@ -1278,14 +1278,30 @@ static PassRefPtr<ImageData> createEmptyImageData(const IntSize& size) return data.get(); } +PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(PassRefPtr<ImageData> imageData, ExceptionCode& ec) const +{ + if (!imageData) { + ec = NOT_SUPPORTED_ERR; + return 0; + } + + IntSize size(imageData->width(), imageData->height()); + return createEmptyImageData(size); +} + PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(float sw, float sh, ExceptionCode& ec) const { ec = 0; + if (!sw || !sh) { + ec = INDEX_SIZE_ERR; + return 0; + } if (!isfinite(sw) || !isfinite(sh)) { ec = NOT_SUPPORTED_ERR; return 0; } - FloatSize unscaledSize(sw, sh); + + FloatSize unscaledSize(fabs(sw), fabs(sh)); IntSize scaledSize = canvas()->convertLogicalToDevice(unscaledSize); if (scaledSize.width() < 1) scaledSize.setWidth(1); @@ -1301,7 +1317,15 @@ PassRefPtr<ImageData> CanvasRenderingContext2D::getImageData(float sx, float sy, ec = SECURITY_ERR; return 0; } - + if (!sw || !sh) { + ec = INDEX_SIZE_ERR; + return 0; + } + if (!isfinite(sx) || !isfinite(sy) || !isfinite(sw) || !isfinite(sh)) { + ec = NOT_SUPPORTED_ERR; + return 0; + } + FloatRect unscaledRect(sx, sy, sw, sh); IntRect scaledRect = canvas()->convertLogicalToDevice(unscaledRect); if (scaledRect.width() < 1) @@ -1332,7 +1356,7 @@ void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, } if (!isfinite(dx) || !isfinite(dy) || !isfinite(dirtyX) || !isfinite(dirtyY) || !isfinite(dirtyWidth) || !isfinite(dirtyHeight)) { - ec = INDEX_SIZE_ERR; + ec = NOT_SUPPORTED_ERR; return; } diff --git a/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.h b/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.h index 553ffd2..2220f7e 100644 --- a/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.h +++ b/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.h @@ -178,6 +178,7 @@ namespace WebCore { PassRefPtr<CanvasPattern> createPattern(HTMLImageElement*, const String& repetitionType, ExceptionCode&); PassRefPtr<CanvasPattern> createPattern(HTMLCanvasElement*, const String& repetitionType, ExceptionCode&); + PassRefPtr<ImageData> createImageData(PassRefPtr<ImageData> imageData, ExceptionCode&) const; PassRefPtr<ImageData> createImageData(float width, float height, ExceptionCode&) const; PassRefPtr<ImageData> getImageData(float sx, float sy, float sw, float sh, ExceptionCode&) const; void putImageData(ImageData*, float dx, float dy, ExceptionCode&); diff --git a/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.idl b/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.idl index f93a752..3f7ead7 100644 --- a/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.idl +++ b/src/3rdparty/webkit/WebCore/html/canvas/CanvasRenderingContext2D.idl @@ -105,13 +105,12 @@ module html { [Custom] void drawImageFromRect(/* 10 */); [Custom] void setShadow(/* 3 */); [Custom] void createPattern(/* 2 */); + [Custom] ImageData createImageData(/* 3 */); attribute [Custom] custom strokeStyle; attribute [Custom] custom fillStyle; // pixel manipulation - ImageData createImageData(in float sw, in float sh) - raises (DOMException); ImageData getImageData(in float sx, in float sy, in float sw, in float sh) raises(DOMException); [Custom] void putImageData(/* in ImageData imagedata, in float dx, in float dy [, in float dirtyX, in float dirtyY, in float dirtyWidth, in float dirtyHeight] */); diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/WebCore/page/FrameView.cpp index 39c92de..bc0519f 100644 --- a/src/3rdparty/webkit/WebCore/page/FrameView.cpp +++ b/src/3rdparty/webkit/WebCore/page/FrameView.cpp @@ -1060,7 +1060,11 @@ void FrameView::setScrollPosition(const IntPoint& scrollPoint) void FrameView::scrollPositionChanged() { frame()->eventHandler()->sendScrollEvent(); + repaintFixedElementsAfterScrolling(); +} +void FrameView::repaintFixedElementsAfterScrolling() +{ // For fixed position elements, update widget positions and compositing layers after scrolling, // but only if we're not inside of layout. // FIXME: we could skip this if we knew the page had no fixed position elements. diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.h b/src/3rdparty/webkit/WebCore/page/FrameView.h index 7119975..71e2966 100644 --- a/src/3rdparty/webkit/WebCore/page/FrameView.h +++ b/src/3rdparty/webkit/WebCore/page/FrameView.h @@ -139,7 +139,8 @@ public: virtual void scrollRectIntoViewRecursively(const IntRect&); virtual void setScrollPosition(const IntPoint&); - virtual void scrollPositionChanged(); + void scrollPositionChanged(); + virtual void repaintFixedElementsAfterScrolling(); String mediaType() const; void setMediaType(const String&); diff --git a/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp b/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp index e50ab55..5753e1d 100644 --- a/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp +++ b/src/3rdparty/webkit/WebCore/platform/ScrollView.cpp @@ -292,7 +292,7 @@ void ScrollView::valueChanged(Scrollbar* scrollbar) if (scrollbarsSuppressed()) return; - scrollPositionChanged(); + repaintFixedElementsAfterScrolling(); scrollContents(scrollDelta); } diff --git a/src/3rdparty/webkit/WebCore/platform/ScrollView.h b/src/3rdparty/webkit/WebCore/platform/ScrollView.h index 118a310..0f79fa8 100644 --- a/src/3rdparty/webkit/WebCore/platform/ScrollView.h +++ b/src/3rdparty/webkit/WebCore/platform/ScrollView.h @@ -303,7 +303,7 @@ private: void updateScrollbars(const IntSize& desiredOffset); // Called when the scroll position within this view changes. FrameView overrides this to generate repaint invalidations. - virtual void scrollPositionChanged() {} + virtual void repaintFixedElementsAfterScrolling() {} void platformInit(); void platformDestroy(); diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/FontQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/FontQt.cpp index b707f9d..ae1033e 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/FontQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/FontQt.cpp @@ -146,6 +146,7 @@ void Font::drawComplexText(GraphicsContext* ctx, const TextRun& run, const Float line.draw(p, pt); p->restore(); } + p->setPen(textFillPen); line.draw(p, pt); p->restore(); return; diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp index 02bf25e..ad2ec9c 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp @@ -43,6 +43,7 @@ namespace WebCore { +#ifndef QT_NO_GRAPHICSEFFECT class MaskEffectQt : public QGraphicsEffect { public: MaskEffectQt(QObject* parent, QGraphicsItem* maskLayer) @@ -57,7 +58,12 @@ public: // It's more efficient to do it this way because // (a) we don't need the QBrush abstraction - we always end up using QGraphicsItem::paint from the mask layer // (b) QGraphicsOpacityEffect detaches the pixmap, which is inefficient on OpenGL. - QPixmap maskPixmap(sourceBoundingRect().toAlignedRect().size()); + const QSize maskSize = sourceBoundingRect().toAlignedRect().size(); + if (!maskSize.isValid() || maskSize.isEmpty()) { + drawSource(painter); + return; + } + QPixmap maskPixmap(maskSize); // we need to do this so the pixmap would have hasAlpha() maskPixmap.fill(Qt::transparent); @@ -91,6 +97,7 @@ public: QGraphicsItem* m_maskLayer; }; +#endif // QT_NO_GRAPHICSEFFECT class GraphicsLayerQtImpl : public QGraphicsObject { Q_OBJECT @@ -179,7 +186,9 @@ public: TransformationMatrix m_transformRelativeToRootLayer; bool m_transformAnimationRunning; bool m_opacityAnimationRunning; +#ifndef QT_NO_GRAPHICSEFFECT QWeakPointer<MaskEffectQt> m_maskEffect; +#endif struct ContentData { QPixmap pixmap; @@ -294,7 +303,7 @@ const GraphicsLayerQtImpl* GraphicsLayerQtImpl::rootLayer() const QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate) { - if (!m_layer->drawsContent()) + if (!m_layer->drawsContent() || m_size.isEmpty() ||!m_size.isValid()) return QPixmap(); QRegion region = regionToUpdate; @@ -321,6 +330,7 @@ QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate) // Render the actual contents into the cache painter.setCompositionMode(QPainter::CompositionMode_SourceOver); m_layer->paintGraphicsLayerContents(gc, region.boundingRect()); + painter.end(); m_backingStoreKey = QPixmapCache::insert(pixmap); return pixmap; @@ -515,6 +525,7 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform // we can't paint here, because we don't know if the mask layer // itself is ready... we'll have to wait till this layer tries to paint setFlag(ItemClipsChildrenToShape, m_layer->maskLayer() || m_layer->masksToBounds()); +#ifndef QT_NO_GRAPHICSEFFECT setGraphicsEffect(0); if (m_layer->maskLayer()) { if (GraphicsLayerQtImpl* mask = qobject_cast<GraphicsLayerQtImpl*>(m_layer->maskLayer()->platformLayer()->toGraphicsObject())) { @@ -522,6 +533,7 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform setGraphicsEffect(mask->m_maskEffect.data()); } } +#endif } if (m_changeMask & SizeChange) { @@ -596,11 +608,15 @@ void GraphicsLayerQtImpl::flushChanges(bool recursive, bool forceUpdateTransform if ((m_changeMask & ContentsOpaqueChange) && m_state.contentsOpaque != m_layer->contentsOpaque()) prepareGeometryChange(); +#ifndef QT_NO_GRAPHICSEFFECT if (m_maskEffect) m_maskEffect.data()->update(); - else if (m_changeMask & DisplayChange) { - // Recache now: all the content is ready and we don't want to wait until the paint event. We only need to do this for HTML content, - // there's no point in caching directly composited content like images or solid rectangles. + else +#endif + if (m_changeMask & DisplayChange) { + // Recache now: all the content is ready and we don't want to wait until the paint event. + // We only need to do this for HTML content, there's no point in caching directly composited + // content like images or solid rectangles. if (m_pendingContent.contentType == HTMLContentType) recache(m_pendingContent.regionToUpdate); update(m_pendingContent.regionToUpdate.boundingRect()); diff --git a/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h b/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h index 781259c..d1f2db4 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h +++ b/src/3rdparty/webkit/WebCore/platform/network/NetworkStateNotifier.h @@ -44,6 +44,15 @@ typedef const struct __SCDynamicStore * SCDynamicStoreRef; #include <windows.h> +#elif PLATFORM(QT) + +#include <QtCore/qglobal.h> + +#ifdef QT_NO_BEARERMANAGEMENT +#undef ENABLE_QT_BEARER +#define ENABLE_QT_BEARER 0 +#endif + #endif namespace WebCore { diff --git a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp index 52512aa..3aae92a 100644 --- a/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/network/qt/NetworkStateNotifierQt.cpp @@ -20,6 +20,8 @@ #include "config.h" #include "NetworkStateNotifier.h" +#if PLATFORM(QT) && ENABLE(QT_BEARER) + #include "NetworkStateNotifierPrivate.h" #include "qnetworkconfigmanager.h" @@ -89,4 +91,6 @@ void NetworkStateNotifier::setNetworkAccessAllowed(bool isAllowed) } // namespace WebCore +#endif + #include "moc_NetworkStateNotifierPrivate.cpp" diff --git a/src/3rdparty/webkit/WebCore/platform/qt/FileSystemQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/FileSystemQt.cpp index f9ced98..54ecbf1 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/FileSystemQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/FileSystemQt.cpp @@ -117,6 +117,7 @@ Vector<String> listDirectory(const String& path, const String& filter) CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle) { +#ifndef QT_NO_TEMPORARYFILE QTemporaryFile* tempFile = new QTemporaryFile(QLatin1String(prefix)); tempFile->setAutoRemove(false); QFile* temp = tempFile; @@ -124,6 +125,7 @@ CString openTemporaryFile(const char* prefix, PlatformFileHandle& handle) handle = temp; return String(temp->fileName()).utf8(); } +#endif handle = invalidPlatformFileHandle; return CString(); } diff --git a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp index 577903b..08b7aca 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/qt/RenderThemeQt.cpp @@ -163,7 +163,9 @@ RenderThemeQt::RenderThemeQt(Page* page) RenderThemeQt::~RenderThemeQt() { delete m_fallbackStyle; +#ifndef QT_NO_LINEEDIT delete m_lineEdit; +#endif } #if USE(QT_MOBILE_THEME) @@ -264,11 +266,17 @@ bool RenderThemeQt::supportsControlTints() const int RenderThemeQt::findFrameLineWidth(QStyle* style) const { +#ifndef QT_NO_LINEEDIT if (!m_lineEdit) m_lineEdit = new QLineEdit(); +#endif QStyleOptionFrameV2 opt; - return style->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, m_lineEdit); + QWidget* widget = 0; +#ifndef QT_NO_LINEEDIT + widget = m_lineEdit; +#endif + return style->pixelMetric(QStyle::PM_DefaultFrameWidth, &opt, widget); } static QRect inflateButtonRect(const QRect& originalRect, QStyle* style) diff --git a/src/3rdparty/webkit/WebCore/platform/text/qt/TextBreakIteratorQt.cpp b/src/3rdparty/webkit/WebCore/platform/text/qt/TextBreakIteratorQt.cpp index 5a8a812..dda443f 100644 --- a/src/3rdparty/webkit/WebCore/platform/text/qt/TextBreakIteratorQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/text/qt/TextBreakIteratorQt.cpp @@ -33,31 +33,49 @@ namespace WebCore { + static unsigned char buffer[1024]; + class TextBreakIterator : public QTextBoundaryFinder { + public: + TextBreakIterator(QTextBoundaryFinder::BoundaryType type, const UChar* string, int length) + : QTextBoundaryFinder(type, (const QChar*)string, length, buffer, sizeof(buffer)) + , length(length) + , string(string) {} + TextBreakIterator() + : QTextBoundaryFinder() + , length(0) + , string(0) {} + + int length; + const UChar* string; }; - static QTextBoundaryFinder* iterator = 0; - static unsigned char buffer[1024]; - TextBreakIterator* wordBreakIterator(const UChar* string, int length) + TextBreakIterator* setUpIterator(TextBreakIterator& iterator, QTextBoundaryFinder::BoundaryType type, const UChar* string, int length) { if (!string || !length) return 0; - if (!iterator) - iterator = new QTextBoundaryFinder; - *iterator = QTextBoundaryFinder(QTextBoundaryFinder::Word, (const QChar *)string, length, buffer, sizeof(buffer)); - return static_cast<TextBreakIterator*>(iterator); + if (iterator.isValid() && type == iterator.type() && length == iterator.length + && memcmp(string, iterator.string, length) == 0) { + iterator.toStart(); + return &iterator; + } + + iterator = TextBreakIterator(type, string, length); + + return &iterator; } - TextBreakIterator* characterBreakIterator(const UChar* string, int length) + TextBreakIterator* wordBreakIterator(const UChar* string, int length) { - if (!string || !length) - return 0; - if (!iterator) - iterator = new QTextBoundaryFinder; + static TextBreakIterator staticWordBreakIterator; + return setUpIterator(staticWordBreakIterator, QTextBoundaryFinder::Word, string, length); + } - *iterator = QTextBoundaryFinder(QTextBoundaryFinder::Grapheme, (const QChar *)string, length, buffer, sizeof(buffer)); - return static_cast<TextBreakIterator*>(iterator); + TextBreakIterator* characterBreakIterator(const UChar* string, int length) + { + static TextBreakIterator staticCharacterBreakIterator; + return setUpIterator(staticCharacterBreakIterator, QTextBoundaryFinder::Grapheme, string, length); } TextBreakIterator* cursorMovementIterator(const UChar* string, int length) @@ -67,25 +85,15 @@ namespace WebCore { TextBreakIterator* lineBreakIterator(const UChar* string, int length) { - static QTextBoundaryFinder *iterator = 0; - if (!string || !length) - return 0; - if (!iterator) - iterator = new QTextBoundaryFinder; - - *iterator = QTextBoundaryFinder(QTextBoundaryFinder::Line, (const QChar *)string, length, buffer, sizeof(buffer)); - return static_cast<TextBreakIterator*>(iterator); + static TextBreakIterator staticLineBreakIterator; + return setUpIterator(staticLineBreakIterator, QTextBoundaryFinder::Line, string, length); } TextBreakIterator* sentenceBreakIterator(const UChar* string, int length) { - if (!string || !length) - return 0; - if (!iterator) - iterator = new QTextBoundaryFinder; + static TextBreakIterator staticSentenceBreakIterator; + return setUpIterator(staticSentenceBreakIterator, QTextBoundaryFinder::Sentence, string, length); - *iterator = QTextBoundaryFinder(QTextBoundaryFinder::Sentence, (const QChar *)string, length, buffer, sizeof(buffer)); - return static_cast<TextBreakIterator*>(iterator); } int textBreakFirst(TextBreakIterator* bi) diff --git a/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp b/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.mm index 1fd4676..57d74ab 100644 --- a/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.cpp +++ b/src/3rdparty/webkit/WebCore/plugins/mac/PluginViewMac.mm @@ -103,9 +103,12 @@ static inline WindowRef nativeWindowFor(PlatformWidget widget) { #if PLATFORM(QT) if (widget) +#if QT_MAC_USE_COCOA + return static_cast<WindowRef>([qt_mac_window_for(widget) windowRef]); +#else return static_cast<WindowRef>(qt_mac_window_for(widget)); #endif -#if PLATFORM(WX) +#elif PLATFORM(WX) if (widget) return (WindowRef)widget->MacGetTopLevelWindowRef(); #endif diff --git a/src/3rdparty/webkit/WebKit/qt/Api/DerivedSources.pro b/src/3rdparty/webkit/WebKit/qt/Api/DerivedSources.pro index 389fb5f..22d4c8d 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/DerivedSources.pro +++ b/src/3rdparty/webkit/WebKit/qt/Api/DerivedSources.pro @@ -28,7 +28,7 @@ qtheader_module.commands += echo $${QUOTE}$${LITERAL_HASH}define QT_QTWEBKIT_MOD qtheader_module.commands += echo $${QUOTE}$${LITERAL_HASH}include $${ESCAPE}<QtNetwork/QtNetwork$${ESCAPE}>$${QUOTE} >> $${qtheader_module.target} && WEBKIT_CLASS_HEADERS = $${LITERAL_DOLLAR}$${LITERAL_DOLLAR}$${LITERAL_DOLLAR}$${LITERAL_DOLLAR}PWD/QtWebKit -regex = ".*\sclass\sQWEBKIT_EXPORT\s(\w+)\s(.*)" +regex = ".*\\sclass\\sQWEBKIT_EXPORT\\s(\\w+)\\s(.*)" for(HEADER, WEBKIT_API_HEADERS) { # 1. Append to QtWebKit header that includes all other header files @@ -70,7 +70,7 @@ for(HEADER, WEBKIT_API_HEADERS) { res = $$find(src, $$regex) isEmpty(res):break() - exp = $$replace(src, $$regex, "EXPORTED_CLASS = \1") + exp = $$replace(src, $$regex, "EXPORTED_CLASS = \\1") eval($$exp) CLASS_TARGET = "qtheader_$${EXPORTED_CLASS}" @@ -87,7 +87,7 @@ for(HEADER, WEBKIT_API_HEADERS) { # Qt's QRegExp does not support inline non-greedy matching, # so we'll have to work around it by updating the haystack - src = $$replace(src, $$regex, "\2") + src = $$replace(src, $$regex, "\\2") src_words = $$join(src, $${LITERAL_WHITESPACE}) } } diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index a61ca2e..8c7b93d 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -1175,7 +1175,7 @@ void QWebPagePrivate::dragEnterEvent(QGraphicsSceneDragDropEvent* ev) Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData)); ev->setDropAction(action); if (action != Qt::IgnoreAction) - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1188,7 +1188,7 @@ void QWebPagePrivate::dragEnterEvent(QDragEnterEvent* ev) ev->setDropAction(action); // We must accept this event in order to receive the drag move events that are sent // while the drag and drop action is in progress. - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1218,7 +1218,7 @@ void QWebPagePrivate::dragMoveEvent(QGraphicsSceneDragDropEvent* ev) Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData)); ev->setDropAction(action); if (action != Qt::IgnoreAction) - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1232,7 +1232,7 @@ void QWebPagePrivate::dragMoveEvent(QDragMoveEvent* ev) ev->setDropAction(action); // We must accept this event in order to receive the drag move events that are sent // while the drag and drop action is in progress. - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1242,7 +1242,7 @@ void QWebPagePrivate::dropEvent(QGraphicsSceneDragDropEvent* ev) DragData dragData(ev->mimeData(), ev->pos().toPoint(), QCursor::pos(), dropActionToDragOp(ev->possibleActions())); if (page->dragController()->performDrag(&dragData)) - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1254,7 +1254,7 @@ void QWebPagePrivate::dropEvent(QDropEvent* ev) DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), dropActionToDragOp(Qt::DropAction(ev->dropAction()))); if (page->dragController()->performDrag(&dragData)) - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1370,6 +1370,7 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev) ev->accept(); } +#ifndef QT_NO_PROPERTIES void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* event) { if (event->propertyName() == "_q_viewMode") { @@ -1424,6 +1425,7 @@ void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* ev } #endif } +#endif void QWebPagePrivate::shortcutOverrideEvent(QKeyEvent* event) { @@ -2808,9 +2810,11 @@ bool QWebPage::event(QEvent *ev) d->touchEvent(static_cast<QTouchEvent*>(ev)); break; #endif +#ifndef QT_NO_PROPERTIES case QEvent::DynamicPropertyChange: d->dynamicPropertyChangeEvent(static_cast<QDynamicPropertyChangeEvent*>(ev)); break; +#endif default: return QObject::event(ev); } @@ -3263,6 +3267,14 @@ bool QWebPage::findText(const QString &subString, FindFlags options) } else return d->page->markAllMatchesForText(subString, caseSensitivity, true, 0); } else { + if (subString.isEmpty()) { + d->page->mainFrame()->selection()->clear(); + Frame* frame = d->page->mainFrame()->tree()->firstChild(); + while (frame) { + frame->selection()->clear(); + frame = frame->tree()->traverseNextWithWrap(false); + } + } ::FindDirection direction = ::FindDirectionForward; if (options & FindBackward) direction = ::FindDirectionBackward; @@ -3620,7 +3632,7 @@ QString QWebPage::userAgentForUrl(const QUrl&) const languageName = d->client->ownerWidget()->locale().name(); else languageName = QLocale().name(); - languageName[2] = QLatin1Char('-'); + languageName.replace(QLatin1Char('_'), QLatin1Char('-')); // Application name/version QString appName = QCoreApplication::applicationName(); diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h index 5350cd9..1b90a66 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage_p.h @@ -112,7 +112,9 @@ public: void inputMethodEvent(QInputMethodEvent*); +#ifndef QT_NO_PROPERTIES void dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent*); +#endif void shortcutOverrideEvent(QKeyEvent*); void leaveEvent(QEvent*); diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpluginfactory.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpluginfactory.cpp index f715430..b9180be 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpluginfactory.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpluginfactory.cpp @@ -63,7 +63,7 @@ /*! \class QWebPluginFactory::Plugin \since 4.4 - \brief the QWebPluginFactory::Plugin structure describes the properties of a plugin a QWebPluginFactory can create. + \brief The QWebPluginFactory::Plugin structure describes the properties of a plugin a QWebPluginFactory can create. \inmodule QtWebKit */ @@ -147,7 +147,7 @@ QWebPluginFactory::~QWebPluginFactory() supported plugins the factory can create. \note Currently, this function is only called when JavaScript programs - access the global \c plugins or \c mimetypes objects. + access the global \c plugins or \c mimetypes objects. */ /*! diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp index 81823f6..a5fc794 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp @@ -48,9 +48,7 @@ #include <QUrl> #include <QFileInfo> -#if ENABLE(QT_BEARER) #include "NetworkStateNotifier.h" -#endif void QWEBKIT_EXPORT qt_networkAccessAllowed(bool isAllowed) { diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index cc2d39a..671acec 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,140 @@ +2010-06-09 Pierre Rossi <pierre.rossi@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + QWebPage::findText() does not clear selection when passed empty string + https://bugs.webkit.org/show_bug.cgi?id=31779 + + * Api/qwebpage.cpp: + (QWebPage::findText): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::findText): + +2010-06-12 No'am Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Add documentation to the QtWebkit bridge + https://bugs.webkit.org/show_bug.cgi?id=35861 + + The previous accepted patch was actually a faulty one; It was hard to trace since it's just a documentation + change. The new patch amends that, with the correct snippets and grammar fixes. + + * docs/qtwebkit-bridge.qdoc: + * docs/webkitsnippets/qtwebkit_bridge_snippets.cpp: + (wrapInFunction): + +2010-06-11 Jesus Sanchez-Palencia <jesus@webkit.org> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Typo error in QWebPluginFactory Documentation + https://bugs.webkit.org/show_bug.cgi?id=40490 + + * Api/qwebpluginfactory.cpp: + +2010-06-10 Andy Shaw <andy.shaw@nokia.com> + + Reviewed by Simon Hausmann. + + REGRESSION: [Qt] When dragging onto a page that handles the drag in Javascript it will be a move and not a copy by default + https://bugs.webkit.org/show_bug.cgi?id=40401 + + The correct pattern in Qt for Dnd events is to use acceptProposedAction() instead + of accept(). + + * Api/qwebpage.cpp: + (QWebPagePrivate::dragEnterEvent): + (QWebPagePrivate::dragMoveEvent): + (QWebPagePrivate::dropEvent): + +2010-06-02 Tasuku Suzuki <tasuku.suzuki@nokia.com> + + Reviewed by Shinichiro Hamaji. + + [Qt] Fix compilation with QT_NO_PROPERTIES + https://bugs.webkit.org/show_bug.cgi?id=38324 + + * Api/qwebpage.cpp: + (QWebPage::event): + * Api/qwebpage_p.h: + * WebCoreSupport/InspectorClientQt.cpp: + (WebCore::InspectorClientQt::openInspectorFrontend): + +2010-05-17 Tasuku Suzuki <tasuku.suzuki@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Fix compilation with QT_NO_COMBOBOX + https://bugs.webkit.org/show_bug.cgi?id=38324 + + * WebCoreSupport/ChromeClientQt.cpp: + (WebCore::ChromeClientQt::createSelectPopup): + * WebCoreSupport/QtFallbackWebPopup.cpp: + * WebCoreSupport/QtFallbackWebPopup.h: + +2010-05-02 Tasuku Suzuki <tasuku.suzuki@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Fix compilation with QT_NO_BEARERMANAGEMENT + https://bugs.webkit.org/show_bug.cgi?id=38324 + + * Api/qwebsettings.cpp: + +2010-03-24 Viatcheslav Ostapenko <ostapenko.viatcheslav@nokia.com> + + Reviewed by Laszlo Gombos. + + Auto-uppercase and predictive text need to be disabled for S60 (as for maemo) + https://bugs.webkit.org/show_bug.cgi?id=33176 + + * WebCoreSupport/EditorClientQt.cpp: + +2010-06-01 Noam Rosenthal <noam.rosenthal@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Add documentation to the QtWebkit bridge + https://bugs.webkit.org/show_bug.cgi?id=35861 + + This patch includes comprehensive qdoc documentation for the QtWebkit bridge. + + * docs/qtwebkit-bridge.qdoc: Added. + * docs/qtwebkit.qdoc: + * docs/webkitsnippets/doc_src_qtscript.qdoc: Added. + * docs/webkitsnippets/qtwebkit_bridge_snippets.cpp: Added. + (wrapInFunction): + +2010-06-01 Simon Hausmann <simon.hausmann@nokia.com> + + Reviewed by Laszlo Gombos. + + [Qt] Rename versioning .pri file to what Qt's mkspecs/features/qt.pri expects. + + * qt_webkit_version.pri: Renamed from WebKit/qt/qtwebkit_version.pri. + +2010-05-31 Oswald Buddenhagen <oswald.buddenhagen@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Escape backslashes in the .pro files + + qmake in Qt 4.7 warns about unescaped backspaces and deprecates them. + + * Api/DerivedSources.pro: + * docs/docs.pri: + +2010-05-19 Denis Dzyubenko <denis.dzyubenko@nokia.com> + + Reviewed by Kenneth Rohde Christiansen. + + When creating the UA, do not sassmue the language code is a + two-letter iso639-1 code. + + * Api/qwebpage.cpp: + (QWebPage::userAgentForUrl): + 2010-05-28 Antti Koivisto <koivisto@iki.fi> 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 4e742fc..7d1c794 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/ChromeClientQt.cpp @@ -573,8 +573,10 @@ QtAbstractWebPopup* ChromeClientQt::createSelectPopup() { #if defined(Q_WS_MAEMO_5) return new QtMaemoWebPopup; -#else +#elif !defined(QT_NO_COMBOBOX) return new QtFallbackWebPopup; +#else + return result; #endif } diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp index 7b7f610..0ce6383 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp @@ -613,11 +613,11 @@ void EditorClientQt::setInputMethodState(bool active) } } webPageClient->setInputMethodHint(Qt::ImhHiddenText, isPasswordField); -#ifdef Q_WS_MAEMO_5 - // Maemo 5 MicroB Browser disables auto-uppercase and predictive text, thus, so do we. +#if defined(Q_WS_MAEMO_5) || defined(Q_OS_SYMBIAN) + // disables auto-uppercase and predictive text for mobile devices webPageClient->setInputMethodHint(Qt::ImhNoAutoUppercase, true); webPageClient->setInputMethodHint(Qt::ImhNoPredictiveText, true); -#endif // Q_WS_MAEMO_5 +#endif // Q_WS_MAEMO_5 || Q_OS_SYMBIAN #endif // QT_VERSION check webPageClient->setInputMethodEnabled(active); } diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp index 725c5fb..2d11700 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/InspectorClientQt.cpp @@ -93,7 +93,10 @@ void InspectorClientQt::openInspectorFrontend(WebCore::InspectorController*) // Web inspector. This is used for SDK purposes. Please keep this hook // around and don't remove it. // https://bugs.webkit.org/show_bug.cgi?id=35340 - QUrl inspectorUrl = inspector->property("_q_inspectorUrl").toUrl(); + QUrl inspectorUrl; +#ifndef QT_NO_PROPERTIES + inspectorUrl = inspector->property("_q_inspectorUrl").toUrl(); +#endif if (!inspectorUrl.isValid()) inspectorUrl = QUrl("qrc:/webkit/inspector/inspector.html"); inspectorView->page()->mainFrame()->load(inspectorUrl); diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.cpp index 7514077..26420e5 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.cpp @@ -21,6 +21,8 @@ #include "config.h" #include "QtFallbackWebPopup.h" +#ifndef QT_NO_COMBOBOX + #include "HostWindow.h" #include "PopupMenuClient.h" #include "QWebPageClient.h" @@ -225,3 +227,5 @@ void QtFallbackWebPopup::activeChanged(int index) } } + +#endif // QT_NO_COMBOBOX diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.h b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.h index 62b8aea..6d2e1ff 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.h +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/QtFallbackWebPopup.h @@ -23,6 +23,8 @@ #include "QtAbstractWebPopup.h" #include <QComboBox> +#ifndef QT_NO_COMBOBOX + QT_BEGIN_NAMESPACE class QGraphicsProxyWidget; QT_END_NAMESPACE @@ -67,4 +69,6 @@ private: } +#endif // QT_NO_COMBOBOX + #endif // QtFallbackWebPopup_h diff --git a/src/3rdparty/webkit/WebKit/qt/docs/docs.pri b/src/3rdparty/webkit/WebKit/qt/docs/docs.pri index 804817b..a56ddb4 100644 --- a/src/3rdparty/webkit/WebKit/qt/docs/docs.pri +++ b/src/3rdparty/webkit/WebKit/qt/docs/docs.pri @@ -3,7 +3,7 @@ include(../../../WebKit.pri) unix { QDOC = SRCDIR=$$PWD/../../.. OUTPUT_DIR=$$OUTPUT_DIR $$(QTDIR)/bin/qdoc3 } else { - QDOC = $$(QTDIR)\bin\qdoc3.exe + QDOC = $$(QTDIR)\\bin\\qdoc3.exe } unix { diff --git a/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit-bridge.qdoc b/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit-bridge.qdoc new file mode 100644 index 0000000..fa93293 --- /dev/null +++ b/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit-bridge.qdoc @@ -0,0 +1,427 @@ +/*! + \inmodule QtWebKit + \page qtwebkit-bridge.html + \title The QtWebKit Bridge + \contentspage QtWebKit + \section1 Overview + \section2 The technology + + The QtWebKit bridge is a mechanism that extends WebKit's JavaScript environment to access native + objects that are represented as \l{QObject}s. It takes advantage of the \l{QObject} introspection, + a part of the \l{Qt Object Model}, which makes it easy to integrate with the dynamic JavaScript environment, + for example \l{QObject} properties map directly to JavaScript properties. + + For example, both JavaScript and QObjects have properties: a construct that represent a getter/setter + pair under one name. + + \section2 Use Cases + + There are two main use cases for the QtWebKit bridge. Web content in a native application, and Thin Clients. + + \section3 Web Content in a Native Application + + This is a common use case in classic Qt application, and a design pattern used by several modern + applications. For example, an application that contains a media-player, playlist manager, and music store. + The playlist manager is usually best authored as a classic desktop application, + with the native-looking robust \l{QWidget}s helping with producing that application. + The media-player control, which usually looks custom, can be written using \l{The Graphics View framework} + or with in a declarative way with \l{QtDeclarative}. The music store, which shows dynamic content + from the internet and gets modified rapidly, is best authored in HTML and maintained on the server. + + With the QtWebKit bridge, that music store component can interact with native parts of the application, + for example, if a file needs to be saved to a specific location. + + \section3 Thin Client + + Another use case is using Qt as a native backend to a full web application, + referred to here as a thin client. In this use-case, the entire UI is driven by + HTML, JavaScript and CSS, and native Qt-based components are used to allow that application + access to native features not usually exposed to the web, or to enable helper components that + are best written with C++. + + An example for such a client is a UI for a video-on-demand service on a TV. The entire content and + UI can be kept on the server, served dynamically through HTTP and rendered with WebKit, with additional + native components for accessing hardware-specific features like extracting the list of images + out of the video. + + \section2 Difference from Other Bridge Technologies + + Of course QtWebKit is not the only bridge technology out there. NPAPI, for example, + is a long-time standard or web-native bridging. Due to Qt's meta-object system, full applications + built partially with web-technologies are much easier to develop. NPAPI, however, is more geared + towards cross-browser plugins, due to it being an accepted standard. + + When developing a plugin for a browser, NPAPI is recommended. When developing a full application + that utilizes HTML-rendering, the QtWebKit bridge is recommended. + + \section2 Relationship with QtScript + + The QtWebKit bridge is similar to \l{QtScript}, especially to some of the features described in the + \l{Making Applications Scriptable} page. However, as of Qt 4.7, full QtScript API is not supported for web applications. + That is planned as an enhancement for future versions. You might notice that some of the features + described here are an exact copy of the ones described in the \l{Making Applications Scriptable} page. That is because + the QtWebKit bridge is a subset of that functionality, and this page tries to capture the full + capabilities available through the QtWebKit bridge specifically. + + \section1 Accessing QObjects + + \section2 Creating the link via QWebFrame + + By default, no QObjects are accessible through the web environment, for security reasons. + To enable web content access for a native QObject, the application must explicitly grant it access, + using the following call: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 0 + + See \l{QWebFrame::addToJavaScriptWindowObject()} for more information. + + \section2 Using Signals and Slots + + The QtWebKit bridge adapts Qt's central \l{Signals and Slots} feature for + scripting. There are three principal ways to use signals and slots + with the QtWebKit bridge: + + \list + \i \bold{Hybrid C++/script}: C++ application code connects a + signal to a script function. For example, the script function can be + a function that the user has typed in, or one that you have read from a + file. This approach is useful if you have a QObject but don't want + to expose the object itself to the scripting environment; you just + want a script to be able to define how a signal should be reacted + to, and leave it up to the C++ side of your application to establish + the connection. + + \i \bold{Hybrid script/C++}: A script can connect signals and slots + to establish connections between pre-defined objects that the + application exposes to the scripting environment. In this scenario, + the slots themselves are still written in C++, but the definition of + the connections is fully dynamic (script-defined). + + \i \bold{Purely script-defined}: A script can both define signal + handler functions (effectively "slots written in JavaScript"), + \e{and} set up the connections that utilize those handlers. For + example, a script can define a function that will handle the + QLineEdit::returnPressed() signal, and then connect that signal to the + script function. + \endlist + + Note that QtScript functions such as qScriptConnect are unavilable in the web environment. + + \section3 Signal to Function Connections + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 6 + + In this form of connection, the argument to \c{connect()} is the + function to connect to the signal. + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 7 + + The argument can be a JavaScript function, as in the above + example, or it can be a QObject slot, as in + the following example: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 8 + + When the argument is a QObject slot, the argument types of the + signal and slot do not necessarily have to be compatible; + If necessary, the QtWebKit bridge will, perform conversion of the signal + arguments to match the argument types of the slot. + + To disconnect from a signal, you invoke the signal's + \c{disconnect()} function, passing the function to disconnect + as argument: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 9 + + When a script function is invoked in response to a signal, the + \c this object will be the Global Object. + + \section3 Signal to Member Function Connections + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 10 + + In this form of the \c{connect()} function, the first argument + is the object that will be bound to the variable, \c this, when + the function specified using the second argument is invoked. + + If you have a push button in a form, you typically want to do + something involving the form in response to the button's + \c{clicked} signal; passing the form as the \c this object + makes sense in such a case. + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 11 + + To disconnect from the signal, pass the same arguments to \c{disconnect()}: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 12 + + \section3 Signal to Named Member Function Connections + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 14 + + This form of the \c{connect()} function requires that the first argument is + the object that will be bound to the variable \c{this} when a function is + invoked in response to the signal. The second argument specifies the + name of a function that is connected to the signal, and this refers to a + member function of the object passed as the first argument (thisObject + in the above scheme). + + Note that the function is resolved when the connection is made, not + when the signal is emitted. + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 15 + + To disconnect from the signal, pass the same arguments to \c{disconnect()}: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 17 + + \section3 Error Handling + + When \c{connect()} or \c{disconnect()} succeeds, the function will + return \c{undefined}; otherwise, it will throw a script exception. + You can obtain an error message from the resulting \c{Error} object. + Example: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 18 + + \section3 Emitting Signals from Scripts + + To emit a signal from script code, you simply invoke the signal + function, passing the relevant arguments: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 19 + + It is currently not possible to define a new signal in a script; + i.e., all signals must be defined by C++ classes. + + \section3 Overloaded Signals and Slots + + When a signal or slot is overloaded, the QtWebKit bridge will attempt to + pick the right overload based on the actual types of the QScriptValue arguments + involved in the function invocation. For example, if your class has slots + \c{myOverloadedSlot(int)} and \c{myOverloadedSlot(QString)}, the following + script code will behave reasonably: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 20 + + You can specify a particular overload by using array-style property access + with the \l{QMetaObject::normalizedSignature()}{normalized signature} of + the C++ function as the property name: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 21 + + If the overloads have different number of arguments, the QtWebKit bridge will + pick the overload with the argument count that best matches the + actual number of arguments passed to the slot. + + For overloaded signals, JavaScript will throw an error if you try to connect + to the signal by name; you have to refer to the signal with the full + normalized signature of the particular overload you want to connect to. + + \section3 Invokable Methods + + Both slots and signals are invokable from script by default. In addition, it's also + possible to define a method that's invokable from script without it being a signal or a slot. + This is especially useful for functions with return types, as slots normally do not return anything + (it would be meaningless to return values from a slot, as the connected signals don't handle the returned data). + To make a non-slot method invokable, simply add the Q_INVOKABLE macro before its definition: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 22 + + \section2 Accessing Properties + + The properties of the QObject are available as properties + of the corresponding JavaScript object. When you manipulate + a property in script code, the C++ get/set method for that + property will automatically be invoked. For example, if your + C++ class has a property declared as follows: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 23 + + then script code can do things like the following: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 24 + + \section2 Accessing Child QObjects + + Every named child of the QObject (that is, for which + QObject::objectName() is not an empty string) is by default available as + a property of the JavaScript wrapper object. For example, + if you have a QDialog with a child widget whose \c{objectName} property is + \c{"okButton"}, you can access this object in script code through + the expression + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 25 + + Since \c{objectName} is itself a Q_PROPERTY, you can manipulate + the name in script code to, for example, rename an object: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 26 + + \section2 Data types + + When calling slots, receiving signals or accessing properties, usually some payload is involved. + For example, a property "text" might return a \l{QString} parameter. + The QtWebKit bridge does the job of converting between a given JavaScript data-type, and the + expected or given Qt type. Each Qt type has a coresponding set of rules of how JavaScript treats it. + + The data type conversions are also applicable for the data returned from non-void invokable methods. + + \section3 Numbers + + All Qt numeric data types are converted to or from a JavaScript number. These include int, short, float, + double, and the porable Qt types (qreal, qint etc). A special case is \l{QChar}; + If a slot expects a QChar, the QtWebKit bridge would use the unicode value in case of a number, + or the first character in a string. + + Note that non-standard (typedefed) number types are not automatically converted to + or from a JavaScript number - it's advised to use standard number types for signal, slots + and properties. + + When a non-number is passed as an argument to a method or property that expects a number, + the appropriate JavaScript conversion function (parseInt / parseFloat) would be used. + + \section3 Strings + + When JavaScript accesses methods or properties that expect a \l{QString}, the QtWebKit bridge + will automatically convert the value to a string (if it is not already a string), using the + built-in JavaScript toString method. + + When a QString is passed to JavaScript from a signal or a property, The QtWebKit bridge will + convert it into a JavaScript string. + + \section3 Date & Time + + Both \l{QDate}, \l{QTime} and \l{QDateTime} are automatically translated to or from the JavaScript + Date object. If a number were passed as an argument to a method that expects one of the date/time + types, the QtWebKit bridge would treat it as a timestamp. If a sting is passed, QtWebKit would + try different Qt date parsing functions to find the right one. + + \section3 Regular Expressions + + The QtWebKit bridge would automatically convert JavaScript RegEx object to a \l{QRegExp}. + If a string is passed to a method expecting a \l{QRegExp}, the string would be converted + to that \l{QRegExp}. + + \section3 Lists + + The QtWebKit bridge treats several types of lists in a special way: \l{QVariantList}, \l{QStringList}, + \l{QObjectList} and \l{QList}<int>. When a slot or property expects one of those list types, + the QtWebKit bridge would try to convert a JavaScript array into that type, converting each of + the array's elements to the single-element type of the list. + + The most useful type of list is perhaps \l{QVariantList}, which can be converted to from any + JavaScript array. + + \section3 Compound (JSON) objects + + JavaScript compound objects, also known as JSON objects, are variables that hold a list + of key-value pairs, where all the keys are strings and the values can have any type. + This translates very well to \l{QVariantMap}, which is nothing more than a \l{QMap} of \l{QString} + to \l{QVariant}. + + The seamless conversion between JSON objects and \l{QVariantMap} allows for a very convenient + way of passing arbitrary structured data between C++ and the JavaScript environment. The native \l{QObject} has + to make sure that compound values are converted to \l{QVariantMap}s and \l{QVariantList}s, and JavaScript is + guaranteed to receive them in a meaningful way. + + Note that types that are not supported by JSON, such as JavaScript functions and getters/setters, + are not converted. + + \section3 QVariants + + When a slot or property accepts a \l{QVariant}, the QtWebKit bridge would create a \l{QVariant} that best + matches the argument passed by JavaScript. A string, for example, would become a \l{QVariant} holding a \l{QString}, + a normal JSON object would become a \l{QVariantMap}, and a JavaScript array would become a \l{QVariantList}. + + Using \l{QVariant}s generously in C++ in that way makes C++ programming feel a bit more like JavaScript programming, + as it adds another level of indirection. Passing \l{QVariant}s around like this q is very flexible, as the program can figure out + the type of argument in runtime just like JavaScript would do, but it also takes away from the type-safety and robust + nature of C++. It's recommended to use \l{QVariant}s only for convenience high-level functions, and to keep most of your + \l{QObject}s somewhat type-safe. + + \section3 QObjects + + A pointer to a \l{QObject} or a \l{QWidget} can be passed as payload in signals, slots and properties. That object + can then be used like an object that's exposed directly; i.e. its slots can be invoked, its signals connected to etc. + However, this functionality is fairly limited - the type used has to be \l{QObject}* or \l{QWidget}*. If the type + specified is a pointer to a non-\l{QWidget} subclass of \l{QObject}, the QtWebKit bridge would not recognize it to be + a \l{QObject}. + + In general its advised to use care when passing \l{QObject}s as arguments, as those objects don't become owned by + the JavaScript engine; That means that the application developer has to be extra careful not to try to access + \l{QObject}s that have already been deleted by the native environment. + + \section3 Pixmaps and Images + + \since 4.7 + + The QtWebKit bridge handles \l{QPixmap}s and \l{QImage}s in a special way. Since QtWebKit stores \l{QPixmap}s to + represent HTML images, \l{QPixmap}s coming from the native environment can be used directly inside WebKit. + A \l{QImage} or a \l{QPixmap} coming from the Qt environment would convert to an intermediate JavaScript object, + that can be represented like this: + + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 1 + + The JavaScript environment can then use the pixmap it gets from Qt and display it inside the HTML environment, + by assigning it to an existing <img /> element using assignToHTMLImageElement. It can also use the toDataURL() function, + which allows using the pixmap as the src attribute of an image or as a background-image url. Note that the toDataURL() + function is costly and should be used with caution. + + Example code: + + C++: + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 2 + + HTML: + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 3 + + When a Qt object expects a \l{QImage} or a \l{QPixmap} as input, and the argument passed is an HTML image element, + the QtWebKit bridge would convert the pixmap assigned to that image element into a \l{QPixmap} or a \l{QImage}. + + \since 4.7 + + \section3 QWebElement + + A signal, slot or property that expects or returns a \l{QWebElement} can work seamlessly with JavaScript references + to DOM elements. The JavaScript environment can select DOM elements, keep them in variables, then pass them to Qt as + a \l{QWebElement}, and receive them back. Example: + + C++: + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 4 + + HTML: + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 5 + + This is specifically useful to create custom renderers or extensions to the web environment. Instead of forcing Qt + to select the element, the web environment already selects the element and then send the selected element directly to Qt. + + Note that \l{QWebElement}s are not thread safe - an object handling them has to live in the UI thread. + + \section1 Architecture issues + + \section2 Limiting the Scope of the Hybrid Layer + + When using QtWebKit's hybrid features, it is a common pitfall to make the API exposed to JavaScript very rich and + use all its features. This, however, leads to complexity and can create bugs that are hard to trace. + Instead, it is advisable to keep the hybrid layer small and manageable: create a gate only when + there's an actual need for it, i.e. there's a new native enabler that requires a direct interface + to the application layer. Sometimes new functionality is better handled internally in the native layer + or in the web layer; simplicity is your friend. + + This usually becomes more apparent when the hybrid layer can create or destroy objects, or uses + signals slots or properties with a \l{QObject}* argument. It is advised to be very careful and to treat + an exposed \l{QObject} as a system - with careful attention to memory management and object ownership. + + \section2 Internet Security + + When exposing native object to an open web environment, it is importwhichant to understand the security + implications. Think whether the exposed object enables the web environment access to things that + shouldn't be open, and whether the web content loaded by that web page comes from a trusted. In general, when + exposing native QObjects that give the web environment access to private information or to functionality + that's potentially harmful to the client, such exposure should be balanced by limiting the web page's + access to trusted URLs only with HTTPS, and by utilizing other measures as part of a security strategy. + + + +*/ diff --git a/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc b/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc index c6dd550..d3f5502 100644 --- a/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc +++ b/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit.qdoc @@ -20,8 +20,9 @@ scripted with JavaScript. A bridge between the JavaScript execution environment and the Qt object - model makes it possible for custom QObjects to be scripted. Integration - with the Qt networking module enables Web pages to be transparently loaded + model makes it possible for custom QObjects to be scripted. For detailed + documentation see \l{The QtWebkit Bridge}. + Integration with the Qt networking module enables Web pages to be transparently loaded from Web servers, the local file system or even the Qt resource system. In addition to providing pure rendering features, HTML documents can be diff --git a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/qtwebkit_bridge_snippets.cpp b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/qtwebkit_bridge_snippets.cpp new file mode 100644 index 0000000..62eeeca --- /dev/null +++ b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/qtwebkit_bridge_snippets.cpp @@ -0,0 +1,177 @@ + +void wrapInFunction() +{ + + //! [0] + // ... + QWebFrame *frame = myWebPage->mainFrame(); + frame->addToJavaScriptWindowObject("someNameForMyObject", myObject); + // ... + //! [0] +#if 0 + //! [1] + { + width: ..., + height: ..., + toDataURL: function() { ... }, + assignToHTMLImageElement: function(element) { ... } + } + //! [1] +#endif + //! [2] + class MyObject : QObject { + Q_OBJECT + Q_PROPERTY(QPixmap myPixmap READ getPixmap) + + public: + QPixmap getPixmap() const; + }; + + /* ... */ + + MyObject myObject; + myWebPage.mainFrame()->addToJavaScriptWindowObject("myObject", &myObject); + + //! [2] +#if 0 + //! [3] + <html> + <head> + <script> + function loadImage() { + myObject.myPixmap.assignToHTMLImageElement(document.getElementById("imageElement")); + } + </script> + </head> + <body onload="loadImage()"> + <img id="imageElement" width="300" height="200" /> + </body> + </html> + //! [3] +#endif + //! [4] + class MyObject : QObject { + Q_OBJECT + + public slots: + void doSomethingWithWebElement(const QWebElement&); + }; + + /* ... */ + + MyObject myObject; + myWebPage.mainFrame()->addToJavaScriptWindowObject("myObject", &myObject); + + //! [4] +#if 0 + //! [5] + <html> + <head> + <script> + function runExample() { + myObject.doSomethingWithWebElement(document.getElementById("someElement")); + } + </script> + </head> + <body onload="runExample()"> + <span id="someElement">Text</span> + </body> + </html> + //! [5] + //! [6] + connect(function); + //! [6] + //! [7] + function myInterestingScriptFunction() { ... } + ... + myQObject.somethingChanged.connect(myInterestingScriptFunction); + //! [7] + //! [8] + myQObject.somethingChanged.connect(myOtherQObject.doSomething); + //! [8] + //! [9] + myQObject.somethingChanged.disconnect(myInterestingFunction); + myQObject.somethingChanged.disconnect(myOtherQObject.doSomething); + //! [9] + //! [10] + connect(thisObject, function) + //! [10] + //! [11] + var obj = { x: 123 }; + var fun = function() { print(this.x); }; + myQObject.somethingChanged.connect(obj, fun); + //! [11] + //! [12] + myQObject.somethingChanged.disconnect(obj, fun); + //! [12] + //! [13] + connect(function); + //! [13] + //! [14] + connect(thisObject, functionName) + //! [14] + //! [15] + var obj = { x: 123, fun: function() { print(this.x); } }; + myQObject.somethingChanged.connect(obj, "fun"); + //! [15] + //! [16] + connect(function); + //! [16] + //! [17] + myQObject.somethingChanged.disconnect(obj, "fun"); + //! [17] + //! [18] + try { + myQObject.somethingChanged.connect(myQObject, "slotThatDoesntExist"); + } catch (e) { + print(e); + } + //! [18] + //! [19] + myQObject.somethingChanged("hello"); + //! [19] + //! [20] + myQObject.myOverloadedSlot(10); // will call the int overload + myQObject.myOverloadedSlot("10"); // will call the QString overload + //! [20] + //! [21] + myQObject['myOverloadedSlot(int)']("10"); // call int overload; the argument is converted to an int + myQObject['myOverloadedSlot(QString)'](10); // call QString overload; the argument is converted to a string + //! [21] + //! [22] + class MyObject : public QObject + { + Q_OBJECT + + public: + Q_INVOKABLE void thisMethodIsInvokableInQtScript(); + void thisMethodIsNotInvokableInQtScript(); + + ... + }; + //! [22] + //! [23] + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled) + //! [23] + //! [24] + myQObject.enabled = true; + + ... + + myQObject.enabled = !myQObject.enabled; + //! [24] + //! [25] + myQObject.enabled = true; + + ... + + myQObject.enabled = !myQObject.enabled; + //! [25] + //! [26] + myDialog.okButton + myDialog.okButton.objectName = "cancelButton"; + // from now on, myDialog.cancelButton references the button + //! [26] +#endif +} + diff --git a/src/3rdparty/webkit/WebKit/qt/qtwebkit_version.pri b/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri index ffd192c..ffd192c 100644 --- a/src/3rdparty/webkit/WebKit/qt/qtwebkit_version.pri +++ b/src/3rdparty/webkit/WebKit/qt/qt_webkit_version.pri 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 27f4b27..0f2ca22 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -122,6 +122,7 @@ private slots: void testJSPrompt(); void showModalDialog(); void testStopScheduledPageRefresh(); + void findText(); private: QWebView* m_view; @@ -2121,5 +2122,21 @@ void tst_QWebPage::testStopScheduledPageRefresh() QCOMPARE(page2.mainFrame()->url().toString(), QString("about:blank")); } +void tst_QWebPage::findText() +{ + m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>")); + m_page->triggerAction(QWebPage::SelectAll); + QVERIFY(!m_page->selectedText().isEmpty()); + m_page->findText(""); + QVERIFY(m_page->selectedText().isEmpty()); + QStringList words = (QStringList() << "foo" << "bar"); + foreach (QString subString, words) { + m_page->findText(subString, QWebPage::FindWrapsAroundDocument); + QCOMPARE(m_page->selectedText(), subString); + m_page->findText(""); + QVERIFY(m_page->selectedText().isEmpty()); + } +} + QTEST_MAIN(tst_QWebPage) #include "tst_qwebpage.moc" diff --git a/src/corelib/global/qconfig-medium.h b/src/corelib/global/qconfig-medium.h index ccd6759..6cb6c2c 100644 --- a/src/corelib/global/qconfig-medium.h +++ b/src/corelib/global/qconfig-medium.h @@ -213,6 +213,9 @@ #ifndef QT_NO_UNDOVIEW # define QT_NO_UNDOVIEW #endif +#ifndef QT_NO_GESTURES +# define QT_NO_GESTURES +#endif /* Widgets */ #ifndef QT_NO_LCDNUMBER diff --git a/src/corelib/global/qconfig-minimal.h b/src/corelib/global/qconfig-minimal.h index 99b16e8..c285e99 100644 --- a/src/corelib/global/qconfig-minimal.h +++ b/src/corelib/global/qconfig-minimal.h @@ -447,6 +447,9 @@ #ifndef QT_NO_UNDOVIEW # define QT_NO_UNDOVIEW #endif +#ifndef QT_NO_GESTURES +# define QT_NO_GESTURES +#endif /* Widgets */ #ifndef QT_NO_GROUPBOX diff --git a/src/corelib/global/qconfig-small.h b/src/corelib/global/qconfig-small.h index 1716b8d..dd74dcf 100644 --- a/src/corelib/global/qconfig-small.h +++ b/src/corelib/global/qconfig-small.h @@ -250,6 +250,9 @@ #ifndef QT_NO_SYSTEMTRAYICON # define QT_NO_SYSTEMTRAYICON #endif +#ifndef QT_NO_GESTURES +# define QT_NO_GESTURES +#endif /* Widgets */ #ifndef QT_NO_LCDNUMBER diff --git a/src/corelib/global/qfeatures.h b/src/corelib/global/qfeatures.h index a333153..b606843 100644 --- a/src/corelib/global/qfeatures.h +++ b/src/corelib/global/qfeatures.h @@ -85,6 +85,9 @@ // Freetype Font Engine //#define QT_NO_FREETYPE +// Gesture +//#define QT_NO_GESTURES + // QGroupBox //#define QT_NO_GROUPBOX diff --git a/src/corelib/global/qfeatures.txt b/src/corelib/global/qfeatures.txt index 3e6af24..4d938a9 100644 --- a/src/corelib/global/qfeatures.txt +++ b/src/corelib/global/qfeatures.txt @@ -1185,6 +1185,12 @@ Requires: PROPERTIES Name: State machine SeeAlso: ??? +Feature: GESTURES +Description: Provides a framework for gestures. +Section: Utilities +Requires: +Name: Gesture +SeeAlso: ??? # SVG diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 08674d2..a12e121 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -236,7 +236,8 @@ public: TextJustificationForced = 0x10000, TextForceLeftToRight = 0x20000, TextForceRightToLeft = 0x40000, - TextLongestVariant = 0x80000 + TextLongestVariant = 0x80000, + TextBypassShaping = 0x100000 #if defined(QT3_SUPPORT) && !defined(Q_MOC_RUN) ,SingleLine = TextSingleLine, @@ -947,6 +948,8 @@ public: #endif Key_MediaNext = 0x01000083, Key_MediaRecord = 0x01000084, + Key_MediaPause = 0x1000085, + Key_MediaTogglePlayPause = 0x1000086, Key_HomePage = 0x01000090, Key_Favorites = 0x01000091, Key_Search = 0x01000092, @@ -1089,11 +1092,15 @@ public: Key_Context2 = 0x01100001, Key_Context3 = 0x01100002, Key_Context4 = 0x01100003, - Key_Call = 0x01100004, - Key_Hangup = 0x01100005, + Key_Call = 0x01100004, // set absolute state to in a call (do not toggle state) + Key_Hangup = 0x01100005, // set absolute state to hang up (do not toggle state) Key_Flip = 0x01100006, - Key_Camera = 0x01100007, - Key_CameraFocus = 0x01100008, + Key_ToggleCallHangup = 0x01100007, // a toggle key for answering, or hanging up, based on current call state + Key_VoiceDial = 0x01100008, + Key_LastNumberRedial = 0x01100009, + + Key_Camera = 0x01100020, + Key_CameraFocus = 0x01100021, Key_unknown = 0x01ffffff }; @@ -1554,7 +1561,8 @@ public: enum LayoutDirection { LeftToRight, - RightToLeft + RightToLeft, + LayoutDirectionAuto }; enum AnchorPoint { @@ -1719,6 +1727,7 @@ public: }; Q_DECLARE_FLAGS(TouchPointStates, TouchPointState) +#ifndef QT_NO_GESTURES enum GestureState { NoGesture, @@ -1748,6 +1757,7 @@ public: IgnoredGesturesPropagateToParent = 0x04 }; Q_DECLARE_FLAGS(GestureFlags, GestureFlag) +#endif // QT_NO_GESTURES enum NavigationMode { @@ -1777,7 +1787,9 @@ Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MatchFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TextInteractionFlags) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::InputMethodHints) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::TouchPointStates) +#ifndef QT_NO_GESTURES Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::GestureFlags) +#endif typedef bool (*qInternalCallback)(void **); diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index f71ba9d..abbc03e 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -1317,7 +1317,7 @@ \value Key_Enter Typically located on the keypad. \value Key_Insert \value Key_Delete - \value Key_Pause + \value Key_Pause The Pause/Break key (\note Not anything to do with pausing media) \value Key_Print \value Key_SysReq \value Key_Clear @@ -1615,12 +1615,14 @@ \value Key_BassDown \value Key_TrebleUp \value Key_TrebleDown - \value Key_MediaPlay - \value Key_MediaStop + \value Key_MediaPlay A key setting the state of the media player to play + \value Key_MediaStop A key setting the state of the media player to stop \value Key_MediaPrevious \omitvalue Key_MediaPrev \value Key_MediaNext \value Key_MediaRecord + \value Key_MediaPause A key setting the state of the media player to pause (\note not the pause/break key) + \value Key_MediaTogglePlayPause A key to toggle the play/pause state in the media player (rather than setting an absolute state) \value Key_HomePage \value Key_Favorites \value Key_Search @@ -1741,18 +1743,21 @@ \value Key_MediaLast \value Key_unknown - \value Key_Call - \value Key_Camera - \value Key_CameraFocus + \value Key_Call A key to answer or initiate a call (\see Key_ToggleCallHangup for a key to toggle current call state) + \value Key_Camera A key to activate the camera shutter + \value Key_CameraFocus A key to focus the camera \value Key_Context1 \value Key_Context2 \value Key_Context3 \value Key_Context4 \value Key_Flip - \value Key_Hangup + \value Key_Hangup A key to end an ongoing call (\see Key_ToggleCallHangup for a key to toggle current call state) \value Key_No \value Key_Select \value Key_Yes + \value Key_ToggleCallHangup A key to toggle the current call state (ie. either answer, or hangup) depending on current call state + \value Key_VoiceDial + \value Key_LastNumberRedial \value Key_Execute \value Key_Printer @@ -2567,15 +2572,23 @@ /*! \enum Qt::LayoutDirection - Specifies the direction of Qt's layouts: + Specifies the direction of Qt's layouts and text handling. \value LeftToRight Left-to-right layout. \value RightToLeft Right-to-left layout. + \value LayoutDirectionAuto Automatic layout. Right-to-left layouts are necessary for certain languages, notably Arabic and Hebrew. - \sa QApplication::setLayoutDirection(), QWidget::setLayoutDirection() + LayoutDirectionAuto serves two purposes. When used in conjunction with widgets and layouts, it + will imply to use the layout direction set on the parent widget or QApplication. This + has the same effect as QWidget::unsetLayoutDirection(). + + When LayoutDirectoinAuto is used in conjunction with text layouting, it will imply that the text + directionality is determined from the content of the string to be layouted. + + \sa QApplication::setLayoutDirection(), QWidget::setLayoutDirection(), QTextOption::setTextDirection(), QString::isRightToLeft() */ /*! diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 8e76e9e..ce9c57e 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -928,7 +928,7 @@ public: } }; -#if defined(Q_OS_UNIX) +#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) #define QT_USE_MMAP #endif diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index a20d171..9d3513a 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -275,17 +275,19 @@ public: TouchUpdate = 195, TouchEnd = 196, +#ifndef QT_NO_GESTURES NativeGesture = 197, // Internal for platform gesture support - +#endif RequestSoftwareInputPanel = 199, CloseSoftwareInputPanel = 200, UpdateSoftKeys = 201, // Internal for compressing soft key updates WinIdChange = 203, +#ifndef QT_NO_GESTURES Gesture = 198, GestureOverride = 202, - +#endif // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event @@ -327,7 +329,9 @@ private: friend class QGraphicsView; friend class QGraphicsViewPrivate; friend class QGraphicsScenePrivate; +#ifndef QT_NO_GESTURES friend class QGestureManager; +#endif }; class Q_CORE_EXPORT QTimerEvent : public QEvent diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index 1cb8455..9d8ee5a 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -484,9 +484,9 @@ void QSelectThread::run() } // end for // traversed all, so update + updateActivatedNotifiers(QSocketNotifier::Exception, &exceptionfds); updateActivatedNotifiers(QSocketNotifier::Read, &readfds); updateActivatedNotifiers(QSocketNotifier::Write, &writefds); - updateActivatedNotifiers(QSocketNotifier::Exception, &exceptionfds); break; case EINTR: // Should never occur on Symbian, but this is future proof! @@ -496,9 +496,9 @@ void QSelectThread::run() break; } } else { + updateActivatedNotifiers(QSocketNotifier::Exception, &exceptionfds); updateActivatedNotifiers(QSocketNotifier::Read, &readfds); updateActivatedNotifiers(QSocketNotifier::Write, &writefds); - updateActivatedNotifiers(QSocketNotifier::Exception, &exceptionfds); } m_waitCond.wait(&m_mutex); diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp index 135ec303..cede810 100644 --- a/src/corelib/kernel/qeventdispatcher_win.cpp +++ b/src/corelib/kernel/qeventdispatcher_win.cpp @@ -71,10 +71,12 @@ extern uint qGlobalPostedEventsCount(); #ifndef WM_TOUCH # define WM_TOUCH 0x0240 #endif +#ifndef QT_NO_GESTURES #ifndef WM_GESTURE # define WM_GESTURE 0x0119 # define WM_GESTURENOTIFY 0x011A #endif +#endif // QT_NO_GESTURES enum { WM_QT_SOCKETNOTIFIER = WM_USER, @@ -738,8 +740,10 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags) || msg.message == WM_MOUSEWHEEL || msg.message == WM_MOUSEHWHEEL || msg.message == WM_TOUCH +#ifndef QT_NO_GESTURES || msg.message == WM_GESTURE || msg.message == WM_GESTURENOTIFY +#endif || msg.message == WM_CLOSE)) { // queue user input events for later processing haveMessage = false; diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index 628afa7..c19f718 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -43,7 +43,7 @@ #include "qabstracteventdispatcher.h" #include "qcoreapplication.h" -#include "qdatetime.h" +#include "qelapsedtimer.h" #include "qobject_p.h" #include <private/qthread_p.h> @@ -247,7 +247,7 @@ void QEventLoop::processEvents(ProcessEventsFlags flags, int maxTime) if (!d->threadData->eventDispatcher) return; - QTime start; + QElapsedTimer start; start.start(); if (flags & DeferredDeletion) QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index ce9ed58..6ebaaa3 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -378,6 +378,8 @@ void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveO void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp, LoadOperator loadOp) { + if (idx < User) + return; //builtin types should not be registered; QVector<QCustomTypeInfo> *ct = customTypes(); if (!ct) return; diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index ca54c6c..1321b14 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -56,7 +56,7 @@ #include "qhash.h" #include "qtranslator_p.h" -#if defined(Q_OS_UNIX) +#if defined(Q_OS_UNIX) && !defined(Q_OS_SYMBIAN) #define QT_USE_MMAP #include "private/qcore_unix_p.h" #endif diff --git a/src/corelib/tools/qelapsedtimer.cpp b/src/corelib/tools/qelapsedtimer.cpp index 28dfc23..cb5e701 100644 --- a/src/corelib/tools/qelapsedtimer.cpp +++ b/src/corelib/tools/qelapsedtimer.cpp @@ -137,7 +137,7 @@ QT_BEGIN_NAMESPACE used. \value SystemTime The human-readable system time. This clock is not monotonic. - \value MonotonicClock The system's monotonic clock, usually found in Unix systems. This clock is not monotonic and does not overflow. + \value MonotonicClock The system's monotonic clock, usually found in Unix systems. This clock is monotonic and does not overflow. \value TickCounter The system's tick counter, used on Windows and Symbian systems. This clock may overflow. \value MachAbsoluteTime The Mach kernel's absolute time (Mac OS X). This clock is monotonic and does not overflow. diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 3374c80..0777f06 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -931,7 +931,7 @@ public: { return QHash<Key, T>::insertMulti(key, value); } inline QMultiHash &operator+=(const QMultiHash &other) - { unite(other); return *this; } + { this->unite(other); return *this; } inline QMultiHash operator+(const QMultiHash &other) const { QMultiHash result = *this; result += other; return result; } @@ -1006,12 +1006,7 @@ Q_INLINE_TEMPLATE int QMultiHash<Key, T>::remove(const Key &key, const T &value) typename QHash<Key, T>::iterator end(QHash<Key, T>::end()); while (i != end && i.key() == key) { if (i.value() == value) { -#if defined(Q_CC_RVCT) - // RVCT has problems with scoping, apparently. - i = QHash<Key, T>::erase(i); -#else - i = erase(i); -#endif + i = this->erase(i); ++n; } else { ++i; diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index c000dc8..a51ee81 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -3478,6 +3478,25 @@ QLocale::MeasurementSystem QLocale::measurementSystem() const } /*! + \since 4.7 + + Returns the text direction of the language. +*/ +Qt::LayoutDirection QLocale::textDirection() const +{ + Language lang = language(); + if (lang == QLocale::Arabic || + lang == QLocale::Hebrew || + lang == QLocale::Persian || + lang == QLocale::Urdu || + lang == QLocale::Syriac) + return Qt::RightToLeft; + + return Qt::LeftToRight; +} + + +/*! \since 4.5 Returns the localized name of the "AM" suffix for times specified using diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index f2fd892..8b424bb 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -666,6 +666,8 @@ public: MeasurementSystem measurementSystem() const; + Qt::LayoutDirection textDirection() const; + inline bool operator==(const QLocale &other) const; inline bool operator!=(const QLocale &other) const; diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 5696ba6..e4b73a1 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -977,7 +977,7 @@ public: { return QMap<Key, T>::insertMulti(key, value); } inline QMultiMap &operator+=(const QMultiMap &other) - { unite(other); return *this; } + { this->unite(other); return *this; } inline QMultiMap operator+(const QMultiMap &other) const { QMultiMap result = *this; result += other; return result; } @@ -1052,12 +1052,7 @@ Q_INLINE_TEMPLATE int QMultiMap<Key, T>::remove(const Key &key, const T &value) typename QMap<Key, T>::iterator end(QMap<Key, T>::end()); while (i != end && !qMapLessThanKey<Key>(key, i.key())) { if (i.value() == value) { -#if defined(Q_CC_RVCT) - // RVCT has problems with scoping, apparently. - i = QMap<Key, T>::erase(i); -#else - i = erase(i); -#endif + i = this->erase(i); ++n; } else { ++i; diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 6acbcec..1d5fab3 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -113,7 +113,7 @@ int qFindStringBoyerMoore(const QChar *haystack, int haystackLen, int from, static int ucstricmp(const ushort *a, const ushort *ae, const ushort *b, const ushort *be) { if (a == b) - return 0; + return (ae - be); if (a == 0) return 1; if (b == 0) @@ -125,7 +125,7 @@ static int ucstricmp(const ushort *a, const ushort *ae, const ushort *b, const u uint alast = 0; uint blast = 0; - while (a != e) { + while (a < e) { // qDebug() << hex << alast << blast; // qDebug() << hex << "*a=" << *a << "alast=" << alast << "folded=" << foldCase (*a, alast); // qDebug() << hex << "*b=" << *b << "blast=" << blast << "folded=" << foldCase (*b, blast); @@ -154,7 +154,7 @@ static int ucstricmp(const ushort *a, const ushort *ae, const uchar *b) if (b == 0) return -1; - while (a != ae && *b) { + while (a < ae && *b) { int diff = foldCase(*a) - foldCase(*b); if ((diff)) return diff; @@ -4640,9 +4640,12 @@ int QString::compare_helper(const QChar *data1, int length1, QLatin1String s2, return length1; if (cs == Qt::CaseSensitive) { - while (uc != e && *c && *uc == *c) + while (uc < e && *c && *uc == *c) uc++, c++; + if (uc == e) + return -*c; + return *uc - *c; } else { return ucstricmp(uc, e, c); @@ -6913,20 +6916,23 @@ void QString::updateProperties() const p++; } - p = d->data; - d->righttoleft = false; + d->righttoleft = isRightToLeft(); + d->clean = true; +} + +bool QString::isRightToLeft() const +{ + ushort *p = d->data; + const ushort * const end = p + d->size; + bool righttoleft = false; while (p < end) { switch(QChar::direction(*p)) { case QChar::DirL: - case QChar::DirLRO: - case QChar::DirLRE: goto end; case QChar::DirR: case QChar::DirAL: - case QChar::DirRLO: - case QChar::DirRLE: - d->righttoleft = true; + righttoleft = true; goto end; default: break; @@ -6934,8 +6940,7 @@ void QString::updateProperties() const ++p; } end: - d->clean = true; - return; + return righttoleft; } /*! \fn bool QString::isSimpleText() const @@ -7093,7 +7098,7 @@ QString QString::fromRawData(const QChar *unicode, int size) */ QString &QString::setRawData(const QChar *unicode, int size) { - if (d->ref != 1 || d->alloc) { + if (d->ref != 1 || (d->data == d->array && d->alloc)) { *this = fromRawData(unicode, size); } else { #ifdef QT3_SUPPORT diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index a1c4e77..e52f59f 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -590,7 +590,7 @@ public: #endif bool isSimpleText() const { if (!d->clean) updateProperties(); return d->simpletext; } - bool isRightToLeft() const { if (!d->clean) updateProperties(); return d->righttoleft; } + bool isRightToLeft() const; QString(int size, Qt::Initialization); diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index bfede94..4a6bb4b 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -127,6 +127,13 @@ public: inline T *data() { return ptr; } inline const T *data() const { return ptr; } inline const T * constData() const { return ptr; } + typedef int size_type; + typedef T value_type; + typedef value_type *pointer; + typedef const value_type *const_pointer; + typedef value_type &reference; + typedef const value_type &const_reference; + typedef qptrdiff difference_type; private: friend class QPodList<T, Prealloc>; diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc index 38901e5..ef2dc58 100644 --- a/src/corelib/tools/qvarlengtharray.qdoc +++ b/src/corelib/tools/qvarlengtharray.qdoc @@ -302,3 +302,52 @@ \a defaultValue. */ +/*! + \typedef QVarLengthArray::size_type + \since 4.7 + + Typedef for int. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::value_type + \since 4.7 + + Typedef for T. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::difference_type + \since 4.7 + + Typedef for ptrdiff_t. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::pointer + \since 4.7 + + Typedef for T *. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::const_pointer + \since 4.7 + + Typedef for const T *. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::reference + \since 4.7 + + Typedef for T &. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::const_reference + \since 4.7 + + Typedef for const T &. Provided for STL compatibility. +*/ + diff --git a/src/declarative/3rdparty/3rdparty.pri b/src/declarative/3rdparty/3rdparty.pri deleted file mode 100644 index fbdcc11..0000000 --- a/src/declarative/3rdparty/3rdparty.pri +++ /dev/null @@ -1,7 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/qlistmodelinterface_p.h\ - -SOURCES += \ - $$PWD/qlistmodelinterface.cpp \ diff --git a/src/declarative/QmlChanges.txt b/src/declarative/QmlChanges.txt index 0df5f10..8b6b83f 100644 --- a/src/declarative/QmlChanges.txt +++ b/src/declarative/QmlChanges.txt @@ -1,8 +1,9 @@ ============================================================================= The changes below are pre Qt 4.7.0 RC +QDeclarativeView + - initialSize() function added TextInput and TextEdit: - - showInputPanelOnFocus property added - openSoftwareInputPanel() and closeSoftwareInputPanel() functions added Flickable: - overShoot is replaced by boundsBehavior enumeration diff --git a/src/declarative/debugger/qdeclarativedebugtrace_p.h b/src/declarative/debugger/qdeclarativedebugtrace_p.h index 5ba49a8..704c49a 100644 --- a/src/declarative/debugger/qdeclarativedebugtrace_p.h +++ b/src/declarative/debugger/qdeclarativedebugtrace_p.h @@ -50,7 +50,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE class QUrl; -class QDeclarativeDebugTrace : public QDeclarativeDebugService +class Q_AUTOTEST_EXPORT QDeclarativeDebugTrace : public QDeclarativeDebugService { public: enum EventType { diff --git a/src/declarative/declarative.pro b/src/declarative/declarative.pro index 8037a16..510e7a5 100644 --- a/src/declarative/declarative.pro +++ b/src/declarative/declarative.pro @@ -20,7 +20,6 @@ include(../qbase.pri) #DESTDIR=. #modules -include(3rdparty/3rdparty.pri) include(util/util.pri) include(graphicsitems/graphicsitems.pri) include(qml/qml.pri) diff --git a/src/declarative/graphicsitems/qdeclarativeanchors.cpp b/src/declarative/graphicsitems/qdeclarativeanchors.cpp index aa53aba..6796977 100644 --- a/src/declarative/graphicsitems/qdeclarativeanchors.cpp +++ b/src/declarative/graphicsitems/qdeclarativeanchors.cpp @@ -53,6 +53,30 @@ QT_BEGIN_NAMESPACE //TODO: should we cache relationships, so we don't have to check each time (parent-child or sibling)? //TODO: support non-parent, non-sibling (need to find lowest common ancestor) +static qreal hcenter(QGraphicsItem *i) +{ + QGraphicsItemPrivate *item = QGraphicsItemPrivate::get(i); + + qreal width = item->width(); + int iw = width; + if (iw % 2) + return (width + 1) / 2; + else + return width / 2; +} + +static qreal vcenter(QGraphicsItem *i) +{ + QGraphicsItemPrivate *item = QGraphicsItemPrivate::get(i); + + qreal height = item->height(); + int ih = height; + if (ih % 2) + return (height + 1) / 2; + else + return height / 2; +} + //### const item? //local position static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine) @@ -73,10 +97,10 @@ static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine ret = item->y() + d->height(); break; case QDeclarativeAnchorLine::HCenter: - ret = item->x() + d->width()/2; + ret = item->x() + hcenter(item); break; case QDeclarativeAnchorLine::VCenter: - ret = item->y() + d->height()/2; + ret = item->y() + vcenter(item); break; case QDeclarativeAnchorLine::Baseline: if (d->isDeclarativeItem) @@ -108,10 +132,10 @@ static qreal adjustedPosition(QGraphicsObject *item, QDeclarativeAnchorLine::Anc ret = d->height(); break; case QDeclarativeAnchorLine::HCenter: - ret = d->width()/2; + ret = hcenter(item); break; case QDeclarativeAnchorLine::VCenter: - ret = d->height()/2; + ret = vcenter(item); break; case QDeclarativeAnchorLine::Baseline: if (d->isDeclarativeItem) @@ -192,14 +216,14 @@ void QDeclarativeAnchorsPrivate::centerInChanged() QGraphicsItemPrivate *itemPrivate = QGraphicsItemPrivate::get(item); if (centerIn == item->parentItem()) { QGraphicsItemPrivate *parentPrivate = QGraphicsItemPrivate::get(item->parentItem()); - QPointF p((parentPrivate->width() - itemPrivate->width()) / 2. + hCenterOffset, - (parentPrivate->height() - itemPrivate->height()) / 2. + vCenterOffset); + QPointF p(hcenter(item->parentItem()) - hcenter(item) + hCenterOffset, + vcenter(item->parentItem()) - vcenter(item) + vCenterOffset); setItemPos(p); } else if (centerIn->parentItem() == item->parentItem()) { QGraphicsItemPrivate *centerPrivate = QGraphicsItemPrivate::get(centerIn); - QPointF p(centerIn->x() + (centerPrivate->width() - itemPrivate->width()) / 2. + hCenterOffset, - centerIn->y() + (centerPrivate->height() - itemPrivate->height()) / 2. + vCenterOffset); + QPointF p(centerIn->x() + hcenter(centerIn) - hcenter(item) + hCenterOffset, + centerIn->y() + vcenter(centerIn) - vcenter(item) + vCenterOffset); setItemPos(p); } @@ -535,9 +559,9 @@ void QDeclarativeAnchorsPrivate::updateVerticalAnchors() //Handle vCenter if (vCenter.item == item->parentItem()) { setItemY(adjustedPosition(vCenter.item, vCenter.anchorLine) - - itemPrivate->height()/2 + vCenterOffset); + - vcenter(item) + vCenterOffset); } else if (vCenter.item->parentItem() == item->parentItem()) { - setItemY(position(vCenter.item, vCenter.anchorLine) - itemPrivate->height()/2 + vCenterOffset); + setItemY(position(vCenter.item, vCenter.anchorLine) - vcenter(item) + vCenterOffset); } } else if (usedAnchors & QDeclarativeAnchors::BaselineAnchor) { //Handle baseline @@ -604,9 +628,9 @@ void QDeclarativeAnchorsPrivate::updateHorizontalAnchors() } else if (usedAnchors & QDeclarativeAnchors::HCenterAnchor) { //Handle hCenter if (hCenter.item == item->parentItem()) { - setItemX(adjustedPosition(hCenter.item, hCenter.anchorLine) - itemPrivate->width()/2 + hCenterOffset); + setItemX(adjustedPosition(hCenter.item, hCenter.anchorLine) - hcenter(item) + hCenterOffset); } else if (hCenter.item->parentItem() == item->parentItem()) { - setItemX(position(hCenter.item, hCenter.anchorLine) - itemPrivate->width()/2 + hCenterOffset); + setItemX(position(hCenter.item, hCenter.anchorLine) - hcenter(item) + hCenterOffset); } } diff --git a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp index a05e426..d8527d3 100644 --- a/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeanimatedimage.cpp @@ -63,22 +63,32 @@ QT_BEGIN_NAMESPACE \inherits Image \since 4.7 - This item provides for playing animations stored as images containing a series of frames, - such as GIF files. The full list of supported formats can be determined with - QMovie::supportedFormats(). + The AnimatedImage element provides for playing animations stored as images containing a series of frames, + such as GIF files. + + The full list of supported formats can be determined with QMovie::supportedFormats(). \table \row \o \image animatedimageitem.gif \o \qml -Item { - width: anim.width; height: anim.height+8 - AnimatedImage { id: anim; source: "pics/games-anim.gif" } - Rectangle { color: "red"; width: 4; height: 8; y: anim.height - x: (anim.width-width)*anim.currentFrame/(anim.frameCount-1) + import Qt 4.7 + + Rectangle { + width: animation.width; height: animation.height + 8 + + AnimatedImage { id: animation; source: "animation.gif" } + + Rectangle { + property int frames: animation.frameCount + + width: 4; height: 8 + x: (animation.width - width) * animation.currentFrame / frames + y: animation.height + color: "red" + } } -} \endqml \endtable */ @@ -96,7 +106,7 @@ QDeclarativeAnimatedImage::~QDeclarativeAnimatedImage() /*! \qmlproperty bool AnimatedImage::paused - This property holds whether the animated image is paused or not + This property holds whether the animated image is paused. Defaults to false, and can be set to true when you want to pause. */ @@ -120,7 +130,7 @@ void QDeclarativeAnimatedImage::setPaused(bool pause) } /*! \qmlproperty bool AnimatedImage::playing - This property holds whether the animated image is playing or not + This property holds whether the animated image is playing. Defaults to true, so as to start playing immediately. */ diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp index 1f1e453..cf458da 100644 --- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp @@ -138,7 +138,7 @@ QDeclarativeBorderImage::~QDeclarativeBorderImage() BorderImage can handle any image format supported by Qt, loaded from any URL scheme supported by Qt. - It can also handle .sci files, which are a Qml-specific format. A .sci file uses a simple text-based format that specifies + It can also handle .sci files, which are a QML-specific format. A .sci file uses a simple text-based format that specifies the borders, the image file and the tile rules. The following .sci file sets the borders to 10 on each side for the image \c picture.png: diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp index 10dc0f8..fdc1444 100644 --- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp @@ -351,6 +351,8 @@ void QDeclarativeFlickablePrivate::updateBeginningEnd() Flickable places its children on a surface that can be dragged and flicked. \code + import Qt 4.7 + Flickable { width: 200; height: 200 contentWidth: image.width; contentHeight: image.height @@ -1039,11 +1041,11 @@ QDeclarativeListProperty<QGraphicsObject> QDeclarativeFlickable::flickableChildr The \c boundsBehavior can be one of: \list - \o \e Flickable.StopAtBounds - the contents can not be dragged beyond the boundary + \o Flickable.StopAtBounds - the contents can not be dragged beyond the boundary of the flickable, and flicks will not overshoot. - \o \e Flickable.DragOverBounds - the contents can be dragged beyond the boundary + \o Flickable.DragOverBounds - the contents can be dragged beyond the boundary of the Flickable, but flicks will not overshoot. - \o \e Flickable.DragAndOvershootBounds (default) - the contents can be dragged + \o Flickable.DragAndOvershootBounds (default) - the contents can be dragged beyond the boundary of the Flickable, and can overshoot the boundary when flicked. \endlist diff --git a/src/declarative/graphicsitems/qdeclarativeflipable.cpp b/src/declarative/graphicsitems/qdeclarativeflipable.cpp index d926119..8c9d2dd 100644 --- a/src/declarative/graphicsitems/qdeclarativeflipable.cpp +++ b/src/declarative/graphicsitems/qdeclarativeflipable.cpp @@ -74,7 +74,7 @@ public: \inherits Item Flipable is an item that can be visibly "flipped" between its front and - back sides. It is used together with Rotation and State/Transition to + back sides. It is used together with \l Rotation and \l {State}/\l {Transition} to produce a flipping effect. Here is a Flipable that flips whenever it is clicked: @@ -83,10 +83,12 @@ public: \image flipable.gif - The Rotation element is used to specify the angle and axis of the flip, - and the State defines the changes in angle which produce the flipping - effect. Finally, the Transition creates the animation that changes the + The \l Rotation element is used to specify the angle and axis of the flip, + and the \l State defines the changes in angle which produce the flipping + effect. Finally, the \l Transition creates the animation that changes the angle over one second. + + \sa {declarative/ui-components/flipable}{Flipable example} */ /*! diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index 906f1fc..3792595 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -108,6 +108,7 @@ public: , highlightComponent(0), highlight(0), trackedItem(0) , moveReason(Other), buffer(0), highlightXAnimator(0), highlightYAnimator(0) , highlightMoveDuration(150) + , footerComponent(0), footer(0), headerComponent(0), header(0) , bufferMode(BufferBefore | BufferAfter), snapMode(QDeclarativeGridView::NoSnap) , ownModel(false), wrap(false), autoHighlight(true) , fixCurrentVisibility(false), lazyRelease(false), layoutScheduled(false) @@ -128,6 +129,8 @@ public: void createHighlight(); void updateHighlight(); void updateCurrent(int modelIndex); + void updateHeader(); + void updateFooter(); void fixupPosition(); FxGridItem *visibleItem(int modelIndex) const { @@ -230,6 +233,18 @@ public: return visibleItems.count() ? visibleItems.first() : 0; } + int lastVisibleIndex() const { + int lastIndex = -1; + for (int i = visibleItems.count()-1; i >= 0; --i) { + FxGridItem *gridItem = visibleItems.at(i); + if (gridItem->index != -1) { + lastIndex = gridItem->index; + break; + } + } + return lastIndex; + } + // Map a model index to visibleItems list index. // These may differ if removed items are still present in the visible list, // e.g. doing a removal animation @@ -246,16 +261,37 @@ public: return -1; // Not in visibleList } - qreal snapPosAt(qreal pos) { + qreal snapPosAt(qreal pos) const { + Q_Q(const QDeclarativeGridView); qreal snapPos = 0; if (!visibleItems.isEmpty()) { pos += rowSize()/2; snapPos = visibleItems.first()->rowPos() - visibleIndex / columns * rowSize(); snapPos = pos - fmodf(pos - snapPos, qreal(rowSize())); + qreal maxExtent = flow == QDeclarativeGridView::LeftToRight ? -q->maxYExtent() : -q->maxXExtent(); + qreal minExtent = flow == QDeclarativeGridView::LeftToRight ? -q->minYExtent() : -q->minXExtent(); + if (snapPos > maxExtent) + snapPos = maxExtent; + if (snapPos < minExtent) + snapPos = minExtent; } return snapPos; } + FxGridItem *snapItemAt(qreal pos) { + for (int i = 0; i < visibleItems.count(); ++i) { + FxGridItem *item = visibleItems[i]; + if (item->index == -1) + continue; + qreal itemTop = item->rowPos(); + if (item->index == model->count()-1 || (itemTop+rowSize()/2 >= pos)) + return item; + } + if (visibleItems.count() && visibleItems.first()->rowPos() <= pos) + return visibleItems.first(); + return 0; + } + int snapIndex() { int index = currentIndex; for (int i = 0; i < visibleItems.count(); ++i) { @@ -283,6 +319,9 @@ public: scheduleLayout(); } } + } else if ((header && header->item == item) || (footer && footer->item == item)) { + updateHeader(); + updateFooter(); } } @@ -330,6 +369,10 @@ public: QSmoothedAnimation *highlightXAnimator; QSmoothedAnimation *highlightYAnimator; int highlightMoveDuration; + QDeclarativeComponent *footerComponent; + FxGridItem *footer; + QDeclarativeComponent *headerComponent; + FxGridItem *header; enum BufferMode { NoBuffer = 0x00, BufferBefore = 0x01, BufferAfter = 0x02 }; int bufferMode; QDeclarativeGridView::SnapMode snapMode; @@ -412,7 +455,6 @@ void QDeclarativeGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) Q_Q(QDeclarativeGridView); if (!isValid() || !q->isComponentComplete()) return; - itemCount = model->count(); qreal bufferFrom = from - buffer; qreal bufferTo = to + buffer; @@ -522,6 +564,10 @@ void QDeclarativeGridViewPrivate::refill(qreal from, qreal to, bool doBuffer) deferredRelease = true; } if (changed) { + if (header) + updateHeader(); + if (footer) + updateFooter(); if (flow == QDeclarativeGridView::LeftToRight) q->setContentHeight(endPosition() - startPosition()); else @@ -557,7 +603,7 @@ void QDeclarativeGridViewPrivate::layout() { Q_Q(QDeclarativeGridView); layoutScheduled = false; - if (!isValid()) { + if (!isValid() && !visibleItems.count()) { clear(); return; } @@ -579,6 +625,10 @@ void QDeclarativeGridViewPrivate::layout() item->setPosition(colPos, rowPos); } } + if (header) + updateHeader(); + if (footer) + updateFooter(); q->refill(); updateHighlight(); moveReason = Other; @@ -742,6 +792,94 @@ void QDeclarativeGridViewPrivate::updateCurrent(int modelIndex) releaseItem(oldCurrentItem); } +void QDeclarativeGridViewPrivate::updateFooter() +{ + Q_Q(QDeclarativeGridView); + if (!footer && footerComponent) { + QDeclarativeItem *item = 0; + QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q)); + QObject *nobj = footerComponent->create(context); + if (nobj) { + QDeclarative_setParent_noEvent(context, nobj); + item = qobject_cast<QDeclarativeItem *>(nobj); + if (!item) + delete nobj; + } else { + delete context; + } + if (item) { + QDeclarative_setParent_noEvent(item, q->viewport()); + item->setParentItem(q->viewport()); + item->setZValue(1); + QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); + itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); + footer = new FxGridItem(item, q); + } + } + if (footer) { + if (visibleItems.count()) { + qreal endPos = endPosition(); + if (lastVisibleIndex() == model->count()-1) { + footer->setPosition(0, endPos); + } else { + qreal visiblePos = position() + q->height(); + if (endPos <= visiblePos || footer->endRowPos() < endPos) + footer->setPosition(0, endPos); + } + } else { + qreal endPos = 0; + if (header) { + endPos += flow == QDeclarativeGridView::LeftToRight + ? header->item->height() + : header->item->width(); + } + footer->setPosition(0, endPos); + } + } +} + +void QDeclarativeGridViewPrivate::updateHeader() +{ + Q_Q(QDeclarativeGridView); + if (!header && headerComponent) { + QDeclarativeItem *item = 0; + QDeclarativeContext *context = new QDeclarativeContext(qmlContext(q)); + QObject *nobj = headerComponent->create(context); + if (nobj) { + QDeclarative_setParent_noEvent(context, nobj); + item = qobject_cast<QDeclarativeItem *>(nobj); + if (!item) + delete nobj; + } else { + delete context; + } + if (item) { + QDeclarative_setParent_noEvent(item, q->viewport()); + item->setParentItem(q->viewport()); + item->setZValue(1); + QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); + itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); + header = new FxGridItem(item, q); + } + } + if (header) { + if (visibleItems.count()) { + qreal startPos = startPosition(); + qreal headerSize = flow == QDeclarativeGridView::LeftToRight + ? header->item->height() + : header->item->width(); + if (visibleIndex == 0) { + header->setPosition(0, startPos - headerSize); + } else { + if (position() <= startPos || header->rowPos() > startPos - headerSize) + header->setPosition(0, startPos - headerSize); + } + } else { + header->setPosition(0, 0); + } + } +} + void QDeclarativeGridViewPrivate::fixupPosition() { moveReason = Other; @@ -753,7 +891,6 @@ void QDeclarativeGridViewPrivate::fixupPosition() void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent) { - Q_Q(QDeclarativeGridView); if ((flow == QDeclarativeGridView::TopToBottom && &data == &vData) || (flow == QDeclarativeGridView::LeftToRight && &data == &hData)) return; @@ -761,7 +898,41 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m int oldDuration = fixupDuration; fixupDuration = moveReason == Mouse ? fixupDuration : 0; - if (haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { + if (snapMode != QDeclarativeGridView::NoSnap) { + FxGridItem *topItem = snapItemAt(position()+highlightRangeStart); + FxGridItem *bottomItem = snapItemAt(position()+highlightRangeEnd); + qreal pos; + if (topItem && bottomItem && haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { + qreal topPos = qMin(topItem->rowPos() - highlightRangeStart, -maxExtent); + qreal bottomPos = qMax(bottomItem->rowPos() - highlightRangeEnd, -minExtent); + pos = qAbs(data.move + topPos) < qAbs(data.move + bottomPos) ? topPos : bottomPos; + } else if (topItem) { + pos = qMax(qMin(topItem->rowPos() - highlightRangeStart, -maxExtent), -minExtent); + } else if (bottomItem) { + pos = qMax(qMin(bottomItem->rowPos() - highlightRangeStart, -maxExtent), -minExtent); + } else { + fixupDuration = oldDuration; + return; + } + if (currentItem && haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { + updateHighlight(); + qreal currPos = currentItem->rowPos(); + if (pos < currPos + rowSize() - highlightRangeEnd) + pos = currPos + rowSize() - highlightRangeEnd; + if (pos > currPos - highlightRangeStart) + pos = currPos - highlightRangeStart; + } + + qreal dist = qAbs(data.move + pos); + if (dist > 0) { + timeline.reset(data.move); + if (fixupDuration) + timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); + else + timeline.set(data.move, -pos); + vTime = timeline.time(); + } + } else if (haveHighlightRange && highlightRange == QDeclarativeGridView::StrictlyEnforceRange) { if (currentItem) { updateHighlight(); qreal pos = currentItem->rowPos(); @@ -773,26 +944,10 @@ void QDeclarativeGridViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m timeline.reset(data.move); if (viewPos != position()) { - if (fixupDuration) { + if (fixupDuration) timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - } else { - data.move.setValue(-viewPos); - q->viewportMoved(); - } - } - vTime = timeline.time(); - } - } else if (snapMode != QDeclarativeGridView::NoSnap) { - qreal pos = -snapPosAt(-(data.move.value() - highlightRangeStart)) + highlightRangeStart; - pos = qMin(qMax(pos, maxExtent), minExtent); - qreal dist = qAbs(data.move.value() - pos); - if (dist > 0) { - timeline.reset(data.move); - if (fixupDuration) { - timeline.move(data.move, pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - } else { - data.move.setValue(pos); - q->viewportMoved(); + else + timeline.set(data.move, -viewPos); } vTime = timeline.time(); } @@ -806,7 +961,6 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m QDeclarativeTimeLineCallback::Callback fixupCallback, qreal velocity) { Q_Q(QDeclarativeGridView); - moveReason = Mouse; if ((!haveHighlightRange || highlightRange != QDeclarativeGridView::StrictlyEnforceRange) && snapMode == QDeclarativeGridView::NoSnap) { @@ -851,9 +1005,10 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m qreal accel = deceleration; qreal v2 = v * v; qreal overshootDist = 0.0; - if (maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) { + if ((maxDistance > 0.0 && v2 / (2.0f * maxDistance) < accel) || snapMode == QDeclarativeGridView::SnapOneRow) { // + rowSize()/4 to encourage moving at least one item in the flick direction qreal dist = v2 / (accel * 2.0) + rowSize()/4; + dist = qMin(dist, maxDistance); if (v > 0) dist = -dist; data.flickTarget = -snapPosAt(-(data.move.value() - highlightRangeStart) + dist) + highlightRangeStart; @@ -904,28 +1059,43 @@ void QDeclarativeGridViewPrivate::flick(AxisData &data, qreal minExtent, qreal m \inherits Flickable \brief The GridView item provides a grid view of items provided by a model. - The model is typically provided by a QAbstractListModel "C++ model object", - but can also be created directly in QML. + A GridView displays data from models created from built-in QML elements like ListModel + and XmlListModel, or custom model classes defined in C++ that inherit from + QAbstractListModel. + + A GridView has a \l model, which defines the data to be displayed, and + a \l delegate, which defines how the data should be displayed. Items in a + GridView are laid out horizontally or vertically. Grid views are inherently flickable + as GridView inherits from \l Flickable. - The items are laid out top to bottom (vertically) or left to right (horizontally) - and may be flicked to scroll. + For example, if there is a simple list model defined in a file \c ContactModel.qml like this: - The below example creates a very simple grid, using a QML model. + \snippet doc/src/snippets/declarative/gridview/ContactModel.qml 0 - \image gridview.png + Another component can display this model data in a GridView, like this: - \snippet doc/src/snippets/declarative/gridview/gridview.qml 3 + \snippet doc/src/snippets/declarative/gridview/gridview.qml import + \codeline + \snippet doc/src/snippets/declarative/gridview/gridview.qml classdocs simple + \image gridview-simple.png - The model is defined as a ListModel using QML: - \quotefile doc/src/snippets/declarative/gridview/dummydata/ContactModel.qml + Here, the GridView creates a \c ContactModel component for its model, and a \l Column element + (containing \l Image and \ Text elements) for its delegate. The view will create a new delegate + for each item in the model. Notice the delegate is able to access the model's \c name and + \c portrait data directly. - In this case ListModel is a handy way for us to test our UI. In practice - the model would be implemented in C++, or perhaps via a SQL data source. + An improved grid view is shown below. The delegate is visually improved and is moved + into a separate \c contactDelegate component. Also, the currently selected item is highlighted + with a blue \l Rectangle using the \l highlight property, and \c focus is set to \c true + to enable keyboard navigation for the grid view. + + \snippet doc/src/snippets/declarative/gridview/gridview.qml classdocs advanced + \image gridview-highlight.png Delegates are instantiated as needed and may be destroyed at any time. State should \e never be stored in a delegate. - \bold Note that views do not enable \e clip automatically. If the view + \note Views do not enable \e clip automatically. If the view is not clipped by another item or the screen, it will be necessary to set \e {clip: true} in order to have the out of view items clipped nicely. @@ -943,11 +1113,13 @@ QDeclarativeGridView::~QDeclarativeGridView() d->clear(); if (d->ownModel) delete d->model; + delete d->header; + delete d->footer; } /*! \qmlattachedproperty bool GridView::isCurrentItem - This attched property is true if this delegate is the current item; otherwise false. + This attached property is true if this delegate is the current item; otherwise false. It is attached to each instance of the delegate. */ @@ -971,19 +1143,7 @@ QDeclarativeGridView::~QDeclarativeGridView() The example below ensures that the animation completes before the item is removed from the grid. - \code - Component { - id: myDelegate - Item { - id: wrapper - GridView.onRemove: SequentialAnimation { - PropertyAction { target: wrapper; property: "GridView.delayRemove"; value: true } - NumberAnimation { target: wrapper; property: "scale"; to: 0; duration: 250; easing.type: Easing.InOutQuad } - PropertyAction { target: wrapper; property: "GridView.delayRemove"; value: false } - } - } - } - \endcode + \snippet doc/src/snippets/declarative/gridview/gridview.qml delayRemove */ /*! @@ -1001,10 +1161,10 @@ QDeclarativeGridView::~QDeclarativeGridView() \qmlproperty model GridView::model This property holds the model providing data for the grid. - The model provides a set of data that is used to create the items - for the view. For large or dynamic datasets the model is usually - provided by a C++ model object. The C++ model object must be a \l - {QAbstractItemModel} subclass, a VisualModel, or a simple list. + The model provides the set of data that is used to create the items + in the view. Models can be created directly in QML using \l ListModel, \l XmlListModel + or \l VisualItemModel, or provided by C++ model classes. If a C++ model class is + used, it must be a subclass of \l QAbstractItemModel or a simple list. \sa {qmlmodels}{Data Models} */ @@ -1079,11 +1239,11 @@ void QDeclarativeGridView::setModel(const QVariant &model) that is not needed for the normal display of the delegate in a \l Loader which can load additional elements when needed. - Note that the GridView will layout the items based on the size of the root item + The GridView will layout the items based on the size of the root item in the delegate. - Here is an example delegate: - \snippet doc/src/snippets/declarative/gridview/gridview.qml 0 + \note Delegates are instantiated as needed and may be destroyed at any time. + State should \e never be stored in a delegate. */ QDeclarativeComponent *QDeclarativeGridView::delegate() const { @@ -1157,8 +1317,7 @@ QDeclarativeItem *QDeclarativeGridView::currentItem() /*! \qmlproperty Item GridView::highlightItem - \c highlightItem holds the highlight item, which was created - from the \l highlight component. + This holds the highlight item created from the \l highlight component. The highlightItem is managed by the view unless \l highlightFollowsCurrentItem is set to false. @@ -1189,13 +1348,10 @@ int QDeclarativeGridView::count() const \qmlproperty Component GridView::highlight This property holds the component to use as the highlight. - An instance of the highlight component will be created for each view. - The geometry of the resultant component instance will be managed by the view + An instance of the highlight component is created for each view. + The geometry of the resulting component instance will be managed by the view so as to stay with the current item, unless the highlightFollowsCurrentItem property is false. - The below example demonstrates how to make a simple highlight: - \snippet doc/src/snippets/declarative/gridview/gridview.qml 1 - \sa highlightItem, highlightFollowsCurrentItem */ QDeclarativeComponent *QDeclarativeGridView::highlight() const @@ -1218,21 +1374,14 @@ void QDeclarativeGridView::setHighlight(QDeclarativeComponent *highlight) \qmlproperty bool GridView::highlightFollowsCurrentItem This property sets whether the highlight is managed by the view. - If highlightFollowsCurrentItem is true, the highlight will be moved smoothly - to follow the current item. If highlightFollowsCurrentItem is false, the - highlight will not be moved by the view, and must be implemented - by the highlight component, for example: - - \code - Component { - id: myHighlight - Rectangle { - id: wrapper; color: "lightsteelblue"; radius: 4; width: 320; height: 60 - SpringFollow on y { source: wrapper.GridView.view.currentItem.y; spring: 3; damping: 0.2 } - SpringFollow on x { source: wrapper.GridView.view.currentItem.x; spring: 3; damping: 0.2 } - } - } - \endcode + If this property is true, the highlight is moved smoothly + to follow the current item. Otherwise, the + highlight is not moved by the view, and any movement must be implemented + by the highlight. + + Here is a highlight with its motion defined by a \l {SpringFollow} item: + + \snippet doc/src/snippets/declarative/gridview/gridview.qml highlightFollowsCurrentItem */ bool QDeclarativeGridView::highlightFollowsCurrentItem() const { @@ -1290,32 +1439,30 @@ void QDeclarativeGridView::setHighlightMoveDuration(int duration) \qmlproperty real GridView::preferredHighlightEnd \qmlproperty enumeration GridView::highlightRangeMode - These properties set the preferred range of the highlight (current item) - within the view. - - Note that this is the correct way to influence where the - current item ends up when the view scrolls. For example, if you want the - currently selected item to be in the middle of the list, then set the - highlight range to be where the middle item would go. Then, when the view scrolls, - the currently selected item will be the item at that spot. This also applies to - when the currently selected item changes - it will scroll to within the preferred - highlight range. Furthermore, the behaviour of the current item index will occur - whether or not a highlight exists. - - If highlightRangeMode is set to \e GridView.ApplyRange the view will - attempt to maintain the highlight within the range, however - the highlight can move outside of the range at the ends of the list - or due to a mouse interaction. + These properties define the preferred range of the highlight (for the current item) + within the view. The \c preferredHighlightBegin value must be less than the + \c preferredHighlightEnd value. - If highlightRangeMode is set to \e GridView.StrictlyEnforceRange the highlight will never - move outside of the range. This means that the current item will change - if a keyboard or mouse action would cause the highlight to move - outside of the range. + These properties affect the position of the current item when the view is scrolled. + For example, if the currently selected item should stay in the middle of the + view when it is scrolled, set the \c preferredHighlightBegin and + \c preferredHighlightEnd values to the top and bottom coordinates of where the middle + item would be. If the \c currentItem is changed programmatically, the view will + automatically scroll so that the current item is in the middle of the view. + Furthermore, the behavior of the current item index will occur whether or not a + highlight exists. - The default value is \e GridView.NoHighlightRange. + Valid values for \c highlightRangeMode are: - Note that a valid range requires preferredHighlightEnd to be greater - than or equal to preferredHighlightBegin. + \list + \o GridView.ApplyRange - the view attempts to maintain the highlight within the range. + However, the highlight can move outside of the range at the ends of the view or due + to mouse interaction. + \o GridView.StrictlyEnforceRange - the highlight never moves outside of the range. + The current item changes if a keyboard or mouse action would cause the highlight to move + outside of the range. + \o GridView.NoHighlightRange - this is the default value. + \endlist */ qreal QDeclarativeGridView::preferredHighlightBegin() const { @@ -1370,10 +1517,12 @@ void QDeclarativeGridView::setHighlightRangeMode(HighlightRangeMode mode) \qmlproperty enumeration GridView::flow This property holds the flow of the grid. - Possible values are \c GridView.LeftToRight (default) and \c GridView.TopToBottom. + Possible values: - If \a flow is \c GridView.LeftToRight, the view will scroll vertically. - If \a flow is \c GridView.TopToBottom, the view will scroll horizontally. + \list + \o GridView.LeftToRight (default) - Items are laid out from left to right, and the view scrolls vertically + \o GridView.TopToBottom - Items are laid out from top to bottom, and the view scrolls horizontally + \endlist */ QDeclarativeGridView::Flow QDeclarativeGridView::flow() const { @@ -1405,8 +1554,9 @@ void QDeclarativeGridView::setFlow(Flow flow) \qmlproperty bool GridView::keyNavigationWraps This property holds whether the grid wraps key navigation - If this property is true then key presses to move off of one end of the grid will cause the - selection to jump to the other side. + If this is true, key navigation that would move the current item selection + past one end of the view instead wraps around and moves the selection to + the other end of the view. */ bool QDeclarativeGridView::isWrapEnabled() const { @@ -1463,7 +1613,7 @@ void QDeclarativeGridView::setCacheBuffer(int buffer) \qmlproperty int GridView::cellWidth \qmlproperty int GridView::cellHeight - These properties holds the width and height of each cell in the grid + These properties holds the width and height of each cell in the grid. The default cell size is 100x100. */ @@ -1503,14 +1653,14 @@ void QDeclarativeGridView::setCellHeight(int cellHeight) /*! \qmlproperty enumeration GridView::snapMode - This property determines where the view will settle following a drag or flick. - The allowed values are: + This property determines how the view scrolling will settle following a drag or flick. + The possible values are: \list - \o GridView.NoSnap (default) - the view will stop anywhere within the visible area. - \o GridView.SnapToRow - the view will settle with a row (or column for TopToBottom flow) + \o GridView.NoSnap (default) - the view stops anywhere within the visible area. + \o GridView.SnapToRow - the view settles with a row (or column for \c GridView.TopToBottom flow) aligned with the start of the view. - \o GridView.SnapOneRow - the view will settle no more than one row (or column for TopToBottom flow) + \o GridView.SnapOneRow - the view will settle no more than one row (or column for \c GridView.TopToBottom flow) away from the first visible row at the time the mouse button is released. This mode is particularly useful for moving one page at a time. \endlist @@ -1531,6 +1681,67 @@ void QDeclarativeGridView::setSnapMode(SnapMode mode) } } +/*! + \qmlproperty Component GridView::footer + This property holds the component to use as the footer. + + An instance of the footer component is created for each view. The + footer is positioned at the end of the view, after any items. + + \sa header +*/ +QDeclarativeComponent *QDeclarativeGridView::footer() const +{ + Q_D(const QDeclarativeGridView); + return d->footerComponent; +} + +void QDeclarativeGridView::setFooter(QDeclarativeComponent *footer) +{ + Q_D(QDeclarativeGridView); + if (d->footerComponent != footer) { + if (d->footer) { + delete d->footer; + d->footer = 0; + } + d->footerComponent = footer; + d->updateFooter(); + d->updateGrid(); + emit footerChanged(); + } +} + +/*! + \qmlproperty Component GridView::header + This property holds the component to use as the header. + + An instance of the header component is created for each view. The + header is positioned at the beginning of the view, before any items. + + \sa footer +*/ +QDeclarativeComponent *QDeclarativeGridView::header() const +{ + Q_D(const QDeclarativeGridView); + return d->headerComponent; +} + +void QDeclarativeGridView::setHeader(QDeclarativeComponent *header) +{ + Q_D(QDeclarativeGridView); + if (d->headerComponent != header) { + if (d->header) { + delete d->header; + d->header = 0; + } + d->headerComponent = header; + d->updateHeader(); + d->updateFooter(); + d->updateGrid(); + emit headerChanged(); + } +} + bool QDeclarativeGridView::event(QEvent *event) { Q_D(QDeclarativeGridView); @@ -1597,6 +1808,8 @@ qreal QDeclarativeGridView::minYExtent() const if (d->flow == QDeclarativeGridView::TopToBottom) return QDeclarativeFlickable::minYExtent(); qreal extent = -d->startPosition(); + if (d->header && d->visibleItems.count()) + extent += d->header->item->height(); if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { extent += d->highlightRangeStart; extent = qMax(extent, -(d->rowPosAt(0) + d->rowSize() - d->highlightRangeEnd)); @@ -1610,13 +1823,17 @@ qreal QDeclarativeGridView::maxYExtent() const if (d->flow == QDeclarativeGridView::TopToBottom) return QDeclarativeFlickable::maxYExtent(); qreal extent; - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + if (!d->model || !d->model->count()) { + extent = 0; + } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { extent = -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart); if (d->highlightRangeEnd != d->highlightRangeStart) extent = qMin(extent, -(d->endPosition() - d->highlightRangeEnd + 1)); } else { extent = -(d->endPosition() - height()); } + if (d->footer) + extent -= d->footer->item->height(); const qreal minY = minYExtent(); if (extent > minY) extent = minY; @@ -1629,6 +1846,8 @@ qreal QDeclarativeGridView::minXExtent() const if (d->flow == QDeclarativeGridView::LeftToRight) return QDeclarativeFlickable::minXExtent(); qreal extent = -d->startPosition(); + if (d->header && d->visibleItems.count()) + extent += d->header->item->width(); if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { extent += d->highlightRangeStart; extent = qMax(extent, -(d->rowPosAt(0) + d->rowSize() - d->highlightRangeEnd)); @@ -1642,13 +1861,17 @@ qreal QDeclarativeGridView::maxXExtent() const if (d->flow == QDeclarativeGridView::LeftToRight) return QDeclarativeFlickable::maxXExtent(); qreal extent; - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + if (!d->model || !d->model->count()) { + extent = 0; + } if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { extent = -(d->rowPosAt(d->model->count()-1) - d->highlightRangeStart); if (d->highlightRangeEnd != d->highlightRangeStart) extent = qMin(extent, -(d->endPosition() - d->highlightRangeEnd + 1)); } else { - extent = -(d->endPosition() - height()); + extent = -(d->endPosition() - width()); } + if (d->footer) + extent -= d->footer->item->width(); const qreal minX = minXExtent(); if (extent > minX) extent = minX; @@ -1789,22 +2012,22 @@ void QDeclarativeGridView::moveCurrentIndexRight() \a mode: \list - \o Beginning - position item at the top (or left for TopToBottom flow) of the view. - \o Center- position item in the center of the view. - \o End - position item at bottom (or right for horizontal orientation) of the view. - \o Visible - if any part of the item is visible then take no action, otherwise + \o GridView.Beginning - position item at the top (or left for \c GridView.TopToBottom flow) of the view. + \o GridView.Center - position item in the center of the view. + \o GridView.End - position item at bottom (or right for horizontal orientation) of the view. + \o GridView.Visible - if any part of the item is visible then take no action, otherwise bring the item into view. - \o Contain - ensure the entire item is visible. If the item is larger than - the view the item is positioned at the top (or left for TopToBottom flow) of the view. + \o GridView.Contain - ensure the entire item is visible. If the item is larger than + the view the item is positioned at the top (or left for \c GridView.TopToBottom flow) of the view. \endlist If positioning the view at the index would cause empty space to be displayed at the beginning or end of the view, the view will be positioned at the boundary. - It is not recommended to use contentX or contentY to position the view + It is not recommended to use \l {Flickable::}{contentX} or \l {Flickable::}{contentY} to position the view at a particular index. This is unreliable since removing items from the start of the view does not cause all other items to be repositioned. - The correct way to bring an item into view is with positionViewAtIndex. + The correct way to bring an item into view is with \c positionViewAtIndex. */ void QDeclarativeGridView::positionViewAtIndex(int index, int mode) { diff --git a/src/declarative/graphicsitems/qdeclarativegridview_p.h b/src/declarative/graphicsitems/qdeclarativegridview_p.h index 2bf154c..021aad9 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview_p.h +++ b/src/declarative/graphicsitems/qdeclarativegridview_p.h @@ -80,6 +80,9 @@ class Q_DECLARATIVE_EXPORT QDeclarativeGridView : public QDeclarativeFlickable Q_PROPERTY(SnapMode snapMode READ snapMode WRITE setSnapMode NOTIFY snapModeChanged) + Q_PROPERTY(QDeclarativeComponent *header READ header WRITE setHeader NOTIFY headerChanged) + Q_PROPERTY(QDeclarativeComponent *footer READ footer WRITE setFooter NOTIFY footerChanged) + Q_ENUMS(HighlightRangeMode) Q_ENUMS(SnapMode) Q_ENUMS(Flow) @@ -142,6 +145,12 @@ public: SnapMode snapMode() const; void setSnapMode(SnapMode mode); + QDeclarativeComponent *footer() const; + void setFooter(QDeclarativeComponent *); + + QDeclarativeComponent *header() const; + void setHeader(QDeclarativeComponent *); + enum PositionMode { Beginning, Center, End, Visible, Contain }; Q_INVOKABLE void positionViewAtIndex(int index, int mode); @@ -172,6 +181,8 @@ Q_SIGNALS: void keyNavigationWrapsChanged(); void cacheBufferChanged(); void snapModeChanged(); + void headerChanged(); + void footerChanged(); protected: virtual bool event(QEvent *event); diff --git a/src/declarative/graphicsitems/qdeclarativeimage.cpp b/src/declarative/graphicsitems/qdeclarativeimage.cpp index 4593cf8..ec08517 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage.cpp +++ b/src/declarative/graphicsitems/qdeclarativeimage.cpp @@ -83,6 +83,8 @@ QT_BEGIN_NAMESPACE that images which do not form part of the user interface have their size bounded via the \l sourceSize property. This is especially important for content that is loaded from external sources or provided by the user. + + \sa {declarative/imageelements/image}{Image example} */ /*! @@ -95,7 +97,7 @@ QT_BEGIN_NAMESPACE Image { source: "pics/star.png" } \endqml - A QDeclarativeImage object can be instantiated in Qml using the tag \l Image. + A QDeclarativeImage object can be instantiated in QML using the tag \l Image. */ QDeclarativeImage::QDeclarativeImage(QDeclarativeItem *parent) @@ -275,11 +277,6 @@ qreal QDeclarativeImage::paintedHeight() const \o Image.Error - an error occurred while loading the image \endlist - Note that a change in the status property does not cause anything to happen - (although it reflects what has happened with the image internally). If you wish - to react to the change in status you need to do it yourself, for example in one - of the following ways: - Use this status to provide an update or respond to the status change in some way. For example, you could: diff --git a/src/declarative/graphicsitems/qdeclarativeimage_p.h b/src/declarative/graphicsitems/qdeclarativeimage_p.h index 5ea700d..fa5b2a9 100644 --- a/src/declarative/graphicsitems/qdeclarativeimage_p.h +++ b/src/declarative/graphicsitems/qdeclarativeimage_p.h @@ -87,8 +87,6 @@ protected: QDeclarativeImage(QDeclarativeImagePrivate &dd, QDeclarativeItem *parent); void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry); void pixmapChange(); - -protected Q_SLOTS: void updatePaintedGeometry(); private: diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 134bd6d..18806e7 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -86,8 +86,8 @@ QT_BEGIN_NAMESPACE The Transform elements let you create and control advanced transformations that can be configured independently using specialized properties. - You can assign any number of Transform elements to an Item. Each Transform is applied in order, - one at a time, to the Item it's assigned to. + You can assign any number of Transform elements to an \l Item. Each Transform is applied in order, + one at a time. */ /*! @@ -97,9 +97,11 @@ QT_BEGIN_NAMESPACE The Translate object provides independent control over position in addition to the Item's x and y properties. - The following example moves the Y axis of the Rectangles while still allowing the Row element + The following example moves the Y axis of the \l Rectangle elements while still allowing the \l Row element to lay the items out as if they had not been transformed: \qml + import Qt 4.7 + Row { Rectangle { width: 100; height: 100 @@ -113,6 +115,8 @@ QT_BEGIN_NAMESPACE } } \endqml + + \image translate.png */ /*! @@ -130,9 +134,9 @@ QT_BEGIN_NAMESPACE /*! \qmlclass Scale QGraphicsScale \since 4.7 - \brief The Scale object provides a way to scale an Item. + \brief The Scale element provides a way to scale an Item. - The Scale object gives more control over scaling than using Item's scale property. Specifically, + The Scale element gives more control over scaling than using \l Item's \l{Item::scale}{scale} property. Specifically, it allows a different scale for the x and y axes, and allows the scale to be relative to an arbitrary point. @@ -144,6 +148,8 @@ QT_BEGIN_NAMESPACE transform: Scale { origin.x: 25; origin.y: 25; xScale: 3} } \endqml + + \sa Rotate, Translate */ /*! @@ -171,7 +177,7 @@ QT_BEGIN_NAMESPACE \since 4.7 \brief The Rotation object provides a way to rotate an Item. - The Rotation object gives more control over rotation than using Item's rotation property. + The Rotation object gives more control over rotation than using \l Item's \l{Item::rotation}{rotation} property. Specifically, it allows (z axis) rotation to be relative to an arbitrary point. The following example rotates a Rectangle around its interior point 25, 25: @@ -722,7 +728,7 @@ void QDeclarativeKeyNavigationAttached::keyReleased(QKeyEvent *event, bool post) The signal properties have a \l KeyEvent parameter, named \e event which contains details of the event. If a key is handled \e event.accepted should be set to true to prevent the - event from propagating up the item heirarchy. + event from propagating up the item hierarchy. \code Item { @@ -1629,7 +1635,7 @@ void QDeclarativeItemPrivate::data_append(QDeclarativeListProperty<QObject> *pro QObject *QDeclarativeItemPrivate::resources_at(QDeclarativeListProperty<QObject> *prop, int index) { - QObjectList children = prop->object->children(); + const QObjectList children = prop->object->children(); if (index < children.count()) return children.at(index); else @@ -2387,6 +2393,28 @@ void QDeclarativeItem::forceFocus() } } + +/*! + \qmlmethod Item::childAt(real x, real y) + + Returns the visible child item at point (\a x, \a y), which is in this + item's coordinate system, or \c null if there is no such item. + */ +QDeclarativeItem *QDeclarativeItem::childAt(qreal x, qreal y) const +{ + const QList<QGraphicsItem *> children = childItems(); + for (int i = children.count()-1; i >= 0; --i) { + if (QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(i))) { + if (child->isVisible() && child->x() <= x + && child->x() + child->width() >= x + && child->y() <= y + && child->y() + child->height() >= y) + return child; + } + } + return 0; +} + void QDeclarativeItemPrivate::focusChanged(bool flag) { Q_Q(QDeclarativeItem); diff --git a/src/declarative/graphicsitems/qdeclarativeitem.h b/src/declarative/graphicsitems/qdeclarativeitem.h index 77e316b..4f420f8 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.h +++ b/src/declarative/graphicsitems/qdeclarativeitem.h @@ -148,6 +148,7 @@ public: Q_INVOKABLE QScriptValue mapFromItem(const QScriptValue &item, qreal x, qreal y) const; Q_INVOKABLE QScriptValue mapToItem(const QScriptValue &item, qreal x, qreal y) const; Q_INVOKABLE void forceFocus(); + Q_INVOKABLE QDeclarativeItem *childAt(qreal x, qreal y) const; Q_SIGNALS: void childrenChanged(); diff --git a/src/declarative/graphicsitems/qdeclarativelayoutitem.cpp b/src/declarative/graphicsitems/qdeclarativelayoutitem.cpp index 4add66d..38d5f59 100644 --- a/src/declarative/graphicsitems/qdeclarativelayoutitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativelayoutitem.cpp @@ -58,7 +58,10 @@ QT_BEGIN_NAMESPACE taking its size hints into account, and you can propagate this to the other elements in your UI via anchors and bindings. This is a QGraphicsLayoutItem subclass, and its properties merely expose the QGraphicsLayoutItem functionality to QML. - See the QGraphicsLayoutItem documentation for further details. + + The \l{declarative/cppextensions/qgraphicslayouts/layoutitem}{LayoutItem example} + demonstrates how a LayoutItem can be used within a \l{Graphics View Framework}{Graphics View} + scene. */ /*! diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 78c56d6..dcf18af 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -427,6 +427,12 @@ public: scheduleLayout(); } } + if ((header && header->item == item) || (footer && footer->item == item)) { + updateHeader(); + updateFooter(); + } + if (currentItem && currentItem->item == item) + updateHighlight(); if (trackedItem && trackedItem->item == item) q->trackedPositionChanged(); } @@ -731,7 +737,7 @@ void QDeclarativeListViewPrivate::layout() { Q_Q(QDeclarativeListView); layoutScheduled = false; - if (!isValid()) { + if (!isValid() && !visibleItems.count()) { clear(); setPosition(0); return; @@ -1043,6 +1049,8 @@ void QDeclarativeListViewPrivate::updateFooter() QDeclarative_setParent_noEvent(item, q->viewport()); item->setParentItem(q->viewport()); item->setZValue(1); + QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); + itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); footer = new FxListItem(item, q); } } @@ -1081,6 +1089,8 @@ void QDeclarativeListViewPrivate::updateHeader() QDeclarative_setParent_noEvent(item, q->viewport()); item->setParentItem(q->viewport()); item->setZValue(1); + QDeclarativeItemPrivate *itemPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(item)); + itemPrivate->addItemChangeListener(this, QDeclarativeItemPrivate::Geometry); header = new FxListItem(item, q); if (visibleItems.isEmpty()) visiblePos = header->size(); @@ -1103,7 +1113,9 @@ void QDeclarativeListViewPrivate::updateHeader() void QDeclarativeListViewPrivate::fixupPosition() { - moveReason = Other; + if ((haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) + || snapMode != QDeclarativeListView::NoSnap) + moveReason = Other; if (orient == QDeclarativeListView::Vertical) fixupY(); else @@ -1112,7 +1124,6 @@ void QDeclarativeListViewPrivate::fixupPosition() void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal maxExtent) { - Q_Q(QDeclarativeListView); if ((orient == QDeclarativeListView::Horizontal && &data == &vData) || (orient == QDeclarativeListView::Vertical && &data == &hData)) return; @@ -1120,7 +1131,41 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m int oldDuration = fixupDuration; fixupDuration = moveReason == Mouse ? fixupDuration : 0; - if (haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) { + if (snapMode != QDeclarativeListView::NoSnap) { + FxListItem *topItem = snapItemAt(position()+highlightRangeStart); + FxListItem *bottomItem = snapItemAt(position()+highlightRangeEnd); + qreal pos; + if (topItem && bottomItem && haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) { + qreal topPos = qMin(topItem->position() - highlightRangeStart, -maxExtent); + qreal bottomPos = qMax(bottomItem->position() - highlightRangeEnd, -minExtent); + pos = qAbs(data.move + topPos) < qAbs(data.move + bottomPos) ? topPos : bottomPos; + } else if (topItem) { + pos = qMax(qMin(topItem->position() - highlightRangeStart, -maxExtent), -minExtent); + } else if (bottomItem) { + pos = qMax(qMin(bottomItem->position() - highlightRangeStart, -maxExtent), -minExtent); + } else { + fixupDuration = oldDuration; + return; + } + if (currentItem && haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) { + updateHighlight(); + qreal currPos = currentItem->position(); + if (pos < currPos + currentItem->size() - highlightRangeEnd) + pos = currPos + currentItem->size() - highlightRangeEnd; + if (pos > currPos - highlightRangeStart) + pos = currPos - highlightRangeStart; + } + + qreal dist = qAbs(data.move + pos); + if (dist > 0) { + timeline.reset(data.move); + if (fixupDuration) + timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); + else + timeline.set(data.move, -pos); + vTime = timeline.time(); + } + } else if (haveHighlightRange && highlightRange == QDeclarativeListView::StrictlyEnforceRange) { if (currentItem) { updateHighlight(); qreal pos = currentItem->position(); @@ -1132,30 +1177,13 @@ void QDeclarativeListViewPrivate::fixup(AxisData &data, qreal minExtent, qreal m timeline.reset(data.move); if (viewPos != position()) { - if (fixupDuration) { + if (fixupDuration) timeline.move(data.move, -viewPos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - } else { - data.move.setValue(-viewPos); - q->viewportMoved(); - } + else + timeline.set(data.move, -viewPos); } vTime = timeline.time(); } - } else if (snapMode != QDeclarativeListView::NoSnap) { - if (FxListItem *item = snapItemAt(position())) { - qreal pos = qMin(item->position() - highlightRangeStart, -maxExtent); - qreal dist = qAbs(data.move + pos); - if (dist > 0) { - timeline.reset(data.move); - if (fixupDuration) { - timeline.move(data.move, -pos, QEasingCurve(QEasingCurve::InOutQuad), fixupDuration/2); - } else { - data.move.setValue(-pos); - q->viewportMoved(); - } - vTime = timeline.time(); - } - } } else { QDeclarativeFlickablePrivate::fixup(data, minExtent, maxExtent); } @@ -1325,13 +1353,11 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m Another component can display this model data in a ListView, like this: - \table - \row - \o \snippet doc/src/snippets/declarative/listview/listview.qml import + \snippet doc/src/snippets/declarative/listview/listview.qml import \codeline \snippet doc/src/snippets/declarative/listview/listview.qml classdocs simple - \o \image listview-simple.png - \endtable + + \image listview-simple.png Here, the ListView creates a \c ContactModel component for its model, and a \l Text element for its delegate. The view will create a new \l Text component for each item in the model. Notice @@ -1342,19 +1368,18 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m with a blue \l Rectangle using the \l highlight property, and \c focus is set to \c true to enable keyboard navigation for the list view. - \table - \row - \o \snippet doc/src/snippets/declarative/listview/listview.qml classdocs advanced - \o \image listview-highlight.png - \endtable + \snippet doc/src/snippets/declarative/listview/listview.qml classdocs advanced + \image listview-highlight.png - In a ListView, delegates are instantiated as needed and may be destroyed at any time. + In a GridView, delegates are instantiated as needed and may be destroyed at any time. State should \e never be stored in a delegate. \note Views do not enable \e clip automatically. If the view is not clipped by another item or the screen, it will be necessary to set \e {clip: true} in order to have the out of view items clipped nicely. + + \sa ListModel, GridView */ QDeclarativeListView::QDeclarativeListView(QDeclarativeItem *parent) @@ -1466,13 +1491,15 @@ void QDeclarativeListView::setModel(const QVariant &model) disconnect(d->model, SIGNAL(destroyingItem(QDeclarativeItem*)), this, SLOT(destroyingItem(QDeclarativeItem*))); } d->clear(); + QDeclarativeVisualModel *oldModel = d->model; + d->model = 0; d->setPosition(0); d->modelVariant = model; QObject *object = qvariant_cast<QObject*>(model); QDeclarativeVisualModel *vim = 0; if (object && (vim = qobject_cast<QDeclarativeVisualModel *>(object))) { if (d->ownModel) { - delete d->model; + delete oldModel; d->ownModel = false; } d->model = vim; @@ -1480,6 +1507,8 @@ void QDeclarativeListView::setModel(const QVariant &model) if (!d->ownModel) { d->model = new QDeclarativeVisualDataModel(qmlContext(this), this); d->ownModel = true; + } else { + d->model = oldModel; } if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model)) dataModel->setModel(model); @@ -1630,7 +1659,7 @@ int QDeclarativeListView::count() const This property holds the component to use as the highlight. An instance of the highlight component is created for each list. - The geometry of the resultant component instance is managed by the list + The geometry of the resulting component instance is managed by the list so as to stay with the current item, unless the highlightFollowsCurrentItem property is false. @@ -1663,7 +1692,7 @@ void QDeclarativeListView::setHighlight(QDeclarativeComponent *highlight) highlight is not moved by the view, and any movement must be implemented by the highlight. - Here is a highlight with its motion defined by the a \l {SpringFollow} item: + Here is a highlight with its motion defined by a \l {SpringFollow} item: \snippet doc/src/snippets/declarative/listview/listview.qml highlightFollowsCurrentItem @@ -2038,8 +2067,8 @@ void QDeclarativeListView::setHighlightResizeDuration(int duration) /*! \qmlproperty enumeration ListView::snapMode - This property determines where the view's scrolling behavior stops following a drag or flick. - The allowed values are: + This property determines how the view scrolling will settle following a drag or flick. + The possible values are: \list \o ListView.NoSnap (default) - the view stops anywhere within the visible area. @@ -2071,6 +2100,15 @@ void QDeclarativeListView::setSnapMode(SnapMode mode) } } +/*! + \qmlproperty Component ListView::footer + This property holds the component to use as the footer. + + An instance of the footer component is created for each view. The + footer is positioned at the end of the view, after any items. + + \sa header +*/ QDeclarativeComponent *QDeclarativeListView::footer() const { Q_D(const QDeclarativeListView); @@ -2094,6 +2132,15 @@ void QDeclarativeListView::setFooter(QDeclarativeComponent *footer) } } +/*! + \qmlproperty Component ListView::header + This property holds the component to use as the header. + + An instance of the header component is created for each view. The + header is positioned at the beginning of the view, before any items. + + \sa footer +*/ QDeclarativeComponent *QDeclarativeListView::header() const { Q_D(const QDeclarativeListView); @@ -2219,7 +2266,9 @@ qreal QDeclarativeListView::maxYExtent() const if (d->orient == QDeclarativeListView::Horizontal) return height(); if (d->maxExtentDirty) { - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + if (!d->model || !d->model->count()) { + d->maxExtent = 0; + } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { d->maxExtent = -(d->positionAt(d->model->count()-1) - d->highlightRangeStart); if (d->highlightRangeEnd != d->highlightRangeStart) d->maxExtent = qMin(d->maxExtent, -(d->endPosition() - d->highlightRangeEnd + 1)); @@ -2261,7 +2310,9 @@ qreal QDeclarativeListView::maxXExtent() const if (d->orient == QDeclarativeListView::Vertical) return width(); if (d->maxExtentDirty) { - if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { + if (!d->model || !d->model->count()) { + d->maxExtent = 0; + } else if (d->haveHighlightRange && d->highlightRange == StrictlyEnforceRange) { d->maxExtent = -(d->positionAt(d->model->count()-1) - d->highlightRangeStart); if (d->highlightRangeEnd != d->highlightRangeStart) d->maxExtent = qMin(d->maxExtent, -(d->endPosition() - d->highlightRangeEnd + 1)); diff --git a/src/declarative/graphicsitems/qdeclarativeloader.cpp b/src/declarative/graphicsitems/qdeclarativeloader.cpp index 4995baf..25b1119 100644 --- a/src/declarative/graphicsitems/qdeclarativeloader.cpp +++ b/src/declarative/graphicsitems/qdeclarativeloader.cpp @@ -112,30 +112,48 @@ void QDeclarativeLoaderPrivate::initResize() \inherits Item \brief The Loader item allows dynamically loading an Item-based - subtree from a QML URL or Component. + subtree from a URL or Component. - Loader instantiates an item from a component. The component to - instantiate may be specified directly by the \c sourceComponent - property, or loaded from a URL via the \c source property. + The Loader element instantiates an item from a component. The component to + be instantiated may be specified directly by the \l sourceComponent + property, or loaded from a URL via the \l source property. + + Loader can be used to delay the creation of a component until it is required. + For example, this loads "Page1.qml" as a component into the \l Loader element + when the \l MouseArea is clicked: - It is also an effective means of delaying the creation of a component - until it is required: \code - Loader { id: pageLoader } - Rectangle { - MouseArea { anchors.fill: parent; onClicked: pageLoader.source = "Page1.qml" } + import Qt 4.7 + + Item { + width: 200; height: 200 + + MouseArea { + anchors.fill: parent + onClicked: pageLoader.source = "Page1.qml" + } + + Loader { id: pageLoader } } \endcode + Note that Loader is like any other graphical Item and needs to be positioned + and sized accordingly to become visible. When a component is loaded, the + Loader is automatically resized to the size of the component. + If the Loader source is changed, any previous items instantiated - will be destroyed. Setting \c source to an empty string, or setting + will be destroyed. Setting \l source to an empty string, or setting sourceComponent to \e undefined will destroy the currently instantiated items, freeing resources and leaving the Loader empty. For example: \code pageLoader.source = "" + \endcode + or + + \code pageLoader.sourceComponent = undefined \endcode @@ -215,7 +233,7 @@ void QDeclarativeLoader::setSource(const QUrl &url) /*! \qmlproperty Component Loader::sourceComponent - The sourceComponent property holds the \l{Component} to instantiate. + This property holds the \l{Component} to instantiate. \qml Item { @@ -229,6 +247,8 @@ void QDeclarativeLoader::setSource(const QUrl &url) } \endqml + Note this value must hold a \l Component object; it cannot be a \l Item. + \sa source, progress */ @@ -340,19 +360,31 @@ void QDeclarativeLoaderPrivate::_q_sourceLoaded() \o Loader.Error - an error occurred while loading the QML source \endlist - Note that a change in the status property does not cause anything to happen - (although it reflects what has happened to the loader internally). If you wish - to react to the change in status you need to do it yourself, for example in one - of the following ways: - \list - \o Create a state, so that a state change occurs, e.g. State{name: 'loaded'; when: loader.status = Loader.Ready;} - \o Do something inside the onLoaded signal handler, e.g. Loader{id: loader; onLoaded: console.log('Loaded');} - \o Bind to the status variable somewhere, e.g. Text{text: if(loader.status!=Loader.Ready){'Not Loaded';}else{'Loaded';}} - \endlist - \sa progress + Use this status to provide an update or respond to the status change in some way. + For example, you could: + + \e {Trigger a state change:} + \qml + State { name: 'loaded'; when: loader.status = Loader.Ready } + \endqml + + \e {Implement an \c onStatusChanged signal handler:} + \qml + Loader { + id: loader + onStatusChanged: if (loader.status == Loader.Ready) console.log('Loaded') + } + \endqml + + \e {Bind to the status value:} + \qml + Text { text: loader.status != Loader.Ready ? 'Not Loaded' : 'Loaded' } + \endqml Note that if the source is a local file, the status will initially be Ready (or Error). While there will be no onStatusChanged signal in that case, the onLoaded will still be invoked. + + \sa progress */ QDeclarativeLoader::Status QDeclarativeLoader::status() const @@ -379,7 +411,7 @@ void QDeclarativeLoader::componentComplete() /*! \qmlsignal Loader::onLoaded() - This handler is called when the \l status becomes Loader.Ready, or on successful + This handler is called when the \l status becomes \c Loader.Ready, or on successful initial load. */ diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index 1947c00..c4956df 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -172,17 +172,21 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate() A MouseArea is typically used in conjunction with a visible item, where the MouseArea effectively 'proxies' mouse handling for that - item. For example, we can put a MouseArea in a Rectangle that changes - the Rectangle color to red when clicked: - \snippet doc/src/snippets/declarative/mouseregion.qml 0 + item. For example, we can put a MouseArea in a \l Rectangle that changes + the \l Rectangle color to red when clicked: + + \snippet doc/src/snippets/declarative/mousearea.qml import + \codeline + \snippet doc/src/snippets/declarative/mousearea.qml intro Many MouseArea signals pass a \l {MouseEvent}{mouse} parameter that contains additional information about the mouse event, such as the position, button, and any key modifiers. - Below we have the previous - example extended so as to give a different color when you right click. - \snippet doc/src/snippets/declarative/mouseregion.qml 1 + Here is an extension of the previous example that produces a different + color when the area is right clicked: + + \snippet doc/src/snippets/declarative/mousearea.qml intro-extended For basic key handling, see the \l {Keys}{Keys attached property}. @@ -238,7 +242,7 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate() releasing is also considered a click). The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y - position of the release of the click, and whether the click wasHeld. + position of the release of the click, and whether the click was held. The \e accepted property of the MouseEvent parameter is ignored in this handler. */ @@ -262,7 +266,7 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate() This handler is called when there is a release. The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y - position of the release of the click, and whether the click wasHeld. + position of the release of the click, and whether the click was held. The \e accepted property of the MouseEvent parameter is ignored in this handler. */ @@ -282,7 +286,7 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate() This handler is called when there is a double-click (a press followed by a release followed by a press). The \l {MouseEvent}{mouse} parameter provides information about the click, including the x and y - position of the release of the click, and whether the click wasHeld. + position of the release of the click, and whether the click was held. The \e accepted property of the MouseEvent parameter is ignored in this handler. */ @@ -301,12 +305,12 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate() /*! \internal \class QDeclarativeMouseArea - \brief The QDeclarativeMouseArea class provides a simple mouse handling abstraction for use within Qml. + \brief The QDeclarativeMouseArea class provides a simple mouse handling abstraction for use within QML. All QDeclarativeItem derived classes can do mouse handling but the QDeclarativeMouseArea class exposes mouse handling data as properties and tracks flicking and dragging of the mouse. - A QDeclarativeMouseArea object can be instantiated in Qml using the tag \l MouseArea. + A QDeclarativeMouseArea object can be instantiated in QML using the tag \l MouseArea. */ QDeclarativeMouseArea::QDeclarativeMouseArea(QDeclarativeItem *parent) : QDeclarativeItem(*(new QDeclarativeMouseAreaPrivate), parent) @@ -328,10 +332,10 @@ QDeclarativeMouseArea::~QDeclarativeMouseArea() while a button is pressed, and will remain valid as long as the button is held even if the mouse is moved outside the area. - If hoverEnabled is true then these properties will be valid: + If hoverEnabled is true then these properties will be valid when: \list - \i when no button is pressed, but the mouse is within the MouseArea (containsMouse is true). - \i if a button is pressed and held, even if it has since moved out of the area. + \i no button is pressed, but the mouse is within the MouseArea (containsMouse is true). + \i a button is pressed and held, even if it has since moved out of the area. \endlist The coordinates are relative to the MouseArea. @@ -378,18 +382,7 @@ void QDeclarativeMouseArea::setEnabled(bool a) \endlist The code below displays "right" when the right mouse buttons is pressed: - \code - Text { - text: mr.pressedButtons & Qt.RightButton ? "right" : "" - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - MouseArea { - id: mr - acceptedButtons: Qt.LeftButton | Qt.RightButton - anchors.fill: parent - } - } - \endcode + \snippet doc/src/snippets/declarative/mousearea.qml mousebuttons \sa acceptedButtons */ @@ -417,7 +410,7 @@ void QDeclarativeMouseArea::mousePressEvent(QGraphicsSceneMouseEvent *event) setHovered(true); d->startScene = event->scenePos(); // we should only start timer if pressAndHold is connected to. - if (d->isConnected("pressAndHold(QDeclarativeMouseEvent*)")) + if (d->isPressAndHoldConnected()) d->pressAndHoldTimer.start(PressAndHoldDelay, this); setKeepMouseGrab(false); event->setAccepted(setPressed(true)); @@ -705,7 +698,7 @@ void QDeclarativeMouseArea::setHovered(bool h) MouseArea { acceptedButtons: Qt.LeftButton | Qt.RightButton } \endcode - The default is to accept the Left button. + The default value is \c Qt.LeftButton. */ Qt::MouseButtons QDeclarativeMouseArea::acceptedButtons() const { @@ -765,17 +758,19 @@ QDeclarativeDrag *QDeclarativeMouseArea::drag() \qmlproperty real MouseArea::drag.minimumY \qmlproperty real MouseArea::drag.maximumY - drag provides a convenient way to make an item draggable. + \c drag provides a convenient way to make an item draggable. \list - \i \c target specifies the item to drag. - \i \c active specifies if the target item is being currently dragged. - \i \c axis specifies whether dragging can be done horizontally (Drag.XAxis), vertically (Drag.YAxis), or both (Drag.XandYAxis) - \i the minimum and maximum properties limit how far the target can be dragged along the corresponding axes. + \i \c drag.target specifies the item to drag. + \i \c drag.active specifies if the target item is currently being dragged. + \i \c drag.axis specifies whether dragging can be done horizontally (\c Drag.XAxis), vertically (\c Drag.YAxis), or both (\c Drag.XandYAxis) + \i \c drag.minimum and \c drag.maximum limit how far the target can be dragged along the corresponding axes. \endlist - The following example uses drag to reduce the opacity of an image as it moves to the right: - \snippet doc/src/snippets/declarative/drag.qml 0 + The following example displays an image that can be dragged along the X-axis. The opacity + of the image is reduced when it is dragged to the right. + + \snippet doc/src/snippets/declarative/mousearea.qml drag */ QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h index 4e909ff..3d7bd1e 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativemousearea_p_p.h @@ -88,9 +88,9 @@ public: lastModifiers = event->modifiers(); } - bool isConnected(const char *signal) { + bool isPressAndHoldConnected() { Q_Q(QDeclarativeMouseArea); - int idx = QObjectPrivate::get(q)->signalIndex(signal); + static int idx = QObjectPrivate::get(q)->signalIndex("pressAndHold(QDeclarativeMouseEvent*)"); return QObjectPrivate::get(q)->isSignalConnected(idx); } diff --git a/src/declarative/graphicsitems/qdeclarativepath.cpp b/src/declarative/graphicsitems/qdeclarativepath.cpp index 141a938..a904869 100644 --- a/src/declarative/graphicsitems/qdeclarativepath.cpp +++ b/src/declarative/graphicsitems/qdeclarativepath.cpp @@ -628,7 +628,7 @@ void QDeclarativePathLine::addToPath(QPainterPath &path) \qml Path { startX: 0; startY: 0 - PathQuad x: 200; y: 0; controlX: 100; controlY: 150 } + PathQuad { x: 200; y: 0; controlX: 100; controlY: 150 } } \endqml \endtable @@ -713,8 +713,9 @@ void QDeclarativePathQuad::addToPath(QPainterPath &path) Path { startX: 20; startY: 0 PathCubic { - x: 180; y: 0; control1X: -10; control1Y: 90 - control2X: 210; control2Y: 90 + x: 180; y: 0 + control1X: -10; control1Y: 90 + control2X: 210; control2Y: 90 } } \endqml diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index 448ec06..0c2d249 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -310,11 +310,21 @@ void QDeclarativePathViewPrivate::regenerate() \brief The PathView element lays out model-provided items on a path. \inherits Item - The model is typically provided by a QAbstractListModel "C++ model object", but can also be created directly in QML. + A PathView displays data from models created from built-in QML elements like ListModel + and XmlListModel, or custom model classes defined in C++ that inherit from + QAbstractListModel. + A ListView has a \l model, which defines the data to be displayed, and + a \l delegate, which defines how the data should be displayed. The \l delegate is instantiated for each item on the \l path. The items may be flicked to move them along the path. + For example, if there is a simple list model defined in a file \c ContactModel.qml like this: + + \snippet doc/src/snippets/declarative/pathview/ContactModel.qml 0 + + This data can be represented as a PathView, like this: + \snippet doc/src/snippets/declarative/pathview/pathview.qml 0 \image pathview.gif @@ -348,6 +358,13 @@ QDeclarativePathView::~QDeclarativePathView() } /*! + \qmlattachedproperty PathView PathView::view + This attached property holds the view that manages this delegate instance. + + It is attached to each instance of the delegate. +*/ + +/*! \qmlattachedproperty bool PathView::onPath This attached property holds whether the item is currently on the path. @@ -885,6 +902,7 @@ void QDeclarativePathView::setPathItemCount(int i) if (i < 1) i = 1; d->pathItems = i; + d->updateMappedRange(); if (d->isValid() && isComponentComplete()) { d->regenerate(); } diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp index 8796e63..ad61bab 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp +++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp @@ -219,6 +219,7 @@ void QDeclarativeBasePositioner::prePositioning() QDeclarativeItem *child = qobject_cast<QDeclarativeItem *>(children.at(ii)); if (!child) continue; + QDeclarativeItemPrivate *childPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(child)); PositionedItem *item = 0; PositionedItem posItem(child); int wIdx = oldItems.find(posItem); @@ -227,11 +228,13 @@ void QDeclarativeBasePositioner::prePositioning() positionedItems.append(posItem); item = &positionedItems[positionedItems.count()-1]; item->isNew = true; - if (child->opacity() <= 0.0 || !child->isVisible()) + if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden) item->isVisible = false; } else { item = &oldItems[wIdx]; - if (child->opacity() <= 0.0 || !child->isVisible()) { + // Items are only omitted from positioning if they are explicitly hidden + // i.e. their positioning is not affected if an ancestor is hidden. + if (child->opacity() <= 0.0 || childPrivate->explicitlyHidden) { item->isVisible = false; } else if (!item->isVisible) { item->isVisible = true; @@ -299,10 +302,16 @@ void QDeclarativeBasePositioner::finishApplyTransitions() d->moveActions.clear(); } +static inline bool isInvisible(QDeclarativeItem *child) +{ + QDeclarativeItemPrivate *childPrivate = static_cast<QDeclarativeItemPrivate*>(QGraphicsItemPrivate::get(child)); + return child->opacity() == 0.0 || childPrivate->explicitlyHidden || !child->width() || !child->height(); +} + /*! \qmlclass Column QDeclarativeColumn \since 4.7 - \brief The Column item lines up its children vertically. + \brief The Column item arranges its children vertically. \inherits Item The Column item positions its child items so that they are vertically @@ -346,8 +355,10 @@ Column { will not change. If you manually change the x or y properties in script, bind the x or y properties, use anchors on a child of a positioner, or have the height of a child depend on the position of a child, then the - positioner may exhibit strange behaviour. + positioner may exhibit strange behaviour. If you need to perform any of these + actions, consider positioning the items without the use of a Column. + \sa Row, {declarative/positioners}{Positioners example} */ /*! \qmlproperty Transition Column::add @@ -396,7 +407,7 @@ Column { spacing is the amount in pixels left empty between each adjacent item, and defaults to 0. - The below example places a Grid containing a red, a blue and a + The below example places a \l Grid containing a red, a blue and a green rectangle on a gray background. The area the grid positioner occupies is colored white. The top positioner has the default of no spacing, and the bottom positioner has its spacing set to 2. @@ -415,11 +426,6 @@ QDeclarativeColumn::QDeclarativeColumn(QDeclarativeItem *parent) { } -static inline bool isInvisible(QDeclarativeItem *child) -{ - return child->opacity() == 0.0 || !child->isVisible() || !child->width() || !child->height(); -} - void QDeclarativeColumn::doPositioning(QSizeF *contentSize) { int voffset = 0; @@ -468,17 +474,15 @@ void QDeclarativeColumn::reportConflictingAnchors() /*! \qmlclass Row QDeclarativeRow \since 4.7 - \brief The Row item lines up its children horizontally. + \brief The Row item arranges its children horizontally. \inherits Item The Row item positions its child items so that they are - horizontally aligned and not overlapping. Spacing can be added between the - items, and a margin around all items can also be added. It also provides for - transitions to be set when items are added, moved, or removed in the - positioner. Adding and removing apply both to items which are deleted or have - their position in the document changed so as to no longer be children of the - positioner, as well as to items which have their opacity set to or from zero - so as to appear or disappear. + horizontally aligned and not overlapping. + + Use \l spacing to set the spacing between items in a Row, and use the + \l add and \l move properties to set the transitions that should be applied + when items are added to, removed from, or re-positioned within the Row. The below example lays out differently shaped rectangles using a Row. \qml @@ -495,8 +499,10 @@ Row { will not change. If you manually change the x or y properties in script, bind the x or y properties, use anchors on a child of a positioner, or have the width of a child depend on the position of a child, then the - positioner may exhibit strange behaviour. + positioner may exhibit strange behaviour. If you need to perform any of these + actions, consider positioning the items without the use of a Row. + \sa Column, {declarative/positioners}{Positioners example} */ /*! \qmlproperty Transition Row::add @@ -504,12 +510,10 @@ Row { The transition will only be applied to the added item(s). Positioner transitions will only affect the position (x,y) of items. - Added can mean that either the object has been created or - reparented, and thus is now a child or the positioner, or that the + An object is considered to be added to the positioner if it has been + created or reparented and thus is now a child or the positioner, or if the object has had its opacity increased from zero, and thus is now visible. - - */ /*! \qmlproperty Transition Row::move @@ -540,7 +544,7 @@ Row { spacing is the amount in pixels left empty between each adjacent item, and defaults to 0. - The below example places a Grid containing a red, a blue and a + The below example places a \l Grid containing a red, a blue and a green rectangle on a gray background. The area the grid positioner occupies is colored white. The top positioner has the default of no spacing, and the bottom positioner has its spacing set to 2. @@ -610,18 +614,20 @@ void QDeclarativeRow::reportConflictingAnchors() \inherits Item The Grid item positions its child items so that they are - aligned in a grid and are not overlapping. Spacing can be added - between the items. It also provides for transitions to be set when items are + aligned in a grid and are not overlapping. + + Spacing can be added + between child items. It also provides for transitions to be set when items are added, moved, or removed in the positioner. Adding and removing apply both to items which are deleted or have their position in the document changed so as to no longer be children of the positioner, as well as to items which have their opacity set to or from zero so as to appear or disappear. - The Grid defaults to using four columns, and as many rows as - are necessary to fit all the child items. The number of rows - and/or the number of columns can be constrained by setting the rows - or columns properties. The grid positioner calculates a grid with + A Grid defaults to four columns, and as many rows as + are necessary to fit all child items. The number of rows + and/or the number of columns can be constrained by setting the \l rows + or \l columns properties. The grid positioner calculates a grid with rectangular cells of sufficient size to hold all items, and then places the items in the cells, going across then down, and positioning each item at the (0,0) corner of the cell. The below @@ -648,7 +654,10 @@ Grid { will not change. If you manually change the x or y properties in script, bind the x or y properties, use anchors on a child of a positioner, or have the width or height of a child depend on the position of a child, then the - positioner may exhibit strange behaviour. + positioner may exhibit strange behaviour. If you need to perform any of these + actions, consider positioning the items without the use of a Grid. + + \sa Flow, {declarative/positioners}{Positioners example} */ /*! \qmlproperty Transition Grid::add @@ -658,12 +667,10 @@ Grid { as that is all the positioners affect. To animate other property change you will have to do so based on how you have changed those properties. - Added can mean that either the object has been created or - reparented, and thus is now a child or the positioner, or that the + An object is considered to be added to the positioner if it has been + created or reparented and thus is now a child or the positioner, or if the object has had its opacity increased from zero, and thus is now visible. - - */ /*! \qmlproperty Transition Grid::move @@ -714,18 +721,16 @@ QDeclarativeGrid::QDeclarativeGrid(QDeclarativeItem *parent) : \qmlproperty int Grid::columns This property holds the number of columns in the grid. - When the columns property is set the Grid will always have - that many columns. Note that if you do not have enough items to - fill this many columns some columns will be of zero width. + If the grid does not have enough items to fill the specified + number of columns, some columns will be of zero width. */ /*! \qmlproperty int Grid::rows This property holds the number of rows in the grid. - When the rows property is set the Grid will always have that - many rows. Note that if you do not have enough items to fill this - many rows some rows will be of zero width. + If the grid does not have enough items to fill the specified + number of rows, some rows will be of zero width. */ void QDeclarativeGrid::setColumns(const int columns) @@ -750,12 +755,14 @@ void QDeclarativeGrid::setRows(const int rows) \qmlproperty enumeration Grid::flow This property holds the flow of the layout. - Possible values are \c Grid.LeftToRight (default) and \c Grid.TopToBottom. + Possible values are: - If \a flow is \c Grid.LeftToRight, the items are positioned next to - to each other from left to right, then wrapped to the next line. - If \a flow is \c Grid.TopToBottom, the items are positioned next to each - other from top to bottom, then wrapped to the next column. + \list + \o Grid.LeftToRight (default) - Items are positioned next to + to each other from left to right, then wrapped to the next line. + \o Grid.TopToBottom - Items are positioned next to each + other from top to bottom, then wrapped to the next column. + \endlist */ QDeclarativeGrid::Flow QDeclarativeGrid::flow() const { @@ -893,15 +900,20 @@ void QDeclarativeGrid::reportConflictingAnchors() /*! \qmlclass Flow QDeclarativeFlow \since 4.7 - \brief The Flow item lines up its children side by side, wrapping as necessary. + \brief The Flow item arranges its children side by side, wrapping as necessary. \inherits Item + The Flow item positions its child items so that they are side by side and are + not overlapping. + Note that the positioner assumes that the x and y positions of its children will not change. If you manually change the x or y properties in script, bind the x or y properties, use anchors on a child of a positioner, or have the width or height of a child depend on the position of a child, then the - positioner may exhibit strange behaviour. + positioner may exhibit strange behaviour. If you need to perform any of these + actions, consider positioning the items without the use of a Flow. + \sa Grid, {declarative/positioners}{Positioners example} */ /*! \qmlproperty Transition Flow::add @@ -909,9 +921,10 @@ void QDeclarativeGrid::reportConflictingAnchors() The transition will only be applied to the added item(s). Positioner transitions will only affect the position (x,y) of items. - Added can mean that either the object has been created or reparented, and thus is now a child or the positioner, or that the object has had its opacity increased from zero, and thus is now visible. - - + An object is considered to be added to the positioner if it has been + created or reparented and thus is now a child or the positioner, or if the + object has had its opacity increased from zero, and thus is now + visible. */ /*! \qmlproperty Transition Flow::move @@ -965,14 +978,16 @@ QDeclarativeFlow::QDeclarativeFlow(QDeclarativeItem *parent) \qmlproperty enumeration Flow::flow This property holds the flow of the layout. - Possible values are \c Flow.LeftToRight (default) and \c Flow.TopToBottom. + Possible values are: - If \a flow is \c Flow.LeftToRight, the items are positioned next to + \list + \o Flow.LeftToRight (default) - Items are positioned next to to each other from left to right until the width of the Flow is exceeded, then wrapped to the next line. - If \a flow is \c Flow.TopToBottom, the items are positioned next to each + \o Flow.TopToBottom - Items are positioned next to each other from top to bottom until the height of the Flow is exceeded, then wrapped to the next column. + \endlist */ QDeclarativeFlow::Flow QDeclarativeFlow::flow() const { diff --git a/src/declarative/graphicsitems/qdeclarativepositioners_p_p.h b/src/declarative/graphicsitems/qdeclarativepositioners_p_p.h index 04f0181..822079b 100644 --- a/src/declarative/graphicsitems/qdeclarativepositioners_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativepositioners_p_p.h @@ -100,18 +100,23 @@ public: bool doingPositioning : 1; bool anchorConflict : 1; - virtual void itemSiblingOrderChanged(QDeclarativeItem* other) + void schedulePositioning() { Q_Q(QDeclarativeBasePositioner); - Q_UNUSED(other); if(!queuedPositioning){ - //Delay is due to many children often being reordered at once - //And we only want to reposition them all once QTimer::singleShot(0,q,SLOT(prePositioning())); queuedPositioning = true; } } + virtual void itemSiblingOrderChanged(QDeclarativeItem* other) + { + Q_UNUSED(other); + //Delay is due to many children often being reordered at once + //And we only want to reposition them all once + schedulePositioning(); + } + void itemGeometryChanged(QDeclarativeItem *, const QRectF &newGeometry, const QRectF &oldGeometry) { Q_Q(QDeclarativeBasePositioner); @@ -120,8 +125,7 @@ public: } virtual void itemVisibilityChanged(QDeclarativeItem *) { - Q_Q(QDeclarativeBasePositioner); - q->prePositioning(); + schedulePositioning(); } virtual void itemOpacityChanged(QDeclarativeItem *) { diff --git a/src/declarative/graphicsitems/qdeclarativerectangle.cpp b/src/declarative/graphicsitems/qdeclarativerectangle.cpp index 301ca00..2756877 100644 --- a/src/declarative/graphicsitems/qdeclarativerectangle.cpp +++ b/src/declarative/graphicsitems/qdeclarativerectangle.cpp @@ -160,6 +160,8 @@ void QDeclarativeGradient::doUpdate() You can also create rounded rectangles using the \l radius property. \qml + import Qt 4.7 + Rectangle { width: 100 height: 100 @@ -202,8 +204,20 @@ void QDeclarativeRectangle::doUpdate() A width of 1 creates a thin line. For no line, use a width of 0 or a transparent color. - To keep the border smooth (rather than blurry), odd widths cause the rectangle to be painted at - a half-pixel offset; + If \c border.width is an odd number, the rectangle is painted at a half-pixel offset to retain + border smoothness. Also, the border is rendered evenly on either side of the + rectangle's boundaries, and the spare pixel is rendered to the right and below the + rectangle (as documented for QRect rendering). This can cause unintended effects if + \c border.width is 1 and the rectangle is \l{Item::clip}{clipped} by a parent item: + + \table + \row + \o \snippet doc/src/snippets/declarative/rect-border-width.qml 0 + \o \image rect-border-width.png + \endtable + + Here, the innermost rectangle's border is clipped on the bottom and right edges by its + parent. To avoid this, the border width can be set to two instead of one. */ QDeclarativePen *QDeclarativeRectangle::border() { diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp index 04076f8..995e22a 100644 --- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp +++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp @@ -65,49 +65,75 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate() \since 4.7 \inherits Item - \brief The Repeater item allows you to repeat an Item-based component using a model. + \brief The Repeater element allows you to repeat an Item-based component using a model. - The Repeater item is used to create a large number of - similar items. For each entry in the model, an item is instantiated - in a context seeded with data from the model. If the repeater will - be instantiating a large number of instances, it may be more efficient to - use one of Qt Declarative's \l {xmlViews}{view items}. + The Repeater element is used to create a large number of + similar items. Like other view elements, a Repeater has a \l model and a \l delegate: + for each entry in the model, the delegate is instantiated + in a context seeded with data from the model. A Repeater item is usually + enclosed in a positioner element such as \l Row or \l Column to visually + position the multiple delegate items created by the Repeater. - The model may be either an object list, a string list, a number or a Qt model. - In each case, the data element and the index is exposed to each instantiated - component. - - The index is always exposed as an accessible \c index property. - In the case of an object or string list, the data element (of type string - or object) is available as the \c modelData property. In the case of a Qt model, - all roles are available as named properties just like in the view classes. The - following example shows how to use the index property inside the instantiated - items. + The following Repeater creates three instances of a \l Rectangle item within + a \l Row: + + \snippet doc/src/snippets/declarative/repeater.qml import + \codeline + \snippet doc/src/snippets/declarative/repeater.qml simple + + \image repeater-simple.png + + The \l model of a Repeater can be specified as a model object, a number, a string list + or an object list. If a model object is used, the + \l delegate can access the model roles as named properties, just as for view elements like + ListView and GridView. + + The \l delegate can also access two additional properties: - \snippet doc/src/snippets/declarative/repeater-index.qml 0 + \list + \o \c index - the index of the delegate's item + \o \c modelData - the data element for the delegate, which is useful where the \l model is a string or object list + \endlist - \image repeater-index.png + Here is a Repeater that uses the \c index property inside the instantiated items: + + \table + \row + \o \snippet doc/src/snippets/declarative/repeater.qml index + \o \image repeater-index.png + \endtable + + Here is another Repeater that uses the \c modelData property to reference the data for a + particular index: + + \table + \row + \o \snippet doc/src/snippets/declarative/repeater.qml modeldata + \o \image repeater-modeldata.png + \endtable Items instantiated by the Repeater are inserted, in order, as children of the Repeater's parent. The insertion starts immediately after - the repeater's position in its parent stacking list. This is to allow - you to use a Repeater inside a layout. The following QML example shows how - the instantiated items would visually appear stacked between the red and - blue rectangles. - - \snippet doc/src/snippets/declarative/repeater.qml 0 + the repeater's position in its parent stacking list. This allows + a Repeater to be used inside a layout. For example, the following Repeater's + items are stacked between a red rectangle and a blue rectangle: + + \snippet doc/src/snippets/declarative/repeater.qml layout \image repeater.png - The repeater instance continues to own all items it instantiates, even - if they are otherwise manipulated. It is illegal to manually remove an item - created by the Repeater. + A Repeater item owns all items it instantiates. Removing or dynamically destroying + an item created by a Repeater results in unpredictable behavior. - \note Repeater is Item-based, and cannot be used to repeat non-Item-derived objects. + Note that if a repeater is + required to instantiate a large number of items, it may be more efficient to + use other view elements such as ListView. + + \note Repeater is \l {Item}-based, and can only repeat \l {Item}-derived objects. For example, it cannot be used to repeat QtObjects. \badcode Item { - //XXX illegal. Can't repeat QtObject as it doesn't derive from Item. + //XXX does not work! Can't repeat QtObject as it doesn't derive from Item. Repeater { model: 10 QtObject {} @@ -143,7 +169,15 @@ QDeclarativeRepeater::~QDeclarativeRepeater() The model providing data for the repeater. - The model may be either an object list, a string list, a number or a Qt model. + This property can be set to any of the following: + + \list + \o A number that indicates the number of delegates to be created + \o A model (e.g. a ListModel item, or a QAbstractItemModel subclass) + \o A string list + \o An object list + \endlist + In each case, the data element and the index is exposed to each instantiated component. The index is always exposed as an accessible \c index property. In the case of an object or string list, the data element (of type string diff --git a/src/declarative/graphicsitems/qdeclarativescalegrid.cpp b/src/declarative/graphicsitems/qdeclarativescalegrid.cpp index fe89190..a053aa0 100644 --- a/src/declarative/graphicsitems/qdeclarativescalegrid.cpp +++ b/src/declarative/graphicsitems/qdeclarativescalegrid.cpp @@ -130,8 +130,9 @@ QDeclarativeGridScaledImage::QDeclarativeGridScaledImage(QIODevice *data) int b = -1; QString imgFile; - while(!data->atEnd()) { - QString line = QString::fromUtf8(data->readLine().trimmed()); + QByteArray raw; + while(raw = data->readLine(), !raw.isEmpty()) { + QString line = QString::fromUtf8(raw.trimmed()); if (line.isEmpty() || line.startsWith(QLatin1Char('#'))) continue; diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp index 55cef8b..c2e0d67 100644 --- a/src/declarative/graphicsitems/qdeclarativetext.cpp +++ b/src/declarative/graphicsitems/qdeclarativetext.cpp @@ -126,10 +126,10 @@ QSet<QUrl> QTextDocumentWithImageResources::errors; \image declarative-text.png If height and width are not explicitly set, Text will attempt to determine how - much room is needed and set it accordingly. Unless \c wrapMode is set, it will always + much room is needed and set it accordingly. Unless \l wrapMode is set, it will always prefer width to height (all text will be placed on a single line). - The \c elide property can alternatively be used to fit a single line of + The \l elide property can alternatively be used to fit a single line of plain text to a set width. Note that the \l{Supported HTML Subset} is limited. Also, if the text contains @@ -161,7 +161,7 @@ QSet<QUrl> QTextDocumentWithImageResources::errors; The \c elide property can alternatively be used to fit a line of plain text to a set width. - A QDeclarativeText object can be instantiated in Qml using the tag \c Text. + A QDeclarativeText object can be instantiated in QML using the tag \c Text. */ QDeclarativeText::QDeclarativeText(QDeclarativeItem *parent) : QDeclarativeItem(*(new QDeclarativeTextPrivate), parent) @@ -477,6 +477,7 @@ void QDeclarativeText::setHAlign(HAlignment align) return; d->hAlign = align; + update(); emit horizontalAlignmentChanged(align); } @@ -493,6 +494,7 @@ void QDeclarativeText::setVAlign(VAlignment align) return; d->vAlign = align; + update(); emit verticalAlignmentChanged(align); } @@ -503,13 +505,11 @@ void QDeclarativeText::setVAlign(VAlignment align) wrap if an explicit width has been set. wrapMode can be one of: \list - \o Text.NoWrap - no wrapping will be performed. If the text contains insufficient newlines, then implicitWidth will exceed a set width. - \o Text.WordWrap - wrapping is done on word boundaries only. If a word is too long, implicitWidth will exceed a set width. + \o Text.NoWrap (default) - no wrapping will be performed. If the text contains insufficient newlines, then \l paintedWidth will exceed a set width. + \o Text.WordWrap - wrapping is done on word boundaries only. If a word is too long, \l paintedWidth will exceed a set width. \o Text.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word. \o Text.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word. \endlist - - The default is Text.NoWrap. */ QDeclarativeText::WrapMode QDeclarativeText::wrapMode() const { @@ -539,13 +539,13 @@ void QDeclarativeText::setWrapMode(WrapMode mode) Supported text formats are: \list - \o Text.AutoText + \o Text.AutoText (default) \o Text.PlainText \o Text.RichText \o Text.StyledText \endlist - The default is Text.AutoText. If the text format is Text.AutoText the text element + If the text format is \c Text.AutoText the text element will automatically determine whether the text should be treated as rich text. This determination is made using Qt::mightBeRichText(). @@ -1167,7 +1167,7 @@ void QDeclarativeText::mousePressEvent(QGraphicsSceneMouseEvent *event) } /*! - \qmlsignal Text::linkActivated(link) + \qmlsignal Text::onLinkActivated(link) This handler is called when the user clicks on a link embedded in the text. */ diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index 15cdb05..3b4f2a7 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -62,25 +62,28 @@ QT_BEGIN_NAMESPACE /*! \qmlclass TextEdit QDeclarativeTextEdit \since 4.7 - \brief The TextEdit item allows you to add editable formatted text to a scene. + \brief The TextEdit item displays multiple lines of editable formatted text. \inherits Item + The TextEdit item displays a block of editable, formatted text. + It can display both plain and rich text. For example: \qml TextEdit { - id: edit + width: 240 text: "<b>Hello</b> <i>World!</i>" - focus: true font.family: "Helvetica" font.pointSize: 20 color: "blue" - width: 240 + focus: true } \endqml \image declarative-textedit.gif + Setting \l {Item::focus}{focus} to \c true enables the TextEdit item to receive keyboard focus. + Note that the TextEdit does not implement scrolling, following the cursor, or other behaviors specific to a look-and-feel. For example, to add flickable scrolling that follows the cursor: @@ -96,7 +99,7 @@ TextEdit { You can translate between cursor positions (characters from the start of the document) and pixel points using positionAt() and positionToRectangle(). - \sa Text + \sa Text, TextInput */ /*! @@ -110,7 +113,7 @@ TextEdit { \image declarative-textedit.png - A QDeclarativeTextEdit object can be instantiated in Qml using the tag \c <TextEdit>. + A QDeclarativeTextEdit object can be instantiated in QML using the tag \c <TextEdit>. */ /*! @@ -206,7 +209,7 @@ QString QDeclarativeTextEdit::text() const Sets the font size in pixels. Using this function makes the font device dependent. - Use \c pointSize to set the size of the font in a device independent manner. + Use \l pointSize to set the size of the font in a device independent manner. */ /*! @@ -453,12 +456,22 @@ void QDeclarativeTextEdit::setSelectedTextColor(const QColor &color) \qmlproperty enumeration TextEdit::horizontalAlignment \qmlproperty enumeration TextEdit::verticalAlignment - Sets the horizontal and vertical alignment of the text within the TextEdit items + Sets the horizontal and vertical alignment of the text within the TextEdit item's width and height. By default, the text is top-left aligned. - The valid values for \c horizontalAlignment are \c TextEdit.AlignLeft, \c TextEdit.AlignRight and - \c TextEdit.AlignHCenter. The valid values for \c verticalAlignment are \c TextEdit.AlignTop, \c TextEdit.AlignBottom - and \c TextEdit.AlignVCenter. + Valid values for \c horizontalAlignment are: + \list + \o TextEdit.AlignLeft (default) + \o TextEdit.AlignRight + \o TextEdit.AlignHCenter + \endlist + + Valid values for \c verticalAlignment are: + \list + \o TextEdit.AlignTop (default) + \o TextEdit.AlignBottom + \c TextEdit.AlignVCenter + \endlist */ QDeclarativeTextEdit::HAlignment QDeclarativeTextEdit::hAlign() const { @@ -529,8 +542,8 @@ void QDeclarativeTextEdit::setWrapMode(WrapMode mode) /*! \qmlproperty real TextEdit::paintedWidth - Returns the width of the text, including width past the width - which is covered due to insufficient wrapping if WrapMode is set. + Returns the width of the text, including the width past the width + which is covered due to insufficient wrapping if \l wrapMode is set. */ qreal QDeclarativeTextEdit::paintedWidth() const { @@ -540,8 +553,8 @@ qreal QDeclarativeTextEdit::paintedWidth() const /*! \qmlproperty real TextEdit::paintedHeight - Returns the height of the text, including height past the height - which is covered due to there being more text than fits in the set height. + Returns the height of the text, including the height past the height + that is covered if the text does not fit within the set height. */ qreal QDeclarativeTextEdit::paintedHeight() const { @@ -567,10 +580,10 @@ QRectF QDeclarativeTextEdit::positionToRectangle(int pos) const /*! \qmlmethod int TextEdit::positionAt(x,y) - Returns the text position closest to pixel position (\a x,\a y). + Returns the text position closest to pixel position (\a x, \a y). Position 0 is before the first character, position 1 is after the first character - but before the second, and so on until position text.length, which is after all characters. + but before the second, and so on until position \l {text}.length, which is after all characters. */ int QDeclarativeTextEdit::positionAt(int x, int y) const { @@ -580,7 +593,7 @@ int QDeclarativeTextEdit::positionAt(int x, int y) const } /*! - \qmlmethod int TextEdit::moveCursorSeletion(int pos) + \qmlmethod int TextEdit::moveCursorSelection(int pos) Moves the cursor to \a position and updates the selection accordingly. (To only move the cursor, set the \l cursorPosition property.) @@ -727,12 +740,9 @@ void QDeclarativeTextEdit::loadCursorDelegate() \qmlproperty int TextEdit::selectionStart The cursor position before the first character in the current selection. - Setting this and selectionEnd allows you to specify a selection in the - text edit. - Note that if selectionStart == selectionEnd then there is no current - selection. If you attempt to set selectionStart to a value outside of - the current text, selectionStart will not be changed. + This property is read-only. To change the selection, use select(start,end), + selectAll(), or selectWord(). \sa selectionEnd, cursorPosition, selectedText */ @@ -742,25 +752,13 @@ int QDeclarativeTextEdit::selectionStart() const return d->control->textCursor().selectionStart(); } -void QDeclarativeTextEdit::setSelectionStart(int s) -{ - Q_D(QDeclarativeTextEdit); - if(d->lastSelectionStart == s || s < 0 || s > text().length()) - return; - d->lastSelectionStart = s; - d->updateSelection();// Will emit the relevant signals -} - /*! \qmlproperty int TextEdit::selectionEnd The cursor position after the last character in the current selection. - Setting this and selectionStart allows you to specify a selection in the - text edit. - Note that if selectionStart == selectionEnd then there is no current - selection. If you attempt to set selectionEnd to a value outside of - the current text, selectionEnd will not be changed. + This property is read-only. To change the selection, use select(start,end), + selectAll(), or selectWord(). \sa selectionStart, cursorPosition, selectedText */ @@ -770,15 +768,6 @@ int QDeclarativeTextEdit::selectionEnd() const return d->control->textCursor().selectionEnd(); } -void QDeclarativeTextEdit::setSelectionEnd(int s) -{ - Q_D(QDeclarativeTextEdit); - if(d->lastSelectionEnd == s || s < 0 || s > text().length()) - return; - d->lastSelectionEnd = s; - d->updateSelection();// Will emit the relevant signals -} - /*! \qmlproperty string TextEdit::selectedText @@ -1028,6 +1017,8 @@ void QDeclarativeTextEditPrivate::focusChanged(bool hasFocus) } /*! + \qmlmethod void TextEdit::selectAll() + Causes all text to be selected. */ void QDeclarativeTextEdit::selectAll() @@ -1037,6 +1028,8 @@ void QDeclarativeTextEdit::selectAll() } /*! + \qmlmethod void TextEdit::selectWord() + Causes the word closest to the current cursor position to be selected. */ void QDeclarativeTextEdit::selectWord() @@ -1048,6 +1041,36 @@ void QDeclarativeTextEdit::selectWord() } /*! + \qmlmethod void TextEdit::select(start,end) + + Causes the text from \a start to \a end to be selected. + + If either start or end is out of range, the selection is not changed. + + After calling this, selectionStart will become the lesser + and selectionEnd will become the greater (regardless of the order passed + to this method). + + \sa selectionStart, selectionEnd +*/ +void QDeclarativeTextEdit::select(int start, int end) +{ + Q_D(QDeclarativeTextEdit); + if (start < 0 || end < 0 || start > d->text.length() || end > d->text.length()) + return; + QTextCursor cursor = d->control->textCursor(); + cursor.beginEditBlock(); + cursor.setPosition(start, QTextCursor::MoveAnchor); + cursor.setPosition(end, QTextCursor::KeepAnchor); + cursor.endEditBlock(); + d->control->setTextCursor(cursor); + + // QTBUG-11100 + updateSelectionMarkers(); +} + +#ifndef QT_NO_CLIPBOARD +/*! \qmlmethod TextEdit::cut() Moves the currently selected text to the system clipboard. @@ -1072,14 +1095,14 @@ void QDeclarativeTextEdit::copy() /*! \qmlmethod TextEdit::paste() - Relaces the currently selected text by the contents of the system clipboard. + Replaces the currently selected text by the contents of the system clipboard. */ void QDeclarativeTextEdit::paste() { Q_D(QDeclarativeTextEdit); d->control->paste(); } - +#endif // QT_NO_CLIPBOARD /*! \overload @@ -1097,9 +1120,15 @@ void QDeclarativeTextEdit::mousePressEvent(QGraphicsSceneMouseEvent *event) p = p->parentItem(); } setFocus(true); - if (hasFocus() == hadFocus && d->showInputPanelOnFocus && !isReadOnly()) { - // re-open input panel on press if already focused - openSoftwareInputPanel(); + if (d->showInputPanelOnFocus) { + if (hasFocus() && hadFocus && !isReadOnly()) { + // re-open input panel on press if already focused + openSoftwareInputPanel(); + } + } else { // show input panel on click + if (hasFocus() && !hadFocus) { + d->clickCausedFocus = true; + } } } if (event->type() != QEvent::GraphicsSceneMouseDoubleClick || d->selectByMouse) @@ -1116,6 +1145,17 @@ void QDeclarativeTextEdit::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextEdit); d->control->processEvent(event, QPointF(0, -d->yoff)); + if (!d->showInputPanelOnFocus) { // input panel on click + if (d->focusOnPress && !isReadOnly() && boundingRect().contains(event->pos())) { + if (QGraphicsView * view = qobject_cast<QGraphicsView*>(qApp->focusWidget())) { + if (view->scene() && view->scene() == scene()) { + qt_widget_private(view)->handleSoftwareInputPanel(event->button(), d->clickCausedFocus); + } + } + } + } + d->clickCausedFocus = false; + if (!event->isAccepted()) QDeclarativePaintedItem::mouseReleaseEvent(event); } @@ -1192,9 +1232,14 @@ void QDeclarativeTextEdit::drawContents(QPainter *painter, const QRect &bounds) void QDeclarativeTextEdit::updateImgCache(const QRectF &rf) { Q_D(const QDeclarativeTextEdit); - QRect r = rf.toRect(); - if (r != QRect(0,0,INT_MAX,INT_MAX)) // Don't translate "everything" - r = r.translated(0,d->yoff); + QRect r; + if (!rf.isValid()) { + r = QRect(0,0,INT_MAX,INT_MAX); + } else { + r = rf.toRect(); + if (r != QRect(0,0,INT_MAX,INT_MAX)) // Don't translate "everything" + r = r.translated(0,d->yoff); + } dirtyCache(r); emit update(); } @@ -1264,7 +1309,6 @@ void QDeclarativeTextEditPrivate::updateSelection() QTextCursor cursor = control->textCursor(); bool startChange = (lastSelectionStart != cursor.selectionStart()); bool endChange = (lastSelectionEnd != cursor.selectionEnd()); - //### Is it worth calculating a more minimal set of movements? cursor.beginEditBlock(); cursor.setPosition(lastSelectionStart, QTextCursor::MoveAnchor); cursor.setPosition(lastSelectionEnd, QTextCursor::KeepAnchor); @@ -1274,8 +1318,6 @@ void QDeclarativeTextEditPrivate::updateSelection() q->selectionStartChanged(); if(endChange) q->selectionEndChanged(); - startChange = (lastSelectionStart != control->textCursor().selectionStart()); - endChange = (lastSelectionEnd != control->textCursor().selectionEnd()); } void QDeclarativeTextEdit::updateSelectionMarkers() @@ -1361,10 +1403,14 @@ void QDeclarativeTextEditPrivate::updateDefaultTextOption() customizing when you want the input keyboard to be shown and hidden in your application. - By default input panels are shown when TextEdit element gains focus and hidden - when the focus is lost. You can disable the automatic behavior by setting the - property showInputPanelOnFocus to false and use functions openSoftwareInputPanel() - and closeSoftwareInputPanel() to implement the behavior you want. + By default the opening of input panels follows the platform style. On Symbian^1 and + Symbian^3 -based devices the panels are opened by clicking TextEdit. On other platforms + the panels are automatically opened when TextEdit element gains focus. Input panels are + always closed if no editor owns focus. + + You can disable the automatic behavior by setting the property \c focusOnPress to false + and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement + the behavior you want. Only relevant on platforms, which provide virtual keyboards. @@ -1373,12 +1419,19 @@ void QDeclarativeTextEditPrivate::updateDefaultTextOption() TextEdit { id: textEdit text: "Hello world!" - showInputPanelOnFocus: false + focusOnPress: false MouseArea { anchors.fill: parent - onClicked: textEdit.openSoftwareInputPanel() + onClicked: { + if (!textEdit.focus) { + textEdit.focus = true; + textEdit.openSoftwareInputPanel(); + } else { + textEdit.focus = false; + } + } + onPressAndHold: textEdit.closeSoftwareInputPanel(); } - onFocusChanged: if (!focus) closeSoftwareInputpanel() } \endcode */ @@ -1401,10 +1454,14 @@ void QDeclarativeTextEdit::openSoftwareInputPanel() for customizing when you want the input keyboard to be shown and hidden in your application. - By default input panels are shown when TextEdit element gains focus and hidden - when the focus is lost. You can disable the automatic behavior by setting the - property showInputPanelOnFocus to false and use functions openSoftwareInputPanel() - and closeSoftwareInputPanel() to implement the behavior you want. + By default the opening of input panels follows the platform style. On Symbian^1 and + Symbian^3 -based devices the panels are opened by clicking TextEdit. On other platforms + the panels are automatically opened when TextEdit element gains focus. Input panels are + always closed if no editor owns focus. + + You can disable the automatic behavior by setting the property \c focusOnPress to false + and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement + the behavior you want. Only relevant on platforms, which provide virtual keyboards. @@ -1413,12 +1470,19 @@ void QDeclarativeTextEdit::openSoftwareInputPanel() TextEdit { id: textEdit text: "Hello world!" - showInputPanelOnFocus: false + focusOnPress: false MouseArea { anchors.fill: parent - onClicked: textEdit.openSoftwareInputPanel() + onClicked: { + if (!textEdit.focus) { + textEdit.focus = true; + textEdit.openSoftwareInputPanel(); + } else { + textEdit.focus = false; + } + } + onPressAndHold: textEdit.closeSoftwareInputPanel(); } - onFocusChanged: if (!focus) closeSoftwareInputpanel() } \endcode */ @@ -1434,46 +1498,15 @@ void QDeclarativeTextEdit::closeSoftwareInputPanel() } } -/*! - \qmlproperty bool TextEdit::showInputPanelOnFocus - Whether input panels are automatically shown when TextEdit element gains - focus and hidden when focus is lost. By default this is set to true. - - Only relevant on platforms, which provide virtual keyboards. -*/ -bool QDeclarativeTextEdit::showInputPanelOnFocus() const -{ - Q_D(const QDeclarativeTextEdit); - return d->showInputPanelOnFocus; -} - -void QDeclarativeTextEdit::setShowInputPanelOnFocus(bool showOnFocus) -{ - Q_D(QDeclarativeTextEdit); - if (d->showInputPanelOnFocus == showOnFocus) - return; - - d->showInputPanelOnFocus = showOnFocus; - - emit showInputPanelOnFocusChanged(d->showInputPanelOnFocus); -} - void QDeclarativeTextEdit::focusInEvent(QFocusEvent *event) { Q_D(const QDeclarativeTextEdit); - if (d->showInputPanelOnFocus && !isReadOnly() && event->reason() != Qt::ActiveWindowFocusReason) { - openSoftwareInputPanel(); + if (d->showInputPanelOnFocus) { + if (d->focusOnPress && !isReadOnly()) { + openSoftwareInputPanel(); + } } QDeclarativePaintedItem::focusInEvent(event); } -void QDeclarativeTextEdit::focusOutEvent(QFocusEvent *event) -{ - Q_D(const QDeclarativeTextEdit); - if (d->showInputPanelOnFocus && !isReadOnly()) { - closeSoftwareInputPanel(); - } - QDeclarativePaintedItem::focusOutEvent(event); -} - QT_END_NAMESPACE diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h index a83b3db..d08f607 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h @@ -82,11 +82,10 @@ class Q_DECLARATIVE_EXPORT QDeclarativeTextEdit : public QDeclarativePaintedItem Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged) Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged) Q_PROPERTY(QDeclarativeComponent* cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged) - Q_PROPERTY(int selectionStart READ selectionStart WRITE setSelectionStart NOTIFY selectionStartChanged) - Q_PROPERTY(int selectionEnd READ selectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged) + Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged) + Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged) Q_PROPERTY(QString selectedText READ selectedText NOTIFY selectionChanged) Q_PROPERTY(bool focusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY focusOnPressChanged) - Q_PROPERTY(bool showInputPanelOnFocus READ showInputPanelOnFocus WRITE setShowInputPanelOnFocus NOTIFY showInputPanelOnFocusChanged) Q_PROPERTY(bool persistentSelection READ persistentSelection WRITE setPersistentSelection NOTIFY persistentSelectionChanged) Q_PROPERTY(qreal textMargin READ textMargin WRITE setTextMargin NOTIFY textMarginChanged) Q_PROPERTY(Qt::InputMethodHints inputMethodHints READ inputMethodHints WRITE setInputMethodHints) @@ -160,19 +159,13 @@ public: void setCursorDelegate(QDeclarativeComponent*); int selectionStart() const; - void setSelectionStart(int); - int selectionEnd() const; - void setSelectionEnd(int); QString selectedText() const; bool focusOnPress() const; void setFocusOnPress(bool on); - bool showInputPanelOnFocus() const; - void setShowInputPanelOnFocus(bool showOnFocus); - bool persistentSelection() const; void setPersistentSelection(bool on); @@ -225,14 +218,16 @@ Q_SIGNALS: void persistentSelectionChanged(bool isPersistentSelection); void textMarginChanged(qreal textMargin); void selectByMouseChanged(bool selectByMouse); - void showInputPanelOnFocusChanged(bool showOnFocus); public Q_SLOTS: void selectAll(); void selectWord(); + void select(int start, int end); +#ifndef QT_NO_CLIPBOARD void cut(); void copy(); void paste(); +#endif private Q_SLOTS: void updateImgCache(const QRectF &rect); @@ -252,7 +247,6 @@ protected: void keyPressEvent(QKeyEvent *); void keyReleaseEvent(QKeyEvent *); void focusInEvent(QFocusEvent *event); - void focusOutEvent(QFocusEvent *event); // mouse filter? void mousePressEvent(QGraphicsSceneMouseEvent *event); diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h index 8e1d630..4092e65 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextedit_p_p.h @@ -70,12 +70,17 @@ public: QDeclarativeTextEditPrivate() : color("black"), hAlign(QDeclarativeTextEdit::AlignLeft), vAlign(QDeclarativeTextEdit::AlignTop), imgDirty(true), dirty(false), richText(false), cursorVisible(false), focusOnPress(true), - showInputPanelOnFocus(true), persistentSelection(true), textMargin(0.0), lastSelectionStart(0), - lastSelectionEnd(0), cursorComponent(0), cursor(0), format(QDeclarativeTextEdit::AutoText), - document(0), wrapMode(QDeclarativeTextEdit::NoWrap), + showInputPanelOnFocus(true), clickCausedFocus(false), persistentSelection(true), textMargin(0.0), + lastSelectionStart(0), lastSelectionEnd(0), cursorComponent(0), cursor(0), + format(QDeclarativeTextEdit::AutoText), document(0), wrapMode(QDeclarativeTextEdit::NoWrap), selectByMouse(false), yoff(0) { +#ifdef Q_OS_SYMBIAN + if (QSysInfo::symbianVersion() == QSysInfo::SV_SF_1 || QSysInfo::symbianVersion() == QSysInfo::SV_SF_3) { + showInputPanelOnFocus = false; + } +#endif } void init(); @@ -102,6 +107,7 @@ public: bool cursorVisible : 1; bool focusOnPress : 1; bool showInputPanelOnFocus : 1; + bool clickCausedFocus : 1; bool persistentSelection : 1; qreal textMargin; int lastSelectionStart; diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index ea958ef..633c01e 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -46,6 +46,7 @@ #include <qdeclarativeinfo.h> #include <QValidator> +#include <QTextCursor> #include <QApplication> #include <QFontMetrics> #include <QPainter> @@ -55,17 +56,20 @@ QT_BEGIN_NAMESPACE /*! \qmlclass TextInput QDeclarativeTextInput \since 4.7 - \brief The TextInput item allows you to add an editable line of text to a scene. + \brief The TextInput item displays an editable line of text. \inherits Item - TextInput can only display a single line of text, and can only display - plain text. However it can provide addition input constraints on the text. + The TextInput element displays a single line of editable plain text. - Input constraints include setting a QValidator, an input mask, or a - maximum input length. + TextInput is used to accept a line of text input. Input constraints + can be placed on a TextInput item (for example, through a \l validator or \l inputMask), + and setting \l echoMode to an appropriate value enables TextInput to be used for + a password input field. On Mac OS X, the Up/Down key bindings for Home/End are explicitly disabled. If you want such bindings (on any platform), you will need to construct them in QML. + + \sa TextEdit, Text */ QDeclarativeTextInput::QDeclarativeTextInput(QDeclarativeItem* parent) : QDeclarativePaintedItem(*(new QDeclarativeTextInputPrivate), parent) @@ -248,7 +252,12 @@ QColor QDeclarativeTextInput::color() const void QDeclarativeTextInput::setColor(const QColor &c) { Q_D(QDeclarativeTextInput); - d->color = c; + if (c != d->color) { + d->color = c; + clearCache(); + update(); + emit colorChanged(c); + } } @@ -429,10 +438,12 @@ void QDeclarativeTextInput::setCursorPosition(int cp) Returns a Rect which encompasses the cursor, but which may be larger than is required. Ignores custom cursor delegates. */ -QRect QDeclarativeTextInput::cursorRect() const +QRect QDeclarativeTextInput::cursorRectangle() const { Q_D(const QDeclarativeTextInput); - return d->control->cursorRect(); + QRect r = d->control->cursorRect(); + r.setHeight(r.height()-1); // Make consistent with TextEdit (QLineControl inexplicably adds 1) + return r; } /*! @@ -454,15 +465,6 @@ int QDeclarativeTextInput::selectionStart() const return d->lastSelectionStart; } -void QDeclarativeTextInput::setSelectionStart(int s) -{ - Q_D(QDeclarativeTextInput); - if(d->lastSelectionStart == s || s < 0 || s > text().length()) - return; - d->lastSelectionStart = s; - d->control->setSelection(s, d->lastSelectionEnd - s); -} - /*! \qmlproperty int TextInput::selectionEnd @@ -482,13 +484,12 @@ int QDeclarativeTextInput::selectionEnd() const return d->lastSelectionEnd; } -void QDeclarativeTextInput::setSelectionEnd(int s) +void QDeclarativeTextInput::select(int start, int end) { Q_D(QDeclarativeTextInput); - if(d->lastSelectionEnd == s || s < 0 || s > text().length()) + if (start < 0 || end < 0 || start > d->control->text().length() || end > d->control->text().length()) return; - d->lastSelectionEnd = s; - d->control->setSelection(d->lastSelectionStart, s - d->lastSelectionStart); + d->control->setSelection(start, end-start); } /*! @@ -560,7 +561,7 @@ void QDeclarativeTextInput::setAutoScroll(bool b) /*! \qmlclass IntValidator QIntValidator - This element provides a validator for integer values + This element provides a validator for integer values. */ /*! \qmlproperty int IntValidator::top @@ -603,10 +604,14 @@ void QDeclarativeTextInput::setAutoScroll(bool b) \qmlproperty enumeration DoubleValidator::notation This property holds the notation of how a string can describe a number. - The values for this property are DoubleValidator.StandardNotation or DoubleValidator.ScientificNotation. - If this property is set to DoubleValidator.ScientificNotation, the written number may have an exponent part(i.e. 1.5E-2). + The possible values for this property are: + + \list + \o DoubleValidator.StandardNotation + \o DoubleValidator.ScientificNotation (default) + \endlist - By default, this property is set to DoubleValidator.ScientificNotation. + If this property is set to DoubleValidator.ScientificNotation, the written number may have an exponent part (e.g. 1.5E-2). */ /*! @@ -835,6 +840,19 @@ void QDeclarativeTextInput::moveCursor() } /*! + \qmlmethod rect TextInput::positionToRectangle(int x) +*/ +QRectF QDeclarativeTextInput::positionToRectangle(int x) const +{ + Q_D(const QDeclarativeTextInput); + QFontMetrics fm = QFontMetrics(d->font); + return QRectF(d->control->cursorToX(x)-d->hscroll, + 0.0, + d->control->cursorWidth(), + cursorRectangle().height()); +} + +/*! \qmlmethod int TextInput::positionAt(int x) This function returns the character position at @@ -845,10 +863,10 @@ void QDeclarativeTextInput::moveCursor() This means that for all x values before the first character this function returns 0, and for all x values after the last character this function returns text.length. */ -int QDeclarativeTextInput::positionAt(int x) +int QDeclarativeTextInput::positionAt(int x) const { Q_D(const QDeclarativeTextInput); - return d->control->xToPos(x - d->hscroll); + return d->control->xToPos(x + d->hscroll); } void QDeclarativeTextInputPrivate::focusChanged(bool hasFocus) @@ -885,6 +903,22 @@ void QDeclarativeTextInput::keyPressEvent(QKeyEvent* ev) QDeclarativePaintedItem::keyPressEvent(ev); } +/*! +\overload +Handles the given mouse \a event. +*/ +void QDeclarativeTextInput::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) +{ + Q_D(QDeclarativeTextInput); + if (d->selectByMouse) { + int cursor = d->xToPos(event->pos().x()); + d->control->selectWordAtPos(cursor); + event->setAccepted(true); + } else { + QDeclarativePaintedItem::mouseDoubleClickEvent(event); + } +} + void QDeclarativeTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextInput); @@ -897,12 +931,17 @@ void QDeclarativeTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event) p = p->parentItem(); } setFocus(true); - if (hasFocus() == hadFocus && d->showInputPanelOnFocus && !isReadOnly()) { - // re-open input panel on press w already focused - openSoftwareInputPanel(); + if (d->showInputPanelOnFocus) { + if (hasFocus() && hadFocus && !isReadOnly()) { + // re-open input panel on press if already focused + openSoftwareInputPanel(); + } + } else { // show input panel on click + if (hasFocus() && !hadFocus) { + d->clickCausedFocus = true; + } } } - bool mark = event->modifiers() & Qt::ShiftModifier; int cursor = d->xToPos(event->pos().x()); d->control->moveCursor(cursor, mark); @@ -927,6 +966,16 @@ Handles the given mouse \a event. void QDeclarativeTextInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { Q_D(QDeclarativeTextInput); + if (!d->showInputPanelOnFocus) { // input panel on click + if (d->focusOnPress && !isReadOnly() && boundingRect().contains(event->pos())) { + if (QGraphicsView * view = qobject_cast<QGraphicsView*>(qApp->focusWidget())) { + if (view->scene() && view->scene() == scene()) { + qt_widget_private(view)->handleSoftwareInputPanel(event->button(), d->clickCausedFocus); + } + } + } + } + d->clickCausedFocus = false; d->control->processEvent(event); if (!event->isAccepted()) QDeclarativePaintedItem::mouseReleaseEvent(event); @@ -943,10 +992,9 @@ bool QDeclarativeTextInput::event(QEvent* ev) case QEvent::GraphicsSceneMousePress: case QEvent::GraphicsSceneMouseMove: case QEvent::GraphicsSceneMouseRelease: + case QEvent::GraphicsSceneMouseDoubleClick: break; default: - if (ev->type() == QEvent::GraphicsSceneMouseDoubleClick && !d->selectByMouse) - break; handled = d->control->processEvent(ev); if (ev->type() == QEvent::InputMethod) updateSize(); @@ -1021,7 +1069,6 @@ void QDeclarativeTextInput::drawContents(QPainter *p, const QRect &r) d->hscroll -= minLB; offset = QPoint(d->hscroll, 0); } - d->control->draw(p, offset, r, flags); p->restore(); @@ -1059,12 +1106,27 @@ QVariant QDeclarativeTextInput::inputMethodQuery(Qt::InputMethodQuery property) } } +/*! + \qmlmethod void TextInput::selectAll() + + Causes all text to be selected. +*/ void QDeclarativeTextInput::selectAll() { Q_D(QDeclarativeTextInput); d->control->setSelection(0, d->control->text().length()); } +/*! + \qmlmethod void TextInput::selectWord() + + Causes the word closest to the current cursor position to be selected. +*/ +void QDeclarativeTextInput::selectWord() +{ + Q_D(QDeclarativeTextInput); + d->control->selectWordAtPos(d->control->cursor()); +} /*! \qmlproperty bool TextInput::smooth @@ -1183,26 +1245,37 @@ void QDeclarativeTextInput::moveCursorSelection(int position) customizing when you want the input keyboard to be shown and hidden in your application. - By default input panels are shown when TextInput element gains focus and hidden - when the focus is lost. You can disable the automatic behavior by setting the - property showInputPanelOnFocus to false and use functions openSoftwareInputPanel() - and closeSoftwareInputPanel() to implement the behavior you want. + By default the opening of input panels follows the platform style. On Symbian^1 and + Symbian^3 -based devices the panels are opened by clicking TextInput. On other platforms + the panels are automatically opened when TextInput element gains focus. Input panels are + always closed if no editor owns focus. + + . You can disable the automatic behavior by setting the property \c focusOnPress to false + and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement + the behavior you want. Only relevant on platforms, which provide virtual keyboards. - \code + \qml import Qt 4.7 TextInput { id: textInput text: "Hello world!" - showInputPanelOnFocus: false + focusOnPress: false MouseArea { anchors.fill: parent - onClicked: textInput.openSoftwareInputPanel() + onClicked: { + if (!textInput.focus) { + textInput.focus = true; + textInput.openSoftwareInputPanel(); + } else { + textInput.focus = false; + } + } + onPressAndHold: textInput.closeSoftwareInputPanel(); } - onFocusChanged: if (!focus) closeSoftwareInputPanel() } - \endcode + \endqml */ void QDeclarativeTextInput::openSoftwareInputPanel() { @@ -1223,26 +1296,37 @@ void QDeclarativeTextInput::openSoftwareInputPanel() for customizing when you want the input keyboard to be shown and hidden in your application. - By default input panels are shown when TextInput element gains focus and hidden - when the focus is lost. You can disable the automatic behavior by setting the - property showInputPanelOnFocus to false and use functions openSoftwareInputPanel() - and closeSoftwareInputPanel() to implement the behavior you want. + By default the opening of input panels follows the platform style. On Symbian^1 and + Symbian^3 -based devices the panels are opened by clicking TextInput. On other platforms + the panels are automatically opened when TextInput element gains focus. Input panels are + always closed if no editor owns focus. + + . You can disable the automatic behavior by setting the property \c focusOnPress to false + and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement + the behavior you want. Only relevant on platforms, which provide virtual keyboards. - \code + \qml import Qt 4.7 TextInput { id: textInput text: "Hello world!" - showInputPanelOnFocus: false + focusOnPress: false MouseArea { anchors.fill: parent - onClicked: textInput.openSoftwareInputPanel() + onClicked: { + if (!textInput.focus) { + textInput.focus = true; + textInput.openSoftwareInputPanel(); + } else { + textInput.focus = false; + } + } + onPressAndHold: textInput.closeSoftwareInputPanel(); } - onFocusChanged: if (!focus) closeSoftwareInputPanel() } - \endcode + \endqml */ void QDeclarativeTextInput::closeSoftwareInputPanel() { @@ -1257,54 +1341,22 @@ void QDeclarativeTextInput::closeSoftwareInputPanel() } } -/*! - \qmlproperty bool TextInput::showInputPanelOnFocus - Whether input panels are automatically shown when TextInput element gains - focus and hidden when focus is lost. By default this is set to true. - - Only relevant on platforms, which provide virtual keyboards. -*/ -bool QDeclarativeTextInput::showInputPanelOnFocus() const -{ - Q_D(const QDeclarativeTextInput); - return d->showInputPanelOnFocus; -} - -void QDeclarativeTextInput::setShowInputPanelOnFocus(bool showOnFocus) -{ - Q_D(QDeclarativeTextInput); - if (d->showInputPanelOnFocus == showOnFocus) - return; - - d->showInputPanelOnFocus = showOnFocus; - - emit showInputPanelOnFocusChanged(d->showInputPanelOnFocus); -} - void QDeclarativeTextInput::focusInEvent(QFocusEvent *event) { Q_D(const QDeclarativeTextInput); - if (d->showInputPanelOnFocus && !isReadOnly() && event->reason() != Qt::ActiveWindowFocusReason) { - openSoftwareInputPanel(); + if (d->showInputPanelOnFocus) { + if (d->focusOnPress && !isReadOnly()) { + openSoftwareInputPanel(); + } } QDeclarativePaintedItem::focusInEvent(event); } -void QDeclarativeTextInput::focusOutEvent(QFocusEvent *event) -{ - Q_D(const QDeclarativeTextInput); - if (d->showInputPanelOnFocus && !isReadOnly()) { - closeSoftwareInputPanel(); - } - QDeclarativePaintedItem::focusOutEvent(event); -} - void QDeclarativeTextInputPrivate::init() { Q_Q(QDeclarativeTextInput); control->setCursorWidth(1); control->setPasswordCharacter(QLatin1Char('*')); - control->setLayoutDirection(Qt::LeftToRight); q->setSmooth(smooth); q->setAcceptedMouseButtons(Qt::LeftButton); q->setFlag(QGraphicsItem::ItemHasNoContents, false); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h index 9d58f13..c539bd3 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h @@ -72,10 +72,10 @@ class Q_DECLARATIVE_EXPORT QDeclarativeTextInput : public QDeclarativePaintedIte Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged) Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged) Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged) - Q_PROPERTY(QRect cursorRect READ cursorRect NOTIFY cursorPositionChanged) + Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorPositionChanged) Q_PROPERTY(QDeclarativeComponent *cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged) - Q_PROPERTY(int selectionStart READ selectionStart WRITE setSelectionStart NOTIFY selectionStartChanged) - Q_PROPERTY(int selectionEnd READ selectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged) + Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged) + Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged) Q_PROPERTY(QString selectedText READ selectedText NOTIFY selectedTextChanged) Q_PROPERTY(int maximumLength READ maxLength WRITE setMaxLength NOTIFY maximumLengthChanged) @@ -88,7 +88,6 @@ class Q_DECLARATIVE_EXPORT QDeclarativeTextInput : public QDeclarativePaintedIte Q_PROPERTY(bool acceptableInput READ hasAcceptableInput NOTIFY acceptableInputChanged) Q_PROPERTY(EchoMode echoMode READ echoMode WRITE setEchoMode NOTIFY echoModeChanged) Q_PROPERTY(bool focusOnPress READ focusOnPress WRITE setFocusOnPress NOTIFY focusOnPressChanged) - Q_PROPERTY(bool showInputPanelOnFocus READ showInputPanelOnFocus WRITE setShowInputPanelOnFocus NOTIFY showInputPanelOnFocusChanged) Q_PROPERTY(QString passwordCharacter READ passwordCharacter WRITE setPasswordCharacter NOTIFY passwordCharacterChanged) Q_PROPERTY(QString displayText READ displayText NOTIFY displayTextChanged) Q_PROPERTY(bool autoScroll READ autoScroll WRITE setAutoScroll NOTIFY autoScrollChanged) @@ -112,7 +111,8 @@ public: }; //Auxilliary functions needed to control the TextInput from QML - Q_INVOKABLE int positionAt(int x); + Q_INVOKABLE int positionAt(int x) const; + Q_INVOKABLE QRectF positionToRectangle(int x) const; Q_INVOKABLE void moveCursorSelection(int pos); Q_INVOKABLE void openSoftwareInputPanel(); @@ -145,13 +145,10 @@ public: int cursorPosition() const; void setCursorPosition(int cp); - QRect cursorRect() const; + QRect cursorRectangle() const; int selectionStart() const; - void setSelectionStart(int); - int selectionEnd() const; - void setSelectionEnd(int); QString selectedText() const; @@ -179,9 +176,6 @@ public: bool focusOnPress() const; void setFocusOnPress(bool); - bool showInputPanelOnFocus() const; - void setShowInputPanelOnFocus(bool showOnFocus); - bool autoScroll() const; void setAutoScroll(bool); @@ -218,7 +212,6 @@ Q_SIGNALS: void focusOnPressChanged(bool focusOnPress); void autoScrollChanged(bool autoScroll); void selectByMouseChanged(bool selectByMouse); - void showInputPanelOnFocusChanged(bool showOnFocus); protected: virtual void geometryChanged(const QRectF &newGeometry, @@ -227,13 +220,15 @@ protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event); void keyPressEvent(QKeyEvent* ev); bool event(QEvent *e); void focusInEvent(QFocusEvent *event); - void focusOutEvent(QFocusEvent *event); public Q_SLOTS: void selectAll(); + void selectWord(); + void select(int start, int end); private Q_SLOTS: void updateSize(bool needsRedraw = true); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h index f44d014..6865147 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h @@ -72,9 +72,15 @@ public: color((QRgb)0), style(QDeclarativeText::Normal), styleColor((QRgb)0), hAlign(QDeclarativeTextInput::AlignLeft), hscroll(0), oldScroll(0), focused(false), focusOnPress(true), - showInputPanelOnFocus(true), cursorVisible(false), autoScroll(true), - selectByMouse(false) + showInputPanelOnFocus(true), clickCausedFocus(false), cursorVisible(false), + autoScroll(true), selectByMouse(false) { +#ifdef Q_OS_SYMBIAN + if (QSysInfo::symbianVersion() == QSysInfo::SV_SF_1 || QSysInfo::symbianVersion() == QSysInfo::SV_SF_3) { + showInputPanelOnFocus = false; + } +#endif + } ~QDeclarativeTextInputPrivate() @@ -116,6 +122,7 @@ public: bool focused; bool focusOnPress; bool showInputPanelOnFocus; + bool clickCausedFocus; bool cursorVisible; bool autoScroll; bool selectByMouse; diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index c6ee46f..5092349 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -113,17 +113,19 @@ public: \since 4.7 \brief The VisualItemModel allows items to be provided to a view. - The children of the VisualItemModel are provided in a model which - can be used in a view. Note that no delegate should be - provided to a view since the VisualItemModel contains the - visual delegate (items). + A VisualItemModel contains the visual items to be used in a view. + When a VisualItemModel is used in a view, the view does not require + a delegate since the VisualItemModel already contains the visual + delegate (items). An item can determine its index within the - model via the VisualItemModel.index attached property. + model via the \l{VisualItemModel::index}{index} attached property. The example below places three colored rectangles in a ListView. \code - Item { + import Qt 4.7 + + Rectangle { VisualItemModel { id: itemModel Rectangle { height: 30; width: 80; color: "red" } @@ -137,12 +139,23 @@ public: } } \endcode + + \image visualitemmodel.png + + \sa {declarative/modelviews/visualitemmodel}{VisualItemModel example} */ QDeclarativeVisualItemModel::QDeclarativeVisualItemModel(QObject *parent) : QDeclarativeVisualModel(*(new QDeclarativeVisualItemModelPrivate), parent) { } +/*! + \qmlattachedproperty int VisualItemModel::index + This attached property holds the index of this delegate's item within the model. + + It is attached to each instance of the delegate. +*/ + QDeclarativeListProperty<QDeclarativeItem> QDeclarativeVisualItemModel::children() { Q_D(QDeclarativeVisualItemModel); @@ -605,30 +618,15 @@ QDeclarativeVisualDataModelData *QDeclarativeVisualDataModelPrivate::data(QObjec A VisualDataModel encapsulates a model and the delegate that will be instantiated for items in the model. - It is usually not necessary to create a VisualDataModel directly, - since the QML views will create one internally. + It is usually not necessary to create VisualDataModel elements. + However, it can be useful for manipulating and accessing the \l modelIndex + when a QAbstractItemModel subclass is used as the + model. Also, VisualDataModel is used together with \l Package to + provide delegates to multiple views. The example below illustrates using a VisualDataModel with a ListView. - \code - VisualDataModel { - id: visualModel - model: myModel - delegate: Component { - Rectangle { - height: 25 - width: 100 - Text { text: "Name:" + name} - } - } - } - ListView { - width: 100 - height: 100 - anchors.fill: parent - model: visualModel - } - \endcode + \snippet doc/src/snippets/declarative/visualdatamodel.qml 0 */ QDeclarativeVisualDataModel::QDeclarativeVisualDataModel() @@ -803,56 +801,22 @@ void QDeclarativeVisualDataModel::setDelegate(QDeclarativeComponent *delegate) /*! \qmlproperty QModelIndex VisualDataModel::rootIndex - QAbstractItemModel provides a heirachical tree of data, whereas + QAbstractItemModel provides a hierarchical tree of data, whereas QML only operates on list data. \c rootIndex allows the children of any node in a QAbstractItemModel to be provided by this model. This property only affects models of type QAbstractItemModel. - \code - // main.cpp + For example, here is a simple interactive file system browser. + When a directory name is clicked, the view's \c rootIndex is set to the + QModelIndex node of the clicked directory, thus updating the view to show + the new directory's contents. - int main(int argc, char ** argv) - { - QApplication app(argc, argv); - - QDeclarativeView view; - - QDirModel model; - view.rootContext()->setContextProperty("myModel", &model); - - view.setSource(QUrl("qrc:view.qml")); - view.show(); - - return app.exec(); - } - - #include "main.moc" - \endcode - - \code - // view.qml - import Qt 4.7 - - ListView { - id: view - width: 200 - height: 200 - model: VisualDataModel { - model: myModel - delegate: Component { - Rectangle { - height: 25; width: 200 - Text { text: filePath } - MouseArea { - anchors.fill: parent; - onClicked: if (hasModelChildren) view.model.rootIndex = view.model.modelIndex(index) - } - } - } - } - } - \endcode + \c main.cpp: + \snippet doc/src/snippets/declarative/visualdatamodel_rootindex/main.cpp 0 + + \c view.qml: + \snippet doc/src/snippets/declarative/visualdatamodel_rootindex/view.qml 0 \sa modelIndex(), parentModelIndex() */ @@ -884,7 +848,7 @@ void QDeclarativeVisualDataModel::setRootIndex(const QVariant &root) /*! \qmlmethod QModelIndex VisualDataModel::modelIndex(int index) - QAbstractItemModel provides a heirachical tree of data, whereas + QAbstractItemModel provides a hierarchical tree of data, whereas QML only operates on list data. This function assists in using tree models in QML. @@ -904,7 +868,7 @@ QVariant QDeclarativeVisualDataModel::modelIndex(int idx) const /*! \qmlmethod QModelIndex VisualDataModel::parentModelIndex() - QAbstractItemModel provides a heirachical tree of data, whereas + QAbstractItemModel provides a hierarchical tree of data, whereas QML only operates on list data. This function assists in using tree models in QML. @@ -998,10 +962,10 @@ QDeclarativeVisualDataModel::ReleaseFlags QDeclarativeVisualDataModel::release(Q The \a parts property selects a VisualDataModel which creates delegates from the part named. This is used in conjunction with - the Package element. + the \l Package element. For example, the code below selects a model which creates - delegates named \e list from a Package: + delegates named \e list from a \l Package: \code VisualDataModel { diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h b/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h index 0bdbbcf..079c9e6 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel_p.h @@ -54,11 +54,6 @@ Q_DECLARE_METATYPE(QModelIndex) QT_BEGIN_NAMESPACE QT_MODULE(Declarative) -/***************************************************************************** - ***************************************************************************** - XXX Experimental - ***************************************************************************** -*****************************************************************************/ class QDeclarativeItem; class QDeclarativeComponent; diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp index 975ad4c..fcaaece 100644 --- a/src/declarative/qml/parser/qdeclarativejslexer.cpp +++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp @@ -57,7 +57,7 @@ #include <string.h> QT_BEGIN_NAMESPACE -Q_DECL_IMPORT extern double qstrtod(const char *s00, char const **se, bool *ok); +Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok); QT_END_NAMESPACE QT_QML_BEGIN_NAMESPACE diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h index d75f0a8..53ff51c 100644 --- a/src/declarative/qml/qdeclarative.h +++ b/src/declarative/qml/qdeclarative.h @@ -67,7 +67,7 @@ QT_BEGIN_HEADER QML_DECLARE_TYPE_HASMETATYPE(INTERFACE) enum { /* TYPEINFO flags */ - QML_HAS_ATTACHED_PROPERTIES = 0x01, + QML_HAS_ATTACHED_PROPERTIES = 0x01 }; #define QML_DECLARE_TYPEINFO(TYPE, FLAGS) \ diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp index 9847079..55ee783 100644 --- a/src/declarative/qml/qdeclarativecomponent.cpp +++ b/src/declarative/qml/qdeclarativecomponent.cpp @@ -78,7 +78,7 @@ class QByteArray; \since 4.7 \brief The Component element encapsulates a QML component description. - Components are reusable, encapsulated Qml element with a well-defined interface. + Components are reusable, encapsulated QML elements with well-defined interfaces. They are often defined in \l {qdeclarativedocuments.html}{Component Files}. The \e Component element allows defining components within a QML file. @@ -547,16 +547,18 @@ QDeclarativeComponent::QDeclarativeComponent(QDeclarativeComponentPrivate &dd, Q /*! \qmlmethod object Component::createObject(parent) - Returns an object instance from this component, or null if object creation fails. + + Creates and returns an object instance of this component that will have the given + \a parent. Returns null if object creation fails. The object will be created in the same context as the one in which the component was created. This function will always return null when called on components which were not created in QML. - Note that if the returned object is to be displayed, its \c parent must be set to - an existing item in a scene, or else the object will not be visible. The parent - argument is required to help you avoid this, you must explicitly pass in null if - you wish to create an object without setting a parent. + If you wish to create an object without setting a parent, specify \c null for + the \a parent value. Note that if the returned object is to be displayed, you + must provide a valid \a parent value or set the returned object's \l{Item::parent}{parent} + property, or else the object will not be visible. */ /*! diff --git a/src/declarative/qml/qdeclarativecontext.cpp b/src/declarative/qml/qdeclarativecontext.cpp index 6a13f15..2221d78 100644 --- a/src/declarative/qml/qdeclarativecontext.cpp +++ b/src/declarative/qml/qdeclarativecontext.cpp @@ -116,7 +116,7 @@ QDeclarativeContextPrivate::QDeclarativeContextPrivate() All properties added explicitly by QDeclarativeContext::setContextProperty() take precedence over the context object's properties. - Contexts form a hierarchy. The root of this heirarchy is the QDeclarativeEngine's + Contexts form a hierarchy. The root of this hierarchy is the QDeclarativeEngine's \l {QDeclarativeEngine::rootContext()}{root context}. A component instance can access the data in its own context, as well as all its ancestor contexts. Data can be made available to all instances by modifying the diff --git a/src/declarative/qml/qdeclarativecontext_p.h b/src/declarative/qml/qdeclarativecontext_p.h index 6b6cd0a..1f5aaf1 100644 --- a/src/declarative/qml/qdeclarativecontext_p.h +++ b/src/declarative/qml/qdeclarativecontext_p.h @@ -108,7 +108,7 @@ public: class QDeclarativeComponentAttached; class QDeclarativeGuardedContextData; -class QDeclarativeContextData +class Q_AUTOTEST_EXPORT QDeclarativeContextData { public: QDeclarativeContextData(); diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 2f2ee08..0715624 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -155,14 +155,26 @@ void QDeclarativeEnginePrivate::defineModule() \qmlclass Qt QDeclarativeEnginePrivate \brief The QML global Qt object provides useful enums and functions from Qt. -The Qt object provides useful enums and functions from Qt, for use in all QML files. +The \c Qt object provides useful enums and functions from Qt, for use in all QML files. + +The \c Qt object is not a QML element; it cannot be instantiated. It is a global object +with enums and functions. To use it, call the members of the global \c Qt object directly. +For example: + +\qml +import Qt 4.7 + +Text { + color: Qt.rgba(255, 0, 0, 1) + text: Qt.md5("hello, world") +} +\endqml -You do not create instances of this type, but instead use the members of the global "Qt" object. \section1 Enums The Qt object contains all enums in the Qt namespace. For example, you can -access the AlignLeft member of the Qt::AlignmentFlag enum with \c Qt.AlignLeft. +access the \c AlignLeft member of the \c Qt::AlignmentFlag enum with \c Qt.AlignLeft. For a full list of enums, see the \l{Qt Namespace} documentation. @@ -172,14 +184,14 @@ data types. This is primarily useful when setting the properties of an item when the property has one of the following types: \list -\o \c color - use \l{Qt::rgba()}{Qt.rgba()}, \l{Qt::darker()}{Qt.darker()}, \l{Qt::lighter()}{Qt.lighter()} or \l{Qt::tint()}{Qt.tint()} +\o \c color - use \l{Qt::rgba()}{Qt.rgba()}, \l{Qt::hsla()}{Qt.hsla()}, \l{Qt::darker()}{Qt.darker()}, \l{Qt::lighter()}{Qt.lighter()} or \l{Qt::tint()}{Qt.tint()} \o \c rect - use \l{Qt::rect()}{Qt.rect()} \o \c point - use \l{Qt::point()}{Qt.point()} \o \c size - use \l{Qt::size()}{Qt.size()} \o \c vector3d - use \l{Qt::vector3d()}{Qt.vector3d()} \endlist -There are also string based constructors for these types, see \l{qdeclarativebasictypes.html}{QML Basic Types}. +There are also string based constructors for these types. See \l{qdeclarativebasictypes.html}{QML Basic Types} for more information. \section1 Date/Time Formatters @@ -200,8 +212,8 @@ items from files or strings. See \l{Dynamic Object Management} for an overview of their use. \list - \o \l{Qt::createComponent}{object Qt.createComponent(url)} - \o \l{Qt::createQmlObject}{object Qt.createQmlObject(string qml, object parent, string filepath)} + \o \l{Qt::createComponent()}{object Qt.createComponent(url)} + \o \l{Qt::createQmlObject()}{object Qt.createQmlObject(string qml, object parent, string filepath)} \endlist */ @@ -1036,14 +1048,15 @@ QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url) /*! \qmlmethod object Qt::createComponent(url) -Returns a \l Component object created from the QML file at the specified \a url, +Returns a \l Component object created using the QML file at the specified \a url, or \c null if there was an error in creating the component. Call \l {Component::createObject()}{Component.createObject()} on the returned component to create an object instance of the component. -Here is an example. Remember that QML files that might be loaded -over the network cannot be expected to be ready immediately. +Here is an example. Notice it checks whether the component \l{Component::status}{status} is +\c Component.Ready before calling \l {Component::createObject()}{createObject()} +in case the QML file is loaded over a network and thus is not ready immediately. \snippet doc/src/snippets/declarative/componentCreation.js 0 \codeline @@ -1083,12 +1096,12 @@ QScriptValue QDeclarativeEnginePrivate::createComponent(QScriptContext *ctxt, QS /*! \qmlmethod object Qt::createQmlObject(string qml, object parent, string filepath) -Returns a new object created from the given \a string of QML with the specified \a parent, +Returns a new object created from the given \a string of QML which will have the specified \a parent, or \c null if there was an error in creating the object. If \a filepath is specified, it will be used for error reporting for the created object. -Example (where \c targetItem is the id of an existing QML item): +Example (where \c parentItem is the id of an existing QML item): \snippet doc/src/snippets/declarative/createQmlObject.qml 0 @@ -1364,7 +1377,7 @@ QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScr /*! \qmlmethod color Qt::rgba(real red, real green, real blue, real alpha) -Returns a Color with the specified \c red, \c green, \c blue and \c alpha components. +Returns a color with the specified \c red, \c green, \c blue and \c alpha components. All components should be in the range 0-1 inclusive. */ QScriptValue QDeclarativeEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine *engine) @@ -1392,7 +1405,7 @@ QScriptValue QDeclarativeEnginePrivate::rgba(QScriptContext *ctxt, QScriptEngine /*! \qmlmethod color Qt::hsla(real hue, real saturation, real lightness, real alpha) -Returns a Color with the specified \c hue, \c saturation, \c lightness and \c alpha components. +Returns a color with the specified \c hue, \c saturation, \c lightness and \c alpha components. All components should be in the range 0-1 inclusive. */ QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine *engine) @@ -1420,7 +1433,9 @@ QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine /*! \qmlmethod rect Qt::rect(int x, int y, int width, int height) -Returns a Rect with the top-left corner at \c x, \c y and the specified \c width and \c height. +Returns a \c rect with the top-left corner at \c x, \c y and the specified \c width and \c height. + +The returned object has \c x, \c y, \c width and \c height attributes with the given values. */ QScriptValue QDeclarativeEnginePrivate::rect(QScriptContext *ctxt, QScriptEngine *engine) { diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp index c658a31..a2e3831 100644 --- a/src/declarative/qml/qdeclarativeimport.cpp +++ b/src/declarative/qml/qdeclarativeimport.cpp @@ -823,7 +823,7 @@ void QDeclarativeImportDatabase::addPluginPath(const QString& path) qDebug() << "QDeclarativeImportDatabase::addPluginPath" << path; QUrl url = QUrl(path); - if (url.isRelative() || url.scheme() == QString::fromLocal8Bit("file")) { + if (url.isRelative() || url.scheme() == QLatin1String("file")) { QDir dir = QDir(path); filePluginPath.prepend(dir.canonicalPath()); } else { @@ -842,7 +842,7 @@ void QDeclarativeImportDatabase::addImportPath(const QString& path) QUrl url = QUrl(path); QString cPath; - if (url.isRelative() || url.scheme() == QString::fromLocal8Bit("file")) { + if (url.isRelative() || url.scheme() == QLatin1String("file")) { QDir dir = QDir(path); cPath = dir.canonicalPath(); } else { diff --git a/src/declarative/qml/qdeclarativeinstruction_p.h b/src/declarative/qml/qdeclarativeinstruction_p.h index dc5f2f8..4627eb3 100644 --- a/src/declarative/qml/qdeclarativeinstruction_p.h +++ b/src/declarative/qml/qdeclarativeinstruction_p.h @@ -158,7 +158,7 @@ public: // // Deferred creation // - Defer, /* defer */ + Defer /* defer */ }; QDeclarativeInstruction() : line(0) {} diff --git a/src/declarative/qml/qdeclarativepropertycache_p.h b/src/declarative/qml/qdeclarativepropertycache_p.h index b01e5cc..72cfeba 100644 --- a/src/declarative/qml/qdeclarativepropertycache_p.h +++ b/src/declarative/qml/qdeclarativepropertycache_p.h @@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE class QDeclarativeEngine; class QMetaProperty; -class QDeclarativePropertyCache : public QDeclarativeRefCount, public QDeclarativeCleanup +class Q_AUTOTEST_EXPORT QDeclarativePropertyCache : public QDeclarativeRefCount, public QDeclarativeCleanup { public: QDeclarativePropertyCache(QDeclarativeEngine *); diff --git a/src/declarative/qml/qdeclarativevaluetype.cpp b/src/declarative/qml/qdeclarativevaluetype.cpp index dbc25bb..c17ec95 100644 --- a/src/declarative/qml/qdeclarativevaluetype.cpp +++ b/src/declarative/qml/qdeclarativevaluetype.cpp @@ -47,6 +47,8 @@ QT_BEGIN_NAMESPACE +Q_DECL_IMPORT extern int qt_defaultDpi(); + template<typename T> int qmlRegisterValueTypeEnums(const char *qmlName) { @@ -909,6 +911,11 @@ void QDeclarativeFontValueType::setStrikeout(bool b) qreal QDeclarativeFontValueType::pointSize() const { + if (font.pointSizeF() == -1) { + if (dpi.isNull) + dpi = qt_defaultDpi(); + return font.pixelSize() * qreal(72.) / qreal(dpi); + } return font.pointSizeF(); } @@ -929,6 +936,11 @@ void QDeclarativeFontValueType::setPointSize(qreal size) int QDeclarativeFontValueType::pixelSize() const { + if (font.pixelSize() == -1) { + if (dpi.isNull) + dpi = qt_defaultDpi(); + return (font.pointSizeF() * dpi) / qreal(72.); + } return font.pixelSize(); } diff --git a/src/declarative/qml/qdeclarativevaluetype_p.h b/src/declarative/qml/qdeclarativevaluetype_p.h index 476c73d..4b1bbd6 100644 --- a/src/declarative/qml/qdeclarativevaluetype_p.h +++ b/src/declarative/qml/qdeclarativevaluetype_p.h @@ -55,6 +55,7 @@ #include "qdeclarativeproperty.h" #include "private/qdeclarativeproperty_p.h" +#include "private/qdeclarativenullablevalue_p_p.h" #include <QtCore/qobject.h> #include <QtCore/qrect.h> @@ -446,7 +447,7 @@ public: InBounce = QEasingCurve::InBounce, OutBounce = QEasingCurve::OutBounce, InOutBounce = QEasingCurve::InOutBounce, OutInBounce = QEasingCurve::OutInBounce, InCurve = QEasingCurve::InCurve, OutCurve = QEasingCurve::OutCurve, - SineCurve = QEasingCurve::SineCurve, CosineCurve = QEasingCurve::CosineCurve, + SineCurve = QEasingCurve::SineCurve, CosineCurve = QEasingCurve::CosineCurve }; QDeclarativeEasingValueType(QObject *parent = 0); @@ -547,6 +548,7 @@ private: QFont font; bool pixelSizeSet; bool pointSizeSet; + mutable QDeclarativeNullableValue<int> dpi; }; QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativeworkerscript.cpp b/src/declarative/qml/qdeclarativeworkerscript.cpp index 2ca030e..aec84a6 100644 --- a/src/declarative/qml/qdeclarativeworkerscript.cpp +++ b/src/declarative/qml/qdeclarativeworkerscript.cpp @@ -521,9 +521,9 @@ void QDeclarativeWorkerScriptEngine::run() that the main GUI thread is not blocked. Messages can be passed between the new thread and the parent thread - using sendMessage() and the onMessage() handler. + using \l sendMessage() and the \l {WorkerScript::onMessage}{onMessage()} handler. - Here is an example: + An example: \snippet doc/src/snippets/declarative/workerscript.qml 0 @@ -541,6 +541,9 @@ void QDeclarativeWorkerScriptEngine::run() called, triggering the \tt WorkerScript.onMessage() handler in \tt script.js. This in turn sends a reply message that is then received by the \tt onMessage() handler of \tt myWorker. + + \sa {declarative/threading/workerscript}{WorkerScript example}, + {declarative/threading/threadedlistmodel}{Threaded ListModel example} */ QDeclarativeWorkerScript::QDeclarativeWorkerScript(QObject *parent) : QObject(parent), m_engine(0), m_scriptId(-1), m_componentComplete(true) @@ -555,7 +558,7 @@ QDeclarativeWorkerScript::~QDeclarativeWorkerScript() /*! \qmlproperty url WorkerScript::source - This holds the url of the javascript file that implements the + This holds the url of the JavaScript file that implements the \tt WorkerScript.onMessage() handler for threaded operations. */ QUrl QDeclarativeWorkerScript::source() const @@ -576,7 +579,7 @@ void QDeclarativeWorkerScript::setSource(const QUrl &source) emit sourceChanged(); } -/* +/*! \qmlmethod WorkerScript::sendMessage(jsobject message) Sends the given \a message to a worker script handler in another diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp index de1c0cb..25cf133 100644 --- a/src/declarative/util/qdeclarativeanimation.cpp +++ b/src/declarative/util/qdeclarativeanimation.cpp @@ -557,6 +557,8 @@ void QDeclarativeAbstractAnimation::timelineComplete() NumberAnimation { ... duration: 200 } } \endcode + + \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} */ /*! \internal @@ -627,6 +629,8 @@ QAbstractAnimation *QDeclarativePauseAnimation::qtAnimation() When used in a transition, ColorAnimation will by default animate all properties of type color that are changing. If a property or properties are explicitly set for the animation, then those will be used instead. + + \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} */ /*! \internal @@ -1082,11 +1086,13 @@ void QDeclarativePropertyAction::transition(QDeclarativeStateActions &actions, \inherits PropertyAnimation \brief The NumberAnimation element allows you to animate changes in properties of type qreal. - Animate a set of properties over 200ms, from their values in the start state to + For example, to animate a set of properties over 200ms, from their values in the start state to their values in the end state of the transition: \code NumberAnimation { properties: "x,y,scale"; duration: 200 } \endcode + + \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} */ /*! @@ -1156,6 +1162,8 @@ void QDeclarativeNumberAnimation::setTo(qreal t) \since 4.7 \inherits PropertyAnimation \brief The Vector3dAnimation element allows you to animate changes in properties of type QVector3d. + + \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} */ /*! @@ -1224,7 +1232,8 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t) When used in a transition RotationAnimation will rotate all properties named "rotation" or "angle". You can override this by providing - your own properties via \c properties or \c property. + your own properties via \l {PropertyAnimation::properties}{properties} or + \l {PropertyAnimation::property}{property}. In the following example we use RotationAnimation to animate the rotation between states via the shortest path. @@ -1238,6 +1247,8 @@ void QDeclarativeVector3dAnimation::setTo(QVector3D t) RotationAnimation { direction: RotationAnimation.Shortest } } \endqml + + \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} */ /*! @@ -1446,7 +1457,7 @@ QDeclarativeListProperty<QDeclarativeAbstractAnimation> QDeclarativeAnimationGro } \endcode - \sa ParallelAnimation + \sa ParallelAnimation, {QML Animation}, {declarative/animation/basics}{Animation basics example} */ QDeclarativeSequentialAnimation::QDeclarativeSequentialAnimation(QObject *parent) : @@ -1508,7 +1519,7 @@ void QDeclarativeSequentialAnimation::transition(QDeclarativeStateActions &actio } \endcode - \sa SequentialAnimation + \sa SequentialAnimation, {QML Animation}, {declarative/animation/basics}{Animation basics example} */ /*! \internal @@ -1657,6 +1668,8 @@ void QDeclarativePropertyAnimationPrivate::convertVariant(QVariant &variant, int Depending on how the animation is used, the set of properties normally used will be different. For more information see the individual property documentation, as well as the \l{QML Animation} introduction. + + \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} */ QDeclarativePropertyAnimation::QDeclarativePropertyAnimation(QObject *parent) @@ -1761,7 +1774,7 @@ void QDeclarativePropertyAnimation::setTo(const QVariant &t) To specify an easing curve you need to specify at least the type. For some curves you can also specify amplitude, period and/or overshoot (more details provided after the table). The default easing curve is - Linear. + \c Easing.Linear. \qml PropertyAnimation { properties: "y"; easing.type: Easing.InOutElastic; easing.amplitude: 2.0; easing.period: 1.5 } @@ -1938,15 +1951,15 @@ void QDeclarativePropertyAnimation::setTo(const QVariant &t) \o \inlineimage qeasingcurve-outinbounce.png \endtable - easing.amplitude is only applicable for bounce and elastic curves (curves of type - Easing.InBounce, Easing.OutBounce, Easing.InOutBounce, Easing.OutInBounce, Easing.InElastic, - Easing.OutElastic, Easing.InOutElastic or Easing.OutInElastic). + \c easing.amplitude is only applicable for bounce and elastic curves (curves of type + \c Easing.InBounce, \c Easing.OutBounce, \c Easing.InOutBounce, \c Easing.OutInBounce, \c Easing.InElastic, + \c Easing.OutElastic, \c Easing.InOutElastic or \c Easing.OutInElastic). - easing.overshoot is only applicable if type is: Easing.InBack, Easing.OutBack, - Easing.InOutBack or Easing.OutInBack. + \c easing.overshoot is only applicable if \c easing.type is: \c Easing.InBack, \c Easing.OutBack, + \c Easing.InOutBack or \c Easing.OutInBack. - easing.period is only applicable if type is: Easing.InElastic, Easing.OutElastic, - Easing.InOutElastic or Easing.OutInElastic. + \c easing.period is only applicable if easing.type is: \c Easing.InElastic, \c Easing.OutElastic, + \c Easing.InOutElastic or \c Easing.OutInElastic. See the \l {declarative/animation/easing}{easing} example for a demonstration of the different easing settings. @@ -2032,8 +2045,9 @@ void QDeclarativePropertyAnimation::setProperties(const QString &prop) The singular forms are slightly optimized, so if you do have only a single target/property to animate you should try to use them. - In many cases these properties do not need to be explicitly specified -- they can be - inferred from the animation framework. + In many cases these properties do not need to be explicitly specified, as they can be + inferred from the animation framework: + \table 80% \row \o Value Source / Behavior @@ -2119,52 +2133,39 @@ QAbstractAnimation *QDeclarativePropertyAnimation::qtAnimation() return d->va; } -struct PropertyUpdater : public QDeclarativeBulkValueUpdater +void QDeclarativeAnimationPropertyUpdater::setValue(qreal v) { - QDeclarativeStateActions actions; - int interpolatorType; //for Number/ColorAnimation - int prevInterpolatorType; //for generic - QVariantAnimation::Interpolator interpolator; - bool reverse; - bool fromSourced; - bool fromDefined; - bool *wasDeleted; - PropertyUpdater() : prevInterpolatorType(0), wasDeleted(0) {} - ~PropertyUpdater() { if (wasDeleted) *wasDeleted = true; } - void setValue(qreal v) - { - bool deleted = false; - wasDeleted = &deleted; - if (reverse) //QVariantAnimation sends us 1->0 when reversed, but we are expecting 0->1 - v = 1 - v; - for (int ii = 0; ii < actions.count(); ++ii) { - QDeclarativeAction &action = actions[ii]; - - if (v == 1.) - QDeclarativePropertyPrivate::write(action.property, action.toValue, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); - else { - if (!fromSourced && !fromDefined) { - action.fromValue = action.property.read(); - if (interpolatorType) - QDeclarativePropertyAnimationPrivate::convertVariant(action.fromValue, interpolatorType); - } - if (!interpolatorType) { - int propType = action.property.propertyType(); - if (!prevInterpolatorType || prevInterpolatorType != propType) { - prevInterpolatorType = propType; - interpolator = QVariantAnimationPrivate::getInterpolator(prevInterpolatorType); - } + bool deleted = false; + wasDeleted = &deleted; + if (reverse) //QVariantAnimation sends us 1->0 when reversed, but we are expecting 0->1 + v = 1 - v; + for (int ii = 0; ii < actions.count(); ++ii) { + QDeclarativeAction &action = actions[ii]; + + if (v == 1.) + QDeclarativePropertyPrivate::write(action.property, action.toValue, QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); + else { + if (!fromSourced && !fromDefined) { + action.fromValue = action.property.read(); + if (interpolatorType) + QDeclarativePropertyAnimationPrivate::convertVariant(action.fromValue, interpolatorType); + } + if (!interpolatorType) { + int propType = action.property.propertyType(); + if (!prevInterpolatorType || prevInterpolatorType != propType) { + prevInterpolatorType = propType; + interpolator = QVariantAnimationPrivate::getInterpolator(prevInterpolatorType); } - if (interpolator) - QDeclarativePropertyPrivate::write(action.property, interpolator(action.fromValue.constData(), action.toValue.constData(), v), QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); } - if (deleted) - return; + if (interpolator) + QDeclarativePropertyPrivate::write(action.property, interpolator(action.fromValue.constData(), action.toValue.constData(), v), QDeclarativePropertyPrivate::BypassInterceptor | QDeclarativePropertyPrivate::DontRemoveBinding); } - wasDeleted = 0; - fromSourced = true; + if (deleted) + return; } -}; + wasDeleted = 0; + fromSourced = true; +} void QDeclarativePropertyAnimation::transition(QDeclarativeStateActions &actions, QDeclarativeProperties &modified, @@ -2194,7 +2195,7 @@ void QDeclarativePropertyAnimation::transition(QDeclarativeStateActions &actions props << d->defaultProperties.split(QLatin1Char(',')); } - PropertyUpdater *data = new PropertyUpdater; + QDeclarativeAnimationPropertyUpdater *data = new QDeclarativeAnimationPropertyUpdater; data->interpolatorType = d->interpolatorType; data->interpolator = d->interpolator; data->reverse = direction == Backward ? true : false; @@ -2319,6 +2320,8 @@ void QDeclarativePropertyAnimation::transition(QDeclarativeStateActions &actions When used in a transition, ParentAnimation will by default animate all ParentChanges. + + \sa {QML Animation}, {declarative/animation/basics}{Animation basics example} */ /*! @@ -2771,7 +2774,7 @@ void QDeclarativeAnchorAnimation::transition(QDeclarativeStateActions &actions, { Q_UNUSED(modified); Q_D(QDeclarativeAnchorAnimation); - PropertyUpdater *data = new PropertyUpdater; + QDeclarativeAnimationPropertyUpdater *data = new QDeclarativeAnimationPropertyUpdater; data->interpolatorType = QMetaType::QReal; data->interpolator = d->interpolator; diff --git a/src/declarative/util/qdeclarativeanimation_p.h b/src/declarative/util/qdeclarativeanimation_p.h index e7cd8a8..3f8fbdd 100644 --- a/src/declarative/util/qdeclarativeanimation_p.h +++ b/src/declarative/util/qdeclarativeanimation_p.h @@ -384,7 +384,7 @@ Q_SIGNALS: }; class QDeclarativeAnimationGroupPrivate; -class QDeclarativeAnimationGroup : public QDeclarativeAbstractAnimation +class Q_AUTOTEST_EXPORT QDeclarativeAnimationGroup : public QDeclarativeAbstractAnimation { Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativeAnimationGroup) diff --git a/src/declarative/util/qdeclarativeanimation_p_p.h b/src/declarative/util/qdeclarativeanimation_p_p.h index 3b0f52e..b6d6bbb 100644 --- a/src/declarative/util/qdeclarativeanimation_p_p.h +++ b/src/declarative/util/qdeclarativeanimation_p_p.h @@ -96,7 +96,7 @@ private: }; //performs an action of type QAbstractAnimationAction -class QActionAnimation : public QAbstractAnimation +class Q_AUTOTEST_EXPORT QActionAnimation : public QAbstractAnimation { Q_OBJECT public: @@ -143,7 +143,7 @@ public: }; //animates QDeclarativeBulkValueUpdater (assumes start and end values will be reals or compatible) -class QDeclarativeBulkValueAnimator : public QVariantAnimation +class Q_AUTOTEST_EXPORT QDeclarativeBulkValueAnimator : public QVariantAnimation { Q_OBJECT public: @@ -378,6 +378,22 @@ public: QList<QDeclarativeItem*> targets; }; +class Q_AUTOTEST_EXPORT QDeclarativeAnimationPropertyUpdater : public QDeclarativeBulkValueUpdater +{ +public: + QDeclarativeStateActions actions; + int interpolatorType; //for Number/ColorAnimation + int prevInterpolatorType; //for generic + QVariantAnimation::Interpolator interpolator; + bool reverse; + bool fromSourced; + bool fromDefined; + bool *wasDeleted; + QDeclarativeAnimationPropertyUpdater() : prevInterpolatorType(0), wasDeleted(0) {} + ~QDeclarativeAnimationPropertyUpdater() { if (wasDeleted) *wasDeleted = true; } + void setValue(qreal v); +}; + QT_END_NAMESPACE #endif // QDECLARATIVEANIMATION_P_H diff --git a/src/declarative/util/qdeclarativeconnections.cpp b/src/declarative/util/qdeclarativeconnections.cpp index 808d196..b364821 100644 --- a/src/declarative/util/qdeclarativeconnections.cpp +++ b/src/declarative/util/qdeclarativeconnections.cpp @@ -72,7 +72,9 @@ public: /*! \qmlclass Connections QDeclarativeConnections \since 4.7 - \brief A Connections object describes generalized connections to signals. + \brief A Connections element describes generalized connections to signals. + + A Connections object creates a connection to a QML signal. When connecting to signals in QML, the usual way is to create an "on<Signal>" handler that reacts when a signal is received, like this: @@ -83,16 +85,16 @@ public: } \endqml - However, in some cases, it is not possible to connect to a signal in this - way, such as: + However, it is not possible to connect to a signal in this way in some + cases, such as when: \list - \i multiple connections to the same signal - \i connections outside the scope of the signal sender - \i connections to targets not defined in QML + \i Multiple connections to the same signal are required + \i Creating connections outside the scope of the signal sender + \i Connecting to targets not defined in QML \endlist - When any of these are needed, the Connections object can be used instead. + When any of these are needed, the Connections element can be used instead. For example, the above code can be changed to use a Connections object, like this: @@ -105,7 +107,7 @@ public: } \endqml - More generally, the Connections object can be a child of some other object than + More generally, the Connections object can be a child of some object other than the sender of the signal: \qml @@ -141,7 +143,7 @@ QDeclarativeConnections::~QDeclarativeConnections() \qmlproperty Object Connections::target This property holds the object that sends the signal. - If not set at all, the target defaults to be the parent of the Connections. + If this property is not set, the \c target defaults to the parent of the Connection. If set to null, no connection is made and any signal handlers are ignored until the target is not null. @@ -175,12 +177,11 @@ void QDeclarativeConnections::setTarget(QObject *obj) /*! \qmlproperty bool Connections::ignoreUnknownSignals - Normally, you will get a runtime error if you try to connect - to signals on an object which the object does not have. + Normally, a connection to a non-existent signal produces runtime errors. - By setting this flag to true, such errors are ignored. This is - useful if you intend to connect to different types of object, handling - a different set of signals for each. + If this property is set to \c true, such errors are ignored. + This is useful if you intend to connect to different types of objects, handling + a different set of signals for each object. */ bool QDeclarativeConnections::ignoreUnknownSignals() const { diff --git a/src/declarative/util/qdeclarativefontloader.cpp b/src/declarative/util/qdeclarativefontloader.cpp index c73f827..83bdb17 100644 --- a/src/declarative/util/qdeclarativefontloader.cpp +++ b/src/declarative/util/qdeclarativefontloader.cpp @@ -79,16 +79,27 @@ public: /*! \qmlclass FontLoader QDeclarativeFontLoader \since 4.7 - \brief This item allows using fonts by name or url. + \brief The FontLoader element allows fonts to be loaded by name or URL. - Example: + The FontLoader element is used to load fonts by name or URL. + + The \l status indicates when the font has been loaded, which is useful + for fonts loaded from remote sources. + + For example: \qml - FontLoader { id: fixedFont; name: "Courier" } - FontLoader { id: webFont; source: "http://www.mysite.com/myfont.ttf" } + import Qt 4.7 - Text { text: "Fixed-size font"; font.family: fixedFont.name } - Text { text: "Fancy font"; font.family: webFont.name } + Column { + FontLoader { id: fixedFont; name: "Courier" } + FontLoader { id: webFont; source: "http://www.mysite.com/myfont.ttf" } + + Text { text: "Fixed-size font"; font.family: fixedFont.name } + Text { text: "Fancy font"; font.family: webFont.name } + } \endqml + + \sa {declarative/text/fonts}{Fonts example} */ QDeclarativeFontLoader::QDeclarativeFontLoader(QObject *parent) : QObject(*(new QDeclarativeFontLoaderPrivate), parent) @@ -183,15 +194,26 @@ void QDeclarativeFontLoader::setName(const QString &name) \o FontLoader.Error - an error occurred while loading the font \endlist - Note that a change in the status property does not cause anything to happen - (although it reflects what has happened to the font loader internally). If you wish - to react to the change in status you need to do it yourself, for example in one - of the following ways: - \list - \o Create a state, so that a state change occurs, e.g. State{name: 'loaded'; when: loader.status = FontLoader.Ready;} - \o Do something inside the onStatusChanged signal handler, e.g. FontLoader{id: loader; onStatusChanged: if(loader.status == FontLoader.Ready) console.log('Loaded');} - \o Bind to the status variable somewhere, e.g. Text{text: if(loader.status!=FontLoader.Ready){'Not Loaded';}else{'Loaded';}} - \endlist + Use this status to provide an update or respond to the status change in some way. + For example, you could: + + \e {Trigger a state change:} + \qml + State { name: 'loaded'; when: loader.status = FontLoader.Ready } + \endqml + + \e {Implement an \c onStatusChanged signal handler:} + \qml + FontLoader { + id: loader + onStatusChanged: if (loader.status == FontLoader.Ready) console.log('Loaded') + } + \endqml + + \e {Bind to the status value:} + \qml + Text { text: loader.status != FontLoader.Ready ? 'Not Loaded' : 'Loaded' } + \endqml */ QDeclarativeFontLoader::Status QDeclarativeFontLoader::status() const { diff --git a/src/declarative/util/qdeclarativelistmodel.cpp b/src/declarative/util/qdeclarativelistmodel.cpp index 7518eb7..ff83227 100644 --- a/src/declarative/util/qdeclarativelistmodel.cpp +++ b/src/declarative/util/qdeclarativelistmodel.cpp @@ -76,125 +76,41 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM For example: - \code - ListModel { - id: fruitModel - ListElement { - name: "Apple" - cost: 2.45 - } - ListElement { - name: "Orange" - cost: 3.25 - } - ListElement { - name: "Banana" - cost: 1.95 - } - } - \endcode + \snippet doc/src/snippets/declarative/listmodel.qml 0 - Roles (properties) must begin with a lower-case letter.The above example defines a + Roles (properties) must begin with a lower-case letter. The above example defines a ListModel containing three elements, with the roles "name" and "cost". Values must be simple constants - either strings (quoted), bools (true, false), numbers, or enum values (like Text.AlignHCenter). The defined model can be used in views such as ListView: - \code - Component { - id: fruitDelegate - Item { - width: 200; height: 50 - Text { text: name } - Text { text: '$'+cost; anchors.right: parent.right } - } - } - ListView { - model: fruitModel - delegate: fruitDelegate - anchors.fill: parent - } - \endcode + \snippet doc/src/snippets/declarative/listmodel-simple.qml 0 + \dots 8 + \snippet doc/src/snippets/declarative/listmodel-simple.qml 1 + \image listmodel.png It is possible for roles to contain list data. In the example below we create a list of fruit attributes: - \code - ListModel { - id: fruitModel - ListElement { - name: "Apple" - cost: 2.45 - attributes: [ - ListElement { description: "Core" }, - ListElement { description: "Deciduous" } - ] - } - ListElement { - name: "Orange" - cost: 3.25 - attributes: [ - ListElement { description: "Citrus" } - ] - } - ListElement { - name: "Banana" - cost: 1.95 - attributes: [ - ListElement { description: "Tropical" }, - ListElement { description: "Seedless" } - ] - } - } - \endcode + \snippet doc/src/snippets/declarative/listmodel-nested.qml model + + The delegate below displays all the fruit attributes: + + \snippet doc/src/snippets/declarative/listmodel-nested.qml delegate + \image listmodel-nested.png - The delegate below will list all the fruit attributes: - \code - Component { - id: fruitDelegate - Item { - width: 200; height: 50 - Text { id: name; text: name } - Text { text: '$'+cost; anchors.right: parent.right } - Row { - anchors.top: name.bottom - spacing: 5 - Text { text: "Attributes:" } - Repeater { - model: attributes - Component { Text { text: description } } - } - } - } - } - \endcode \section2 Modifying list models The content of a ListModel may be created and modified using the clear(), - append(), and set() methods. For example: - - \code - Component { - id: fruitDelegate - Item { - width: 200; height: 50 - Text { text: name } - Text { text: '$'+cost; anchors.right: parent.right } - - // Double the price when clicked. - MouseArea { - anchors.fill: parent - onClicked: fruitModel.set(index, "cost", cost*2) - } - } - } - \endcode + append(), set() and setProperty() methods. For example: + + \snippet doc/src/snippets/declarative/listmodel-modify.qml delegate When creating content dynamically, note that the set of available properties cannot be changed - except by first clearing the model - whatever properties are first added are then the - only permitted properties in the model. + except by first clearing the model. Whatever properties are first added to the model are then the + only permitted properties in the model until it is cleared. \section2 Using threaded list models with WorkerScript @@ -214,11 +130,11 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM \snippet examples/declarative/threading/threadedlistmodel/dataloader.js 0 The application's \tt Timer object periodically sends a message to the - worker script by calling \tt WorkerScript::sendMessage(). When this message - is received, \tt WorkerScript.onMessage() is invoked in + worker script by calling \l WorkerScript::sendMessage(). When this message + is received, \l {WorkerScript::onMessage}{WorkerScript.onMessage()} is invoked in \tt dataloader.js, which appends the current time to the list model. - Note the call to sync() from the \c WorkerScript.onMessage() handler. + Note the call to sync() from the \l {WorkerScript::onMessage}{WorkerScript.onMessage()} handler. You must call sync() or else the changes made to the list from the external thread will not be reflected in the list model in the main thread. @@ -244,7 +160,7 @@ QDeclarativeListModelParser::ListInstruction *QDeclarativeListModelParser::ListM In addition, the WorkerScript cannot add any list data to the model. - \sa {qmlmodels}{Data Models}, WorkerScript, QtDeclarative + \sa {qmlmodels}{Data Models}, {declarative/threading/threadedlistmodel}{Threaded ListModel example}, QtDeclarative */ @@ -454,7 +370,7 @@ void QDeclarativeListModel::insert(int index, const QScriptValue& valuemap) to the end of the list: \code - fruitModel.move(0,fruitModel.count-3,3) + fruitModel.move(0, fruitModel.count - 3, 3) \endcode \sa append() diff --git a/src/declarative/util/qdeclarativepackage.cpp b/src/declarative/util/qdeclarativepackage.cpp index 9617b86..b149120 100644 --- a/src/declarative/util/qdeclarativepackage.cpp +++ b/src/declarative/util/qdeclarativepackage.cpp @@ -48,17 +48,17 @@ QT_BEGIN_NAMESPACE /*! \qmlclass Package QDeclarativePackage - \brief Package provides a collection of named items + \brief Package provides a collection of named items. - The Package class is currently used in conjunction with + The Package class is used in conjunction with VisualDataModel to enable delegates with a shared context to be provided to multiple views. Any item within a Package may be assigned a name via the - \e {Package.name} attached property. + \l{Package::name}{Package.name} attached property. The example below creates a Package containing two named items; - \e list and \e grid. The third element in the package is parented to whichever + \e list and \e grid. The third element in the package (the \l Rectangle) is parented to whichever delegate it should appear in. This allows an item to move between views. @@ -70,7 +70,12 @@ QT_BEGIN_NAMESPACE \snippet examples/declarative/modelviews/package/view.qml 0 - \sa QtDeclarative + \sa {declarative/modelviews/package}{Package example}, QtDeclarative +*/ + +/*! + \qmlattachedproperty bool Package::name + This attached property holds the name of an item within a Package. */ diff --git a/src/declarative/util/qdeclarativepackage_p.h b/src/declarative/util/qdeclarativepackage_p.h index 87d9b80..6b12ef7 100644 --- a/src/declarative/util/qdeclarativepackage_p.h +++ b/src/declarative/util/qdeclarativepackage_p.h @@ -50,15 +50,9 @@ QT_BEGIN_NAMESPACE QT_MODULE(Declarative) -/***************************************************************************** - ***************************************************************************** - XXX Experimental - ***************************************************************************** -*****************************************************************************/ - class QDeclarativePackagePrivate; class QDeclarativePackageAttached; -class QDeclarativePackage : public QObject +class Q_AUTOTEST_EXPORT QDeclarativePackage : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QDeclarativePackage) diff --git a/src/declarative/util/qdeclarativepropertychanges.cpp b/src/declarative/util/qdeclarativepropertychanges.cpp index d99de7a..8e3ec82 100644 --- a/src/declarative/util/qdeclarativepropertychanges.cpp +++ b/src/declarative/util/qdeclarativepropertychanges.cpp @@ -62,11 +62,11 @@ QT_BEGIN_NAMESPACE /*! \qmlclass PropertyChanges QDeclarativePropertyChanges \since 4.7 - \brief The PropertyChanges element describes new property values for a state. + \brief The PropertyChanges element describes new property bindings or values for a state. PropertyChanges provides a state change that modifies the properties of an item. - Here is a property change that modifies the text and color of a Text element + Here is a property change that modifies the text and color of a \l Text element when it is clicked: \qml @@ -89,6 +89,21 @@ QT_BEGIN_NAMESPACE MouseArea { anchors.fill: parent; onClicked: myText.state = 'myState' } } \endqml + + By default, PropertyChanges will establish new bindings where appropriate. + For example, the following creates a new binding for myItem's \c height property. + + \qml + PropertyChanges { + target: myItem + height: parent.height + } + \endqml + + If you don't want a binding to be established (and instead just want to assign + the value of the binding at the time the state is entered), + you should set the PropertyChange's \l{PropertyChanges::explicit}{explicit} + property to \c true. State-specific script for signal handlers can also be specified: @@ -485,8 +500,8 @@ QDeclarativePropertyChanges::ActionList QDeclarativePropertyChanges::actions() If explicit is set to true, any potential bindings will be interpreted as once-off assignments that occur when the state is entered. - In the following example, the addition of explicit prevents myItem.width from - being bound to parent.width. Instead, it is assigned the value of parent.width + In the following example, the addition of explicit prevents \c myItem.width from + being bound to \c parent.width. Instead, it is assigned the value of \c parent.width at the time of the state change. \qml PropertyChanges { diff --git a/src/declarative/util/qdeclarativesmoothedanimation.cpp b/src/declarative/util/qdeclarativesmoothedanimation.cpp index bd48ef0..6b6df4d 100644 --- a/src/declarative/util/qdeclarativesmoothedanimation.cpp +++ b/src/declarative/util/qdeclarativesmoothedanimation.cpp @@ -307,7 +307,7 @@ Rectangle { set to a value such as 0.5 units/second. Animating from 0 to 1.0 with a velocity of 0.5 will take 2000 ms to complete. - \sa SpringFollow + \sa SpringFollow, {QML Animation}, {declarative/animation/basics}{Animation basics example} */ QDeclarativeSmoothedAnimation::QDeclarativeSmoothedAnimation(QObject *parent) diff --git a/src/declarative/util/qdeclarativesmoothedanimation_p_p.h b/src/declarative/util/qdeclarativesmoothedanimation_p_p.h index 81cd229..8cdbea2 100644 --- a/src/declarative/util/qdeclarativesmoothedanimation_p_p.h +++ b/src/declarative/util/qdeclarativesmoothedanimation_p_p.h @@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE -class QSmoothedAnimation : public QAbstractAnimation +class Q_AUTOTEST_EXPORT QSmoothedAnimation : public QAbstractAnimation { public: QSmoothedAnimation(QObject *parent=0); diff --git a/src/declarative/util/qdeclarativestate.cpp b/src/declarative/util/qdeclarativestate.cpp index dc2b2cc..ae19a9c 100644 --- a/src/declarative/util/qdeclarativestate.cpp +++ b/src/declarative/util/qdeclarativestate.cpp @@ -136,12 +136,31 @@ QDeclarativeStateOperation::QDeclarativeStateOperation(QObjectPrivate &dd, QObje \since 4.7 \brief The State element defines configurations of objects and properties. - A state is specified as a set of batched changes from the default configuration. + A \e state is a set of batched changes from the default configuration. + + All items have a default state that defines the default configuration of objects + and property values. New states can be defined by adding State items to the \l {Item::states}{states} property to + allow items to switch between different configurations. These configurations + can, for example, be used to apply different sets of property values or execute + different scripts. + + The following example displays a single Rectangle. In the default state, the rectangle + is colored black. In the "clicked" state, a PropertyChanges element changes the + rectangle's color to red. Clicking within the MouseArea toggles the rectangle's state + between the default state and the "clicked" state, thus toggling the color of the + rectangle between black and red. + + \snippet doc/src/snippets/declarative/state.qml 0 + + Notice the default state is referred to using an empty string (""). + + States are commonly used together with \l {state-transitions}{Transitions} to provide + animations when state changes occur. \note setting the state of an object from within another state of the same object is not allowed. - \sa {qmlstates}{States}, {state-transitions}{Transitions}, QtDeclarative + \sa {declarative/animation/states}{states example}, {qmlstates}{States}, {state-transitions}{Transitions}, QtDeclarative */ /*! @@ -173,7 +192,7 @@ QDeclarativeState::~QDeclarativeState() /*! \qmlproperty string State::name - This property holds the name of the state + This property holds the name of the state. Each state should have a unique name. */ @@ -187,6 +206,13 @@ void QDeclarativeState::setName(const QString &n) { Q_D(QDeclarativeState); d->name = n; + d->named = true; +} + +bool QDeclarativeState::isNamed() const +{ + Q_D(const QDeclarativeState); + return d->named; } bool QDeclarativeState::isWhenKnown() const @@ -197,12 +223,12 @@ bool QDeclarativeState::isWhenKnown() const /*! \qmlproperty bool State::when - This property holds when the state should be applied + This property holds when the state should be applied. - This should be set to an expression that evaluates to true when you want the state to + This should be set to an expression that evaluates to \c true when you want the state to be applied. - If multiple states in a group have \c when clauses that evaluate to true at the same time, + If multiple states in a group have \c when clauses that evaluate to \c true at the same time, the first matching state will be applied. For example, in the following snippet \c state1 will always be selected rather than \c state2 when sharedCondition becomes \c true. @@ -229,7 +255,9 @@ void QDeclarativeState::setWhen(QDeclarativeBinding *when) /*! \qmlproperty string State::extend - This property holds the state that this state extends + This property holds the state that this state extends. + + When a state extends another state, it inherits all the changes of that state. The state being extended is treated as the base state in regards to the changes specified by the extending state. diff --git a/src/declarative/util/qdeclarativestate_p.h b/src/declarative/util/qdeclarativestate_p.h index 25715c6..2e2ce7b 100644 --- a/src/declarative/util/qdeclarativestate_p.h +++ b/src/declarative/util/qdeclarativestate_p.h @@ -84,7 +84,7 @@ public: void deleteFromBinding(); }; -class QDeclarativeActionEvent +class Q_AUTOTEST_EXPORT QDeclarativeActionEvent { public: virtual ~QDeclarativeActionEvent(); @@ -146,6 +146,7 @@ public: QString name() const; void setName(const QString &); + bool isNamed() const; /*'when' is a QDeclarativeBinding to limit state changes oscillation due to the unpredictable order of evaluation of bound expressions*/ diff --git a/src/declarative/util/qdeclarativestate_p_p.h b/src/declarative/util/qdeclarativestate_p_p.h index 4a2af0f..2ef9bb0 100644 --- a/src/declarative/util/qdeclarativestate_p_p.h +++ b/src/declarative/util/qdeclarativestate_p_p.h @@ -101,12 +101,13 @@ class QDeclarativeStatePrivate : public QObjectPrivate public: QDeclarativeStatePrivate() - : when(0), inState(false), group(0) {} + : when(0), named(false), inState(false), group(0) {} typedef QList<QDeclarativeSimpleAction> SimpleActionList; QString name; QDeclarativeBinding *when; + bool named; struct OperationGuard : public QDeclarativeGuard<QDeclarativeStateOperation> { diff --git a/src/declarative/util/qdeclarativestategroup.cpp b/src/declarative/util/qdeclarativestategroup.cpp index 9b042d7..67cd12e 100644 --- a/src/declarative/util/qdeclarativestategroup.cpp +++ b/src/declarative/util/qdeclarativestategroup.cpp @@ -91,8 +91,8 @@ public: \since 4.7 \brief The StateGroup element provides state support for non-Item elements. - Item (and all dervied elements) provides built in support for states and transitions - via its state, states and transitions properties. StateGroup provides an easy way to + Item (and all derived elements) provides built in support for states and transitions + via its \l{Item::state}{state}, \l{Item::states}{states} and \l{Item::transitions}{transitions} properties. StateGroup provides an easy way to use this support in other (non-Item-derived) elements. \qml @@ -263,7 +263,7 @@ void QDeclarativeStateGroup::componentComplete() for (int ii = 0; ii < d->states.count(); ++ii) { QDeclarativeState *state = d->states.at(ii); - if (state->name().isEmpty()) + if (!state->isNamed()) state->setName(QLatin1String("anonymousState") % QString::number(++d->unnamedCount)); } @@ -295,7 +295,7 @@ bool QDeclarativeStateGroupPrivate::updateAutoState() for (int ii = 0; ii < states.count(); ++ii) { QDeclarativeState *state = states.at(ii); if (state->isWhenKnown()) { - if (!state->name().isEmpty()) { + if (state->isNamed()) { if (state->when() && state->when()->evaluate().toBool()) { if (stateChangeDebug()) qWarning() << "Setting auto state due to:" diff --git a/src/declarative/util/qdeclarativestateoperations.cpp b/src/declarative/util/qdeclarativestateoperations.cpp index 99f163e..51e6f99 100644 --- a/src/declarative/util/qdeclarativestateoperations.cpp +++ b/src/declarative/util/qdeclarativestateoperations.cpp @@ -172,6 +172,14 @@ void QDeclarativeParentChangePrivate::doChange(QDeclarativeItem *targetParent, Q items involved in the reparenting (i.e. items in the common ancestor tree for the original and new parent). + The example below displays a large red rectangle and a small blue rectangle, side by side. + When the \c blueRect is clicked, it changes to the "reparented" state: its parent is changed to \c redRect and it is + positioned at (10, 10) within the red rectangle, as specified in the ParentChange. + + \snippet doc/src/snippets/declarative/parentchange.qml 0 + + \image parentchange.png + You can specify at which point in a transition you want a ParentChange to occur by using a ParentAnimation. */ @@ -583,9 +591,9 @@ public: \qmlclass StateChangeScript QDeclarativeStateChangeScript \brief The StateChangeScript element allows you to run a script in a state. - StateChangeScripts are run when entering the state. You can use - ScriptAction to specify at which point in the transition - you want the StateChangeScript to be run. + A StateChangeScript is run upon entering a state. You can optionally use + ScriptAction to specify the point in the transition at which + the StateChangeScript should to be run. \qml State { @@ -687,22 +695,18 @@ QString QDeclarativeStateChangeScript::typeName() const \qmlclass AnchorChanges QDeclarativeAnchorChanges \brief The AnchorChanges element allows you to change the anchors of an item in a state. - In the following example we change the top and bottom anchors of an item: - \qml - State { - name: "reanchored" - AnchorChanges { - target: content; - anchors.top: window.top; - anchors.bottom: window.bottom - } - PropertyChanges { - target: content; - anchors.topMargin: 3 - anchors.bottomMargin: 3; - } - } - \endqml + The AnchorChanges element is used to modify the anchors of an item in a \l State. + + AnchorChanges cannot be used to modify the margins on an item. For this, use + PropertyChanges intead. + + In the following example we change the top and bottom anchors of an item + using AnchorChanges, and the top and bottom anchor margins using + PropertyChanges: + + \snippet doc/src/snippets/declarative/anchorchanges.qml 0 + + \image anchorchanges.png AnchorChanges can be animated using AnchorAnimation. \qml diff --git a/src/declarative/util/qdeclarativesystempalette.cpp b/src/declarative/util/qdeclarativesystempalette.cpp index 6c62446..c334859 100644 --- a/src/declarative/util/qdeclarativesystempalette.cpp +++ b/src/declarative/util/qdeclarativesystempalette.cpp @@ -59,22 +59,25 @@ public: /*! \qmlclass SystemPalette QDeclarativeSystemPalette \since 4.7 - \brief The SystemPalette item gives access to the Qt palettes. - \sa QPalette + \brief The SystemPalette element provides access to the Qt palettes. - Example: - \qml - SystemPalette { id: myPalette; colorGroup: Qt.Active } + The SystemPalette element provides access to the Qt application + palettes. This provides information about the standard colors used + for application windows, buttons and other features. These colors + are grouped into three \e {color groups}: \c Active, \c Inactive, + and \c Disabled. See the QPalette documentation for details about + color groups and the properties provided by SystemPalette. - Rectangle { - width: 640; height: 480 - color: myPalette.window - Text { - anchors.fill: parent - text: "Hello!"; color: myPalette.windowText - } - } - \endqml + This can be used to color items in a way that provides a more + native look and feel. + + The following example creates a palette from the \c Active color + group and uses this to color the window and text items + appropriately: + + \snippet doc/src/snippets/declarative/systempalette.qml 0 + + \sa QPalette */ QDeclarativeSystemPalette::QDeclarativeSystemPalette(QObject *parent) : QObject(*(new QDeclarativeSystemPalettePrivate), parent) @@ -258,10 +261,15 @@ QColor QDeclarativeSystemPalette::highlightedText() const } /*! - \qmlproperty QDeclarativeSystemPalette::ColorGroup SystemPalette::colorGroup + \qmlproperty enumeration SystemPalette::colorGroup + + The color group of the palette. This can be one of: - The color group of the palette. It can be Active, Inactive or Disabled. - Active is the default. + \list + \o SystemPalette.Active (default) + \o SystemPalette.Inactive + \o SystemPalette.Disabled + \endlist \sa QPalette::ColorGroup */ diff --git a/src/declarative/util/qdeclarativetimeline_p_p.h b/src/declarative/util/qdeclarativetimeline_p_p.h index 598c897..61f6bcd 100644 --- a/src/declarative/util/qdeclarativetimeline_p_p.h +++ b/src/declarative/util/qdeclarativetimeline_p_p.h @@ -63,7 +63,7 @@ class QDeclarativeTimeLineValue; class QDeclarativeTimeLineCallback; struct QDeclarativeTimeLinePrivate; class QDeclarativeTimeLineObject; -class QDeclarativeTimeLine : public QAbstractAnimation +class Q_AUTOTEST_EXPORT QDeclarativeTimeLine : public QAbstractAnimation { Q_OBJECT public: @@ -117,7 +117,7 @@ private: QDeclarativeTimeLinePrivate *d; }; -class QDeclarativeTimeLineObject +class Q_AUTOTEST_EXPORT QDeclarativeTimeLineObject { public: QDeclarativeTimeLineObject(); @@ -129,7 +129,7 @@ protected: QDeclarativeTimeLine *_t; }; -class QDeclarativeTimeLineValue : public QDeclarativeTimeLineObject +class Q_AUTOTEST_EXPORT QDeclarativeTimeLineValue : public QDeclarativeTimeLineObject { public: QDeclarativeTimeLineValue(qreal v = 0.) : _v(v) {} @@ -147,7 +147,7 @@ private: qreal _v; }; -class QDeclarativeTimeLineCallback +class Q_AUTOTEST_EXPORT QDeclarativeTimeLineCallback { public: typedef void (*Callback)(void *); diff --git a/src/declarative/util/qdeclarativetimer.cpp b/src/declarative/util/qdeclarativetimer.cpp index 53a9d83..9e18eb5 100644 --- a/src/declarative/util/qdeclarativetimer.cpp +++ b/src/declarative/util/qdeclarativetimer.cpp @@ -80,17 +80,22 @@ public: the text every 500 milliseconds: \qml - Timer { - interval: 500; running: true; repeat: true - onTriggered: time.text = Date().toString() - } - Text { - id: time + import Qt 4.7 + + Item { + Timer { + interval: 500; running: true; repeat: true + onTriggered: time.text = Date().toString() + } + + Text { + id: time + } } \endqml - QDeclarativeTimer is synchronized with the animation timer. Since the animation - timer is usually set to 60fps, the resolution of QDeclarativeTimer will be + The Timer element is synchronized with the animation timer. Since the animation + timer is usually set to 60fps, the resolution of Timer will be at best 16ms. If the Timer is running and one of its properties is changed, the @@ -98,8 +103,6 @@ public: 1000ms has its \e repeat property changed 500ms after starting, the elapsed time will be reset to 0, and the Timer will be triggered 1000ms later. - - \sa {QtDeclarative} */ QDeclarativeTimer::QDeclarativeTimer(QObject *parent) diff --git a/src/declarative/util/qdeclarativetransitionmanager_p_p.h b/src/declarative/util/qdeclarativetransitionmanager_p_p.h index 2e23898..75d11a9 100644 --- a/src/declarative/util/qdeclarativetransitionmanager_p_p.h +++ b/src/declarative/util/qdeclarativetransitionmanager_p_p.h @@ -59,7 +59,7 @@ QT_BEGIN_NAMESPACE class QDeclarativeStatePrivate; class QDeclarativeTransitionManagerPrivate; -class QDeclarativeTransitionManager +class Q_AUTOTEST_EXPORT QDeclarativeTransitionManager { public: QDeclarativeTransitionManager(); diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index 6059ad6..0414e65 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -131,7 +131,7 @@ class QDeclarativeViewPrivate : public QGraphicsViewPrivate, public QDeclarative Q_DECLARE_PUBLIC(QDeclarativeView) public: QDeclarativeViewPrivate() - : root(0), declarativeItemRoot(0), graphicsWidgetRoot(0), component(0), resizeMode(QDeclarativeView::SizeViewToRootObject) {} + : root(0), declarativeItemRoot(0), graphicsWidgetRoot(0), component(0), resizeMode(QDeclarativeView::SizeViewToRootObject), initialSize(0,0) {} ~QDeclarativeViewPrivate() { delete root; } void execute(); void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry); @@ -150,6 +150,7 @@ public: QBasicTimer resizetimer; QDeclarativeView::ResizeMode resizeMode; + QSize initialSize; QElapsedTimer frameTimer; void init(); @@ -586,9 +587,11 @@ void QDeclarativeView::setRootObject(QObject *obj) } if (d->root) { - QSize initialSize = d->rootObjectSize(); - if (initialSize != size()) { - resize(initialSize); + d->initialSize = d->rootObjectSize(); + if (d->initialSize != size()) { + if (!(parentWidget() && parentWidget()->layout())) { + resize(d->initialSize); + } } d->initResize(); } @@ -638,6 +641,15 @@ QSize QDeclarativeView::sizeHint() const } /*! + Returns the initial size of the root object +*/ +QSize QDeclarativeView::initialSize() const +{ + Q_D(const QDeclarativeView); + return d->initialSize; +} + +/*! Returns the view's root \l {QGraphicsObject} {item}. */ QGraphicsObject *QDeclarativeView::rootObject() const diff --git a/src/declarative/util/qdeclarativeview.h b/src/declarative/util/qdeclarativeview.h index e9cff32..cdcf134 100644 --- a/src/declarative/util/qdeclarativeview.h +++ b/src/declarative/util/qdeclarativeview.h @@ -90,6 +90,7 @@ public: QList<QDeclarativeError> errors() const; QSize sizeHint() const; + QSize initialSize() const; Q_SIGNALS: void sceneResized(QSize size); // ??? diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp index 4f9355b..4adef25 100644 --- a/src/declarative/util/qdeclarativexmllistmodel.cpp +++ b/src/declarative/util/qdeclarativexmllistmodel.cpp @@ -523,10 +523,13 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla A XmlListModel could create a model from this data, like this: \qml + import Qt 4.7 + XmlListModel { id: xmlModel source: "http://www.mysite.com/feed.xml" query: "/rss/channel/item" + XmlRole { name: "title"; query: "title/string()" } XmlRole { name: "pubDate"; query: "pubDate/string()" } } @@ -536,7 +539,7 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla a model item for each \c <item> in the XML document. The XmlRole objects define the - model item attributes; here, each model item will have \c title and \c pubDate + model item attributes. Here, each model item will have \c title and \c pubDate attributes that match the \c title and \c pubDate values of its corresponding \c <item>. (See \l XmlRole::query for more examples of valid XPath expressions for XmlRole.) @@ -672,11 +675,11 @@ void QDeclarativeXmlListModel::setSource(const QUrl &src) /*! \qmlproperty string XmlListModel::xml - This property holds XML text set directly. + This property holds the XML data for this model, if set. The text is assumed to be UTF-8 encoded. - If both source and xml are set, xml will be used. + If both \l source and \c xml are set, \c xml will be used. */ QString QDeclarativeXmlListModel::xml() const { @@ -733,6 +736,7 @@ void QDeclarativeXmlListModel::setQuery(const QString &query) source: "http://mysite.com/feed.xml" query: "/feed/entry" namespaceDeclarations: "declare default element namespace 'http://www.w3.org/2005/Atom';" + XmlRole { name: "title"; query: "title/string()" } } \endqml diff --git a/src/declarative/3rdparty/qlistmodelinterface.cpp b/src/declarative/util/qlistmodelinterface.cpp index 98d6a5b..98d6a5b 100644 --- a/src/declarative/3rdparty/qlistmodelinterface.cpp +++ b/src/declarative/util/qlistmodelinterface.cpp diff --git a/src/declarative/3rdparty/qlistmodelinterface_p.h b/src/declarative/util/qlistmodelinterface_p.h index 07592ad..07592ad 100644 --- a/src/declarative/3rdparty/qlistmodelinterface_p.h +++ b/src/declarative/util/qlistmodelinterface_p.h diff --git a/src/declarative/util/util.pri b/src/declarative/util/util.pri index f20bba1..04cfc68 100644 --- a/src/declarative/util/util.pri +++ b/src/declarative/util/util.pri @@ -27,7 +27,8 @@ SOURCES += \ $$PWD/qdeclarativebehavior.cpp \ $$PWD/qdeclarativefontloader.cpp \ $$PWD/qdeclarativestyledtext.cpp \ - $$PWD/qdeclarativelistmodelworkeragent.cpp + $$PWD/qdeclarativelistmodelworkeragent.cpp \ + $$PWD/qlistmodelinterface.cpp HEADERS += \ $$PWD/qdeclarativeutilmodule_p.h\ @@ -61,7 +62,8 @@ HEADERS += \ $$PWD/qdeclarativebehavior_p.h \ $$PWD/qdeclarativefontloader_p.h \ $$PWD/qdeclarativestyledtext_p.h \ - $$PWD/qdeclarativelistmodelworkeragent_p.h + $$PWD/qdeclarativelistmodelworkeragent_p.h \ + $$PWD/qlistmodelinterface_p.h contains(QT_CONFIG, xmlpatterns) { QT+=xmlpatterns diff --git a/src/gui/embedded/qwsmanager_qws.cpp b/src/gui/embedded/qwsmanager_qws.cpp index 79076c5..b0259b9 100644 --- a/src/gui/embedded/qwsmanager_qws.cpp +++ b/src/gui/embedded/qwsmanager_qws.cpp @@ -394,7 +394,7 @@ void QWSManagerPrivate::dirtyRegion(int decorationRegion, const QRegion &clip) { QTLWExtra *topextra = managed->d_func()->extra->topextra; - QWidgetBackingStore *bs = topextra->backingStore; + QWidgetBackingStore *bs = topextra->backingStore.data(); const bool pendingUpdateRequest = bs->isDirty(); if (decorationRegion == QDecoration::All) { diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 9d7354a..8042c46 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -1427,12 +1427,14 @@ QGraphicsItem::~QGraphicsItem() d_ptr->inDestructor = 1; d_ptr->removeExtraItemCache(); +#ifndef QT_NO_GESTURES if (d_ptr->isObject && !d_ptr->gestureContext.isEmpty()) { QGraphicsObject *o = static_cast<QGraphicsObject *>(this); QGestureManager *manager = QGestureManager::instance(); foreach (Qt::GestureType type, d_ptr->gestureContext.keys()) manager->cleanupCachedGestures(o, type); } +#endif clearFocus(); @@ -5687,18 +5689,20 @@ void QGraphicsItem::scroll(qreal dx, qreal dy, const QRectF &rect) return; } - // Find pixmap in cache, then remove to avoid deep copy when modifying.s + // Find pixmap in cache. QPixmap cachedPixmap; if (!QPixmapCache::find(cache->key, &cachedPixmap)) { update(rect); return; } - QPixmapCache::remove(cache->key); QRect scrollRect = (rect.isNull() ? boundingRect() : rect).toAlignedRect(); if (!scrollRect.intersects(cache->boundingRect)) return; // Nothing to scroll. + // Remove from cache to avoid deep copy when modifying. + QPixmapCache::remove(cache->key); + QRegion exposed; cachedPixmap.scroll(dx, dy, scrollRect.translated(-cache->boundingRect.topLeft()), &exposed); @@ -7569,6 +7573,7 @@ QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent QGraphicsItem::d_ptr->isObject = true; } +#ifndef QT_NO_GESTURES /*! Subscribes the graphics object to the given \a gesture with specific \a flags. @@ -7592,6 +7597,8 @@ void QGraphicsObject::ungrabGesture(Qt::GestureType gesture) if (QGraphicsItem::d_ptr->gestureContext.remove(gesture) && QGraphicsItem::d_ptr->scene) QGraphicsItem::d_ptr->scene->d_func()->ungrabGesture(this, gesture); } +#endif // QT_NO_GESTURES + /*! Updates the item's micro focus. This is slot for convenience. diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index 9891af3..d7d5332 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -485,7 +485,9 @@ private: friend class QGraphicsSceneBspTreeIndexPrivate; friend class QGraphicsItemEffectSourcePrivate; friend class QGraphicsTransformPrivate; +#ifndef QT_NO_GESTURES friend class QGestureManager; +#endif friend class ::tst_QGraphicsItem; friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *); friend bool qt_closestItemFirst(const QGraphicsItem *, const QGraphicsItem *); @@ -572,8 +574,10 @@ public: using QObject::children; #endif +#ifndef QT_NO_GESTURES void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags()); void ungrabGesture(Qt::GestureType type); +#endif protected Q_SLOTS: void updateMicroFocus(); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index e812f29..bde6e7d 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -525,7 +525,9 @@ public: QGraphicsItem *focusScopeItem; Qt::InputMethodHints imHints; QGraphicsItem::PanelModality panelModality; +#ifndef QT_NO_GESTURES QMap<Qt::GestureType, Qt::GestureFlags> gestureContext; +#endif // Packed 32 bits quint32 acceptedMouseButtons : 5; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 22c3f92..7b0722e 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -699,6 +699,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) if (!selectionChanging && selectedItems.size() != oldSelectedItemsSize) emit q->selectionChanged(); +#ifndef QT_NO_GESTURES QHash<QGesture *, QGraphicsObject *>::iterator it; for (it = gestureTargets.begin(); it != gestureTargets.end();) { if (it.value() == item) @@ -706,6 +707,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) else ++it; } + QGraphicsObject *dummy = static_cast<QGraphicsObject *>(item); cachedTargetItems.removeOne(dummy); cachedItemGestures.remove(dummy); @@ -713,6 +715,7 @@ void QGraphicsScenePrivate::removeItemHelper(QGraphicsItem *item) foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys()) ungrabGesture(item, gesture); +#endif // QT_NO_GESTURES } /*! @@ -1180,11 +1183,13 @@ bool QGraphicsScenePrivate::filterEvent(QGraphicsItem *item, QEvent *event) bool QGraphicsScenePrivate::sendEvent(QGraphicsItem *item, QEvent *event) { if (QGraphicsObject *object = item->toGraphicsObject()) { +#ifndef QT_NO_GESTURES QGestureManager *gestureManager = QApplicationPrivate::instance()->gestureManager; if (gestureManager) { if (gestureManager->filterEvent(object, event)) return true; } +#endif // QT_NO_GESTURES } if (filterEvent(item, event)) @@ -2602,8 +2607,10 @@ void QGraphicsScene::addItem(QGraphicsItem *item) d->enableTouchEventsOnViews(); } +#ifndef QT_NO_GESTURES foreach (Qt::GestureType gesture, item->d_ptr->gestureContext.keys()) d->grabGesture(item, gesture); +#endif // Update selection lists if (item->isSelected()) @@ -3525,10 +3532,12 @@ bool QGraphicsScene::event(QEvent *event) case QEvent::TouchEnd: d->touchEventHandler(static_cast<QTouchEvent *>(event)); break; +#ifndef QT_NO_GESTURES case QEvent::Gesture: case QEvent::GestureOverride: d->gestureEventHandler(static_cast<QGestureEvent *>(event)); break; +#endif // QT_NO_GESTURES default: return QObject::event(event); } @@ -5637,8 +5646,10 @@ bool QGraphicsScene::sendEvent(QGraphicsItem *item, QEvent *event) void QGraphicsScenePrivate::addView(QGraphicsView *view) { views << view; +#ifndef QT_NO_GESTURES foreach (Qt::GestureType gesture, grabbedGestures.keys()) view->viewport()->grabGesture(gesture); +#endif } void QGraphicsScenePrivate::removeView(QGraphicsView *view) @@ -5968,6 +5979,7 @@ void QGraphicsScenePrivate::leaveModal(QGraphicsItem *panel) dispatchHoverEvent(&hoverEvent); } +#ifndef QT_NO_GESTURES void QGraphicsScenePrivate::gestureTargetsAtHotSpots(const QSet<QGesture *> &gestures, Qt::GestureFlag flag, QHash<QGraphicsObject *, QSet<QGesture *> > *targets, @@ -6356,6 +6368,7 @@ void QGraphicsScenePrivate::ungrabGesture(QGraphicsItem *item, Qt::GestureType g view->viewport()->ungrabGesture(gesture); } } +#endif // QT_NO_GESTURES QT_END_NAMESPACE diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index c34a303..f8615f4 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -313,7 +313,9 @@ private: friend class QGraphicsSceneBspTreeIndex; friend class QGraphicsSceneBspTreeIndexPrivate; friend class QGraphicsItemEffectSourcePrivate; +#ifndef QT_NO_GESTURES friend class QGesture; +#endif }; Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsScene::SceneLayers) diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h index 8ad2a0a..f28dfe9 100644 --- a/src/gui/graphicsview/qgraphicsscene_p.h +++ b/src/gui/graphicsview/qgraphicsscene_p.h @@ -299,6 +299,7 @@ public: void enableTouchEventsOnViews(); QList<QGraphicsObject *> cachedTargetItems; +#ifndef QT_NO_GESTURES QHash<QGraphicsObject *, QSet<QGesture *> > cachedItemGestures; QHash<QGraphicsObject *, QSet<QGesture *> > cachedAlreadyDeliveredGestures; QHash<QGesture *, QGraphicsObject *> gestureTargets; @@ -313,6 +314,7 @@ public: void cancelGesturesForChildren(QGesture *original); void grabGesture(QGraphicsItem *, Qt::GestureType gesture); void ungrabGesture(QGraphicsItem *, Qt::GestureType gesture); +#endif // QT_NO_GESTURES void updateInputMethodSensitivityInViews(); diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index a83b528..0674610 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -2688,10 +2688,12 @@ void QGraphicsView::setupViewport(QWidget *widget) if (d->scene && !d->scene->d_func()->allItemsIgnoreTouchEvents) widget->setAttribute(Qt::WA_AcceptTouchEvents); +#ifndef QT_NO_GESTURES if (d->scene) { foreach (Qt::GestureType gesture, d->scene->d_func()->grabbedGestures.keys()) widget->grabGesture(gesture); } +#endif widget->setAcceptDrops(acceptDrops()); } @@ -2838,6 +2840,7 @@ bool QGraphicsView::viewportEvent(QEvent *event) return true; } +#ifndef QT_NO_GESTURES case QEvent::Gesture: case QEvent::GestureOverride: { @@ -2851,6 +2854,7 @@ bool QGraphicsView::viewportEvent(QEvent *event) } return true; } +#endif // QT_NO_GESTURES default: break; } diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp index a515ef8..34f40a9 100644 --- a/src/gui/image/qiconloader.cpp +++ b/src/gui/image/qiconloader.cpp @@ -63,6 +63,8 @@ #include <private/qt_x11_p.h> #endif +#include <private/qstylehelper_p.h> + QT_BEGIN_NAMESPACE Q_GLOBAL_STATIC(QIconLoader, iconLoaderInstance) @@ -488,14 +490,12 @@ QPixmap PixmapEntry::pixmap(const QSize &size, QIcon::Mode mode, QIcon::State st basePixmap.load(filename); int actualSize = qMin(size.width(), size.height()); - QString key = QLatin1String("$qt_theme_") - + QString::number(basePixmap.cacheKey(), 16) - + QLatin1Char('_') - + QString::number(mode) - + QLatin1Char('_') - + QString::number(qApp->palette().cacheKey(), 16) - + QLatin1Char('_') - + QString::number(actualSize); + + QString key = QLatin1Literal("$qt_theme_") + % HexString<qint64>(basePixmap.cacheKey()) + % HexString<int>(mode) + % HexString<qint64>(qApp->palette().cacheKey()) + % HexString<int>(actualSize); QPixmap cachedPixmap; if (QPixmapCache::find(key, &cachedPixmap)) { diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 98f235e..adc2632 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -272,6 +272,8 @@ bool QImageData::checkForAlphaPixels() const switch (format) { + case QImage::Format_Mono: + case QImage::Format_MonoLSB: case QImage::Format_Indexed8: has_alpha_pixels = has_alpha_clut; break; @@ -4208,6 +4210,7 @@ QImage QImage::createHeuristicMask(bool clipTight) const int w = width(); int h = height(); QImage m(w, h, Format_MonoLSB); + QIMAGE_SANITYCHECK_MEMORY(m); m.setColorCount(2); m.setColor(0, QColor(Qt::color0).rgba()); m.setColor(1, QColor(Qt::color1).rgba()); @@ -4300,6 +4303,7 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const if (!d) return QImage(); QImage maskImage(size(), QImage::Format_MonoLSB); + QIMAGE_SANITYCHECK_MEMORY(maskImage); maskImage.fill(0); uchar *s = maskImage.bits(); @@ -4360,6 +4364,7 @@ QImage QImage::mirrored(bool horizontal, bool vertical) const int h = d->height; // Create result image, copy colormap QImage result(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(result); // check if we ran out of of memory.. if (!result.d) @@ -4497,6 +4502,7 @@ QImage QImage::rgbSwapped() const case Format_ARGB32: case Format_ARGB32_Premultiplied: res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); for (int i = 0; i < d->height; i++) { uint *q = (uint*)res.scanLine(i); uint *p = (uint*)scanLine(i); @@ -4510,6 +4516,7 @@ QImage QImage::rgbSwapped() const break; case Format_RGB16: res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); for (int i = 0; i < d->height; i++) { ushort *q = (ushort*)res.scanLine(i); const ushort *p = (const ushort*)scanLine(i); @@ -4523,6 +4530,7 @@ QImage QImage::rgbSwapped() const break; case Format_ARGB8565_Premultiplied: res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); for (int i = 0; i < d->height; i++) { quint8 *p = (quint8*)scanLine(i); const quint8 *end = p + d->width * sizeof(qargb8565); @@ -4535,6 +4543,7 @@ QImage QImage::rgbSwapped() const break; case Format_RGB666: res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); for (int i = 0; i < d->height; i++) { qrgb666 *q = reinterpret_cast<qrgb666*>(res.scanLine(i)); const qrgb666 *p = reinterpret_cast<const qrgb666*>(scanLine(i)); @@ -4547,6 +4556,7 @@ QImage QImage::rgbSwapped() const break; case Format_ARGB6666_Premultiplied: res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); for (int i = 0; i < d->height; i++) { qargb6666 *q = reinterpret_cast<qargb6666*>(res.scanLine(i)); const qargb6666 *p = reinterpret_cast<const qargb6666*>(scanLine(i)); @@ -4559,6 +4569,7 @@ QImage QImage::rgbSwapped() const break; case Format_RGB555: res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); for (int i = 0; i < d->height; i++) { ushort *q = (ushort*)res.scanLine(i); const ushort *p = (const ushort*)scanLine(i); @@ -4572,6 +4583,7 @@ QImage QImage::rgbSwapped() const break; case Format_ARGB8555_Premultiplied: res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); for (int i = 0; i < d->height; i++) { quint8 *p = (quint8*)scanLine(i); const quint8 *end = p + d->width * sizeof(qargb8555); @@ -4584,6 +4596,7 @@ QImage QImage::rgbSwapped() const break; case Format_RGB888: res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); for (int i = 0; i < d->height; i++) { quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i)); const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i)); @@ -4599,6 +4612,7 @@ QImage QImage::rgbSwapped() const break; case Format_RGB444: res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); for (int i = 0; i < d->height; i++) { quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i)); const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i)); @@ -4613,6 +4627,7 @@ QImage QImage::rgbSwapped() const break; case Format_ARGB4444_Premultiplied: res = QImage(d->width, d->height, d->format); + QIMAGE_SANITYCHECK_MEMORY(res); for (int i = 0; i < d->height; i++) { quint8 *q = reinterpret_cast<quint8*>(res.scanLine(i)); const quint8 *p = reinterpret_cast<const quint8*>(scanLine(i)); diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 3013726..20e4b50 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -82,6 +82,7 @@ #endif #include "qpixmap_raster_p.h" +#include "private/qstylehelper_p.h" QT_BEGIN_NAMESPACE @@ -829,8 +830,14 @@ bool QPixmap::load(const QString &fileName, const char *format, Qt::ImageConvers return false; QFileInfo info(fileName); - QString key = QLatin1String("qt_pixmap_") + info.absoluteFilePath() + QLatin1Char('_') + QString::number(info.lastModified().toTime_t()) + QLatin1Char('_') + - QString::number(info.size()) + QLatin1Char('_') + QString::number(data ? data->pixelType() : QPixmapData::PixmapType); + if (!info.exists()) + return false; + + QString key = QLatin1Literal("qt_pixmap") + % info.absoluteFilePath() + % HexString<uint>(info.lastModified().toTime_t()) + % HexString<quint64>(info.size()) + % HexString<uint>(data ? data->pixelType() : QPixmapData::PixmapType); if (QPixmapCache::find(key, *this)) return true; diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index 7a6a73f..ca21a0c 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -196,9 +196,10 @@ public: static QPixmapCache::KeyData* getKeyData(QPixmapCache::Key *key); QList< QPair<QString,QPixmap> > allPixmaps() const; - void flushDetachedPixmaps(bool nt); + bool flushDetachedPixmaps(bool nt); private: + enum { soon_time = 10000, flush_time = 30000 }; int *keyArray; int theid; int ps; @@ -236,38 +237,44 @@ QPMCache::~QPMCache() cleaning-up, and to not cut down the size of the cache while the cache is in active use. - When the last pixmap has been deleted from the cache, kill the - timer so Qt won't keep the CPU from going into sleep mode. + When the last detached pixmap has been deleted from the cache, kill the + timer so Qt won't keep the CPU from going into sleep mode. Currently + the timer is not restarted when the pixmap becomes unused, but it does + restart once something else is added (i.e. the cache space is actually needed). + + Returns true if any were removed. */ -void QPMCache::flushDetachedPixmaps(bool nt) +bool QPMCache::flushDetachedPixmaps(bool nt) { int mc = maxCost(); setMaxCost(nt ? totalCost() * 3 / 4 : totalCost() -1); setMaxCost(mc); ps = totalCost(); + bool any = false; QHash<QString, QPixmapCache::Key>::iterator it = cacheKeys.begin(); while (it != cacheKeys.end()) { if (!contains(it.value())) { releaseKey(it.value()); it = cacheKeys.erase(it); + any = true; } else { ++it; } } + + return any; } void QPMCache::timerEvent(QTimerEvent *) { bool nt = totalCost() == ps; - flushDetachedPixmaps(nt); - - if (!size()) { + if (!flushDetachedPixmaps(nt)) { killTimer(theid); theid = 0; } else if (nt != t) { killTimer(theid); - theid = startTimer(nt ? 10000 : 30000); + theid = startTimer(nt ? soon_time : flush_time); t = nt; } } @@ -315,7 +322,7 @@ bool QPMCache::insert(const QString& key, const QPixmap &pixmap, int cost) if (success) { cacheKeys.insert(key, cacheKey); if (!theid) { - theid = startTimer(30000); + theid = startTimer(flush_time); t = false; } } else { @@ -331,7 +338,7 @@ QPixmapCache::Key QPMCache::insert(const QPixmap &pixmap, int cost) bool success = QCache<QPixmapCache::Key, QPixmapCacheEntry>::insert(cacheKey, new QPixmapCacheEntry(cacheKey, pixmap), cost); if (success) { if (!theid) { - theid = startTimer(30000); + theid = startTimer(flush_time); t = false; } } else { @@ -352,7 +359,7 @@ bool QPMCache::replace(const QPixmapCache::Key &key, const QPixmap &pixmap, int bool success = QCache<QPixmapCache::Key, QPixmapCacheEntry>::insert(cacheKey, new QPixmapCacheEntry(cacheKey, pixmap), cost); if (success) { if(!theid) { - theid = startTimer(30000); + theid = startTimer(flush_time); t = false; } const_cast<QPixmapCache::Key&>(key) = cacheKey; diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index d081cfd..4cdc4ad 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -44,6 +44,9 @@ #include "qcoefepinputcontext_p.h" #include <qapplication.h> #include <qtextformat.h> +#include <qgraphicsview.h> +#include <qgraphicsscene.h> +#include <qgraphicswidget.h> #include <private/qcore_symbian_p.h> #include <fepitfr.h> @@ -320,12 +323,14 @@ TCoeInputCapabilities QCoeFepInputContext::inputCapabilities() return TCoeInputCapabilities(m_textCapabilities, this, 0); } -static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat) +static QTextCharFormat qt_TCharFormat2QTextCharFormat(const TCharFormat &cFormat, bool validStyleColor) { QTextCharFormat qFormat; - QBrush foreground(QColor(cFormat.iFontPresentation.iTextColor.Internal())); - qFormat.setForeground(foreground); + if (validStyleColor) { + QBrush foreground(QColor(cFormat.iFontPresentation.iTextColor.Internal())); + qFormat.setForeground(foreground); + } qFormat.setFontStrikeOut(cFormat.iFontPresentation.iStrikethrough == EStrikethroughOn); qFormat.setFontUnderline(cFormat.iFontPresentation.iUnderline == EUnderlineOn); @@ -484,10 +489,30 @@ void QCoeFepInputContext::applyHints(Qt::InputMethodHints hints) void QCoeFepInputContext::applyFormat(QList<QInputMethodEvent::Attribute> *attributes) { TCharFormat cFormat; - const QColor styleTextColor = focusWidget() ? focusWidget()->palette().text().color() : - QApplication::palette("QLineEdit").text().color(); - const TLogicalRgb fontColor(TRgb(styleTextColor.red(), styleTextColor.green(), styleTextColor.blue(), styleTextColor.alpha())); - cFormat.iFontPresentation.iTextColor = fontColor; + QColor styleTextColor; + if (QWidget *focused = focusWidget()) { + QGraphicsView *gv = qobject_cast<QGraphicsView*>(focused); + if (!gv) // could be either the QGV or its viewport that has focus + gv = qobject_cast<QGraphicsView*>(focused->parentWidget()); + if (gv) { + if (QGraphicsScene *scene = gv->scene()) { + if (QGraphicsItem *focusItem = scene->focusItem()) { + if (focusItem->isWidget()) { + styleTextColor = static_cast<QGraphicsWidget*>(focusItem)->palette().text().color(); + } + } + } + } else { + styleTextColor = focused->palette().text().color(); + } + } else { + styleTextColor = QApplication::palette("QLineEdit").text().color(); + } + + if (styleTextColor.isValid()) { + const TLogicalRgb fontColor(TRgb(styleTextColor.red(), styleTextColor.green(), styleTextColor.blue(), styleTextColor.alpha())); + cFormat.iFontPresentation.iTextColor = fontColor; + } TInt numChars = 0; TInt charPos = 0; @@ -501,7 +526,7 @@ void QCoeFepInputContext::applyFormat(QList<QInputMethodEvent::Attribute> *attri attributes->append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, charPos, numChars, - QVariant(qt_TCharFormat2QTextCharFormat(cFormat)))); + QVariant(qt_TCharFormat2QTextCharFormat(cFormat, styleTextColor.isValid())))); charPos += numChars; if (charPos >= m_preeditString.size()) { break; diff --git a/src/gui/inputmethod/qximinputcontext_x11.cpp b/src/gui/inputmethod/qximinputcontext_x11.cpp index d048b36..ed5aa23 100644 --- a/src/gui/inputmethod/qximinputcontext_x11.cpp +++ b/src/gui/inputmethod/qximinputcontext_x11.cpp @@ -346,10 +346,7 @@ static XFontSet getFontSet(const QFont &f) extern bool qt_use_rtl_extensions; // from qapplication_x11.cpp #ifndef QT_NO_XKB -extern void q_getLocaleAndDirection(QLocale *locale, - Qt::LayoutDirection *direction, - const QByteArray &layoutName, - const QByteArray &variantName); +extern QLocale q_getKeyboardLocale(const QByteArray &layoutName, const QByteArray &variantName); #endif QXIMInputContext::QXIMInputContext() @@ -407,17 +404,12 @@ QXIMInputContext::QXIMInputContext() QList<QByteArray> layoutNames = QByteArray::fromRawData(names[2], qstrlen(names[2])).split(','); QList<QByteArray> variantNames = QByteArray::fromRawData(names[3], qstrlen(names[3])).split(','); for (int i = 0; i < qMin(layoutNames.count(), variantNames.count()); ++i ) { - QLocale keyboardInputLocale; - Qt::LayoutDirection keyboardInputDirection; QByteArray variantName = variantNames.at(i); const int dashPos = variantName.indexOf("-"); if (dashPos >= 0) variantName.truncate(dashPos); - q_getLocaleAndDirection(&keyboardInputLocale, - &keyboardInputDirection, - layoutNames.at(i), - variantName); - if (keyboardInputDirection == Qt::RightToLeft) + QLocale keyboardInputLocale = q_getKeyboardLocale(layoutNames.at(i), variantName); + if (keyboardInputLocale.textDirection() == Qt::RightToLeft) qt_use_rtl_extensions = true; } } diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 09a3bfe..52767b8 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -146,7 +146,7 @@ static void initResources() QT_BEGIN_NAMESPACE -Q_DECL_IMPORT extern void qt_call_post_routines(); +Q_CORE_EXPORT void qt_call_post_routines(); int QApplicationPrivate::app_compile_version = 0x040000; //we don't know exactly, but it's at least 4.0.0 @@ -187,8 +187,10 @@ QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::T directPainters = 0; #endif +#ifndef QT_NO_GESTURES gestureManager = 0; gestureWidget = 0; +#endif // QT_NO_GESTURES #if defined(Q_WS_X11) || defined(Q_WS_WIN) move_cursor = 0; @@ -3542,7 +3544,7 @@ int QApplication::startDragDistance() void QApplication::setLayoutDirection(Qt::LayoutDirection direction) { - if (layout_direction == direction) + if (layout_direction == direction || direction == Qt::LayoutDirectionAuto) return; layout_direction = direction; @@ -3718,6 +3720,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) #endif // !QT_NO_WHEELEVENT || !QT_NO_TABLETEVENT } +#ifndef QT_NO_GESTURES // walk through parents and check for gestures if (d->gestureManager) { switch (e->type()) { @@ -3762,7 +3765,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) } } } - +#endif // QT_NO_GESTURES // User input and window activation makes tooltips sleep switch (e->type()) { @@ -4267,6 +4270,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) res = d->notify_helper(receiver, e); break; +#ifndef QT_NO_GESTURES case QEvent::NativeGesture: { // only propagate the first gesture event (after the GID_BEGIN) @@ -4345,6 +4349,7 @@ bool QApplication::notify(QObject *receiver, QEvent *e) } break; } +#endif // QT_NO_GESTURES default: res = d->notify_helper(receiver, e); break; @@ -5777,6 +5782,7 @@ Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window, QApplicationPrivate::translateRawTouchEvent(window, deviceType, touchPoints); } +#ifndef QT_NO_GESTURES QGestureManager* QGestureManager::instance() { QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); @@ -5784,6 +5790,7 @@ QGestureManager* QGestureManager::instance() qAppPriv->gestureManager = new QGestureManager(qApp); return qAppPriv->gestureManager; } +#endif // QT_NO_GESTURES // These pixmaps approximate the images in the Windows User Interface Guidelines. diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index c21b982..cb1d063 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -399,7 +399,9 @@ private: friend class QDirectPainter; friend class QDirectPainterPrivate; #endif +#ifndef QT_NO_GESTURES friend class QGestureManager; +#endif #if defined(Q_WS_MAC) || defined(Q_WS_X11) Q_PRIVATE_SLOT(d_func(), void _q_alertTimeOut()) diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index e83cd71..3a3f816 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -84,7 +84,9 @@ class QInputContext; class QObject; class QWidget; class QSocketNotifier; +#ifndef QT_NO_GESTURES class QGestureManager; +#endif extern bool qt_is_gui_used; #ifndef QT_NO_CLIPBOARD @@ -200,6 +202,7 @@ typedef BOOL (WINAPI *PtrRegisterTouchWindow)(HWND, ULONG); typedef BOOL (WINAPI *PtrGetTouchInputInfo)(HANDLE, UINT, PVOID, int); typedef BOOL (WINAPI *PtrCloseTouchInputHandle)(HANDLE); +#ifndef QT_NO_GESTURES typedef BOOL (WINAPI *PtrGetGestureInfo)(HANDLE, PVOID); typedef BOOL (WINAPI *PtrGetGestureExtraArgs)(HANDLE, UINT, PBYTE); typedef BOOL (WINAPI *PtrCloseGestureInfoHandle)(HANDLE); @@ -263,6 +266,8 @@ typedef struct tagGESTURECONFIG #define GID_ROLLOVER 0xf003 #endif +#endif // QT_NO_GESTURES + #endif // Q_WS_WIN class QScopedLoopLevelCounter @@ -519,6 +524,7 @@ public: void sendSyntheticEnterLeave(QWidget *widget); #endif +#ifndef QT_NO_GESTURES QGestureManager *gestureManager; QWidget *gestureWidget; #if defined(Q_WS_X11) || defined(Q_WS_WIN) @@ -526,6 +532,7 @@ public: QPixmap *copy_cursor; QPixmap *link_cursor; #endif +#endif #if defined(Q_WS_WIN) QPixmap *ignore_cursor; #endif @@ -554,6 +561,7 @@ public: QHash<DWORD, int> touchInputIDToTouchPointID; bool translateTouchEvent(const MSG &msg); +#ifndef QT_NO_GESTURES PtrGetGestureInfo GetGestureInfo; PtrGetGestureExtraArgs GetGestureExtraArgs; PtrCloseGestureInfoHandle CloseGestureInfoHandle; @@ -562,6 +570,7 @@ public: PtrBeginPanningFeedback BeginPanningFeedback; PtrUpdatePanningFeedback UpdatePanningFeedback; PtrEndPanningFeedback EndPanningFeedback; +#endif // QT_NO_GESTURES #endif #ifdef QT_RX71_MULTITOUCH diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 8ab82c9..a50fd95 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1032,6 +1032,9 @@ void QSymbianControl::SizeChanged() qwidget->d_func()->syncBackingStore(); if (!slowResize && tlwExtra) tlwExtra->inTopLevelResize = false; + } else { + QResizeEvent *e = new QResizeEvent(newSize, oldSize); + QApplication::postEvent(qwidget, e); } } @@ -1800,19 +1803,27 @@ int QApplicationPrivate::symbianProcessWsEvent(const QSymbianEvent *symbianEvent return 1; const TWsVisibilityChangedEvent *visChangedEvent = event->VisibilityChanged(); QWidget *w = QWidgetPrivate::mapper->value(control); - if (!w->d_func()->maybeTopData()) + QWidget *const window = w->window(); + if (!window->d_func()->maybeTopData()) break; + QRefCountedWidgetBackingStore &backingStore = window->d_func()->maybeTopData()->backingStore; if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::ENotVisible) { - delete w->d_func()->topData()->backingStore; - w->d_func()->topData()->backingStore = 0; + // Decrement backing store reference count + backingStore.deref(); // 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); - w->d_func()->invalidateBuffer(w->rect()); - w->repaint(); + } else if (visChangedEvent->iFlags & TWsVisibilityChangedEvent::EPartiallyVisible) { + if (backingStore.data()) { + // Increment backing store reference count + backingStore.ref(); + } else { + // Create backing store with an initial reference count of 1 + backingStore.create(window); + backingStore.ref(); + w->d_func()->invalidateBuffer(w->rect()); + w->repaint(); + } } return 1; } diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 60fc5e1..09535fa 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -52,9 +52,11 @@ extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.c #include <windowsm.h> #include <tpcshell.h> #ifdef QT_WINCE_GESTURES +#ifndef QT_NO_GESTURES #include <gesture.h> #endif #endif +#endif #include "qapplication.h" #include "qdesktopwidget.h" @@ -198,6 +200,7 @@ struct SHRGINFO { #define SPI_SETSIPINFO 224 #endif +#ifndef QT_NO_GESTURES typedef DWORD (API *AygRecognizeGesture)(SHRGINFO*); static AygRecognizeGesture ptrRecognizeGesture = 0; static bool aygResolved = false; @@ -211,6 +214,7 @@ static void resolveAygLibs() ptrRecognizeGesture = (AygRecognizeGesture) ayglib.resolve("SHRecognizeGesture"); } } +#endif // QT_NO_GESTURES #endif @@ -463,7 +467,9 @@ public: bool translateConfigEvent(const MSG &msg); bool translateCloseEvent(const MSG &msg); bool translateTabletEvent(const MSG &msg, PACKET *localPacketBuf, int numPackets); +#ifndef QT_NO_GESTURES bool translateGestureEvent(const MSG &msg, const GESTUREINFO &gi); +#endif void repolishStyle(QStyle &style); inline void showChildren(bool spontaneous) { d_func()->showChildren(spontaneous); } inline void hideChildren(bool spontaneous) { d_func()->hideChildren(spontaneous); } @@ -843,6 +849,7 @@ void qt_init(QApplicationPrivate *priv, int) ptrSetProcessDPIAware(); #endif +#ifndef QT_NO_GESTURES priv->GetGestureInfo = 0; priv->GetGestureExtraArgs = 0; priv->CloseGestureInfoHandle = 0; @@ -883,6 +890,7 @@ void qt_init(QApplicationPrivate *priv, int) (PtrEndPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), "EndPanningFeedback"); #endif +#endif // QT_NO_GESTURES } /***************************************************************************** @@ -1542,7 +1550,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa case WM_SETTINGCHANGE: #ifdef Q_WS_WINCE // CE SIP hide/show - if (wParam == SPI_SETSIPINFO) { + if (qt_desktopWidget && wParam == SPI_SETSIPINFO) { QResizeEvent re(QSize(0, 0), QSize(0, 0)); // Calculated by QDesktopWidget QApplication::sendEvent(qt_desktopWidget, &re); break; @@ -1667,12 +1675,14 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa shrg.ptDown.y = GET_Y_LPARAM(lParam); shrg.dwFlags = SHRG_RETURNCMD | SHRG_NOANIMATION; resolveAygLibs(); +#ifndef QT_NO_GESTURES if (ptrRecognizeGesture && (ptrRecognizeGesture(&shrg) == GN_CONTEXTMENU)) { if (QApplication::activePopupWidget()) QApplication::activePopupWidget()->close(); QContextMenuEvent e(QContextMenuEvent::Mouse, pos, globalPos); result = qt_sendSpontaneousEvent(alienWidget, &e); } +#endif // QT_NO_GESTURES } } } @@ -2556,6 +2566,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa } result = false; break; +#ifndef QT_NO_GESTURES #if !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES) case WM_GESTURE: { GESTUREINFO gi; @@ -2590,6 +2601,7 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa break; } #endif // !defined(Q_WS_WINCE) || defined(QT_WINCE_GESTURES) +#endif // QT_NO_GESTURES #ifndef QT_NO_CURSOR case WM_SETCURSOR: { QCursor *ovr = QApplication::overrideCursor(); @@ -3825,6 +3837,7 @@ bool QETWidget::translateCloseEvent(const MSG &) return d_func()->close_helper(QWidgetPrivate::CloseWithSpontaneousEvent); } +#ifndef QT_NO_GESTURES bool QETWidget::translateGestureEvent(const MSG &, const GESTUREINFO &gi) { const QPoint widgetPos = QPoint(gi.ptsLocation.x, gi.ptsLocation.y); @@ -3863,7 +3876,7 @@ bool QETWidget::translateGestureEvent(const MSG &, const GESTUREINFO &gi) qt_sendSpontaneousEvent(widget, &event); return true; } - +#endif // QT_NO_GESTURES void QApplication::setCursorFlashTime(int msecs) { diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 78fc704..3664743 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -5268,7 +5268,7 @@ bool QETWidget::translateConfigEvent(const XEvent *event) if (isVisible() && data->crect.size() != oldSize) { Q_ASSERT(d->extra->topextra); - QWidgetBackingStore *bs = d->extra->topextra->backingStore; + QWidgetBackingStore *bs = d->extra->topextra->backingStore.data(); const bool hasStaticContents = bs && bs->hasStaticContents(); // If we have a backing store with static contents, we have to disable the top-level // resize optimization in order to get invalidated regions for resized widgets. diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index 4953c48..eec9699 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -952,12 +952,14 @@ static int qCocoaViewCount = 0; if (!QApplicationPrivate::tryModalHelper(qwidget, 0)) return; +#ifndef QT_NO_GESTURES QNativeGestureEvent qNGEvent; qNGEvent.gestureType = QNativeGestureEvent::Zoom; NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]]; qNGEvent.position = flipPoint(p).toPoint(); qNGEvent.percentage = [event magnification]; qt_sendSpontaneousEvent(qwidget, &qNGEvent); +#endif // QT_NO_GESTURES } - (void)rotateWithEvent:(NSEvent *)event; @@ -965,12 +967,14 @@ static int qCocoaViewCount = 0; if (!QApplicationPrivate::tryModalHelper(qwidget, 0)) return; +#ifndef QT_NO_GESTURES QNativeGestureEvent qNGEvent; qNGEvent.gestureType = QNativeGestureEvent::Rotate; NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]]; qNGEvent.position = flipPoint(p).toPoint(); qNGEvent.percentage = -[event rotation]; qt_sendSpontaneousEvent(qwidget, &qNGEvent); +#endif // QT_NO_GESTURES } - (void)swipeWithEvent:(NSEvent *)event; @@ -978,6 +982,7 @@ static int qCocoaViewCount = 0; if (!QApplicationPrivate::tryModalHelper(qwidget, 0)) return; +#ifndef QT_NO_GESTURES QNativeGestureEvent qNGEvent; qNGEvent.gestureType = QNativeGestureEvent::Swipe; NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]]; @@ -991,6 +996,7 @@ static int qCocoaViewCount = 0; else if ([event deltaY] == -1) qNGEvent.angle = 270.0f; qt_sendSpontaneousEvent(qwidget, &qNGEvent); +#endif // QT_NO_GESTURES } - (void)beginGestureWithEvent:(NSEvent *)event; @@ -998,11 +1004,13 @@ static int qCocoaViewCount = 0; if (!QApplicationPrivate::tryModalHelper(qwidget, 0)) return; +#ifndef QT_NO_GESTURES QNativeGestureEvent qNGEvent; qNGEvent.gestureType = QNativeGestureEvent::GestureBegin; NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]]; qNGEvent.position = flipPoint(p).toPoint(); qt_sendSpontaneousEvent(qwidget, &qNGEvent); +#endif // QT_NO_GESTURES } - (void)endGestureWithEvent:(NSEvent *)event; @@ -1010,11 +1018,13 @@ static int qCocoaViewCount = 0; if (!QApplicationPrivate::tryModalHelper(qwidget, 0)) return; +#ifndef QT_NO_GESTURES QNativeGestureEvent qNGEvent; qNGEvent.gestureType = QNativeGestureEvent::GestureEnd; NSPoint p = [[event window] convertBaseToScreen:[event locationInWindow]]; qNGEvent.position = flipPoint(p).toPoint(); qt_sendSpontaneousEvent(qwidget, &qNGEvent); +#endif // QT_NO_GESTURES } - (void)frameDidChange:(NSNotification *)note diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index acf7184..92eed33 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3421,9 +3421,11 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { case QEvent::ChildRemoved: n = n ? n : "ChildRemoved"; dbg.nospace() << "QChildEvent(" << n << ", " << (static_cast<const QChildEvent*>(e))->child(); return dbg.space(); +#ifndef QT_NO_GESTURES case QEvent::Gesture: n = "Gesture"; break; +#endif default: dbg.nospace() << "QEvent(" << (const void *)e << ", type = " << e->type() << ')'; return dbg.space(); @@ -4254,6 +4256,7 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T return *this; } +#ifndef QT_NO_GESTURES /*! \class QGestureEvent \since 4.6 @@ -4558,4 +4561,6 @@ const QGestureEventPrivate *QGestureEvent::d_func() const */ #endif +#endif // QT_NO_GESTURES + QT_END_NAMESPACE diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 90242fe..9c70c02 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -62,7 +62,9 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) class QAction; +#ifndef QT_NO_GESTURES class QGesture; +#endif class Q_GUI_EXPORT QInputEvent : public QEvent { @@ -824,6 +826,7 @@ protected: friend class QApplicationPrivate; }; +#ifndef QT_NO_GESTURES class QGesture; class QGestureEventPrivate; class Q_GUI_EXPORT QGestureEvent : public QEvent @@ -875,6 +878,7 @@ private: friend class QApplication; friend class QGestureManager; }; +#endif // QT_NO_GESTURES QT_END_NAMESPACE diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index 5c94a23..e323aa9 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -120,6 +120,7 @@ public: qreal pressure; }; +#ifndef QT_NO_GESTURES class QNativeGestureEvent : public QEvent { public: @@ -164,7 +165,7 @@ public: QMap<Qt::GestureType, bool> accepted; QMap<Qt::GestureType, QWidget *> targetWidgets; }; - +#endif // QT_NO_GESTURES class QFileOpenEventPrivate { diff --git a/src/gui/kernel/qeventdispatcher_mac.mm b/src/gui/kernel/qeventdispatcher_mac.mm index 0d93b9f..e26fbde 100644 --- a/src/gui/kernel/qeventdispatcher_mac.mm +++ b/src/gui/kernel/qeventdispatcher_mac.mm @@ -492,6 +492,7 @@ static bool IsMouseOrKeyEvent( NSEvent* event ) case NSOtherMouseDown: case NSOtherMouseUp: case NSOtherMouseDragged: +#ifndef QT_NO_GESTURES #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6 case NSEventTypeGesture: // touch events case NSEventTypeMagnify: @@ -500,6 +501,7 @@ static bool IsMouseOrKeyEvent( NSEvent* event ) case NSEventTypeBeginGesture: case NSEventTypeEndGesture: #endif +#endif // QT_NO_GESTURES result = true; break; diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index 49bdea7..f5688f4 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -42,6 +42,8 @@ #include "qgesture.h" #include "private/qgesture_p.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE /*! @@ -725,3 +727,5 @@ void QTapAndHoldGesture::setPosition(const QPointF &value) } QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index c9bdce6..8c10895 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -49,6 +49,8 @@ #include <QtCore/qrect.h> #include <QtCore/qmetatype.h> +#ifndef QT_NO_GESTURES + QT_BEGIN_HEADER Q_DECLARE_METATYPE(Qt::GestureState) @@ -258,4 +260,6 @@ QT_END_NAMESPACE Q_DECLARE_METATYPE(QGesture::GestureCancelPolicy) QT_END_HEADER +#endif // QT_NO_GESTURES + #endif // QGESTURE_H diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index bf60f97..f5474c1 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -59,6 +59,8 @@ #include "qelapsedtimer.h" #include "private/qobject_p.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE class QGesturePrivate : public QObjectPrivate @@ -179,4 +181,6 @@ public: QT_END_NAMESPACE +#endif // QT_NO_GESTURES + #endif // QGESTURE_P_H diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 43facef..2af031b 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -66,6 +66,8 @@ # define DEBUG qDebug #endif +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE QGestureManager::QGestureManager(QObject *parent) @@ -684,6 +686,7 @@ void QGestureManager::recycle(QGesture *gesture) if (recognizer) { gesture->setGestureCancelPolicy(QGesture::CancelNone); recognizer->reset(gesture); + m_activeGestures.remove(gesture); } else { cleanupGesturesForRemovedRecognizer(gesture); } @@ -691,4 +694,6 @@ void QGestureManager::recycle(QGesture *gesture) QT_END_NAMESPACE +#endif // QT_NO_GESTURES + #include "moc_qgesturemanager_p.cpp" diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h index c452f49..747cb1a 100644 --- a/src/gui/kernel/qgesturemanager_p.h +++ b/src/gui/kernel/qgesturemanager_p.h @@ -58,6 +58,8 @@ #include "private/qwidget_p.h" #include "qgesturerecognizer.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE class QBasicTimer; @@ -143,4 +145,6 @@ private: QT_END_NAMESPACE +#endif // QT_NO_GESTURES + #endif // QGESTUREMANAGER_P_H diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp index 9dcca17..3e23bbf 100644 --- a/src/gui/kernel/qgesturerecognizer.cpp +++ b/src/gui/kernel/qgesturerecognizer.cpp @@ -44,6 +44,8 @@ #include "private/qgesture_p.h" #include "private/qgesturemanager_p.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE /*! @@ -231,3 +233,5 @@ void QGestureRecognizer::unregisterRecognizer(Qt::GestureType type) } QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qgesturerecognizer.h b/src/gui/kernel/qgesturerecognizer.h index 3e17c99..5afb43f 100644 --- a/src/gui/kernel/qgesturerecognizer.h +++ b/src/gui/kernel/qgesturerecognizer.h @@ -45,6 +45,8 @@ #include <QtCore/qglobal.h> #include <QtCore/qnamespace.h> +#ifndef QT_NO_GESTURES + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -95,4 +97,6 @@ QT_END_NAMESPACE QT_END_HEADER +#endif // QT_NO_GESTURES + #endif // QGESTURERECOGNIZER_H diff --git a/src/gui/kernel/qkeymapper_mac.cpp b/src/gui/kernel/qkeymapper_mac.cpp index a7145d4..873b8f9 100644 --- a/src/gui/kernel/qkeymapper_mac.cpp +++ b/src/gui/kernel/qkeymapper_mac.cpp @@ -672,23 +672,7 @@ QKeyMapperPrivate::updateKeyboard() #endif if (iso639Code) { keyboardInputLocale = QLocale(QCFString::toQString(iso639Code)); - QString monday = keyboardInputLocale.dayName(1); - bool rtl = false; - for (int i = 0; i < monday.length(); ++i) { - switch (monday.at(i).direction()) { - default: - break; - case QChar::DirR: - case QChar::DirAL: - case QChar::DirRLE: - case QChar::DirRLO: - rtl = true; - break; - } - if (rtl) - break; - } - keyboardInputDirection = rtl ? Qt::RightToLeft : Qt::LeftToRight; + keyboardInputDirection = keyboardInputLocale.textDirection(); } else { keyboardInputLocale = QLocale::c(); keyboardInputDirection = Qt::LeftToRight; diff --git a/src/gui/kernel/qkeymapper_qws.cpp b/src/gui/kernel/qkeymapper_qws.cpp index 5b6b1c4..63bb46b 100644 --- a/src/gui/kernel/qkeymapper_qws.cpp +++ b/src/gui/kernel/qkeymapper_qws.cpp @@ -52,7 +52,7 @@ QT_USE_NAMESPACE QKeyMapperPrivate::QKeyMapperPrivate() { keyboardInputLocale = QLocale::system(); - keyboardInputDirection = Qt::RightToLeft; + keyboardInputDirection = keyboardInputLocale.textDirection(); } QKeyMapperPrivate::~QKeyMapperPrivate() diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/gui/kernel/qkeymapper_x11.cpp index 807959c..825edbc 100644 --- a/src/gui/kernel/qkeymapper_x11.cpp +++ b/src/gui/kernel/qkeymapper_x11.cpp @@ -80,22 +80,15 @@ QT_BEGIN_NAMESPACE (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF)) #endif -void q_getLocaleAndDirection(QLocale *locale, - Qt::LayoutDirection *direction, - const QByteArray &layoutName, - const QByteArray &variantName) +QLocale q_getKeyboardLocale(const QByteArray &layoutName, const QByteArray &variantName) { int i = 0; while (xkbLayoutData[i].layout != 0) { - if (layoutName == xkbLayoutData[i].layout && variantName == xkbLayoutData[i].variant) { - *locale = QLocale(xkbLayoutData[i].language, xkbLayoutData[i].country); - *direction = xkbLayoutData[i].direction; - return; - } + if (layoutName == xkbLayoutData[i].layout && variantName == xkbLayoutData[i].variant) + return QLocale(xkbLayoutData[i].language, xkbLayoutData[i].country); ++i; } - *locale = QLocale::c(); - *direction = Qt::LeftToRight; + return QLocale::c(); } #endif // QT_NO_XKB @@ -523,10 +516,8 @@ void QKeyMapperPrivate::clearMappings() // if (keyboardLayoutName.isEmpty()) // qWarning("Qt: unable to determine keyboard layout, please talk to qt-bugs@trolltech.com"); ? - q_getLocaleAndDirection(&keyboardInputLocale, - &keyboardInputDirection, - layoutName, - variantName); + keyboardInputLocale = q_getKeyboardLocale(layoutName, variantName); + keyboardInputDirection = keyboardInputLocale.textDirection(); #if 0 qDebug() << "keyboard input locale =" diff --git a/src/gui/kernel/qkeymapper_x11_p.cpp b/src/gui/kernel/qkeymapper_x11_p.cpp index 20fcc86..6308973 100644 --- a/src/gui/kernel/qkeymapper_x11_p.cpp +++ b/src/gui/kernel/qkeymapper_x11_p.cpp @@ -271,13 +271,13 @@ static struct { // name = is:nodeadkeys, description = Iceland { "is", "nodeadkeys", Qt::LeftToRight, QLocale::Icelandic, QLocale::Iceland }, // name = il, description = Israel - { "il", "", Qt::LeftToRight, QLocale::Hebrew, QLocale::Israel }, + { "il", "", Qt::RightToLeft, QLocale::Hebrew, QLocale::Israel }, // name = il:lyx, description = Israel - { "il", "lyx", Qt::LeftToRight, QLocale::Hebrew, QLocale::Israel }, + { "il", "lyx", Qt::RightToLeft, QLocale::Hebrew, QLocale::Israel }, // name = il:si1452, description = Israel - { "il", "si1452", Qt::LeftToRight, QLocale::Hebrew, QLocale::Israel }, + { "il", "si1452", Qt::RightToLeft, QLocale::Hebrew, QLocale::Israel }, // name = il:phonetic, description = Israel - { "il", "phonetic", Qt::LeftToRight, QLocale::Hebrew, QLocale::Israel }, + { "il", "phonetic", Qt::RightToLeft, QLocale::Hebrew, QLocale::Israel }, // name = it, description = Italy { "it", "", Qt::LeftToRight, QLocale::Italian, QLocale::Italy }, // name = it:nodeadkeys, description = Italy @@ -419,11 +419,11 @@ static struct { // name = ch:fr_sundeadkeys, description = Switzerland { "ch", "fr_sundeadkeys", Qt::LeftToRight, QLocale::French, QLocale::Switzerland }, // name = sy, description = Syria - { "sy", "", Qt::RightToLeft, QLocale::Arabic, QLocale::SyrianArabRepublic }, + { "sy", "", Qt::RightToLeft, QLocale::Syriac, QLocale::SyrianArabRepublic }, // name = sy:syc, description = Syria - { "sy", "syc", Qt::RightToLeft, QLocale::Arabic, QLocale::SyrianArabRepublic }, + { "sy", "syc", Qt::RightToLeft, QLocale::Syriac, QLocale::SyrianArabRepublic }, // name = sy:syc_phonetic, description = Syria - { "sy", "syc_phonetic", Qt::RightToLeft, QLocale::Arabic, QLocale::SyrianArabRepublic }, + { "sy", "syc_phonetic", Qt::RightToLeft, QLocale::Syriac, QLocale::SyrianArabRepublic }, // name = tj, description = Tajikistan { "tj", "", Qt::LeftToRight, QLocale::Tajik, QLocale::Tajikistan }, // name = lk, description = Sri Lanka diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp index 931bc33..c2f275a 100644 --- a/src/gui/kernel/qkeysequence.cpp +++ b/src/gui/kernel/qkeysequence.cpp @@ -439,6 +439,10 @@ static const struct { { Qt::Key_MediaPrevious, QT_TRANSLATE_NOOP("QShortcut", "Media Previous") }, { Qt::Key_MediaNext, QT_TRANSLATE_NOOP("QShortcut", "Media Next") }, { Qt::Key_MediaRecord, QT_TRANSLATE_NOOP("QShortcut", "Media Record") }, + //: Media player pause button + { Qt::Key_MediaPause, QT_TRANSLATE_NOOP("QShortcut", "Media Pause") }, + //: Media player button to toggle between playing and paused + { Qt::Key_MediaTogglePlayPause, QT_TRANSLATE_NOOP("QShortcut", "Toggle Media Play/Pause") }, { Qt::Key_HomePage, QT_TRANSLATE_NOOP("QShortcut", "Home Page") }, { Qt::Key_Favorites, QT_TRANSLATE_NOOP("QShortcut", "Favorites") }, { Qt::Key_Search, QT_TRANSLATE_NOOP("QShortcut", "Search") }, @@ -575,13 +579,25 @@ static const struct { // -------------------------------------------------------------- // Device keys - { Qt::Key_Context1, QT_TRANSLATE_NOOP("QShortcut", "Context1") }, - { Qt::Key_Context2, QT_TRANSLATE_NOOP("QShortcut", "Context2") }, - { Qt::Key_Context3, QT_TRANSLATE_NOOP("QShortcut", "Context3") }, - { Qt::Key_Context4, QT_TRANSLATE_NOOP("QShortcut", "Context4") }, - { Qt::Key_Call, QT_TRANSLATE_NOOP("QShortcut", "Call") }, - { Qt::Key_Hangup, QT_TRANSLATE_NOOP("QShortcut", "Hangup") }, - { Qt::Key_Flip, QT_TRANSLATE_NOOP("QShortcut", "Flip") }, + { Qt::Key_Context1, QT_TRANSLATE_NOOP("QShortcut", "Context1") }, + { Qt::Key_Context2, QT_TRANSLATE_NOOP("QShortcut", "Context2") }, + { Qt::Key_Context3, QT_TRANSLATE_NOOP("QShortcut", "Context3") }, + { Qt::Key_Context4, QT_TRANSLATE_NOOP("QShortcut", "Context4") }, + //: Button to start a call (note: a separate button is used to end the call) + { Qt::Key_Call, QT_TRANSLATE_NOOP("QShortcut", "Call") }, + //: Button to end a call (note: a separate button is used to start the call) + { Qt::Key_Hangup, QT_TRANSLATE_NOOP("QShortcut", "Hangup") }, + //: Button that will hang up if we're in call, or make a call if we're not. + { Qt::Key_ToggleCallHangup, QT_TRANSLATE_NOOP("QShortcut", "Toggle Call/Hangup") }, + { Qt::Key_Flip, QT_TRANSLATE_NOOP("QShortcut", "Flip") }, + //: Button to trigger voice dialling + { Qt::Key_VoiceDial, QT_TRANSLATE_NOOP("QShortcut", "Voice Dial") }, + //: Button to redial the last number called + { Qt::Key_LastNumberRedial, QT_TRANSLATE_NOOP("QShortcut", "Last Number Redial") }, + //: Button to trigger the camera shutter (take a picture) + { Qt::Key_Camera, QT_TRANSLATE_NOOP("QShortcut", "Camera Shutter") }, + //: Button to focus the camera + { Qt::Key_CameraFocus, QT_TRANSLATE_NOOP("QShortcut", "Camera Focus") }, // -------------------------------------------------------------- // Japanese keyboard support diff --git a/src/gui/kernel/qmacgesturerecognizer_mac.mm b/src/gui/kernel/qmacgesturerecognizer_mac.mm index fba839b..0ccbb52 100644 --- a/src/gui/kernel/qmacgesturerecognizer_mac.mm +++ b/src/gui/kernel/qmacgesturerecognizer_mac.mm @@ -47,6 +47,8 @@ #include "qwidget.h" #include "qdebug.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE QMacSwipeGestureRecognizer::QMacSwipeGestureRecognizer() @@ -260,3 +262,5 @@ void QMacPanGestureRecognizer::reset(QGesture *gesture) #endif // QT_MAC_USE_COCOA QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qmacgesturerecognizer_mac_p.h b/src/gui/kernel/qmacgesturerecognizer_mac_p.h index dd8a150..f48c160 100644 --- a/src/gui/kernel/qmacgesturerecognizer_mac_p.h +++ b/src/gui/kernel/qmacgesturerecognizer_mac_p.h @@ -57,6 +57,8 @@ #include "qpoint.h" #include "qgesturerecognizer.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE class QMacSwipeGestureRecognizer : public QGestureRecognizer @@ -99,4 +101,6 @@ private: QT_END_NAMESPACE +#endif // QT_NO_GESTURES + #endif // QMACSWIPEGESTURERECOGNIZER_MAC_P_H diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index a575717..6960838 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -47,6 +47,8 @@ #include "qabstractscrollarea.h" #include "qdebug.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE QPanGestureRecognizer::QPanGestureRecognizer() @@ -563,3 +565,5 @@ void QTapAndHoldGestureRecognizer::reset(QGesture *state) } QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index 64505d8..da73b85 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -56,6 +56,8 @@ #include "qgesturerecognizer.h" #include "private/qgesture_p.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE class QPanGestureRecognizer : public QGestureRecognizer @@ -110,4 +112,6 @@ public: QT_END_NAMESPACE +#endif // QT_NO_GESTURES + #endif // QSTANDARDGESTURES_P_H diff --git a/src/gui/kernel/qwhatsthis.cpp b/src/gui/kernel/qwhatsthis.cpp index 6181b62..ff4641e 100644 --- a/src/gui/kernel/qwhatsthis.cpp +++ b/src/gui/kernel/qwhatsthis.cpp @@ -143,7 +143,7 @@ QT_BEGIN_NAMESPACE \sa QToolTip */ -Q_DECL_IMPORT extern void qDeleteInEventHandler(QObject *o); +Q_CORE_EXPORT void qDeleteInEventHandler(QObject *o); class QWhatsThat : public QWidget { diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index b5879ae..492954a 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -67,6 +67,7 @@ # include "qt_mac_p.h" # include "qt_cocoa_helpers_mac_p.h" # include "qmainwindow.h" +# include "qtoolbar.h" #endif #if defined(Q_WS_QWS) # include "qwsdisplay_qws.h" @@ -161,6 +162,51 @@ static inline bool hasBackingStoreSupport() extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp + +QRefCountedWidgetBackingStore::QRefCountedWidgetBackingStore() + : m_ptr(0) + , m_count(0) +{ + +} + +QRefCountedWidgetBackingStore::~QRefCountedWidgetBackingStore() +{ + delete m_ptr; +} + +void QRefCountedWidgetBackingStore::create(QWidget *widget) +{ + destroy(); + m_ptr = new QWidgetBackingStore(widget); + m_count = 0; +} + +void QRefCountedWidgetBackingStore::destroy() +{ + delete m_ptr; + m_ptr = 0; + m_count = 0; +} + +void QRefCountedWidgetBackingStore::ref() +{ + Q_ASSERT(m_ptr); + ++m_count; +} + +void QRefCountedWidgetBackingStore::deref() +{ + if (m_count) { + Q_ASSERT(m_ptr); + if (0 == --m_count) { + delete m_ptr; + m_ptr = 0; + } + } +} + + QWidgetPrivate::QWidgetPrivate(int version) : QObjectPrivate(version) , extra(0) @@ -202,7 +248,9 @@ QWidgetPrivate::QWidgetPrivate(int version) , picture(0) #elif defined(Q_WS_WIN) , noPaintOnScreen(0) + #ifndef QT_NO_GESTURES , nativeGesturePanEnabled(0) + #endif #elif defined(Q_WS_MAC) , needWindowChange(0) , hasAlienChildren(0) @@ -1348,11 +1396,9 @@ void QWidget::create(WId window, bool initializeWindow, bool destroyOldWindow) // a real toplevel window needs a backing store if (isWindow() && windowType() != Qt::Desktop) { - delete d->topData()->backingStore; - // QWidgetBackingStore will check this variable, hence it must be 0 - d->topData()->backingStore = 0; + d->topData()->backingStore.destroy(); if (hasBackingStoreSupport()) - d->topData()->backingStore = new QWidgetBackingStore(this); + d->topData()->backingStore.create(this); } d->setModal_sys(); @@ -1397,8 +1443,10 @@ QWidget::~QWidget() qWarning("QWidget: %s (%s) deleted while being painted", className(), name()); #endif +#ifndef QT_NO_GESTURES foreach (Qt::GestureType type, d->gestureContext.keys()) ungrabGesture(type); +#endif // force acceptDrops false before winId is destroyed. d->registerDropSite(false); @@ -1478,8 +1526,7 @@ QWidget::~QWidget() // 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; + d->extra->topextra->backingStore.destroy(); } #endif if (QWidgetBackingStore *bs = d->maybeBackingStore()) { @@ -1576,7 +1623,6 @@ void QWidgetPrivate::createTLExtra() QTLWExtra* x = extra->topextra = new QTLWExtra; x->icon = 0; x->iconPixmap = 0; - x->backingStore = 0; x->windowSurface = 0; x->sharedPainter = 0; x->incw = x->inch = 0; @@ -1660,7 +1706,7 @@ void QWidgetPrivate::deleteExtra() #endif if (extra->topextra) { deleteTLSysExtra(); - delete extra->topextra->backingStore; + extra->topextra->backingStore.destroy(); delete extra->topextra->icon; delete extra->topextra->iconPixmap; #if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) @@ -4783,6 +4829,11 @@ void QWidget::setLayoutDirection(Qt::LayoutDirection direction) { Q_D(QWidget); + if (direction == Qt::LayoutDirectionAuto) { + unsetLayoutDirection(); + return; + } + setAttribute(Qt::WA_SetLayoutDirection); d->setLayoutDirection_helper(direction); } @@ -8539,9 +8590,11 @@ bool QWidget::event(QEvent *event) #endif // Q_WS_MAC break; } +#ifndef QT_NO_GESTURES case QEvent::Gesture: event->ignore(); break; +#endif #ifndef QT_NO_PROPERTIES case QEvent::DynamicPropertyChange: { const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName(); @@ -9664,46 +9717,58 @@ QWidget *QWidget::childAt(const QPoint &p) const QWidget *QWidgetPrivate::childAt_helper(const QPoint &p, bool ignoreChildrenInDestructor) const { - Q_Q(const QWidget); + if (children.isEmpty()) + return 0; + #ifdef Q_WS_MAC + Q_Q(const QWidget); + // Unified tool bars on the Mac require special handling since they live outside + // QMainWindow's geometry(). See commit: 35667fd45ada49269a5987c235fdedfc43e92bb8 bool includeFrame = q->isWindow() && qobject_cast<const QMainWindow *>(q) && static_cast<const QMainWindow *>(q)->unifiedTitleAndToolBarOnMac(); + if (includeFrame) + return childAtRecursiveHelper(p, ignoreChildrenInDestructor, includeFrame); #endif - if ( -#ifdef Q_WS_MAC - !includeFrame && -#endif - !q->rect().contains(p)) + if (!pointInsideRectAndMask(p)) return 0; + return childAtRecursiveHelper(p, ignoreChildrenInDestructor); +} - for (int i = children.size(); i > 0 ;) { - --i; - QWidget *w = qobject_cast<QWidget *>(children.at(i)); - if (w && !w->isWindow() && !w->isHidden() - && (w->geometry().contains(p) -#ifdef Q_WS_MAC - || (includeFrame && w->geometry().contains(qt_mac_nativeMapFromParent(w, p))) +QWidget *QWidgetPrivate::childAtRecursiveHelper(const QPoint &p, bool ignoreChildrenInDestructor, bool includeFrame) const +{ +#ifndef Q_WS_MAC + Q_UNUSED(includeFrame); #endif - )) { - if (ignoreChildrenInDestructor && w->data->in_destructor) - continue; - if (w->testAttribute(Qt::WA_TransparentForMouseEvents)) - continue; - QPoint childPoint = w->mapFromParent(p); -#ifdef Q_WS_MAC - if (includeFrame && !w->geometry().contains(p)) - childPoint = qt_mac_nativeMapFromParent(w, p); -#endif - if (QWidget *t = w->d_func()->childAt_helper(childPoint, ignoreChildrenInDestructor)) - return t; - // if WMouseNoMask is set the widget mask is ignored, if - // the widget has no mask then the WMouseNoMask flag has no - // effect - if (w->testAttribute(Qt::WA_MouseNoMask) || w->mask().contains(childPoint) - || w->mask().isEmpty()) - return w; + for (int i = children.size() - 1; i >= 0; --i) { + QWidget *child = qobject_cast<QWidget *>(children.at(i)); + if (!child || child->isWindow() || child->isHidden() || child->testAttribute(Qt::WA_TransparentForMouseEvents) + || (ignoreChildrenInDestructor && child->data->in_destructor)) { + continue; } + + // Map the point 'p' from parent coordinates to child coordinates. + QPoint childPoint = p; +#ifdef Q_WS_MAC + // 'includeFrame' is true if the child's parent is a top-level QMainWindow with an unified tool bar. + // An unified tool bar on the Mac lives outside QMainWindow's geometry(), so a normal + // QWidget::mapFromParent won't do the trick. + if (includeFrame && qobject_cast<QToolBar *>(child)) + childPoint = qt_mac_nativeMapFromParent(child, p); + else +#endif + childPoint -= child->data->crect.topLeft(); + + // Check if the point hits the child. + if (!child->d_func()->pointInsideRectAndMask(childPoint)) + continue; + + // Do the same for the child's descendants. + if (QWidget *w = child->d_func()->childAtRecursiveHelper(childPoint, ignoreChildrenInDestructor)) + return w; + + // We have found our target; namely the child at position 'p'. + return child; } return 0; } @@ -11957,6 +12022,7 @@ QGraphicsProxyWidget *QWidget::graphicsProxyWidget() const Synonym for QList<QWidget *>. */ +#ifndef QT_NO_GESTURES /*! Subscribes the widget to a given \a gesture with specific \a flags. @@ -11984,7 +12050,7 @@ void QWidget::ungrabGesture(Qt::GestureType gesture) manager->cleanupCachedGestures(this, gesture); } } - +#endif // QT_NO_GESTURES /*! \typedef WId diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index e12148b..941bd68 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -360,8 +360,10 @@ public: void setGraphicsEffect(QGraphicsEffect *effect); #endif //QT_NO_GRAPHICSEFFECT +#ifndef QT_NO_GESTURES void grabGesture(Qt::GestureType type, Qt::GestureFlags flags = Qt::GestureFlags()); void ungrabGesture(Qt::GestureType type); +#endif public Q_SLOTS: void setWindowTitle(const QString &); @@ -742,8 +744,10 @@ private: friend class QGraphicsProxyWidgetPrivate; friend class QStyleSheetStyle; friend struct QWidgetExceptionCleaner; +#ifndef QT_NO_GESTURES friend class QGestureManager; friend class QWinNativePanGestureRecognizer; +#endif // QT_NO_GESTURES friend class QWidgetEffectSourcePrivate; #ifdef Q_WS_MAC diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index f12c956..280712a 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -752,6 +752,7 @@ static OSWindowRef qt_mac_create_window(QWidget *, WindowClass wclass, WindowAtt return window; } +#ifndef QT_NO_GESTURES #if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 /* We build the release package against the 10.4 SDK. So, to enable gestures for applications running on @@ -768,6 +769,7 @@ enum { kEventParamMagnificationAmount = 'magn' }; #endif +#endif // QT_NO_GESTURES // window events static EventTypeSpec window_events[] = { @@ -1076,6 +1078,7 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, handled_event = false; break; } +#ifndef QT_NO_GESTURES case kEventClassGesture: { // First, find the widget that was under // the mouse when the gesture happened: @@ -1142,6 +1145,7 @@ OSStatus QWidgetPrivate::qt_window_event(EventHandlerCallRef er, EventRef event, QApplication::sendSpontaneousEvent(widget, &qNGEvent); break; } +#endif // QT_NO_GESTURES default: handled_event = false; @@ -2684,6 +2688,7 @@ QWidget::macCGHandle() const void QWidget::destroy(bool destroyWindow, bool destroySubWindows) { Q_D(QWidget); + d->aboutToDestroy(); if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); d->deactivateWidgetCleanup(); @@ -3990,10 +3995,10 @@ static void qt_mac_update_widget_position(QWidget *q, QRect oldRect, QRect newRe (oldRect.isValid() == false || newRect.isValid() == false) || // the position update is a part of a drag-and-drop operation - QDragManager::self()->object || - - // we are on Panther (no HIViewSetNeedsDisplayInRect) - QSysInfo::MacintoshVersion < QSysInfo::MV_10_4 + QDragManager::self()->object || + + // we are on Panther (no HIViewSetNeedsDisplayInRect) + QSysInfo::MacintoshVersion < QSysInfo::MV_10_4 ){ HIViewSetFrame(view, &bounds); return; diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 3f494d8..587d7fb 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -110,13 +110,53 @@ class QWidgetItemV2; class QStyle; +class Q_AUTOTEST_EXPORT QRefCountedWidgetBackingStore +{ +public: + QRefCountedWidgetBackingStore(); + ~QRefCountedWidgetBackingStore(); + + void create(QWidget *tlw); + void destroy(); + + void ref(); + void deref(); + + inline QWidgetBackingStore* data() + { + return m_ptr; + } + + inline QWidgetBackingStore* operator->() + { + return m_ptr; + } + + inline QWidgetBackingStore& operator*() + { + return *m_ptr; + } + + inline operator bool() const + { + return (0 != m_ptr); + } + +private: + Q_DISABLE_COPY(QRefCountedWidgetBackingStore) + +private: + QWidgetBackingStore* m_ptr; + int m_count; +}; + struct QTLWExtra { // *************************** Cross-platform variables ***************************** // Regular pointers (keep them together to avoid gaps on 64 bits architectures). QIcon *icon; // widget icon QPixmap *iconPixmap; - QWidgetBackingStore *backingStore; + QRefCountedWidgetBackingStore backingStore; QWindowSurface *windowSurface; QPainter *sharedPainter; @@ -502,13 +542,20 @@ public: bool setMinimumSize_helper(int &minw, int &minh); bool setMaximumSize_helper(int &maxw, int &maxh); void setConstraints_sys(); + bool pointInsideRectAndMask(const QPoint &) const; QWidget *childAt_helper(const QPoint &, bool) const; + QWidget *childAtRecursiveHelper(const QPoint &p, bool, bool includeFrame = false) const; void updateGeometry_helper(bool forceUpdate); void getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const; void setLayoutItemMargins(int left, int top, int right, int bottom); void setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt = 0); + // aboutToDestroy() is called just before the contents of + // QWidget::destroy() is executed. It's used to signal QWidget + // sub-classes that their internals are about to be released. + virtual void aboutToDestroy() {} + QInputContext *inputContext() const; inline QWidget *effectiveFocusWidget() { QWidget *w = q_func(); @@ -685,7 +732,9 @@ public: #ifndef QT_NO_ACTION QList<QAction*> actions; #endif +#ifndef QT_NO_GESTURES QMap<Qt::GestureType, Qt::GestureFlags> gestureContext; +#endif // Bit fields. uint high_attributes[4]; // the low ones are in QWidget::widget_attributes @@ -714,8 +763,9 @@ public: void updateX11AcceptFocus(); #elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine() +#ifndef QT_NO_GESTURES uint nativeGesturePanEnabled : 1; - +#endif bool shouldShowMaximizeButton(); void winUpdateIsOpaque(); void reparentChildren(); @@ -925,11 +975,18 @@ inline void QWidgetPrivate::setSharedPainter(QPainter *painter) x->sharedPainter = painter; } +inline bool QWidgetPrivate::pointInsideRectAndMask(const QPoint &p) const +{ + Q_Q(const QWidget); + return q->rect().contains(p) && (!extra || !extra->hasMask || q->testAttribute(Qt::WA_MouseNoMask) + || extra->mask.contains(p)); +} + inline QWidgetBackingStore *QWidgetPrivate::maybeBackingStore() const { Q_Q(const QWidget); QTLWExtra *x = q->window()->d_func()->maybeTopData(); - return x ? x->backingStore : 0; + return x ? x->backingStore.data() : 0; } QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget_qws.cpp b/src/gui/kernel/qwidget_qws.cpp index b827e8b..3145136 100644 --- a/src/gui/kernel/qwidget_qws.cpp +++ b/src/gui/kernel/qwidget_qws.cpp @@ -256,7 +256,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool /*destro void QWidget::destroy(bool destroyWindow, bool destroySubWindows) { Q_D(QWidget); - + d->aboutToDestroy(); if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 02e7cb8..68f9470 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -433,6 +433,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de // Request mouse move events. drawableWindow->PointerFilter(EPointerFilterEnterExit | EPointerFilterMove | EPointerFilterDrag, 0); + drawableWindow->EnableVisibilityChangeEvents(); if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) { activateSymbianWindow(control.data()); @@ -487,11 +488,8 @@ void QWidgetPrivate::show_sys() && !S60->buttonGroupContainer() && !S60->statusPane()) { bool isFullscreen = q->windowState() & Qt::WindowFullScreen; - bool cbaRequested = q->windowFlags() & Qt::WindowSoftkeysVisibleHint; - // If the window is fullscreen and has not explicitly requested that the CBA be visible - // we delay the creation even more. - if ((!isFullscreen || cbaRequested) && !q->testAttribute(Qt::WA_DontShowOnScreen)) { + if (!q->testAttribute(Qt::WA_DontShowOnScreen)) { // Create the status pane and CBA here CEikAppUi *ui = static_cast<CEikAppUi *>(S60->appUi()); @@ -911,14 +909,12 @@ void QWidgetPrivate::registerDropSite(bool /* on */) void QWidgetPrivate::createTLSysExtra() { - extra->topextra->backingStore = 0; extra->topextra->inExpose = 0; } void QWidgetPrivate::deleteTLSysExtra() { - delete extra->topextra->backingStore; - extra->topextra->backingStore = 0; + extra->topextra->backingStore.destroy(); } void QWidgetPrivate::createSysExtra() @@ -1181,6 +1177,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) void QWidget::destroy(bool destroyWindow, bool destroySubWindows) { Q_D(QWidget); + d->aboutToDestroy(); if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(geometry()); d->deactivateWidgetCleanup(); diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index 5482da3..9c65aa0 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -544,6 +544,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO void QWidget::destroy(bool destroyWindow, bool destroySubWindows) { Q_D(QWidget); + d->aboutToDestroy(); if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); d->deactivateWidgetCleanup(); @@ -2075,7 +2076,7 @@ void QWidgetPrivate::registerTouchWindow() void QWidgetPrivate::winSetupGestures() { -#if !defined(QT_NO_NATIVE_GESTURES) +#if !defined(QT_NO_GESTURES) && !defined(QT_NO_NATIVE_GESTURES) Q_Q(QWidget); if (!q || !q->isVisible() || !nativeGesturePanEnabled) return; diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 43f510c..e01489f 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -1023,6 +1023,7 @@ bool QWidgetPrivate::isBackgroundInherited() const void QWidget::destroy(bool destroyWindow, bool destroySubWindows) { Q_D(QWidget); + d->aboutToDestroy(); if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); d->deactivateWidgetCleanup(); diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp index 0bddbf6..780de5d 100644 --- a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp +++ b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp @@ -50,6 +50,8 @@ #include "private/qapplication_p.h" #include "private/qwidget_p.h" +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE #if !defined(QT_NO_NATIVE_GESTURES) @@ -127,3 +129,5 @@ void QWinNativePanGestureRecognizer::reset(QGesture *state) #endif // QT_NO_NATIVE_GESTURES QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h index 146b067..64addeb 100644 --- a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h +++ b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h @@ -54,6 +54,7 @@ // #include <QGestureRecognizer> + #include <objbase.h> class IInkRectangle; @@ -87,6 +88,8 @@ DECLARE_INTERFACE_(IInkTablets, IDispatch) STDMETHOD(IsPacketPropertySupported)(THIS_ BSTR packetPropertyName, VARIANT_BOOL *Supported) PURE; }; +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE #if !defined(QT_NO_NATIVE_GESTURES) @@ -105,4 +108,6 @@ public: QT_END_NAMESPACE +#endif // QT_NO_GESTURES + #endif // QWINNATIVEPANGESTURERECOGNIZER_WIN_P_H diff --git a/src/gui/painting/qbackingstore.cpp b/src/gui/painting/qbackingstore.cpp index f9cd59b..83751ed 100644 --- a/src/gui/painting/qbackingstore.cpp +++ b/src/gui/painting/qbackingstore.cpp @@ -909,7 +909,7 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) QWidgetPrivate *pd = pw->d_func(); QRect clipR(pd->clipRect()); #ifdef Q_WS_QWS - QWidgetBackingStore *wbs = x->backingStore; + QWidgetBackingStore *wbs = x->backingStore.data(); QWSWindowSurface *surface = static_cast<QWSWindowSurface*>(wbs->windowSurface); clipR = clipR.intersected(surface->clipRegion().translated(-toplevelOffset).boundingRect()); #endif @@ -939,7 +939,7 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy) invalidateBuffer((newRect & clipR).translated(-data.crect.topLeft())); } else { - QWidgetBackingStore *wbs = x->backingStore; + QWidgetBackingStore *wbs = x->backingStore.data(); QRegion childExpose(newRect & clipR); if (sourceRect.isValid() && wbs->bltRect(sourceRect, dx, dy, pw)) @@ -982,7 +982,7 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy) if (x->inTopLevelResize) return; - QWidgetBackingStore *wbs = x->backingStore; + QWidgetBackingStore *wbs = x->backingStore.data(); if (!wbs) return; diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index b468b11..d3061d8 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -48,6 +48,7 @@ #include "qline.h" #include "qdebug.h" #include <QtCore/qcoreapplication.h> +#include "private/qstylehelper_p.h" QT_BEGIN_NAMESPACE @@ -96,9 +97,11 @@ const uchar *qt_patternForBrush(int brushStyle, bool invert) QPixmap qt_pixmapForBrush(int brushStyle, bool invert) { + QPixmap pm; - QString key = QLatin1String("$qt-brush$") + QString::number(brushStyle) - + QString::number((int)invert); + QString key = QLatin1Literal("$qt-brush$") + % HexString<uint>(brushStyle) + % QLatin1Char(invert ? '1' : '0'); if (!QPixmapCache::find(key, pm)) { pm = QBitmap::fromData(QSize(8, 8), qt_patternForBrush(brushStyle, invert), QImage::Format_MonoLSB); diff --git a/src/gui/painting/qdrawutil.cpp b/src/gui/painting/qdrawutil.cpp index 3ce95ef..11ea6d5 100644 --- a/src/gui/painting/qdrawutil.cpp +++ b/src/gui/painting/qdrawutil.cpp @@ -48,6 +48,7 @@ #include <private/qpaintengineex_p.h> #include <qvarlengtharray.h> #include <qmath.h> +#include <private/qstylehelper_p.h> QT_BEGIN_NAMESPACE @@ -1018,7 +1019,9 @@ void qDrawItem(QPainter *p, Qt::GUIStyle gs, ; #ifndef QT_NO_IMAGE_HEURISTIC_MASK } else { // color pixmap, no mask - QString k = QString::fromLatin1("$qt-drawitem-%1").arg(pm.cacheKey()); + QString k = QLatin1Literal("$qt-drawitem") + % HexString<qint64>(pm.cacheKey()); + if (!QPixmapCache::find(k, pm)) { pm = pm.createHeuristicMask(); pm.setMask((QBitmap&)pm); diff --git a/src/gui/painting/qgrayraster.c b/src/gui/painting/qgrayraster.c index ff2469c..5e7c67a 100644 --- a/src/gui/painting/qgrayraster.c +++ b/src/gui/painting/qgrayraster.c @@ -156,6 +156,7 @@ #define ErrRaster_Invalid_Outline -1 #define ErrRaster_Invalid_Argument -3 #define ErrRaster_Memory_Overflow -4 +#define ErrRaster_OutOfMemory -6 #define QT_FT_BEGIN_HEADER #define QT_FT_END_HEADER @@ -222,7 +223,6 @@ #define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) ) #endif - /*************************************************************************/ /* */ /* TYPE DEFINITIONS */ @@ -1757,8 +1757,7 @@ #ifdef DEBUG_GRAYS fprintf( stderr, "Rotten glyph!\n" ); #endif - /* == Raster_Err_OutOfMemory in qblackraster.c */ - return -6; + return ErrRaster_OutOfMemory; } if ( bottom-top >= ras.band_size ) @@ -1784,7 +1783,7 @@ static int - gray_raster_render( PRaster raster, + gray_raster_render( QT_FT_Raster raster, const QT_FT_Raster_Params* params ) { const QT_FT_Outline* outline = (const QT_FT_Outline*)params->source; @@ -1795,6 +1794,12 @@ if ( !raster || !raster->buffer || !raster->buffer_size ) return ErrRaster_Invalid_Argument; + // If raster object and raster buffer are allocated, but + // raster size isn't of the minimum size, indicate out of + // memory. + if (raster && raster->buffer && raster->buffer_size < MINIMUM_POOL_SIZE ) + return ErrRaster_OutOfMemory; + /* return immediately if the outline is empty */ if ( outline->n_points == 0 || outline->n_contours <= 0 ) return 0; @@ -1874,19 +1879,15 @@ /**** a static object. *****/ static int - gray_raster_new( void * memory, - QT_FT_Raster* araster ) + gray_raster_new( QT_FT_Raster* araster ) { - if (memory) - fprintf(stderr, "gray_raster_new(), memory ignored"); - memory = malloc(sizeof(TRaster)); - if (!memory) { + *araster = malloc(sizeof(TRaster)); + if (!*araster) { *araster = 0; return ErrRaster_Memory_Overflow; } - QT_FT_MEM_ZERO(memory, sizeof(TRaster)); + QT_FT_MEM_ZERO(*araster, sizeof(TRaster)); - *araster = (QT_FT_Raster) memory; return 0; } @@ -1905,10 +1906,9 @@ { PRaster rast = (PRaster)raster; - if ( raster ) { - if ( pool_base && pool_size >= (long)sizeof ( TWorker ) + 2048 ) + if ( pool_base && ( pool_size >= MINIMUM_POOL_SIZE ) ) { PWorker worker = (PWorker)pool_base; @@ -1923,6 +1923,13 @@ rast->band_size = (int)( rast->buffer_size / ( sizeof ( TCell ) * 8 ) ); } + else if ( pool_base) + { // Case when there is a raster pool allocated, but it + // doesn't have the minimum size (and so memory will be reallocated) + rast->buffer = pool_base; + rast->worker = NULL; + rast->buffer_size = pool_size; + } else { rast->buffer = NULL; diff --git a/src/gui/painting/qgrayraster_p.h b/src/gui/painting/qgrayraster_p.h index 4463fc9..ad595b8 100644 --- a/src/gui/painting/qgrayraster_p.h +++ b/src/gui/painting/qgrayraster_p.h @@ -89,6 +89,10 @@ #define QT_FT_EXPORT_VAR( x ) extern x #endif +/* Minimum buffer size for raster object, that accounts + for TWorker and TCell sizes.*/ +#define MINIMUM_POOL_SIZE 4096 + QT_FT_EXPORT_VAR( const QT_FT_Raster_Funcs ) qt_ft_grays_raster; diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 48974e8..9f1128b 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -68,6 +68,7 @@ // #include <private/qrasterizer_p.h> #include <private/qimage_p.h> #include <private/qstatictext_p.h> +#include "qmemrotate_p.h" #include "qpaintengine_raster_p.h" // #include "qbezier_p.h" @@ -344,7 +345,7 @@ void QRasterPaintEngine::init() // The antialiasing raster. d->grayRaster.reset(new QT_FT_Raster); Q_CHECK_PTR(d->grayRaster.data()); - if (qt_ft_grays_raster.raster_new(0, d->grayRaster.data())) + if (qt_ft_grays_raster.raster_new(d->grayRaster.data())) QT_THROW(std::bad_alloc()); // an error creating the raster is caused by a bad malloc @@ -2521,6 +2522,58 @@ QRectF qt_mapRect_non_normalizing(const QRectF &r, const QTransform &t) return QRectF(r.topLeft() * t, r.bottomRight() * t); } +namespace { + enum RotationType { + Rotation90, + Rotation180, + Rotation270, + NoRotation + }; + + inline RotationType qRotationType(const QTransform &transform) + { + QTransform::TransformationType type = transform.type(); + + if (type > QTransform::TxRotate) + return NoRotation; + + if (type == QTransform::TxRotate && qFuzzyIsNull(transform.m11()) && qFuzzyCompare(transform.m12(), qreal(-1)) + && qFuzzyCompare(transform.m21(), qreal(1)) && qFuzzyIsNull(transform.m22())) + return Rotation90; + + if (type == QTransform::TxScale && qFuzzyCompare(transform.m11(), qreal(-1)) && qFuzzyIsNull(transform.m12()) + && qFuzzyIsNull(transform.m21()) && qFuzzyCompare(transform.m22(), qreal(-1))) + return Rotation180; + + if (type == QTransform::TxRotate && qFuzzyIsNull(transform.m11()) && qFuzzyCompare(transform.m12(), qreal(1)) + && qFuzzyCompare(transform.m21(), qreal(-1)) && qFuzzyIsNull(transform.m22())) + return Rotation270; + + return NoRotation; + } + + template <typename T> void memRotate(RotationType type, const T *srcBase, int w, int h, int sbpl, T *dstBase, int dbpl) + { + switch (type) { + case Rotation90: + qt_memrotate90(srcBase, w, h, sbpl, dstBase, dbpl); + break; + case Rotation180: + qt_memrotate180(srcBase, w, h, sbpl, dstBase, dbpl); + break; + case Rotation270: + qt_memrotate270(srcBase, w, h, sbpl, dstBase, dbpl); + break; + case NoRotation: + break; + } + } + + inline bool isPixelAligned(const QRectF &rect) { + return QRectF(rect.toRect()) == rect; + } +} + /*! \reimp */ @@ -2582,6 +2635,58 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe const QClipData *clip = d->clip(); + if (s->matrix.type() > QTransform::TxTranslate + && !stretch_sr + && (!clip || clip->hasRectClip) + && s->intOpacity == 256 + && (d->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver + || d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source) + && d->rasterBuffer->format == img.format() + && (d->rasterBuffer->format == QImage::Format_RGB16 + || d->rasterBuffer->format == QImage::Format_RGB32 + || (d->rasterBuffer->format == QImage::Format_ARGB32_Premultiplied + && d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source))) + { + RotationType rotationType = qRotationType(s->matrix); + + if (rotationType != NoRotation && img.rect().contains(sr.toAlignedRect())) { + QRectF transformedTargetRect = s->matrix.mapRect(r); + + if ((!(s->renderHints & QPainter::SmoothPixmapTransform) && !(s->renderHints & QPainter::Antialiasing)) + || (isPixelAligned(transformedTargetRect) && isPixelAligned(sr))) + { + QRect clippedTransformedTargetRect = transformedTargetRect.toRect().intersected(clip ? clip->clipRect : d->deviceRect); + if (clippedTransformedTargetRect.isNull()) + return; + + QRectF clippedTargetRect = s->matrix.inverted().mapRect(QRectF(clippedTransformedTargetRect)); + + QRect clippedSourceRect + = QRectF(sr.x() + clippedTargetRect.x() - r.x(), sr.y() + clippedTargetRect.y() - r.y(), + clippedTargetRect.width(), clippedTargetRect.height()).toRect(); + + uint dbpl = d->rasterBuffer->bytesPerLine(); + uint sbpl = img.bytesPerLine(); + + uchar *dst = d->rasterBuffer->buffer(); + uint bpp = img.depth() >> 3; + + const uchar *srcBase = img.bits() + clippedSourceRect.y() * sbpl + clippedSourceRect.x() * bpp; + uchar *dstBase = dst + clippedTransformedTargetRect.y() * dbpl + clippedTransformedTargetRect.x() * bpp; + + uint cw = clippedSourceRect.width(); + uint ch = clippedSourceRect.height(); + + if (d->rasterBuffer->format == QImage::Format_RGB16) + memRotate(rotationType, (quint16 *)srcBase, cw, ch, sbpl, (quint16 *)dstBase, dbpl); + else + memRotate(rotationType, (quint32 *)srcBase, cw, ch, sbpl, (quint32 *)dstBase, dbpl); + + return; + } + } + } + if (s->matrix.type() > QTransform::TxTranslate || stretch_sr) { if (s->flags.fast_images) { @@ -4080,7 +4185,11 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, return; } - const int rasterPoolInitialSize = 8192; + // Initial size for raster pool is MINIMUM_POOL_SIZE so as to + // minimize memory reallocations. However if initial size for + // raster pool is changed for lower value, reallocations will + // occur normally. + const int rasterPoolInitialSize = MINIMUM_POOL_SIZE; int rasterPoolSize = rasterPoolInitialSize; unsigned char *rasterPoolBase; #if defined(Q_WS_WIN64) @@ -4124,7 +4233,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, error = qt_ft_grays_raster.raster_render(*grayRaster.data(), &rasterParams); // Out of memory, reallocate some more and try again... - if (error == -6) { // -6 is Result_err_OutOfMemory + if (error == -6) { // ErrRaster_OutOfMemory from qgrayraster.c int new_size = rasterPoolSize * 2; if (new_size > 1024 * 1024) { qWarning("QPainter: Rasterization of primitive failed"); @@ -4150,7 +4259,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, Q_CHECK_PTR(rasterPoolBase); // note: we just freed the old rasterPoolBase. I hope it's not fatal. qt_ft_grays_raster.raster_done(*grayRaster.data()); - qt_ft_grays_raster.raster_new(0, grayRaster.data()); + qt_ft_grays_raster.raster_new(grayRaster.data()); qt_ft_grays_raster.raster_reset(*grayRaster.data(), rasterPoolBase, rasterPoolSize); } else { done = true; diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index aef8b80..b8ad9b3 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -79,6 +79,8 @@ #include <private/qtessellator_p.h> #endif +#include <private/qstylehelper_p.h> + QT_BEGIN_NAMESPACE extern Drawable qt_x11Handle(const QPaintDevice *pd); @@ -224,7 +226,10 @@ static const uchar base_dither_matrix[DITHER_SIZE][DITHER_SIZE] = { static QPixmap qt_patternForAlpha(uchar alpha, int screen) { QPixmap pm; - QString key = QLatin1String("$qt-alpha-brush$") + QString::number(alpha) + QString::number(screen); + QString key = QLatin1Literal("$qt-alpha-brush$") + % HexString<uchar>(alpha) + % HexString<int>(screen); + if (!QPixmapCache::find(key, pm)) { // #### why not use a mono image here???? QImage pattern(DITHER_SIZE, DITHER_SIZE, QImage::Format_ARGB32); diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 657229a..e8c4599 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -72,6 +72,7 @@ #include <private/qmath_p.h> #include <qstatictext.h> #include <private/qstatictext_p.h> +#include <private/qstylehelper_p.h> QT_BEGIN_NAMESPACE @@ -1563,7 +1564,6 @@ void QPainter::initFrom(const QWidget *widget) d->engine->setDirty(QPaintEngine::DirtyBrush); d->engine->setDirty(QPaintEngine::DirtyFont); } - d->state->layoutDirection = widget->layoutDirection(); } @@ -1873,7 +1873,7 @@ bool QPainter::begin(QPaintDevice *pd) QWidget *widget = static_cast<QWidget *>(d->original_device); initFrom(widget); } else { - d->state->layoutDirection = QApplication::layoutDirection(); + d->state->layoutDirection = Qt::LayoutDirectionAuto; // make sure we have a font compatible with the paintdevice d->state->deviceFont = d->state->font = QFont(d->state->deviceFont, device()); } @@ -5855,14 +5855,24 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText return; } + if (d->extended->type() == QPaintEngine::OpenGL2 && !staticText_d->untransformedCoordinates) { + staticText_d->untransformedCoordinates = true; + staticText_d->needsRelayout = true; + } else if (d->extended->type() != QPaintEngine::OpenGL2 && staticText_d->untransformedCoordinates) { + staticText_d->untransformedCoordinates = false; + staticText_d->needsRelayout = true; + } + // Don't recalculate entire layout because of translation, rather add the dx and dy // into the position to move each text item the correct distance. - QPointF transformedPosition = topLeftPosition * d->state->matrix; - QTransform matrix = d->state->matrix; + QPointF transformedPosition = topLeftPosition; + if (!staticText_d->untransformedCoordinates) + transformedPosition = transformedPosition * d->state->matrix; + QTransform oldMatrix; // The translation has been applied to transformedPosition. Remove translation // component from matrix. - if (d->state->matrix.isTranslating()) { + if (d->state->matrix.isTranslating() && !staticText_d->untransformedCoordinates) { qreal m11 = d->state->matrix.m11(); qreal m12 = d->state->matrix.m12(); qreal m13 = d->state->matrix.m13(); @@ -5871,6 +5881,7 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText qreal m23 = d->state->matrix.m23(); qreal m33 = d->state->matrix.m33(); + oldMatrix = d->state->matrix; d->state->matrix.setMatrix(m11, m12, m13, m21, m22, m23, 0.0, 0.0, m33); @@ -5879,7 +5890,7 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText // If the transform is not identical to the text transform, // we have to relayout the text (for other transformations than plain translation) bool staticTextNeedsReinit = staticText_d->needsRelayout; - if (staticText_d->matrix != d->state->matrix) { + if (!staticText_d->untransformedCoordinates && staticText_d->matrix != d->state->matrix) { staticText_d->matrix = d->state->matrix; staticTextNeedsReinit = true; } @@ -5918,8 +5929,8 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText if (currentColor != oldPen.color()) setPen(oldPen); - if (matrix.isTranslating()) - d->state->matrix = matrix; + if (!staticText_d->untransformedCoordinates && oldMatrix.isTranslating()) + d->state->matrix = oldMatrix; } /*! @@ -5937,6 +5948,23 @@ void QPainter::drawText(const QPointF &p, const QString &str, int tf, int justif if (!d->engine || str.isEmpty() || pen().style() == Qt::NoPen) return; + if (tf & Qt::TextBypassShaping) { + // Skip harfbuzz complex shaping, shape using glyph advances only + int len = str.length(); + int numGlyphs = len; + QVarLengthGlyphLayoutArray glyphs(len); + QFontEngine *fontEngine = d->state->font.d->engineForScript(QUnicodeTables::Common); + if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) { + glyphs.resize(numGlyphs); + if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) + Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice"); + } + + QTextItemInt gf(glyphs, &d->state->font, fontEngine); + drawTextItem(p, gf); + return; + } + QStackTextEngine engine(str, d->state->font); engine.option.setTextDirection(d->state->layoutDirection); if (tf & (Qt::TextForceLeftToRight|Qt::TextForceRightToLeft)) { @@ -6217,10 +6245,9 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen) { const qreal radiusBase = qMax(qreal(1), maxRadius); - QString key = QLatin1String("WaveUnderline-"); - key += pen.color().name(); - key += QLatin1Char('-'); - key += QString::number(radiusBase); + QString key = QLatin1Literal("WaveUnderline-") + % pen.color().name() + % HexString<qreal>(radiusBase); QPixmap pixmap; if (QPixmapCache::find(key, pixmap)) @@ -8028,7 +8055,10 @@ start_lengthVariant: Sets the layout direction used by the painter when drawing text, to the specified \a direction. - \sa layoutDirection(), drawText(), {QPainter#Settings}{Settings} + The default is Qt::LayoutDirectionAuto, which will implicitly determine the + direction from the text drawn. + + \sa QTextOption::setTextDirection(), layoutDirection(), drawText(), {QPainter#Settings}{Settings} */ void QPainter::setLayoutDirection(Qt::LayoutDirection direction) { @@ -8040,12 +8070,12 @@ void QPainter::setLayoutDirection(Qt::LayoutDirection direction) /*! Returns the layout direction used by the painter when drawing text. - \sa setLayoutDirection(), drawText(), {QPainter#Settings}{Settings} + \sa QTextOption::textDirection(), setLayoutDirection(), drawText(), {QPainter#Settings}{Settings} */ Qt::LayoutDirection QPainter::layoutDirection() const { Q_D(const QPainter); - return d->state ? d->state->layoutDirection : Qt::LeftToRight; + return d->state ? d->state->layoutDirection : Qt::LayoutDirectionAuto; } QPainterState::QPainterState(const QPainterState *s) diff --git a/src/gui/painting/qrasterdefs_p.h b/src/gui/painting/qrasterdefs_p.h index c33fa57..19a0b16 100644 --- a/src/gui/painting/qrasterdefs_p.h +++ b/src/gui/painting/qrasterdefs_p.h @@ -81,7 +81,6 @@ QT_FT_BEGIN_HEADER - /*************************************************************************/ /* */ /* <Section> */ @@ -837,7 +836,7 @@ QT_FT_BEGIN_HEADER /* A handle (pointer) to a raster object. Each object can be used */ /* independently to convert an outline into a bitmap or pixmap. */ /* */ - typedef struct QT_FT_RasterRec_* QT_FT_Raster; + typedef struct TRaster_ *QT_FT_Raster; /*************************************************************************/ @@ -1118,8 +1117,7 @@ QT_FT_BEGIN_HEADER /* ignored by a given raster implementation. */ /* */ typedef int - (*QT_FT_Raster_NewFunc)( void* memory, - QT_FT_Raster* raster ); + (*QT_FT_Raster_NewFunc)( QT_FT_Raster* raster ); #define QT_FT_Raster_New_Func QT_FT_Raster_NewFunc diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 423cce9..47b7758 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -1626,7 +1626,7 @@ static QPainterPath mapProjective(const QTransform &transform, const QPainterPat QPainterPath QTransform::map(const QPainterPath &path) const { TransformationType t = inline_type(); - if (t == TxNone || path.isEmpty()) + if (t == TxNone || path.elementCount() == 0) return path; if (t >= TxProject) diff --git a/src/gui/statemachine/qguistatemachine.cpp b/src/gui/statemachine/qguistatemachine.cpp index 63ad94e..2b4c9c2 100644 --- a/src/gui/statemachine/qguistatemachine.cpp +++ b/src/gui/statemachine/qguistatemachine.cpp @@ -474,9 +474,11 @@ static QEvent *cloneEvent(QEvent *e) case QEvent::TouchEnd: return new QTouchEvent(*static_cast<QTouchEvent*>(e)); +#ifndef QT_NO_GESTURES case QEvent::NativeGesture: Q_ASSERT_X(false, "cloneEvent()", "not implemented"); break; +#endif case QEvent::RequestSoftwareInputPanel: case QEvent::CloseSoftwareInputPanel: diff --git a/src/gui/styles/qgtkpainter.cpp b/src/gui/styles/qgtkpainter.cpp index 79c53e9..0217a39 100644 --- a/src/gui/styles/qgtkpainter.cpp +++ b/src/gui/styles/qgtkpainter.cpp @@ -241,8 +241,10 @@ void QGtkPainter::paintBoxGap(GtkWidget *gtkWidget, const gchar* part, if (rect.height() > maxHeight && (gap_side == GTK_POS_TOP || gap_side == GTK_POS_BOTTOM)) rect.setHeight(2 * border + 1); - QString gapExtras = QString(QLS("s %0 w %1 g %2")).arg(gap_side).arg(width).arg(x); - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) + gapExtras; + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) + % HexString<uchar>(gap_side) + % HexString<gint>(width) + % HexString<gint>(x); if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_box_gap (style, @@ -307,7 +309,7 @@ void QGtkPainter::paintBox(GtkWidget *gtkWidget, const gchar* part, rect.setHeight(2 * border + 1); QString pixmapName = uniqueName(QLS(part), state, shadow, - rect.size(), gtkWidget) + pmKey; + rect.size(), gtkWidget) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_box (style, @@ -357,9 +359,11 @@ void QGtkPainter::paintHline(GtkWidget *gtkWidget, const gchar* part, return; QPixmap cache; - QString hLineExtras = QString(QLS("%0 %1 %2")).arg(x1).arg(x2).arg(y); QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) - + hLineExtras + pmKey; + % HexString<int>(x1) + % HexString<int>(x2) + % HexString<int>(y) + % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_hline (style, pixmap, @@ -384,9 +388,12 @@ void QGtkPainter::paintVline(GtkWidget *gtkWidget, const gchar* part, return; QPixmap cache; - QString vLineExtras = QString(QLS("%0 %1 %2")).arg(y1).arg(y2).arg(x); - QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), - gtkWidget) + vLineExtras +pmKey; + QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) + % HexString<int>(y1) + % HexString<int>(y2) + % HexString<int>(x) + % pmKey; + if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_vline (style, pixmap, @@ -412,8 +419,10 @@ void QGtkPainter::paintExpander(GtkWidget *gtkWidget, return; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), - gtkWidget) + QString::number(expander_state) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) + % HexString<uchar>(expander_state) + % pmKey; + if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_expander (style, pixmap, state, NULL, @@ -436,7 +445,7 @@ void QGtkPainter::paintFocus(GtkWidget *gtkWidget, const gchar* part, return; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, GTK_SHADOW_NONE, rect.size(), gtkWidget) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_focus (style, pixmap, state, NULL, gtkWidget, @@ -461,7 +470,7 @@ void QGtkPainter::paintResizeGrip(GtkWidget *gtkWidget, const gchar* part, return; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_resize_grip (style, pixmap, state, NULL, gtkWidget, @@ -486,8 +495,9 @@ void QGtkPainter::paintArrow(GtkWidget *gtkWidget, const gchar* part, return; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) + - QString::number((int)arrow_type) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) + % HexString<uchar>(arrow_type) + % pmKey; GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()}; int xOffset = m_cliprect.isValid() ? arrowrect.x() - m_cliprect.x() : 0; @@ -518,7 +528,8 @@ void QGtkPainter::paintHandle(GtkWidget *gtkWidget, const gchar* part, const QRe QPixmap cache; QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) - + QString::number(orientation); + % HexString<uchar>(orientation); + if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_handle (style, pixmap, @@ -546,7 +557,7 @@ void QGtkPainter::paintSlider(GtkWidget *gtkWidget, const gchar* part, const QRe return; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_slider (style, pixmap, @@ -577,7 +588,7 @@ void QGtkPainter::paintShadow(GtkWidget *gtkWidget, const gchar* part, QRect r = rect; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_shadow(style, pixmap, state, shadow, NULL, gtkWidget, part, 0, 0, rect.width(), rect.height())); @@ -596,7 +607,7 @@ void QGtkPainter::paintFlatBox(GtkWidget *gtkWidget, const gchar* part, return; QRect r = rect; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) + pmKey; + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_flat_box (style, pixmap, @@ -623,8 +634,8 @@ void QGtkPainter::paintExtention(GtkWidget *gtkWidget, QRect r = rect; QPixmap cache; - QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget); - pixmapName += QString::number(gap_pos); + QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) + % HexString<uchar>(gap_pos); if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { DRAW_TO_CACHE(QGtkStylePrivate::gtk_paint_extension (style, pixmap, state, shadow, diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 9d6dc9a..b59a033 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -67,6 +67,7 @@ #include <QtGui/QRadioButton> #include <QtGui/QCheckBox> #include <QtGui/QTreeView> +#include <QtGui/QStyledItemDelegate> #include <qpixmapcache.h> #undef signals // Collides with GTK stymbols #include <private/qgtkpainter_p.h> @@ -692,7 +693,7 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, // thin rectangular images const int pmSize = 64; const int border = proxy()->pixelMetric(PM_DefaultFrameWidth, option, widget); - const QString pmKey = QString(QLS("windowframe %0")).arg(option->state); + const QString pmKey = QLatin1Literal("windowframe") % HexString<uint>(option->state); QPixmap pixmap; QRect pmRect(QPoint(0,0), QSize(pmSize, pmSize)); @@ -817,24 +818,49 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, option->state & State_Open ? openState : closedState , gtkTreeView->style); } break; + + case PE_PanelItemViewRow: + // This primitive is only used to draw selection behind selected expander arrows. + // We try not to decorate the tree branch background unless you inherit from StyledItemDelegate + // The reason for this is that a lot of code that relies on custom item delegates will look odd having + // a gradient on the branch but a flat shaded color on the item itself. + QCommonStyle::drawPrimitive(element, option, painter, widget); + if (!option->state & State_Selected) { + break; + } else { + if (const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(widget)) { + if (!qobject_cast<QStyledItemDelegate*>(view->itemDelegate())) + break; + } + } // fall through + case PE_PanelItemViewItem: if (const QStyleOptionViewItemV4 *vopt = qstyleoption_cast<const QStyleOptionViewItemV4 *>(option)) { - if (vopt->state & State_Selected) { - QLinearGradient gradient; - gradient.setStart(option->rect.left(), option->rect.top()); - gradient.setFinalStop(option->rect.left(), option->rect.bottom()); - gradient.setColorAt(0, option->palette.highlight().color().lighter(105)); - gradient.setColorAt(0.5, option->palette.highlight().color().lighter(101)); - gradient.setColorAt(0.51, option->palette.highlight().color().darker(101)); - gradient.setColorAt(1, option->palette.highlight().color().darker(105)); - painter->fillRect(option->rect, gradient); - } else { - if (vopt->backgroundBrush.style() != Qt::NoBrush) { - QPointF oldBO = painter->brushOrigin(); - painter->setBrushOrigin(vopt->rect.topLeft()); - painter->fillRect(vopt->rect, vopt->backgroundBrush); - painter->setBrushOrigin(oldBO); + if (vopt->backgroundBrush.style() != Qt::NoBrush) { + QPointF oldBO = painter->brushOrigin(); + painter->setBrushOrigin(vopt->rect.topLeft()); + painter->fillRect(vopt->rect, vopt->backgroundBrush); + painter->setBrushOrigin(oldBO); + if (!(option->state & State_Selected)) + break; + } + if (GtkWidget *gtkTreeView = d->gtkWidget("GtkTreeView")) { + const char *detail = "cell_even_ruled"; + if (vopt && vopt->features & QStyleOptionViewItemV2::Alternate) + detail = "cell_odd_ruled"; + bool isActive = option->state & State_Active; + QString key; + if (isActive ) { + // Required for active/non-active window appearance + key = QLS("a"); + GTK_WIDGET_SET_FLAGS(gtkTreeView, GTK_HAS_FOCUS); } + gtkPainter.paintFlatBox(gtkTreeView, detail, option->rect, + option->state & State_Selected ? GTK_STATE_SELECTED : + option->state & State_Enabled ? GTK_STATE_NORMAL : GTK_STATE_INSENSITIVE, + GTK_SHADOW_OUT, gtkTreeView->style, key); + if (isActive ) + GTK_WIDGET_UNSET_FLAGS(gtkTreeView, GTK_HAS_FOCUS); } } break; diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index c8711f6..20d9bd9 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -488,7 +488,9 @@ static void qBrushSetAlphaF(QBrush *brush, qreal alpha) // Modify the texture - ridiculously expensive. QPixmap texture = brush->texture(); QPixmap pixmap; - QString name = QString::fromLatin1("qbrushtexture-alpha-%1-%2").arg(alpha).arg(texture.cacheKey()); + QString name = QLatin1Literal("qbrushtexture-alpha") + % HexString<qreal>(alpha) + % HexString<qint64>(texture.cacheKey()); if (!QPixmapCache::find(name, pixmap)) { QImage image = texture.toImage(); QRgb *rgb = reinterpret_cast<QRgb *>(image.bits()); @@ -549,7 +551,10 @@ static QBrush qBrushLight(QBrush brush, int light) // Modify the texture - ridiculously expensive. QPixmap texture = brush.texture(); QPixmap pixmap; - QString name = QString::fromLatin1("qbrushtexture-light-%1-%2").arg(light).arg(texture.cacheKey()); + QString name = QLatin1Literal("qbrushtexture-light") + % HexString<int>(light) + % HexString<qint64>(texture.cacheKey()); + if (!QPixmapCache::find(name, pixmap)) { QImage image = texture.toImage(); QRgb *rgb = reinterpret_cast<QRgb *>(image.bits()); @@ -608,7 +613,10 @@ static QBrush qBrushDark(QBrush brush, int dark) // Modify the texture - ridiculously expensive. QPixmap texture = brush.texture(); QPixmap pixmap; - QString name = QString::fromLatin1("qbrushtexture-dark-%1-%2").arg(dark).arg(brush.texture().cacheKey()); + QString name = QLatin1Literal("qbrushtexture-dark") + % HexString<int>(dark) + % HexString<qint64>(texture.cacheKey()); + if (!QPixmapCache::find(name, pixmap)) { QImage image = texture.toImage(); QRgb *rgb = reinterpret_cast<QRgb *>(image.bits()); @@ -732,8 +740,12 @@ static QColor mergedColors(const QColor &colorA, const QColor &colorB, int facto static void qt_plastique_draw_gradient(QPainter *painter, const QRect &rect, const QColor &gradientStart, const QColor &gradientStop) { - QString gradientName; - gradientName.sprintf("%dx%d-%x-%x", rect.width(), rect.height(), gradientStart.rgba(), gradientStop.rgba()); + QString gradientName = QLatin1Literal("qplastique-g") + % HexString<int>(rect.width()) + % HexString<int>(rect.height()) + % HexString<QRgb>(gradientStart.rgba()) + % HexString<QRgb>(gradientStop.rgba()); + QPixmap cache; QPainter *p = painter; QRect r = rect; @@ -1092,14 +1104,6 @@ void QPlastiqueStyle::drawPrimitive(PrimitiveElement element, const QStyleOption Q_ASSERT(option); QColor borderColor = option->palette.background().color().darker(178); - QColor gradientStartColor = option->palette.button().color().lighter(104); - QColor gradientStopColor = option->palette.button().color().darker(105); - QColor highlightedGradientStartColor = option->palette.button().color().lighter(101); - QColor highlightedGradientStopColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 85); - QColor highlightedBaseGradientStartColor = option->palette.base().color(); - QColor highlightedBaseGradientStopColor = mergedColors(option->palette.base().color().darker(105), option->palette.highlight().color(), 70); - QColor highlightedDarkInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 35); - QColor highlightedLightInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 58); QColor alphaCornerColor; if (widget) { // ### backgroundrole/foregroundrole should be part of the style option @@ -1107,13 +1111,7 @@ void QPlastiqueStyle::drawPrimitive(PrimitiveElement element, const QStyleOption } else { alphaCornerColor = mergedColors(option->palette.background().color(), borderColor); } - QColor alphaInnerColor = mergedColors(highlightedLightInnerBorderColor, gradientStartColor); - QColor alphaInnerColorNoHover = mergedColors(borderColor, gradientStartColor); QColor alphaTextColor = mergedColors(option->palette.background().color(), option->palette.text().color()); - QColor alphaLightTextColor = mergedColors(option->palette.background().color().lighter(250), option->palette.text().color().lighter(250)); - QColor lightShadow = option->palette.button().color().lighter(105); - QColor shadowGradientStartColor = option->palette.button().color().darker(115); - QColor shadow = shadowGradientStartColor; switch (element) { case PE_IndicatorButtonDropDown: @@ -2057,7 +2055,6 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op bool reverse = (tab->direction == Qt::RightToLeft); int lowerTop = selected ? 0 : 3; // to make the selected tab bigger than the rest - QRect adjustedRect; bool atEnd = (tab->position == QStyleOptionTab::End) || onlyTab; bool atBeginning = ((tab->position == QStyleOptionTab::Beginning) || onlyTab) && !leftCornerWidget; diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp index d28e1d9..91d3fa6 100644 --- a/src/gui/styles/qs60style.cpp +++ b/src/gui/styles/qs60style.cpp @@ -135,13 +135,13 @@ const struct QS60StylePrivate::frameElementCenter QS60StylePrivate::m_frameEleme {SE_TableHeaderItem, QS60StyleEnums::SP_QsnFrCaleHeadingCenter}, {SE_ToolTip, QS60StyleEnums::SP_QsnFrPopupPreviewCenter}, {SE_ToolBar, QS60StyleEnums::SP_QsnFrPopupSubCenter}, - {SE_ToolBarButton, QS60StyleEnums::SP_QsnFrSctrlButtonCenter}, - {SE_ToolBarButtonPressed, QS60StyleEnums::SP_QsnFrSctrlButtonCenterPressed}, + {SE_ToolBarButton, QS60StyleEnums::SP_QgnFrSctrlButtonCenter}, + {SE_ToolBarButtonPressed, QS60StyleEnums::SP_QgnFrSctrlButtonCenterPressed}, {SE_PanelBackground, QS60StyleEnums::SP_QsnFrSetOptCenter}, {SE_ButtonInactive, QS60StyleEnums::SP_QsnFrButtonCenterInactive}, {SE_Editor, QS60StyleEnums::SP_QsnFrInputCenter}, {SE_TableItemPressed, QS60StyleEnums::SP_QsnFrGridCenterPressed}, - {SE_ListItemPressed, QS60StyleEnums::SP_QsnFrListPressed}, + {SE_ListItemPressed, QS60StyleEnums::SP_QsnFrListCenterPressed}, }; static const int frameElementsCount = @@ -1750,6 +1750,12 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, } const bool enabled = optionMenuItem.state & State_Enabled; const bool checkable = optionMenuItem.checkType != QStyleOptionMenuItem::NotCheckable; + bool ignoreCheckMark = false; + +#ifndef QT_NO_COMBOBOX + if (qobject_cast<const QComboBox*>(widget)) + ignoreCheckMark = true; //ignore the checkmarks provided by the QComboMenuDelegate +#endif uint text_flags = Qt::AlignLeading | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine | Qt::AlignVCenter; @@ -1787,7 +1793,8 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, iconRect.translate(-optionCheckBox.rect.width() - vSpacing, 0); optionCheckBox.rect.translate(textRect.width() + iconRect.width(), 0); } - drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget); + if (!ignoreCheckMark) + drawPrimitive(PE_IndicatorMenuCheckMark, &optionCheckBox, painter, widget); } //draw icon and/or checkState QPixmap pix = menuItem->icon.pixmap(pixelMetric(PM_SmallIconSize), @@ -1817,7 +1824,7 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option, QS60StylePrivate::SF_PointNorth : QS60StylePrivate::SF_PointSouth; painter->save(); painter->setPen(option->palette.windowText().color()); - QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnIndiSubMenu, painter, arrowOptions.rect, + QS60StylePrivate::drawSkinPart(QS60StyleEnums::SP_QgnIndiSubmenu, painter, arrowOptions.rect, (flags | QS60StylePrivate::SF_ColorSkinned | arrowDirection)); painter->restore(); } @@ -3321,13 +3328,13 @@ QIcon QS60Style::standardIconImplementation(StandardPixmap standardIcon, part = QS60StyleEnums::SP_QgnNoteErased; break; case SP_ToolBarHorizontalExtensionButton: - part = QS60StyleEnums::SP_QgnIndiSubMenu; + part = QS60StyleEnums::SP_QgnIndiSubmenu; if (QApplication::layoutDirection() == Qt::RightToLeft) adjustedFlags |= QS60StylePrivate::SF_PointSouth; break; case SP_ToolBarVerticalExtensionButton: adjustedFlags |= QS60StylePrivate::SF_PointEast; - part = QS60StyleEnums::SP_QgnIndiSubMenu; + part = QS60StyleEnums::SP_QgnIndiSubmenu; break; default: diff --git a/src/gui/styles/qs60style_p.h b/src/gui/styles/qs60style_p.h index d8c31f8..836969a 100644 --- a/src/gui/styles/qs60style_p.h +++ b/src/gui/styles/qs60style_p.h @@ -154,7 +154,7 @@ public: SP_QgnIndiRadiobuttOn, SP_QgnGrafNsliderMarker, SP_QgnGrafNsliderMarkerSelected, - SP_QgnIndiSubMenu, + SP_QgnIndiSubmenu, SP_QgnNoteErased, SP_QgnNoteError, SP_QgnNoteInfo, @@ -166,6 +166,24 @@ public: SP_QgnPropFolderSmall, SP_QgnPropFolderSmallNew, SP_QgnPropPhoneMemcLarge, + SP_QgnFrSctrlButtonCornerTl, // Toolbar button + SP_QgnFrSctrlButtonCornerTr, + SP_QgnFrSctrlButtonCornerBl, + SP_QgnFrSctrlButtonCornerBr, + SP_QgnFrSctrlButtonSideT, + SP_QgnFrSctrlButtonSideB, + SP_QgnFrSctrlButtonSideL, + SP_QgnFrSctrlButtonSideR, + SP_QgnFrSctrlButtonCenter, + SP_QgnFrSctrlButtonCornerTlPressed, // Toolbar button, pressed + SP_QgnFrSctrlButtonCornerTrPressed, + SP_QgnFrSctrlButtonCornerBlPressed, + SP_QgnFrSctrlButtonCornerBrPressed, + SP_QgnFrSctrlButtonSideTPressed, + SP_QgnFrSctrlButtonSideBPressed, + SP_QgnFrSctrlButtonSideLPressed, + SP_QgnFrSctrlButtonSideRPressed, + SP_QgnFrSctrlButtonCenterPressed, SP_QsnCpScrollHandleBottomPressed, //ScrollBar handle, pressed state SP_QsnCpScrollHandleMiddlePressed, SP_QsnCpScrollHandleTopPressed, @@ -198,10 +216,10 @@ public: SP_QsnFrCaleCornerTr, SP_QsnFrCaleCornerBl, SP_QsnFrCaleCornerBr, - SP_QsnFrCaleGSideT, - SP_QsnFrCaleGSideB, - SP_QsnFrCaleGSideL, - SP_QsnFrCaleGSideR, + SP_QsnFrCaleSideT, + SP_QsnFrCaleSideB, + SP_QsnFrCaleSideL, + SP_QsnFrCaleSideR, SP_QsnFrCaleCenter, SP_QsnFrCaleHeadingCornerTl, // calendar grid header SP_QsnFrCaleHeadingCornerTr, @@ -266,24 +284,6 @@ public: SP_QsnFrPopupSubSideL, SP_QsnFrPopupSubSideR, SP_QsnFrPopupSubCenter, - SP_QsnFrSctrlButtonCornerTl, // Toolbar button - SP_QsnFrSctrlButtonCornerTr, - SP_QsnFrSctrlButtonCornerBl, - SP_QsnFrSctrlButtonCornerBr, - SP_QsnFrSctrlButtonSideT, - SP_QsnFrSctrlButtonSideB, - SP_QsnFrSctrlButtonSideL, - SP_QsnFrSctrlButtonSideR, - SP_QsnFrSctrlButtonCenter, - SP_QsnFrSctrlButtonCornerTlPressed, // Toolbar button, pressed - SP_QsnFrSctrlButtonCornerTrPressed, - SP_QsnFrSctrlButtonCornerBlPressed, - SP_QsnFrSctrlButtonCornerBrPressed, - SP_QsnFrSctrlButtonSideTPressed, - SP_QsnFrSctrlButtonSideBPressed, - SP_QsnFrSctrlButtonSideLPressed, - SP_QsnFrSctrlButtonSideRPressed, - SP_QsnFrSctrlButtonCenterPressed, SP_QsnFrButtonCornerTlInactive, // Inactive button SP_QsnFrButtonCornerTrInactive, SP_QsnFrButtonCornerBlInactive, @@ -310,7 +310,7 @@ public: SP_QsnFrListSideBPressed, SP_QsnFrListSideLPressed, SP_QsnFrListSideRPressed, - SP_QsnFrListPressed, + SP_QsnFrListCenterPressed, }; enum ColorLists { diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp index c1223af..e5c74ad 100644 --- a/src/gui/styles/qs60style_s60.cpp +++ b/src/gui/styles/qs60style_s60.cpp @@ -179,7 +179,7 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { /* SP_QgnGrafBarFrameSideR */ {KAknsIIDQgnGrafBarFrameSideR, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnGrafBarProgress */ {KAknsIIDQgnGrafBarProgress, EDrawIcon, ES60_All, -1,-1}, // No drop area for 3.x non-touch devices - /* SP_QgnGrafOrgBgGrid */ {KAknsIIDNone, EDrawIcon, ES60_3_X, EAknsMajorGeneric ,0x1eba}, //KAknsIIDQgnGrafOrgBgGrid + /* SP_QgnGrafOrgBgGrid */ {KAknsIIDNone, EDrawIcon, ES60_3_X, EAknsMajorGeneric ,0x1eba}, //KAknsIIDQgnGrafOrgBgGrid /* SP_QgnGrafScrollArrowDown */ {KAknsIIDQgnGrafScrollArrowDown, EDrawGulIcon, ES60_All, -1,-1}, /* SP_QgnGrafScrollArrowLeft */ {KAknsIIDQgnGrafScrollArrowLeft, EDrawGulIcon, ES60_All, -1,-1}, /* SP_QgnGrafScrollArrowRight */ {KAknsIIDQgnGrafScrollArrowRight, EDrawGulIcon, ES60_All, -1,-1}, @@ -214,7 +214,7 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { // In 3.1 there different slider graphic and no pressed state. /* SP_QgnGrafNsliderMarker */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x19d1 /* KAknsIIDQgnGrafNsliderMarker */}, /* SP_QgnGrafNsliderMarkerSelected */ {KAknsIIDQgnIndiSliderEdit, EDrawIcon, ES60_3_1, EAknsMajorGeneric, 0x1a4a /* KAknsIIDQgnGrafNsliderMarkerSelected */}, - /* SP_QgnIndiSubMenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_All, -1,-1}, + /* SP_QgnIndiSubmenu */ {KAknsIIDQgnIndiSubmenu, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnNoteErased */ {KAknsIIDQgnNoteErased, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnNoteError */ {KAknsIIDQgnNoteError, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnNoteInfo */ {KAknsIIDQgnNoteInfo, EDrawIcon, ES60_All, -1,-1}, @@ -227,6 +227,28 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { /* SP_QgnPropFolderSmallNew */ {KAknsIIDQgnPropFolderSmallNew, EDrawIcon, ES60_All, -1,-1}, /* SP_QgnPropPhoneMemcLarge */ {KAknsIIDQgnPropPhoneMemcLarge, EDrawIcon, ES60_All, -1,-1}, + // Toolbar graphics is different in 3.1/3.2 vs. 5.0 + /* SP_QgnFrSctrlButtonCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2301}, /* KAknsIIDQgnFrSctrlButtonCornerTl*/ + /* SP_QgnFrSctrlButtonCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2302}, + /* SP_QgnFrSctrlButtonCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2303}, + /* SP_QgnFrSctrlButtonCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2304}, + /* SP_QgnFrSctrlButtonSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2305}, + /* SP_QgnFrSctrlButtonSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2306}, + /* SP_QgnFrSctrlButtonSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2307}, + /* SP_QgnFrSctrlButtonSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2308}, + /* SP_QgnFrSctrlButtonCenter */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2309}, /*KAknsIIDQgnFrSctrlButtonCenter*/ + + // No pressed state for toolbar button in 3.1/3.2. + /* SP_QgnFrSctrlButtonCornerTlPressed */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2621}, /*KAknsIIDQgnFrSctrlButtonCornerTlPressed*/ + /* SP_QgnFrSctrlButtonCornerTrPressed */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2622}, + /* SP_QgnFrSctrlButtonCornerBlPressed */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2623}, + /* SP_QgnFrSctrlButtonCornerBrPressed */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2624}, + /* SP_QgnFrSctrlButtonSideTPressed */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2625}, + /* SP_QgnFrSctrlButtonSideBPressed */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2626}, + /* SP_QgnFrSctrlButtonSideLPressed */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2627}, + /* SP_QgnFrSctrlButtonSideRPressed */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2628}, + /* SP_QgnFrSctrlButtonCenterPressed */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2629}, + // 3.1 & 3.2 do not have pressed state for scrollbar, so use normal scrollbar graphics instead. /* SP_QsnCpScrollHandleBottomPressed*/ {KAknsIIDQsnCpScrollHandleBottom, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20f8}, /*KAknsIIDQsnCpScrollHandleBottomPressed*/ /* SP_QsnCpScrollHandleMiddlePressed*/ {KAknsIIDQsnCpScrollHandleMiddle, EDrawIcon, ES60_3_X, EAknsMajorGeneric, 0x20f9}, /*KAknsIIDQsnCpScrollHandleMiddlePressed*/ @@ -266,10 +288,10 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { /* SP_QsnFrCaleCornerTr */ {KAknsIIDQsnFrCaleCornerTr, ENoDraw, ES60_All, -1,-1}, /* SP_QsnFrCaleCornerBl */ {KAknsIIDQsnFrCaleCornerBl, ENoDraw, ES60_All, -1,-1}, /* SP_QsnFrCaleCornerBr */ {KAknsIIDQsnFrCaleCornerBr, ENoDraw, ES60_All, -1,-1}, - /* SP_QsnFrCaleGSideT */ {KAknsIIDQsnFrCaleSideT, ENoDraw, ES60_All, -1,-1}, - /* SP_QsnFrCaleGSideB */ {KAknsIIDQsnFrCaleSideB, ENoDraw, ES60_All, -1,-1}, - /* SP_QsnFrCaleGSideL */ {KAknsIIDQsnFrCaleSideL, ENoDraw, ES60_All, -1,-1}, - /* SP_QsnFrCaleGSideR */ {KAknsIIDQsnFrCaleSideR, ENoDraw, ES60_All, -1,-1}, + /* SP_QsnFrCaleSideT */ {KAknsIIDQsnFrCaleSideT, ENoDraw, ES60_All, -1,-1}, + /* SP_QsnFrCaleSideB */ {KAknsIIDQsnFrCaleSideB, ENoDraw, ES60_All, -1,-1}, + /* SP_QsnFrCaleSideL */ {KAknsIIDQsnFrCaleSideL, ENoDraw, ES60_All, -1,-1}, + /* SP_QsnFrCaleSideR */ {KAknsIIDQsnFrCaleSideR, ENoDraw, ES60_All, -1,-1}, /* SP_QsnFrCaleCenter */ {KAknsIIDQsnFrCaleCenter, ENoDraw, ES60_All, -1,-1}, /* SP_QsnFrCaleHeadingCornerTl */ {KAknsIIDQsnFrCaleHeadingCornerTl, ENoDraw, ES60_All, -1,-1}, @@ -344,28 +366,6 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { /* SP_QsnFrPopupSubSideR */ {KAknsIIDQsnFrPopupSubSideR, ENoDraw, ES60_3_X, -1,-1}, /* SP_QsnFrPopupSubCenter */ {KAknsIIDQsnFrPopupCenterSubmenu, ENoDraw, ES60_3_X, -1,-1}, - // Toolbar graphics is different in 3.1/3.2 vs. 5.0 - /* SP_QsnFrSctrlButtonCornerTl */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2301}, /* KAknsIIDQgnFrSctrlButtonCornerTl*/ - /* SP_QsnFrSctrlButtonCornerTr */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2302}, - /* SP_QsnFrSctrlButtonCornerBl */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2303}, - /* SP_QsnFrSctrlButtonCornerBr */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2304}, - /* SP_QsnFrSctrlButtonSideT */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2305}, - /* SP_QsnFrSctrlButtonSideB */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2306}, - /* SP_QsnFrSctrlButtonSideL */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2307}, - /* SP_QsnFrSctrlButtonSideR */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2308}, - /* SP_QsnFrSctrlButtonCenter */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2309}, /*KAknsIIDQgnFrSctrlButtonCenter*/ - - // No pressed state for toolbar button in 3.1/3.2. - /* SP_QsnFrSctrlButtonCornerTlPressed */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2621}, /*KAknsIIDQsnFrSctrlButtonCornerTlPressed*/ - /* SP_QsnFrSctrlButtonCornerTrPressed */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2622}, - /* SP_QsnFrSctrlButtonCornerBlPressed */ {KAknsIIDQsnFrButtonTbCornerBl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2623}, - /* SP_QsnFrSctrlButtonCornerBrPressed */ {KAknsIIDQsnFrButtonTbCornerBr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2624}, - /* SP_QsnFrSctrlButtonSideTPressed */ {KAknsIIDQsnFrButtonTbSideT, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2625}, - /* SP_QsnFrSctrlButtonSideBPressed */ {KAknsIIDQsnFrButtonTbSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2626}, - /* SP_QsnFrSctrlButtonSideLPressed */ {KAknsIIDQsnFrButtonTbSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2627}, - /* SP_QsnFrSctrlButtonSideRPressed */ {KAknsIIDQsnFrButtonTbSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2628}, - /* SP_QsnFrSctrlButtonCenterPressed */ {KAknsIIDQsnFrButtonTbCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2629}, - // No inactive button graphics in 3.1/3.2 /* SP_QsnFrButtonCornerTlInactive */ {KAknsIIDQsnFrButtonTbCornerTl, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b1}, /*KAknsIIDQsnFrButtonCornerTlInactive*/ /* SP_QsnFrButtonCornerTrInactive */ {KAknsIIDQsnFrButtonTbCornerTr, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x21b2}, @@ -397,7 +397,7 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = { /* SP_QsnFrListSideBPressed */ {KAknsIIDQsnFrListSideB, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2690}, /* SP_QsnFrListSideLPressed */ {KAknsIIDQsnFrListSideL, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2691}, /* SP_QsnFrListSideRPressed */ {KAknsIIDQsnFrListSideR, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2692}, - /* SP_QsnFrListPressed */ {KAknsIIDQsnFrList, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2693}, + /* SP_QsnFrListCenterPressed */ {KAknsIIDQsnFrListCenter, ENoDraw, ES60_3_X, EAknsMajorSkin, 0x2693}, }; QPixmap QS60StyleModeSpecifics::skinnedGraphics( @@ -514,7 +514,7 @@ void QS60StyleModeSpecifics::fallbackInfo(const QS60StyleEnums::SkinParts &style case QS60StyleEnums::SP_QgnGrafNsliderMarkerSelected: fallbackIndex = 17574; /* EMbmAvkonQgn_graf_nslider_marker_selected */ break; - case QS60StyleEnums::SP_QgnIndiSubMenu: + case QS60StyleEnums::SP_QgnIndiSubmenu: fallbackIndex = EMbmAvkonQgn_indi_submenu; break; case QS60StyleEnums::SP_QgnNoteErased: diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp index 515b6c7..43fa4b9 100644 --- a/src/gui/styles/qstylesheetstyle.cpp +++ b/src/gui/styles/qstylesheetstyle.cpp @@ -3190,7 +3190,7 @@ void QStyleSheetStyle::drawComplexControl(ComplexControl cc, const QStyleOptionC subRule2.drawRule(p, r); } - handleSubRule.drawRule(p, grooveSubRule.boxRect(hr, Margin)); + handleSubRule.drawRule(p, handleSubRule.boxRect(hr, Margin)); } if (slider->subControls & SC_SliderTickmarks) { diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 0314c6f..579dd0b 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -1388,8 +1388,9 @@ void QWindowsStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QRect r = opt->rect; int size = qMin(r.height(), r.width()); QPixmap pixmap; - QString pixmapName = QStyleHelper::uniqueName(QLatin1String("$qt_ia-") + QLatin1String(metaObject()->className()), opt, QSize(size, size)) - + QLatin1Char('-') + QString::number(pe); + QString pixmapName = QStyleHelper::uniqueName(QLatin1String("$qt_ia-") + % QLatin1String(metaObject()->className()), opt, QSize(size, size)) + % HexString<uint>(pe); if (!QPixmapCache::find(pixmapName, pixmap)) { int border = size/5; int sqsize = 2*(size/2); diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 489b70b..943df7f 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -49,12 +49,12 @@ #include <private/qt_s60_p.h> #include "qendian.h" #include <private/qcore_symbian_p.h> -#if defined(QT_NO_FREETYPE) +#ifdef QT_NO_FREETYPE #include <openfont.h> #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS #include <graphics/openfontrasterizer.h> // COpenFontRasterizer has moved to a new header file #endif // SYMBIAN_ENABLE_SPLIT_HEADERS -#endif +#endif // QT_NO_FREETYPE QT_BEGIN_NAMESPACE @@ -91,7 +91,7 @@ QFileInfoList alternativeFilePaths(const QString &path, const QStringList &nameF return result; } -#if defined(QT_NO_FREETYPE) +#ifdef QT_NO_FREETYPE class QSymbianFontDatabaseExtrasImplementation : public QSymbianFontDatabaseExtras { public: @@ -100,16 +100,41 @@ public: const QSymbianTypeFaceExtras *extras(const QString &typeface, bool bold, bool italic) const; +#ifndef Q_SYMBIAN_HAS_FONTTABLE_API + struct CFontFromFontStoreReleaser { + static inline void cleanup(CFont *font) + { + if (!font) + return; + const QSymbianFontDatabaseExtrasImplementation *dbExtras = + static_cast<const QSymbianFontDatabaseExtrasImplementation*>(privateDb()->symbianExtras); + dbExtras->m_store->ReleaseFont(font); + } + }; +#endif // !Q_SYMBIAN_HAS_FONTTABLE_API + + struct CFontFromScreenDeviceReleaser { + static inline void cleanup(CFont *font) + { + if (!font) + return; + QS60Data::screenDevice()->ReleaseFont(font); + } + }; + private: +#ifndef Q_SYMBIAN_HAS_FONTTABLE_API RHeap* m_heap; CFontStore *m_store; COpenFontRasterizer *m_rasterizer; mutable QList<const QSymbianTypeFaceExtras *> m_extras; +#endif // !Q_SYMBIAN_HAS_FONTTABLE_API mutable QHash<QString, const QSymbianTypeFaceExtras *> m_extrasHash; }; QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementation() { +#ifndef Q_SYMBIAN_HAS_FONTTABLE_API QStringList filters; filters.append(QLatin1String("*.ttf")); filters.append(QLatin1String("*.ccc")); @@ -131,10 +156,14 @@ QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementati TPtrC fontFilePtr(qt_QString2TPtrC(fontFile)); QT_TRAP_THROWING(m_store->AddFileL(fontFilePtr)); } +#endif // !Q_SYMBIAN_HAS_FONTTABLE_API } QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementation() { +#ifdef Q_SYMBIAN_HAS_FONTTABLE_API + qDeleteAll(m_extrasHash); +#else // Q_SYMBIAN_HAS_FONTTABLE_API typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator; for (iterator p = m_extras.begin(); p != m_extras.end(); ++p) { m_store->ReleaseFont((*p)->fontOwner()); @@ -143,6 +172,7 @@ QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementat delete m_store; m_heap->Close(); +#endif // Q_SYMBIAN_HAS_FONTTABLE_API } #ifndef FNTSTORE_H_INLINES_SUPPORT_FMM @@ -167,26 +197,37 @@ const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(c { const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic)); if (!m_extrasHash.contains(searchKey)) { - CFont* font = NULL; TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1); if (bold) searchSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); if (italic) searchSpec.iFontStyle.SetPosture(EPostureItalic); + + CFont* font = NULL; +#ifdef Q_SYMBIAN_HAS_FONTTABLE_API + const TInt err = QS60Data::screenDevice()->GetNearestFontToDesignHeightInPixels(font, searchSpec); + Q_ASSERT(err == KErrNone && font); + QScopedPointer<CFont, CFontFromScreenDeviceReleaser> sFont(font); + QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font); + sFont.take(); + m_extrasHash.insert(searchKey, extras); +#else // Q_SYMBIAN_HAS_FONTTABLE_API const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec); Q_ASSERT(err == KErrNone && font); const CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font); COpenFont *openFont = #ifdef FNTSTORE_H_INLINES_SUPPORT_FMM - bitmapFont->openFont(); -#else + bitmapFont->OpenFont(); +#else // FNTSTORE_H_INLINES_SUPPORT_FMM OpenFontFromBitmapFont(bitmapFont); #endif // FNTSTORE_H_INLINES_SUPPORT_FMM const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib(); const QString foundKey = QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length()); if (!m_extrasHash.contains(foundKey)) { + QScopedPointer<CFont, CFontFromFontStoreReleaser> sFont(font); QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont); + sFont.take(); m_extras.append(extras); m_extrasHash.insert(searchKey, extras); m_extrasHash.insert(foundKey, extras); @@ -194,10 +235,11 @@ const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(c m_store->ReleaseFont(font); m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey)); } +#endif // Q_SYMBIAN_HAS_FONTTABLE_API } return m_extrasHash.value(searchKey); } -#else +#else // QT_NO_FREETYPE class QFontEngineFTS60 : public QFontEngineFT { public: @@ -209,7 +251,7 @@ QFontEngineFTS60::QFontEngineFTS60(const QFontDef &fd) { default_hint_style = HintFull; } -#endif // defined(QT_NO_FREETYPE) +#endif // QT_NO_FREETYPE /* QFontEngineS60::pixelsToPoints, QFontEngineS60::pointsToPixels, QFontEngineMultiS60::QFontEngineMultiS60 @@ -261,12 +303,12 @@ static void initializeDb() if(!db || db->count) return; -#if defined(QT_NO_FREETYPE) +#ifdef QT_NO_FREETYPE if (!db->symbianExtras) db->symbianExtras = new QSymbianFontDatabaseExtrasImplementation; QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock); - + const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces(); const QSymbianFontDatabaseExtrasImplementation *dbExtras = static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras); @@ -278,6 +320,7 @@ static void initializeDb() TFontSpec fontSpec(typefaceSupport.iTypeface.iName, 11); if (QS60Data::screenDevice()->GetNearestFontInPixels(font, fontSpec) != KErrNone) continue; + QScopedPointer<CFont, QSymbianFontDatabaseExtrasImplementation::CFontFromScreenDeviceReleaser> sFont(font); if (font->TypeUid() == KCFbsFontUid) { TOpenFontFaceAttrib faceAttrib; const CFbsFont *cfbsFont = static_cast<const CFbsFont *>(font); @@ -318,14 +361,13 @@ static void initializeDb() fontAdded = true; } - QS60Data::screenDevice()->ReleaseFont(font); } Q_ASSERT(fontAdded); - lock.relock(); + lock.relock(); -#else // defined(QT_NO_FREETYPE) +#else // QT_NO_FREETYPE QDir dir(QDesktopServices::storageLocation(QDesktopServices::FontsLocation)); dir.setNameFilters(QStringList() << QLatin1String("*.ttf") << QLatin1String("*.ttc") << QLatin1String("*.pfa") @@ -334,7 +376,7 @@ static void initializeDb() const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i])); db->addTTFile(file); } -#endif // defined(QT_NO_FREETYPE) +#endif // QT_NO_FREETYPE } static inline void load(const QString &family = QString(), int script = -1) @@ -416,13 +458,13 @@ QFontEngine *QFontDatabase::findFont(int script, const QFontPrivate *, const QFo const QString fontFamily = desc.family->name; QFontDef request = req; request.family = fontFamily; -#if defined(QT_NO_FREETYPE) +#ifdef QT_NO_FREETYPE const QSymbianFontDatabaseExtrasImplementation *dbExtras = static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras); const QSymbianTypeFaceExtras *typeFaceExtras = dbExtras->extras(fontFamily, request.weight > QFont::Normal, request.style != QFont::StyleNormal); fe = new QFontEngineS60(request, typeFaceExtras); -#else +#else // QT_NO_FREETYPE QFontEngine::FaceId faceId; const QtFontFamily * const reqQtFontFamily = db->family(fontFamily); faceId.filename = reqQtFontFamily->fontFilename; @@ -433,7 +475,7 @@ QFontEngine *QFontDatabase::findFont(int script, const QFontPrivate *, const QFo fe = fte; else delete fte; -#endif +#endif // QT_NO_FREETYPE Q_ASSERT(fe); if (script == QUnicodeTables::Common diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 449dffd..2c4fbab 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -58,6 +58,7 @@ #include <ft2build.h> #include FT_FREETYPE_H #include FT_OUTLINE_H +#include FT_SYNTHESIS_H #include FT_TRUETYPE_TABLES_H #include FT_TYPE1_TABLES_H #include FT_GLYPH_H @@ -617,6 +618,7 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd) cache_cost = 100; kerning_pairs_loaded = false; transform = false; + embolden = false; antialias = true; freetype = 0; default_load_flags = FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; @@ -679,10 +681,7 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format) FT_Face face = lockFace(); - //underline metrics if (FT_IS_SCALABLE(face)) { - line_thickness = QFixed::fromFixed(FT_MulFix(face->underline_thickness, face->size->metrics.y_scale)); - underline_position = QFixed::fromFixed(-FT_MulFix(face->underline_position, face->size->metrics.y_scale)); bool fake_oblique = (fontDef.style != QFont::StyleNormal) && !(face->style_flags & FT_STYLE_FLAG_ITALIC); if (fake_oblique) matrix.xy = 0x10000*3/10; @@ -690,6 +689,12 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format) freetype->matrix = matrix; if (fake_oblique) transform = true; + // fake bold + if ((fontDef.weight == QFont::Bold) && !(face->style_flags & FT_STYLE_FLAG_BOLD) && !FT_IS_FIXED_WIDTH(face)) + embolden = true; + // underline metrics + line_thickness = QFixed::fromFixed(FT_MulFix(face->underline_thickness, face->size->metrics.y_scale)); + underline_position = QFixed::fromFixed(-FT_MulFix(face->underline_position, face->size->metrics.y_scale)); } else { // copied from QFontEngineQPF // ad hoc algorithm @@ -789,6 +794,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph } FT_GlyphSlot slot = face->glyph; + if (embolden) FT_GlyphSlot_Embolden(slot); int left = slot->metrics.horiBearingX; int right = slot->metrics.horiBearingX + slot->metrics.width; int top = slot->metrics.horiBearingY; @@ -934,6 +940,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, Glyph return 0; FT_GlyphSlot slot = face->glyph; + if (embolden) FT_GlyphSlot_Embolden(slot); FT_Library library = qt_getFreetype(); info.xOff = TRUNC(ROUND(slot->advance.x)); @@ -1209,6 +1216,8 @@ int QFontEngineFT::synthesized() const int s = 0; if ((fontDef.style != QFont::StyleNormal) && !(freetype->face->style_flags & FT_STYLE_FLAG_ITALIC)) s = SynthesizedItalic; + if ((fontDef.weight == QFont::Bold) && !(freetype->face->style_flags & FT_STYLE_FLAG_BOLD)) + s |= SynthesizedBold; if (fontDef.stretch != 100 && FT_IS_SCALABLE(freetype->face)) s |= SynthesizedStretch; return s; diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 12b7da8..2f05a8b 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -304,6 +304,7 @@ protected: bool antialias; bool transform; + bool embolden; SubpixelAntialiasingType subpixelType; int lcdFilterType; bool canUploadGlyphsToServer; diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp index 93f02ff..925b3bf 100644 --- a/src/gui/text/qfontengine_s60.cpp +++ b/src/gui/text/qfontengine_s60.cpp @@ -50,21 +50,73 @@ #include <e32std.h> #include <eikenv.h> #include <gdi.h> +#if defined(Q_SYMBIAN_HAS_FONTTABLE_API) || defined(Q_SYMBIAN_HAS_GLYPHOUTLINE_API) +#include <graphics/gdi/gdiplatapi.h> +#endif // Q_SYMBIAN_HAS_FONTTABLE_API || Q_SYMBIAN_HAS_GLYPHOUTLINE_API QT_BEGIN_NAMESPACE -QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* fontOwner, COpenFont *font) - : m_font(font) - , m_cmap(0) +#ifdef Q_SYMBIAN_HAS_FONTTABLE_API +QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont) + : m_cFont(cFont) , m_symbolCMap(false) - , m_fontOwner(fontOwner) +{ + Q_UNUSED(openFont) +} + +QSymbianTypeFaceExtras::~QSymbianTypeFaceExtras() +{ + QS60Data::screenDevice()->ReleaseFont(m_cFont); +} + +QByteArray QSymbianTypeFaceExtras::getSfntTable(uint tag) const +{ + RFontTable fontTable; + if (fontTable.Open(*m_cFont, tag) != KErrNone) + return QByteArray(); + const QByteArray byteArray(reinterpret_cast<const char *> + (fontTable.TableContent()),fontTable.TableLength()); + fontTable.Close(); + return byteArray; +} + +bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *length) const +{ + RFontTable fontTable; + if (fontTable.Open(*m_cFont, tag) != KErrNone) + return false; + + bool result = true; + const TInt tableByteLength = fontTable.TableLength(); + + if (*length > 0 && *length < tableByteLength) { + result = false; // Caller did not allocate enough memory + } else { + *length = tableByteLength; + if (buffer) + qMemCopy(buffer, fontTable.TableContent(), tableByteLength); + } + + fontTable.Close(); + return result; +} + +#else // Q_SYMBIAN_HAS_FONTTABLE_API +QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont) + : m_cFont(cFont) + , m_symbolCMap(false) + , m_openFont(openFont) { TAny *trueTypeExtension = NULL; - m_font->ExtendedInterface(KUidOpenFontTrueTypeExtension, trueTypeExtension); + m_openFont->ExtendedInterface(KUidOpenFontTrueTypeExtension, trueTypeExtension); m_trueTypeExtension = static_cast<MOpenFontTrueTypeExtension*>(trueTypeExtension); Q_ASSERT(m_trueTypeExtension); } +QSymbianTypeFaceExtras::~QSymbianTypeFaceExtras() +{ +} + QByteArray QSymbianTypeFaceExtras::getSfntTable(uint tag) const { Q_ASSERT(m_trueTypeExtension->HasTrueTypeTable(tag)); @@ -100,23 +152,25 @@ bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *len m_trueTypeExtension->ReleaseTrueTypeTable(table); return result; } +#endif // Q_SYMBIAN_HAS_FONTTABLE_API -const unsigned char *QSymbianTypeFaceExtras::cmap() const +const uchar *QSymbianTypeFaceExtras::cmap() const { - if (!m_cmap) { - m_cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p')); + if (m_cmapTable.isNull()) { + const QByteArray cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p')); int size = 0; - m_cmap = QFontEngineS60::getCMap(reinterpret_cast<const uchar *>(m_cmapTable.constData()), m_cmapTable.size(), &m_symbolCMap, &size); + const uchar *cmap = QFontEngine::getCMap(reinterpret_cast<const uchar *> + (cmapTable.constData()), cmapTable.size(), &m_symbolCMap, &size); + m_cmapTable = QByteArray(reinterpret_cast<const char *>(cmap), size); } - return m_cmap; + return reinterpret_cast<const uchar *>(m_cmapTable.constData()); } CFont *QSymbianTypeFaceExtras::fontOwner() const { - return m_fontOwner; + return m_cFont; } - // duplicated from qfontengine_xyz.cpp static inline unsigned int getChar(const QChar *str, int &i, const int len) { @@ -225,6 +279,35 @@ void QFontEngineS60::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla } } +#ifdef Q_SYMBIAN_HAS_GLYPHOUTLINE_API +static bool parseGlyphPathData(const char *dataStr, const char *dataEnd, QPainterPath &path, + qreal fontPixelSize, const QPointF &offset, bool hinted); +#endif //Q_SYMBIAN_HAS_GLYPHOUTLINE_API + +void QFontEngineS60::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, + int nglyphs, QPainterPath *path, + QTextItem::RenderFlags flags) +{ +#ifdef Q_SYMBIAN_HAS_GLYPHOUTLINE_API + Q_UNUSED(flags) + RGlyphOutlineIterator iterator; + const TInt error = iterator.Open(*m_activeFont, glyphs, nglyphs); + if (KErrNone != error) + return; + const qreal fontSizeInPixels = qreal(m_activeFont->HeightInPixels()); + int count = 0; + do { + const TUint8* outlineUint8 = iterator.Outline(); + const char* const outlineChar = reinterpret_cast<const char*>(outlineUint8); + const char* const outlineEnd = outlineChar + iterator.OutlineLength(); + parseGlyphPathData(outlineChar, outlineEnd, *path, fontSizeInPixels, + positions[count++].toPointF(), false); + } while(KErrNone == iterator.Next() && count <= nglyphs); +#else // Q_SYMBIAN_HAS_GLYPHOUTLINE_API + QFontEngine::addGlyphsToPath(glyphs, positions, nglyphs, path, flags); +#endif //Q_SYMBIAN_HAS_GLYPHOUTLINE_API +} + QImage QFontEngineS60::alphaMapForGlyph(glyph_t glyph) { TOpenFontCharMetrics metrics; @@ -356,4 +439,69 @@ void QFontEngineS60::getCharacterData(glyph_t glyph, TOpenFontCharMetrics& metri } } +#ifdef Q_SYMBIAN_HAS_GLYPHOUTLINE_API +static inline void skipSpacesAndComma(const char* &str, const char* const strEnd) +{ + while (str <= strEnd && (*str == ' ' || *str == ',')) + ++str; +} + +static bool parseGlyphPathData(const char *svgPath, const char *svgPathEnd, QPainterPath &path, + qreal fontPixelSize, const QPointF &offset, bool hinted) +{ + Q_UNUSED(hinted) + QPointF p1, p2, firstSubPathPoint; + qreal *elementValues[] = + {&p1.rx(), &p1.ry(), &p2.rx(), &p2.ry()}; + const int unitsPerEm = 2048; // See: http://en.wikipedia.org/wiki/Em_%28typography%29 + const qreal resizeFactor = fontPixelSize / unitsPerEm; + + while (svgPath < svgPathEnd) { + skipSpacesAndComma(svgPath, svgPathEnd); + const char pathElem = *svgPath++; + skipSpacesAndComma(svgPath, svgPathEnd); + + if (pathElem != 'Z') { + char *endStr = 0; + int elementValuesCount = 0; + for (int i = 0; i < 4; ++i) { // 4 = size of elementValues[] + qreal coordinateValue = strtod(svgPath, &endStr); + if (svgPath == endStr) + break; + if (i % 2) // Flip vertically + coordinateValue = -coordinateValue; + *elementValues[i] = coordinateValue * resizeFactor; + elementValuesCount++; + svgPath = endStr; + skipSpacesAndComma(svgPath, svgPathEnd); + } + p1 += offset; + if (elementValuesCount == 2) + p2 = firstSubPathPoint; + else + p2 += offset; + } + + switch (pathElem) { + case 'M': + firstSubPathPoint = p1; + path.moveTo(p1); + break; + case 'Z': + path.closeSubpath(); + break; + case 'L': + path.lineTo(p1); + break; + case 'Q': + path.quadTo(p1, p2); + break; + default: + return false; + } + } + return true; +} +#endif // Q_SYMBIAN_HAS_GLYPHOUTLINE_API + QT_END_NAMESPACE diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h index 6883730..beeb4cc 100644 --- a/src/gui/text/qfontengine_s60_p.h +++ b/src/gui/text/qfontengine_s60_p.h @@ -58,6 +58,14 @@ #include "qsize.h" #include <openfont.h> +#ifdef SYMBIAN_GDI_GLYPHDATA +#define Q_SYMBIAN_HAS_FONTTABLE_API +#endif + +#ifdef Q_SYMBIAN_HAS_FONTTABLE_API +#define Q_SYMBIAN_HAS_GLYPHOUTLINE_API +#endif // Q_SYMBIAN_HAS_FONTTABLE_API + class CFont; QT_BEGIN_NAMESPACE @@ -66,20 +74,22 @@ QT_BEGIN_NAMESPACE class QSymbianTypeFaceExtras { public: - QSymbianTypeFaceExtras(CFont* fontOwner, COpenFont *font); + QSymbianTypeFaceExtras(CFont* cFont, COpenFont *openFont = 0); + ~QSymbianTypeFaceExtras(); QByteArray getSfntTable(uint tag) const; bool getSfntTableData(uint tag, uchar *buffer, uint *length) const; - const unsigned char *cmap() const; + const uchar *cmap() const; CFont *fontOwner() const; private: - COpenFont *m_font; - mutable MOpenFontTrueTypeExtension *m_trueTypeExtension; - mutable const unsigned char *m_cmap; + CFont* m_cFont; mutable bool m_symbolCMap; mutable QByteArray m_cmapTable; - CFont* m_fontOwner; +#ifndef Q_SYMBIAN_HAS_FONTTABLE_API + COpenFont *m_openFont; + mutable MOpenFontTrueTypeExtension *m_trueTypeExtension; +#endif // Q_SYMBIAN_HAS_FONTTABLE_API }; class QFontEngineS60 : public QFontEngine @@ -91,6 +101,9 @@ public: bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; void recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlags flags) const; + void addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs, + QPainterPath *path, QTextItem::RenderFlags flags); + QImage alphaMapForGlyph(glyph_t glyph); glyph_metrics_t boundingBox(const QGlyphLayout &glyphs); diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 5163c94..d02e841 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -526,6 +526,14 @@ int QFontMetrics::rightBearing(QChar ch) const */ int QFontMetrics::width(const QString &text, int len) const { + return width(text, len, 0); +} + +/*! + \internal +*/ +int QFontMetrics::width(const QString &text, int len, int flags) const +{ int pos = text.indexOf(QLatin1Char('\x9c')); if (pos != -1) { len = (len < 0) ? pos : qMin(pos, len); @@ -535,6 +543,23 @@ int QFontMetrics::width(const QString &text, int len) const if (len == 0) return 0; + if (flags & Qt::TextBypassShaping) { + // Skip harfbuzz complex shaping, only use advances + int numGlyphs = len; + QVarLengthGlyphLayoutArray glyphs(numGlyphs); + QFontEngine *engine = d->engineForScript(QUnicodeTables::Common); + if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0)) { + glyphs.resize(numGlyphs); + if (!engine->stringToCMap(text.data(), len, &glyphs, &numGlyphs, 0)) + Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice"); + } + + QFixed width; + for (int i = 0; i < numGlyphs; ++i) + width += glyphs.advances_x[i]; + return qRound(width); + } + QStackTextEngine layout(text, d.data()); layout.ignoreBidi = true; return qRound(layout.width(0, len)); diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h index dca4b93..2518b54 100644 --- a/src/gui/text/qfontmetrics.h +++ b/src/gui/text/qfontmetrics.h @@ -89,6 +89,7 @@ public: int leftBearing(QChar) const; int rightBearing(QChar) const; int width(const QString &, int len = -1) const; + int width(const QString &, int len, int flags) const; int width(QChar) const; int charWidth(const QString &str, int pos) const; diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index 84c1d96..c742455 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -115,10 +115,12 @@ QT_BEGIN_NAMESPACE Qt::RichText. If it's the first time the static text is drawn, or if the static text, or the painter's font - or matrix have been altered since the last time it was drawn, the text's layout has to be - recalculated. This will impose an overhead on the QPainter::drawStaticText() call where the - relayout occurs. To avoid this overhead in the paint event, you can call prepare() ahead of - time to ensure that the layout is calculated. + has been altered since the last time it was drawn, the text's layout has to be + recalculated. On some paint engines, changing the matrix of the painter will also cause the + layout to be recalculated. In particular, this will happen for any engine except for the + OpenGL2 paint engine. Recalculating the layout will impose an overhead on the + QPainter::drawStaticText() call where it occurs. To avoid this overhead in the paint event, you + can call prepare() ahead of time to ensure that the layout is calculated. \sa QPainter::drawText(), QPainter::drawStaticText(), QTextLayout, QTextDocument */ @@ -188,8 +190,9 @@ void QStaticText::detach() When drawStaticText() is called, the layout of the QStaticText will be recalculated if any part of the QStaticText object has changed since the last time it was drawn. It will also be - recalculated if the painter's font or matrix are not the same as when the QStaticText was last - drawn. + recalculated if the painter's font is not the same as when the QStaticText was last drawn, or, + on any other paint engine than the OpenGL2 engine, if the painter's matrix has been altered + since the static text was last drawn. To avoid the overhead of creating the layout the first time you draw the QStaticText after making changes, you can use the prepare() function and pass in the \a matrix and \a font you @@ -321,6 +324,26 @@ QStaticText::PerformanceHint QStaticText::performanceHint() const } /*! + Sets the text option structure that controls the layout process to the given \a textOption. + + \sa textOption() +*/ +void QStaticText::setTextOption(const QTextOption &textOption) +{ + detach(); + data->textOption = textOption; + data->invalidate(); +} + +/*! + Returns the current text option used to control the layout process. +*/ +QTextOption QStaticText::textOption() const +{ + return data->textOption; +} + +/*! Sets the preferred width for this QStaticText. If the text is wider than the specified width, it will be broken into multiple lines and grow vertically. If the text cannot be split into multiple lines, it will be larger than the specified \a textWidth. @@ -364,14 +387,16 @@ QSizeF QStaticText::size() const QStaticTextPrivate::QStaticTextPrivate() : textWidth(-1.0), items(0), itemCount(0), glyphPool(0), positionPool(0), charPool(0), - needsRelayout(true), useBackendOptimizations(false), textFormat(Qt::AutoText) + needsRelayout(true), useBackendOptimizations(false), textFormat(Qt::AutoText), + untransformedCoordinates(false) { } QStaticTextPrivate::QStaticTextPrivate(const QStaticTextPrivate &other) : text(other.text), font(other.font), textWidth(other.textWidth), matrix(other.matrix), items(0), itemCount(0), glyphPool(0), positionPool(0), charPool(0), needsRelayout(true), - useBackendOptimizations(other.useBackendOptimizations), textFormat(other.textFormat) + useBackendOptimizations(other.useBackendOptimizations), textFormat(other.textFormat), + untransformedCoordinates(other.untransformedCoordinates) { } @@ -396,8 +421,9 @@ namespace { class DrawTextItemRecorder: public QPaintEngine { public: - DrawTextItemRecorder(bool useBackendOptimizations, int numChars) - : m_dirtyPen(false), m_useBackendOptimizations(useBackendOptimizations) + DrawTextItemRecorder(bool untransformedCoordinates, bool useBackendOptimizations, int numChars) + : m_dirtyPen(false), m_useBackendOptimizations(useBackendOptimizations), + m_untransformedCoordinates(untransformedCoordinates) { } @@ -423,7 +449,7 @@ namespace { if (m_dirtyPen) currentItem.color = state->pen().color(); - QTransform matrix = state->transform(); + QTransform matrix = m_untransformedCoordinates ? QTransform() : state->transform(); matrix.translate(position.x(), position.y()); QVarLengthArray<glyph_t> glyphs; @@ -486,14 +512,17 @@ namespace { bool m_dirtyPen; bool m_useBackendOptimizations; + bool m_untransformedCoordinates; }; class DrawTextItemDevice: public QPaintDevice { public: - DrawTextItemDevice(bool useBackendOptimizations, int numChars) + DrawTextItemDevice(bool untransformedCoordinates, bool useBackendOptimizations, + int numChars) { - m_paintEngine = new DrawTextItemRecorder(useBackendOptimizations, numChars); + m_paintEngine = new DrawTextItemRecorder(untransformedCoordinates, + useBackendOptimizations, numChars); } ~DrawTextItemDevice() @@ -571,6 +600,7 @@ void QStaticTextPrivate::paintText(const QPointF &topLeftPosition, QPainter *p) QTextLayout textLayout; textLayout.setText(text); textLayout.setFont(font); + textLayout.setTextOption(textOption); qreal leading = QFontMetricsF(font).leading(); qreal height = -leading; @@ -601,21 +631,26 @@ void QStaticTextPrivate::paintText(const QPointF &topLeftPosition, QPainter *p) .arg(QString::number(color.blue(), 16), 2, QLatin1Char('0'))); #endif document.setDefaultFont(font); - document.setDocumentMargin(0.0); - if (textWidth >= 0.0) - document.setTextWidth(textWidth); + document.setDocumentMargin(0.0); #ifndef QT_NO_TEXTHTMLPARSER document.setHtml(text); #else document.setPlainText(text); #endif + if (textWidth >= 0.0) + document.setTextWidth(textWidth); + else + document.adjustSize(); + document.setDefaultTextOption(textOption); - document.adjustSize(); p->save(); p->translate(topLeftPosition); document.drawContents(p); p->restore(); + if (textWidth >= 0.0) + document.adjustSize(); // Find optimal size + actualSize = document.size(); } } @@ -629,7 +664,7 @@ void QStaticTextPrivate::init() position = QPointF(0, 0); - DrawTextItemDevice device(useBackendOptimizations, text.size()); + DrawTextItemDevice device(untransformedCoordinates, useBackendOptimizations, text.size()); { QPainter painter(&device); painter.setFont(font); diff --git a/src/gui/text/qstatictext.h b/src/gui/text/qstatictext.h index f3bef93..4febde2 100644 --- a/src/gui/text/qstatictext.h +++ b/src/gui/text/qstatictext.h @@ -48,7 +48,7 @@ #include <QtGui/qtransform.h> #include <QtGui/qfont.h> - +#include <QtGui/qtextoption.h> QT_BEGIN_HEADER @@ -79,6 +79,9 @@ public: void setTextWidth(qreal textWidth); qreal textWidth() const; + void setTextOption(const QTextOption &textOption); + QTextOption textOption() const; + QSizeF size() const; void prepare(const QTransform &matrix = QTransform(), const QFont &font = QFont()); diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h index 2ab5579..cb60626 100644 --- a/src/gui/text/qstatictext_p.h +++ b/src/gui/text/qstatictext_p.h @@ -53,6 +53,8 @@ // We mean it. // +#include "qstatictext.h" + #include <private/qtextureglyphcache_p.h> #include <QtGui/qcolor.h> @@ -148,11 +150,14 @@ public: QFixedPoint *positionPool; // 4 bytes per text QChar *charPool; // 4 bytes per text - unsigned char needsRelayout : 1; - unsigned char useBackendOptimizations : 1; // 1 byte per text - unsigned char textFormat : 2; + QTextOption textOption; // 28 bytes per text + + unsigned char needsRelayout : 1; // 1 byte per text + unsigned char useBackendOptimizations : 1; + unsigned char textFormat : 2; + unsigned char untransformedCoordinates : 1; // ================ - // 167 bytes per text + // 195 bytes per text static QStaticTextPrivate *get(const QStaticText *q); }; diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index c91df3c..a9caa6b 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -64,7 +64,7 @@ enum { QTextCursorPrivate::QTextCursorPrivate(QTextDocumentPrivate *p) : priv(p), x(0), position(0), anchor(0), adjusted_anchor(0), - currentCharFormat(-1), visualNavigation(false) + currentCharFormat(-1), visualNavigation(false), keepPositionOnInsert(false) { priv->addCursor(this); } @@ -79,6 +79,7 @@ QTextCursorPrivate::QTextCursorPrivate(const QTextCursorPrivate &rhs) x = rhs.x; currentCharFormat = rhs.currentCharFormat; visualNavigation = rhs.visualNavigation; + keepPositionOnInsert = rhs.keepPositionOnInsert; priv->addCursor(this); } @@ -95,7 +96,7 @@ QTextCursorPrivate::AdjustResult QTextCursorPrivate::adjustPosition(int position if (position < positionOfChange || (position == positionOfChange && (op == QTextUndoCommand::KeepCursor - || anchor < position) + || keepPositionOnInsert) ) ) { result = CursorUnchanged; @@ -361,7 +362,7 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor QTextBlock blockIt = block(); if (op >= QTextCursor::Left && op <= QTextCursor::WordRight - && blockIt.blockFormat().layoutDirection() == Qt::RightToLeft) { + && blockIt.textDirection() == Qt::RightToLeft) { if (op == QTextCursor::Left) op = QTextCursor::NextCharacter; else if (op == QTextCursor::Right) @@ -1276,6 +1277,80 @@ void QTextCursor::setVisualNavigation(bool b) d->visualNavigation = b; } + +/*! + \since 4.7 + + Sets the visual x position for vertical cursor movements. + + The vertical movement x position is cleared automatically when the cursor moves horizontally, and kept + unchanged when the cursor moves vertically. The mechanism allows the cursor to move up and down on a + visually straight line with proportional fonts, and to gently "jump" over short lines. + + A value of -1 indicates no predefined x position. It will then be set automatically the next time the + cursor moves up or down. + + \sa verticalMovementX() + */ +void QTextCursor::setVerticalMovementX(int x) +{ + if (d) + d->x = x; +} + +/*! \since 4.7 + + Returns the visual x position for vertical cursor movements. + + A value of -1 indicates no predefined x position. It will then be set automatically the next time the + cursor moves up or down. + + \sa setVerticalMovementX() + */ +int QTextCursor::verticalMovementX() const +{ + return d ? d->x : -1; +} + +/*! + \since 4.7 + + Returns whether the cursor should keep its current position when text gets inserted at the position of the + cursor. + + The default is false; + + \sa setKeepPositionOnInsert() + */ +bool QTextCursor::keepPositionOnInsert() const +{ + return d ? d->keepPositionOnInsert : false; +} + +/*! + \since 4.7 + + Defines whether the cursor should keep its current position when text gets inserted at the current position of the + cursor. + + If \b is true, the cursor keeps its current position when text gets inserted at the positing of the cursor. + If \b is false, the cursor moves along with the inserted text. + + The default is false. + + Note that a cursor always moves when text is inserted before the current position of the cursor, and it + always keeps its position when text is inserted after the current position of the cursor. + + \sa keepPositionOnInsert() + */ +void QTextCursor::setKeepPositionOnInsert(bool b) +{ + if (d) + d->keepPositionOnInsert = b; +} + + + /*! Inserts \a text at the current position, using the current character format. @@ -1408,16 +1483,16 @@ void QTextCursor::deletePreviousChar() { if (!d || !d->priv) return; - + if (d->position != d->anchor) { removeSelectedText(); return; } - + if (d->anchor < 1 || !d->canDelete(d->anchor-1)) return; d->anchor--; - + QTextDocumentPrivate::FragmentIterator fragIt = d->priv->find(d->anchor); const QTextFragmentData * const frag = fragIt.value(); int fpos = fragIt.position(); @@ -1429,7 +1504,7 @@ void QTextCursor::deletePreviousChar() if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) --d->anchor; } - + d->adjusted_anchor = d->anchor; d->remove(); d->setX(); @@ -2362,6 +2437,9 @@ void QTextCursor::beginEditBlock() if (!d || !d->priv) return; + if (d->priv->editBlock == 0) // we are the initial edit block, store current cursor position for undo + d->priv->editBlockCursorPosition = d->position; + d->priv->beginEditBlock(); } diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index 3e968a3..251cb33 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -132,6 +132,12 @@ public: bool visualNavigation() const; void setVisualNavigation(bool b); + void setVerticalMovementX(int x); + int verticalMovementX() const; + + void setKeepPositionOnInsert(bool b); + bool keepPositionOnInsert() const; + void deleteChar(); void deletePreviousChar(); diff --git a/src/gui/text/qtextcursor_p.h b/src/gui/text/qtextcursor_p.h index 1bdfa78..4e36b95 100644 --- a/src/gui/text/qtextcursor_p.h +++ b/src/gui/text/qtextcursor_p.h @@ -112,7 +112,8 @@ public: int anchor; int adjusted_anchor; int currentCharFormat; - bool visualNavigation; + uint visualNavigation : 1; + uint keepPositionOnInsert : 1; }; QT_END_NAMESPACE diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index c7a9756..48aee8f 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2496,13 +2496,10 @@ void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block) QTextBlockFormat format = block.blockFormat(); emitAlignment(format.alignment()); - Qt::LayoutDirection dir = format.layoutDirection(); - if (dir == Qt::LeftToRight) { - // assume default to not bloat the html too much - // html += QLatin1String(" dir='ltr'"); - } else { + // assume default to not bloat the html too much + // html += QLatin1String(" dir='ltr'"); + if (block.textDirection() == Qt::RightToLeft) html += QLatin1String(" dir='rtl'"); - } QLatin1String style(" style=\""); html += style; diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index e2bca04..f3cd481 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -192,6 +192,7 @@ QTextDocumentPrivate::QTextDocumentPrivate() initialBlockCharFormatIndex(-1) // set correctly later in init() { editBlock = 0; + editBlockCursorPosition = -1; docChangeFrom = -1; undoState = 0; @@ -967,6 +968,10 @@ int QTextDocumentPrivate::undoRedo(bool undo) editPos = -1; break; } + case QTextUndoCommand::CursorMoved: + editPos = c.pos; + editLength = 0; + break; case QTextUndoCommand::Custom: resetBlockRevision = -1; // ## TODO if (undo) @@ -1046,6 +1051,18 @@ void QTextDocumentPrivate::appendUndoItem(const QTextUndoCommand &c) if (undoState < undoStack.size()) clearUndoRedoStacks(QTextDocument::RedoStack); + if (editBlock != 0 && editBlockCursorPosition >= 0) { // we had a beginEditBlock() with a cursor position + if (c.pos != (quint32) editBlockCursorPosition) { // and that cursor position is different from the command + // generate a CursorMoved undo item + QT_INIT_TEXTUNDOCOMMAND(cc, QTextUndoCommand::CursorMoved, true, QTextUndoCommand::MoveCursor, + 0, 0, editBlockCursorPosition, 0, 0); + undoStack.append(cc); + undoState++; + editBlockCursorPosition = -1; + } + } + + if (!undoStack.isEmpty() && modified) { QTextUndoCommand &last = undoStack[undoState - 1]; @@ -1167,6 +1184,8 @@ void QTextDocumentPrivate::endEditBlock() } } + editBlockCursorPosition = -1; + finishEdit(); } diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h index ac5ed3c..d1bd698 100644 --- a/src/gui/text/qtextdocument_p.h +++ b/src/gui/text/qtextdocument_p.h @@ -132,6 +132,7 @@ public: BlockAdded = 6, BlockDeleted = 7, GroupFormatChange = 8, + CursorMoved = 9, Custom = 256 }; enum Operation { @@ -315,6 +316,7 @@ private: bool modified; int editBlock; + int editBlockCursorPosition; int docChangeFrom; int docChangeOldLength; int docChangeLength; diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index f12bf0b..ff14490 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -79,7 +79,7 @@ Q_GUI_EXPORT extern int qt_defaultDpi(); // ################ should probably add frameFormatChange notification! -struct QLayoutStruct; +struct QTextLayoutStruct; class QTextFrameData : public QTextFrameLayoutData { @@ -109,7 +109,7 @@ public: QFixed minimumWidth; QFixed maximumWidth; - QLayoutStruct *currentLayoutStruct; + QTextLayoutStruct *currentLayoutStruct; bool sizeDirty; bool layoutDirty; @@ -123,8 +123,8 @@ QTextFrameData::QTextFrameData() { } -struct QLayoutStruct { - QLayoutStruct() : maximumWidth(QFIXED_MAX), fullLayout(false) +struct QTextLayoutStruct { + QTextLayoutStruct() : maximumWidth(QFIXED_MAX), fullLayout(false) {} QTextFrame *frame; QFixed x_left; @@ -477,9 +477,9 @@ public: HitPoint hitTest(QTextTable *table, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; HitPoint hitTest(QTextBlock bl, const QFixedPoint &point, int *position, QTextLayout **l, Qt::HitTestAccuracy accuracy) const; - QLayoutStruct layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, - int layoutFrom, int layoutTo, QTextTableData *tableData, QFixed absoluteTableY, - bool withPageBreaks); + QTextLayoutStruct layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, + int layoutFrom, int layoutTo, QTextTableData *tableData, QFixed absoluteTableY, + bool withPageBreaks); void setCellPosition(QTextTable *t, const QTextTableCell &cell, const QPointF &pos); QRectF layoutTable(QTextTable *t, int layoutFrom, int layoutTo, QFixed parentY); @@ -490,13 +490,13 @@ public: QRectF layoutFrame(QTextFrame *f, int layoutFrom, int layoutTo, QFixed frameWidth, QFixed frameHeight, QFixed parentY = 0); void layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, - QLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat); - void layoutFlow(QTextFrame::Iterator it, QLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, QFixed width = 0); - void pageBreakInsideTable(QTextTable *table, QLayoutStruct *layoutStruct); + QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat); + void layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, QFixed width = 0); + void pageBreakInsideTable(QTextTable *table, QTextLayoutStruct *layoutStruct); - void floatMargins(const QFixed &y, const QLayoutStruct *layoutStruct, QFixed *left, QFixed *right) const; - QFixed findY(QFixed yFrom, const QLayoutStruct *layoutStruct, QFixed requiredWidth) const; + void floatMargins(const QFixed &y, const QTextLayoutStruct *layoutStruct, QFixed *left, QFixed *right) const; + QFixed findY(QFixed yFrom, const QTextLayoutStruct *layoutStruct, QFixed requiredWidth) const; QVector<QCheckPoint> checkPoints; @@ -1369,9 +1369,7 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p QTextLine firstLine = layout->lineAt(0); Q_ASSERT(firstLine.isValid()); QPointF pos = (offset + layout->position()).toPoint(); - Qt::LayoutDirection dir = docPrivate->defaultTextOption.textDirection(); - if (blockFormat.hasProperty(QTextFormat::LayoutDirection)) - dir = blockFormat.layoutDirection(); + Qt::LayoutDirection dir = bl.textDirection(); { QRectF textRect = firstLine.naturalTextRect(); pos += textRect.topLeft().toPoint(); @@ -1487,12 +1485,12 @@ static QFixed firstChildPos(const QTextFrame *f) return flowPosition(f->begin()); } -QLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, - int layoutFrom, int layoutTo, QTextTableData *td, - QFixed absoluteTableY, bool withPageBreaks) +QTextLayoutStruct QTextDocumentLayoutPrivate::layoutCell(QTextTable *t, const QTextTableCell &cell, QFixed width, + int layoutFrom, int layoutTo, QTextTableData *td, + QFixed absoluteTableY, bool withPageBreaks) { LDEBUG << "layoutCell"; - QLayoutStruct layoutStruct; + QTextLayoutStruct layoutStruct; layoutStruct.frame = t; layoutStruct.minimumWidth = 0; layoutStruct.maximumWidth = QFIXED_MAX; @@ -1641,9 +1639,9 @@ recalc_minmax_widths: // to figure out the min and the max width lay out the cell at // maximum width. otherwise the maxwidth calculation sometimes // returns wrong values - QLayoutStruct layoutStruct = layoutCell(table, cell, QFIXED_MAX, layoutFrom, - layoutTo, td, absoluteTableY, - /*withPageBreaks =*/false); + QTextLayoutStruct layoutStruct = layoutCell(table, cell, QFIXED_MAX, layoutFrom, + layoutTo, td, absoluteTableY, + /*withPageBreaks =*/false); // distribute the minimum width over all columns the cell spans QFixed widthToDistribute = layoutStruct.minimumWidth + widthPadding; @@ -1868,10 +1866,10 @@ relayout: ++rowCellCount; const QFixed width = td->cellWidth(c, cspan) - widthPadding; - QLayoutStruct layoutStruct = layoutCell(table, cell, width, - layoutFrom, layoutTo, - td, absoluteTableY, - /*withPageBreaks =*/true); + QTextLayoutStruct layoutStruct = layoutCell(table, cell, width, + layoutFrom, layoutTo, + td, absoluteTableY, + /*withPageBreaks =*/true); const QFixed height = layoutStruct.y + bottomPadding + topPadding; @@ -1976,7 +1974,7 @@ void QTextDocumentLayoutPrivate::positionFloat(QTextFrame *frame, QTextLine *cur QTextFrameData *pd = data(parent); Q_ASSERT(pd && pd->currentLayoutStruct); - QLayoutStruct *layoutStruct = pd->currentLayoutStruct; + QTextLayoutStruct *layoutStruct = pd->currentLayoutStruct; if (!pd->floats.contains(frame)) pd->floats.append(frame); @@ -2116,7 +2114,7 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in // function. fd->contentsWidth = newContentsWidth; - QLayoutStruct layoutStruct; + QTextLayoutStruct layoutStruct; layoutStruct.frame = f; layoutStruct.x_left = fd->leftMargin + fd->border + fd->padding; layoutStruct.x_right = layoutStruct.x_left + newContentsWidth; @@ -2179,7 +2177,7 @@ QRectF QTextDocumentLayoutPrivate::layoutFrame(QTextFrame *f, int layoutFrom, in return layoutStruct.updateRect; } -void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QLayoutStruct *layoutStruct, +void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, QFixed width) { LDEBUG << "layoutFlow from=" << layoutFrom << "to=" << layoutTo; @@ -2509,7 +2507,7 @@ void QTextDocumentLayoutPrivate::layoutFlow(QTextFrame::Iterator it, QLayoutStru } void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosition, const QTextBlockFormat &blockFormat, - QLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat) + QTextLayoutStruct *layoutStruct, int layoutFrom, int layoutTo, const QTextBlockFormat *previousBlockFormat) { Q_Q(QTextDocumentLayout); @@ -2530,9 +2528,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi //QTextFrameData *fd = data(layoutStruct->frame); - Qt::LayoutDirection dir = docPrivate->defaultTextOption.textDirection(); - if (blockFormat.hasProperty(QTextFormat::LayoutDirection)) - dir = blockFormat.layoutDirection(); + Qt::LayoutDirection dir = bl.textDirection(); QFixed extraMargin; if (docPrivate->defaultTextOption.flags() & QTextOption::AddSpaceForLineAndParagraphSeparators) { @@ -2718,7 +2714,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi } } -void QTextDocumentLayoutPrivate::floatMargins(const QFixed &y, const QLayoutStruct *layoutStruct, +void QTextDocumentLayoutPrivate::floatMargins(const QFixed &y, const QTextLayoutStruct *layoutStruct, QFixed *left, QFixed *right) const { // qDebug() << "floatMargins y=" << y; @@ -2740,7 +2736,7 @@ void QTextDocumentLayoutPrivate::floatMargins(const QFixed &y, const QLayoutStru // qDebug() << "floatMargins: left="<<*left<<"right="<<*right<<"y="<<y; } -QFixed QTextDocumentLayoutPrivate::findY(QFixed yFrom, const QLayoutStruct *layoutStruct, QFixed requiredWidth) const +QFixed QTextDocumentLayoutPrivate::findY(QFixed yFrom, const QTextLayoutStruct *layoutStruct, QFixed requiredWidth) const { QFixed right, left; requiredWidth = qMin(requiredWidth, layoutStruct->x_right - layoutStruct->x_left); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index d34553f..ac1fffd 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -885,7 +885,7 @@ void QTextEngine::shapeText(int item) const QFixed letterSpacing = font.d->letterSpacing; QFixed wordSpacing = font.d->wordSpacing; - if (letterSpacingIsAbsolute) + if (letterSpacingIsAbsolute && letterSpacing.value()) letterSpacing *= font.d->dpi / qt_defaultDpiY(); if (letterSpacing != 0) { @@ -1404,7 +1404,10 @@ void QTextEngine::itemize() const #else bool ignore = ignoreBidi; #endif - if (!ignore && option.textDirection() == Qt::LeftToRight) { + + bool rtl = isRightToLeft(); + + if (!ignore && !rtl) { ignore = true; const QChar *start = layoutData->string.unicode(); const QChar * const end = start + length; @@ -1420,7 +1423,7 @@ void QTextEngine::itemize() const QVarLengthArray<QScriptAnalysis, 4096> scriptAnalysis(length); QScriptAnalysis *analysis = scriptAnalysis.data(); - QBidiControl control(option.textDirection() == Qt::RightToLeft); + QBidiControl control(rtl); if (ignore) { memset(analysis, 0, length*sizeof(QScriptAnalysis)); @@ -1515,6 +1518,23 @@ void QTextEngine::itemize() const resolveAdditionalFormats(); } +bool QTextEngine::isRightToLeft() const +{ + switch (option.textDirection()) { + case Qt::LeftToRight: + return false; + case Qt::RightToLeft: + return true; + default: + break; + } + // this places the cursor in the right position depending on the keyboard layout + if (layoutData->string.isEmpty()) + return QApplication::keyboardInputDirection() == Qt::RightToLeft; + return layoutData->string.isRightToLeft(); +} + + int QTextEngine::findItem(int strPos) const { itemize(); @@ -2511,7 +2531,7 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const QList<QTextOption::Tab> tabArray = option.tabs(); if (!tabArray.isEmpty()) { - if (option.textDirection() == Qt::RightToLeft) { // rebase the tabArray positions. + if (isRightToLeft()) { // rebase the tabArray positions. QList<QTextOption::Tab> newTabs; QList<QTextOption::Tab>::Iterator iter = tabArray.begin(); while(iter != tabArray.end()) { @@ -2648,6 +2668,12 @@ QTextItemInt::QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFo flags |= QTextItem::StrikeOut; } +QTextItemInt::QTextItemInt(const QGlyphLayout &g, QFont *font, QFontEngine *fe) + : flags(0), justified(false), underlineStyle(QTextCharFormat::NoUnderline), + num_chars(0), chars(0), logClusters(0), f(font), fontEngine(fe), glyphs(g) +{ +} + QTextItemInt QTextItemInt::midItem(QFontEngine *fontEngine, int firstGlyphIndex, int numGlyphs) const { QTextItemInt ti = *this; diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index d92148f..908a0ec 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -311,6 +311,7 @@ public: logClusters(0), f(0), fontEngine(0) {} QTextItemInt(const QScriptItem &si, QFont *font, const QTextCharFormat &format = QTextCharFormat()); + QTextItemInt(const QGlyphLayout &g, QFont *font, QFontEngine *fe); /// copy the structure items, adjusting the glyphs arrays to the right subarrays. /// the width of the returned QTextItemInt is not adjusted, for speed reasons @@ -457,6 +458,7 @@ public: void validate() const; void itemize() const; + bool isRightToLeft() const; static void bidiReorder(int numRuns, const quint8 *levels, int *visualOrder); const HB_CharAttributes *attributes() const; diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 140cf43..46db253 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -900,11 +900,14 @@ bool QTextFormat::boolProperty(int propertyId) const */ int QTextFormat::intProperty(int propertyId) const { + // required, since the default layout direction has to be LayoutDirectionAuto, which is not integer 0 + int def = (propertyId == QTextFormat::LayoutDirection) ? int(Qt::LayoutDirectionAuto) : 0; + if (!d) - return 0; + return def; const QVariant prop = d->property(propertyId); if (prop.userType() != QVariant::Int) - return 0; + return def; return prop.toInt(); } diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 3f67408..ddf9411 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -69,7 +69,7 @@ static inline QFixed leadingSpaceWidth(QTextEngine *eng, const QScriptLine &line if (!line.hasTrailingSpaces || (eng->option.flags() & QTextOption::IncludeTrailingSpaces) || !(eng->option.alignment() & Qt::AlignRight) - || (eng->option.textDirection() != Qt::RightToLeft)) + || !eng->isRightToLeft()) return QFixed(); int pos = line.length; @@ -86,12 +86,12 @@ static QFixed alignLine(QTextEngine *eng, const QScriptLine &line) // if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned. if (!line.justified && line.width != QFIXED_MAX) { int align = eng->option.alignment(); - if (align & Qt::AlignJustify && eng->option.textDirection() == Qt::RightToLeft) + if (align & Qt::AlignJustify && eng->isRightToLeft()) align = Qt::AlignRight; if (align & Qt::AlignRight) - x = line.width - (line.textWidth + leadingSpaceWidth(eng, line)); + x = line.width - (line.textAdvance + leadingSpaceWidth(eng, line)); else if (align & Qt::AlignHCenter) - x = (line.width - line.textWidth)/2; + x = (line.width - line.textAdvance)/2; } return x; } @@ -1337,7 +1337,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition int itm = d->findItem(cursorPosition - 1); QFixed base = sl.base(); QFixed descent = sl.descent; - bool rightToLeft = (d->option.textDirection() == Qt::RightToLeft); + bool rightToLeft = d->isRightToLeft(); if (itm >= 0) { const QScriptItem &si = d->layoutData->items.at(itm); if (si.ascent > 0) diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp index 2986ee7..a0ff520 100644 --- a/src/gui/text/qtextlist.cpp +++ b/src/gui/text/qtextlist.cpp @@ -262,7 +262,7 @@ QString QTextList::itemText(const QTextBlock &blockIt) const default: Q_ASSERT(false); } - if (blockFormat.layoutDirection() == Qt::RightToLeft) + if (blockIt.textDirection() == Qt::RightToLeft) return result.prepend(QLatin1Char('.')); return result + QLatin1Char('.'); } diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index 088eb98..f386871 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -1140,6 +1140,49 @@ int QTextBlock::charFormatIndex() const } /*! + \since 4.7 + + Returns the resolved text direction. + + If the block has no explicit direction set, it will resolve the + direction from the blocks content. Returns either Qt::LeftToRight + or Qt::RightToLeft. + + \sa QTextBlock::layoutDirection(), QString::isRightToLeft(), Qt::LayoutDirection +*/ +Qt::LayoutDirection QTextBlock::textDirection() const +{ + Qt::LayoutDirection dir = blockFormat().layoutDirection(); + if (dir != Qt::LayoutDirectionAuto) + return dir; + + const QString buffer = p->buffer(); + + const int pos = position(); + QTextDocumentPrivate::FragmentIterator it = p->find(pos); + QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char + for (; it != end; ++it) { + const QTextFragmentData * const frag = it.value(); + const QChar *p = buffer.constData() + frag->stringPosition; + const QChar * const end = p + frag->size_array[0]; + while (p < end) { + switch(QChar::direction(p->unicode())) + { + case QChar::DirL: + return Qt::LeftToRight; + case QChar::DirR: + case QChar::DirAL: + return Qt::RightToLeft; + default: + break; + } + ++p; + } + } + return Qt::LeftToRight; +} + +/*! Returns the block's contents as plain text. \sa length() charFormat() blockFormat() diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h index 67f67d8..a573a26 100644 --- a/src/gui/text/qtextobject.h +++ b/src/gui/text/qtextobject.h @@ -221,6 +221,8 @@ public: QTextCharFormat charFormat() const; int charFormatIndex() const; + Qt::LayoutDirection textDirection() const; + QString text() const; const QTextDocument *document() const; diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp index c1e254c..3b02ebe 100644 --- a/src/gui/text/qtextoption.cpp +++ b/src/gui/text/qtextoption.cpp @@ -65,7 +65,7 @@ QTextOption::QTextOption() tab(-1), d(0) { - direction = QApplication::layoutDirection(); + direction = Qt::LayoutDirectionAuto; } /*! diff --git a/src/gui/text/qtextoption.h b/src/gui/text/qtextoption.h index 1381ed1..fa8c6f2 100644 --- a/src/gui/text/qtextoption.h +++ b/src/gui/text/qtextoption.h @@ -134,8 +134,8 @@ private: uint align : 8; uint wordWrap : 4; uint design : 1; - uint direction : 1; - uint unused : 19; + uint direction : 2; + uint unused : 18; uint f; qreal tab; QTextOptionPrivate *d; diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index 9ec3142..d5a9c74 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -138,6 +138,7 @@ contains(QT_CONFIG, freetype) { ../3rdparty/freetype/src/base/ftinit.c \ ../3rdparty/freetype/src/base/ftmm.c \ ../3rdparty/freetype/src/base/fttype1.c \ + ../3rdparty/freetype/src/base/ftsynth.c \ ../3rdparty/freetype/src/base/ftbitmap.c\ ../3rdparty/freetype/src/bdf/bdf.c \ ../3rdparty/freetype/src/cache/ftcache.c \ diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 8cffebd..30ce23b 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -295,8 +295,10 @@ void QAbstractScrollAreaPrivate::init() q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); layoutChildren(); #ifndef Q_WS_MAC +#ifndef QT_NO_GESTURES viewport->grabGesture(Qt::PanGesture); #endif +#endif } #ifdef Q_WS_WIN @@ -546,8 +548,10 @@ void QAbstractScrollArea::setViewport(QWidget *widget) d->viewport->setFocusProxy(this); d->viewport->installEventFilter(d->viewportFilter.data()); #ifndef Q_WS_MAC +#ifndef QT_NO_GESTURES d->viewport->grabGesture(Qt::PanGesture); #endif +#endif d->layoutChildren(); if (isVisible()) d->viewport->show(); @@ -960,6 +964,7 @@ bool QAbstractScrollArea::event(QEvent *e) case QEvent::TouchUpdate: case QEvent::TouchEnd: return false; +#ifndef QT_NO_GESTURES case QEvent::Gesture: { QGestureEvent *ge = static_cast<QGestureEvent *>(e); @@ -980,6 +985,7 @@ bool QAbstractScrollArea::event(QEvent *e) } return false; } +#endif // QT_NO_GESTURES case QEvent::StyleChange: case QEvent::LayoutDirectionChange: case QEvent::ApplicationLayoutDirectionChange: @@ -1036,9 +1042,11 @@ bool QAbstractScrollArea::viewportEvent(QEvent *e) #endif return QFrame::event(e); case QEvent::LayoutRequest: +#ifndef QT_NO_GESTURES case QEvent::Gesture: case QEvent::GestureOverride: return event(e); +#endif default: break; } diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 5da1831..7068f62 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -78,7 +78,7 @@ class Q_GUI_EXPORT QLineControl : public QObject public: QLineControl(const QString &txt = QString()) - : m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LeftToRight), + : m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LayoutDirectionAuto), m_hideCursor(false), m_separator(0), m_readOnly(0), m_dragEnabled(0), m_echoMode(0), m_textDirty(0), m_selDirty(0), m_validInput(1), m_blinkStatus(0), m_blinkPeriod(0), m_blinkTimer(0), m_deleteAllTimer(0), @@ -272,7 +272,14 @@ public: QChar passwordCharacter() const { return m_passwordCharacter; } void setPasswordCharacter(const QChar &character) { m_passwordCharacter = character; updateDisplayText(); } - Qt::LayoutDirection layoutDirection() const { return m_layoutDirection; } + Qt::LayoutDirection layoutDirection() const { + if (m_layoutDirection == Qt::LayoutDirectionAuto) { + if (m_text.isEmpty()) + return QApplication::keyboardInputDirection(); + return m_text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight; + } + return m_layoutDirection; + } void setLayoutDirection(Qt::LayoutDirection direction) { if (direction != m_layoutDirection) { diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index c1c4abf..1bffde1 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1860,7 +1860,7 @@ void QLineEdit::paintEvent(QPaintEvent *) p.setClipRect(r); QFontMetrics fm = fontMetrics(); - Qt::Alignment va = QStyle::visualAlignment(layoutDirection(), QFlag(d->alignment)); + Qt::Alignment va = QStyle::visualAlignment(d->control->layoutDirection(), QFlag(d->alignment)); switch (va & Qt::AlignVertical_Mask) { case Qt::AlignBottom: d->vscroll = r.y() + r.height() - fm.height() - d->verticalMargin; @@ -2161,9 +2161,6 @@ void QLineEdit::changeEvent(QEvent *ev) } update(); break; - case QEvent::LayoutDirectionChange: - d->control->setLayoutDirection(layoutDirection()); - break; default: break; } diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index 2734fba..21c2635 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -1476,6 +1476,7 @@ bool QPlainTextEdit::event(QEvent *e) d->sendControlEvent(e); } #endif +#ifndef QT_NO_GESTURES else if (e->type() == QEvent::Gesture) { QGestureEvent *ge = static_cast<QGestureEvent *>(e); QPanGesture *g = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture)); @@ -1499,6 +1500,7 @@ bool QPlainTextEdit::event(QEvent *e) } return true; } +#endif // QT_NO_GESTURES return QAbstractScrollArea::event(e); } diff --git a/src/gui/widgets/qprogressbar.h b/src/gui/widgets/qprogressbar.h index b461a21..58bc8b2 100644 --- a/src/gui/widgets/qprogressbar.h +++ b/src/gui/widgets/qprogressbar.h @@ -93,9 +93,11 @@ public: Qt::Orientation orientation() const; void setInvertedAppearance(bool invert); - bool invertedAppearance(); + bool invertedAppearance(); //### Qt5 make const + bool invertedAppearance() const { return const_cast<QProgressBar *>(this)->invertedAppearance(); } void setTextDirection(QProgressBar::Direction textDirection); - QProgressBar::Direction textDirection(); + QProgressBar::Direction textDirection(); //### Qt5 make const + QProgressBar::Direction textDirection() const { return const_cast<QProgressBar *>(this)->textDirection(); } void setFormat(const QString &format); QString format() const; diff --git a/src/gui/widgets/qstackedwidget.cpp b/src/gui/widgets/qstackedwidget.cpp index 2509a21..de8d3e6 100644 --- a/src/gui/widgets/qstackedwidget.cpp +++ b/src/gui/widgets/qstackedwidget.cpp @@ -186,11 +186,11 @@ int QStackedWidget::insertWidget(int index, QWidget *widget) } /*! - Removes the given \a widget from the QStackedWidget. + Removes \a widget from the QStackedWidget. i.e., \a widget is \e + not deleted but simply removed from the stacked layout, causing it + to be hidden. - \bold{Note:} The ownership of \a widget remains the same. - The widget is \e not deleted, but simply removed from the widget's - stacked layout, causing it to be hidden. + \bold{Note:} Ownership of \a widget reverts to the application. \sa addWidget(), insertWidget(), currentWidget() */ diff --git a/src/imports/gestures/plugin.cpp b/src/imports/gestures/plugin.cpp index 11f2392..1fc23ca 100644 --- a/src/imports/gestures/plugin.cpp +++ b/src/imports/gestures/plugin.cpp @@ -53,7 +53,9 @@ public: virtual void registerTypes(const char *uri) { Q_ASSERT(QLatin1String(uri) == QLatin1String("Qt.labs.gestures")); +#ifndef QT_NO_GESTURES qmlRegisterCustomType<QDeclarativeGestureArea>(uri,1,0, "GestureArea", new QDeclarativeGestureAreaParser); +#endif } }; @@ -62,4 +64,3 @@ QT_END_NAMESPACE #include "plugin.moc" Q_EXPORT_PLUGIN2(qmlgesturesplugin, QT_PREPEND_NAMESPACE(GestureAreaQmlPlugin)); - diff --git a/src/imports/gestures/qdeclarativegesturearea.cpp b/src/imports/gestures/qdeclarativegesturearea.cpp index 1b0aeeb..22be2f1 100644 --- a/src/imports/gestures/qdeclarativegesturearea.cpp +++ b/src/imports/gestures/qdeclarativegesturearea.cpp @@ -55,6 +55,8 @@ #include <private/qobject_p.h> +#ifndef QT_NO_GESTURES + QT_BEGIN_NAMESPACE class QDeclarativeGestureAreaPrivate : public QDeclarativeItemPrivate @@ -267,3 +269,5 @@ bool QDeclarativeGestureAreaPrivate::gestureEvent(QGestureEvent *event) } QT_END_NAMESPACE + +#endif // QT_NO_GESTURES diff --git a/src/imports/gestures/qdeclarativegesturearea_p.h b/src/imports/gestures/qdeclarativegesturearea_p.h index 0195511..ff89166 100644 --- a/src/imports/gestures/qdeclarativegesturearea_p.h +++ b/src/imports/gestures/qdeclarativegesturearea_p.h @@ -50,6 +50,8 @@ #include <QtCore/qstring.h> #include <QtGui/qgesture.h> +#ifndef QT_NO_GESTURES + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -97,4 +99,6 @@ QML_DECLARE_TYPE(QDeclarativeGestureArea) QT_END_HEADER +#endif // QT_NO_GESTURES + #endif diff --git a/src/imports/particles/qdeclarativeparticles.cpp b/src/imports/particles/qdeclarativeparticles.cpp index ecc6604..630c068 100644 --- a/src/imports/particles/qdeclarativeparticles.cpp +++ b/src/imports/particles/qdeclarativeparticles.cpp @@ -241,11 +241,13 @@ void QDeclarativeParticleMotionGravity::setAcceleration(qreal accel) void QDeclarativeParticleMotionGravity::advance(QDeclarativeParticle &p, int interval) { - qreal xdiff = p.x - _xAttr; - qreal ydiff = p.y - _yAttr; + qreal xdiff = _xAttr - p.x; + qreal ydiff = _yAttr - p.y; + qreal absXdiff = qAbs(xdiff); + qreal absYdiff = qAbs(ydiff); - qreal xcomp = xdiff / (xdiff + ydiff); - qreal ycomp = ydiff / (xdiff + ydiff); + qreal xcomp = xdiff / (absXdiff + absYdiff); + qreal ycomp = ydiff / (absXdiff + absYdiff); p.x_velocity += xcomp * _accel * interval; p.y_velocity += ycomp * _accel * interval; @@ -1284,11 +1286,7 @@ void QDeclarativeParticlesPainter::paint(QPainter *p, const QStyleOptionGraphics const int myX = x() + parentItem()->x(); const int myY = y() + parentItem()->y(); -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) QVarLengthArray<QPainter::PixmapFragment, 256> pixmapData; -#else - QVarLengthArray<QDrawPixmaps::Data, 256> pixmapData; -#endif pixmapData.resize(d->particles.count()); const QRectF sourceRect = d->image.rect(); @@ -1296,32 +1294,20 @@ void QDeclarativeParticlesPainter::paint(QPainter *p, const QStyleOptionGraphics qreal halfPHeight = sourceRect.height()/2.; for (int i = 0; i < d->particles.count(); ++i) { const QDeclarativeParticle &particle = d->particles.at(i); -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) pixmapData[i].x = particle.x - myX + halfPWidth; pixmapData[i].y = particle.y - myY + halfPHeight; -#else - pixmapData[i].point = QPointF(particle.x - myX + halfPWidth, particle.y - myY + halfPHeight); -#endif pixmapData[i].opacity = particle.opacity; //these never change pixmapData[i].rotation = 0; pixmapData[i].scaleX = 1; pixmapData[i].scaleY = 1; -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) pixmapData[i].sourceLeft = sourceRect.left(); pixmapData[i].sourceTop = sourceRect.top(); pixmapData[i].width = sourceRect.width(); pixmapData[i].height = sourceRect.height(); -#else - pixmapData[i].source = sourceRect; -#endif } -#if (QT_VERSION >= QT_VERSION_CHECK(4,7,0)) p->drawPixmapFragments(pixmapData.data(), d->particles.count(), d->image); -#else - qDrawPixmaps(p, pixmapData.data(), d->particles.count(), d->image); -#endif } void QDeclarativeParticles::componentComplete() diff --git a/src/imports/qimportbase.pri b/src/imports/qimportbase.pri index 91f6552..0f70030 100644 --- a/src/imports/qimportbase.pri +++ b/src/imports/qimportbase.pri @@ -1,3 +1,4 @@ +symbian:include(../plugins/qpluginbase.pri) TEMPLATE = lib CONFIG += qt plugin @@ -17,6 +18,8 @@ copy2build.output = $$QT_BUILD_TREE/imports/$$TARGETPATH/qmldir copy2build.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} copy2build.name = COPY ${QMAKE_FILE_IN} copy2build.CONFIG += no_link +# `clean' should leave the build in a runnable state, which means it shouldn't delete qmldir +copy2build.CONFIG += no_clean QMAKE_EXTRA_COMPILERS += copy2build TARGET = $$qtLibraryTarget($$TARGET) diff --git a/src/imports/webkit/qdeclarativewebview.cpp b/src/imports/webkit/qdeclarativewebview.cpp index 050e2b7..383f1ce 100644 --- a/src/imports/webkit/qdeclarativewebview.cpp +++ b/src/imports/webkit/qdeclarativewebview.cpp @@ -711,7 +711,7 @@ bool QDeclarativeWebView::sceneEvent(QEvent *event) return QDeclarativeItem::sceneEvent(event); } - +#ifndef QT_NO_ACTION /*! \qmlproperty action WebView::back This property holds the action for causing the previous URL in the history to be displayed. @@ -747,6 +747,7 @@ QAction *QDeclarativeWebView::stopAction() const { return page()->action(QWebPage::Stop); } +#endif // QT_NO_ACTION /*! \qmlproperty real WebView::title @@ -1162,9 +1163,9 @@ QString QDeclarativeWebPage::chooseFile(QWebFrame *originatingFrame, const QStri } /*! - \qmlsignal WebView::alert(message) + \qmlsignal WebView::onAlert(message) - This signal is emitted when the web engine sends a JavaScript alert. The \a message is the text + This handler is called when the web engine sends a JavaScript alert. The \a message is the text to be displayed in the alert to the user. */ diff --git a/src/imports/webkit/qdeclarativewebview_p.h b/src/imports/webkit/qdeclarativewebview_p.h index 87bd938..042237e 100644 --- a/src/imports/webkit/qdeclarativewebview_p.h +++ b/src/imports/webkit/qdeclarativewebview_p.h @@ -108,10 +108,12 @@ class QDeclarativeWebView : public QDeclarativeItem Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged) Q_PROPERTY(Status status READ status NOTIFY statusChanged) +#ifndef QT_NO_ACTION Q_PROPERTY(QAction* reload READ reloadAction CONSTANT) Q_PROPERTY(QAction* back READ backAction CONSTANT) Q_PROPERTY(QAction* forward READ forwardAction CONSTANT) Q_PROPERTY(QAction* stop READ stopAction CONSTANT) +#endif Q_PROPERTY(QDeclarativeWebSettings* settings READ settingsObject CONSTANT) @@ -154,10 +156,12 @@ public: qreal progress() const; QString statusText() const; +#ifndef QT_NO_ACTION QAction *reloadAction() const; QAction *backAction() const; QAction *forwardAction() const; QAction *stopAction() const; +#endif QWebPage *page() const; void setPage(QWebPage *page); diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 42c64fb..837cf66 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -464,6 +464,15 @@ QNetworkAccessManager::~QNetworkAccessManager() #ifndef QT_NO_NETWORKPROXY delete d_func()->proxyFactory; #endif + + // Delete the QNetworkReply children first. + // Else a QAbstractNetworkCache might get deleted in ~QObject + // before a QNetworkReply that accesses the QAbstractNetworkCache + // object in its destructor. + qDeleteAll(findChildren<QNetworkReply *>()); + // The other children will be deleted in this ~QObject + // FIXME instead of this "hack" make the QNetworkReplyImpl + // properly watch the cache deletion, e.g. via a QWeakPointer. } #ifndef QT_NO_NETWORKPROXY diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 865d338..d1bdd57 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -991,6 +991,8 @@ QList<QNetworkCookie> QNetworkCookiePrivate::parseSetCookieHeaderLine(const QByt } QString normalizedDomain = QUrl::fromAce(QUrl::toAce(QString::fromUtf8(rawDomain))); + if (normalizedDomain.isEmpty() && !rawDomain.isEmpty()) + return result; cookie.setDomain(maybeLeadingDot + normalizedDomain); } else if (field.first == "max-age") { bool ok = false; diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index 471927a..5d4274f 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -483,8 +483,10 @@ void QNetworkConfigurationManagerPrivate::pollEngines() QMutexLocker locker(&mutex); for (int i = 0; i < sessionEngines.count(); ++i) { - if ((forcedPolling && sessionEngines.at(i)->requiresPolling()) || - sessionEngines.at(i)->configurationsInUse()) { + if (!sessionEngines.at(i)->requiresPolling()) + continue; + + if (forcedPolling || sessionEngines.at(i)->configurationsInUse()) { pollingEngines.insert(i); QMetaObject::invokeMethod(sessionEngines.at(i), "requestUpdate"); } diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp index ada9381..bc5a025 100644 --- a/src/network/kernel/qnetworkproxy.cpp +++ b/src/network/kernel/qnetworkproxy.cpp @@ -1138,6 +1138,20 @@ void QNetworkProxyQuery::setUrl(const QUrl &url) multiple connections, such as QNetworkAccessManager. When set on such object, the factory will be queried for sockets created by that framework only. + + \section1 System Proxies + + You can configure a factory to use the system proxy's settings. + Call the setUseSystemConfiguration() function with true to enable + this behavior, or false to disable it. + + Similarly, you can use a factory to make queries directly to the + system proxy by calling its systemProxyForQuery() function. + + \warning Depending on the configuration of the user's system, the + use of system proxy features on certain platforms may be subject + to limitations. The systemProxyForQuery() documentation contains a + list of these limitations for those platforms that are affected. */ /*! @@ -1159,17 +1173,20 @@ QNetworkProxyFactory::~QNetworkProxyFactory() /*! + \since 4.6 + Enables the use of the platform-specific proxy settings, and only those. See systemProxyForQuery() for more information. Internally, this method (when called with \a enable set to true) sets an application-wide proxy factory. For this reason, this method - is mutually exclusive with setApplicationProxyFactory: calling - setApplicationProxyFactory overrides the use of the system-wide proxy, - and calling setUseSystemConfiguration overrides any + is mutually exclusive with setApplicationProxyFactory(): calling + setApplicationProxyFactory() overrides the use of the system-wide proxy, + and calling setUseSystemConfiguration() overrides any application proxy or proxy factory that was previously set. - \since 4.6 + \note See the systemProxyForQuery() documentation for a list of + limitations related to the use of system proxies. */ void QNetworkProxyFactory::setUseSystemConfiguration(bool enable) { @@ -1264,8 +1281,13 @@ void QNetworkProxyFactory::setApplicationProxyFactory(QNetworkProxyFactory *fact function. Future versions of Qt may lift some of the limitations listed here. - On MacOS X, this function will ignore the Proxy Auto Configuration + \list + \o On MacOS X, this function will ignore the Proxy Auto Configuration settings, since it cannot execute the associated ECMAScript code. + + \o On Windows platforms, this function may take several seconds to + execute depending on the configuration of the user's system. + \endlist */ /*! diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index fd647e2..31c5ed1 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -259,13 +259,28 @@ QByteArray QSslCertificate::version() const /*! Returns the certificate's serial number string in decimal format. + In case the serial number cannot be converted to decimal format + (i.e. if it is bigger than 4294967295, which means it does not fit into 4 bytes), + its hexadecimal version is returned. */ QByteArray QSslCertificate::serialNumber() const { - if (d->serialNumberString.isEmpty() && d->x509) - d->serialNumberString = - QByteArray::number(qlonglong(q_ASN1_INTEGER_get(d->x509->cert_info->serialNumber))); - + if (d->serialNumberString.isEmpty() && d->x509) { + ASN1_INTEGER *serialNumber = d->x509->cert_info->serialNumber; + // if we cannot convert to a long, just output the hexadecimal number + if (serialNumber->length > 4) { + QByteArray hexString; + hexString.reserve(serialNumber->length * 3); + for (int a = 0; a < serialNumber->length; ++a) { + hexString += QByteArray::number(serialNumber->data[a], 16).rightJustified(2, '0'); + hexString += ':'; + } + hexString.chop(1); + d->serialNumberString = hexString; + } else { + d->serialNumberString = QByteArray::number(qlonglong(q_ASN1_INTEGER_get(serialNumber))); + } + } return d->serialNumberString; } diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 5758b25..ee49a3d 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -1333,8 +1333,16 @@ void QGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem) QFontEngineGlyphCache::Type glyphType = textItem->fontEngine->glyphFormat >= 0 ? QFontEngineGlyphCache::Type(textItem->fontEngine->glyphFormat) : d->glyphCacheType; + if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) { + if (d->device->alphaRequested() || state()->matrix.type() > QTransform::TxTranslate + || (state()->composition_mode != QPainter::CompositionMode_Source + && state()->composition_mode != QPainter::CompositionMode_SourceOver)) + { + glyphType = QFontEngineGlyphCache::Raster_A8; + } + } - d->drawCachedGlyphs(glyphType, textItem, true); + d->drawCachedGlyphs(glyphType, textItem); } bool QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src) @@ -1408,7 +1416,7 @@ void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem staticTextItem.numGlyphs = glyphs.size(); staticTextItem.glyphPositions = positions.data(); - d->drawCachedGlyphs(glyphType, &staticTextItem, false); + d->drawCachedGlyphs(glyphType, &staticTextItem); } return; } @@ -1439,21 +1447,16 @@ namespace { // #define QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType, - QStaticTextItem *staticTextItem, - bool includeMatrixInCache) + QStaticTextItem *staticTextItem) { Q_Q(QGL2PaintEngineEx); QOpenGL2PaintEngineState *s = q->state(); QGLTextureGlyphCache *cache = - (QGLTextureGlyphCache *) staticTextItem->fontEngine->glyphCache(ctx, glyphType, - includeMatrixInCache - ? s->matrix - : QTransform()); + (QGLTextureGlyphCache *) staticTextItem->fontEngine->glyphCache(ctx, glyphType, QTransform()); if (!cache || cache->cacheType() != glyphType) { - cache = new QGLTextureGlyphCache(ctx, glyphType, - includeMatrixInCache ? s->matrix : QTransform()); + cache = new QGLTextureGlyphCache(ctx, glyphType, QTransform()); staticTextItem->fontEngine->setGlyphCache(ctx, cache); } @@ -1561,13 +1564,6 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp QBrush pensBrush = q->state()->pen.brush(); setBrush(pensBrush); - // When painting a QStaticTextItem, the glyph positions are already in device coordinates, - // therefore we temporarily set an identity matrix on the painter for the draw call to - // avoid transforming the positions twice. - QTransform old = s->matrix; - if (includeMatrixInCache) - s->matrix = QTransform(); - if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) { // Subpixel antialiasing without gamma correction @@ -1664,9 +1660,6 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp #else glDrawElements(GL_TRIANGLE_STRIP, 6 * staticTextItem->numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); #endif - - if (includeMatrixInCache) - s->matrix = old; } void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h index 0a046dc..59b90d8 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h @@ -202,8 +202,7 @@ public: void drawTexture(const QGLRect& dest, const QGLRect& src, const QSize &textureSize, bool opaque, bool pattern = false); void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, QPainter::PixmapFragmentHints hints); - void drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType, QStaticTextItem *staticTextItem, - bool includeMatrixInCache); + void drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType, QStaticTextItem *staticTextItem); // Calls glVertexAttributePointer if the pointer has changed inline void setVertexAttributePointer(unsigned int arrayIndex, const GLfloat *pointer); diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp index 410cf21..5371c5e 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl.cpp @@ -276,6 +276,11 @@ void QGLTextureGlyphCache::fillTexture(const Coord &c, glyph_t glyph) } } +int QGLTextureGlyphCache::glyphMargin() const +{ + return 1; +} + int QGLTextureGlyphCache::glyphPadding() const { return 1; diff --git a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h index 6bcd655..84e9021 100644 --- a/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h +++ b/src/opengl/gl2paintengineex/qtextureglyphcache_gl_p.h @@ -72,6 +72,7 @@ public: virtual void createTextureData(int width, int height); virtual void resizeTextureData(int width, int height); virtual void fillTexture(const Coord &c, glyph_t glyph); + virtual int glyphMargin() const; virtual int glyphPadding() const; inline GLuint texture() const { return m_texture; } diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index c8502c2..b4c85ac 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1256,6 +1256,8 @@ QGLFormat::OpenGLVersionFlags Q_AUTOTEST_EXPORT qOpenGLVersionFlagsFromString(co QGLFormat::OpenGL_Version_2_1 | QGLFormat::OpenGL_Version_3_0; switch (versionString[2].toAscii()) { + case '3': + versionFlags |= QGLFormat::OpenGL_Version_3_3; case '2': versionFlags |= QGLFormat::OpenGL_Version_3_2; case '1': @@ -1264,9 +1266,23 @@ QGLFormat::OpenGLVersionFlags Q_AUTOTEST_EXPORT qOpenGLVersionFlagsFromString(co break; default: versionFlags |= QGLFormat::OpenGL_Version_3_1 | - QGLFormat::OpenGL_Version_3_2; + QGLFormat::OpenGL_Version_3_2 | + QGLFormat::OpenGL_Version_3_3; break; } + } else if (versionString.startsWith(QLatin1String("4."))) { + versionFlags |= QGLFormat::OpenGL_Version_1_1 | + QGLFormat::OpenGL_Version_1_2 | + QGLFormat::OpenGL_Version_1_3 | + QGLFormat::OpenGL_Version_1_4 | + QGLFormat::OpenGL_Version_1_5 | + QGLFormat::OpenGL_Version_2_0 | + QGLFormat::OpenGL_Version_2_1 | + QGLFormat::OpenGL_Version_3_0 | + QGLFormat::OpenGL_Version_3_1 | + QGLFormat::OpenGL_Version_3_2 | + QGLFormat::OpenGL_Version_3_3 | + QGLFormat::OpenGL_Version_4_0; } else { versionFlags |= QGLFormat::OpenGL_Version_1_1 | QGLFormat::OpenGL_Version_1_2 | @@ -1277,7 +1293,9 @@ QGLFormat::OpenGLVersionFlags Q_AUTOTEST_EXPORT qOpenGLVersionFlagsFromString(co QGLFormat::OpenGL_Version_2_1 | QGLFormat::OpenGL_Version_3_0 | QGLFormat::OpenGL_Version_3_1 | - QGLFormat::OpenGL_Version_3_2; + QGLFormat::OpenGL_Version_3_2 | + QGLFormat::OpenGL_Version_3_3 | + QGLFormat::OpenGL_Version_4_0; } } return versionFlags; @@ -3656,8 +3674,10 @@ QGLWidget::~QGLWidget() bool doRelease = (glcx && glcx->windowCreated()); #endif delete d->glcx; + d->glcx = 0; #if defined(Q_WGL) delete d->olcx; + d->olcx = 0; #endif #if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT) if (doRelease) diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index f297009..f0b36f7 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -266,7 +266,9 @@ public: OpenGL_ES_Version_2_0 = 0x00000800, OpenGL_Version_3_0 = 0x00001000, OpenGL_Version_3_1 = 0x00002000, - OpenGL_Version_3_2 = 0x00004000 + OpenGL_Version_3_2 = 0x00004000, + OpenGL_Version_3_3 = 0x00008000, + OpenGL_Version_4_0 = 0x00010000 }; Q_DECLARE_FLAGS(OpenGLVersionFlags, OpenGLVersionFlag) diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 44e8ae9..0a19531 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -190,7 +190,7 @@ void QGLContext::makeCurrent() if (!d->workaroundsCached) { d->workaroundsCached = true; const char *renderer = reinterpret_cast<const char *>(glGetString(GL_RENDERER)); - if (strstr(renderer, "SGX") || strstr(renderer, "MBX")) { + if (renderer && (strstr(renderer, "SGX") || strstr(renderer, "MBX"))) { // PowerVR MBX/SGX chips needs to clear all buffers when starting to render // a new frame, otherwise there will be a performance penalty to pay for // each frame. @@ -200,7 +200,8 @@ void QGLContext::makeCurrent() // bug which prevents glCopyTexSubImage2D() to work with a POT // or GL_ALPHA texture bound to an FBO. The only way to // identify that driver is to check the EGL version number for it. - if (strstr(eglQueryString(d->eglContext->display(), EGL_VERSION), "1.3")) + const char *egl_version = eglQueryString(d->eglContext->display(), EGL_VERSION); + if (egl_version && strstr(egl_version, "1.3")) d->workaround_brokenFBOReadBack = true; } } diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 16c225f..1727a41 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -177,6 +177,10 @@ public: void initContext(QGLContext *context, const QGLWidget* shareWidget); bool renderCxPm(QPixmap *pixmap); void cleanupColormaps(); + void aboutToDestroy() { + if (glcx) + glcx->reset(); + } QGLContext *glcx; QGLWidgetGLPaintDevice glDevice; diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index d203646..bfb232d 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -115,6 +115,20 @@ extern const QX11Info *qt_x11Info(const QPaintDevice *pd); #define GLX_FRONT_LEFT_EXT 0x20DE #endif +#ifndef GLX_ARB_create_context +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#endif + +#ifndef GLX_ARB_create_context_profile +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 +#endif + /* The qt_gl_choose_cmap function is internal and used by QGLWidget::setContext() and GLX (not Windows). If the application can't find any sharable @@ -401,6 +415,148 @@ bool QGLFormat::hasOpenGLOverlays() return trans_colors.size() > 0; } +static bool buildSpec(int* spec, const QGLFormat& f, QPaintDevice* paintDevice, + int bufDepth, bool onlyFBConfig = false) +{ + int i = 0; + spec[i++] = GLX_LEVEL; + spec[i++] = f.plane(); + const QX11Info *xinfo = qt_x11Info(paintDevice); + bool useFBConfig = onlyFBConfig; + +#if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) && !defined(Q_OS_HPUX) + /* + HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions. + Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented. + */ + QWidget* widget = 0; + if (paintDevice->devType() == QInternal::Widget) + widget = static_cast<QWidget*>(paintDevice); + + // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual + if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender) + useFBConfig = true; +#endif + +#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) + static bool useTranspExt = false; + static bool useTranspExtChecked = false; + if (f.plane() && !useTranspExtChecked && paintDevice) { + QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); + useTranspExt = extensions.match("GLX_EXT_visual_info"); + //# (A bit simplistic; that could theoretically be a substring) + if (useTranspExt) { + QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR)); + useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround + if (useTranspExt) { + // bug workaround - some systems (eg. FireGL) refuses to return an overlay + // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if + // the implementation supports transparent overlays + int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT, + f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT, + XNone }; + XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec); + if (!vinf) { + useTranspExt = false; + } + } + } + + useTranspExtChecked = true; + } + if (f.plane() && useTranspExt && !useFBConfig) { + // Required to avoid non-transparent overlay visual(!) on some systems + spec[i++] = GLX_TRANSPARENT_TYPE_EXT; + spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; + } +#endif + +#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) + // GLX_RENDER_TYPE is only in glx >=1.3 + if (useFBConfig) { + spec[i++] = GLX_RENDER_TYPE; + spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + } +#endif + + if (f.doubleBuffer()) + spec[i++] = GLX_DOUBLEBUFFER; + if (useFBConfig) + spec[i++] = True; + if (f.depth()) { + spec[i++] = GLX_DEPTH_SIZE; + spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize(); + } + if (f.stereo()) { + spec[i++] = GLX_STEREO; + if (useFBConfig) + spec[i++] = True; + } + if (f.stencil()) { + spec[i++] = GLX_STENCIL_SIZE; + spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize(); + } + if (f.rgba()) { + if (!useFBConfig) + spec[i++] = GLX_RGBA; + spec[i++] = GLX_RED_SIZE; + spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize(); + spec[i++] = GLX_GREEN_SIZE; + spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize(); + spec[i++] = GLX_BLUE_SIZE; + spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize(); + if (f.alpha()) { + spec[i++] = GLX_ALPHA_SIZE; + spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize(); + } + if (f.accum()) { + spec[i++] = GLX_ACCUM_RED_SIZE; + spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); + spec[i++] = GLX_ACCUM_GREEN_SIZE; + spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); + spec[i++] = GLX_ACCUM_BLUE_SIZE; + spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); + if (f.alpha()) { + spec[i++] = GLX_ACCUM_ALPHA_SIZE; + spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); + } + } + } else { + spec[i++] = GLX_BUFFER_SIZE; + spec[i++] = bufDepth; + } + + if (f.sampleBuffers()) { + spec[i++] = GLX_SAMPLE_BUFFERS_ARB; + spec[i++] = 1; + spec[i++] = GLX_SAMPLES_ARB; + spec[i++] = f.samples() == -1 ? 4 : f.samples(); + } + +#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) + if (useFBConfig) { + spec[i++] = GLX_DRAWABLE_TYPE; + switch(paintDevice->devType()) { + case QInternal::Pixmap: + spec[i++] = GLX_PIXMAP_BIT; + break; + case QInternal::Pbuffer: + spec[i++] = GLX_PBUFFER_BIT; + break; + default: + qWarning("QGLContext: Unknown paint device type %d", paintDevice->devType()); + // Fall-through & assume it's a window + case QInternal::Widget: + spec[i++] = GLX_WINDOW_BIT; + break; + }; + } +#endif + + spec[i] = XNone; + return useFBConfig; +} + /***************************************************************************** QGLContext UNIX/GLX-specific code *****************************************************************************/ @@ -493,21 +649,85 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) shareContext = 0; } + const int major = d->reqFormat.majorVersion(); + const int minor = d->reqFormat.minorVersion(); + const int profile = d->reqFormat.profile() == QGLFormat::CompatibilityProfile + ? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB + : GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + d->cx = 0; - if (shareContext) { + +#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) + /* + HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions. + Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented. + */ + if ((major == 3 && minor >= 2) || major > 3) { + QGLTemporaryContext *tmpContext = 0; + if (!QGLContext::currentContext()) + tmpContext = new QGLTemporaryContext; + + int attributes[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, major, + GLX_CONTEXT_MINOR_VERSION_ARB, minor, + GLX_CONTEXT_PROFILE_MASK_ARB, profile, + 0 }; + + typedef GLXContext ( * Q_PFNGLXCREATECONTEXTATTRIBSARBPROC) + (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); + + + Q_PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = + (Q_PFNGLXCREATECONTEXTATTRIBSARBPROC) qglx_getProcAddress("glXCreateContextAttribsARB"); + + if (glXCreateContextAttribs) { + int spec[45]; + glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BUFFER_SIZE, &res); + buildSpec(spec, format(), d->paintDevice, res, true); + + GLXFBConfig *configs; + int configCount = 0; + configs = glXChooseFBConfig(disp, xinfo->screen(), spec, &configCount); + + if (configs && configCount > 0) { + d->cx = glXCreateContextAttribs(disp, configs[0], + shareContext ? (GLXContext)shareContext->d_func()->cx : 0, direct, attributes); + if (!d->cx && shareContext) { + shareContext = 0; + d->cx = glXCreateContextAttribs(disp, configs[0], 0, direct, attributes); + } + d->screen = ((XVisualInfo*)d->vi)->screen; + } + XFree(configs); + } else { + qWarning("QGLContext::chooseContext(): OpenGL %d.%d is not supported", major, minor); + } + + if (tmpContext) + delete tmpContext; + } +#else + Q_UNUSED(major); + Q_UNUSED(minor); + Q_UNUSED(profile); +#endif + + if (!d->cx && shareContext) { d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, (GLXContext)shareContext->d_func()->cx, direct); d->screen = ((XVisualInfo*)d->vi)->screen; - if (d->cx) { - QGLContext *share = const_cast<QGLContext *>(shareContext); - d->sharing = true; - share->d_func()->sharing = true; - } } if (!d->cx) { d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, NULL, direct); d->screen = ((XVisualInfo*)d->vi)->screen; + shareContext = 0; + } + + if (shareContext && d->cx) { + QGLContext *share = const_cast<QGLContext *>(shareContext); + d->sharing = true; + share->d_func()->sharing = true; } + if (!d->cx) return false; d->glFormat.setDirectRendering(glXIsDirect(disp, (GLXContext)d->cx)); @@ -606,143 +826,8 @@ void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) { Q_D(QGLContext); int spec[45]; - int i = 0; - spec[i++] = GLX_LEVEL; - spec[i++] = f.plane(); const QX11Info *xinfo = qt_x11Info(d->paintDevice); - bool useFBConfig = false; - -#if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) && !defined(Q_OS_HPUX) - /* - HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions. - Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented. - */ - QWidget* widget = 0; - if (d->paintDevice->devType() == QInternal::Widget) - widget = static_cast<QWidget*>(d->paintDevice); - - // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual - if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender) - useFBConfig = true; -#endif - -#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) - static bool useTranspExt = false; - static bool useTranspExtChecked = false; - if (f.plane() && !useTranspExtChecked && d->paintDevice) { - QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); - useTranspExt = extensions.match("GLX_EXT_visual_info"); - //# (A bit simplistic; that could theoretically be a substring) - if (useTranspExt) { - QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR)); - useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround - if (useTranspExt) { - // bug workaround - some systems (eg. FireGL) refuses to return an overlay - // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if - // the implementation supports transparent overlays - int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT, - f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT, - XNone }; - XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec); - if (!vinf) { - useTranspExt = false; - } - } - } - - useTranspExtChecked = true; - } - if (f.plane() && useTranspExt && !useFBConfig) { - // Required to avoid non-transparent overlay visual(!) on some systems - spec[i++] = GLX_TRANSPARENT_TYPE_EXT; - spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; - } -#endif - -#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) - // GLX_RENDER_TYPE is only in glx >=1.3 - if (useFBConfig) { - spec[i++] = GLX_RENDER_TYPE; - spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; - } -#endif - - if (f.doubleBuffer()) - spec[i++] = GLX_DOUBLEBUFFER; - if (useFBConfig) - spec[i++] = True; - if (f.depth()) { - spec[i++] = GLX_DEPTH_SIZE; - spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize(); - } - if (f.stereo()) { - spec[i++] = GLX_STEREO; - if (useFBConfig) - spec[i++] = True; - } - if (f.stencil()) { - spec[i++] = GLX_STENCIL_SIZE; - spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize(); - } - if (f.rgba()) { - if (!useFBConfig) - spec[i++] = GLX_RGBA; - spec[i++] = GLX_RED_SIZE; - spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize(); - spec[i++] = GLX_GREEN_SIZE; - spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize(); - spec[i++] = GLX_BLUE_SIZE; - spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize(); - if (f.alpha()) { - spec[i++] = GLX_ALPHA_SIZE; - spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize(); - } - if (f.accum()) { - spec[i++] = GLX_ACCUM_RED_SIZE; - spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); - spec[i++] = GLX_ACCUM_GREEN_SIZE; - spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); - spec[i++] = GLX_ACCUM_BLUE_SIZE; - spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); - if (f.alpha()) { - spec[i++] = GLX_ACCUM_ALPHA_SIZE; - spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); - } - } - } else { - spec[i++] = GLX_BUFFER_SIZE; - spec[i++] = bufDepth; - } - - if (f.sampleBuffers()) { - spec[i++] = GLX_SAMPLE_BUFFERS_ARB; - spec[i++] = 1; - spec[i++] = GLX_SAMPLES_ARB; - spec[i++] = f.samples() == -1 ? 4 : f.samples(); - } - -#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) - if (useFBConfig) { - spec[i++] = GLX_DRAWABLE_TYPE; - switch(d->paintDevice->devType()) { - case QInternal::Pixmap: - spec[i++] = GLX_PIXMAP_BIT; - break; - case QInternal::Pbuffer: - spec[i++] = GLX_PBUFFER_BIT; - break; - default: - qWarning("QGLContext: Unknown paint device type %d", d->paintDevice->devType()); - // Fall-through & assume it's a window - case QInternal::Widget: - spec[i++] = GLX_WINDOW_BIT; - break; - }; - } -#endif - - spec[i] = XNone; - + bool useFBConfig = buildSpec(spec, f, d->paintDevice, bufDepth, false); XVisualInfo* chosenVisualInfo = 0; @@ -755,7 +840,7 @@ void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) if (!configs) break; // fallback to trying glXChooseVisual - for (i = 0; i < configCount; ++i) { + for (int i = 0; i < configCount; ++i) { XVisualInfo* vi; vi = glXGetVisualFromFBConfig(xinfo->display(), configs[i]); if (!vi) @@ -843,7 +928,7 @@ void QGLContext::makeCurrent() } else if (d->paintDevice->devType() == QInternal::Pbuffer) { ok = glXMakeCurrent(xinfo->display(), (GLXPbuffer)d->pbuf, (GLXContext)d->cx); } else if (d->paintDevice->devType() == QInternal::Widget) { - ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)->winId(), (GLXContext)d->cx); + ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)->internalWinId(), (GLXContext)d->cx); } if (!ok) qWarning("QGLContext::makeCurrent(): Failed."); @@ -1773,6 +1858,9 @@ QGLTexture *QGLContextPrivate::bindTextureFromNativePixmap(QPixmap *pixmap, cons glXBindTexImageEXT(x11Info.display(), (GLXPixmap)pixmapData->gl_surface, GLX_FRONT_LEFT_EXT, 0); glBindTexture(GL_TEXTURE_2D, textureId); + GLuint filtering = (options & QGLContext::LinearFilteringBindOption) ? GL_LINEAR : GL_NEAREST; + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filtering); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filtering); if (!((hasAlpha && RGBAConfigInverted) || (!hasAlpha && RGBConfigInverted))) options &= ~QGLContext::InvertedYBindOption; diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 890b029..deffc20 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -1024,6 +1024,36 @@ QPaintEngine *QGLFramebufferObject::paintEngine() const } /*! + \fn bool QGLFramebufferObject::bindDefault() + \internal + + Switches rendering back to the default, windowing system provided + framebuffer. + Returns true upon success, false otherwise. + + \sa bind(), release() +*/ +bool QGLFramebufferObject::bindDefault() +{ + QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext()); + + if (ctx) { + bool ext_detected = (QGLExtensions::glExtensions() & QGLExtensions::FramebufferObject); + if (!ext_detected || (ext_detected && !qt_resolve_framebufferobject_extensions(ctx))) + return false; + + ctx->d_ptr->current_fbo = ctx->d_ptr->default_fbo; + glBindFramebuffer(GL_FRAMEBUFFER_EXT, ctx->d_ptr->default_fbo); +#ifdef QT_DEBUG + } else { + qWarning("QGLFramebufferObject::bindDefault() called without current context."); +#endif + } + + return ctx != 0; +} + +/*! \fn bool QGLFramebufferObject::hasOpenGLFramebufferObjects() Returns true if the OpenGL \c{GL_EXT_framebuffer_object} extension diff --git a/src/opengl/qglframebufferobject.h b/src/opengl/qglframebufferobject.h index 306b6ff..6ff6645 100644 --- a/src/opengl/qglframebufferobject.h +++ b/src/opengl/qglframebufferobject.h @@ -108,6 +108,8 @@ public: QPaintEngine *paintEngine() const; GLuint handle() const; + static bool bindDefault(); + static bool hasOpenGLFramebufferObjects(); void drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget = GL_TEXTURE_2D); diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 76a605a..4b22d5e 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -1622,11 +1622,48 @@ 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); - } else { - // The best we can do is clip to the bounding rectangle - // of all control points. - clip(path.controlPointRect().toRect(), op); + return; + } + + // Try converting the path into a QRegion that tightly follows + // the outline of the path we want to clip with. + QRegion region(path.convertToPainterPath().toFillPolygon(QTransform()).toPolygon()); + switch (op) { + case Qt::NoClip: + { + region = defaultClipRegion(); + } + break; + + case Qt::ReplaceClip: + { + region = d->transform.map(region); + } + break; + + case Qt::IntersectClip: + { + region = s->clipRegion.intersect(d->transform.map(region)); + } + break; + + case Qt::UniteClip: + { + region = s->clipRegion.unite(d->transform.map(region)); + } + break; } + if (region.numRects() <= d->maxScissorRects) { + // We haven't reached the maximum scissor count yet, so we can + // still make use of this region. + s->clipRegion = region; + updateScissor(); + return; + } + + // The best we can do is clip to the bounding rectangle + // of all control points. + clip(path.controlPointRect().toRect(), op); } void QVGPaintEngine::clip(const QRect &rect, Qt::ClipOperation op) diff --git a/src/plugins/bearer/symbian/symbianengine.cpp b/src/plugins/bearer/symbian/symbianengine.cpp index 8c26cf0..ab1ba28 100644 --- a/src/plugins/bearer/symbian/symbianengine.cpp +++ b/src/plugins/bearer/symbian/symbianengine.cpp @@ -389,9 +389,9 @@ void SymbianEngine::updateConfigurationsL() QNetworkConfigurationPrivatePointer ptr(cpPriv); accessPointConfigurations.insert(ident, ptr); - locker.unlock(); + mutex.unlock(); emit configurationAdded(ptr); - locker.relock(); + mutex.lock(); } else { delete cpPriv; } diff --git a/src/plugins/s60/s60pluginbase.pri b/src/plugins/s60/s60pluginbase.pri index 1a6f4a2..4e15102 100644 --- a/src/plugins/s60/s60pluginbase.pri +++ b/src/plugins/s60/s60pluginbase.pri @@ -8,11 +8,16 @@ QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/s60 MMP_RULES += NOEXPORTLIBRARY -defBlock = \ - "$${LITERAL_HASH}ifdef WINSCW" \ - "DEFFILE ../bwins/qts60plugin.def" \ - "$${LITERAL_HASH}else" \ - "DEFFILE ../eabi/qts60plugin.def" \ - "$${LITERAL_HASH}endif" +symbian-abld|symbian-sbsv2 { + defBlock = \ + "$${LITERAL_HASH}ifdef WINSCW" \ + "DEFFILE ../bwins/qts60plugin.def" \ + "$${LITERAL_HASH}else" \ + "DEFFILE ../eabi/qts60plugin.def" \ + "$${LITERAL_HASH}endif" +} else { + CONFIG *= def_files + DEF_FILE = ../eabi/qts60pluginu.def +} MMP_RULES += defBlock
\ No newline at end of file diff --git a/src/qbase.pri b/src/qbase.pri index 4a75565..83ae069 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -1,4 +1,4 @@ -isEmpty(TARGET):error(You must set TARGET before include()'ing $${_FILE_}) +isEmpty(TARGET):error("You must set TARGET before include()'ing $${_FILE_}") INCLUDEPATH *= $$QMAKE_INCDIR_QT/$$TARGET #just for today to have some compat !isEmpty(RCC_DIR): INCLUDEPATH += $$RCC_DIR isEmpty(QT_ARCH):!isEmpty(ARCH):QT_ARCH=$$ARCH #another compat that will rot for change #215700 diff --git a/src/s60installs/bwins/QtDeclarativeu.def b/src/s60installs/bwins/QtDeclarativeu.def index 3df0f47..2992cf6 100644 --- a/src/s60installs/bwins/QtDeclarativeu.def +++ b/src/s60installs/bwins/QtDeclarativeu.def @@ -862,7 +862,7 @@ EXPORTS ?cursorPositionChanged@QDeclarativeTextEdit@@IAEXXZ @ 861 NONAME ; void QDeclarativeTextEdit::cursorPositionChanged(void) ?cursorPositionChanged@QDeclarativeTextInput@@IAEXXZ @ 862 NONAME ; void QDeclarativeTextInput::cursorPositionChanged(void) ?cursorRect@QDeclarativeTextEdit@@QBE?AVQRect@@XZ @ 863 NONAME ABSENT ; class QRect QDeclarativeTextEdit::cursorRect(void) const - ?cursorRect@QDeclarativeTextInput@@QBE?AVQRect@@XZ @ 864 NONAME ; class QRect QDeclarativeTextInput::cursorRect(void) const + ?cursorRect@QDeclarativeTextInput@@QBE?AVQRect@@XZ @ 864 NONAME ABSENT ; class QRect QDeclarativeTextInput::cursorRect(void) const ?cursorVisibleChanged@QDeclarativeTextEdit@@IAEX_N@Z @ 865 NONAME ; void QDeclarativeTextEdit::cursorVisibleChanged(bool) ?cursorVisibleChanged@QDeclarativeTextInput@@IAEX_N@Z @ 866 NONAME ; void QDeclarativeTextInput::cursorVisibleChanged(bool) ?customParser@QDeclarativeType@@QBEPAVQDeclarativeCustomParser@@XZ @ 867 NONAME ; class QDeclarativeCustomParser * QDeclarativeType::customParser(void) const @@ -2568,10 +2568,10 @@ EXPORTS ?setSelectedTextColor@QDeclarativeTextInput@@QAEXABVQColor@@@Z @ 2567 NONAME ; void QDeclarativeTextInput::setSelectedTextColor(class QColor const &) ?setSelectionColor@QDeclarativeTextEdit@@QAEXABVQColor@@@Z @ 2568 NONAME ; void QDeclarativeTextEdit::setSelectionColor(class QColor const &) ?setSelectionColor@QDeclarativeTextInput@@QAEXABVQColor@@@Z @ 2569 NONAME ; void QDeclarativeTextInput::setSelectionColor(class QColor const &) - ?setSelectionEnd@QDeclarativeTextEdit@@QAEXH@Z @ 2570 NONAME ; void QDeclarativeTextEdit::setSelectionEnd(int) - ?setSelectionEnd@QDeclarativeTextInput@@QAEXH@Z @ 2571 NONAME ; void QDeclarativeTextInput::setSelectionEnd(int) - ?setSelectionStart@QDeclarativeTextEdit@@QAEXH@Z @ 2572 NONAME ; void QDeclarativeTextEdit::setSelectionStart(int) - ?setSelectionStart@QDeclarativeTextInput@@QAEXH@Z @ 2573 NONAME ; void QDeclarativeTextInput::setSelectionStart(int) + ?setSelectionEnd@QDeclarativeTextEdit@@QAEXH@Z @ 2570 NONAME ABSENT ; void QDeclarativeTextEdit::setSelectionEnd(int) + ?setSelectionEnd@QDeclarativeTextInput@@QAEXH@Z @ 2571 NONAME ABSENT ; void QDeclarativeTextInput::setSelectionEnd(int) + ?setSelectionStart@QDeclarativeTextEdit@@QAEXH@Z @ 2572 NONAME ABSENT ; void QDeclarativeTextEdit::setSelectionStart(int) + ?setSelectionStart@QDeclarativeTextInput@@QAEXH@Z @ 2573 NONAME ABSENT ; void QDeclarativeTextInput::setSelectionStart(int) ?setSmooth@QDeclarativeItem@@QAEX_N@Z @ 2574 NONAME ; void QDeclarativeItem::setSmooth(bool) ?setSmoothCache@QDeclarativePaintedItem@@QAEX_N@Z @ 2575 NONAME ; void QDeclarativePaintedItem::setSmoothCache(bool) ?setSnapMode@QDeclarativeListView@@QAEXW4SnapMode@1@@Z @ 2576 NONAME ; void QDeclarativeListView::setSnapMode(enum QDeclarativeListView::SnapMode) @@ -3891,7 +3891,7 @@ EXPORTS ?wrapMode@QDeclarativeTextEdit@@QBE?AW4WrapMode@1@XZ @ 3890 NONAME ; enum QDeclarativeTextEdit::WrapMode QDeclarativeTextEdit::wrapMode(void) const ?wrapModeChanged@QDeclarativeText@@IAEXXZ @ 3891 NONAME ; void QDeclarativeText::wrapModeChanged(void) ?wrapModeChanged@QDeclarativeTextEdit@@IAEXXZ @ 3892 NONAME ; void QDeclarativeTextEdit::wrapModeChanged(void) - ?xToPosition@QDeclarativeTextInput@@QAEHH@Z @ 3893 NONAME ; int QDeclarativeTextInput::xToPosition(int) + ?xToPosition@QDeclarativeTextInput@@QAEHH@Z @ 3893 NONAME ABSENT ; int QDeclarativeTextInput::xToPosition(int) ?staticMetaObject@QDeclarativeSmoothedFollow@@2UQMetaObject@@B @ 3894 NONAME ; struct QMetaObject const QDeclarativeSmoothedFollow::staticMetaObject ?trUtf8@QDeclarativeCompiler@@SA?AVQString@@PBD0H@Z @ 3895 NONAME ; class QString QDeclarativeCompiler::trUtf8(char const *, char const *, int) ?findSignalByName@QDeclarativePropertyPrivate@@SA?AVQMetaMethod@@PBUQMetaObject@@ABVQByteArray@@@Z @ 3896 NONAME ; class QMetaMethod QDeclarativePropertyPrivate::findSignalByName(struct QMetaObject const *, class QByteArray const &) @@ -4024,10 +4024,10 @@ EXPORTS ?restart@QDeclarativeItemPrivate@@SA_JAAVQElapsedTimer@@@Z @ 4023 NONAME ; long long QDeclarativeItemPrivate::restart(class QElapsedTimer &) ?get@QDeclarativeXmlListModel@@QBE?AVQScriptValue@@H@Z @ 4024 NONAME ; class QScriptValue QDeclarativeXmlListModel::get(int) const ?setScale@QDeclarativeParentChange@@QAEXVQDeclarativeScriptString@@@Z @ 4025 NONAME ; void QDeclarativeParentChange::setScale(class QDeclarativeScriptString) - ?showInputPanelOnFocusChanged@QDeclarativeTextEdit@@IAEX_N@Z @ 4026 NONAME ; void QDeclarativeTextEdit::showInputPanelOnFocusChanged(bool) + ?showInputPanelOnFocusChanged@QDeclarativeTextEdit@@IAEX_N@Z @ 4026 NONAME ABSENT ; void QDeclarativeTextEdit::showInputPanelOnFocusChanged(bool) ?focusOutEvent@QDeclarativeTextInput@@MAEXPAVQFocusEvent@@@Z @ 4027 NONAME ; void QDeclarativeTextInput::focusOutEvent(class QFocusEvent *) ?height@QDeclarativeParentChange@@QBE?AVQDeclarativeScriptString@@XZ @ 4028 NONAME ; class QDeclarativeScriptString QDeclarativeParentChange::height(void) const - ?showInputPanelOnFocus@QDeclarativeTextEdit@@QBE_NXZ @ 4029 NONAME ; bool QDeclarativeTextEdit::showInputPanelOnFocus(void) const + ?showInputPanelOnFocus@QDeclarativeTextEdit@@QBE_NXZ @ 4029 NONAME ABSENT ; bool QDeclarativeTextEdit::showInputPanelOnFocus(void) const ?errorString@QDeclarativeComponent@@QBE?AVQString@@XZ @ 4030 NONAME ; class QString QDeclarativeComponent::errorString(void) const ?elapsed@QDeclarativeItemPrivate@@SA_JAAVQElapsedTimer@@@Z @ 4031 NONAME ; long long QDeclarativeItemPrivate::elapsed(class QElapsedTimer &) ?focusInEvent@QDeclarativeTextInput@@MAEXPAVQFocusEvent@@@Z @ 4032 NONAME ; void QDeclarativeTextInput::focusInEvent(class QFocusEvent *) @@ -4042,15 +4042,15 @@ EXPORTS ?errorString@QDeclarativeXmlListModel@@QBE?AVQString@@XZ @ 4041 NONAME ; class QString QDeclarativeXmlListModel::errorString(void) const ?consistentTime@QDeclarativeItemPrivate@@2_JA @ 4042 NONAME ; long long QDeclarativeItemPrivate::consistentTime ?scale@QDeclarativeParentChange@@QBE?AVQDeclarativeScriptString@@XZ @ 4043 NONAME ; class QDeclarativeScriptString QDeclarativeParentChange::scale(void) const - ?showInputPanelOnFocus@QDeclarativeTextInput@@QBE_NXZ @ 4044 NONAME ; bool QDeclarativeTextInput::showInputPanelOnFocus(void) const + ?showInputPanelOnFocus@QDeclarativeTextInput@@QBE_NXZ @ 4044 NONAME ABSENT ; bool QDeclarativeTextInput::showInputPanelOnFocus(void) const ?focusInEvent@QDeclarativeTextEdit@@MAEXPAVQFocusEvent@@@Z @ 4045 NONAME ; void QDeclarativeTextEdit::focusInEvent(class QFocusEvent *) ?y@QDeclarativeParentChange@@QBE?AVQDeclarativeScriptString@@XZ @ 4046 NONAME ; class QDeclarativeScriptString QDeclarativeParentChange::y(void) const ?setY@QDeclarativeParentChange@@QAEXVQDeclarativeScriptString@@@Z @ 4047 NONAME ; void QDeclarativeParentChange::setY(class QDeclarativeScriptString) - ?setShowInputPanelOnFocus@QDeclarativeTextEdit@@QAEX_N@Z @ 4048 NONAME ; void QDeclarativeTextEdit::setShowInputPanelOnFocus(bool) + ?setShowInputPanelOnFocus@QDeclarativeTextEdit@@QAEX_N@Z @ 4048 NONAME ABSENT ; void QDeclarativeTextEdit::setShowInputPanelOnFocus(bool) ?paintedSizeChanged@QDeclarativeText@@IAEXXZ @ 4049 NONAME ; void QDeclarativeText::paintedSizeChanged(void) ?selectByMouseChanged@QDeclarativeTextEdit@@IAEX_N@Z @ 4050 NONAME ; void QDeclarativeTextEdit::selectByMouseChanged(bool) ?openSoftwareInputPanel@QDeclarativeTextInput@@QAEXXZ @ 4051 NONAME ; void QDeclarativeTextInput::openSoftwareInputPanel(void) - ?setShowInputPanelOnFocus@QDeclarativeTextInput@@QAEX_N@Z @ 4052 NONAME ; void QDeclarativeTextInput::setShowInputPanelOnFocus(bool) + ?setShowInputPanelOnFocus@QDeclarativeTextInput@@QAEX_N@Z @ 4052 NONAME ABSENT ; void QDeclarativeTextInput::setShowInputPanelOnFocus(bool) ?boundingRect@QDeclarativePaintedItem@@MBE?AVQRectF@@XZ @ 4053 NONAME ; class QRectF QDeclarativePaintedItem::boundingRect(void) const ?closeSoftwareInputPanel@QDeclarativeTextInput@@QAEXXZ @ 4054 NONAME ; void QDeclarativeTextInput::closeSoftwareInputPanel(void) ?setWidth@QDeclarativeParentChange@@QAEXVQDeclarativeScriptString@@@Z @ 4055 NONAME ; void QDeclarativeParentChange::setWidth(class QDeclarativeScriptString) @@ -4067,11 +4067,25 @@ EXPORTS ?selectByMouse@QDeclarativeTextEdit@@QBE_NXZ @ 4066 NONAME ; bool QDeclarativeTextEdit::selectByMouse(void) const ?setHeight@QDeclarativeParentChange@@QAEXVQDeclarativeScriptString@@@Z @ 4067 NONAME ; void QDeclarativeParentChange::setHeight(class QDeclarativeScriptString) ?start@QDeclarativeItemPrivate@@SAXAAVQElapsedTimer@@@Z @ 4068 NONAME ; void QDeclarativeItemPrivate::start(class QElapsedTimer &) - ?showInputPanelOnFocusChanged@QDeclarativeTextInput@@IAEX_N@Z @ 4069 NONAME ; void QDeclarativeTextInput::showInputPanelOnFocusChanged(bool) + ?showInputPanelOnFocusChanged@QDeclarativeTextInput@@IAEX_N@Z @ 4069 NONAME ABSENT ; void QDeclarativeTextInput::showInputPanelOnFocusChanged(bool) ?x@QDeclarativeParentChange@@QBE?AVQDeclarativeScriptString@@XZ @ 4070 NONAME ; class QDeclarativeScriptString QDeclarativeParentChange::x(void) const ?selectByMouseChanged@QDeclarativeTextInput@@IAEX_N@Z @ 4071 NONAME ; void QDeclarativeTextInput::selectByMouseChanged(bool) ?width@QDeclarativeParentChange@@QBE?AVQDeclarativeScriptString@@XZ @ 4072 NONAME ; class QDeclarativeScriptString QDeclarativeParentChange::width(void) const ?openSoftwareInputPanel@QDeclarativeTextEdit@@QAEXXZ @ 4073 NONAME ; void QDeclarativeTextEdit::openSoftwareInputPanel(void) ?cursorRectangleChanged@QDeclarativeTextEdit@@IAEXXZ @ 4074 NONAME ; void QDeclarativeTextEdit::cursorRectangleChanged(void) ?cursorRectangle@QDeclarativeTextEdit@@QBE?AVQRect@@XZ @ 4075 NONAME ; class QRect QDeclarativeTextEdit::cursorRectangle(void) const + ?selectWord@QDeclarativeTextInput@@QAEXXZ @ 4076 NONAME ; void QDeclarativeTextInput::selectWord(void) + ?positionToRectangle@QDeclarativeTextEdit@@QBE?AVQRectF@@H@Z @ 4077 NONAME ; class QRectF QDeclarativeTextEdit::positionToRectangle(int) const + ?cursorRectangle@QDeclarativeTextInput@@QBE?AVQRect@@XZ @ 4078 NONAME ; class QRect QDeclarativeTextInput::cursorRectangle(void) const + ?mouseDoubleClickEvent@QDeclarativeTextInput@@MAEXPAVQGraphicsSceneMouseEvent@@@Z @ 4079 NONAME ; void QDeclarativeTextInput::mouseDoubleClickEvent(class QGraphicsSceneMouseEvent *) + ?positionAt@QDeclarativeTextEdit@@QBEHHH@Z @ 4080 NONAME ; int QDeclarativeTextEdit::positionAt(int, int) const + ?cut@QDeclarativeTextEdit@@QAEXXZ @ 4081 NONAME ; void QDeclarativeTextEdit::cut(void) + ?copy@QDeclarativeTextEdit@@QAEXXZ @ 4082 NONAME ; void QDeclarativeTextEdit::copy(void) + ?select@QDeclarativeTextEdit@@QAEXHH@Z @ 4083 NONAME ; void QDeclarativeTextEdit::select(int, int) + ?moveCursorSelection@QDeclarativeTextEdit@@QAEXH@Z @ 4084 NONAME ; void QDeclarativeTextEdit::moveCursorSelection(int) + ?select@QDeclarativeTextInput@@QAEXHH@Z @ 4085 NONAME ; void QDeclarativeTextInput::select(int, int) + ?paste@QDeclarativeTextEdit@@QAEXXZ @ 4086 NONAME ; void QDeclarativeTextEdit::paste(void) + ?positionToRectangle@QDeclarativeTextInput@@QBE?AVQRectF@@H@Z @ 4087 NONAME ; class QRectF QDeclarativeTextInput::positionToRectangle(int) const + ?positionAt@QDeclarativeTextInput@@QBEHH@Z @ 4088 NONAME ; int QDeclarativeTextInput::positionAt(int) const + ?selectWord@QDeclarativeTextEdit@@QAEXXZ @ 4089 NONAME ; void QDeclarativeTextEdit::selectWord(void) diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index a1e05e2..9b4ecc2 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -12805,4 +12805,12 @@ EXPORTS ?setPerformanceHint@QStaticText@@QAEXW4PerformanceHint@1@@Z @ 12804 NONAME ; void QStaticText::setPerformanceHint(enum QStaticText::PerformanceHint) ??0QStaticText@@QAE@ABV0@@Z @ 12805 NONAME ; QStaticText::QStaticText(class QStaticText const &) ??0QImageTextureGlyphCache@@QAE@W4Type@QFontEngineGlyphCache@@ABVQTransform@@@Z @ 12806 NONAME ; QImageTextureGlyphCache::QImageTextureGlyphCache(enum QFontEngineGlyphCache::Type, class QTransform const &) + ?verticalMovementX@QTextCursor@@QBEHXZ @ 12807 NONAME ; int QTextCursor::verticalMovementX(void) const + ?runtime_graphics_system@QApplicationPrivate@@2_NA @ 12808 NONAME ; bool QApplicationPrivate::runtime_graphics_system + ?keepPositionOnInsert@QTextCursor@@QBE_NXZ @ 12809 NONAME ; bool QTextCursor::keepPositionOnInsert(void) const + ?setKeepPositionOnInsert@QTextCursor@@QAEX_N@Z @ 12810 NONAME ; void QTextCursor::setKeepPositionOnInsert(bool) + ?textDirection@QProgressBar@@QBE?AW4Direction@1@XZ @ 12811 NONAME ; enum QProgressBar::Direction QProgressBar::textDirection(void) const + ?setVerticalMovementX@QTextCursor@@QAEXH@Z @ 12812 NONAME ; void QTextCursor::setVerticalMovementX(int) + ?invertedAppearance@QProgressBar@@QBE_NXZ @ 12813 NONAME ; bool QProgressBar::invertedAppearance(void) const + ?width@QFontMetrics@@QBEHABVQString@@HH@Z @ 12814 NONAME ; int QFontMetrics::width(class QString const &, int, int) const diff --git a/src/s60installs/eabi/QtDeclarativeu.def b/src/s60installs/eabi/QtDeclarativeu.def index 320a780..1c4cd5d 100644 --- a/src/s60installs/eabi/QtDeclarativeu.def +++ b/src/s60installs/eabi/QtDeclarativeu.def @@ -911,7 +911,7 @@ EXPORTS _ZN20QDeclarativeTextEdit15mousePressEventEP24QGraphicsSceneMouseEvent @ 910 NONAME _ZN20QDeclarativeTextEdit15readOnlyChangedEb @ 911 NONAME _ZN20QDeclarativeTextEdit15setFocusOnPressEb @ 912 NONAME - _ZN20QDeclarativeTextEdit15setSelectionEndEi @ 913 NONAME + _ZN20QDeclarativeTextEdit15setSelectionEndEi @ 913 NONAME ABSENT _ZN20QDeclarativeTextEdit16inputMethodEventEP17QInputMethodEvent @ 914 NONAME _ZN20QDeclarativeTextEdit16selectionChangedEv @ 915 NONAME _ZN20QDeclarativeTextEdit16setCursorVisibleEb @ 916 NONAME @@ -921,7 +921,7 @@ EXPORTS _ZN20QDeclarativeTextEdit17setCursorDelegateEP21QDeclarativeComponent @ 920 NONAME _ZN20QDeclarativeTextEdit17setCursorPositionEi @ 921 NONAME _ZN20QDeclarativeTextEdit17setSelectionColorERK6QColor @ 922 NONAME - _ZN20QDeclarativeTextEdit17setSelectionStartEi @ 923 NONAME + _ZN20QDeclarativeTextEdit17setSelectionStartEi @ 923 NONAME ABSENT _ZN20QDeclarativeTextEdit17textFormatChangedENS_10TextFormatE @ 924 NONAME _ZN20QDeclarativeTextEdit17textMarginChangedEf @ 925 NONAME _ZN20QDeclarativeTextEdit18loadCursorDelegateEv @ 926 NONAME @@ -1207,7 +1207,7 @@ EXPORTS _ZN21QDeclarativeTextInput15mousePressEventEP24QGraphicsSceneMouseEvent @ 1206 NONAME _ZN21QDeclarativeTextInput15readOnlyChangedEb @ 1207 NONAME _ZN21QDeclarativeTextInput15setFocusOnPressEb @ 1208 NONAME - _ZN21QDeclarativeTextInput15setSelectionEndEi @ 1209 NONAME + _ZN21QDeclarativeTextInput15setSelectionEndEi @ 1209 NONAME ABSENT _ZN21QDeclarativeTextInput16cursorPosChangedEv @ 1210 NONAME _ZN21QDeclarativeTextInput16inputMaskChangedERK7QString @ 1211 NONAME _ZN21QDeclarativeTextInput16selectionChangedEv @ 1212 NONAME @@ -1218,7 +1218,7 @@ EXPORTS _ZN21QDeclarativeTextInput17setCursorDelegateEP21QDeclarativeComponent @ 1217 NONAME _ZN21QDeclarativeTextInput17setCursorPositionEi @ 1218 NONAME _ZN21QDeclarativeTextInput17setSelectionColorERK6QColor @ 1219 NONAME - _ZN21QDeclarativeTextInput17setSelectionStartEi @ 1220 NONAME + _ZN21QDeclarativeTextInput17setSelectionStartEi @ 1220 NONAME ABSENT _ZN21QDeclarativeTextInput19focusOnPressChangedEb @ 1221 NONAME _ZN21QDeclarativeTextInput19getStaticMetaObjectEv @ 1222 NONAME _ZN21QDeclarativeTextInput19selectedTextChangedEv @ 1223 NONAME @@ -2627,7 +2627,7 @@ EXPORTS _ZNK21QDeclarativeRectangle8gradientEv @ 2626 NONAME _ZNK21QDeclarativeScaleGrid10metaObjectEv @ 2627 NONAME _ZNK21QDeclarativeScaleGrid6isNullEv @ 2628 NONAME - _ZNK21QDeclarativeTextInput10cursorRectEv @ 2629 NONAME + _ZNK21QDeclarativeTextInput10cursorRectEv @ 2629 NONAME ABSENT _ZNK21QDeclarativeTextInput10isReadOnlyEv @ 2630 NONAME _ZNK21QDeclarativeTextInput10metaObjectEv @ 2631 NONAME _ZNK21QDeclarativeTextInput12focusOnPressEv @ 2632 NONAME @@ -3413,7 +3413,7 @@ EXPORTS _ZN20QDeclarativePathView28highlightMoveDurationChangedEv @ 3412 NONAME _ZN20QDeclarativeTextEdit11setWrapModeENS_8WrapModeE @ 3413 NONAME _ZN20QDeclarativeTextEdit15wrapModeChangedEv @ 3414 NONAME - _ZN21QDeclarativeTextInput11xToPositionEi @ 3415 NONAME + _ZN21QDeclarativeTextInput11xToPositionEi @ 3415 NONAME ABSENT _ZN21QDeclarativeTextInput13setAutoScrollEb @ 3416 NONAME _ZN21QDeclarativeTextInput14mouseMoveEventEP24QGraphicsSceneMouseEvent @ 3417 NONAME _ZN21QDeclarativeTextInput17autoScrollChangedEb @ 3418 NONAME @@ -3612,16 +3612,16 @@ EXPORTS _ZN20QDeclarativeTextEdit22cursorRectangleChangedEv @ 3611 NONAME _ZN20QDeclarativeTextEdit22openSoftwareInputPanelEv @ 3612 NONAME _ZN20QDeclarativeTextEdit23closeSoftwareInputPanelEv @ 3613 NONAME - _ZN20QDeclarativeTextEdit24setShowInputPanelOnFocusEb @ 3614 NONAME - _ZN20QDeclarativeTextEdit28showInputPanelOnFocusChangedEb @ 3615 NONAME + _ZN20QDeclarativeTextEdit24setShowInputPanelOnFocusEb @ 3614 NONAME ABSENT + _ZN20QDeclarativeTextEdit28showInputPanelOnFocusChangedEb @ 3615 NONAME ABSENT _ZN21QDeclarativeTextInput12focusInEventEP11QFocusEvent @ 3616 NONAME _ZN21QDeclarativeTextInput13focusOutEventEP11QFocusEvent @ 3617 NONAME _ZN21QDeclarativeTextInput16setSelectByMouseEb @ 3618 NONAME _ZN21QDeclarativeTextInput20selectByMouseChangedEb @ 3619 NONAME _ZN21QDeclarativeTextInput22openSoftwareInputPanelEv @ 3620 NONAME _ZN21QDeclarativeTextInput23closeSoftwareInputPanelEv @ 3621 NONAME - _ZN21QDeclarativeTextInput24setShowInputPanelOnFocusEb @ 3622 NONAME - _ZN21QDeclarativeTextInput28showInputPanelOnFocusChangedEb @ 3623 NONAME + _ZN21QDeclarativeTextInput24setShowInputPanelOnFocusEb @ 3622 NONAME ABSENT + _ZN21QDeclarativeTextInput28showInputPanelOnFocusChangedEb @ 3623 NONAME ABSENT _ZN22QDeclarativeExpressionC1EP19QDeclarativeContextP7QObjectRK7QStringS3_ @ 3624 NONAME _ZN22QDeclarativeExpressionC1EP23QDeclarativeContextDataP7QObjectRK7QString @ 3625 NONAME _ZN22QDeclarativeExpressionC1EP23QDeclarativeContextDataP7QObjectRK7QStringR29QDeclarativeExpressionPrivate @ 3626 NONAME @@ -3645,10 +3645,10 @@ EXPORTS _ZNK20QDeclarativeTextEdit13paintedHeightEv @ 3644 NONAME _ZNK20QDeclarativeTextEdit13selectByMouseEv @ 3645 NONAME _ZNK20QDeclarativeTextEdit15cursorRectangleEv @ 3646 NONAME - _ZNK20QDeclarativeTextEdit21showInputPanelOnFocusEv @ 3647 NONAME + _ZNK20QDeclarativeTextEdit21showInputPanelOnFocusEv @ 3647 NONAME ABSENT _ZNK21QDeclarativeComponent11errorStringEv @ 3648 NONAME _ZNK21QDeclarativeTextInput13selectByMouseEv @ 3649 NONAME - _ZNK21QDeclarativeTextInput21showInputPanelOnFocusEv @ 3650 NONAME + _ZNK21QDeclarativeTextInput21showInputPanelOnFocusEv @ 3650 NONAME ABSENT _ZNK23QDeclarativePaintedItem12boundingRectEv @ 3651 NONAME _ZNK24QDeclarativeXmlListModel11errorStringEv @ 3652 NONAME _ZNK24QDeclarativeXmlListModel3getEi @ 3653 NONAME @@ -3657,4 +3657,19 @@ EXPORTS _ZThn8_N21QDeclarativeTextInput12focusInEventEP11QFocusEvent @ 3656 NONAME _ZThn8_N21QDeclarativeTextInput13focusOutEventEP11QFocusEvent @ 3657 NONAME _ZThn8_NK23QDeclarativePaintedItem12boundingRectEv @ 3658 NONAME + _ZN20QDeclarativeTextEdit10selectWordEv @ 3659 NONAME + _ZN20QDeclarativeTextEdit19moveCursorSelectionEi @ 3660 NONAME + _ZN20QDeclarativeTextEdit3cutEv @ 3661 NONAME + _ZN20QDeclarativeTextEdit4copyEv @ 3662 NONAME + _ZN20QDeclarativeTextEdit5pasteEv @ 3663 NONAME + _ZN20QDeclarativeTextEdit6selectEii @ 3664 NONAME + _ZN21QDeclarativeTextInput10selectWordEv @ 3665 NONAME + _ZN21QDeclarativeTextInput21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent @ 3666 NONAME + _ZN21QDeclarativeTextInput6selectEii @ 3667 NONAME + _ZNK20QDeclarativeTextEdit10positionAtEii @ 3668 NONAME + _ZNK20QDeclarativeTextEdit19positionToRectangleEi @ 3669 NONAME + _ZNK21QDeclarativeTextInput10positionAtEi @ 3670 NONAME + _ZNK21QDeclarativeTextInput15cursorRectangleEv @ 3671 NONAME + _ZNK21QDeclarativeTextInput19positionToRectangleEi @ 3672 NONAME + _ZThn8_N21QDeclarativeTextInput21mouseDoubleClickEventEP24QGraphicsSceneMouseEvent @ 3673 NONAME diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 8aafde9..9c1002d 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -12006,4 +12006,10 @@ EXPORTS _ZTV20QGraphicsViewPrivate @ 12005 NONAME _ZTV23QImageTextureGlyphCache @ 12006 NONAME _ZTV26QAbstractScrollAreaPrivate @ 12007 NONAME + _ZN11QTextCursor20setVerticalMovementXEi @ 12008 NONAME + _ZN11QTextCursor23setKeepPositionOnInsertEb @ 12009 NONAME + _ZN19QApplicationPrivate23runtime_graphics_systemE @ 12010 NONAME DATA 1 + _ZNK11QTextCursor17verticalMovementXEv @ 12011 NONAME + _ZNK11QTextCursor20keepPositionOnInsertEv @ 12012 NONAME + _ZNK12QFontMetrics5widthERK7QStringii @ 12013 NONAME diff --git a/src/s60installs/qt.iby b/src/s60installs/qt.iby index ec019e2..f43f344 100644 --- a/src/s60installs/qt.iby +++ b/src/s60installs/qt.iby @@ -74,6 +74,21 @@ data=\epoc32\data\z\resource\qt\plugins\codecs\qtwcodecs.qtplugin resou // iconengines stubs data=\epoc32\data\z\resource\qt\plugins\iconengines\qsvgicon.qtplugin resource\qt\plugins\iconengines\qsvgicon.qtplugin +// qml import plugins +file=ABI_DIR\BUILD_DIR\qmlwebkitplugin.dll SHARED_LIB_DIR\qmlwebkitplugin.dll +file=ABI_DIR\BUILD_DIR\qmlfolderlistmodelplugin.dll SHARED_LIB_DIR\qmlfolderlistmodelplugin.dll +file=ABI_DIR\BUILD_DIR\qmlgesturesplugin.dll SHARED_LIB_DIR\qmlgesturesplugin.dll +file=ABI_DIR\BUILD_DIR\qmlparticlesplugin.dll SHARED_LIB_DIR\qmlparticlesplugin.dll + +data=\epoc32\data\z\resource\qt\imports\org\webkit\qmlwebkitplugin.qtplugin resource\qt\imports\org\webkit\qmlwebkitplugin.qtplugin +data=\epoc32\data\z\resource\qt\imports\Qt\labs\folderlistmodel\qmlfolderlistmodelplugin.qtplugin resource\qt\imports\Qt\labs\folderlistmodel\qmlfolderlistmodelplugin.qtplugin +data=\epoc32\data\z\resource\qt\imports\Qt\labs\gestures\qmlgesturesplugin.qtplugin resource\qt\imports\Qt\labs\gestures\qmlgesturesplugin.qtplugin +data=\epoc32\data\z\resource\qt\imports\Qt\labs\particles\qmlparticlesplugin.qtplugin resource\qt\imports\Qt\labs\particles\qmlparticlesplugin.qtplugin + +data=\epoc32\data\z\resource\qt\imports\org\webkit\qmldir resource\qt\imports\org\webkit\qmldir +data=\epoc32\data\z\resource\qt\imports\Qt\labs\folderlistmodel\qmldir resource\qt\imports\Qt\labs\folderlistmodel\qmldir +data=\epoc32\data\z\resource\qt\imports\Qt\labs\gestures\qmldir resource\qt\imports\Qt\labs\gestures\qmldir +data=\epoc32\data\z\resource\qt\imports\Qt\labs\particles\qmldir resource\qt\imports\Qt\labs\particles\qmldir // QtMultimedia audio backend data=\epoc32\data\qt\qtlibspluginstubs\qaudio.qtplugin resource\qt\plugins\audio\qaudio.qtplugin diff --git a/src/s60installs/qt.svg b/src/s60installs/qt.svg index 6230ada..566acfa 100644 --- a/src/s60installs/qt.svg +++ b/src/s60installs/qt.svg @@ -1,17 +1,93 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1 Tiny//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11-tiny.dtd"> -<svg xmlns="http://www.w3.org/2000/svg" baseProfile="tiny" height="146.3063" version="1.0" viewBox="0 0 122 146" width="121.60006"> -<g transform="translate(-376.34283,-407.78046)"> -<g transform="matrix(0.697424,0,0,0.697424,376.34283,407.78046)"> -<path d="M 43.086,0.358597 C 40.9414,0.00358582 38.8399,-0.0824127 36.8086,0.0775909 L 36.8047,0.0735931 C 36.8047,0.0735931 22.9219,1.01859 22.2891,1.0696 C 9.6211,2.08159 0,12.5036 0,26.8896 L 0,196.554 L 14.1914,209.781 L 156.789,185.816 C 166.606,184.113 174.356,172.538 174.356,160.038 L 174.356,21.8786 L 43.086,0.358597 z" style="fill:#006225;fill-rule:evenodd;stroke:none"/> -<path d="M 174.356,160.042 C 174.356,172.538 166.606,184.113 156.789,185.816 L 14.1914,209.781 L 14.1914,25.9916 C 14.1914,9.2726 27.5313,-2.20741 43.086,0.358597 L 174.356,21.8786 L 174.356,160.042 z" style="fill:#80c342;fill-rule:evenodd;stroke:none"/> -<path d="M 130.422,45.9136 L 141.938,47.1516 L 141.938,67.3626 L 154.899,68.2766 L 154.899,80.9566 L 141.938,80.3586 L 141.938,126.691 C 141.938,130.723 142.383,133.316 143.278,134.48 C 144.078,135.547 145.324,136.074 146.988,136.074 C 147.149,136.074 147.317,136.07 147.485,136.058 C 150.035,135.91 152.805,135.125 155.828,133.75 L 155.828,145.398 C 150.692,147.656 145.653,148.996 140.703,149.418 C 139.985,149.473 139.293,149.504 138.625,149.504 C 134.145,149.504 130.719,148.203 128.379,145.57 C 125.649,142.519 124.289,137.621 124.289,130.898 L 124.289,79.5426 L 118.063,79.2576 L 118.063,65.6716 L 125.649,66.2186 L 130.422,45.9136 z" style="fill:#ffffff;fill-rule:evenodd;stroke:none"/> -<path d="M 154.899,80.9566 L 141.938,80.3586 L 141.938,80.6366 L 148.883,80.9566 L 154.899,80.9566 z" style="fill:#006225;fill-rule:evenodd;stroke:none"/> -<path d="M 144.637,135.598 C 145.297,135.926 146.067,136.074 146.988,136.074 C 147.149,136.074 147.317,136.07 147.485,136.058 C 150.035,135.91 152.805,135.125 155.828,133.75 L 149.813,133.75 C 147.992,134.582 146.281,135.207 144.637,135.598 z" style="fill:#006225;fill-rule:evenodd;stroke:none"/> -<path d="M 128.379,145.57 C 125.649,142.519 124.289,137.621 124.289,130.898 L 124.289,79.5426 L 118.063,79.2576 L 118.063,65.6716 L 112.047,65.6716 L 112.047,68.7066 C 112.918,71.9796 113.602,75.5266 114.11,79.3506 L 118.274,79.5426 L 118.274,130.898 C 118.274,137.621 119.641,142.519 122.364,145.57 C 124.707,148.203 128.129,149.504 132.61,149.504 L 138.625,149.504 C 134.145,149.504 130.719,148.203 128.379,145.57 z M 130.422,45.9136 L 124.406,45.9136 L 119.738,65.7966 L 125.649,66.2186 L 130.422,45.9136 z" style="fill:#006225;fill-rule:evenodd;stroke:none"/> -<path d="M 91.1528,132.406 C 93.5038,126.355 94.6638,114.492 94.6638,96.7886 C 94.6638,80.8976 93.5158,69.9726 91.1798,63.9756 C 88.8438,57.9486 85.3478,54.6946 80.6598,54.2846 C 80.3008,54.2536 79.9458,54.2336 79.6018,54.2336 C 75.2618,54.2336 71.9218,56.7686 69.5938,61.8586 C 67.0738,67.4016 65.8008,78.8976 65.8008,96.2966 C 65.8008,113.113 67.0388,125.047 69.5348,132.051 C 71.8908,138.723 75.4138,142.027 80.0388,142.027 C 80.2458,142.027 80.4488,142.019 80.6598,142.008 C 85.2928,141.715 88.7808,138.512 91.1528,132.406 M 109.129,136.156 C 105.012,145.863 98.7348,152.214 90.1408,155.156 C 91.0078,159.605 92.3168,162.597 94.0628,164.175 C 95.4138,165.386 97.4958,165.996 100.285,165.996 C 101.09,165.996 101.953,165.941 102.875,165.839 L 102.875,178.964 L 96.9138,179.746 C 95.1558,179.976 93.4878,180.089 91.9098,180.089 C 86.6918,180.089 82.4648,178.824 79.2888,176.265 C 75.0818,172.886 71.9808,166.371 69.9918,156.73 C 60.8555,154.785 53.7344,148.976 48.8008,139.226 C 43.7969,129.324 41.25,114.836 41.25,95.8866 C 41.25,75.4566 44.7344,60.3786 51.5938,50.8156 C 57.3828,42.7456 65.4568,38.7766 75.6168,38.7766 C 77.2458,38.7766 78.9258,38.8786 80.6598,39.0816 C 92.6138,40.4566 101.278,46.0976 106.918,55.8706 C 112.453,65.4326 115.172,79.1366 115.172,97.1326 C 115.172,113.617 113.172,126.582 109.129,136.156 z" style="fill:#ffffff;fill-rule:evenodd;stroke:none"/> -<path d="M 100.281,165.996 C 101.09,165.996 101.953,165.941 102.871,165.839 L 98.0348,165.839 C 98.7108,165.945 99.4878,165.996 100.281,165.996 z" style="fill:#006225;fill-rule:evenodd;stroke:none"/> -<path d="M 84.8518,63.9756 C 87.1878,69.9726 88.3358,80.8976 88.3358,96.7886 C 88.3358,114.492 87.1758,126.355 84.8238,132.406 C 82.9298,137.285 80.2968,140.308 76.9608,141.476 C 77.9258,141.844 78.9528,142.027 80.0388,142.027 C 80.2458,142.027 80.4488,142.019 80.6598,142.008 C 85.2928,141.715 88.7808,138.512 91.1528,132.406 C 93.5038,126.355 94.6638,114.492 94.6638,96.7886 C 94.6638,80.8976 93.5158,69.9726 91.1798,63.9756 C 88.8438,57.9486 85.3478,54.6946 80.6598,54.2846 C 80.3008,54.2536 79.9458,54.2336 79.6018,54.2336 C 78.5118,54.2336 77.4848,54.3936 76.5198,54.7146 L 76.5198,54.7146 L 76.5158,54.7146 C 80.1168,55.8356 82.8948,58.9296 84.8518,63.9756 z M 82.5078,178.253 C 82.3948,178.203 82.2808,178.148 82.1718,178.093 C 82.1598,178.089 82.1488,178.081 82.1368,178.078 C 82.0348,178.027 81.9298,177.972 81.8278,177.921 C 81.8088,177.91 81.7888,177.902 81.7698,177.89 C 81.6798,177.839 81.5858,177.792 81.4918,177.742 C 81.4648,177.726 81.4378,177.706 81.4058,177.691 C 81.3238,177.648 81.2418,177.601 81.1638,177.554 C 81.1248,177.531 81.0858,177.507 81.0508,177.484 C 80.9808,177.445 80.9058,177.402 80.8358,177.359 C 80.7888,177.328 80.7418,177.3 80.6958,177.269 C 80.6368,177.23 80.5778,177.195 80.5198,177.156 C 80.4608,177.117 80.4058,177.081 80.3518,177.042 C 80.3008,177.011 80.2498,176.976 80.2028,176.945 C 80.1368,176.898 80.0708,176.851 80.0078,176.808 C 79.9688,176.781 79.9298,176.753 79.8948,176.726 C 79.8168,176.671 79.7418,176.613 79.6638,176.554 C 79.6408,176.538 79.6138,176.519 79.5858,176.499 C 79.4878,176.421 79.3868,176.343 79.2888,176.265 C 75.0818,172.886 71.9808,166.371 69.9918,156.73 C 60.8555,154.785 53.7344,148.976 48.8008,139.226 C 43.7969,129.324 41.25,114.836 41.25,95.8866 C 41.25,75.4566 44.7344,60.3786 51.5938,50.8156 C 57.3828,42.7456 65.4568,38.7766 75.6168,38.7766 C 75.6528,38.7766 69.2658,38.7766 69.2658,38.7766 L 69.2658,38.7766 C 59.1172,38.7846 51.0508,42.7536 45.2656,50.8156 C 38.4102,60.3786 34.9219,75.4566 34.9219,95.8866 C 34.9219,114.836 37.4688,129.324 42.4727,139.226 C 47.4063,148.976 54.5274,154.785 63.6638,156.73 C 65.6528,166.371 68.7538,172.886 72.9608,176.265 C 76.1368,178.824 80.3638,180.089 85.5858,180.089 C 85.6838,180.089 85.7848,180.089 85.8828,180.085 L 91.4218,180.085 C 88.0158,180.035 85.0388,179.425 82.5158,178.257 C 82.5158,178.257 82.5118,178.257 82.5078,178.253 z" style="fill:#006225;fill-rule:evenodd;stroke:none"/> -</g> -</g> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + height="44px" + version="1.1" + viewBox="0 0 44 44" + width="44px" + x="0px" + y="0px" + id="svg2" + inkscape:version="0.47 r22583" + sodipodi:docname="qt.svg"> + <metadata + id="metadata18"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs16"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 22 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="44 : 22 : 1" + inkscape:persp3d-origin="22 : 14.666667 : 1" + id="perspective2836" /> + </defs> + <sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1920" + inkscape:window-height="1020" + id="namedview14" + showgrid="false" + inkscape:zoom="21.454545" + inkscape:cx="49.412871" + inkscape:cy="21.894358" + inkscape:window-x="-4" + inkscape:window-y="-4" + inkscape:window-maximized="1" + inkscape:current-layer="g3" /> + <g + transform="matrix(0.18308778,0,0,0.18308778,6.6100946,3.2385199)" + id="g3"> + <path + d="M 43.09,0.3586 C 40.94,0.0036 38.84,-0.0824 36.81,0.0776 31.968136,0.39505671 27.122677,0.73638425 22.28,1.0696 9.62,2.0816 0,12.4996 0,26.8896 l 0,169.7 14.19,13.2 28.87,-209.42 0.03,-0.011 z" + style="fill:#006225" + id="path5" + sodipodi:nodetypes="cccccccc" /> + <path + d="m 174.4,160 c 0,12.5 -7.75,24.07 -17.57,25.77 L 14.23,209.73 V 25.93 C 14.23,9.21 27.57,-2.27 43.12,0.3 l 131.3,21.52 v 138.2 z" + style="fill:#80c342" + id="path7" /> + <path + d="m 154.9,80.96 -12.96,-0.598 0,0.278 6.945,0.32 6.016,0 z" + style="fill:#006225" + id="path11" /> + <path + d="m 144.6,135.6 c 0.66,0.328 1.43,0.476 2.351,0.476 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 h -6.015 c -1.821,0.832 -3.532,1.457 -5.176,1.848 z" + style="fill:#006225" + id="path13" /> + <path + id="path17" + style="fill:#ffffff" + d="m 91.15,132.4 c 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -4.34,0 -7.68,2.535 -10.01,7.625 -2.52,5.543 -3.793,17.04 -3.793,34.44 0,16.82 1.238,28.75 3.734,35.75 2.356,6.672 5.879,9.976 10.5,9.976 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 m 17.98,3.75 c -4.117,9.707 -10.39,16.06 -18.99,19 0.867,4.449 2.176,7.441 3.922,9.019 1.351,1.211 3.433,1.821 6.222,1.821 0.805,0 1.668,-0.055 2.59,-0.157 v 13.12 l -5.961,0.782 c -1.758,0.23 -3.426,0.343 -5.004,0.343 -5.218,0 -9.445,-1.265 -12.62,-3.824 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 1.629,0 3.309,0.102 5.043,0.305 11.95,1.375 20.62,7.016 26.26,16.79 5.535,9.562 8.254,23.27 8.254,41.26 0,16.48 -2,29.45 -6.043,39.02 z M 130.4,45.91 l 11.52,1.238 0,20.21 12.96,0.914 0,12.68 -12.96,-0.598 0,46.33 c 0,4.032 0.445,6.625 1.34,7.789 0.8,1.067 2.046,1.594 3.71,1.594 0.161,0 0.329,-0.004 0.497,-0.016 2.55,-0.148 5.32,-0.933 8.343,-2.308 v 11.65 c -5.136,2.258 -10.18,3.598 -15.12,4.02 -0.718,0.055 -1.41,0.086 -2.078,0.086 -4.48,0 -7.906,-1.301 -10.25,-3.934 -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.535 L 118.046,79.25 V 65.66 l 7.586,0.547 4.773,-20.3 z" /> + <path + d="m 100.3,166 c 0.809,0 1.672,-0.055 2.59,-0.157 H 98.054 C 98.73,165.949 99.507,166 100.3,166 z" + style="fill:#006225" + id="path19" /> + <path + id="path21" + style="fill:#006225" + d="m 84.85,63.98 c 2.336,5.997 3.484,16.92 3.484,32.81 0,17.7 -1.16,29.57 -3.512,35.62 -1.894,4.879 -4.527,7.902 -7.863,9.07 0.965,0.368 1.992,0.551 3.078,0.551 0.207,0 0.41,-0.008 0.621,-0.019 4.633,-0.293 8.121,-3.496 10.49,-9.602 2.351,-6.051 3.511,-17.91 3.511,-35.62 0,-15.89 -1.148,-26.82 -3.484,-32.81 -2.336,-6.027 -5.832,-9.281 -10.52,-9.691 -0.359,-0.031 -0.714,-0.051 -1.058,-0.051 -1.09,0 -2.117,0.16 -3.082,0.481 h -0.004 c 3.601,1.121 6.379,4.215 8.336,9.261 z m -2.344,114.3 c -0.113,-0.05 -0.227,-0.105 -0.336,-0.16 -0.012,-0.004 -0.023,-0.012 -0.035,-0.015 -0.102,-0.051 -0.207,-0.106 -0.309,-0.157 -0.019,-0.011 -0.039,-0.019 -0.058,-0.031 -0.09,-0.051 -0.184,-0.098 -0.278,-0.148 -0.027,-0.016 -0.054,-0.036 -0.086,-0.051 -0.082,-0.043 -0.164,-0.09 -0.242,-0.137 -0.039,-0.023 -0.078,-0.047 -0.113,-0.07 -0.07,-0.039 -0.145,-0.082 -0.215,-0.125 -0.047,-0.031 -0.094,-0.059 -0.14,-0.09 -0.059,-0.039 -0.118,-0.074 -0.176,-0.113 -0.059,-0.039 -0.114,-0.075 -0.168,-0.114 -0.051,-0.031 -0.102,-0.066 -0.149,-0.097 -0.066,-0.047 -0.132,-0.094 -0.195,-0.137 -0.039,-0.027 -0.078,-0.055 -0.113,-0.082 -0.078,-0.055 -0.153,-0.113 -0.231,-0.172 -0.023,-0.016 -0.05,-0.035 -0.078,-0.055 -0.098,-0.078 -0.199,-0.156 -0.297,-0.234 -4.207,-3.379 -7.308,-9.894 -9.297,-19.54 -9.136,-1.945 -16.26,-7.754 -21.19,-17.5 -5.004,-9.902 -7.551,-24.39 -7.551,-43.34 0,-20.43 3.484,-35.51 10.34,-45.07 5.789,-8.07 13.86,-12.04 24.02,-12.04 h -6.351 c -10.15,0.008 -18.22,3.977 -24,12.04 -6.855,9.563 -10.34,24.64 -10.34,45.07 0,18.95 2.547,33.44 7.551,43.34 4.934,9.75 12.05,15.56 21.19,17.5 1.989,9.641 5.09,16.16 9.297,19.54 3.176,2.559 7.403,3.824 12.62,3.824 0.098,0 0.199,0 0.297,-0.004 h 5.539 c -3.406,-0.05 -6.383,-0.66 -8.906,-1.828 L 82.498,178.28 z M 128.4,145.6 c -2.73,-3.051 -4.09,-7.949 -4.09,-14.67 V 79.57 l -6.226,-0.285 v -13.59 h -6.016 v 3.035 c 0.871,3.273 1.555,6.82 2.063,10.64 l 4.164,0.192 v 51.36 c 0,6.723 1.367,11.62 4.09,14.67 2.343,2.633 5.765,3.934 10.25,3.934 h 6.015 c -4.48,0 -7.906,-1.301 -10.25,-3.934 z m 2.043,-99.66 -6.016,0 -4.668,19.88 5.911,0.422 4.773,-20.3 z" /> + </g> </svg> diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 90c362b..d751134 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -11,21 +11,24 @@ symbian: { isEmpty(QT_LIBINFIX) { TARGET.UID3 = 0x2001E61C - - # sqlite3 is expected to be already found on phone if infixed configuration is built. - BLD_INF_RULES.prj_exports += \ - "sqlite3.sis $${EPOCROOT}epoc32/data/qt/sis/sqlite3.sis" \ - "sqlite3_selfsigned.sis $${EPOCROOT}epoc32/data/qt/sis/sqlite3_selfsigned.sis" - symbian-abld|symbian-sbsv2 { - sqlitedeployment = \ - "; Deploy sqlite onto phone that does not have it already" \ - "@\"$${EPOCROOT}epoc32/data/qt/sis/sqlite3.sis\", (0x2002af5f)" - } else { - sqlitedeployment = \ - "; Deploy sqlite onto phone that does not have it already" \ - "@\"$${PWD}/sqlite3.sis\", (0x2002af5f)" + + # Sqlite3 is expected to be already found on phone if infixed configuration is built. + # It is also expected that devices newer than those based on S60 5.0 all have sqlite3.dll. + contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { + BLD_INF_RULES.prj_exports += \ + "sqlite3.sis $${EPOCROOT}epoc32/data/qt/sis/sqlite3.sis" \ + "sqlite3_selfsigned.sis $${EPOCROOT}epoc32/data/qt/sis/sqlite3_selfsigned.sis" + symbian-abld|symbian-sbsv2 { + sqlitedeployment = \ + "; Deploy sqlite onto phone that does not have it already" \ + "@\"$${EPOCROOT}epoc32/data/qt/sis/sqlite3.sis\", (0x2002af5f)" + } else { + sqlitedeployment = \ + "; Deploy sqlite onto phone that does not have it already" \ + "@\"$${PWD}/sqlite3.sis\", (0x2002af5f)" + } + qtlibraries.pkg_postrules += sqlitedeployment } - qtlibraries.pkg_postrules += sqlitedeployment } else { # Always use experimental UID for infixed configuration to avoid UID clash TARGET.UID3 = 0xE001E61C @@ -81,12 +84,16 @@ symbian: { qtlibraries.pkg_prerules = vendorinfo qtlibraries.pkg_prerules += "; Dependencies of Qt libraries" - qtlibraries.pkg_prerules += "(0x20013851), 1, 5, 1, {\"PIPS Installer\"}" - contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) { - qtlibraries.pkg_prerules += "(0x200110CB), 1, 5, 1, {\"Open C LIBSSL Common\"}" - } - contains(CONFIG, stl) { - qtlibraries.pkg_prerules += "(0x2000F866), 1, 0, 0, {\"Standard C++ Library Common\"}" + + # It is expected that Symbian^3 and newer phones will have sufficiently new OpenC already installed + contains(S60_VERSION, 3.1)|contains(S60_VERSION, 3.2)|contains(S60_VERSION, 5.0) { + qtlibraries.pkg_prerules += "(0x20013851), 1, 5, 1, {\"PIPS Installer\"}" + contains(QT_CONFIG, openssl) | contains(QT_CONFIG, openssl-linked) { + qtlibraries.pkg_prerules += "(0x200110CB), 1, 5, 1, {\"Open C LIBSSL Common\"}" + } + contains(CONFIG, stl) { + qtlibraries.pkg_prerules += "(0x2000F866), 1, 0, 0, {\"Standard C++ Library Common\"}" + } } qtlibraries.pkg_prerules += "(0x2002af5f), 0, 5, 0, {\"sqlite3\"}" @@ -143,12 +150,39 @@ symbian: { contains(QT_CONFIG, declarative): { qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtDeclarative$${QT_LIBINFIX}.dll + + folderlistmodelImport.sources = $$QT_BUILD_TREE/imports/Qt/labs/folderlistmodel/qmlfolderlistmodelplugin$${QT_LIBINFIX}.dll + gesturesImport.sources = $$QT_BUILD_TREE/imports/Qt/labs/gestures/qmlgesturesplugin$${QT_LIBINFIX}.dll + particlesImport.sources = $$QT_BUILD_TREE/imports/Qt/labs/particles/qmlparticlesplugin$${QT_LIBINFIX}.dll + + folderlistmodelImport.sources += $$QT_SOURCE_TREE/src/imports/folderlistmodel/qmldir + gesturesImport.sources += $$QT_SOURCE_TREE/src/imports/gestures/qmldir + particlesImport.sources += $$QT_SOURCE_TREE/src/imports/particles/qmldir + + folderlistmodelImport.path = c:$$QT_IMPORTS_BASE_DIR/Qt/labs/folderlistmodel + gesturesImport.path = c:$$QT_IMPORTS_BASE_DIR/Qt/labs/gestures + particlesImport.path = c:$$QT_IMPORTS_BASE_DIR/Qt/labs/particles + + DEPLOYMENT += folderlistmodelImport gesturesImport particlesImport + + contains(QT_CONFIG, webkit): { + webkitImport.sources = $$QT_BUILD_TREE/imports/org/webkit/qmlwebkitplugin$${QT_LIBINFIX}.dll + webkitImport.sources += $$QT_SOURCE_TREE/src/imports/webkit/qmldir + webkitImport.path = c:$$QT_IMPORTS_BASE_DIR/org/webkit + DEPLOYMENT += webkitImport + } } graphicssystems_plugins.path = c:$$QT_PLUGINS_BASE_DIR/graphicssystems contains(QT_CONFIG, openvg) { qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtOpenVG$${QT_LIBINFIX}.dll graphicssystems_plugins.sources += $$QT_BUILD_TREE/plugins/graphicssystems/qvggraphicssystem$${QT_LIBINFIX}.dll + # OpenVG requires Symbian^3 or later + pkg_platform_dependencies -= \ + "[0x101F7961],0,0,0,{\"S60ProductID\"}" \ + "[0x102032BE],0,0,0,{\"S60ProductID\"}" \ + "[0x102752AE],0,0,0,{\"S60ProductID\"}" \ + "[0x1028315F],0,0,0,{\"S60ProductID\"}" } contains(QT_CONFIG, multimedia){ diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 86915bb..f02ea52 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -1525,7 +1525,7 @@ void QScriptEnginePrivate::detachAllRegisteredScriptStrings() #ifndef QT_NO_REGEXP -Q_DECL_IMPORT extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); +Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QRegExp ®exp) { @@ -2020,8 +2020,6 @@ QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, #ifndef QT_NO_REGEXP -Q_DECL_IMPORT extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); - /*! Creates a QtScript object of class RegExp with the given \a regexp. diff --git a/src/script/parser/qscriptlexer.cpp b/src/script/parser/qscriptlexer.cpp index ca64776..3ddc3aa 100644 --- a/src/script/parser/qscriptlexer.cpp +++ b/src/script/parser/qscriptlexer.cpp @@ -31,7 +31,7 @@ QT_BEGIN_NAMESPACE -Q_DECL_IMPORT extern double qstrtod(const char *s00, char const **se, bool *ok); +Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok); #define shiftWindowsLineBreak() \ do { \ diff --git a/src/sql/drivers/odbc/qsql_odbc.cpp b/src/sql/drivers/odbc/qsql_odbc.cpp index 6fd1725..9a35ac5 100644 --- a/src/sql/drivers/odbc/qsql_odbc.cpp +++ b/src/sql/drivers/odbc/qsql_odbc.cpp @@ -259,14 +259,14 @@ static QString qWarnODBCHandle(int handleType, SQLHANDLE handle, int *nativeCode static QString qODBCWarn(const QODBCPrivate* odbc, int *nativeCode = 0) { - return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->dpEnv()) + QLatin1Char(' ') + return QString(qWarnODBCHandle(SQL_HANDLE_ENV, odbc->dpEnv()) + QLatin1Char(' ') + qWarnODBCHandle(SQL_HANDLE_DBC, odbc->dpDbc()) + QLatin1Char(' ') + qWarnODBCHandle(SQL_HANDLE_STMT, odbc->hStmt, nativeCode)).simplified(); } static QString qODBCWarn(const QODBCDriverPrivate* odbc, int *nativeCode = 0) { - return (qWarnODBCHandle(SQL_HANDLE_ENV, odbc->hEnv) + QLatin1Char(' ') + return QString(qWarnODBCHandle(SQL_HANDLE_ENV, odbc->hEnv) + QLatin1Char(' ') + qWarnODBCHandle(SQL_HANDLE_DBC, odbc->hDbc, nativeCode)).simplified(); } diff --git a/src/src.pro b/src/src.pro index 5436c4a..3ac69be 100644 --- a/src/src.pro +++ b/src/src.pro @@ -84,7 +84,7 @@ src_declarative.subdir = $$QT_SOURCE_TREE/src/declarative src_declarative.target = sub-declarative #CONFIG += ordered -!wince*:!ordered { +!wince*:!ordered:!symbian-abld:!symbian-sbsv2 { src_corelib.depends = src_tools_moc src_tools_rcc src_gui.depends = src_corelib src_tools_uic embedded: src_gui.depends += src_network diff --git a/src/svg/qgraphicssvgitem.cpp b/src/svg/qgraphicssvgitem.cpp index 69ff7a3..e035e1d 100644 --- a/src/svg/qgraphicssvgitem.cpp +++ b/src/svg/qgraphicssvgitem.cpp @@ -124,8 +124,10 @@ public: \snippet doc/src/snippets/code/src_svg_qgraphicssvgitem.cpp 0 - Size of the item can be set via the setSize() method or via - direct manipulation of the items transformation matrix. + Size of the item can be set via the \l{QRectF::setSize()} + {setSize()} method of the \l{QGraphicsSvgItem::boundingRect()} + {bounding rectangle} or via direct manipulation of the items + transformation matrix. By default the SVG rendering is cached using QGraphicsItem::DeviceCoordinateCache mode to speedup the display of items. Caching can be disabled by passing diff --git a/src/xmlpatterns/data/qdecimal_p.h b/src/xmlpatterns/data/qdecimal_p.h index d17b647..2a5e0b3 100644 --- a/src/xmlpatterns/data/qdecimal_p.h +++ b/src/xmlpatterns/data/qdecimal_p.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE /** * Defined in QtCore's qlocale.cpp. */ -Q_DECL_IMPORT extern char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp); +Q_CORE_EXPORT char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp); namespace QPatternist { |