From 0a3ae605065c879493e17c83164b6770bd874532 Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Thu, 3 Sep 2009 11:35:17 +0300 Subject: Fixed patch_capabilites to patch also template pkg UID. Reviewed-by: Miikka Heikkinen --- bin/patch_capabilities.pl | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 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); } } -- cgit v0.12 From c810859ac54eaa3cba8f0a860659e763eadefeef Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Thu, 3 Sep 2009 12:29:15 +0300 Subject: Renamed make 'sisx' target to 'sis' and QT_SISX_* variables to QT_SIS_* Renaming done based feedback. Reviewed-by: TrustMe --- doc/src/s60-introduction.qdoc | 20 ++++++------ doc/src/snippets/code/doc_src_installation.qdoc | 4 +-- .../snippets/code/doc_src_s60-introduction.qdoc | 12 +++---- mkspecs/symbian-sbsv2/flm/qt/qmake_store_build.flm | 4 +-- qmake/generators/symbian/symmake.cpp | 38 +++++++++++----------- qmake/generators/symbian/symmake.h | 2 +- qmake/generators/symbian/symmake_abld.cpp | 8 ++--- qmake/generators/symbian/symmake_sbsv2.cpp | 2 +- 8 files changed, 45 insertions(+), 45 deletions(-) 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= QT_SISX_KEY= +make sis QT_SIS_OPTIONS=-i QT_SIS_CERTIFICATE= QT_SIS_KEY= //! [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/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); -- cgit v0.12 From 9f455fc7088a059899fa8346f34d6b96e908fea6 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Thu, 27 Aug 2009 13:22:23 +0200 Subject: Added simple manualtests for gestures Reviewed-by: trustme --- src/gui/kernel/qstandardgestures.cpp | 20 +++ tests/manual/gestures/pinch/main.cpp | 68 +++++++++++ tests/manual/gestures/pinch/pinch.pro | 4 + tests/manual/gestures/pinch/pinch.qrc | 5 + tests/manual/gestures/pinch/pinchwidget.cpp | 118 ++++++++++++++++++ tests/manual/gestures/pinch/pinchwidget.h | 78 ++++++++++++ tests/manual/gestures/pinch/qt-logo.png | Bin 0 -> 13923 bytes tests/manual/gestures/twopanwidgets/main.cpp | 135 +++++++++++++++++++++ .../gestures/twopanwidgets/twopanwidgets.pro | 1 + 9 files changed, 429 insertions(+) create mode 100644 tests/manual/gestures/pinch/main.cpp create mode 100644 tests/manual/gestures/pinch/pinch.pro create mode 100644 tests/manual/gestures/pinch/pinch.qrc create mode 100644 tests/manual/gestures/pinch/pinchwidget.cpp create mode 100644 tests/manual/gestures/pinch/pinchwidget.h create mode 100644 tests/manual/gestures/pinch/qt-logo.png create mode 100644 tests/manual/gestures/twopanwidgets/main.cpp create mode 100644 tests/manual/gestures/twopanwidgets/twopanwidgets.pro diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index cc30049..4e0c27f 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -87,6 +87,16 @@ QPanGesture::QPanGesture(QWidget *gestureTarget, QObject *parent) setObjectName(QLatin1String("QPanGesture")); } +/*! + \internal + An internal constructor to mark the gesture implicitely created by Qt. +*/ +QPanGesture::QPanGesture(QWidget *gestureTarget, QObject *parent, void*) + : QGesture(*new QPanGesturePrivate, gestureTarget, parent) +{ + setObjectName(QLatin1String("QPanGesture")); +} + void QPanGesturePrivate::setupGestureTarget(QObject *newGestureTarget) { Q_Q(QPanGesture); @@ -331,6 +341,16 @@ QPinchGesture::QPinchGesture(QWidget *gestureTarget, QObject *parent) setObjectName(QLatin1String("QPinchGesture")); } +/*! + \internal + An internal constructor to mark the gesture implicitely created by Qt. +*/ +QPinchGesture::QPinchGesture(QWidget *gestureTarget, QObject *parent, void*) + : QGesture(*new QPinchGesturePrivate, gestureTarget, parent) +{ + setObjectName(QLatin1String("QPinchGesture")); +} + void QPinchGesturePrivate::setupGestureTarget(QObject *newGestureTarget) { Q_Q(QPinchGesture); 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 +#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 @@ + + + qt-logo.png + + diff --git a/tests/manual/gestures/pinch/pinchwidget.cpp b/tests/manual/gestures/pinch/pinchwidget.cpp new file mode 100644 index 0000000..aa11f8d --- /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 +#include +#include +#include +#include +#include + +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(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->scaleFactor(), pinch->scaleFactor()) + .rotateRadians(pinch->rotationAngle()) + .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 +#include + +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 new file mode 100644 index 0000000..7d3e97e Binary files /dev/null and b/tests/manual/gestures/pinch/qt-logo.png differ 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 + +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(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(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 -- cgit v0.12 From 0d5b6dccf5fa854632e61971364629b36e0d3857 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 1 Sep 2009 11:08:57 +0200 Subject: Fixed the QGesture::updateState function. When a state changes from NoGesture to any valid gesture state and we emit the started() signal, we need to make sure that the state of the gesture is set to the appropriate Qt::GestureStarted state. Reviewed-by: trustme --- src/gui/kernel/qgesture.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) 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) -- cgit v0.12 From a1a0ea71d8861e2b794f2f9b55447d50fc520de3 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 1 Sep 2009 11:10:53 +0200 Subject: Improved the gesture api. Added a new widget attribute Qt::WA_DontUseStandardGestures that disables all implicit gestures (i.e. gestures that are automatically enabled by Qt itself). This change also changes the way gestures are handled on QAbstractScrollArea-based widgets on Windows - the gestures are supposed to be created on the viewport widget. Reviewed-by: Bradley T. Hughes --- src/corelib/global/qnamespace.h | 2 ++ src/corelib/global/qnamespace.qdoc | 2 ++ src/gui/kernel/qgesture_p.h | 5 ++- src/gui/kernel/qstandardgestures.cpp | 55 +++++++++++++++++---------------- src/gui/kernel/qstandardgestures.h | 1 + src/gui/kernel/qwidget.cpp | 2 -- src/gui/kernel/qwidget_win.cpp | 28 +++++------------ src/gui/widgets/qabstractscrollarea.cpp | 6 +++- src/gui/widgets/qplaintextedit.cpp | 4 --- src/gui/widgets/qplaintextedit_p.h | 1 - src/gui/widgets/qtextedit.cpp | 2 -- 11 files changed, 50 insertions(+), 58 deletions(-) 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/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 4e0c27f..f6534d1 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -87,22 +87,15 @@ QPanGesture::QPanGesture(QWidget *gestureTarget, QObject *parent) setObjectName(QLatin1String("QPanGesture")); } -/*! - \internal - An internal constructor to mark the gesture implicitely created by Qt. -*/ -QPanGesture::QPanGesture(QWidget *gestureTarget, QObject *parent, void*) - : QGesture(*new QPanGesturePrivate, gestureTarget, parent) -{ - setObjectName(QLatin1String("QPanGesture")); -} - void QPanGesturePrivate::setupGestureTarget(QObject *newGestureTarget) { Q_Q(QPanGesture); + QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); + if (gestureTarget && gestureTarget->isWidgetType()) { QWidget *w = static_cast(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) @@ -113,7 +106,7 @@ void QPanGesturePrivate::setupGestureTarget(QObject *newGestureTarget) if (newGestureTarget && newGestureTarget->isWidgetType()) { QWidget *w = static_cast(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) @@ -143,8 +136,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(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures)) + return false; + +#ifdef Q_WS_WIN if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) { QNativeGestureEvent *ev = static_cast(event); QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); @@ -191,8 +189,13 @@ 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(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures)) + return false; + +#if defined(Q_WS_WIN) const QTouchEvent *ev = static_cast(event); if (event->type() == QEvent::TouchBegin) { @@ -229,7 +232,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(event); @@ -341,16 +343,6 @@ QPinchGesture::QPinchGesture(QWidget *gestureTarget, QObject *parent) setObjectName(QLatin1String("QPinchGesture")); } -/*! - \internal - An internal constructor to mark the gesture implicitely created by Qt. -*/ -QPinchGesture::QPinchGesture(QWidget *gestureTarget, QObject *parent, void*) - : QGesture(*new QPinchGesturePrivate, gestureTarget, parent) -{ - setObjectName(QLatin1String("QPinchGesture")); -} - void QPinchGesturePrivate::setupGestureTarget(QObject *newGestureTarget) { Q_Q(QPinchGesture); @@ -380,8 +372,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(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(event); #if defined(Q_WS_WIN) @@ -458,6 +455,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(d->gestureTarget.data())->testAttribute(Qt::WA_DontUseStandardGestures)) + return false; + Q_UNUSED(event); return false; } diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h index bb6f3b6..33166fe 100644 --- a/src/gui/kernel/qstandardgestures.h +++ b/src/gui/kernel/qstandardgestures.h @@ -78,6 +78,7 @@ private: bool eventFilter(QObject *receiver, QEvent *event); friend class QWidget; + friend class QAbstractScrollAreaPrivate; }; class QPinchGesturePrivate; 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 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(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(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/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 #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 #include -#include - #include #endif -- cgit v0.12 From 466bc1ed4bf0c466e54732b2f8f7a16a34b716a8 Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Tue, 1 Sep 2009 14:25:42 +0200 Subject: Improved the gesture api. Made properties in QPanGesture and QPinchGesture more consistent - all of them have value, lastValue and totalValue. Documented that totalValue means the value from the beginning of the gesture, while the 'value' - from the beginning of the current sequence. This is especially useful on Windows when you zoom with two fingers and then release one finger and touch again to continue zooming. Also added a workaround for native Rotate gesture on Windows which contain a 'bad' value in the first WM_GESTURE message in every gesture sequence. Reviewed-by: Bradley T. Hughes --- examples/gestures/imageviewer/imagewidget.cpp | 6 +- src/gui/kernel/qstandardgestures.cpp | 153 +++++++++++++++++++++----- src/gui/kernel/qstandardgestures.h | 14 ++- src/gui/kernel/qstandardgestures_p.h | 16 ++- tests/manual/gestures/pinch/pinchwidget.cpp | 4 +- 5 files changed, 150 insertions(+), 43 deletions(-) diff --git a/examples/gestures/imageviewer/imagewidget.cpp b/examples/gestures/imageviewer/imagewidget.cpp index 7dbd084..a4ea238 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(sender()); - rotationAngle += pg->rotationAngle(); - scaleFactor += pg->scaleFactor(); + if (pg->rotationAngle() != 0.0) + rotationAngle += pg->rotationAngle() - pg->lastRotationAngle(); + if (pg->scaleFactor() != 1.0) + scaleFactor += pg->scaleFactor() - pg->lastScaleFactor(); update(); } diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index f6534d1..783c1d3 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -47,6 +47,7 @@ #include #include #include +#include QT_BEGIN_NAMESPACE @@ -172,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); @@ -201,16 +203,17 @@ bool QPanGesture::filterEvent(QEvent *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); } @@ -219,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); @@ -264,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) { @@ -285,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) @@ -310,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 { @@ -319,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; +} + ////////////////////////////////////////////////////////////////////////////// /*! @@ -397,37 +413,75 @@ 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->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 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; event->accept(); @@ -469,16 +523,33 @@ bool QPinchGesture::filterEvent(QEvent *event) void QPinchGesture::reset() { Q_D(QPinchGesture); - d->scaleFactor = d->lastScaleFactor = 0; - d->rotationAngle = d->lastRotationAngle = 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::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 { @@ -496,9 +567,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 { @@ -509,6 +600,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 33166fe..c6dfa92 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(); @@ -87,11 +89,13 @@ class Q_GUI_EXPORT QPinchGesture : public QGesture Q_OBJECT Q_DECLARE_PRIVATE(QPinchGesture) - Q_PROPERTY(qreal scaleFactor READ scaleFactor) + 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) @@ -107,11 +111,13 @@ public: 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..9e23515 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,30 @@ class QPinchGesturePrivate : public QGesturePrivate public: QPinchGesturePrivate() - : scaleFactor(0), lastScaleFactor(0), - rotationAngle(0), lastRotationAngle(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; + 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/tests/manual/gestures/pinch/pinchwidget.cpp b/tests/manual/gestures/pinch/pinchwidget.cpp index aa11f8d..cc16443 100644 --- a/tests/manual/gestures/pinch/pinchwidget.cpp +++ b/tests/manual/gestures/pinch/pinchwidget.cpp @@ -104,8 +104,8 @@ void PinchWidget::onPinchTriggered() QPoint transformCenter = worldTransform.map(QPoint(width()/2, height()/2)); currentPinchTransform = QTransform() .translate(transformCenter.x(), transformCenter.y()) - .scale(pinch->scaleFactor(), pinch->scaleFactor()) - .rotateRadians(pinch->rotationAngle()) + .scale(pinch->totalScaleFactor(), pinch->totalScaleFactor()) + .rotate(pinch->totalRotationAngle()) .translate(-transformCenter.x(), -transformCenter.y()); update(); } -- cgit v0.12 From 70f5d838e42b6c34a28de54b5294d18b11529c8a Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 2 Sep 2009 17:59:11 +0200 Subject: Added a property to QPinchGesture to specify what exactly changed. Added QPinchGesture::whatChanged() which specifies which property in the pinch gesture changed - the scale factor or rotation angle or both. Reviewed-by: Bradley T. Hughes --- examples/gestures/imageviewer/imagewidget.cpp | 4 ++-- src/gui/kernel/qstandardgestures.cpp | 16 ++++++++++++++++ src/gui/kernel/qstandardgestures.h | 13 +++++++++++++ src/gui/kernel/qstandardgestures_p.h | 4 +++- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/examples/gestures/imageviewer/imagewidget.cpp b/examples/gestures/imageviewer/imagewidget.cpp index a4ea238..c71c461 100644 --- a/examples/gestures/imageviewer/imagewidget.cpp +++ b/examples/gestures/imageviewer/imagewidget.cpp @@ -123,9 +123,9 @@ void ImageWidget::panTriggered() void ImageWidget::pinchTriggered() { QPinchGesture *pg = qobject_cast(sender()); - if (pg->rotationAngle() != 0.0) + if (pg->whatChanged() & QPinchGesture::RotationAngleChanged) rotationAngle += pg->rotationAngle() - pg->lastRotationAngle(); - if (pg->scaleFactor() != 1.0) + if (pg->whatChanged() & QPinchGesture::ScaleFactorChanged) scaleFactor += pg->scaleFactor() - pg->lastScaleFactor(); update(); } diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index 783c1d3..8e76715 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -413,6 +413,7 @@ 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->changes = 0; d->totalScaleFactor = d->scaleFactor = d->lastScaleFactor = 1.; d->totalRotationAngle = d->rotationAngle = d->lastRotationAngle = 0.; d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPointF(); @@ -460,6 +461,7 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) if (!windowsRotateWorkaround) nextState = Qt::GestureUpdated; #endif + d->changes = QPinchGesture::RotationAngleChanged; event->accept(); break; } @@ -484,6 +486,7 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) d->scaleFactor += ev->percentage; #endif nextState = Qt::GestureUpdated; + d->changes = QPinchGesture::ScaleFactorChanged; event->accept(); break; case QNativeGestureEvent::GestureEnd: @@ -498,6 +501,8 @@ bool QPinchGesture::eventFilter(QObject *receiver, QEvent *event) d->startCenterPoint = d->centerPoint; d->lastCenterPoint = d->centerPoint; d->centerPoint = static_cast(receiver)->mapFromGlobal(ev->position); + if (d->lastCenterPoint != d->centerPoint) + d->changes |= QPinchGesture::CenterPointChanged; updateState(nextState); return true; } @@ -523,6 +528,7 @@ bool QPinchGesture::filterEvent(QEvent *event) void QPinchGesture::reset() { Q_D(QPinchGesture); + d->changes = 0; d->totalScaleFactor = d->scaleFactor = d->lastScaleFactor = 1.; d->totalRotationAngle = d->rotationAngle = d->lastRotationAngle = 0.; d->startCenterPoint = d->centerPoint = d->lastCenterPoint = QPointF(); @@ -530,6 +536,16 @@ void QPinchGesture::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 diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h index c6dfa92..53c4416 100644 --- a/src/gui/kernel/qstandardgestures.h +++ b/src/gui/kernel/qstandardgestures.h @@ -89,6 +89,16 @@ class Q_GUI_EXPORT QPinchGesture : public QGesture Q_OBJECT Q_DECLARE_PRIVATE(QPinchGesture) +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) @@ -102,11 +112,14 @@ class Q_GUI_EXPORT QPinchGesture : public QGesture 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; diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index 9e23515..354ebee 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -89,7 +89,7 @@ class QPinchGesturePrivate : public QGesturePrivate public: QPinchGesturePrivate() - : totalScaleFactor(0.), lastScaleFactor(0.), scaleFactor(0.), + : changes(0), totalScaleFactor(0.), lastScaleFactor(0.), scaleFactor(0.), totalRotationAngle(0.), lastRotationAngle(0.), rotationAngle(0.) #ifdef Q_WS_WIN ,initialDistance(0), lastSequenceId(0) @@ -99,6 +99,8 @@ public: void setupGestureTarget(QObject *o); + QPinchGesture::WhatChanged changes; + qreal totalScaleFactor; // total scale factor, excluding the current sequence. qreal lastScaleFactor; qreal scaleFactor; // scale factor in the current sequence. -- cgit v0.12 From 25014061b8de7345f4480eb0eb20221ef2e34710 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 3 Sep 2009 11:51:54 +0200 Subject: Revert "Optimize qt_format_text test operations: try not to detach" This reverts commit 5c4c47facfcb75b0277872a0fac813ab41700e5e. The commit broke line breaks in text (and also other special formatting characters.) QChar *chr is a pointer for a reason =) Reviewed-by: Trond Task number: 260622 Conflicts: src/gui/painting/qpainter.cpp --- src/gui/painting/qpainter.cpp | 68 +++++++++++++++++++++++++------------------ 1 file changed, 40 insertions(+), 28 deletions(-) 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 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; } /*! -- cgit v0.12 From 1bf7506ca27ff797d4e4deac567ac515a87eb324 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Thu, 3 Sep 2009 11:43:33 +0200 Subject: qfsfileengine_win.cpp MinGW compile fix On MinGW REPARSE_DATA_BUFFER_HEADER_SIZE is defined but no IO_REPARSE_TAG_SYMLINK. So this define must be checked separately. Reviewed-by: phartman --- src/corelib/io/qfsfileengine_win.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) 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 -- cgit v0.12 From f55a2e6b2b3d97e74c3368552a6fba412d86e0b9 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 3 Sep 2009 12:07:06 +0200 Subject: compile on Windows The include was accidentally removed in commit e4dfcd4392e5be1b5de8648fc20ff45f7faa30ca; well, now we know what that was for... --- src/script/api/qscriptstring.cpp | 1 + 1 file changed, 1 insertion(+) 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" -- cgit v0.12 From 0dcf114697309f3f23f9717b608fa2be1813fe94 Mon Sep 17 00:00:00 2001 From: Morten Sorvig Date: Thu, 3 Sep 2009 12:17:39 +0200 Subject: Revert ed00fff3cb. This caused dublicate key events in come cases, for example in the Qt Creator quick serach line edit. RevBy: TrustMe --- src/gui/kernel/qcocoaview_mac.mm | 11 +---------- src/gui/kernel/qcocoaview_mac_p.h | 1 - 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm index bc32078..59494a7 100644 --- a/src/gui/kernel/qcocoaview_mac.mm +++ b/src/gui/kernel/qcocoaview_mac.mm @@ -201,7 +201,6 @@ extern "C" { composingText = new QString(); composing = false; sendKeyEvents = true; - inKeyDown = false; currentCustomTypes = 0; [self setHidden:YES]; return self; @@ -1037,7 +1036,6 @@ extern "C" { - (void)keyDown:(NSEvent *)theEvent { - inKeyDown = true; sendKeyEvents = true; QWidget *widgetToGetKey = qwidget; @@ -1057,7 +1055,6 @@ extern "C" { if (!keyOK && !sendToPopup) [super keyDown:theEvent]; } - inKeyDown = false; } @@ -1104,13 +1101,7 @@ extern "C" { }; } - if ([aString length] && !inKeyDown) { - // Handle the case where insertText is called from somewhere else than the keyDown - // implementation, for example when inserting text from the character palette. - QInputMethodEvent e; - e.setCommitString(commitText); - qt_sendSpontaneousEvent(qwidget, &e); - } else if ([aString length] && composing) { + if ([aString length] && composing) { // Send the commit string to the widget. composing = false; sendKeyEvents = false; diff --git a/src/gui/kernel/qcocoaview_mac_p.h b/src/gui/kernel/qcocoaview_mac_p.h index 9d4e3d0..3810a2b 100644 --- a/src/gui/kernel/qcocoaview_mac_p.h +++ b/src/gui/kernel/qcocoaview_mac_p.h @@ -86,7 +86,6 @@ Q_GUI_EXPORT bool composing; int composingLength; bool sendKeyEvents; - bool inKeyDown; QString *composingText; QStringList *currentCustomTypes; NSInteger dragEnterSequence; -- cgit v0.12 From 464ee98eee5ce160b497aec6a1163422980dd797 Mon Sep 17 00:00:00 2001 From: Andreas Aardal Hanssen Date: Thu, 3 Sep 2009 12:28:08 +0200 Subject: Fix test failure & optimize matrix operations in QGraphicsItem. This fixes failures in tst_QGraphicsItem::setTransformProperties(). Change 9e8ff32d introduced QMatrix4x4 as an internal matrix for QGraphicsItem. Problem is, QMatrix4x4 is float-based whereas QTransform is double-based. This change readds the use of QTransform in the case where there are no QGraphicsTransforms in the list. This by itself also makes this common case a bit faster. The workaround is moot if somebody adds any QGraphicsTransform, including one that doesn't do anything (like rotate by 0 degrees). So we might have to find a better fix. Reviewed-by: Olivier --- src/gui/graphicsview/qgraphicsitem_p.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 49361cf..55ed62e 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -517,6 +517,19 @@ struct QGraphicsItemPrivate::TransformData return transform * *postmultiplyTransform; } + if (graphicsTransforms.isEmpty()) { + // Faster, and higher precision if there are no graphics + // transforms. + QTransform x(transform); + x.translate(xOrigin, yOrigin); + x.rotate(rotation); + x.scale(scale, scale); + x.translate(-xOrigin, -yOrigin); + if (postmultiplyTransform) + x *= *postmultiplyTransform; + return x; + } + QMatrix4x4 x(transform); for (int i = 0; i < graphicsTransforms.size(); ++i) graphicsTransforms.at(i)->applyTo(&x); -- cgit v0.12 From d3673b331426346167e4dd1cd6c7b78ab7bf5176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Wed, 2 Sep 2009 19:35:17 +0200 Subject: Fixed some clipping bugs in raster paint engine. Clip against the correct base region in clip(const QRegion &, ...) and make sure to not access QClipData's clipRect unless hasRectClip is true. This fixes the tst_QWidget::render_systemClip3() autotest, and the clipping bugs in Qt Creator. Task-number: 260666 Reviewed-by: Gunnar Sletta --- src/gui/painting/qpaintengine_raster.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 86b2d0f..81924ff 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -1391,7 +1391,7 @@ void QRasterPaintEngine::clip(const QRegion ®ion, Qt::ClipOperation op) if (curClip->hasRectClip) newClip->setClipRegion(r & curClip->clipRect); else if (curClip->hasRegionClip) - newClip->setClipRegion(r & clip->clipRegion); + newClip->setClipRegion(r & curClip->clipRegion); qrasterpaintengine_dirty_clip(d, s); } @@ -3079,11 +3079,11 @@ bool QRasterPaintEnginePrivate::isUnclipped_normalized(const QRect &r) const } - // currently all painting functions clips to deviceRect internally - if (cl->clipRect == deviceRect) - return true; - if (cl->hasRectClip) { + // currently all painting functions clips to deviceRect internally + if (cl->clipRect == deviceRect) + return true; + // inline contains() for performance (we know the rects are normalized) const QRect &r1 = cl->clipRect; return (r.left() >= r1.left() && r.right() <= r1.right() @@ -3109,7 +3109,7 @@ bool QRasterPaintEnginePrivate::isUnclipped(const QRect &rect, // currently all painting functions that call this function clip to deviceRect internally - if (cl->clipRect == deviceRect) + if (cl->hasRectClip && cl->clipRect == deviceRect) return true; if (s->flags.antialiased) @@ -3123,7 +3123,7 @@ bool QRasterPaintEnginePrivate::isUnclipped(const QRect &rect, r.setHeight(r.height() + 2 * penWidth); } - if (!cl->clipRect.isEmpty()) { + if (cl->hasRectClip) { // inline contains() for performance (we know the rects are normalized) const QRect &r1 = cl->clipRect; return (r.left() >= r1.left() && r.right() <= r1.right() -- cgit v0.12