diff options
author | Morten Sorvig <msorvig@trolltech.com> | 2009-09-03 10:19:11 (GMT) |
---|---|---|
committer | Morten Sorvig <msorvig@trolltech.com> | 2009-09-03 10:19:11 (GMT) |
commit | 75078d7b20155ba192b88ec54008e07d1ee44676 (patch) | |
tree | e170f474aaed28d2476dc2d134f3be27e76c3741 | |
parent | 0dcf114697309f3f23f9717b608fa2be1813fe94 (diff) | |
parent | f55a2e6b2b3d97e74c3368552a6fba412d86e0b9 (diff) | |
download | Qt-75078d7b20155ba192b88ec54008e07d1ee44676.zip Qt-75078d7b20155ba192b88ec54008e07d1ee44676.tar.gz Qt-75078d7b20155ba192b88ec54008e07d1ee44676.tar.bz2 |
Merge branch '4.6' of scm.dev.nokia.troll.no:qt/qt into 4.6
34 files changed, 757 insertions, 163 deletions
diff --git a/bin/patch_capabilities.pl b/bin/patch_capabilities.pl index ca80891..cf8353e 100644 --- a/bin/patch_capabilities.pl +++ b/bin/patch_capabilities.pl @@ -26,17 +26,26 @@ if (@ARGV) # Parse the first given script argument as a ".pkg" file name. my $pkgFileName = shift(@ARGV); - # Check if using template .pkg and do preprocessing if needed + # These variables will only be set for template .pkg files. + my $target; + my $platform; + + # Check if using template .pkg and set target/platform variables if (($pkgFileName =~ m|_template\.pkg$|i) && -r($pkgFileName)) { - my $target; - unless ($target = shift(@ARGV)) + my $targetplatform; + unless ($targetplatform = shift(@ARGV)) { Usage(); } - system ("createpackage.bat -p ".$pkgFileName." ".$target); - $pkgFileName =~ s/_template\.pkg/_${target}\.pkg/; + my @tmpvalues = split('-', $targetplatform); + $target = $tmpvalues[0]; + $platform = $tmpvalues[1]; + + # Convert visual target to real target (debug->udeb and release->urel) + $target =~ s/debug/udeb/i; + $target =~ s/release/urel/i; } # If the specified ".pkg" file exists (and can be read), @@ -80,8 +89,16 @@ if (@ARGV) my $destinationPath = $2; # If the given file is a binary, check the target and binary type (+ the actual filename) from its path. - if ($sourcePath =~ m:/epoc32/release/([^/]+)/(udeb|urel)/(\w+(\.dll|\.exe)):i) + if ($sourcePath =~ m:/epoc32/release/([^/]+)/(udeb|urel|\$\(TARGET\))/(\w+(\.dll|\.exe)):i) { + # Do preprocessing for template pkg, + # In case of template pkg target and platform variables are set + if(length($target) && length($platform)) + { + $sourcePath =~ s/\$\(PLATFORM\)/$platform/gm; + $sourcePath =~ s/\$\(TARGET\)/$target/gm; + } + push (@binaries, $sourcePath); } } diff --git a/doc/src/s60-introduction.qdoc b/doc/src/s60-introduction.qdoc index 53ad562..0fd3a30 100644 --- a/doc/src/s60-introduction.qdoc +++ b/doc/src/s60-introduction.qdoc @@ -90,7 +90,7 @@ \row \o \c debug-armv5 \o Build debug binaries for hardware using RVCT. \row \o \c release-armv5 \o Build release binaries for hardware using RVCT. \row \o \c run \o Run the emulator binaries from the build directory. - \row \o \c sisx \o Create signed \c .sis file for project. + \row \o \c sis \o Create signed \c .sis file for project. \endtable The following lines perform a debug build for the emulator @@ -104,9 +104,9 @@ \section1 Installing your own applications To install your own applications on hardware, you need signed \c .sis file. - The signed \c .sis file can be created with \c make \c sisx target. \c sisx target + The signed \c .sis file can be created with \c make \c sis target. \c sis target is only supported for executables or projects with \c DEPLOYMENT statements. - By default the \c sisx target will create signed \.sis file for last build + By default the \c sis target will create signed \.sis file for last build target. For example, the following sequence will generate the needed makefiles, build the project for \c debug-winscw and \c release-armv5, and create self-signed \c .sis file for \c release-armv5 target: @@ -118,18 +118,18 @@ shown in the table below: \table - \row \o \c QT_SISX_OPTIONS \o Options accepted by \c .sis creation. + \row \o \c QT_SIS_OPTIONS \o Options accepted by \c .sis creation. Currently only -i, install the package right away using PC suite, is supported. By default no otions are given. - \row \o \c QT_SISX_TARGET \o Target for which \c .sis file is created. + \row \o \c QT_SIS_TARGET \o Target for which \c .sis file is created. Accepted values are build targets listed in previous table. By default last build target. - \row \o \c QT_SISX_CERTIFICATE \o The certificate file used for signing. + \row \o \c QT_SIS_CERTIFICATE \o The certificate file used for signing. By default self-signed certificate. - \row \o \c QT_SISX_KEY \o The certificate's private key file. + \row \o \c QT_SIS_KEY \o The certificate's private key file. By default key is associated to self-signed certificate. - \row \o \c QT_SISX_PASSPHRASE \o The certificate's private key file's passphrase. + \row \o \c QT_SIS_PASSPHRASE \o The certificate's private key file's passphrase. By default empty. \endtable @@ -142,8 +142,8 @@ \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 4 If you want to install the program immediately, make sure that the device - is connected to the computer in "PC Suite" mode, and run \c sisx target - with the \c QT_SISX_OPTIONS=-i, like this: + is connected to the computer in "PC Suite" mode, and run \c sis target + with the \c QT_SIS_OPTIONS=-i, like this: \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 5 */ diff --git a/doc/src/snippets/code/doc_src_installation.qdoc b/doc/src/snippets/code/doc_src_installation.qdoc index e84e188..e294c12 100644 --- a/doc/src/snippets/code/doc_src_installation.qdoc +++ b/doc/src/snippets/code/doc_src_installation.qdoc @@ -197,10 +197,10 @@ make release-armv5 //! [29] cd src\s60installs -make sisx QT_SISX_OPTIONS=-i QT_SISX_CERTIFICATE=<certificate file> QT_SISX_KEY=<certificate key file> +make sis QT_SIS_OPTIONS=-i QT_SIS_CERTIFICATE=<certificate file> QT_SIS_KEY=<certificate key file> //! [29] //! [30] cd embedded\fluidlauncher -make sisx QT_SISX_OPTIONS=-i +make sis QT_SIS_OPTIONS=-i //! [30] diff --git a/doc/src/snippets/code/doc_src_s60-introduction.qdoc b/doc/src/snippets/code/doc_src_s60-introduction.qdoc index fa9fd45..09ea359 100644 --- a/doc/src/snippets/code/doc_src_s60-introduction.qdoc +++ b/doc/src/snippets/code/doc_src_s60-introduction.qdoc @@ -10,19 +10,19 @@ //! [2] qmake make debug-winscw release-armv5 - make sisx + make sis //! [2] //! [3] - make sisx QT_SISX_TARGET=debug-armv5 + make sis QT_SIS_TARGET=debug-armv5 //! [3] //! [4] - set QT_SISX_TARGET=debug-armv5 - make sisx + set QT_SIS_TARGET=debug-armv5 + make sis //! [4] //! [5] - set QT_SISX_OPTIONS=-i - make sisx + set QT_SIS_OPTIONS=-i + make sis //! [5]
\ No newline at end of file diff --git a/examples/gestures/imageviewer/imagewidget.cpp b/examples/gestures/imageviewer/imagewidget.cpp index 7dbd084..c71c461 100644 --- a/examples/gestures/imageviewer/imagewidget.cpp +++ b/examples/gestures/imageviewer/imagewidget.cpp @@ -123,8 +123,10 @@ void ImageWidget::panTriggered() void ImageWidget::pinchTriggered() { QPinchGesture *pg = qobject_cast<QPinchGesture*>(sender()); - rotationAngle += pg->rotationAngle(); - scaleFactor += pg->scaleFactor(); + if (pg->whatChanged() & QPinchGesture::RotationAngleChanged) + rotationAngle += pg->rotationAngle() - pg->lastRotationAngle(); + if (pg->whatChanged() & QPinchGesture::ScaleFactorChanged) + scaleFactor += pg->scaleFactor() - pg->lastScaleFactor(); update(); } diff --git a/mkspecs/symbian-sbsv2/flm/qt/qmake_store_build.flm b/mkspecs/symbian-sbsv2/flm/qt/qmake_store_build.flm index 96eb189..0abc7c4 100644 --- a/mkspecs/symbian-sbsv2/flm/qt/qmake_store_build.flm +++ b/mkspecs/symbian-sbsv2/flm/qt/qmake_store_build.flm @@ -27,10 +27,10 @@ $(STORE_BUILD_TARGET): echo "# Name : .make.cache" >> $(CACHE_FILENAME) && \ echo "# Part of : " >> $(CACHE_FILENAME) && \ echo "# Description : This file is used to cache last build target for" >> $(CACHE_FILENAME) && \ - echo "# make sisx target." >> $(CACHE_FILENAME) && \ + echo "# make sis target." >> $(CACHE_FILENAME) && \ echo "# Version : " >> $(CACHE_FILENAME) && \ echo "# ==============================================================================" >> $(CACHE_FILENAME) && \ - echo QT_SISX_TARGET ?= $(VISUAL_CFG)-$(PLATFORM_PATH) >> $(CACHE_FILENAME) \ + echo QT_SIS_TARGET ?= $(VISUAL_CFG)-$(PLATFORM_PATH) >> $(CACHE_FILENAME) \ $(call endrule,qmake_store_build) endef diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index 519b2ed..9ddd378 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -72,10 +72,10 @@ #define MMP_TARGETTYPE "TARGETTYPE" #define MMP_SECUREID "SECUREID" -#define SISX_TARGET "sisx" -#define OK_SISX_TARGET "ok_sisx" -#define FAIL_SISX_NOPKG_TARGET "fail_sisx_nopkg" -#define FAIL_SISX_NOCACHE_TARGET "fail_sisx_nocache" +#define SIS_TARGET "sis" +#define OK_SIS_TARGET "ok_sis" +#define FAIL_SIS_NOPKG_TARGET "fail_sis_nopkg" +#define FAIL_SIS_NOCACHE_TARGET "fail_sis_nocache" #define RESTORE_BUILD_TARGET "restore_build" #define PRINT_FILE_CREATE_ERROR(filename) fprintf(stderr, "Error: Could not create '%s'\n", qPrintable(filename)); @@ -329,7 +329,7 @@ void SymbianMakefileGenerator::generatePkgFile(const QString &iconFile) t << ":\"Vendor\"" << endl << endl; } - // PKG pre-rules - these are added before actual file installations i.e. SISX package body + // PKG pre-rules - these are added before actual file installations i.e. SIS package body if (rawPkgPreRules.size()) { t << "; Manual PKG pre-rules from PRO files" << endl; foreach(QString item, rawPkgPreRules) { @@ -1632,36 +1632,36 @@ void SymbianMakefileGenerator::removeSpecialCharacters(QString& str) str.replace(QString(" "), QString("_")); } -void SymbianMakefileGenerator::writeSisxTargets(QTextStream &t) +void SymbianMakefileGenerator::writeSisTargets(QTextStream &t) { - t << SISX_TARGET ": " RESTORE_BUILD_TARGET << endl; - QString sisxcommand = QString("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \ + t << SIS_TARGET ": " RESTORE_BUILD_TARGET << endl; + QString siscommand = QString("\t$(if $(wildcard %1_template.%2),$(if $(wildcard %3)," \ "$(MAKE) -s -f $(MAKEFILE) %4,$(MAKE) -s -f $(MAKEFILE) %5)," \ "$(MAKE) -s -f $(MAKEFILE) %6)") .arg(fixedTarget) .arg("pkg") .arg(MAKE_CACHE_NAME) - .arg(OK_SISX_TARGET) - .arg(FAIL_SISX_NOCACHE_TARGET) - .arg(FAIL_SISX_NOPKG_TARGET); - t << sisxcommand << endl; + .arg(OK_SIS_TARGET) + .arg(FAIL_SIS_NOCACHE_TARGET) + .arg(FAIL_SIS_NOPKG_TARGET); + t << siscommand << endl; t << endl; - t << OK_SISX_TARGET ":" << endl; + t << OK_SIS_TARGET ":" << endl; - QString pkgcommand = QString("\tcreatepackage.bat $(QT_SISX_OPTIONS) %1_template.%2 $(QT_SISX_TARGET) " \ - "$(QT_SISX_CERTIFICATE) $(QT_SISX_KEY) $(QT_SISX_PASSPHRASE)") + QString pkgcommand = QString("\tcreatepackage.bat $(QT_SIS_OPTIONS) %1_template.%2 $(QT_SIS_TARGET) " \ + "$(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)") .arg(fixedTarget) .arg("pkg"); t << pkgcommand << endl; t << endl; - t << FAIL_SISX_NOPKG_TARGET ":" << endl; - t << "\t$(error PKG file does not exist, 'SISX' target is only supported for executables or projects with DEPLOYMENT statement)" << endl; + t << FAIL_SIS_NOPKG_TARGET ":" << endl; + t << "\t$(error PKG file does not exist, 'SIS' target is only supported for executables or projects with DEPLOYMENT statement)" << endl; t << endl; - t << FAIL_SISX_NOCACHE_TARGET ":" << endl; - t << "\t$(error Project has to be build before calling 'SISX' target)" << endl; + t << FAIL_SIS_NOCACHE_TARGET ":" << endl; + t << "\t$(error Project has to be build before calling 'SIS' target)" << endl; t << endl; diff --git a/qmake/generators/symbian/symmake.h b/qmake/generators/symbian/symmake.h index b0ca5a3..0e5eb14 100644 --- a/qmake/generators/symbian/symmake.h +++ b/qmake/generators/symbian/symmake.h @@ -137,7 +137,7 @@ protected: const QString& itemPrefix, const QString& itemSuffix); - void writeSisxTargets(QTextStream &t); + void writeSisTargets(QTextStream &t); void generateDistcleanTargets(QTextStream& t); // Subclass implements diff --git a/qmake/generators/symbian/symmake_abld.cpp b/qmake/generators/symbian/symmake_abld.cpp index 31ef312..bf98079 100644 --- a/qmake/generators/symbian/symmake_abld.cpp +++ b/qmake/generators/symbian/symmake_abld.cpp @@ -153,7 +153,7 @@ void SymbianAbldMakefileGenerator::writeMkFile(const QString& wrapperFileName, b QString makefile(Option::fixPathToTargetOS(fileInfo(wrapperFileName).canonicalFilePath())); foreach(QString target, wrapperTargets) { t << target << " : " << makefile << endl; - t << "\t-$(MAKE) -f \"" << makefile << "\" " << target << " QT_SISX_TARGET=$(VISUAL_CFG)-$(PLATFORM)" << endl << endl; + t << "\t-$(MAKE) -f \"" << makefile << "\" " << target << " QT_SIS_TARGET=$(VISUAL_CFG)-$(PLATFORM)" << endl << endl; } t << endl; @@ -361,7 +361,7 @@ void SymbianAbldMakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool writeDeploymentTargets(t); - writeSisxTargets(t); + writeSisTargets(t); writeStoreBuildTarget(t); @@ -428,12 +428,12 @@ void SymbianAbldMakefileGenerator::writeStoreBuildTarget(QTextStream &t) t << "\t@echo # Name : " << MAKE_CACHE_NAME << " >> " MAKE_CACHE_NAME << endl; t << "\t@echo # Part of : " << project->values("TARGET").join(" ") << " >> " MAKE_CACHE_NAME << endl; t << "\t@echo # Description : This file is used to cache last build target for >> " MAKE_CACHE_NAME << endl; - t << "\t@echo # make sisx target. >> " MAKE_CACHE_NAME << endl; + t << "\t@echo # make sis target. >> " MAKE_CACHE_NAME << endl; t << "\t@echo # Version : >> " MAKE_CACHE_NAME << endl; t << "\t@echo # >> " MAKE_CACHE_NAME << endl; t << "\t@echo # ============================================================================== >> " MAKE_CACHE_NAME << endl; t << "\t@echo. >> " MAKE_CACHE_NAME << endl; - t << "\t@echo QT_SISX_TARGET ?= $(QT_SISX_TARGET) >> " MAKE_CACHE_NAME << endl; + t << "\t@echo QT_SIS_TARGET ?= $(QT_SIS_TARGET) >> " MAKE_CACHE_NAME << endl; t << endl; generatedFiles << MAKE_CACHE_NAME; diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index a76d959..a1381c6 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -216,7 +216,7 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo qDeleteAll(subtargets); } - writeSisxTargets(t); + writeSisTargets(t); generateDistcleanTargets(t); diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index a6f5907..dd17061 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -501,6 +501,8 @@ public: WA_WState_AcceptedTouchBeginEvent = 122, WA_TouchPadAcceptSingleTouchEvents = 123, + WA_DontUseStandardGestures = 124, + // Add new attributes before this line WA_AttributeCount }; diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 1a0b3e6..06eea68 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -1222,6 +1222,8 @@ \value WA_TouchPadAcceptSingleTouchEvents Allows touchpad single touch events to be sent to the widget. + \value WA_DontUseStandardGestures Disables standard gestures on Qt widgets. + \omitvalue WA_SetLayoutDirection \omitvalue WA_InputMethodTransparent \omitvalue WA_WState_CompressKeys diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 5ff0716..a5ed95c 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -89,7 +89,8 @@ typedef INT_PTR intptr_t; # define INVALID_FILE_ATTRIBUTES (DWORD (-1)) #endif -#if !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) && !defined(Q_OS_WINCE) +#if !defined(Q_OS_WINCE) +# if !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) typedef struct _REPARSE_DATA_BUFFER { ULONG ReparseTag; USHORT ReparseDataLength; @@ -115,8 +116,9 @@ typedef struct _REPARSE_DATA_BUFFER { } GenericReparseBuffer; }; } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; +# define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) +# endif // !defined(REPARSE_DATA_BUFFER_HEADER_SIZE) -# define REPARSE_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_DATA_BUFFER, GenericReparseBuffer) # ifndef MAXIMUM_REPARSE_DATA_BUFFER_SIZE # define MAXIMUM_REPARSE_DATA_BUFFER_SIZE 16384 # endif @@ -126,7 +128,7 @@ typedef struct _REPARSE_DATA_BUFFER { # ifndef FSCTL_GET_REPARSE_POINT # define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 42, METHOD_BUFFERED, FILE_ANY_ACCESS) # endif -#endif +#endif // !defined(Q_OS_WINCE) QT_BEGIN_NAMESPACE diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index bd37f68..7831893 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -241,15 +241,18 @@ void QGesture::updateState(Qt::GestureState state) return; } const Qt::GestureState oldState = d->state; - d->state = state; if (state != Qt::NoGesture && oldState > state) { // comparing the state as ints: state should only be changed from // started to (optionally) updated and to finished. + d->state = state; qWarning("QGesture::updateState: incorrect new state"); return; } - if (oldState == Qt::NoGesture) + if (oldState == Qt::NoGesture) { + d->state = Qt::GestureStarted; emit started(); + } + d->state = state; if (state == Qt::GestureUpdated) emit triggered(); else if (state == Qt::GestureFinished) diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index 2cfabef..ddca79e 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -70,7 +70,7 @@ class QGesturePrivate : public QObjectPrivate public: QGesturePrivate() : gestureTarget(0), graphicsItem(0), eventFilterProxyGraphicsItem(0), - state(Qt::NoGesture) + state(Qt::NoGesture), implicitGesture(false) { } @@ -81,6 +81,9 @@ public: QGraphicsItem *eventFilterProxyGraphicsItem; Qt::GestureState state; + + // the flag specifies if the gesture was created implicitely by Qt. + bool implicitGesture; }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index cc30049..8e76715 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -47,6 +47,7 @@ #include <private/qapplication_p.h> #include <private/qevent_p.h> #include <private/qwidget_p.h> +#include <qmath.h> QT_BEGIN_NAMESPACE @@ -90,9 +91,12 @@ QPanGesture::QPanGesture(QWidget *gestureTarget, QObject *parent) void QPanGesturePrivate::setupGestureTarget(QObject *newGestureTarget) { Q_Q(QPanGesture); + QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); + if (gestureTarget && gestureTarget->isWidgetType()) { QWidget *w = static_cast<QWidget*>(gestureTarget.data()); - QApplicationPrivate::instance()->widgetGestures[w].pan = 0; + if (qAppPriv->widgetGestures[w].pan == q) + qAppPriv->widgetGestures[w].pan = 0; #if defined(Q_WS_WIN) qt_widget_private(w)->winSetupGestures(); #elif defined(Q_WS_MAC) @@ -103,7 +107,7 @@ void QPanGesturePrivate::setupGestureTarget(QObject *newGestureTarget) if (newGestureTarget && newGestureTarget->isWidgetType()) { QWidget *w = static_cast<QWidget*>(newGestureTarget); - QApplicationPrivate::instance()->widgetGestures[w].pan = q; + qAppPriv->widgetGestures[w].pan = q; #if defined(Q_WS_WIN) qt_widget_private(w)->winSetupGestures(); #elif defined(Q_WS_MAC) @@ -133,8 +137,13 @@ bool QPanGesture::event(QEvent *event) bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) { -#ifdef Q_WS_WIN Q_D(QPanGesture); + + if (d->implicitGesture && d->gestureTarget && d->gestureTarget->isWidgetType() && + static_cast<QWidget*>(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures)) + return false; + +#ifdef Q_WS_WIN if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) { QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event); QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); @@ -164,11 +173,12 @@ bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) return false; } if (state() == Qt::NoGesture) { - d->lastOffset = d->totalOffset = QSize(); + d->lastOffset = d->totalOffset = d->offset = QSize(); } else { - d->lastOffset = QSize(ev->position.x() - d->lastPosition.x(), - ev->position.y() - d->lastPosition.y()); - d->totalOffset += d->lastOffset; + d->lastOffset = d->offset; + d->offset = QSize(ev->position.x() - d->lastPosition.x(), + ev->position.y() - d->lastPosition.y()); + d->totalOffset += d->offset; } d->lastPosition = ev->position; updateState(nextState); @@ -181,23 +191,29 @@ bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) /*! \internal */ bool QPanGesture::filterEvent(QEvent *event) { -#if defined(Q_WS_WIN) Q_D(QPanGesture); + + if (d->implicitGesture && d->gestureTarget && d->gestureTarget->isWidgetType() && + static_cast<QWidget*>(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures)) + return false; + +#if defined(Q_WS_WIN) const QTouchEvent *ev = static_cast<const QTouchEvent*>(event); if (event->type() == QEvent::TouchBegin) { QTouchEvent::TouchPoint p = ev->touchPoints().at(0); d->lastPosition = p.pos().toPoint(); - d->lastOffset = d->totalOffset = QSize(); + d->lastOffset = d->totalOffset = d->offset = QSize(); } else if (event->type() == QEvent::TouchEnd) { if (state() != Qt::NoGesture) { if (ev->touchPoints().size() == 2) { QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0); QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1); - d->lastOffset = + d->lastOffset = d->offset; + d->offset = QSize(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(), p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2; - d->totalOffset += d->lastOffset; + d->totalOffset += d->offset; } updateState(Qt::GestureFinished); } @@ -206,10 +222,11 @@ bool QPanGesture::filterEvent(QEvent *event) if (ev->touchPoints().size() == 2) { QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0); QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1); - d->lastOffset = + d->lastOffset = d->offset; + d->offset = QSize(p1.pos().x() - p1.lastPos().x() + p2.pos().x() - p2.lastPos().x(), p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2; - d->totalOffset += d->lastOffset; + d->totalOffset += d->offset; if (d->totalOffset.width() > 10 || d->totalOffset.height() > 10 || d->totalOffset.width() < -10 || d->totalOffset.height() < -10) { updateState(Qt::GestureUpdated); @@ -219,7 +236,6 @@ bool QPanGesture::filterEvent(QEvent *event) #elif defined(QT_MAC_USE_COCOA) // The following implements single touch // panning on Mac: - Q_D(QPanGesture); const int panBeginDelay = 300; const int panBeginRadius = 3; const QTouchEvent *ev = static_cast<const QTouchEvent*>(event); @@ -252,8 +268,9 @@ bool QPanGesture::filterEvent(QEvent *event) QPointF mousePos = QCursor::pos(); QPointF dist = mousePos - d->lastPosition; d->lastPosition = mousePos; - d->lastOffset = QSizeF(dist.x(), dist.y()); - d->totalOffset += d->lastOffset; + d->lastOffset = d->offset; + d->offset = QSizeF(dist.x(), dist.y()); + d->totalOffset += d->offset; updateState(Qt::GestureUpdated); } } else if (state() == Qt::NoGesture) { @@ -273,7 +290,7 @@ bool QPanGesture::filterEvent(QEvent *event) void QPanGesture::reset() { Q_D(QPanGesture); - d->lastOffset = d->totalOffset = QSize(0, 0); + d->lastOffset = d->totalOffset = d->offset = QSize(0, 0); d->lastPosition = QPoint(0, 0); #if defined(QT_MAC_USE_COCOA) @@ -298,8 +315,7 @@ QSizeF QPanGesture::totalOffset() const /*! \property QPanGesture::lastOffset - Specifies a pan offset since the last time the gesture was - triggered. + Specifies a pan offset the last time the gesture was triggered. */ QSizeF QPanGesture::lastOffset() const { @@ -307,6 +323,18 @@ QSizeF QPanGesture::lastOffset() const return d->lastOffset; } +/*! + \property QPanGesture::offset + + Specifies the current pan offset since the last time the gesture was + triggered. +*/ +QSizeF QPanGesture::offset() const +{ + Q_D(const QPanGesture); + return d->offset; +} + ////////////////////////////////////////////////////////////////////////////// /*! @@ -360,8 +388,13 @@ bool QPinchGesture::event(QEvent *event) bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) { -#if defined(Q_WS_WIN) || defined(Q_WS_MAC) Q_D(QPinchGesture); + + if (d->implicitGesture && d->gestureTarget && d->gestureTarget->isWidgetType() && + static_cast<QWidget*>(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures)) + return false; + +#if defined(Q_WS_WIN) || defined(Q_WS_MAC) if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) { QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event); #if defined(Q_WS_WIN) @@ -380,39 +413,80 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) // next we might receive the first gesture update event, so we // prepare for it. d->state = Qt::NoGesture; - d->scaleFactor = d->lastScaleFactor = 1; - d->rotationAngle = d->lastRotationAngle = 0; + d->changes = 0; + d->totalScaleFactor = d->scaleFactor = d->lastScaleFactor = 1.; + d->totalRotationAngle = d->rotationAngle = d->lastRotationAngle = 0.; d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPointF(); #if defined(Q_WS_WIN) d->initialDistance = 0; + d->lastSequenceId = ev->sequenceId; #endif return false; - case QNativeGestureEvent::Rotate: - d->scaleFactor = 0; + case QNativeGestureEvent::Rotate: { + d->lastScaleFactor = d->scaleFactor; d->lastRotationAngle = d->rotationAngle; -#if defined(Q_WS_WIN) - d->rotationAngle = -1 * GID_ROTATE_ANGLE_FROM_ARGUMENT(ev->argument); -#elif defined(Q_WS_MAC) - d->rotationAngle = ev->percentage; -#endif +#if defined(Q_WS_MAC) + d->rotationAngle += ev->percentage; nextState = Qt::GestureUpdated; +#elif defined(Q_WS_WIN) + // This is a workaround for an issue with the native rotation + // gesture on Windows 7. For some reason the rotation angle in the + // first WM_GESTURE message in a sequence contains value that is + // off a little bit and causes the rotating item to "jump", so + // we just ignore the first WM_GESTURE in every sequence. + bool windowsRotateWorkaround = false; + if (!d->lastSequenceId) { + windowsRotateWorkaround = true; + d->lastSequenceId = ev->sequenceId; + } + if (d->lastSequenceId > 0 && d->lastSequenceId != (ulong)-1 && ev->sequenceId != d->lastSequenceId) { + // this is the first WM_GESTURE message in a sequence. + d->totalRotationAngle += d->rotationAngle; + windowsRotateWorkaround = true; + // a magic value to mark that the next WM_GESTURE message is + // the second message in a sequence and we should clear the + // lastRotationAngle + d->lastSequenceId = (ulong)-1; + } + if (!windowsRotateWorkaround) { + d->rotationAngle = -1 * GID_ROTATE_ANGLE_FROM_ARGUMENT(ev->argument) * 180. / M_PI; + if (d->lastSequenceId == (ulong)-1) { + // a special case since we need to set the lastRotationAngle to + // rotationAngle when the first WM_GESTURE is received in each + // sequence. + d->lastRotationAngle = d->rotationAngle; + } + d->lastSequenceId = ev->sequenceId; + } + if (!windowsRotateWorkaround) + nextState = Qt::GestureUpdated; +#endif + d->changes = QPinchGesture::RotationAngleChanged; event->accept(); break; + } case QNativeGestureEvent::Zoom: - d->rotationAngle = 0; + d->lastRotationAngle = d->rotationAngle; + d->lastScaleFactor = d->scaleFactor; #if defined(Q_WS_WIN) if (d->initialDistance != 0) { - d->lastScaleFactor = d->scaleFactor; int distance = int(qint64(ev->argument)); - d->scaleFactor = (qreal) distance / d->initialDistance; + if (d->lastSequenceId && ev->sequenceId != d->lastSequenceId) { + d->totalScaleFactor *= d->scaleFactor; + d->initialDistance = int(qint64(ev->argument)); + d->lastScaleFactor = d->scaleFactor = (qreal) distance / d->initialDistance; + } else { + d->scaleFactor = (qreal) distance / d->initialDistance; + } + d->lastSequenceId = ev->sequenceId; } else { d->initialDistance = int(qint64(ev->argument)); } #elif defined(Q_WS_MAC) - d->lastScaleFactor = d->scaleFactor; - d->scaleFactor = ev->percentage; + d->scaleFactor += ev->percentage; #endif nextState = Qt::GestureUpdated; + d->changes = QPinchGesture::ScaleFactorChanged; event->accept(); break; case QNativeGestureEvent::GestureEnd: @@ -427,6 +501,8 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) d->startCenterPoint = d->centerPoint; d->lastCenterPoint = d->centerPoint; d->centerPoint = static_cast<QWidget*>(receiver)->mapFromGlobal(ev->position); + if (d->lastCenterPoint != d->centerPoint) + d->changes |= QPinchGesture::CenterPointChanged; updateState(nextState); return true; } @@ -438,6 +514,12 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) /*! \internal */ bool QPinchGesture::filterEvent(QEvent *event) { + Q_D(QPinchGesture); + + if (d->implicitGesture && d->gestureTarget && d->gestureTarget->isWidgetType() && + static_cast<QWidget*>(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures)) + return false; + Q_UNUSED(event); return false; } @@ -446,16 +528,44 @@ bool QPinchGesture::filterEvent(QEvent *event) void QPinchGesture::reset() { Q_D(QPinchGesture); - d->scaleFactor = d->lastScaleFactor = 0; - d->rotationAngle = d->lastRotationAngle = 0; + d->changes = 0; + d->totalScaleFactor = d->scaleFactor = d->lastScaleFactor = 1.; + d->totalRotationAngle = d->rotationAngle = d->lastRotationAngle = 0.; d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPointF(); QGesture::reset(); } /*! + \property QPinchGesture::whatChanged + + Specifies which values were changed in the gesture. +*/ +QPinchGesture::WhatChanged QPinchGesture::whatChanged() const +{ + return d_func()->changes; +} + +/*! + \property QPinchGesture::totalScaleFactor + + Specifies a total scale factor of the pinch gesture since the gesture + started. +*/ +qreal QPinchGesture::totalScaleFactor() const +{ + Q_D(const QPinchGesture); + return d->totalScaleFactor * d->scaleFactor; +} + +/*! \property QPinchGesture::scaleFactor Specifies a scale factor of the pinch gesture. + + If the gesture consists of several pinch sequences (i.e. zoom and rotate + sequences), then this property specifies the scale factor in the current + sequence. When pinching changes the rotation angle only, the value of this + property is 1. */ qreal QPinchGesture::scaleFactor() const { @@ -473,9 +583,29 @@ qreal QPinchGesture::lastScaleFactor() const } /*! + \property QPinchGesture::totalRotationAngle + + Specifies a total rotation angle of the gesture since the gesture started. + + The angle is specified in degrees. +*/ +qreal QPinchGesture::totalRotationAngle() const +{ + Q_D(const QPinchGesture); + return d->totalRotationAngle + d->rotationAngle; +} + +/*! \property QPinchGesture::rotationAngle Specifies a rotation angle of the gesture. + + If the gesture consists of several pinch sequences (i.e. zoom and rotate + sequences), then this property specifies the rotation angle in the current + sequence. When pinching changes the scale factor only, the value of this + property is 0. + + The angle is specified in degrees. */ qreal QPinchGesture::rotationAngle() const { @@ -486,6 +616,8 @@ qreal QPinchGesture::rotationAngle() const \property QPinchGesture::lastRotationAngle Specifies a previous rotation angle of the gesture. + + The angle is specified in degrees. */ qreal QPinchGesture::lastRotationAngle() const { diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h index bb6f3b6..53c4416 100644 --- a/src/gui/kernel/qstandardgestures.h +++ b/src/gui/kernel/qstandardgestures.h @@ -61,6 +61,7 @@ class Q_GUI_EXPORT QPanGesture : public QGesture Q_PROPERTY(QSizeF totalOffset READ totalOffset) Q_PROPERTY(QSizeF lastOffset READ lastOffset) + Q_PROPERTY(QSizeF offset READ offset) public: QPanGesture(QWidget *gestureTarget, QObject *parent = 0); @@ -69,6 +70,7 @@ public: QSizeF totalOffset() const; QSizeF lastOffset() const; + QSizeF offset() const; protected: void reset(); @@ -78,6 +80,7 @@ private: bool eventFilter(QObject *receiver, QEvent *event); friend class QWidget; + friend class QAbstractScrollAreaPrivate; }; class QPinchGesturePrivate; @@ -86,31 +89,48 @@ class Q_GUI_EXPORT QPinchGesture : public QGesture Q_OBJECT Q_DECLARE_PRIVATE(QPinchGesture) - Q_PROPERTY(qreal scaleFactor READ scaleFactor) +public: + enum WhatChange { + ScaleFactorChanged = 0x1, + RotationAngleChanged = 0x2, + CenterPointChanged = 0x4 + }; + Q_DECLARE_FLAGS(WhatChanged, WhatChange) + + Q_PROPERTY(WhatChanged whatChanged READ whatChanged) + + Q_PROPERTY(qreal totalScaleFactor READ totalScaleFactor) Q_PROPERTY(qreal lastScaleFactor READ lastScaleFactor) + Q_PROPERTY(qreal scaleFactor READ scaleFactor) - Q_PROPERTY(qreal rotationAngle READ rotationAngle) + Q_PROPERTY(qreal totalRotationAngle READ totalRotationAngle) Q_PROPERTY(qreal lastRotationAngle READ lastRotationAngle) + Q_PROPERTY(qreal rotationAngle READ rotationAngle) Q_PROPERTY(QPointF startCenterPoint READ startCenterPoint) Q_PROPERTY(QPointF lastCenterPoint READ lastCenterPoint) Q_PROPERTY(QPointF centerPoint READ centerPoint) public: + QPinchGesture(QWidget *gestureTarget, QObject *parent = 0); bool filterEvent(QEvent *event); void reset(); + WhatChanged whatChanged() const; + QPointF startCenterPoint() const; QPointF lastCenterPoint() const; QPointF centerPoint() const; - qreal scaleFactor() const; + qreal totalScaleFactor() const; qreal lastScaleFactor() const; + qreal scaleFactor() const; - qreal rotationAngle() const; + qreal totalRotationAngle() const; qreal lastRotationAngle() const; + qreal rotationAngle() const; private: bool event(QEvent *event); diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index 270f307..354ebee 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -74,6 +74,7 @@ public: QSizeF totalOffset; QSizeF lastOffset; + QSizeF offset; QPointF lastPosition; #if defined(QT_MAC_USE_COCOA) @@ -88,25 +89,32 @@ class QPinchGesturePrivate : public QGesturePrivate public: QPinchGesturePrivate() - : scaleFactor(0), lastScaleFactor(0), - rotationAngle(0), lastRotationAngle(0) + : changes(0), totalScaleFactor(0.), lastScaleFactor(0.), scaleFactor(0.), + totalRotationAngle(0.), lastRotationAngle(0.), rotationAngle(0.) #ifdef Q_WS_WIN - ,initialDistance(0) + ,initialDistance(0), lastSequenceId(0) #endif { } void setupGestureTarget(QObject *o); - qreal scaleFactor; + QPinchGesture::WhatChanged changes; + + qreal totalScaleFactor; // total scale factor, excluding the current sequence. qreal lastScaleFactor; - qreal rotationAngle; + qreal scaleFactor; // scale factor in the current sequence. + + qreal totalRotationAngle; // total rotation angle, excluding the current sequence. qreal lastRotationAngle; + qreal rotationAngle; // rotation angle in the current sequence. + QPointF startCenterPoint; QPointF lastCenterPoint; QPointF centerPoint; #ifdef Q_WS_WIN int initialDistance; + ulong lastSequenceId; #endif }; diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 863c43e..44f9db1 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -82,8 +82,6 @@ #include "private/qstyle_p.h" #include "private/qinputcontext_p.h" #include "qfileinfo.h" -#include "qstandardgestures.h" -#include "qstandardgestures_p.h" #if defined (Q_WS_WIN) # include <private/qwininputcontext_p.h> diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index 8e60fb3..0ec7e7e 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -2062,29 +2062,21 @@ void QWidgetPrivate::registerTouchWindow() void QWidgetPrivate::winSetupGestures() { Q_Q(QWidget); - if (!q) - return; - if (!q->isVisible()) + if (!q || !q->isVisible()) return; QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); - bool needh = false; - bool needv = false; - bool singleFingerPanEnabled = false; QApplicationPrivate::WidgetStandardGesturesMap::const_iterator it = qAppPriv->widgetGestures.find(q); if (it == qAppPriv->widgetGestures.end()) return; const QStandardGestures &gestures = it.value(); - WId winid = 0; + WId winid = q->effectiveWinId(); - if (QAbstractScrollArea *asa = qobject_cast<QAbstractScrollArea*>(q)) { - winid = asa->viewport()->internalWinId(); - if (!winid) { - QWidget *nativeParent = asa->viewport()->nativeParentWidget(); - if (!nativeParent) - return; - winid = nativeParent->internalWinId(); - } + bool needh = false; + bool needv = false; + bool singleFingerPanEnabled = false; + + if (QAbstractScrollArea *asa = qobject_cast<QAbstractScrollArea*>(q->parent())) { QScrollBar *hbar = asa->horizontalScrollBar(); QScrollBar *vbar = asa->verticalScrollBar(); Qt::ScrollBarPolicy hbarpolicy = asa->horizontalScrollBarPolicy(); @@ -2094,12 +2086,6 @@ void QWidgetPrivate::winSetupGestures() needv = (vbarpolicy == Qt::ScrollBarAlwaysOn || (vbarpolicy == Qt::ScrollBarAsNeeded && vbar->minimum() < vbar->maximum())); singleFingerPanEnabled = asa->d_func()->singleFingerPanEnabled; - } else { - winid = q->internalWinId(); - if (!winid) { - if (QWidget *nativeParent = q->nativeParentWidget()) - winid = nativeParent->internalWinId(); - } } if (winid && qAppPriv->SetGestureConfig) { GESTURECONFIG gc[3]; diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index d82e7ee..ed400df 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -7542,9 +7542,10 @@ void qt_format_text(const QFont &fnt, const QRectF &_r, if (!painter) tf |= Qt::TextDontPrint; - uint maxUnderlines = 0; + int maxUnderlines = 0; int numUnderlines = 0; - QVarLengthArray<int, 32> underlinePositions(1); + int underlinePositionStack[32]; + int *underlinePositions = underlinePositionStack; QFontMetricsF fm(fnt); QString text = str; @@ -7553,46 +7554,54 @@ start_lengthVariant: bool hasMoreLengthVariants = false; // compatible behaviour to the old implementation. Replace // tabs by spaces + QChar *chr = text.data() + offset; + QChar *end = text.data() + text.length(); bool has_tab = false; - int old_offset = offset; - for (; offset < text.length(); offset++) { - QChar chr = text.at(offset); - if (chr == QLatin1Char('\r') || (singleline && chr == QLatin1Char('\n'))) { - text[offset] = QLatin1Char(' '); - } else if (chr == QLatin1Char('\n')) { - chr = QChar::LineSeparator; - } else if (chr == QLatin1Char('&')) { + while (chr != end) { + if (*chr == QLatin1Char('\r') || (singleline && *chr == QLatin1Char('\n'))) { + *chr = QLatin1Char(' '); + } else if (*chr == QLatin1Char('\n')) { + *chr = QChar::LineSeparator; + } else if (*chr == QLatin1Char('&')) { ++maxUnderlines; - } else if (chr == QLatin1Char('\t')) { - if (!expandtabs) { - text[offset] = QLatin1Char(' '); - } else if (!tabarraylen && !tabstops) { - tabstops = qRound(fm.width(QLatin1Char('x'))*8); - } + } else if (*chr == QLatin1Char('\t')) { has_tab = true; - } else if (chr == QChar(ushort(0x9c))) { + } else if (*chr == QChar(ushort(0x9c))) { // string with multiple length variants + end = chr; hasMoreLengthVariants = true; break; } + ++chr; + } + if (has_tab) { + if (!expandtabs) { + chr = text.data() + offset; + while (chr != end) { + if (*chr == QLatin1Char('\t')) + *chr = QLatin1Char(' '); + ++chr; + } + } else if (!tabarraylen && !tabstops) { + tabstops = qRound(fm.width(QLatin1Char('x'))*8); + } } - int length = offset - old_offset; - if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) { - underlinePositions.resize(maxUnderlines + 1); - - QChar *cout = text.data() + old_offset; + QChar *cout = end; + if (hidemnmemonic || showmnemonic) { + if (maxUnderlines > 32) + underlinePositions = new int[maxUnderlines]; + cout = text.data() + offset; QChar *cin = cout; - int l = length; + int l = end - cout; while (l) { if (*cin == QLatin1Char('&')) { ++cin; - --length; --l; if (!l) break; if (*cin != QLatin1Char('&') && !hidemnmemonic) - underlinePositions[numUnderlines++] = cout - text.data() - old_offset; + underlinePositions[numUnderlines++] = cout - text.unicode(); } *cout = *cin; ++cout; @@ -7609,7 +7618,7 @@ start_lengthVariant: qreal height = 0; qreal width = 0; - QString finalText = text.mid(old_offset, length); + QString finalText = text.mid(offset, cout - (text.data() + offset)); QStackTextEngine engine(finalText, fnt); if (option) { engine.option = *option; @@ -7628,7 +7637,7 @@ start_lengthVariant: engine.forceJustification = true; QTextLayout textLayout(&engine); textLayout.setCacheEnabled(true); - textLayout.engine()->underlinePositions = underlinePositions.data(); + textLayout.engine()->underlinePositions = underlinePositions; if (finalText.isEmpty()) { height = fm.height(); @@ -7697,7 +7706,7 @@ start_lengthVariant: QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height); if (hasMoreLengthVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) { - offset++; + offset = end - text.data() + 1; goto start_lengthVariant; } if (brect) @@ -7726,6 +7735,9 @@ start_lengthVariant: painter->restore(); } } + + if (underlinePositions != underlinePositionStack) + delete [] underlinePositions; } /*! diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 770e769..6de7c10 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -54,6 +54,7 @@ #ifdef Q_WS_WIN #include "qstandardgestures.h" +#include <private/qstandardgestures_p.h> #endif #include "qabstractscrollarea_p.h" @@ -299,8 +300,11 @@ void QAbstractScrollAreaPrivate::init() layoutChildren(); #ifdef Q_WS_WIN - panGesture = new QPanGesture(viewport); + panGesture = new QPanGesture(viewport, q); + panGesture->d_func()->implicitGesture = true; + QObject::connect(panGesture, SIGNAL(started()), q, SLOT(_q_gestureTriggered())); QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered())); + QObject::connect(panGesture, SIGNAL(finished()), q, SLOT(_q_gestureTriggered())); #endif // Q_WS_WIN } diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index c79e482..085341c 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -794,10 +794,6 @@ void QPlainTextEditPrivate::init(const QString &txt) viewport->setCursor(Qt::IBeamCursor); #endif originalOffsetY = 0; -#ifdef Q_WS_WIN - panGesture = new QPanGesture(q); - QObject::connect(panGesture, SIGNAL(triggered()), q, SLOT(_q_gestureTriggered())); -#endif } void QPlainTextEditPrivate::_q_repaintContents(const QRectF &contentsRect) diff --git a/src/gui/widgets/qplaintextedit_p.h b/src/gui/widgets/qplaintextedit_p.h index 7ff0c03..cda1d92 100644 --- a/src/gui/widgets/qplaintextedit_p.h +++ b/src/gui/widgets/qplaintextedit_p.h @@ -182,7 +182,6 @@ public: #ifdef Q_WS_WIN void _q_gestureTriggered(); - QPanGesture *panGesture; #endif }; diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index 547a4fb..cc79464 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -67,8 +67,6 @@ #include <qtexttable.h> #include <qvariant.h> -#include <qstandardgestures.h> - #include <qinputcontext.h> #endif diff --git a/src/script/api/qscriptstring.cpp b/src/script/api/qscriptstring.cpp index 8c818e1..94b69b9 100644 --- a/src/script/api/qscriptstring.cpp +++ b/src/script/api/qscriptstring.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include "config.h" // compile on Windows #include "qscriptstring.h" #include "qscriptstring_p.h" #include "qscriptengine.h" diff --git a/tests/manual/gestures/pinch/main.cpp b/tests/manual/gestures/pinch/main.cpp new file mode 100644 index 0000000..0e5b928 --- /dev/null +++ b/tests/manual/gestures/pinch/main.cpp @@ -0,0 +1,68 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> +#include "pinchwidget.h" + +class MainWindow : public QWidget +{ +public: + MainWindow(); +}; + +MainWindow::MainWindow() +{ + QVBoxLayout *l = new QVBoxLayout(this); + QPushButton *btn = new QPushButton(QLatin1String("AcceptTouchEvents")); + l->addWidget(btn); + QImage image(":/images/qt-logo.png"); + PinchWidget *w = new PinchWidget(image); + l->addWidget(w); + connect(btn, SIGNAL(clicked()), w, SLOT(acceptTouchEvents())); +} + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + MainWindow w; + w.show(); + return app.exec(); +} diff --git a/tests/manual/gestures/pinch/pinch.pro b/tests/manual/gestures/pinch/pinch.pro new file mode 100644 index 0000000..d1f28cc --- /dev/null +++ b/tests/manual/gestures/pinch/pinch.pro @@ -0,0 +1,4 @@ +SOURCES = main.cpp \ + pinchwidget.cpp +HEADERS += pinchwidget.h +RESOURCES += pinch.qrc diff --git a/tests/manual/gestures/pinch/pinch.qrc b/tests/manual/gestures/pinch/pinch.qrc new file mode 100644 index 0000000..0be9ba1 --- /dev/null +++ b/tests/manual/gestures/pinch/pinch.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource prefix="/images" > + <file>qt-logo.png</file> + </qresource> +</RCC> diff --git a/tests/manual/gestures/pinch/pinchwidget.cpp b/tests/manual/gestures/pinch/pinchwidget.cpp new file mode 100644 index 0000000..cc16443 --- /dev/null +++ b/tests/manual/gestures/pinch/pinchwidget.cpp @@ -0,0 +1,118 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "pinchwidget.h" + +#include <QPainter> +#include <QImage> +#include <QPixmap> +#include <QPanGesture> +#include <QPinchGesture> +#include <QPushButton> + +PinchWidget::PinchWidget(const QImage &image, QWidget *parent) + : QWidget(parent) +{ + setMinimumSize(100,100); + this->image = image; + pan = new QPanGesture(this); + connect(pan, SIGNAL(triggered()), this, SLOT(onPanTriggered())); + connect(pan, SIGNAL(finished()), this, SLOT(onPanFinished())); + pinch = new QPinchGesture(this); + connect(pinch, SIGNAL(triggered()), this, SLOT(onPinchTriggered())); + connect(pinch, SIGNAL(finished()), this, SLOT(onPinchFinished())); +} + +QSize PinchWidget::sizeHint() const +{ + return image.size()*1.5; +} + +void PinchWidget::paintEvent(QPaintEvent *) +{ + QPainter p(this); + QTransform t = worldTransform * currentPanTransform * currentPinchTransform; + p.setTransform(t); + QPoint center = QPoint(width()/2, height()/2); + QPoint size = QPoint(image.width()/2, image.height()/2); + p.translate(center - size); + p.drawImage(QPoint(0,0), image); +} + +void PinchWidget::acceptTouchEvents() +{ + setAttribute(Qt::WA_AcceptTouchEvents); + if (QWidget *w = qobject_cast<QPushButton*>(sender())) + w->setEnabled(false); +} + +void PinchWidget::onPanTriggered() +{ + currentPanTransform = QTransform() + .translate(pan->totalOffset().width(), + pan->totalOffset().height()); + update(); +} + +void PinchWidget::onPanFinished() +{ + worldTransform *= currentPanTransform; + currentPanTransform.reset(); + update(); +} + +void PinchWidget::onPinchTriggered() +{ + QPoint transformCenter = worldTransform.map(QPoint(width()/2, height()/2)); + currentPinchTransform = QTransform() + .translate(transformCenter.x(), transformCenter.y()) + .scale(pinch->totalScaleFactor(), pinch->totalScaleFactor()) + .rotate(pinch->totalRotationAngle()) + .translate(-transformCenter.x(), -transformCenter.y()); + update(); +} + +void PinchWidget::onPinchFinished() +{ + worldTransform *= currentPinchTransform; + currentPinchTransform.reset(); + update(); +} diff --git a/tests/manual/gestures/pinch/pinchwidget.h b/tests/manual/gestures/pinch/pinchwidget.h new file mode 100644 index 0000000..a76e287 --- /dev/null +++ b/tests/manual/gestures/pinch/pinchwidget.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PINCHWIDGET_H +#define PINCHWIDGET_H + +#include <QWidget> +#include <QTransform> + +class QPanGesture; +class QPinchGesture; + +class PinchWidget : public QWidget +{ + Q_OBJECT +public: + PinchWidget(const QImage &image, QWidget *parent = 0); + +private Q_SLOTS: + void acceptTouchEvents(); + void onPanTriggered(); + void onPanFinished(); + void onPinchTriggered(); + void onPinchFinished(); + +private: + void paintEvent(QPaintEvent *); + QSize sizeHint() const; + + QImage image; + + QPanGesture *pan; + QPinchGesture *pinch; + + QTransform worldTransform; + QTransform currentPanTransform; + QTransform currentPinchTransform; +}; + +#endif // PINCHWIDGET_H diff --git a/tests/manual/gestures/pinch/qt-logo.png b/tests/manual/gestures/pinch/qt-logo.png Binary files differnew file mode 100644 index 0000000..7d3e97e --- /dev/null +++ b/tests/manual/gestures/pinch/qt-logo.png diff --git a/tests/manual/gestures/twopanwidgets/main.cpp b/tests/manual/gestures/twopanwidgets/main.cpp new file mode 100644 index 0000000..7750d1d --- /dev/null +++ b/tests/manual/gestures/twopanwidgets/main.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> + +static const char text[] = + "Hello world! This is just a lot of text with to make sure scrollbar appear"; + +class TextEdit : public QTextEdit +{ + Q_OBJECT +public Q_SLOTS: + void acceptTouch() + { + viewport()->setAttribute(Qt::WA_AcceptTouchEvents); + if (QWidget *w = qobject_cast<QPushButton*>(sender())) + w->setEnabled(false); + } +}; + +class PlainTextEdit : public QPlainTextEdit +{ + Q_OBJECT +public Q_SLOTS: + void acceptTouch() + { + viewport()->setAttribute(Qt::WA_AcceptTouchEvents); + if (QWidget *w = qobject_cast<QPushButton*>(sender())) + w->setEnabled(false); + } +}; + +class MainWindow : public QMainWindow +{ +public: + MainWindow(); +}; + +MainWindow::MainWindow() +{ + QTabWidget *tw = new QTabWidget; + setCentralWidget(tw); + { + QWidget *tab = new QWidget; + QGridLayout *layout = new QGridLayout(tab); + QTextEdit *edit1 = new TextEdit; + QTextEdit *edit2 = new TextEdit; + QString text1 = QString(text).replace(' ', '\n'); + for (int i = 0; i < 5; ++i) text1 += text1; + QString text2 = QString(text); + for (int i = 0; i < 5; ++i) text2 += text2; + edit1->setPlainText(text1); + edit2->setPlainText(text2); + edit2->setWordWrapMode(QTextOption::NoWrap); + QPushButton *btn1 = new QPushButton(QLatin1String("AcceptTouchEvents")); + connect(btn1, SIGNAL(clicked()), edit1, SLOT(acceptTouch())); + QPushButton *btn2 = new QPushButton(QLatin1String("AcceptTouchEvents")); + connect(btn2, SIGNAL(clicked()), edit2, SLOT(acceptTouch())); + layout->addWidget(btn1, 0, 0); + layout->addWidget(btn2, 0, 1); + layout->addWidget(edit1, 1, 0); + layout->addWidget(edit2, 1, 1); + tw->addTab(tab, QLatin1String("QTextEdit")); + } + { + QWidget *tab = new QWidget; + QGridLayout *layout = new QGridLayout(tab); + QPlainTextEdit *edit1 = new PlainTextEdit; + QPlainTextEdit *edit2 = new PlainTextEdit; + QString text1 = QString(text).replace(' ', '\n'); + for (int i = 0; i < 5; ++i) text1 += text1; + QString text2 = QString(text); + for (int i = 0; i < 5; ++i) text2 += text2; + edit1->setPlainText(text1); + edit2->setPlainText(text2); + edit2->setWordWrapMode(QTextOption::NoWrap); + QPushButton *btn1 = new QPushButton(QLatin1String("AcceptTouchEvents")); + connect(btn1, SIGNAL(clicked()), edit1, SLOT(acceptTouch())); + QPushButton *btn2 = new QPushButton(QLatin1String("AcceptTouchEvents")); + connect(btn2, SIGNAL(clicked()), edit2, SLOT(acceptTouch())); + layout->addWidget(btn1, 0, 0); + layout->addWidget(btn2, 0, 1); + layout->addWidget(edit1, 1, 0); + layout->addWidget(edit2, 1, 1); + tw->addTab(tab, QLatin1String("QPlainTextEdit")); + } +} + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + MainWindow window; + window.show(); + return app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/gestures/twopanwidgets/twopanwidgets.pro b/tests/manual/gestures/twopanwidgets/twopanwidgets.pro new file mode 100644 index 0000000..5254077 --- /dev/null +++ b/tests/manual/gestures/twopanwidgets/twopanwidgets.pro @@ -0,0 +1 @@ +SOURCES = main.cpp
\ No newline at end of file |