diff options
author | Alexis Menard <alexis.menard@nokia.com> | 2009-10-12 14:48:33 (GMT) |
---|---|---|
committer | Alexis Menard <alexis.menard@nokia.com> | 2009-10-12 14:48:33 (GMT) |
commit | bc53cf1334738307110a661f19b6fbb9be9b72d6 (patch) | |
tree | 268f8a23eba6e491258d0189362e44deb3fdce6d | |
parent | 8da7252de0badb818302763cbe62c38ad699f1f3 (diff) | |
parent | 8df79a473e1a7e5c79b9b10827985bf3e9501002 (diff) | |
download | Qt-bc53cf1334738307110a661f19b6fbb9be9b72d6.zip Qt-bc53cf1334738307110a661f19b6fbb9be9b72d6.tar.gz Qt-bc53cf1334738307110a661f19b6fbb9be9b72d6.tar.bz2 |
Merge commit '8df79a473e1a7e5c79b9b10827985bf3e9501002' into 4.6
148 files changed, 4273 insertions, 2187 deletions
@@ -5,16 +5,16 @@ this pre-release you can make advanced graphical applications and utilize TCP/IP connections. More specifically, these modules are now available for S60: -QtCore - http://doc.trolltech.com/4.6/qtcore.html -QtGui - http://doc.trolltech.com/4.6/qtgui.html -QtNetwork - http://doc.trolltech.com/4.6/qtnetwork.html -QtScript - http://doc.trolltech.com/4.6/qtscript.html -QtSql - http://doc.trolltech.com/4.6/qtsql.html -QtSvg - http://doc.trolltech.com/4.6/qtsvg.html -QtTest - http://doc.trolltech.com/4.6/qttest.html -QtWebKit - http://doc.trolltech.com/4.6/qtwebkit.html -QtXml - http://doc.trolltech.com/4.6/qtxml.html -Phonon - http://doc.trolltech.com/4.6/phonon-module.html +QtCore - http://doc.trolltech.com/4.6-snapshot/qtcore.html +QtGui - http://doc.trolltech.com/4.6-snapshot/qtgui.html +QtNetwork - http://doc.trolltech.com/4.6-snapshot/qtnetwork.html +QtScript - http://doc.trolltech.com/4.6-snapshot/qtscript.html +QtSql - http://doc.trolltech.com/4.6-snapshot/qtsql.html +QtSvg - http://doc.trolltech.com/4.6-snapshot/qtsvg.html +QtTest - http://doc.trolltech.com/4.6-snapshot/qttest.html +QtWebKit - http://doc.trolltech.com/4.6-snapshot/qtwebkit.html +QtXml - http://doc.trolltech.com/4.6-snapshot/qtxml.html +Phonon - http://doc.trolltech.com/4.6-snapshot/phonon-module.html INSTALLING Qt @@ -23,7 +23,7 @@ Follow the instructions in the INSTALL file. REFERENCE DOCUMENTATION The Qt reference documentation is available locally in Qt's doc/html -directory or at http://doc.trolltech.com/4.6/index.html +directory or at http://doc.trolltech.com/4.6-snapshot/index.html SUPPORTED PLATFORMS diff --git a/demos/demos.pro b/demos/demos.pro index c4b8872..4a9d451 100644 --- a/demos/demos.pro +++ b/demos/demos.pro @@ -64,7 +64,7 @@ demos_arthurplugin.subdir = arthurplugin demos_sqlbrowser.subdir = sqlbrowser demos_undo.subdir = undo demos_qtdemo.subdir = qtdemo -demos_mediaplayer.subdir = mediaplayer +demos_mediaplayer.subdir = qmediaplayer demos_browser.subdir = browser diff --git a/demos/embedded/anomaly/anomaly.pro b/demos/embedded/anomaly/anomaly.pro index 06d73fa..8f2825b 100644 --- a/demos/embedded/anomaly/anomaly.pro +++ b/demos/embedded/anomaly/anomaly.pro @@ -24,7 +24,7 @@ RESOURCES += src/anomaly.qrc symbian { TARGET.UID3 = 0xA000CF71 include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/ftp/sym_iap_util.h + HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h LIBS += -lesock -linsock -lconnmon TARGET.CAPABILITY = NetworkServices TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 diff --git a/demos/embedded/flightinfo/flightinfo.pro b/demos/embedded/flightinfo/flightinfo.pro index 5659fa2..0a51287 100644 --- a/demos/embedded/flightinfo/flightinfo.pro +++ b/demos/embedded/flightinfo/flightinfo.pro @@ -8,7 +8,7 @@ QT += network symbian { TARGET.UID3 = 0xA000CF74 include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/ftp/sym_iap_util.h + HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h LIBS += -lesock -lconnmon -linsock TARGET.CAPABILITY = NetworkServices } diff --git a/demos/embedded/fluidlauncher/config_s60/config.xml b/demos/embedded/fluidlauncher/config_s60/config.xml index fefa3dd..2c61baf 100644 --- a/demos/embedded/fluidlauncher/config_s60/config.xml +++ b/demos/embedded/fluidlauncher/config_s60/config.xml @@ -6,7 +6,7 @@ <example filename="deform" name="Vector Deformation" image="screenshots/deform.png" args="-small-screen"/> <example filename="pathstroke" name="Path Stroking" image="screenshots/pathstroke.png" args="-small-screen"/> <example filename="wiggly" name="Wiggly Text" image="screenshots/wiggly_s60.png" args="-small-screen"/> - <example filename="ftp" name="Ftp Client" image="screenshots/ftp_s60.png"/> + <example filename="qftp" name="Ftp Client" image="screenshots/ftp_s60.png"/> <example filename="context2d" name="Context2d" image="screenshots/context2d_s60.png" args="-small-screen"/> <example filename="saxbookmarks" name="SaxBookmarks" image="screenshots/saxbookmarks_s60.png"/> <example filename="desktopservices" name="Desktop Services" image="screenshots/desktopservices_s60.png"/> diff --git a/demos/embedded/fluidlauncher/fluidlauncher.pro b/demos/embedded/fluidlauncher/fluidlauncher.pro index f2abde6..dd931e6 100644 --- a/demos/embedded/fluidlauncher/fluidlauncher.pro +++ b/demos/embedded/fluidlauncher/fluidlauncher.pro @@ -66,7 +66,7 @@ symbian { deform.exe \ pathstroke.exe \ wiggly.exe \ - ftp.exe \ + qftp.exe \ saxbookmarks.exe \ desktopservices.exe \ fridgemagnets.exe \ @@ -85,7 +85,7 @@ symbian { $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/deform_reg.rsc \ $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/pathstroke_reg.rsc \ $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/wiggly_reg.rsc \ - $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/ftp_reg.rsc\ + $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/qftp_reg.rsc\ $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/saxbookmarks_reg.rsc \ $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/desktopservices_reg.rsc \ $${EPOCROOT}$$HW_ZDIR$$REG_RESOURCE_IMPORT_DIR/fridgemagnets_reg.rsc \ @@ -109,7 +109,7 @@ symbian { $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/deform.rsc \ $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/pathstroke.rsc \ $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/wiggly.rsc \ - $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/ftp.rsc\ + $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/qftp.rsc\ $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/saxbookmarks.rsc \ $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/desktopservices.rsc \ $${EPOCROOT}$$HW_ZDIR$$APP_RESOURCE_DIR/fridgemagnets.rsc \ diff --git a/demos/embedded/lightmaps/lightmaps.pro b/demos/embedded/lightmaps/lightmaps.pro index 122865e..cc78efa 100644 --- a/demos/embedded/lightmaps/lightmaps.pro +++ b/demos/embedded/lightmaps/lightmaps.pro @@ -5,7 +5,7 @@ QT += network symbian { TARGET.UID3 = 0xA000CF75 include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/ftp/sym_iap_util.h + HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h LIBS += -lesock -lconnmon -linsock TARGET.CAPABILITY = NetworkServices TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 diff --git a/demos/embedded/weatherinfo/weatherinfo.pro b/demos/embedded/weatherinfo/weatherinfo.pro index 5b2f03a..54c3857 100644 --- a/demos/embedded/weatherinfo/weatherinfo.pro +++ b/demos/embedded/weatherinfo/weatherinfo.pro @@ -7,7 +7,7 @@ QT += network svg symbian { TARGET.UID3 = 0xA000CF77 include($$QT_SOURCE_TREE/demos/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/ftp/sym_iap_util.h + HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h LIBS += -lesock -lconnmon -linsock TARGET.CAPABILITY = NetworkServices } diff --git a/demos/mediaplayer/images/screen.png b/demos/qmediaplayer/images/screen.png Binary files differindex a15df92..a15df92 100644 --- a/demos/mediaplayer/images/screen.png +++ b/demos/qmediaplayer/images/screen.png diff --git a/demos/mediaplayer/main.cpp b/demos/qmediaplayer/main.cpp index 66aa445..66aa445 100644 --- a/demos/mediaplayer/main.cpp +++ b/demos/qmediaplayer/main.cpp diff --git a/demos/mediaplayer/mediaplayer.cpp b/demos/qmediaplayer/mediaplayer.cpp index baac236..baac236 100644 --- a/demos/mediaplayer/mediaplayer.cpp +++ b/demos/qmediaplayer/mediaplayer.cpp diff --git a/demos/mediaplayer/mediaplayer.h b/demos/qmediaplayer/mediaplayer.h index 40ffa40..40ffa40 100644 --- a/demos/mediaplayer/mediaplayer.h +++ b/demos/qmediaplayer/mediaplayer.h diff --git a/demos/mediaplayer/mediaplayer.qrc b/demos/qmediaplayer/mediaplayer.qrc index bcdf404..bcdf404 100644 --- a/demos/mediaplayer/mediaplayer.qrc +++ b/demos/qmediaplayer/mediaplayer.qrc diff --git a/demos/mediaplayer/mediaplayer.pro b/demos/qmediaplayer/qmediaplayer.pro index a420cc3..2f15c28 100644 --- a/demos/mediaplayer/mediaplayer.pro +++ b/demos/qmediaplayer/qmediaplayer.pro @@ -3,7 +3,6 @@ ###################################################################### TEMPLATE = app -TARGET = qmediaplayer DEPENDPATH += . build src ui QT += phonon @@ -18,7 +17,7 @@ HEADERS += mediaplayer.h target.path = $$[QT_INSTALL_DEMOS]/qmediaplayer sources.files = $$SOURCES $$HEADERS $$FORMS $$RESOURCES *.pro *.html *.doc images -sources.path = $$[QT_INSTALL_DEMOS]/mediaplayer +sources.path = $$[QT_INSTALL_DEMOS]/qmediaplayer INSTALLS += target sources wince*{ diff --git a/demos/mediaplayer/settings.ui b/demos/qmediaplayer/settings.ui index d2cedd4..d2cedd4 100644 --- a/demos/mediaplayer/settings.ui +++ b/demos/qmediaplayer/settings.ui diff --git a/demos/qtdemo/xml/examples.xml b/demos/qtdemo/xml/examples.xml index 3f0cd25..2c31484 100644 --- a/demos/qtdemo/xml/examples.xml +++ b/demos/qtdemo/xml/examples.xml @@ -121,7 +121,7 @@ <example filename="network-chat" name="Network Chat Client" /> <example filename="fortuneclient" name="Fortune Client" /> <example filename="fortuneserver" name="Fortune Server" /> - <example filename="ftp" changedirectory="false" name="FTP Client" /> + <example filename="qftp" changedirectory="false" name="FTP Client" /> <example filename="http" changedirectory="false" name="HTTP Client" /> <example filename="loopback" name="Loopback" /> <example filename="threadedfortuneserver" name="Threaded Fort. Server" /> @@ -152,7 +152,7 @@ <example filename="transformations" name="Transformations" /> </category> <category dirname="phonon" name="Phonon"> - <example filename="musicplayer" name="Music Player" /> + <example filename="qmusicplayer" name="Music Player" /> </category> <category dirname="multimedia/audio" name="Multimedia"> <example filename="audiodevices" name="Audio Devices" /> diff --git a/doc/src/demos/mediaplayer.qdoc b/doc/src/demos/mediaplayer.qdoc index 9e6b3f9..17ae79b 100644 --- a/doc/src/demos/mediaplayer.qdoc +++ b/doc/src/demos/mediaplayer.qdoc @@ -40,7 +40,7 @@ ****************************************************************************/ /*! - \example demos/mediaplayer + \example demos/qmediaplayer \title Media Player The Media Player demonstration shows how \l{Phonon Module}{Phonon} diff --git a/doc/src/development/qmake-manual.qdoc b/doc/src/development/qmake-manual.qdoc index 87132cc..d040d3d 100644 --- a/doc/src/development/qmake-manual.qdoc +++ b/doc/src/development/qmake-manual.qdoc @@ -952,7 +952,7 @@ \snippet doc/src/snippets/code/doc_src_qmake-manual.qdoc 130 - The default values depend on the version of the S60 SDK you're using. + The default values depend on the version of the Symbian SDK you're using. \section2 Compiler specific options @@ -983,8 +983,7 @@ an official UID, please contact Nokia. Both \c SID and \c VID default to empty values. For more information about unique identifiers and their meaning for - Symbian applications, please refer to the - \l{http://www.symbian.com/developer/techlib/v9.2docs/doc_source/ToolsAndUtilities/BuildTools/UsingUids.guide.html}{respective S60 SDK documentation}. + Symbian applications, please refer to the Symbian SDK documentation. \section2 Capabilities @@ -1000,8 +999,7 @@ \snippet doc/src/snippets/code/doc_src_qmake-manual.qdoc 134 - For more information about capabilities, please refer to the - \l{http://www.symbian.com/developer/techlib/v9.2docs/doc_source/guide/platsecsdk/index.html}{respective S60 SDK documentation}. + For more information about capabilities, please refer to the Symbian SDK documentation. */ /*! @@ -2925,7 +2923,7 @@ For example: \e {This is only used on the Symbian platform.} Specifies which platform capabilities the application should have. For more - information, please refer to the S60 SDK documentation. + information, please refer to the Symbian SDK documentation. \target TARGET.EPOCALLOWDLLDATA \section1 TARGET.EPOCALLOWDLLDATA @@ -2961,7 +2959,7 @@ For example: \e {This is only used on the Symbian platform.} Specifies which secure identifier to use for the target application or - library. For more information, see the S60 SDK documentation. + library. For more information, see the Symbian SDK documentation. \target TARGET.UID2 \section1 TARGET.UID2 @@ -2970,7 +2968,7 @@ For example: Specifies which unique identifier 2 to use for the target application or library. If this variable is not specified, it defaults to the same value - as TARGET.UID3. For more information, see the S60 SDK documentation. + as TARGET.UID3. For more information, see the Symbian SDK documentation. \target TARGET.UID3 \section1 TARGET.UID3 @@ -2981,7 +2979,7 @@ For example: library. If this variable is not specified, a UID3 suitable for development and debugging will be generated automatically. However, applications being released should always define this variable. For more information, see the - S60 SDK documentation. + Symbian SDK documentation. \target TARGET.VID \section1 TARGET.VID @@ -2989,7 +2987,7 @@ For example: \e {This is only used on the Symbian platform.} Specifies which vendor identifier to use for the target application or - library. For more information, see the S60 SDK documentation. + library. For more information, see the Symbian SDK documentation. \section1 TARGET_EXT diff --git a/doc/src/examples/ftp.qdoc b/doc/src/examples/ftp.qdoc index ec8584c..8fded88 100644 --- a/doc/src/examples/ftp.qdoc +++ b/doc/src/examples/ftp.qdoc @@ -78,13 +78,13 @@ \l{QFtp::Command}{commands} we request are finished, the progress of current commands, and information about files on the server. - \snippet examples/network/ftp/ftpwindow.h 0 + \snippet examples/network/qftp/ftpwindow.h 0 We will look at each slot when we examine the \c FtpWindow implementation in the next section. We also make use of a few private variables: - \snippet examples/network/ftp/ftpwindow.h 1 + \snippet examples/network/qftp/ftpwindow.h 1 The \c isDirectory hash keeps a history of all entries explored on the FTP server, and registers whether an entry represents a @@ -98,7 +98,7 @@ We move on to the slots, starting with \c connectOrDisconnect(). - \snippet examples/network/ftp/ftpwindow.cpp 0 + \snippet examples/network/qftp/ftpwindow.cpp 0 If \c ftp is already pointing to a QFtp object, we QFtp::Close its FTP connection and delete the object it points to. Note that we do @@ -106,7 +106,7 @@ to finish its abort operation. \dots - \snippet examples/network/ftp/ftpwindow.cpp 1 + \snippet examples/network/qftp/ftpwindow.cpp 1 If we get here, \c connectOrDisconnect() was called to establish a new FTP connection. We create a new QFtp for our new connection, @@ -118,7 +118,7 @@ is emitted repeatedly during an FTP file transfer, giving us progress reports. - \snippet examples/network/ftp/ftpwindow.cpp 2 + \snippet examples/network/qftp/ftpwindow.cpp 2 The \gui {Ftp Server} line edit contains the IP address or hostname of the server to which we want to connect. We first check @@ -134,39 +134,39 @@ We move on to the \c downloadFile() slot: - \snippet examples/network/ftp/ftpwindow.cpp 3 + \snippet examples/network/qftp/ftpwindow.cpp 3 \dots - \snippet examples/network/ftp/ftpwindow.cpp 4 + \snippet examples/network/qftp/ftpwindow.cpp 4 We first fetch the name of the file, which we find in the selected item of \c fileList. We then start the download by using QFtp::get(). QFtp will send progress signals during the download and a signal when the download is completed. - \snippet examples/network/ftp/ftpwindow.cpp 5 + \snippet examples/network/qftp/ftpwindow.cpp 5 QFtp supports canceling the download of files. - \snippet examples/network/ftp/ftpwindow.cpp 6 + \snippet examples/network/qftp/ftpwindow.cpp 6 The \c ftpCommandFinished() slot is called when QFtp has finished a QFtp::Command. If an error occurred during the command, QFtp will set \c error to one of the values in the QFtp::Error enum; otherwise, \c error is zero. - \snippet examples/network/ftp/ftpwindow.cpp 7 + \snippet examples/network/qftp/ftpwindow.cpp 7 After login, the QFtp::list() function will list the top-level directory on the server. addToList() is connected to QFtp::listInfo(), and will be invoked for each entry in that directory. - \snippet examples/network/ftp/ftpwindow.cpp 8 + \snippet examples/network/qftp/ftpwindow.cpp 8 When a \l{QFtp::}{Get} command is finished, a file has finished downloading (or an error occurred during the download). - \snippet examples/network/ftp/ftpwindow.cpp 9 + \snippet examples/network/qftp/ftpwindow.cpp 9 After a \l{QFtp::}{List} command is performed, we have to check if no entries were found (in which case our \c addToList() function @@ -174,7 +174,7 @@ Let's continue with the \c addToList() slot: - \snippet examples/network/ftp/ftpwindow.cpp 10 + \snippet examples/network/qftp/ftpwindow.cpp 10 When a new file has been resolved during a QFtp::List command, this slot is invoked with a QUrlInfo describing the file. We @@ -182,26 +182,26 @@ does not have a current item, we set the new item to be the current item. - \snippet examples/network/ftp/ftpwindow.cpp 11 + \snippet examples/network/qftp/ftpwindow.cpp 11 The \c processItem() slot is called when an item is double clicked in the \gui {File List}. If the item represents a directory, we want to load the contents of that directory with QFtp::list(). - \snippet examples/network/ftp/ftpwindow.cpp 12 + \snippet examples/network/qftp/ftpwindow.cpp 12 \c cdToParent() is invoked when the user requests to go to the parent directory of the one displayed in the file list. After changing the directory, we QFtp::List its contents. - \snippet examples/network/ftp/ftpwindow.cpp 13 + \snippet examples/network/qftp/ftpwindow.cpp 13 The \c updateDataTransferProgress() slot is called regularly by QFtp::dataTransferProgress() when a file download is in progress. We use a QProgressDialog to show the download progression to the user. - \snippet examples/network/ftp/ftpwindow.cpp 14 + \snippet examples/network/qftp/ftpwindow.cpp 14 The \c enableDownloadButton() is called whenever the current item in \c fileList changes. If the item represents a file, the \gui diff --git a/doc/src/examples/musicplayerexample.qdoc b/doc/src/examples/musicplayerexample.qdoc index 41c9f3a..7145583 100644 --- a/doc/src/examples/musicplayerexample.qdoc +++ b/doc/src/examples/musicplayerexample.qdoc @@ -40,7 +40,7 @@ ****************************************************************************/ /*! - \example phonon/musicplayer + \example phonon/qmusicplayer \title Music Player Example The Music Player Example shows how to use Phonon - the multimedia @@ -90,7 +90,7 @@ look at them when we walk through the \c MainWindow implementation. - \snippet examples/phonon/musicplayer/mainwindow.h 2 + \snippet examples/phonon/qmusicplayer/mainwindow.h 2 We use the \l{Phonon::}{SeekSlider} to move the current playback position in the media stream, and the \l{Phonon::}{VolumeSlider} @@ -99,7 +99,7 @@ metaInformationProvider, to get the meta information from the music files. More on this later. - \snippet examples/phonon/musicplayer/mainwindow.h 1 + \snippet examples/phonon/qmusicplayer/mainwindow.h 1 The \l{Phonon::}{MediaObject} informs us of the state of the playback and properties of the media it is playing back through a series of @@ -116,7 +116,7 @@ We start with the constructor: - \snippet examples/phonon/musicplayer/mainwindow.cpp 0 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 0 We start by instantiating our media and audio output objects. As mentioned, the media object knows how to playback @@ -130,20 +130,20 @@ paths. Objects are connected using the \c createPath() function, which is part of the Phonon namespace. - \snippet examples/phonon/musicplayer/mainwindow.cpp 1 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 1 We also connect signals of the media object to slots in our \c MainWindow. We will examine them shortly. - \snippet examples/phonon/musicplayer/mainwindow.cpp 2 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 2 Finally, we call private helper functions to set up the GUI. The \c setupUi() function contains code for setting up the seek , and volume slider. We move on to \c setupUi(): - \snippet examples/phonon/musicplayer/mainwindow.cpp 3 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 3 \dots - \snippet examples/phonon/musicplayer/mainwindow.cpp 4 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 4 After creating the widgets, they must be supplied with the \l{Phonon::}{MediaObject} and \l{Phonon::}{AudioOutput} objects @@ -152,12 +152,12 @@ In the \c setupActions(), we connect the actions for the play, pause, and stop tool buttons, to slots of the media object. - \snippet examples/phonon/musicplayer/mainwindow.cpp 5 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 5 We move on to the slots of \c MainWindow, starting with \c addFiles(): - \snippet examples/phonon/musicplayer/mainwindow.cpp 6 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 6 In the \c addFiles() slot, we add files selected by the user to the \c sources list. We then set the first source selected on the @@ -169,7 +169,7 @@ stateChanged() signal. The \c stateChanged() slot is connected to this signal. - \snippet examples/phonon/musicplayer/mainwindow.cpp 9 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 9 The \l{Phonon::MediaObject::}{errorString()} function gives a description of the error that is suitable for users of a Phonon @@ -177,7 +177,7 @@ helps us determine whether it is possible to try to play the same file again. - \snippet examples/phonon/musicplayer/mainwindow.cpp 10 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 10 We update the GUI when the playback state changes, i.e., when it starts, pauses, stops, or resumes. @@ -188,26 +188,26 @@ The \c tick() slot is connected to a \l{Phonon::}{MediaObject} signal which is emitted when the playback position changes: - \snippet examples/phonon/musicplayer/mainwindow.cpp 11 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 11 The \c time is given in milliseconds. When the table is clicked on with the mouse, \c tableClick() is invoked: - \snippet examples/phonon/musicplayer/mainwindow.cpp 12 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 12 Since we stop the media object, we first check whether it is currently playing. \c row contains the row in the table that was clicked upon; the indices of \c sources follows the table, so we can simply use \c row to find the new source. - \snippet examples/phonon/musicplayer/mainwindow.cpp 13 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 13 When the media source changes, we simply need to select the corresponding row in the table. - \snippet examples/phonon/musicplayer/mainwindow.cpp 14 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 14 When \c metaStateChanged() is invoked, \c metaInformationProvider has resolved the meta data for its current @@ -220,7 +220,7 @@ music table. A file might not contain the meta data requested, in which case an empty string is returned. - \snippet examples/phonon/musicplayer/mainwindow.cpp 15 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 15 If we have media sources in \c sources of which meta information is not resolved, we set a new source on the \c @@ -229,7 +229,7 @@ We move on to the \c aboutToFinish() slot: - \snippet examples/phonon/musicplayer/mainwindow.cpp 16 + \snippet examples/phonon/qmusicplayer/mainwindow.cpp 16 When a file is finished playing, the Music Player will move on and play the next file in the table. This slot is connected to the @@ -244,5 +244,5 @@ \l{QCoreApplication::}{setApplicationName()}. This is because D-Bus, which is used by Phonon on Linux systems, demands this. - \snippet examples/phonon/musicplayer/main.cpp 1 + \snippet examples/phonon/qmusicplayer/main.cpp 1 */ diff --git a/doc/src/frameworks-technologies/model-view-programming.qdoc b/doc/src/frameworks-technologies/model-view-programming.qdoc index bc884df..f0f20b4 100644 --- a/doc/src/frameworks-technologies/model-view-programming.qdoc +++ b/doc/src/frameworks-technologies/model-view-programming.qdoc @@ -215,8 +215,8 @@ \o QStringListModel is used to store a simple list of QString items. \o QStandardItemModel manages more complex tree structures of items, each of which can contain arbitrary data. - \o QDirModel provides information about files and directories in the local - filing system. + \o QFileSystemModel provides information about files and directories in the + local filing system. \o QSqlQueryModel, QSqlTableModel, and QSqlRelationalTableModel are used to access databases using model/view conventions. \endlist @@ -313,14 +313,14 @@ \section1 Introduction Two of the standard models provided by Qt are QStandardItemModel and - QDirModel. QStandardItemModel is a multi-purpose model that can be used - to represent various different data structures needed by list, table, + QFileSystemModel. QStandardItemModel is a multi-purpose model that can be + used to represent various different data structures needed by list, table, and tree views. This model also holds the items of data. - QDirModel is a model that maintains information about the contents of a - directory. As a result, it does not hold any items of data itself, but + QFileSystemModel is a model that maintains information about the contents + of a directory. As a result, it does not hold any items of data itself, but simply represents files and directories on the local filing system. - QDirModel provides a ready-to-use model to experiment with, and can be + QFileSystemModel provides a ready-to-use model to experiment with, and can be easily configured to use existing data. Using this model, we can show how to set up a model for use with ready-made views, and explore how to manipulate data using model indexes. @@ -328,22 +328,25 @@ \section1 Using Views with an Existing Model The QListView and QTreeView classes are the most suitable views - to use with QDirModel. The example presented below displays the + to use with QFileSystemModel. The example presented below displays the contents of a directory in a tree view next to the same information in a list view. The views share the user's selection so that the selected items are highlighted in both views. \img shareddirmodel.png - We set up a QDirModel so that it is ready for use, and create some + We set up a QFileSystemModel so that it is ready for use, and create some views to display the contents of a directory. This shows the simplest way to use a model. The construction and use of the model is performed from within a single \c main() function: \snippet doc/src/snippets/shareddirmodel/main.cpp 0 - The model is set up to use data from a default directory. We create two - views so that we can examine the items held in the model in two + The model is set up to use data from a certain file system. The call to + \l{QFileSystemModel::}{setRootPath()} tell the model which drive on the + file system to expose to the views. + + We create two views so that we can examine the items held in the model in two different ways: \snippet doc/src/snippets/shareddirmodel/main.cpp 5 @@ -351,13 +354,13 @@ The views are constructed in the same way as other widgets. Setting up a view to display the items in the model is simply a matter of calling its \l{QAbstractItemView::setModel()}{setModel()} function with the directory - model as the argument. The calls to - \l{QAbstractItemView::setRootIndex()}{setRootIndex()} tell the views which - directory to display by supplying a \e{model index} that we obtain from - the directory model. + model as the argument. We filter the data supplied by the model by calling + the \l{QAbstractItemView::}{setRootIndex()} function on each view, passing + a suitable \e{model index} from the file system model for the current + directory. - The \c index() function used in this case is unique to QDirModel; we supply - it with a directory and it returns a model index. Model indexes are + The \c index() function used in this case is unique to QFileSystemModel; we + supply it with a directory and it returns a model index. Model indexes are discussed in the \l{Model Classes} chapter. The rest of the function just displays the views within a splitter @@ -556,19 +559,19 @@ \section2 Using Model Indexes To demonstrate how data can be retrieved from a model, using model - indexes, we set up a QDirModel without a view and display the + indexes, we set up a QFileSystemModel without a view and display the names of files and directories in a widget. Although this does not show a normal way of using a model, it demonstrates the conventions used by models when dealing with model indexes. - We construct a directory model in the following way: + We construct a file system model in the following way: \snippet doc/src/snippets/simplemodel-use/main.cpp 0 - In this case, we set up a default QDirModel, obtain a parent index using - a specific implementation of \l{QDirModel::index()}{index()} provided by - that model, and we count the number of rows in the model using the - \l{QDirModel::rowCount()}{rowCount()} function. + In this case, we set up a default QFileSystemModel, obtain a parent index + using a specific implementation of \l{QFileSystemModel::}{index()} + provided by that model, and we count the number of rows in the model using + the \l{QFileSystemModel::}{rowCount()} function. For simplicity, we are only interested in the items in the first column of the model. We examine each row in turn, obtaining a model index for @@ -581,7 +584,7 @@ for the first column), and the appropriate model index for the parent of all the items that we want. The text stored in each item is retrieved using the model's - \l{QDirModel::data()}{data()} function. We specify the model index and + \l{QFileSystemModel::}{data()} function. We specify the model index and the \l{Qt::ItemDataRole}{DisplayRole} to obtain data for the item in the form of a string. diff --git a/doc/src/getting-started/demos.qdoc b/doc/src/getting-started/demos.qdoc index 532715e..8f2829a 100644 --- a/doc/src/getting-started/demos.qdoc +++ b/doc/src/getting-started/demos.qdoc @@ -157,7 +157,7 @@ \section1 Phonon \list - \o \l{demos/mediaplayer}{Media Player} demonstrates how the \l{Phonon Module} can be + \o \l{demos/qmediaplayer}{Media Player} demonstrates how the \l{Phonon Module} can be used to implement a basic media player application. \endlist diff --git a/doc/src/getting-started/examples.qdoc b/doc/src/getting-started/examples.qdoc index 30dae88..2ad730a7 100644 --- a/doc/src/getting-started/examples.qdoc +++ b/doc/src/getting-started/examples.qdoc @@ -827,7 +827,7 @@ \list \o \l{phonon/capabilities}{Capabilities}\raisedaster - \o \l{phonon/musicplayer}{Music Player}\raisedaster + \o \l{phonon/qmusicplayer}{Music Player}\raisedaster \endlist */ diff --git a/doc/src/getting-started/installation.qdoc b/doc/src/getting-started/installation.qdoc index 366a906..8269552 100644 --- a/doc/src/getting-started/installation.qdoc +++ b/doc/src/getting-started/installation.qdoc @@ -510,9 +510,9 @@ in the \l{Qt for Symbian platform Requirements} document. \o Install Qt - Run \c{qt-s60-%VERSION%.exe} and follow the instructions. + Run \c{qt-symbian-opensource-%VERSION%.exe} and follow the instructions. - \note Qt must be installed on the same drive as the S60 SDK you are + \note Qt must be installed on the same drive as the Symbian SDK you are using, and the install path must not contain any spaces. \o Running Qt demos @@ -567,7 +567,7 @@ If you are using pre-built binaries, follow the instructions Uncompress the package into the directory you want Qt installed, e.g. \c{C:\Qt\%VERSION%}. - \note Qt must be installed on the same drive as the S60 SDK you are + \note Qt must be installed on the same drive as the Symbian SDK you are using, and the install path must not contain any spaces. \o Environment variables @@ -582,7 +582,7 @@ If you are using pre-built binaries, follow the instructions On Windows the PATH can be extended by navigating to "Control Panel->System->Advanced->Environment variables". - In addition, you must configure the environment for use with the S60 + In addition, you must configure the environment for use with the Symbian emulator. This is done by locating the Carbide.c++ submenu on the Start menu, and choosing "Configure environment for WINSCW command line". @@ -972,13 +972,13 @@ Symbian platform, see \l{Symbian platform - Introduction to using Qt}. \endlist \o \l{http://www.forum.nokia.com/main/resources/tools_and_sdks/S60SDK/}{S60 Platform SDK 3rd Edition FP1 or higher} \o \l{http://www.forum.nokia.com/main/resources/technologies/openc_cpp/}{Open C/C++ v1.6.0 or higher}. - Install this to all S60 SDKs you plan to use Qt with. + Install this to all Symbian SDKs you plan to use Qt with. \o Building Qt libraries requires \l{http://www.arm.com/products/DevTools/RVCT.html}{RVCT} 2.2 [build 686] or later, which is not available free of charge. \endlist Running Qt on real device requires the following packages to be installed on your device. - The packages can be found in the S60 SDK where you installed Open C/C++: + The packages can be found in the Symbian SDK where you installed Open C/C++: \list \o \c{nokia_plugin\openc\s60opencsis\pips_s60_<version>.sis} \o \c{nokia_plugin\openc\s60opencsis\openc_ssl_s60_<version>.sis} diff --git a/doc/src/getting-started/known-issues.qdoc b/doc/src/getting-started/known-issues.qdoc index 6f8eb66..40ac1c7 100644 --- a/doc/src/getting-started/known-issues.qdoc +++ b/doc/src/getting-started/known-issues.qdoc @@ -45,20 +45,72 @@ \ingroup platform-specific \brief A summary of known issues in Qt %VERSION% at the time of release. - An up-to-date list of known issues with Qt %VERSION% can be found via the - \l{Task Tracker} on the Qt website which provides additional information - about known issues and tasks related to Qt. + This page documents known problems with the packaging and installation in + Qt %VERSION%, as well as issues with third party software that we have + not been able to work around. For a list of such issues in previous Qt + versions refer to this page in the respective documentation. - \section1 General Issues + For a list list of known bugs in Qt %VERSION%, see the \l{Task Tracker} + on the Qt website. - When running Qt applications on Windows or with \c{-graphicssystem raster}, - any process that triggers a QWidget::update() from within a destructor - might result in a crash. + \section1 Installation Issues + \section2 Building the Source Package on Windows 7 + + \list + \o When building Qt 4.5.0 with Windows 7, the build fails with an error + message regarding failing to embed manifest. This a known issue with + Windows 7, explained in the Windows 7 SDK Beta + \l{http://download.microsoft.com/download/8/8/0/8808A472-6450-4723-9C87-977069714B27/ReleaseNotes.Htm} + {release notes}. A workaround for this issue is to patch the + \bold{embed_manifest_exe.prf} file with the following: + + \code + diff --git a/mkspecs/features/win32/embed_manifest_exe.prf b/mkspecs/features/win32/embed_manifest_exe.prf + index e1747f1..05f116e 100644 + --- a/mkspecs/features/win32/embed_manifest_exe.prf + +++ b/mkspecs/features/win32/embed_manifest_exe.prf + @@ -8,4 +8,9 @@ if(win32-msvc2005|win32-msvc2008):!equals(TEMPLATE_PREFIX, "vc"):equals(TEMPLATE + QMAKE_POST_LINK = $$quote(mt.exe -nologo -manifest \"$$replace(OBJECTS_DIR,/,\\)\\$${NOPATH_TARGET}.intermediate.ma + nifest\" -outputresource:$(DESTDIR_TARGET);1$$escape_expand(\n\t)) + QMAKE_POST_LINK += $$QMAKE_PREV_POST_LINK + QMAKE_CLEAN += \"$$replace(OBJECTS_DIR,/,\\)\\$${NOPATH_TARGET}.intermediate.manifest\" + + isEmpty(RC_FILE) { + + system("echo.>$$replace(OUT_PWD,/,\\)\\$$replace(OBJECTS_DIR,/,\\)\\Windows7WorkAround.rc") + + RC_FILE = $$replace(OUT_PWD,/,\\)\\$$replace(OBJECTS_DIR,/,\\)\\Windows7WorkAround.rc + + } + + + } + \endcode + + \section2 Installing the Source Package on Unix systems + + \o If you download a Zip source package, you will need to convert + Windows-style line endings (CR/LF) to Unix-style line-endings (LF) when + you uncompress the package. To do this, give the "-a" option when you + run the "unzip' command. + + If you fail to supply the "-a" option when unzipping the package, you + will see the following error message when you attempt to execute the + configure command: + "bash: ./configure: /bin/sh^M: bad interpreter: No such file or directory" + \endlist + + \section2 Installing on Mac OS X 10.6 "Snow Leopard" + \list + \o Performing a new install of the Qt 4.6 beta on Snow Leopard + triggers a bug in the installer that causes the install to fail. + Updating an existing Qt installation works fine. + + There are two workarounds, either disable spotlight for the target + drive during the install, or do a custom install where you deselect + documentation and examples. Run the installer again as a full + install to get the documentation and examples installed. + \endlist \section1 Issues with Third Party Software - \section2 X11 Hardware Support + \section2 X11 \list \o There is a bug in the 169.xx NVIDIA drivers on certain GeForce 8 series @@ -76,7 +128,7 @@ of the drivers. \endlist - \section2 Windows Hardware Support + \section2 Windows \list \o When using version 6.14.11.6921 of the NVIDIA drivers for the GeForce @@ -85,43 +137,6 @@ applications that use OpenGL. This problem can be worked around by reducing the level of graphics acceleration provided by the driver, or by disabling hardware acceleration completely. - \endlist - - \section2 Windows Software Issues - - \list - - \o When building Qt 4.5.0 with Windows 7, the build fails with an error - message regarding failing to embed manifest. This a known issue with - Windows 7, explained in the Windows 7 SDK Beta - \l{http://download.microsoft.com/download/8/8/0/8808A472-6450-4723-9C87-977069714B27/ReleaseNotes.Htm} - {release notes}. A workaround for this issue is to patch the - \bold{embed_manifest_exe.prf} file with the following: - - \code - diff --git a/mkspecs/features/win32/embed_manifest_exe.prf b/mkspecs/features/win32/embed_manifest_exe.prf - index e1747f1..05f116e 100644 - --- a/mkspecs/features/win32/embed_manifest_exe.prf - +++ b/mkspecs/features/win32/embed_manifest_exe.prf - @@ -8,4 +8,9 @@ if(win32-msvc2005|win32-msvc2008):!equals(TEMPLATE_PREFIX, "vc"):equals(TEMPLATE - QMAKE_POST_LINK = $$quote(mt.exe -nologo -manifest \"$$replace(OBJECTS_DIR,/,\\)\\$${NOPATH_TARGET}.intermediate.ma - nifest\" -outputresource:$(DESTDIR_TARGET);1$$escape_expand(\n\t)) - QMAKE_POST_LINK += $$QMAKE_PREV_POST_LINK - QMAKE_CLEAN += \"$$replace(OBJECTS_DIR,/,\\)\\$${NOPATH_TARGET}.intermediate.manifest\" - + isEmpty(RC_FILE) { - + system("echo.>$$replace(OUT_PWD,/,\\)\\$$replace(OBJECTS_DIR,/,\\)\\Windows7WorkAround.rc") - + RC_FILE = $$replace(OUT_PWD,/,\\)\\$$replace(OBJECTS_DIR,/,\\)\\Windows7WorkAround.rc - + } - + - } - \endcode - - \o Under certain circumstances Visual Studio Integration v1.4.0 will not - be able to install the integration for Visual Studio 2005 on Windows - Vista. An error message states that .NET Framework v2.0 Service Pack 1 - is not installed. This is due to a problem with the built-in - installation of this on Windows Vista. This issue can be fixed by - installing .NET Framework version 3.5. \o With NVIDIA GeForce 7950 GT (driver version 6.14.11.7824), a fullscreen QGLWidget flickers when child widgets are shown/hidden. The workaround @@ -133,42 +148,11 @@ \endlist - - \section2 Mac OS X Software Support + \section2 Mac OS X \list \o If a sheet is opened for a given window, clicking the title bar of that window will cause it to flash. This behavior has been reported to Apple (bug number 5827676). \endlist - - - \section2 Installing source packages on Unix systems - - \list - \o If you download a Zip source package, you will need to convert - Windows-style line endings (CR/LF) to Unix-style line-endings (LF) when - you uncompress the package. To do this, give the "-a" option when you - run the "unzip' command. - - If you fail to supply the "-a" option when unzipping the package, you - will see the following error message when you attempt to execute the - configure command: - "bash: ./configure: /bin/sh^M: bad interpreter: No such file or directory" - \endlist - - - \section2 Running evaluation packages on Windows XP - - \list - \o If running the qt-win-eval-%VERSION%-vs2008.exe package on a Windows XP - system, you may encounter the following error message: - "The application failed to start because the application configuration - is incorrect. Reinstalling the application may fix this problem.". - - This error occurs because the version of the CRT component on the - system is incorrect. Visual Studio 2008 requires CRT90 while Windows - XP comes with CRT80. To solve this problem, please install the 2008 CRT - redistributable package from Microsoft. - \endlist */ diff --git a/doc/src/howtos/exceptionsafety.qdoc b/doc/src/howtos/exceptionsafety.qdoc index 23bedf5..fa1427b 100644 --- a/doc/src/howtos/exceptionsafety.qdoc +++ b/doc/src/howtos/exceptionsafety.qdoc @@ -144,12 +144,12 @@ \section1 Platform-Specific Exception Handling - \section2 Symbian (Qt for S60) + \section2 The Symbian platform The Symbian platform implements its own exception system that differs from the standard - C++ mechanism. When using Qt for S60, and especially when writing code to access Symbian - functionality directly, it may be necessary to know about the underlying implementation - and how it interacts with Qt. + C++ mechanism. When using Qt for Symbian platform, and especially when writing code to + access Symbian functionality directly, it may be necessary to know about the underlying + implementation and how it interacts with Qt. The \l{Exception Safety with Symbian} document shows how to use the facilities provided by Qt to use exceptions as safely as possible. diff --git a/doc/src/images/qt-colors.png b/doc/src/images/qt-colors.png Binary files differindex 524123f..331c975 100644 --- a/doc/src/images/qt-colors.png +++ b/doc/src/images/qt-colors.png diff --git a/doc/src/images/shareddirmodel.png b/doc/src/images/shareddirmodel.png Binary files differindex 6daa9d3..7b9fded 100644 --- a/doc/src/images/shareddirmodel.png +++ b/doc/src/images/shareddirmodel.png diff --git a/doc/src/images/standard-views.png b/doc/src/images/standard-views.png Binary files differindex 836ae36..c804551 100644 --- a/doc/src/images/standard-views.png +++ b/doc/src/images/standard-views.png diff --git a/doc/src/platforms/platform-notes.qdoc b/doc/src/platforms/platform-notes.qdoc index 5be66f8..9896b08 100644 --- a/doc/src/platforms/platform-notes.qdoc +++ b/doc/src/platforms/platform-notes.qdoc @@ -67,6 +67,8 @@ \tableofcontents{1 Platform Notes - Windows} \o \l{Platform Notes - Mac OS X} \tableofcontents{1 Platform Notes - Mac OS X} + \o \l{Platform Notes - Symbian} + \tableofcontents{1 Platform Notes - Symbian} \o \l{Platform Notes - Embedded Linux} \tableofcontents{1 Platform Notes - Embedded Linux} \o \l{Platform Notes - Windows CE} @@ -409,7 +411,7 @@ to run on. More information about the combinations of platforms and compilers supported by Qt can be found on the \l{Supported Platforms} page. - For information about mixing exceptions with symbian leaves, + For information about mixing exceptions with Symbian leaves, see \l{Exception Safety with Symbian} \section1 Multimedia and Phonon Support diff --git a/doc/src/platforms/s60-introduction.qdoc b/doc/src/platforms/s60-introduction.qdoc index d145a82..5fd0cbe 100644 --- a/doc/src/platforms/s60-introduction.qdoc +++ b/doc/src/platforms/s60-introduction.qdoc @@ -50,12 +50,12 @@ \tableofcontents \section1 Required tools - + See \l{Qt for Symbian platform Requirements} to see what tools are -required to use Qt for Symbian platform. + required to use Qt for Symbian platform. \section1 Installing Qt and running demos - + Follow the instructions found in \l{Installing Qt on the Symbian platform using binary package} to learn how to install Qt using binary package and how to build and run Qt demos. @@ -69,7 +69,7 @@ required to use Qt for Symbian platform. Qt application on the Symbian platform compared to any of the other platforms supported by Qt is not that big. - Once you have crated a \c .pro file for your project, generate the + Once you have created a \c .pro file for your project, generate the Carbide specific \c Bld.inf and \c .mmp files this way: \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 0 @@ -78,9 +78,9 @@ required to use Qt for Symbian platform. {qmake Tutorial}. Now you can build the Qt for the Symbian platform application with -standard build tools. By default, running \c make will produce binaries for -the emulator. However, the Symbian platform comes with several alternative -build targets, as shown in the table below: + standard build tools. By default, running \c make will produce binaries for + the emulator. However, the Symbian platform comes with several alternative + build targets, as shown in the table below: \table \row \o \c debug-winscw \o Build debug binaries for the emulator (default). @@ -111,19 +111,19 @@ build targets, as shown in the table below: 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: - + \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 2 If you want to use different certificate information or override the default target for \c .sis file creation you can use the environment variables as shown in the table below: - + \table \row \o \c QT_SIS_OPTIONS \o Options accepted by \c .sis creation. -i, install the package right away using PC suite. -c=<file>, read certificate information from a file. - Execute \c{perl createpackage.pl} for more information - about options. + Execute the \c{createpackage.pl} script without any + parameters for more information about options. By default no otions are given. \row \o \c QT_SIS_TARGET \o Target for which \c .sis file is created. Accepted values are build targets listed in @@ -135,15 +135,15 @@ build targets, as shown in the table below: \row \o \c QT_SIS_PASSPHRASE \o The certificate's private key file's passphrase. By default empty. \endtable - + For example: - + \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 4 The environment variables for \c make can also be given as parameters: - + \snippet doc/src/snippets/code/doc_src_s60-introduction.qdoc 3 - + 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 sis target with the \c QT_SIS_OPTIONS=-i, like this: diff --git a/doc/src/porting/qt4-interview.qdoc b/doc/src/porting/qt4-interview.qdoc index 29d9f5c..fd3fb36 100644 --- a/doc/src/porting/qt4-interview.qdoc +++ b/doc/src/porting/qt4-interview.qdoc @@ -109,8 +109,8 @@ \list \o QStandardItemModel is a minimal convenience model that developers can use to manage items of data. - \o QDirModel provides directory information for use with QListView and - QTreeView. + \o QFileSystemModel provides directory information for use with QListView + and QTreeView. \o QStringListModel is a convenience model that can be used to hold strings for views such as QListView and QComboBox. \endlist @@ -153,7 +153,7 @@ In this example, we display the contents of a model using two different views, and share the user's selection between - them. We will use the QDirModel supplied with Qt because it + them. We will use the QFileSystemModel supplied with Qt because it requires very little configuration, and provides existing data to the views. @@ -174,7 +174,7 @@ \image interview-shareddirmodel.png - The model/view architecture allows us to replace the QDirModel in + The model/view architecture allows us to replace the QFileSystemModel in this example with a completely different model, one that will perhaps obtain data from a remote server, or from a database. diff --git a/doc/src/qt4-intro.qdoc b/doc/src/qt4-intro.qdoc index 38f346f..a946540 100644 --- a/doc/src/qt4-intro.qdoc +++ b/doc/src/qt4-intro.qdoc @@ -488,7 +488,7 @@ Qt 4.6 is the first release to include support for the Symbian platform, with integration into the S60 framework. The port to Symbian and S60 provides all functionality required to develop - rich end-user applications for devices running Symbian 3.1 and + rich end-user applications for devices running S60 3.1 and later. \section1 Animation Framework diff --git a/doc/src/snippets/colors/colors.pro b/doc/src/snippets/colors/colors.pro new file mode 100644 index 0000000..b2cc87d --- /dev/null +++ b/doc/src/snippets/colors/colors.pro @@ -0,0 +1,2 @@ +HEADERS = window.h +SOURCES = main.cpp window.cpp diff --git a/tests/manual/gestures/pinch/main.cpp b/doc/src/snippets/colors/main.cpp index 4d9c14c..4e09036 100644 --- a/tests/manual/gestures/pinch/main.cpp +++ b/doc/src/snippets/colors/main.cpp @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the test suite of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -40,29 +40,13 @@ ****************************************************************************/ #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())); -} +#include "window.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); - MainWindow w; - w.show(); + Window window; + window.setFixedSize(640, 215); + window.show(); return app.exec(); } diff --git a/doc/src/snippets/colors/window.cpp b/doc/src/snippets/colors/window.cpp new file mode 100644 index 0000000..0cec5f5 --- /dev/null +++ b/doc/src/snippets/colors/window.cpp @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the documentation of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> +#include "window.h" + +Window::Window(QWidget *parent) + : QWidget(parent) +{ + QFont font; + font.setPixelSize(12); + setFont(font); +} + +void Window::closeEvent(QCloseEvent *event) +{ + QPixmap pixmap(size()); + render(&pixmap); + pixmap.save("qt-colors.png"); + + event->accept(); +} + +void Window::paintEvent(QPaintEvent *) +{ + QPainter painter; + painter.begin(this); + + int h = 216 / 5; + QRect r = QRect(0, 0, 160, h); + painter.fillRect(r, Qt::white); + painter.setPen(Qt::black); + painter.drawText(r, Qt::AlignCenter, QLatin1String("white")); + r = QRect(0, h, 160, h); + painter.fillRect(r, Qt::red); + painter.drawText(r, Qt::AlignCenter, QLatin1String("red")); + r = QRect(0, h*2, 160, h); + painter.fillRect(r, Qt::green); + painter.drawText(r, Qt::AlignCenter, QLatin1String("green")); + r = QRect(0, h*3, 160, h); + painter.fillRect(r, Qt::blue); + painter.setPen(Qt::white); + painter.drawText(r, Qt::AlignCenter, QLatin1String("blue")); + + r = QRect(160, 0, 160, h); + painter.fillRect(r, Qt::black); + painter.drawText(r, Qt::AlignCenter, QLatin1String("black")); + r = QRect(160, h, 160, h); + painter.fillRect(r, Qt::darkRed); + painter.drawText(r, Qt::AlignCenter, QLatin1String("darkRed")); + r = QRect(160, h*2, 160, h); + painter.fillRect(r, Qt::darkGreen); + painter.drawText(r, Qt::AlignCenter, QLatin1String("darkGreen")); + r = QRect(160, h*3, 160, h); + painter.fillRect(r, Qt::darkBlue); + painter.drawText(r, Qt::AlignCenter, QLatin1String("darkBlue")); + + r = QRect(320, 0, 160, h); + painter.fillRect(r, Qt::cyan); + painter.setPen(Qt::black); + painter.drawText(r, Qt::AlignCenter, QLatin1String("cyan")); + r = QRect(320, h, 160, h); + painter.fillRect(r, Qt::magenta); + painter.drawText(r, Qt::AlignCenter, QLatin1String("magenta")); + r = QRect(320, h*2, 160, h); + painter.fillRect(r, Qt::yellow); + painter.drawText(r, Qt::AlignCenter, QLatin1String("yellow")); + r = QRect(320, h*3, 160, h); + painter.fillRect(r, Qt::gray); + painter.setPen(Qt::white); + painter.drawText(r, Qt::AlignCenter, QLatin1String("gray")); + + r = QRect(480, 0, 160, h); + painter.fillRect(r, Qt::darkCyan); + painter.drawText(r, Qt::AlignCenter, QLatin1String("darkCyan")); + r = QRect(480, h, 160, h); + painter.fillRect(r, Qt::darkMagenta); + painter.drawText(r, Qt::AlignCenter, QLatin1String("darkMagenta")); + r = QRect(480, h*2, 160, h); + painter.fillRect(r, Qt::darkYellow); + painter.drawText(r, Qt::AlignCenter, QLatin1String("darkYellow")); + r = QRect(480, h*3, 160, h); + painter.fillRect(r, Qt::darkGray); + painter.drawText(r, Qt::AlignCenter, QLatin1String("darkGray")); + + r = QRect(0, h*4, 640, h); + painter.fillRect(r, Qt::lightGray); + painter.setPen(Qt::black); + painter.drawText(r, Qt::AlignCenter, QLatin1String("lightGray")); + + painter.end(); +} + diff --git a/examples/gestures/imageviewer/tapandholdgesture.h b/doc/src/snippets/colors/window.h index 682342e..3b08b90 100644 --- a/examples/gestures/imageviewer/tapandholdgesture.h +++ b/doc/src/snippets/colors/window.h @@ -4,7 +4,7 @@ ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** -** This file is part of the examples of the Qt Toolkit. +** This file is part of the documentation of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** No Commercial Usage @@ -39,36 +39,15 @@ ** ****************************************************************************/ -#ifndef TAPANDHOLDGESTURE_H -#define TAPANDHOLDGESTURE_H +#include <QWidget> -#include <QtCore/QBasicTimer> -#include <QtGui/QGesture> -#include <QtGui/QWidget> - -class TapAndHoldGesture : public QGesture +class Window : public QWidget { - Q_OBJECT - Q_PROPERTY(QPoint pos READ pos) - public: - TapAndHoldGesture(QWidget *parent); - - bool filterEvent(QEvent *event); - void reset(); - - QPoint pos() const; + Window(QWidget *parent = 0); protected: - void timerEvent(QTimerEvent *event); - -private: - QBasicTimer timer; - int iteration; - QPoint position; - QPoint startPosition; - static const int iterationCount; - static const int iterationTimeout; + void closeEvent(QCloseEvent *event); + void paintEvent(QPaintEvent *event); }; -#endif // TAPANDHOLDGESTURE_H diff --git a/doc/src/snippets/shareddirmodel/main.cpp b/doc/src/snippets/shareddirmodel/main.cpp index 82034b5..3cb63c9 100644 --- a/doc/src/snippets/shareddirmodel/main.cpp +++ b/doc/src/snippets/shareddirmodel/main.cpp @@ -55,7 +55,8 @@ int main(int argc, char *argv[]) QSplitter *splitter = new QSplitter; //! [2] //! [3] - QDirModel *model = new QDirModel; + QFileSystemModel *model = new QFileSystemModel; + model->setRootPath(QDir::currentPath()); //! [0] //! [2] //! [4] //! [5] QTreeView *tree = new QTreeView(splitter); //! [3] //! [6] @@ -74,7 +75,7 @@ int main(int argc, char *argv[]) list->setSelectionModel(selection); //! [8] - splitter->setWindowTitle("Two views onto the same directory model"); + splitter->setWindowTitle("Two views onto the same file system model"); splitter->show(); return app.exec(); } diff --git a/doc/src/snippets/simplemodel-use/main.cpp b/doc/src/snippets/simplemodel-use/main.cpp index a3bb0e7..d7fc755 100644 --- a/doc/src/snippets/simplemodel-use/main.cpp +++ b/doc/src/snippets/simplemodel-use/main.cpp @@ -69,7 +69,7 @@ int main(int argc, char *argv[]) layout->addWidget(title); //! [0] - QDirModel *model = new QDirModel; + QFileSystemModel *model = new QFileSystemModel; QModelIndex parentIndex = model->index(QDir::currentPath()); int numRows = model->rowCount(parentIndex); //! [0] diff --git a/examples/gestures/imageviewer/imageviewer.pro b/examples/gestures/imageviewer/imageviewer.pro index 124175e..68c1f1c 100644 --- a/examples/gestures/imageviewer/imageviewer.pro +++ b/examples/gestures/imageviewer/imageviewer.pro @@ -1,11 +1,14 @@ -HEADERS += imagewidget.h \ - tapandholdgesture.h +HEADERS += imagewidget.h SOURCES += imagewidget.cpp \ - tapandholdgesture.cpp \ main.cpp # install target.path = $$[QT_INSTALL_EXAMPLES]/gestures/imageviewer -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS imageviewer.pro +sources.files = $$SOURCES \ + $$HEADERS \ + $$RESOURCES \ + $$FORMS \ + imageviewer.pro sources.path = $$[QT_INSTALL_EXAMPLES]/gestures/imageviewer -INSTALLS += target sources +INSTALLS += target \ + sources diff --git a/examples/gestures/imageviewer/imagewidget.cpp b/examples/gestures/imageviewer/imagewidget.cpp index 3489b5b..5633942 100644 --- a/examples/gestures/imageviewer/imagewidget.cpp +++ b/examples/gestures/imageviewer/imagewidget.cpp @@ -59,24 +59,16 @@ ImageWidget::ImageWidget(QWidget *parent) setAttribute(Qt::WA_OpaquePaintEvent); setAttribute(Qt::WA_NoSystemBackground); - QGesture *panGesture = new QPanGesture(this); - connect(panGesture, SIGNAL(started()), this, SLOT(panTriggered())); - connect(panGesture, SIGNAL(finished()), this, SLOT(panTriggered())); - connect(panGesture, SIGNAL(canceled()), this, SLOT(panTriggered())); - connect(panGesture, SIGNAL(triggered()), this, SLOT(panTriggered())); - - QGesture *pinchGesture = new QPinchGesture(this); - connect(pinchGesture, SIGNAL(started()), this, SLOT(pinchTriggered())); - connect(pinchGesture, SIGNAL(finished()), this, SLOT(pinchTriggered())); - connect(pinchGesture, SIGNAL(canceled()), this, SLOT(pinchTriggered())); - connect(pinchGesture, SIGNAL(triggered()), this, SLOT(pinchTriggered())); - -//! [construct swipe gesture] - QGesture *swipeGesture = new QSwipeGesture(this); -//! [construct swipe gesture] -//! [connect swipe gesture] - connect(swipeGesture, SIGNAL(triggered()), this, SLOT(swipeTriggered())); -//! [connect swipe gesture] + grabGesture(Qt::PanGesture); + grabGesture(Qt::PinchGesture); + grabGesture(Qt::SwipeGesture); +} + +bool ImageWidget::event(QEvent *event) +{ + if (event->type() == QEvent::Gesture) + return gestureEvent(static_cast<QGestureEvent*>(event)); + return QWidget::event(event); } void ImageWidget::paintEvent(QPaintEvent*) @@ -106,11 +98,25 @@ void ImageWidget::mouseDoubleClickEvent(QMouseEvent *) update(); } -void ImageWidget::panTriggered() +bool ImageWidget::gestureEvent(QGestureEvent *event) +{ + if (QGesture *pan = event->gesture(Qt::PanGesture)) { + panTriggered(static_cast<QPanGesture*>(pan)); + return true; + } else if (QGesture *pinch = event->gesture(Qt::PinchGesture)) { + pinchTriggered(static_cast<QPinchGesture*>(pan)); + return true; + } else if (QGesture *swipe = event->gesture(Qt::SwipeGesture)) { + swipeTriggered(static_cast<QSwipeGesture*>(pan)); + return true; + } + return false; +} + +void ImageWidget::panTriggered(QPanGesture *gesture) { - QPanGesture *pg = qobject_cast<QPanGesture*>(sender()); #ifndef QT_NO_CURSOR - switch (pg->state()) { + switch (gesture->state()) { case Qt::GestureStarted: case Qt::GestureUpdated: setCursor(Qt::SizeAllCursor); @@ -119,33 +125,37 @@ void ImageWidget::panTriggered() setCursor(Qt::ArrowCursor); } #endif - horizontalOffset += pg->lastOffset().width(); - verticalOffset += pg->lastOffset().height(); + QSizeF lastOffset = gesture->property("lastOffset").toSizeF(); + horizontalOffset += lastOffset.width(); + verticalOffset += lastOffset.height(); update(); } -void ImageWidget::pinchTriggered() +void ImageWidget::pinchTriggered(QPinchGesture *gesture) { - QPinchGesture *pg = qobject_cast<QPinchGesture*>(sender()); - if (pg->whatChanged() & QPinchGesture::RotationAngleChanged) - rotationAngle += pg->rotationAngle() - pg->lastRotationAngle(); - if (pg->whatChanged() & QPinchGesture::ScaleFactorChanged) - scaleFactor += pg->scaleFactor() - pg->lastScaleFactor(); + QPinchGesture::WhatChanged whatChanged = gesture->property("whatChanged").value<QPinchGesture::WhatChanged>(); + if (whatChanged & QPinchGesture::RotationAngleChanged) { + qreal value = gesture->property("rotationAngle").toReal(); + qreal lastValue = gesture->property("lastRotationAngle").toReal(); + rotationAngle += value - lastValue; + } + if (whatChanged & QPinchGesture::ScaleFactorChanged) { + qreal value = gesture->property("scaleFactor").toReal(); + qreal lastValue = gesture->property("lastScaleFactor").toReal(); + scaleFactor += value - lastValue; + } update(); } -//! [swipe slot start] -void ImageWidget::swipeTriggered() +void ImageWidget::swipeTriggered(QSwipeGesture *gesture) { - QSwipeGesture *pg = qobject_cast<QSwipeGesture*>(sender()); - if (pg->horizontalDirection() == QSwipeGesture::Left - || pg->verticalDirection() == QSwipeGesture::Up) + if (gesture->horizontalDirection() == QSwipeGesture::Left + || gesture->verticalDirection() == QSwipeGesture::Up) goPrevImage(); else goNextImage(); update(); } -//! [swipe slot start] void ImageWidget::resizeEvent(QResizeEvent*) { diff --git a/examples/gestures/imageviewer/imagewidget.h b/examples/gestures/imageviewer/imagewidget.h index 2a1bfca..e05a67a 100644 --- a/examples/gestures/imageviewer/imagewidget.h +++ b/examples/gestures/imageviewer/imagewidget.h @@ -46,6 +46,11 @@ #include <QImage> #include <QtGui> +class QGestureEvent; +class QPanGesture; +class QPinchGesture; +class QSwipeGesture; + class ImageWidget : public QWidget { Q_OBJECT @@ -56,14 +61,16 @@ public: void openDirectory(const QString &path); protected: + bool event(QEvent*); + bool gestureEvent(QGestureEvent*); void paintEvent(QPaintEvent*); void resizeEvent(QResizeEvent*); void mouseDoubleClickEvent(QMouseEvent*); -private slots: - void panTriggered(); - void pinchTriggered(); - void swipeTriggered(); +private: + void panTriggered(QPanGesture*); + void pinchTriggered(QPinchGesture*); + void swipeTriggered(QSwipeGesture*); private: void updateImage(); diff --git a/examples/gestures/imageviewer/tapandholdgesture.cpp b/examples/gestures/imageviewer/tapandholdgesture.cpp deleted file mode 100644 index a10c192..0000000 --- a/examples/gestures/imageviewer/tapandholdgesture.cpp +++ /dev/null @@ -1,155 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the examples of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "tapandholdgesture.h" - -#include <QtGui/qevent.h> - -// #define TAPANDHOLD_USING_MOUSE - -/*! - \class TapAndHoldGesture - \since 4.6 - - \brief The TapAndHoldGesture class represents a Tap-and-Hold gesture, - providing additional information. -*/ - -const int TapAndHoldGesture::iterationCount = 40; -const int TapAndHoldGesture::iterationTimeout = 50; - -/*! - Creates a new Tap and Hold gesture handler object and marks it as a child - of \a parent. - - On some platforms like Windows there is a system-wide tap and hold gesture - that cannot be overriden, hence the gesture might never trigger and default - context menu will be shown instead. -*/ -TapAndHoldGesture::TapAndHoldGesture(QWidget *parent) - : QGesture(parent), iteration(0) -{ -} - -/*! \internal */ -bool TapAndHoldGesture::filterEvent(QEvent *event) -{ - const QTouchEvent *ev = static_cast<const QTouchEvent*>(event); - switch (event->type()) { - case QEvent::TouchBegin: { - if (timer.isActive()) - timer.stop(); - timer.start(TapAndHoldGesture::iterationTimeout, this); - const QPoint p = ev->touchPoints().at(0).pos().toPoint(); - position = p; - break; - } - case QEvent::TouchUpdate: - if (ev->touchPoints().size() == 1) { - const QPoint startPos = ev->touchPoints().at(0).startPos().toPoint(); - const QPoint pos = ev->touchPoints().at(0).pos().toPoint(); - if ((startPos - pos).manhattanLength() > 15) - reset(); - } else { - reset(); - } - break; - case QEvent::TouchEnd: - reset(); - break; -#ifdef TAPANDHOLD_USING_MOUSE - case QEvent::MouseButtonPress: { - if (timer.isActive()) - timer.stop(); - timer.start(TapAndHoldGesture::iterationTimeout, this); - const QPoint p = static_cast<QMouseEvent*>(event)->pos(); - position = startPosition = p; - break; - } - case QEvent::MouseMove: { - const QPoint startPos = startPosition; - const QPoint pos = static_cast<QMouseEvent*>(event)->pos(); - if ((startPos - pos).manhattanLength() > 15) - reset(); - break; - } - case QEvent::MouseButtonRelease: - reset(); - break; -#endif // TAPANDHOLD_USING_MOUSE - default: - break; - } - return false; -} - -/*! \internal */ -void TapAndHoldGesture::timerEvent(QTimerEvent *event) -{ - if (event->timerId() != timer.timerId()) - return; - if (iteration == TapAndHoldGesture::iterationCount) { - timer.stop(); - updateState(Qt::GestureFinished); - } else { - updateState(Qt::GestureUpdated); - } - ++iteration; -} - -/*! \internal */ -void TapAndHoldGesture::reset() -{ - timer.stop(); - iteration = 0; - position = startPosition = QPoint(); - updateState(Qt::NoGesture); -} - -/*! - \property TapAndHoldGesture::pos - - \brief The position of the gesture. -*/ -QPoint TapAndHoldGesture::pos() const -{ - return position; -} diff --git a/examples/network/fortuneclient/fortuneclient.pro b/examples/network/fortuneclient/fortuneclient.pro index d7ad9d5..c9dc39a 100644 --- a/examples/network/fortuneclient/fortuneclient.pro +++ b/examples/network/fortuneclient/fortuneclient.pro @@ -11,7 +11,7 @@ INSTALLS += target sources symbian { include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/ftp/sym_iap_util.h + HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h LIBS += -lesock TARGET.CAPABILITY = "NetworkServices ReadUserData WriteUserData" TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 diff --git a/examples/network/fortuneserver/fortuneserver.pro b/examples/network/fortuneserver/fortuneserver.pro index 803c2f2..4dbc2e8 100644 --- a/examples/network/fortuneserver/fortuneserver.pro +++ b/examples/network/fortuneserver/fortuneserver.pro @@ -12,7 +12,7 @@ INSTALLS += target sources symbian { TARGET.UID3 = 0xA000CF71 include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/ftp/sym_iap_util.h + HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h LIBS += -lesock TARGET.CAPABILITY = "All -TCB" TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 diff --git a/examples/network/network-chat/network-chat.pro b/examples/network/network-chat/network-chat.pro index 99e82ae..16c11e3 100644 --- a/examples/network/network-chat/network-chat.pro +++ b/examples/network/network-chat/network-chat.pro @@ -20,7 +20,7 @@ INSTALLS += target sources symbian { include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) - HEADERS += $$QT_SOURCE_TREE/examples/network/ftp/sym_iap_util.h + HEADERS += $$QT_SOURCE_TREE/examples/network/qftp/sym_iap_util.h LIBS += -lesock -lconnmon -lcharconv -linsock TARGET.CAPABILITY = "NetworkServices ReadUserData WriteUserData" TARGET.EPOCHEAPSIZE = 0x20000 0x2000000 diff --git a/examples/network/network.pro b/examples/network/network.pro index 38cdae8..0849271 100644 --- a/examples/network/network.pro +++ b/examples/network/network.pro @@ -6,7 +6,7 @@ SUBDIRS = blockingfortuneclient \ downloadmanager \ fortuneclient \ fortuneserver \ - ftp \ + qftp \ http \ loopback \ threadedfortuneserver \ @@ -16,7 +16,7 @@ SUBDIRS = blockingfortuneclient \ # no QProcess !vxworks:!qnx:SUBDIRS += network-chat -symbian: SUBDIRS = ftp +symbian: SUBDIRS = qftp contains(QT_CONFIG, openssl):SUBDIRS += securesocketclient diff --git a/examples/network/ftp/ftp.qrc b/examples/network/qftp/ftp.qrc index b598ab8..b598ab8 100644 --- a/examples/network/ftp/ftp.qrc +++ b/examples/network/qftp/ftp.qrc diff --git a/examples/network/ftp/ftpwindow.cpp b/examples/network/qftp/ftpwindow.cpp index f3fc52b..f3fc52b 100644 --- a/examples/network/ftp/ftpwindow.cpp +++ b/examples/network/qftp/ftpwindow.cpp diff --git a/examples/network/ftp/ftpwindow.h b/examples/network/qftp/ftpwindow.h index f92c36a..f92c36a 100644 --- a/examples/network/ftp/ftpwindow.h +++ b/examples/network/qftp/ftpwindow.h diff --git a/examples/network/ftp/images/cdtoparent.png b/examples/network/qftp/images/cdtoparent.png Binary files differindex 24b6180..24b6180 100644 --- a/examples/network/ftp/images/cdtoparent.png +++ b/examples/network/qftp/images/cdtoparent.png diff --git a/examples/network/ftp/images/dir.png b/examples/network/qftp/images/dir.png Binary files differindex 0ce5ae7..0ce5ae7 100644 --- a/examples/network/ftp/images/dir.png +++ b/examples/network/qftp/images/dir.png diff --git a/examples/network/ftp/images/file.png b/examples/network/qftp/images/file.png Binary files differindex be6c530..be6c530 100644 --- a/examples/network/ftp/images/file.png +++ b/examples/network/qftp/images/file.png diff --git a/examples/network/ftp/main.cpp b/examples/network/qftp/main.cpp index d44ccd7..d44ccd7 100644 --- a/examples/network/ftp/main.cpp +++ b/examples/network/qftp/main.cpp diff --git a/examples/network/ftp/ftp.pro b/examples/network/qftp/qftp.pro index ce2a97b..b3106c3 100644 --- a/examples/network/ftp/ftp.pro +++ b/examples/network/qftp/qftp.pro @@ -5,9 +5,9 @@ RESOURCES += ftp.qrc QT += network # install -target.path = $$[QT_INSTALL_EXAMPLES]/network/ftp -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS ftp.pro images -sources.path = $$[QT_INSTALL_EXAMPLES]/network/ftp +target.path = $$[QT_INSTALL_EXAMPLES]/network/qftp +sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS *.pro images +sources.path = $$[QT_INSTALL_EXAMPLES]/network/qftp INSTALLS += target sources symbian { diff --git a/examples/network/ftp/sym_iap_util.h b/examples/network/qftp/sym_iap_util.h index ebeae0a..ebeae0a 100644 --- a/examples/network/ftp/sym_iap_util.h +++ b/examples/network/qftp/sym_iap_util.h diff --git a/examples/phonon/phonon.pro b/examples/phonon/phonon.pro index 0ddf767..aa6ac13 100644 --- a/examples/phonon/phonon.pro +++ b/examples/phonon/phonon.pro @@ -1,6 +1,6 @@ TEMPLATE = subdirs CONFIG += ordered -SUBDIRS = musicplayer \ +SUBDIRS = qmusicplayer \ capabilities # install diff --git a/examples/phonon/musicplayer/main.cpp b/examples/phonon/qmusicplayer/main.cpp index fc7baa3..fc7baa3 100644 --- a/examples/phonon/musicplayer/main.cpp +++ b/examples/phonon/qmusicplayer/main.cpp diff --git a/examples/phonon/musicplayer/mainwindow.cpp b/examples/phonon/qmusicplayer/mainwindow.cpp index 787ae53..787ae53 100644 --- a/examples/phonon/musicplayer/mainwindow.cpp +++ b/examples/phonon/qmusicplayer/mainwindow.cpp diff --git a/examples/phonon/musicplayer/mainwindow.h b/examples/phonon/qmusicplayer/mainwindow.h index 41f8147..41f8147 100644 --- a/examples/phonon/musicplayer/mainwindow.h +++ b/examples/phonon/qmusicplayer/mainwindow.h diff --git a/examples/phonon/musicplayer/musicplayer.pro b/examples/phonon/qmusicplayer/qmusicplayer.pro index a0c953a..25ab7eb 100644 --- a/examples/phonon/musicplayer/musicplayer.pro +++ b/examples/phonon/qmusicplayer/qmusicplayer.pro @@ -5,9 +5,9 @@ SOURCES += main.cpp \ mainwindow.cpp # install -target.path = $$[QT_INSTALL_EXAMPLES]/phonon/musicplayer +target.path = $$[QT_INSTALL_EXAMPLES]/phonon/qmusicplayer sources.files = $$SOURCES $$HEADERS $$FORMS $$RESOURCES *.pro *.png images -sources.path = $$[QT_INSTALL_EXAMPLES]/phonon/musicplayer +sources.path = $$[QT_INSTALL_EXAMPLES]/phonon/qmusicplayer INSTALLS += target sources wince*{ diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp index f2148d0..f3ded7e 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/wtf/FastMalloc.cpp @@ -103,6 +103,11 @@ #define USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY 1 #endif +#if defined(__HP_aCC) +// HP'a aCC compiler has broken for scoping +# define for if(0){}else for +#endif + #ifndef NDEBUG namespace WTF { @@ -2902,7 +2907,7 @@ TCMalloc_ThreadCache* TCMalloc_ThreadCache::CreateCacheIfNecessary() { // Initialize per-thread data if necessary TCMalloc_ThreadCache* heap = NULL; { - SpinLockHolder h(&pageheap_lock); + SpinLockHolder lockholder(&pageheap_lock); #if COMPILER(MSVC) DWORD me; diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 4f7dd4f..493a64d 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,13 @@ +2009-10-09 Joe Ligman <joseph.ligman@nokia.com> + + Reviewed by Simon Hausmann. + + [Qt] Added pure virtual methods setInputMethodEnabled and setInputMethodHint to QWebPageClient + + https://bugs.webkit.org/show_bug.cgi?id=30023 + + * platform/qt/QWebPageClient.h: + 2009-10-07 Janne Koskinen <janne.p.koskinen@digia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/platform/qt/QWebPageClient.h b/src/3rdparty/webkit/WebCore/platform/qt/QWebPageClient.h index 1fc29a0..37941eb 100644 --- a/src/3rdparty/webkit/WebCore/platform/qt/QWebPageClient.h +++ b/src/3rdparty/webkit/WebCore/platform/qt/QWebPageClient.h @@ -33,6 +33,10 @@ public: virtual void scroll(int dx, int dy, const QRect&) = 0; virtual void update(const QRect&) = 0; + virtual void setInputMethodEnabled(bool enable) = 0; +#if QT_VERSION >= 0x040600 + virtual void setInputMethodHint(Qt::InputMethodHint hint, bool enable) = 0; +#endif inline void resetCursor() { if (!cursor().bitmap() && cursor().shape() == m_lastCursor.shape()) diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp index 2a0ee20..b11890d 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp @@ -44,6 +44,10 @@ public: virtual void scroll(int dx, int dy, const QRect&); virtual void update(const QRect& dirtyRect); + virtual void setInputMethodEnabled(bool enable); +#if QT_VERSION >= 0x040600 + virtual void setInputMethodHint(Qt::InputMethodHint hint, bool enable); +#endif virtual QCursor cursor() const; virtual void updateCursor(const QCursor& cursor); @@ -95,6 +99,21 @@ void QGraphicsWebViewPrivate::update(const QRect & dirtyRect) q->update(QRectF(dirtyRect)); } +void QGraphicsWebViewPrivate::setInputMethodEnabled(bool enable) +{ + q->setAttribute(Qt::WA_InputMethodEnabled, enable); +} + +#if QT_VERSION >= 0x040600 +void QGraphicsWebViewPrivate::setInputMethodHint(Qt::InputMethodHint hint, bool enable) +{ + if (enable) + q->setInputMethodHints(q->inputMethodHints() | hint); + else + q->setInputMethodHints(q->inputMethodHints() & ~hint); +} +#endif + QCursor QGraphicsWebViewPrivate::cursor() const { return q->cursor(); diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp index 882f3d7..b06b93a 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebview.cpp @@ -47,6 +47,10 @@ public: virtual void scroll(int dx, int dy, const QRect&); virtual void update(const QRect& dirtyRect); + virtual void setInputMethodEnabled(bool enable); +#if QT_VERSION >= 0x040600 + virtual void setInputMethodHint(Qt::InputMethodHint hint, bool enable); +#endif virtual QCursor cursor() const; virtual void updateCursor(const QCursor& cursor); @@ -72,6 +76,20 @@ void QWebViewPrivate::update(const QRect & dirtyRect) view->update(dirtyRect); } +void QWebViewPrivate::setInputMethodEnabled(bool enable) +{ + view->setAttribute(Qt::WA_InputMethodEnabled, enable); +} +#if QT_VERSION >= 0x040600 +void QWebViewPrivate::setInputMethodHint(Qt::InputMethodHint hint, bool enable) +{ + if (enable) + view->setInputMethodHints(view->inputMethodHints() | hint); + else + view->setInputMethodHints(view->inputMethodHints() & ~hint); +} +#endif + QCursor QWebViewPrivate::cursor() const { return view->cursor(); diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index 99ddaa5..85d0e4f 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,29 @@ +2009-10-09 Joe Ligman <joseph.ligman@nokia.com> + + Reviewed by Simon Hausmann. + + Sets Qt::WA_InputMethodEnabled and Qt::ImhHiddenText for password fields in EditorClientQt + setInputMethodState. This change is needed so widgets such as the s60 software + input panel can receive input method events for password fields. + It's up to the Qt platform to determine which widget will receive input method + events when these flags are set. + Also added implementation for setInputMethodEnabled and setInputMethodHint + to QGraphicsWebViewPrivate and QWebViewPrivate. This change removes the direct + dependency on QWebView and uses QWebPageClient. + Added autotest to tst_qwebpage.cpp + https://bugs.webkit.org/show_bug.cgi?id=30023 + + * Api/qgraphicswebview.cpp: + (QGraphicsWebViewPrivate::setInputMethodEnabled): + (QGraphicsWebViewPrivate::setInputMethodHint): + * Api/qwebview.cpp: + (QWebViewPrivate::setInputMethodEnabled): + (QWebViewPrivate::setInputMethodHint): + * WebCoreSupport/EditorClientQt.cpp: + (WebCore::EditorClientQt::setInputMethodState): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::inputMethods): + 2009-10-06 Janne Koskinen <janne.p.koskinen@digia.com> Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp index 5d5df97..34241f0 100644 --- a/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp +++ b/src/3rdparty/webkit/WebKit/qt/WebCoreSupport/EditorClientQt.cpp @@ -41,6 +41,7 @@ #include "FocusController.h" #include "Frame.h" #include "HTMLElement.h" +#include "HTMLInputElement.h" #include "HTMLNames.h" #include "KeyboardCodes.h" #include "KeyboardEvent.h" @@ -48,6 +49,7 @@ #include "Page.h" #include "Page.h" #include "PlatformKeyboardEvent.h" +#include "QWebPageClient.h" #include "Range.h" #include <stdio.h> @@ -596,10 +598,26 @@ bool EditorClientQt::isEditing() const void EditorClientQt::setInputMethodState(bool active) { - QWidget *view = m_page->view(); - if (view) - view->setAttribute(Qt::WA_InputMethodEnabled, active); - + QWebPageClient* webPageClient = m_page->d->client; + if (webPageClient) { +#if QT_VERSION >= 0x040600 + bool isPasswordField = false; + if (!active) { + // Setting the Qt::WA_InputMethodEnabled attribute true and Qt::ImhHiddenText flag + // for password fields. The Qt platform is responsible for determining which widget + // will receive input method events for password fields. + Frame* frame = m_page->d->page->focusController()->focusedOrMainFrame(); + if (frame && frame->document() && frame->document()->focusedNode()) { + if (frame->document()->focusedNode()->hasTagName(HTMLNames::inputTag)) { + HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(frame->document()->focusedNode()); + active = isPasswordField = inputElement->isPasswordField(); + } + } + } + webPageClient->setInputMethodHint(Qt::ImhHiddenText, isPasswordField); +#endif + webPageClient->setInputMethodEnabled(active); + } emit m_page->microFocusChanged(); } diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 8f9a740..bdcc27f 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -1208,7 +1208,8 @@ void tst_QWebPage::frameAt() void tst_QWebPage::inputMethods() { m_view->page()->mainFrame()->setHtml("<html><body>" \ - "<input type='text' id='input1' style='font-family: serif' value='' maxlength='20'/>" \ + "<input type='text' id='input1' style='font-family: serif' value='' maxlength='20'/><br>" \ + "<input type='password'/>" \ "</body></html>"); m_view->page()->mainFrame()->setFocus(); @@ -1291,6 +1292,21 @@ void tst_QWebPage::inputMethods() value = variant.value<QString>(); QCOMPARE(value, QString("QtWebKit")); #endif + + //ImhHiddenText + QMouseEvent evpresPassword(QEvent::MouseButtonPress, inputs.at(1).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + m_view->page()->event(&evpresPassword); + QMouseEvent evrelPassword(QEvent::MouseButtonRelease, inputs.at(1).geometry().center(), Qt::LeftButton, Qt::NoButton, Qt::NoModifier); + m_view->page()->event(&evrelPassword); + + QVERIFY(m_view->testAttribute(Qt::WA_InputMethodEnabled)); +#if QT_VERSION >= 0x040600 + QVERIFY(m_view->inputMethodHints() & Qt::ImhHiddenText); + + m_view->page()->event(&evpres); + m_view->page()->event(&evrel); + QVERIFY(!(m_view->inputMethodHints() & Qt::ImhHiddenText)); +#endif } // import a little DRT helper function to trigger the garbage collector diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index 742f4ec..9fc3c8d 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -46,6 +46,7 @@ #include "qthreadstorage.h" #include "qdir.h" #include "qstringlist.h" +#include "qdatetime.h" #ifndef QT_NO_QOBJECT #include <private/qthread_p.h> @@ -2523,6 +2524,33 @@ void qsrand(uint seed) #endif } +/*! \internal + \relates <QtGlobal> + \since 4.6 + + Seed the PRNG, but only if it has not already been seeded. + + The default seed is a combination of current time, a stack address and a + serial counter (since thread stack addresses are re-used). +*/ +void qsrand() +{ +#if defined(Q_OS_UNIX) && !defined(QT_NO_THREAD) && !defined(Q_OS_SYMBIAN) + SeedStorageType *pseed = randTLS()->localData(); + if (pseed) { + // already seeded + return; + } + randTLS()->setLocalData(pseed = new SeedStorageType); + static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0); + *pseed = QDateTime::currentDateTime().toTime_t() + + quintptr(&pseed) + + serial.fetchAndAddRelaxed(1); +#else + // On Windows, we assume that rand() already does the right thing +#endif +} + /*! \relates <QtGlobal> \since 4.2 diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 4234a7e..ad4bc55 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -501,8 +501,6 @@ public: WA_WState_AcceptedTouchBeginEvent = 122, WA_TouchPadAcceptSingleTouchEvents = 123, - WA_DontUseStandardGestures = 124, - // Add new attributes before this line WA_AttributeCount }; @@ -1615,9 +1613,29 @@ public: enum GestureState { NoGesture, - GestureStarted = 1, - GestureUpdated = 2, - GestureFinished = 3 + GestureStarted = 1, + GestureUpdated = 2, + GestureFinished = 3, + GestureCanceled = 4 + }; + + enum GestureType + { + TapGesture = 1, + TapAndHoldGesture = 2, + PanGesture = 3, + PinchGesture = 4, + SwipeGesture = 5, + + CustomGesture = 0x0100, + + LastGestureType = ~0u + }; + + enum GestureContext + { + WidgetGesture = 0, + WidgetWithChildrenGesture = 3 }; enum NavigationMode @@ -1638,7 +1656,6 @@ public: ; #endif - Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::MouseButtons) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::Orientations) Q_DECLARE_OPERATORS_FOR_FLAGS(Qt::KeyboardModifiers) diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index ab232bf..385edad 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -1225,8 +1225,6 @@ \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/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index 744e6a9..5883042 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -228,6 +228,8 @@ QT_BEGIN_NAMESPACE \value TouchBegin Beginning of a sequence of touch-screen and/or track-pad events (QTouchEvent) \value TouchUpdate Touch-screen event (QTouchEvent) \value TouchEnd End of touch-event sequence (QTouchEvent) + \value Gesture A gesture was triggered (QGestureEvent) + \value GestureOverride A gesture override was triggered (QGestureEvent) User events should have values between \c User and \c{MaxUser}: diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h index d66cead..ee1e1b9 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -283,6 +283,9 @@ public: UpdateSoftKeys = 201, // Internal for compressing soft key updates + Gesture = 198, + GestureOverride = 202, + // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event @@ -324,6 +327,7 @@ private: friend class QGraphicsView; friend class QGraphicsViewPrivate; friend class QGraphicsScenePrivate; + friend class QGestureManager; }; class Q_CORE_EXPORT QTimerEvent : public QEvent diff --git a/src/corelib/plugin/quuid.cpp b/src/corelib/plugin/quuid.cpp index 7224ad3..3c79653 100644 --- a/src/corelib/plugin/quuid.cpp +++ b/src/corelib/plugin/quuid.cpp @@ -548,9 +548,11 @@ bool QUuid::operator>(const QUuid &other) const On any platform other than Windows, this function returns a new UUID with variant QUuid::DCE and version QUuid::Random. The random numbers used to construct the UUID are obtained from the local - pseudo-random generator, which is usually not a cryptographic + pseudo-random generator, qrand(), which is usually not a cryptographic quality random number generator. Therefore, a UUID generated by - this function can't be guaranteed to be unique. + this function can't be guaranteed to be unique. If the pseudo-random + number generator for the calling thread has not yet been seeded, this + function will seed the pseudo-random number generator by calling qsrand(). On a Windows platform, a GUID is generated, which almost certainly \e{will} be unique, on this or any other system, networked or not. @@ -578,6 +580,8 @@ QT_BEGIN_INCLUDE_NAMESPACE #include "stdlib.h" // For srand/rand QT_END_INCLUDE_NAMESPACE +extern void qsrand(); // in qglobal.cpp + QUuid QUuid::createUuid() { static const int intbits = sizeof(int)*8; @@ -585,10 +589,11 @@ QUuid QUuid::createUuid() if (!randbits) { int max = RAND_MAX; do { ++randbits; } while ((max=max>>1)); - qsrand((uint)QDateTime::currentDateTime().toTime_t()); - qrand(); // Skip first } + // reseed, but only if not already seeded + qsrand(); + QUuid result; uint *data = &(result.data1); int chunks = 16 / sizeof(uint); diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 1277623..1b559cf 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -54,6 +54,7 @@ #ifndef Q_WS_WIN #include <locale.h> #endif + #include <time.h> #if defined(Q_OS_WINCE) #include "qfunctions_wince.h" @@ -68,31 +69,6 @@ # define QDTPDEBUGN if (false) qDebug #endif -#if defined(Q_OS_SYMBIAN) - // Workaround for OpenC bug. - - // OpenC incorrectly caches DST information between localtime_r - // calls, i.e. if previous call to localtime_r has been called for DST - // affected date, also the second call will be affected by DST even - // the date is such that DST should not be applied. - - // The workaround is to call mktime with non-DST affected date before - // calling localtime_r. mktime call resets the OpenC internal DST cache - // to right value and localtime_r will return correct values. -#define FIX_OPENC_DSTCACHE \ - tm localTM; \ - localTM.tm_sec = 0; \ - localTM.tm_min = 0; \ - localTM.tm_hour = 12; \ - localTM.tm_mday = 1; \ - localTM.tm_mon = 1; \ - localTM.tm_year = 2002 - 1900; \ - localTM.tm_isdst = -1; \ - time_t temp = mktime(&localTM); -#else -#define FIX_OPENC_DSTCACHE -#endif - #if defined(Q_WS_MAC) #include <private/qcore_mac_p.h> #endif @@ -1162,7 +1138,6 @@ QDate QDate::currentDate() // use the reentrant version of localtime() where available tzset(); tm res; - FIX_OPENC_DSTCACHE t = localtime_r(<ime, &res); #else t = localtime(<ime); @@ -1859,13 +1834,12 @@ QTime QTime::currentTime() // use the reentrant version of localtime() where available tzset(); tm res; - FIX_OPENC_DSTCACHE t = localtime_r(<ime, &res); #else t = localtime(<ime); #endif Q_CHECK_PTR(t); - + ct.mds = MSECS_PER_HOUR * t->tm_hour + MSECS_PER_MIN * t->tm_min + 1000 * t->tm_sec + tv.tv_usec / 1000; #else @@ -2913,7 +2887,6 @@ QDateTime QDateTime::currentDateTime() // use the reentrant version of localtime() where available tzset(); tm res; - FIX_OPENC_DSTCACHE t = localtime_r(<ime, &res); #else t = localtime(<ime); @@ -3731,7 +3704,6 @@ static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) // use the reentrant version of localtime() where available tzset(); tm res; - FIX_OPENC_DSTCACHE brokenDown = localtime_r(&secsSince1Jan1970UTC, &res); #elif defined(_MSC_VER) && _MSC_VER >= 1400 tm res; diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 3069733..81bbb5c 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -663,6 +663,8 @@ #include <private/qpixmap_x11_p.h> #endif +#include <private/qgesturemanager_p.h> + #include <math.h> QT_BEGIN_NAMESPACE @@ -7285,6 +7287,13 @@ QGraphicsObject::QGraphicsObject(QGraphicsItemPrivate &dd, QGraphicsItem *parent QGraphicsItem::d_ptr->isObject = true; } +void QGraphicsObject::grabGesture(Qt::GestureType type, Qt::GestureContext context) +{ + QGraphicsItemPrivate * const d = QGraphicsItem::d_func(); + d->gestureContext.insert(type, context); + (void)QGestureManager::instance(); // create a gesture manager +} + /*! \property QGraphicsObject::parent \brief the parent of the item diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index e6e324a..2665235 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -464,6 +464,7 @@ private: friend class QGraphicsSceneBspTree; friend class QGraphicsView; friend class QGraphicsViewPrivate; + friend class QGraphicsObject; friend class QGraphicsWidget; friend class QGraphicsWidgetPrivate; friend class QGraphicsProxyWidgetPrivate; @@ -473,6 +474,7 @@ private: friend class QGraphicsSceneBspTreeIndexPrivate; friend class QGraphicsItemEffectSourcePrivate; friend class QGraphicsTransformPrivate; + friend class QGestureManager; friend class ::tst_QGraphicsItem; friend bool qt_closestLeaf(const QGraphicsItem *, const QGraphicsItem *); friend bool qt_closestItemFirst(const QGraphicsItem *, const QGraphicsItem *); @@ -553,6 +555,8 @@ public: using QObject::children; #endif + void grabGesture(Qt::GestureType type, Qt::GestureContext context = Qt::WidgetWithChildrenGesture); + Q_SIGNALS: void parentChanged(); void opacityChanged(); diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h index 51bfea1..6550362 100644 --- a/src/gui/graphicsview/qgraphicsitem_p.h +++ b/src/gui/graphicsview/qgraphicsitem_p.h @@ -450,6 +450,7 @@ public: QGraphicsItem *focusScopeItem; Qt::InputMethodHints imHints; QGraphicsItem::PanelModality panelModality; + QMap<Qt::GestureType, Qt::GestureContext> gestureContext; // Packed 32 bits quint32 acceptedMouseButtons : 5; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index 056a7ce..0773559 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -5478,11 +5478,11 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent) } if (itemsNeedingEvents.isEmpty()) { - sceneTouchEvent->ignore(); + sceneTouchEvent->accept(); return; } - bool acceptSceneTouchEvent = false; + bool ignoreSceneTouchEvent = true; QHash<QGraphicsItem *, StatesAndTouchPoints>::ConstIterator it = itemsNeedingEvents.constBegin(); const QHash<QGraphicsItem *, StatesAndTouchPoints>::ConstIterator end = itemsNeedingEvents.constEnd(); for (; it != end; ++it) { @@ -5525,19 +5525,20 @@ void QGraphicsScenePrivate::touchEventHandler(QTouchEvent *sceneTouchEvent) item->d_ptr->acceptedTouchBeginEvent = true; bool res = sendTouchBeginEvent(item, &touchEvent) && touchEvent.isAccepted(); - acceptSceneTouchEvent = acceptSceneTouchEvent || res; + if (!res) + ignoreSceneTouchEvent = false; break; } default: if (item->d_ptr->acceptedTouchBeginEvent) { updateTouchPointsForItem(item, &touchEvent); (void) sendEvent(item, &touchEvent); - acceptSceneTouchEvent = true; + ignoreSceneTouchEvent = false; } break; } } - sceneTouchEvent->setAccepted(acceptSceneTouchEvent); + sceneTouchEvent->setAccepted(ignoreSceneTouchEvent); } bool QGraphicsScenePrivate::sendTouchBeginEvent(QGraphicsItem *origin, QTouchEvent *touchEvent) diff --git a/src/gui/graphicsview/qgraphicsscene.h b/src/gui/graphicsview/qgraphicsscene.h index ba47530..d6d48d7 100644 --- a/src/gui/graphicsview/qgraphicsscene.h +++ b/src/gui/graphicsview/qgraphicsscene.h @@ -311,6 +311,7 @@ private: friend class QGraphicsSceneBspTreeIndex; friend class QGraphicsSceneBspTreeIndexPrivate; friend class QGraphicsItemEffectSourcePrivate; + friend class QGesture; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QGraphicsScene::SceneLayers) diff --git a/src/gui/itemviews/qheaderview.cpp b/src/gui/itemviews/qheaderview.cpp index a754579..fc9820f 100644 --- a/src/gui/itemviews/qheaderview.cpp +++ b/src/gui/itemviews/qheaderview.cpp @@ -524,10 +524,8 @@ QSize QHeaderView::sizeHint() const Q_D(const QHeaderView); if (d->cachedSizeHint.isValid()) return d->cachedSizeHint; - int width = 0; - int height = 0; + d->cachedSizeHint = QSize(0, 0); //reinitialize the cached size hint const int sectionCount = count(); - d->executePostedLayout(); // get size hint for the first n sections int i = 0; diff --git a/src/gui/kernel/kernel.pri b/src/gui/kernel/kernel.pri index 760d73c..88c1f73 100644 --- a/src/gui/kernel/kernel.pri +++ b/src/gui/kernel/kernel.pri @@ -45,10 +45,11 @@ HEADERS += \ kernel/qkeymapper_p.h \ kernel/qgesture.h \ kernel/qgesture_p.h \ - kernel/qstandardgestures.h \ - kernel/qstandardgestures_p.h \ - kernel/qsoftkeymanager_p.h \ - kernel/qguiplatformplugin_p.h + kernel/qstandardgestures_p.h \ + kernel/qgesturerecognizer.h \ + kernel/qgesturemanager_p.h \ + kernel/qsoftkeymanager_p.h \ + kernel/qguiplatformplugin_p.h SOURCES += \ kernel/qaction.cpp \ @@ -79,13 +80,18 @@ SOURCES += \ kernel/qwidgetaction.cpp \ kernel/qkeymapper.cpp \ kernel/qgesture.cpp \ - kernel/qstandardgestures.cpp \ - kernel/qsoftkeymanager.cpp \ - kernel/qguiplatformplugin.cpp + kernel/qstandardgestures.cpp \ + kernel/qgesturerecognizer.cpp \ + kernel/qgesturemanager.cpp \ + kernel/qsoftkeymanager.cpp \ + kernel/qguiplatformplugin.cpp win32 { DEFINES += QT_NO_DIRECTDRAW + HEADERS += \ + kernel/qwinnativepangesturerecognizer_win_p.h + SOURCES += \ kernel/qapplication_win.cpp \ kernel/qclipboard_win.cpp \ @@ -96,7 +102,8 @@ win32 { kernel/qsound_win.cpp \ kernel/qwidget_win.cpp \ kernel/qole_win.cpp \ - kernel/qkeymapper_win.cpp + kernel/qkeymapper_win.cpp \ + kernel/qwinnativepangesturerecognizer_win.cpp !contains(DEFINES, QT_NO_DIRECTDRAW):LIBS += ddraw.lib } diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 43addb6..afc6f63 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -99,6 +99,9 @@ #include "qapplication.h" +#include "qgesture.h" +#include "private/qgesturemanager_p.h" + #ifndef QT_NO_LIBRARY #include "qlibrary.h" #endif @@ -154,6 +157,14 @@ bool QApplicationPrivate::autoSipEnabled = false; bool QApplicationPrivate::autoSipEnabled = true; #endif +QGestureManager* QGestureManager::instance() +{ + QApplicationPrivate *d = qApp->d_func(); + if (!d->gestureManager) + d->gestureManager = new QGestureManager(qApp); + return d->gestureManager; +} + QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::Type type) : QCoreApplicationPrivate(argc, argv) { @@ -177,6 +188,8 @@ QApplicationPrivate::QApplicationPrivate(int &argc, char **argv, QApplication::T directPainters = 0; #endif + gestureManager = 0; + if (!self) self = this; } @@ -3632,6 +3645,13 @@ bool QApplication::notify(QObject *receiver, QEvent *e) #endif // !QT_NO_WHEELEVENT || !QT_NO_TABLETEVENT } + // walk through parents and check for gestures + if (d->gestureManager) { + if (d->gestureManager->filterEvent(receiver, e)) + return true; + } + + // User input and window activation makes tooltips sleep switch (e->type()) { case QEvent::Wheel: @@ -4133,6 +4153,65 @@ bool QApplication::notify(QObject *receiver, QEvent *e) } break; } + case QEvent::Gesture: + case QEvent::GestureOverride: + { + if (receiver->isWidgetType()) { + QWidget *w = static_cast<QWidget *>(receiver); + QGestureEvent *gestureEvent = static_cast<QGestureEvent *>(e); + QList<QGesture *> allGestures = gestureEvent->allGestures(); + + bool eventAccepted = gestureEvent->isAccepted(); + bool wasAccepted = eventAccepted; + while (w) { + // send only gestures the widget expects + QList<QGesture *> gestures; + QWidgetPrivate *wd = w->d_func(); + for (int i = 0; i < allGestures.size();) { + QGesture *g = allGestures.at(i); + Qt::GestureType type = g->gestureType(); + if (wd->gestureContext.contains(type)) { + allGestures.removeAt(i); + gestures.append(g); + gestureEvent->setAccepted(g, false); + } else { + ++i; + } + } + if (!gestures.isEmpty()) { + QGestureEvent ge(gestures); + ge.t = gestureEvent->t; + ge.spont = gestureEvent->spont; + ge.m_accept = wasAccepted; + res = d->notify_helper(w, &ge); + gestureEvent->spont = false; + eventAccepted = ge.isAccepted(); + if (res && eventAccepted) + break; + if (!eventAccepted) { + // ### two ways to ignore the event/gesture + + // if the whole event wasn't accepted, put back those + // gestures that were not accepted. + for (int i = 0; i < gestures.size(); ++i) { + QGesture *g = gestures.at(i); + if (!ge.isAccepted(g)) + allGestures.append(g); + } + } + } + if (allGestures.isEmpty()) + break; + if (w->isWindow()) + break; + w = w->parentWidget(); + } + gestureEvent->m_accept = eventAccepted; + } else { + res = d->notify_helper(receiver, e); + } + break; + } default: res = d->notify_helper(receiver, e); break; @@ -5540,6 +5619,16 @@ Q_GUI_EXPORT void qt_translateRawTouchEvent(QWidget *window, QApplicationPrivate::translateRawTouchEvent(window, deviceType, touchPoints); } +Qt::GestureType QApplication::registerGestureRecognizer(QGestureRecognizer *recognizer) +{ + return QGestureManager::instance()->registerGestureRecognizer(recognizer); +} + +void QApplication::unregisterGestureRecognizer(Qt::GestureType type) +{ + QGestureManager::instance()->unregisterGestureRecognizer(type); +} + QT_END_NAMESPACE #include "moc_qapplication.cpp" diff --git a/src/gui/kernel/qapplication.h b/src/gui/kernel/qapplication.h index 5f21a56..12b398d 100644 --- a/src/gui/kernel/qapplication.h +++ b/src/gui/kernel/qapplication.h @@ -86,6 +86,7 @@ class QDecoration; class QApplication; class QApplicationPrivate; +class QGestureRecognizer; #if defined(qApp) #undef qApp #endif @@ -289,6 +290,9 @@ public: static Qt::NavigationMode navigationMode(); #endif + Qt::GestureType registerGestureRecognizer(QGestureRecognizer *recognizer); + void unregisterGestureRecognizer(Qt::GestureType type); + Q_SIGNALS: void lastWindowClosed(); void focusChanged(QWidget *old, QWidget *now); @@ -400,6 +404,7 @@ private: friend class QDirectPainter; friend class QDirectPainterPrivate; #endif + friend class QGestureManager; #if defined(Q_WS_MAC) || defined(Q_WS_X11) Q_PRIVATE_SLOT(d_func(), void _q_alertTimeOut()) diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index 95b6d28..2d3d18c 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -83,8 +83,8 @@ class QGraphicsSystem; class QInputContext; class QObject; class QWidget; -class QGestureManager; class QSocketNotifier; +class QGestureManager; extern bool qt_is_gui_used; #ifndef QT_NO_CLIPBOARD @@ -265,20 +265,6 @@ typedef struct tagGESTURECONFIG #endif // Q_WS_WIN -class QPanGesture; -class QPinchGesture; -class QSwipeGesture; - -struct QStandardGestures -{ - QPanGesture *pan; - QPinchGesture *pinch; - QSwipeGesture *swipe; - - QStandardGestures() : pan(0), pinch(0), swipe(0) { } -}; - - class QScopedLoopLevelCounter { QThreadData *threadData; @@ -522,6 +508,8 @@ public: void sendSyntheticEnterLeave(QWidget *widget); #endif + QGestureManager *gestureManager; + QMap<int, QWidget *> widgetForTouchPointId; QMap<int, QTouchEvent::TouchPoint> appCurrentTouchPoints; static void updateTouchPointsForWidget(QWidget *widget, QTouchEvent *touchEvent); @@ -536,9 +524,6 @@ public: QTouchEvent::DeviceType deviceType, const QList<QTouchEvent::TouchPoint> &touchPoints); - typedef QMap<QWidget*, QStandardGestures> WidgetStandardGesturesMap; - WidgetStandardGesturesMap widgetGestures; - #if defined(Q_WS_WIN) static PtrRegisterTouchWindow RegisterTouchWindow; static PtrGetTouchInputInfo GetTouchInputInfo; @@ -555,7 +540,6 @@ public: PtrBeginPanningFeedback BeginPanningFeedback; PtrUpdatePanningFeedback UpdatePanningFeedback; PtrEndPanningFeedback EndPanningFeedback; - QWidget *gestureWidget; #endif #ifdef QT_RX71_MULTITOUCH diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 270562f..540f0a2 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -92,8 +92,6 @@ extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.c #include <private/qkeymapper_p.h> #include <private/qlocale_p.h> #include "qevent_p.h" -#include "qstandardgestures.h" -#include "qstandardgestures_p.h" //#define ALIEN_DEBUG @@ -854,7 +852,6 @@ void qt_init(QApplicationPrivate *priv, int) (PtrEndPanningFeedback)QLibrary::resolve(QLatin1String("uxtheme"), "EndPanningFeedback"); #endif - priv->gestureWidget = 0; } /***************************************************************************** @@ -2499,24 +2496,24 @@ LRESULT CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam if (qAppPriv->GetGestureInfo) bResult = qAppPriv->GetGestureInfo((HANDLE)msg.lParam, &gi); if (bResult) { - if (gi.dwID == GID_BEGIN) { - // find the alien widget for the gesture position. - // This might not be accurate as the position is the center - // point of two fingers for multi-finger gestures. - QPoint pt(gi.ptsLocation.x, gi.ptsLocation.y); - QWidget *w = widget->childAt(widget->mapFromGlobal(pt)); - qAppPriv->gestureWidget = w ? w : widget; - } - if (qAppPriv->gestureWidget) - static_cast<QETWidget*>(qAppPriv->gestureWidget)->translateGestureEvent(msg, gi); - if (qAppPriv->CloseGestureInfoHandle) - qAppPriv->CloseGestureInfoHandle((HANDLE)msg.lParam); - if (gi.dwID == GID_END) - qAppPriv->gestureWidget = 0; - } else { - DWORD dwErr = GetLastError(); - if (dwErr > 0) - qWarning() << "translateGestureEvent: error = " << dwErr; +// if (gi.dwID == GID_BEGIN) { +// // find the alien widget for the gesture position. +// // This might not be accurate as the position is the center +// // point of two fingers for multi-finger gestures. +// QPoint pt(gi.ptsLocation.x, gi.ptsLocation.y); +// QWidget *w = widget->childAt(widget->mapFromGlobal(pt)); +// qAppPriv->gestureWidget = w ? w : widget; +// } +// if (qAppPriv->gestureWidget) +// static_cast<QETWidget*>(qAppPriv->gestureWidget)->translateGestureEvent(msg, gi); +// if (qAppPriv->CloseGestureInfoHandle) +// qAppPriv->CloseGestureInfoHandle((HANDLE)msg.lParam); +// if (gi.dwID == GID_END) +// qAppPriv->gestureWidget = 0; +// } else { +// DWORD dwErr = GetLastError(); +// if (dwErr > 0) +// qWarning() << "translateGestureEvent: error = " << dwErr; } result = true; break; diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 7b9cc9a..4316714 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -49,6 +49,8 @@ #include "qmime.h" #include "qdnd_p.h" #include "qevent_p.h" +#include "qgesture.h" +#include "qgesture_p.h" QT_BEGIN_NAMESPACE @@ -3357,6 +3359,9 @@ QDebug operator<<(QDebug dbg, const QEvent *e) { case QEvent::ChildRemoved: n = n ? n : "ChildRemoved"; dbg.nospace() << "QChildEvent(" << n << ", " << (static_cast<const QChildEvent*>(e))->child(); return dbg.space(); + case QEvent::Gesture: + n = "Gesture"; + break; default: dbg.nospace() << "QEvent(" << (const void *)e << ", type = " << e->type() << ')'; return dbg.space(); @@ -4186,4 +4191,73 @@ QTouchEvent::TouchPoint &QTouchEvent::TouchPoint::operator=(const QTouchEvent::T return *this; } +/*! + \class QGestureEvent + \since 4.6 + \ingroup events + + \brief The QGestureEvent class provides the description of triggered + gestures. + + The QGestureEvent class contains a list of gestures that are being executed + right now (\l{QGestureEvent::}{activeGestures()}) and a list of gestures + that are \l{QGestureEvent::canceledGestures}{cancelled} (a gesture might be + cancelled because the window lost focus, or because of timeout, etc). + + \sa QGesture +*/ + +/*! + Creates new QGestureEvent containing a list of \a gestures. +*/ +QGestureEvent::QGestureEvent(const QList<QGesture*> &gestures) + : QEvent(QEvent::Gesture), gestures_(gestures) +{ +} + +QList<QGesture*> QGestureEvent::allGestures() const +{ + return gestures_; +} + +QGesture* QGestureEvent::gesture(Qt::GestureType type) +{ + for(int i = 0; i < gestures_.size(); ++i) + if (gestures_.at(i)->gestureType() == type) + return gestures_.at(i); + return 0; +} + +QList<QGesture*> QGestureEvent::activeGestures() const +{ + return gestures_; +} + +QList<QGesture*> QGestureEvent::canceledGestures() const +{ + return gestures_; +} + +void QGestureEvent::setAccepted(QGesture *gesture, bool value) +{ + setAccepted(false); + if (gesture) + gesture->d_func()->accept = value; +} + +void QGestureEvent::accept(QGesture *gesture) +{ + setAccepted(gesture, true); +} + +void QGestureEvent::ignore(QGesture *gesture) +{ + setAccepted(gesture, false); +} + +bool QGestureEvent::isAccepted(QGesture *gesture) const +{ + return gesture ? gesture->d_func()->accept : false; +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 4396766..224b479 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -819,6 +819,40 @@ protected: friend class QApplicationPrivate; }; +class QGesture; +class Q_GUI_EXPORT QGestureEvent : public QEvent +{ +public: + QGestureEvent(const QList<QGesture *> &gestures); + + QList<QGesture *> allGestures() const; + QGesture *gesture(Qt::GestureType type); + + QList<QGesture *> activeGestures() const; + QList<QGesture *> canceledGestures() const; + +#ifdef Q_NO_USING_KEYWORD + inline void setAccepted(bool accepted) { QEvent::setAccepted(accepted); } + inline bool isAccepted() const { return QEvent::isAccepted(); } + + inline void accept() { QEvent::accept(); } + inline void ignore() { QEvent::ignore(); } +#else + using QEvent::setAccepted; + using QEvent::isAccepted; + using QEvent::accept; + using QEvent::ignore; +#endif + + void setAccepted(QGesture *, bool); + void accept(QGesture *); + void ignore(QGesture *); + bool isAccepted(QGesture *) const; + +private: + QList<QGesture *> gestures_; +}; + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/kernel/qgesture.cpp b/src/gui/kernel/qgesture.cpp index 237ce46..68cb9cd 100644 --- a/src/gui/kernel/qgesture.cpp +++ b/src/gui/kernel/qgesture.cpp @@ -40,274 +40,284 @@ ****************************************************************************/ #include "qgesture.h" -#include <private/qgesture_p.h> -#include "qgraphicsitem.h" +#include "private/qgesture_p.h" QT_BEGIN_NAMESPACE + /*! + \class QGesture + \since 4.6 -class QEventFilterProxyGraphicsItem : public QGraphicsItem -{ -public: - QEventFilterProxyGraphicsItem(QGesture *g) - : gesture(g) - { - } - bool sceneEventFilter(QGraphicsItem *, QEvent *event) - { - return gesture ? gesture->filterEvent(event) : false; - } - QRectF boundingRect() const { return QRectF(); } - void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) { } + \brief The QGesture class represents a gesture, containing all + properties that describe a gesture. -private: - QGesture *gesture; -}; + The widget receives a QGestureEvent with a list of QGesture + objects that represent gestures that are occuring on it. The class + has a list of properties that can be queried by the user to get + some gesture-specific arguments (i.e. position of the tap in the + DoubleTap gesture). -/*! - \class QGesture - \since 4.6 - \preliminary - - \brief The QGesture class is the base class for implementing custom - gestures. - - This class represents both an object that recognizes a gesture out of a set - of input events (a gesture recognizer), and a gesture object itself that - can be used to get extended information about the triggered gesture. - - The class has a list of properties that can be queried by the user to get - some gesture-specific parameters (for example, an offset of a Pan gesture). - - Usually gesture recognizer implements a state machine, storing its state - internally in the recognizer object. The recognizer receives input events - through the \l{QGesture::}{filterEvent()} virtual function and decides - whether the event should change the state of the recognizer by emitting an - appropriate signal. - - Input events should be either fed to the recognizer one by one with a - filterEvent() function, or the gesture recognizer should be attached to an - object it filters events for by specifying it as a parent object. The - QGesture object installs itself as an event filter to the parent object - automatically, the unsetObject() function should be used to remove an event - filter from the parent object. To make a - gesture that operates on a QGraphicsItem, both the appropriate QGraphicsView - should be passed as a parent object and setGraphicsItem() functions should - be used to attach a gesture to a graphics item. - - This is a base class, to create a custom gesture type, you should subclass - it and implement its pure virtual functions. - - \sa QPanGesture + When creating custom gesture recognizers, they might add new + properties to the gesture object, or custom gesture developers + might subclass the QGesture objects to provide some extended + information. + + \sa QGestureEvent, QGestureRecognizer */ -/*! \fn bool QGesture::filterEvent(QEvent *event) +QGesture::QGesture(QObject *parent) + : QObject(*new QGesturePrivate, parent) +{ + d_func()->gestureType = Qt::CustomGesture; +} - Parses input \a event and emits a signal when detects a gesture. +QGesture::QGesture(QGesturePrivate &dd, QObject *parent) + : QObject(dd, parent) +{ +} - In your reimplementation of this function, if you want to filter the \a - event out, i.e. stop it being handled further, return true; otherwise - return false; +QGesture::~QGesture() +{ +} - This is a pure virtual function that needs to be implemented in subclasses. -*/ +Qt::GestureType QGesture::gestureType() const +{ + return d_func()->gestureType; +} -/*! \fn void QGesture::started() +Qt::GestureState QGesture::state() const +{ + return d_func()->state; +} - The signal is emitted when the gesture is started. Extended information - about the gesture is contained in the signal sender object. +QObject *QGesture::targetObject() const +{ + return d_func()->targetObject; +} - In addition to started(), a triggered() signal should also be emitted. -*/ +void QGesture::setTargetObject(QObject *value) +{ + d_func()->targetObject = value; +} -/*! \fn void QGesture::triggered() +QPointF QGesture::hotSpot() const +{ + return d_func()->hotSpot; +} - The signal is emitted when the gesture is detected. Extended information - about the gesture is contained in the signal sender object. -*/ +void QGesture::setHotSpot(const QPointF &value) +{ + Q_D(QGesture); + d->hotSpot = value; + d->isHotSpotSet = true; +} -/*! \fn void QGesture::finished() +bool QGesture::hasHotSpot() const +{ + return d_func()->isHotSpotSet; +} - The signal is emitted when the gesture is finished. Extended information - about the gesture is contained in the signal sender object. -*/ +void QGesture::unsetHotSpot() +{ + d_func()->isHotSpotSet = false; +} -/*! \fn void QGesture::canceled() +// QPanGesture - The signal is emitted when the gesture is canceled, for example the - reset() function is called while the gesture was in the process of - emitting a triggered() signal. Extended information about the - gesture is contained in the sender object. -*/ +QPanGesture::QPanGesture(QObject *parent) + : QGesture(*new QPanGesturePrivate, parent) +{ + d_func()->gestureType = Qt::PanGesture; +} -/*! - Creates a new gesture handler object and marks it as a child of \a - parent. \a gestureTarget is the object that the gesture will watch - for events. +QSizeF QPanGesture::totalOffset() const +{ + return d_func()->totalOffset; +} - The \a parent object is also the default event source for the - gesture, meaning that the gesture installs itself as an event filter - for the \a parent. +QSizeF QPanGesture::lastOffset() const +{ + return d_func()->lastOffset; +} - \sa setGraphicsItem() -*/ -QGesture::QGesture(QObject *gestureTarget, QObject *parent) - : QObject(*new QGesturePrivate, parent) +QSizeF QPanGesture::offset() const { - setGestureTarget(gestureTarget); + return d_func()->offset; } -/*! \internal - */ -QGesture::QGesture(QGesturePrivate &dd, QObject *gestureTarget, QObject *parent) - : QObject(dd, parent) +qreal QPanGesture::acceleration() const { - setGestureTarget(gestureTarget); + return d_func()->acceleration; } -/*! - Destroys the gesture object. -*/ -QGesture::~QGesture() + +void QPanGesture::setTotalOffset(const QSizeF &value) { + d_func()->totalOffset = value; } -/*! - \property QGesture::gestureTarget +void QPanGesture::setLastOffset(const QSizeF &value) +{ + d_func()->lastOffset = value; +} - Gesture target is the object that the gesture will watch for events. - Typically this means that the gesture installs an event filter on the - target object. -*/ -void QGesture::setGestureTarget(QObject *object) +void QPanGesture::setOffset(const QSizeF &value) { - d_func()->setupGestureTarget(object); + d_func()->offset = value; } -QObject* QGesture::gestureTarget() const +void QPanGesture::setAcceleration(qreal value) { - return d_func()->gestureTarget; + d_func()->acceleration = value; } -void QGesturePrivate::setupGestureTarget(QObject *object) +// QPinchGesture + +QPinchGesture::QPinchGesture(QObject *parent) + : QGesture(*new QPinchGesturePrivate, parent) { - Q_Q(QGesture); - if (gestureTarget) - gestureTarget->removeEventFilter(q); - if (object) - object->installEventFilter(q); - gestureTarget = object; + d_func()->gestureType = Qt::PinchGesture; } -/*! \internal - */ -bool QGesture::eventFilter(QObject *receiver, QEvent *event) +QPinchGesture::WhatChanged QPinchGesture::whatChanged() const { - Q_D(QGesture); - if (d->graphicsItem && receiver == parent()) - return false; - return filterEvent(event); + return d_func()->whatChanged; } -/*! - \property QGesture::state +void QPinchGesture::setWhatChanged(QPinchGesture::WhatChanged value) +{ + d_func()->whatChanged = value; +} - \brief The current state of the gesture. -*/ -/*! - Returns the gesture recognition state. - */ -Qt::GestureState QGesture::state() const +QPointF QPinchGesture::startCenterPoint() const { - return d_func()->state; + return d_func()->startCenterPoint; } -/*! - Sets this gesture's recognition state to \a state and emits appropriate - signals. +QPointF QPinchGesture::lastCenterPoint() const +{ + return d_func()->lastCenterPoint; +} - This functions emits the signals according to the old state and the new - \a state, and it should be called after all the internal properties have been - initialized. +QPointF QPinchGesture::centerPoint() const +{ + return d_func()->centerPoint; +} - \sa started(), triggered(), finished(), canceled() - */ -void QGesture::updateState(Qt::GestureState state) +void QPinchGesture::setStartCenterPoint(const QPointF &value) { - Q_D(QGesture); - if (d->state == state) { - if (state == Qt::GestureUpdated) - emit triggered(); - return; - } - const Qt::GestureState oldState = d->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) { - d->state = Qt::GestureStarted; - emit started(); - } - d->state = state; - if (state == Qt::GestureUpdated) - emit triggered(); - else if (state == Qt::GestureFinished) - emit finished(); - else if (state == Qt::NoGesture) - emit canceled(); - - if (state == Qt::GestureFinished) { - // gesture is finished, so we reset the internal state. - d->state = Qt::NoGesture; - } -} - -/*! - Sets the \a graphicsItem the gesture is filtering events for. - - The gesture will install an event filter to the \a graphicsItem and - redirect them to the filterEvent() function. - - \sa graphicsItem() -*/ -void QGesture::setGraphicsItem(QGraphicsItem *graphicsItem) + d_func()->startCenterPoint = value; +} + +void QPinchGesture::setLastCenterPoint(const QPointF &value) { - Q_D(QGesture); - if (d->graphicsItem && d->eventFilterProxyGraphicsItem) - d->graphicsItem->removeSceneEventFilter(d->eventFilterProxyGraphicsItem); - d->graphicsItem = graphicsItem; - if (!d->eventFilterProxyGraphicsItem) - d->eventFilterProxyGraphicsItem = new QEventFilterProxyGraphicsItem(this); - if (graphicsItem) - graphicsItem->installSceneEventFilter(d->eventFilterProxyGraphicsItem); + d_func()->lastCenterPoint = value; +} + +void QPinchGesture::setCenterPoint(const QPointF &value) +{ + d_func()->centerPoint = value; } -/*! - Returns the graphics item the gesture is filtering events for. - \sa setGraphicsItem() -*/ -QGraphicsItem* QGesture::graphicsItem() const +qreal QPinchGesture::totalScaleFactor() const +{ + return d_func()->totalScaleFactor; +} + +qreal QPinchGesture::lastScaleFactor() const { - return d_func()->graphicsItem; + return d_func()->lastScaleFactor; } -/*! \fn void QGesture::reset() +qreal QPinchGesture::scaleFactor() const +{ + return d_func()->scaleFactor; +} - Resets the internal state of the gesture. This function might be called by - the filterEvent() implementation in a derived class, or by the user to - cancel a gesture. The base class implementation calls - updateState(Qt::NoGesture) which emits the canceled() - signal if the state() of the gesture indicated it was active. -*/ -void QGesture::reset() +void QPinchGesture::setTotalScaleFactor(qreal value) +{ + d_func()->totalScaleFactor = value; +} + +void QPinchGesture::setLastScaleFactor(qreal value) +{ + d_func()->lastScaleFactor = value; +} + +void QPinchGesture::setScaleFactor(qreal value) +{ + d_func()->scaleFactor = value; +} + + +qreal QPinchGesture::totalRotationAngle() const +{ + return d_func()->totalRotationAngle; +} + +qreal QPinchGesture::lastRotationAngle() const +{ + return d_func()->lastRotationAngle; +} + +qreal QPinchGesture::rotationAngle() const +{ + return d_func()->rotationAngle; +} + +void QPinchGesture::setTotalRotationAngle(qreal value) +{ + d_func()->totalRotationAngle = value; +} + +void QPinchGesture::setLastRotationAngle(qreal value) +{ + d_func()->lastRotationAngle = value; +} + +void QPinchGesture::setRotationAngle(qreal value) +{ + d_func()->rotationAngle = value; +} + +// QSwipeGesture + +QSwipeGesture::QSwipeGesture(QObject *parent) + : QGesture(*new QSwipeGesturePrivate, parent) +{ + d_func()->gestureType = Qt::SwipeGesture; +} + +QSwipeGesture::SwipeDirection QSwipeGesture::horizontalDirection() const +{ + return d_func()->horizontalDirection; +} + +QSwipeGesture::SwipeDirection QSwipeGesture::verticalDirection() const +{ + return d_func()->verticalDirection; +} + +void QSwipeGesture::setHorizontalDirection(QSwipeGesture::SwipeDirection value) +{ + d_func()->horizontalDirection = value; +} + +void QSwipeGesture::setVerticalDirection(QSwipeGesture::SwipeDirection value) +{ + d_func()->verticalDirection = value; +} + +qreal QSwipeGesture::swipeAngle() const +{ + return d_func()->swipeAngle; +} + +void QSwipeGesture::setSwipeAngle(qreal value) { - updateState(Qt::NoGesture); + d_func()->swipeAngle = value; } QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesture.h b/src/gui/kernel/qgesture.h index 440565e..bf72759 100644 --- a/src/gui/kernel/qgesture.h +++ b/src/gui/kernel/qgesture.h @@ -55,7 +55,8 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -class QGraphicsItem; +Q_DECLARE_METATYPE(Qt::GestureState) + class QGesturePrivate; class Q_GUI_EXPORT QGesture : public QObject { @@ -63,37 +64,148 @@ class Q_GUI_EXPORT QGesture : public QObject Q_DECLARE_PRIVATE(QGesture) Q_PROPERTY(Qt::GestureState state READ state) - Q_PROPERTY(QObject* gestureTarget READ gestureTarget WRITE setGestureTarget) + Q_PROPERTY(Qt::GestureType gestureType READ gestureType) + Q_PROPERTY(QPointF hotSpot READ hotSpot WRITE setHotSpot RESET unsetHotSpot) + Q_PROPERTY(bool hasHotSpot READ hasHotSpot) + Q_PROPERTY(QObject* targetObject READ targetObject WRITE setTargetObject) public: - explicit QGesture(QObject *gestureTarget = 0, QObject *parent = 0); + explicit QGesture(QObject *parent = 0); ~QGesture(); - virtual bool filterEvent(QEvent *event) = 0; + Qt::GestureType gestureType() const; - void setGestureTarget(QObject *object); - QObject* gestureTarget() const; + Qt::GestureState state() const; - void setGraphicsItem(QGraphicsItem *); - QGraphicsItem *graphicsItem() const; + QObject *targetObject() const; + void setTargetObject(QObject *value); - Qt::GestureState state() const; + QPointF hotSpot() const; + void setHotSpot(const QPointF &value); + bool hasHotSpot() const; + void unsetHotSpot(); protected: - QGesture(QGesturePrivate &dd, QObject *gestureTarget, QObject *parent); - bool eventFilter(QObject*, QEvent*); + QGesture(QGesturePrivate &dd, QObject *parent); - virtual void reset(); - void updateState(Qt::GestureState state); +private: + friend class QGestureEvent; + friend class QGestureRecognizer; + friend class QGestureManager; +}; -Q_SIGNALS: - void started(); - void triggered(); - void finished(); - void canceled(); +class QPanGesturePrivate; +class Q_GUI_EXPORT QPanGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QPanGesture) -private: - friend class QWidget; + Q_PROPERTY(QSizeF totalOffset READ totalOffset WRITE setTotalOffset) + Q_PROPERTY(QSizeF lastOffset READ lastOffset WRITE setLastOffset) + Q_PROPERTY(QSizeF offset READ offset WRITE setOffset) + Q_PROPERTY(qreal acceleration READ acceleration WRITE setAcceleration) + +public: + QPanGesture(QObject *parent = 0); + + QSizeF totalOffset() const; + QSizeF lastOffset() const; + QSizeF offset() const; + qreal acceleration() const; + + void setTotalOffset(const QSizeF &value); + void setLastOffset(const QSizeF &value); + void setOffset(const QSizeF &value); + void setAcceleration(qreal value); + + friend class QPanGestureRecognizer; + friend class QWinNativePanGestureRecognizer; +}; + +class QPinchGesturePrivate; +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 WRITE setWhatChanged) + + Q_PROPERTY(qreal totalScaleFactor READ totalScaleFactor WRITE setTotalScaleFactor) + Q_PROPERTY(qreal lastScaleFactor READ lastScaleFactor WRITE setLastScaleFactor) + Q_PROPERTY(qreal scaleFactor READ scaleFactor WRITE setScaleFactor) + + Q_PROPERTY(qreal totalRotationAngle READ totalRotationAngle WRITE setTotalRotationAngle) + Q_PROPERTY(qreal lastRotationAngle READ lastRotationAngle WRITE setLastRotationAngle) + Q_PROPERTY(qreal rotationAngle READ rotationAngle WRITE setRotationAngle) + + Q_PROPERTY(QPointF startCenterPoint READ startCenterPoint WRITE setStartCenterPoint) + Q_PROPERTY(QPointF lastCenterPoint READ lastCenterPoint WRITE setLastCenterPoint) + Q_PROPERTY(QPointF centerPoint READ centerPoint WRITE setCenterPoint) + +public: + QPinchGesture(QObject *parent = 0); + + WhatChanged whatChanged() const; + void setWhatChanged(WhatChanged value); + + QPointF startCenterPoint() const; + QPointF lastCenterPoint() const; + QPointF centerPoint() const; + void setStartCenterPoint(const QPointF &value); + void setLastCenterPoint(const QPointF &value); + void setCenterPoint(const QPointF &value); + + qreal totalScaleFactor() const; + qreal lastScaleFactor() const; + qreal scaleFactor() const; + void setTotalScaleFactor(qreal value); + void setLastScaleFactor(qreal value); + void setScaleFactor(qreal value); + + qreal totalRotationAngle() const; + qreal lastRotationAngle() const; + qreal rotationAngle() const; + void setTotalRotationAngle(qreal value); + void setLastRotationAngle(qreal value); + void setRotationAngle(qreal value); + + friend class QPinchGestureRecognizer; +}; + +Q_DECLARE_METATYPE(QPinchGesture::WhatChanged) + +class QSwipeGesturePrivate; +class Q_GUI_EXPORT QSwipeGesture : public QGesture +{ + Q_OBJECT + Q_DECLARE_PRIVATE(QSwipeGesture) + Q_ENUMS(SwipeDirection) + + Q_PROPERTY(SwipeDirection horizontalDirection READ horizontalDirection WRITE setHorizontalDirection) + Q_PROPERTY(SwipeDirection verticalDirection READ verticalDirection WRITE setVerticalDirection) + Q_PROPERTY(qreal swipeAngle READ swipeAngle WRITE setSwipeAngle) + +public: + enum SwipeDirection { NoDirection, Left, Right, Up, Down }; + QSwipeGesture(QObject *parent = 0); + + SwipeDirection horizontalDirection() const; + SwipeDirection verticalDirection() const; + void setHorizontalDirection(SwipeDirection value); + void setVerticalDirection(SwipeDirection value); + + qreal swipeAngle() const; + void setSwipeAngle(qreal value); + + friend class QSwipeGestureRecognizer; }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesture_p.h b/src/gui/kernel/qgesture_p.h index 52e399f..7f69a4e 100644 --- a/src/gui/kernel/qgesture_p.h +++ b/src/gui/kernel/qgesture_p.h @@ -61,29 +61,83 @@ QT_BEGIN_NAMESPACE -class QObject; -class QGraphicsItem; class QGesturePrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QGesture) public: QGesturePrivate() - : gestureTarget(0), graphicsItem(0), eventFilterProxyGraphicsItem(0), - state(Qt::NoGesture), implicitGesture(false) + : gestureType(Qt::CustomGesture), state(Qt::NoGesture), isHotSpotSet(false), + targetObject(0), accept(true) { } - virtual void setupGestureTarget(QObject *o); + Qt::GestureType gestureType; + Qt::GestureState state; + QPointF hotSpot; + bool isHotSpotSet; + QObject *targetObject; + bool accept; +}; - QPointer<QObject> gestureTarget; - QGraphicsItem *graphicsItem; - QGraphicsItem *eventFilterProxyGraphicsItem; +class QPanGesturePrivate : public QGesturePrivate +{ + Q_DECLARE_PUBLIC(QPanGesture) - Qt::GestureState state; +public: + QPanGesturePrivate() + : acceleration(0) + { + } + + QSizeF totalOffset; + QSizeF lastOffset; + QSizeF offset; + QPoint lastPosition; + qreal acceleration; +}; + +class QPinchGesturePrivate : public QGesturePrivate +{ + Q_DECLARE_PUBLIC(QPinchGesture) + +public: + QPinchGesturePrivate() + : whatChanged(0), totalScaleFactor(0), lastScaleFactor(0), scaleFactor(0), + totalRotationAngle(0), lastRotationAngle(0), rotationAngle(0) + { + } + + QPinchGesture::WhatChanged whatChanged; + + QPointF startCenterPoint; + QPointF lastCenterPoint; + QPointF centerPoint; + + qreal totalScaleFactor; + qreal lastScaleFactor; + qreal scaleFactor; + + qreal totalRotationAngle; + qreal lastRotationAngle; + qreal rotationAngle; +}; + +class QSwipeGesturePrivate : public QGesturePrivate +{ + Q_DECLARE_PUBLIC(QSwipeGesture) + +public: + QSwipeGesturePrivate() + : horizontalDirection(QSwipeGesture::NoDirection), + verticalDirection(QSwipeGesture::NoDirection), + swipeAngle(0) + { + } - // the flag specifies if the gesture was created implicitely by Qt. - bool implicitGesture; + QSwipeGesture::SwipeDirection horizontalDirection; + QSwipeGesture::SwipeDirection verticalDirection; + qreal swipeAngle; }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp new file mode 100644 index 0000000..000f44f --- /dev/null +++ b/src/gui/kernel/qgesturemanager.cpp @@ -0,0 +1,453 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "private/qgesturemanager_p.h" +#include "private/qstandardgestures_p.h" +#include "private/qwidget_p.h" +#include "private/qgesture_p.h" +#include "private/qgraphicsitem_p.h" +#include "qgesture.h" +#include "qevent.h" +#include "qgraphicsitem.h" + +#include "qdebug.h" + +// #define GESTURE_DEBUG +#ifndef GESTURE_DEBUG +# define DEBUG if (0) qDebug +#else +# define DEBUG qDebug +#endif + +QT_BEGIN_NAMESPACE + +QGestureManager::QGestureManager(QObject *parent) + : QObject(parent), state(NotGesture), lastCustomGestureId(0) +{ + qRegisterMetaType<Qt::GestureState>(); + + registerGestureRecognizer(new QPanGestureRecognizer); +} + +QGestureManager::~QGestureManager() +{ + +} + +Qt::GestureType QGestureManager::registerGestureRecognizer(QGestureRecognizer *recognizer) +{ + QGesture *dummy = recognizer->createGesture(0); + if (!dummy) { + qWarning("QGestureManager::registerGestureRecognizer: the recognizer doesn't provide gesture object"); + return Qt::GestureType(0); + } + Qt::GestureType type = dummy->gestureType(); + if (type == Qt::CustomGesture) { + // generate a new custom gesture id + ++lastCustomGestureId; + type = Qt::GestureType(Qt::CustomGesture + lastCustomGestureId); + } + recognizers.insertMulti(type, recognizer); + delete dummy; + return type; +} + +void QGestureManager::unregisterGestureRecognizer(Qt::GestureType) +{ + +} + +QGesture* QGestureManager::getState(QObject *object, Qt::GestureType type) +{ + // if the widget is being deleted we should be carefull and not to + // create a new state, as it will create QWeakPointer which doesnt work + // from the destructor. + if (object->isWidgetType()) { + if (static_cast<QWidget *>(object)->d_func()->data.in_destructor) + return 0; + } + + QWeakPointer<QGesture> state = objectGestures.value(QGestureManager::ObjectGesture(object, type)); + if (!state) { + QGestureRecognizer *recognizer = recognizers.value(type); + if (recognizer) { + state = recognizer->createGesture(object); + if (!state) + return 0; + if (state.data()->gestureType() == Qt::CustomGesture) { + // if the recognizer didn't fill in the gesture type, then this + // is a custom gesture with autogenerated it and we fill it. + state.data()->d_func()->gestureType = type; + } + objectGestures.insert(QGestureManager::ObjectGesture(object, type), state); + gestureToRecognizer[state.data()] = recognizer; + } + } + return state.data(); +} + +bool QGestureManager::filterEvent(QObject *receiver, QEvent *event) +{ + QSet<QGesture *> triggeredGestures; + QSet<QGesture *> finishedGestures; + QSet<QGesture *> newMaybeGestures; + QSet<QGesture *> canceledGestures; + QSet<QGesture *> notGestures; + + QGraphicsObject *graphicsObject = qobject_cast<QGraphicsObject *>(receiver); + if (receiver->isWidgetType() || graphicsObject) { + QMap<QObject *, Qt::GestureType> contexts; + if (receiver->isWidgetType()) { + QWidget *w = static_cast<QWidget *>(receiver); + if (!w->d_func()->gestureContext.isEmpty()) { + typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator; + for(ContextIterator it = w->d_func()->gestureContext.begin(), + e = w->d_func()->gestureContext.end(); it != e; ++it) { + contexts.insertMulti(w, it.key()); + } + } + // find all gesture contexts for the widget tree + w = w->parentWidget(); + while (w) + { + typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator; + for (ContextIterator it = w->d_func()->gestureContext.begin(), + e = w->d_func()->gestureContext.end(); it != e; ++it) { + if (it.value() == Qt::WidgetWithChildrenGesture) + contexts.insertMulti(w, it.key()); + } + w = w->parentWidget(); + } + } else { + QGraphicsObject *item = graphicsObject; + if (!item->QGraphicsItem::d_func()->gestureContext.isEmpty()) { + typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator; + for(ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(), + e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) { + contexts.insertMulti(item, it.key()); + } + } + // find all gesture contexts for the widget tree + item = item->parentObject(); + while (item) + { + typedef QMap<Qt::GestureType, Qt::GestureContext>::const_iterator ContextIterator; + for (ContextIterator it = item->QGraphicsItem::d_func()->gestureContext.begin(), + e = item->QGraphicsItem::d_func()->gestureContext.end(); it != e; ++it) { + if (it.value() == Qt::WidgetWithChildrenGesture) + contexts.insertMulti(item, it.key()); + } + item = item->parentObject(); + } + } + // filter the event through recognizers + typedef QMap<QObject *, Qt::GestureType>::const_iterator ContextIterator; + for (ContextIterator cit = contexts.begin(), ce = contexts.end(); cit != ce; ++cit) { + Qt::GestureType gestureType = cit.value(); + QMap<Qt::GestureType, QGestureRecognizer *>::const_iterator + rit = recognizers.lowerBound(gestureType), + re = recognizers.upperBound(gestureType); + for (; rit != re; ++rit) { + QGestureRecognizer *recognizer = rit.value(); + QObject *target = cit.key(); + QGesture *state = getState(target, gestureType); + if (!state) + continue; + QGestureRecognizer::Result result = recognizer->filterEvent(state, target, event); + QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask; + if (type == QGestureRecognizer::GestureTriggered) { + DEBUG() << "QGestureManager: gesture triggered: " << state; + triggeredGestures << state; + } else if (type == QGestureRecognizer::GestureFinished) { + DEBUG() << "QGestureManager: gesture finished: " << state; + finishedGestures << state; + } else if (type == QGestureRecognizer::MaybeGesture) { + DEBUG() << "QGestureManager: maybe gesture: " << state; + newMaybeGestures << state; + } else if (type == QGestureRecognizer::NotGesture) { + DEBUG() << "QGestureManager: not gesture: " << state; + notGestures << state; + } else if (type == QGestureRecognizer::Ignore) { + DEBUG() << "QGestureManager: gesture ignored the event: " << state; + } else { + DEBUG() << "QGestureManager: hm, lets assume the recognizer ignored the event: " << state; + } + if (result & QGestureRecognizer::ConsumeEventHint) { + DEBUG() << "QGestureManager: we were asked to consume the event: " << state; + //TODO: consume events if asked + } + } + } + } else if (QGesture *state = qobject_cast<QGesture*>(receiver)) { + if (QGestureRecognizer *recognizer = gestureToRecognizer.value(state)) { + QGestureRecognizer::Result result = recognizer->filterEvent(state, state, event); + QGestureRecognizer::Result type = result & QGestureRecognizer::ResultState_Mask; + if (type == QGestureRecognizer::GestureTriggered) { + DEBUG() << "QGestureManager: gesture triggered: " << state; + triggeredGestures << state; + } else if (type == QGestureRecognizer::GestureFinished) { + DEBUG() << "QGestureManager: gesture finished: " << state; + finishedGestures << state; + } else if (type == QGestureRecognizer::MaybeGesture) { + DEBUG() << "QGestureManager: maybe gesture: " << state; + newMaybeGestures << state; + } else if (type == QGestureRecognizer::NotGesture) { + DEBUG() << "QGestureManager: not gesture: " << state; + notGestures << state; + } else if (type == QGestureRecognizer::Ignore) { + DEBUG() << "QGestureManager: gesture ignored the event: " << state; + } else { + DEBUG() << "QGestureManager: hm, lets assume the recognizer ignored the event: " << state; + } + } + } else { + return false; + } + + QSet<QGesture *> startedGestures = triggeredGestures - activeGestures; + triggeredGestures &= activeGestures; + + // check if a running gesture switched back to maybe state + QSet<QGesture *> activeToMaybeGestures = activeGestures & newMaybeGestures; + + // check if a running gesture switched back to not gesture state, i.e. were canceled + QSet<QGesture *> activeToCancelGestures = activeGestures & notGestures; + canceledGestures += activeToCancelGestures; + + // start timers for new gestures in maybe state + foreach (QGesture *state, newMaybeGestures) { + QBasicTimer &timer = maybeGestures[state]; + if (!timer.isActive()) + timer.start(3000, this); + } + // kill timers for gestures that were in maybe state + QSet<QGesture *> notMaybeGestures = (startedGestures | triggeredGestures | finishedGestures | canceledGestures | notGestures); + foreach(QGesture *gesture, notMaybeGestures) { + QMap<QGesture *, QBasicTimer>::iterator it = + maybeGestures.find(gesture); + if (it != maybeGestures.end()) { + it.value().stop(); + maybeGestures.erase(it); + } + } + + Q_ASSERT((startedGestures & finishedGestures).isEmpty()); + Q_ASSERT((startedGestures & newMaybeGestures).isEmpty()); + Q_ASSERT((startedGestures & canceledGestures).isEmpty()); + Q_ASSERT((finishedGestures & newMaybeGestures).isEmpty()); + Q_ASSERT((finishedGestures & canceledGestures).isEmpty()); + Q_ASSERT((canceledGestures & newMaybeGestures).isEmpty()); + + QSet<QGesture *> notStarted = finishedGestures - activeGestures; + if (!notStarted.isEmpty()) { + // there are some gestures that claim to be finished, but never started. + qWarning("QGestureManager::filterEvent: some gestures were finished even though they've never started"); + finishedGestures -= notStarted; + } + + activeGestures += startedGestures; + // sanity check: all triggered gestures should already be in active gestures list + Q_ASSERT((activeGestures & triggeredGestures).size() == triggeredGestures.size()); + activeGestures -= finishedGestures; + activeGestures -= activeToMaybeGestures; + activeGestures -= canceledGestures; + + // set the proper gesture state on each gesture + foreach (QGesture *gesture, startedGestures) + gesture->d_func()->state = Qt::GestureStarted; + foreach (QGesture *gesture, triggeredGestures) + gesture->d_func()->state = Qt::GestureUpdated; + foreach (QGesture *gesture, finishedGestures) + gesture->d_func()->state = Qt::GestureFinished; + foreach (QGesture *gesture, canceledGestures) + gesture->d_func()->state = Qt::GestureCanceled; + foreach (QGesture *gesture, activeToMaybeGestures) + gesture->d_func()->state = Qt::GestureFinished; + + if (!activeGestures.isEmpty() || !maybeGestures.isEmpty() || + !startedGestures.isEmpty() || !triggeredGestures.isEmpty() || + !finishedGestures.isEmpty() || !canceledGestures.isEmpty()) { + DEBUG() << "QGestureManager::filterEvent:" + << "\n\tactiveGestures:" << activeGestures + << "\n\tmaybeGestures:" << maybeGestures.keys() + << "\n\tstarted:" << startedGestures + << "\n\ttriggered:" << triggeredGestures + << "\n\tfinished:" << finishedGestures + << "\n\tcanceled:" << canceledGestures; + } + + deliverEvents(startedGestures+triggeredGestures+finishedGestures+canceledGestures, receiver); + + // reset gestures that ended + QSet<QGesture *> endedGestures = finishedGestures + canceledGestures; + foreach (QGesture *gesture, endedGestures) { + if (QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0)) { + recognizer->reset(gesture); + } + gestureTargets.remove(gesture); + } + return false; +} + +void QGestureManager::deliverEvents(const QSet<QGesture*> &gestures, QObject *lastReceiver) +{ + if (gestures.isEmpty()) + return; + + // group gestures by widgets + typedef QMap<QObject *, QList<QGesture *> > GesturesPerReceiver; + GesturesPerReceiver groupedGestures; + // for conflicted gestures the key is always the innermost widget (i.e. the child) + GesturesPerReceiver conflictedGestures; + QMultiHash<QObject *, QGesture *> objectGestures; + + foreach (QGesture *gesture, gestures) { + QObject *target = gestureTargets.value(gesture, 0); + if (!target) { + Q_ASSERT(gesture->state() == Qt::GestureStarted); + if (gesture->hasHotSpot()) { + // guess the target using the hotspot of the gesture + QPoint pt = gesture->hotSpot().toPoint(); + if (!pt.isNull()) { + if (QWidget *w = qApp->topLevelAt(pt)) + target = w->childAt(w->mapFromGlobal(pt)); + } + } + if (!target) { + target = gesture->targetObject(); + if (!target) + target = lastReceiver; + } + } + if (target) { + gestureTargets.insert(gesture, target); + if (target->isWidgetType()) + objectGestures.insert(target, gesture); + groupedGestures[target].append(gesture); + } else { + qWarning() << "QGestureManager::deliverEvent: could not find the target for gesture" + << gesture->gestureType(); + } + } + + typedef QMultiHash<QObject *, QGesture *>::const_iterator ObjectGesturesIterator; + for (ObjectGesturesIterator it = objectGestures.begin(), e = objectGestures.end(); it != e; ++it) { + QObject *object1 = it.key(); + QWidget *widget1 = qobject_cast<QWidget *>(object1); + QGraphicsObject *item1 = qobject_cast<QGraphicsObject *>(object1); + QGesture *gesture1 = it.value(); + ObjectGesturesIterator cit = it; + for (++cit; cit != e; ++cit) { + QObject *object2 = cit.key(); + QWidget *widget2 = qobject_cast<QWidget *>(object2); + QGraphicsObject *item2 = qobject_cast<QGraphicsObject *>(object2); + QGesture *gesture2 = cit.value(); + // TODO: ugly, rewrite this. + if ((widget1 && widget2 && widget2->isAncestorOf(widget1)) || + (item1 && item2 && item2->isAncestorOf(item1))) { + groupedGestures[object2].removeOne(gesture2); + groupedGestures[object1].removeOne(gesture1); + conflictedGestures[object1].append(gesture1); + } else if ((widget1 && widget2 && widget1->isAncestorOf(widget2)) || + (item1 && item2 && item1->isAncestorOf(item2))) { + groupedGestures[object2].removeOne(gesture2); + groupedGestures[object1].removeOne(gesture1); + conflictedGestures[object2].append(gesture2); + } + } + } + + DEBUG() << "deliverEvents: conflicted =" << conflictedGestures.values() + << " grouped =" << groupedGestures.values(); + + // if there are conflicting gestures, send the GestureOverride event + for (GesturesPerReceiver::const_iterator it = conflictedGestures.begin(), + e = conflictedGestures.end(); it != e; ++it) { + DEBUG() << "QGestureManager::deliverEvents: sending GestureOverride to" + << it.key() + << " gestures:" << it.value(); + QGestureEvent event(it.value()); + event.t = QEvent::GestureOverride; + event.ignore(); + QApplication::sendEvent(it.key(), &event); + if (!event.isAccepted()) { + // nobody accepted the GestureOverride, put it back to deliver to + // the closest context (i.e. to the inner-most widget). + DEBUG() <<" override was not accepted"; + groupedGestures[it.key()].append(it.value()); + } + } + + for (GesturesPerReceiver::const_iterator it = groupedGestures.begin(), + e = groupedGestures.end(); it != e; ++it) { + if (!it.value().isEmpty()) { + DEBUG() << "QGestureManager::deliverEvents: sending to" << it.key() + << " gestures:" << it.value(); + QGestureEvent event(it.value()); + QApplication::sendEvent(it.key(), &event); + } + } +} + +void QGestureManager::timerEvent(QTimerEvent *event) +{ + QMap<QGesture*, QBasicTimer>::iterator it = maybeGestures.begin(), + e = maybeGestures.end(); + for (; it != e; ) { + QBasicTimer &timer = it.value(); + Q_ASSERT(timer.isActive()); + if (timer.timerId() == event->timerId()) { + timer.stop(); + QGesture *gesture = it.key(); + it = maybeGestures.erase(it); + DEBUG() << "QGestureManager::timerEvent: gesture stopped due to timeout:" << gesture; + QGestureRecognizer *recognizer = gestureToRecognizer.value(gesture, 0); + if (recognizer) + recognizer->reset(gesture); + } else { + ++it; + } + } +} + +QT_END_NAMESPACE + +#include "moc_qgesturemanager_p.cpp" diff --git a/src/gui/kernel/qgesturemanager_p.h b/src/gui/kernel/qgesturemanager_p.h new file mode 100644 index 0000000..c61819f --- /dev/null +++ b/src/gui/kernel/qgesturemanager_p.h @@ -0,0 +1,125 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGESTUREMANAGER_P_H +#define QGESTUREMANAGER_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qobject.h" +#include "qbasictimer.h" +#include "private/qwidget_p.h" +#include "qgesturerecognizer.h" + +QT_BEGIN_NAMESPACE + +class QBasicTimer; +class QGestureManager : public QObject +{ + Q_OBJECT +public: + QGestureManager(QObject *parent); + ~QGestureManager(); + + Qt::GestureType registerGestureRecognizer(QGestureRecognizer *recognizer); + void unregisterGestureRecognizer(Qt::GestureType type); + + bool filterEvent(QObject *receiver, QEvent *event); + + // declared in qapplication.cpp + static QGestureManager* instance(); + +protected: + void timerEvent(QTimerEvent *event); + +private: + QMultiMap<Qt::GestureType, QGestureRecognizer *> recognizers; + + QSet<QGesture *> activeGestures; + QMap<QGesture *, QBasicTimer> maybeGestures; + + enum State { + Gesture, + NotGesture, + MaybeGesture // this means timers are up and waiting for some + // more events, and input events are handled by + // gesture recognizer explicitely + } state; + + struct ObjectGesture + { + QWeakPointer<QObject> object; + Qt::GestureType gesture; + + ObjectGesture(QObject *o, const Qt::GestureType &g) : object(o), gesture(g) { } + inline bool operator<(const ObjectGesture& rhs) const + { + if (object.data() < rhs.object.data()) + return true; + if (object == rhs.object) + return gesture < rhs.gesture; + return false; + } + }; + + QMap<ObjectGesture, QWeakPointer<QGesture> > objectGestures; + QMap<QGesture *, QGestureRecognizer *> gestureToRecognizer; + + QHash<QGesture *, QObject *> gestureTargets; + + int lastCustomGestureId; + + QGesture *getState(QObject *widget, Qt::GestureType gesture); + void deliverEvents(const QSet<QGesture *> &gestures, QObject *lastReceiver); +}; + +QT_END_NAMESPACE + +#endif // QGESTUREMANAGER_P_H diff --git a/src/gui/kernel/qgesturerecognizer.cpp b/src/gui/kernel/qgesturerecognizer.cpp new file mode 100644 index 0000000..590f09e --- /dev/null +++ b/src/gui/kernel/qgesturerecognizer.cpp @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qgesturerecognizer.h" + +#include "private/qgesture_p.h" + +QT_BEGIN_NAMESPACE + +QGestureRecognizer::QGestureRecognizer() +{ +} + +QGestureRecognizer::~QGestureRecognizer() +{ +} + +QGesture *QGestureRecognizer::createGesture(QObject *) +{ + return new QGesture; +} + +void QGestureRecognizer::reset(QGesture *state) +{ + if (state) { + QGesturePrivate *d = state->d_func(); + d->state = Qt::NoGesture; + d->hotSpot = QPointF(); + d->targetObject = 0; + } +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qgesturerecognizer.h b/src/gui/kernel/qgesturerecognizer.h new file mode 100644 index 0000000..efd8565 --- /dev/null +++ b/src/gui/kernel/qgesturerecognizer.h @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QGESTURERECOGNIZER_H +#define QGESTURERECOGNIZER_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QObject; +class QEvent; +class QGesture; +class Q_GUI_EXPORT QGestureRecognizer +{ +public: + enum ResultFlags + { + Ignore = 0x0001, + NotGesture = 0x0002, + MaybeGesture = 0x0004, + GestureTriggered = 0x0008, // Gesture started or updated + GestureFinished = 0x0010, + + ResultState_Mask = 0x00ff, + + ConsumeEventHint = 0x0100, + // StoreEventHint = 0x0200, + // ReplayStoredEventsHint = 0x0400, + // DiscardStoredEventsHint = 0x0800, + + ResultHint_Mask = 0xff00 + }; + Q_DECLARE_FLAGS(Result, ResultFlags) + + QGestureRecognizer(); + virtual ~QGestureRecognizer(); + + virtual QGesture *createGesture(QObject *target); + virtual QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event) = 0; + + virtual void reset(QGesture *state); +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(QGestureRecognizer::Result) + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QGESTURERECOGNIZER_H diff --git a/src/gui/kernel/qsoftkeymanager.cpp b/src/gui/kernel/qsoftkeymanager.cpp index cd3ad22..1214f08 100644 --- a/src/gui/kernel/qsoftkeymanager.cpp +++ b/src/gui/kernel/qsoftkeymanager.cpp @@ -200,6 +200,7 @@ bool QSoftKeyManager::event(QEvent *e) void QSoftKeyManagerPrivate::updateSoftKeys_sys(const QList<QAction*> &softkeys) { CEikButtonGroupContainer* nativeContainer = S60->buttonGroupContainer(); + nativeContainer->DrawableWindow()->SetPointerCapturePriority(1); //keep softkeys available in modal dialog QT_TRAP_THROWING(nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS)); int position = -1; diff --git a/src/gui/kernel/qstandardgestures.cpp b/src/gui/kernel/qstandardgestures.cpp index 3cfb987..dfc3499 100644 --- a/src/gui/kernel/qstandardgestures.cpp +++ b/src/gui/kernel/qstandardgestures.cpp @@ -39,174 +39,45 @@ ** ****************************************************************************/ -#include "qstandardgestures.h" #include "qstandardgestures_p.h" - -#include <qabstractscrollarea.h> -#include <qscrollbar.h> -#include <private/qapplication_p.h> -#include <private/qevent_p.h> -#include <private/qwidget_p.h> -#include <qmath.h> +#include "qgesture.h" +#include "qgesture_p.h" +#include "qevent.h" +#include "qwidget.h" QT_BEGIN_NAMESPACE -#ifdef Q_WS_WIN -QWidgetPrivate *qt_widget_private(QWidget *widget); -#endif - -/*! - \class QPanGesture - \preliminary - \since 4.6 - - \brief The QPanGesture class represents a Pan gesture, - providing additional information related to panning. -*/ - -/*! - \enum QSwipeGesture::SwipeDirection - \brief This enum specifies the direction of the swipe gesture. - - \value NoDirection - \value Left - \value Right - \value Up - \value Down -*/ - -/*! - Creates a new pan gesture handler object and marks it as a child of - \a parent. The pan gesture handler watches \a gestureTarget for its - events. - - On some platform like Windows it's necessary to provide a non-null - widget as \a parent to get native gesture support. -*/ -QPanGesture::QPanGesture(QWidget *gestureTarget, QObject *parent) - : QGesture(*new QPanGesturePrivate, gestureTarget, parent) +QPanGestureRecognizer::QPanGestureRecognizer() { - setObjectName(QLatin1String("QPanGesture")); -} - -void QPanGesturePrivate::setupGestureTarget(QObject *newGestureTarget) -{ - Q_Q(QPanGesture); - QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); - - if (gestureTarget && gestureTarget->isWidgetType()) { - QWidget *w = static_cast<QWidget*>(gestureTarget.data()); - 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) - w->setAttribute(Qt::WA_AcceptTouchEvents, false); - w->setAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents, false); -#endif - } - - if (newGestureTarget && newGestureTarget->isWidgetType()) { - QWidget *w = static_cast<QWidget*>(newGestureTarget); - qAppPriv->widgetGestures[w].pan = q; -#if defined(Q_WS_WIN) - qt_widget_private(w)->winSetupGestures(); -#elif defined(Q_WS_MAC) - w->setAttribute(Qt::WA_AcceptTouchEvents); - w->setAttribute(Qt::WA_TouchPadAcceptSingleTouchEvents); -#endif - } - QGesturePrivate::setupGestureTarget(newGestureTarget); -} - -/*! \internal */ -bool QPanGesture::event(QEvent *event) -{ -#if defined(QT_MAC_USE_COCOA) - Q_D(QPanGesture); - if (event->type() == QEvent::Timer) { - const QTimerEvent *te = static_cast<QTimerEvent *>(event); - if (te->timerId() == d->singleTouchPanTimer.timerId()) { - d->singleTouchPanTimer.stop(); - updateState(Qt::GestureStarted); - } - } -#endif - - return QObject::event(event); } -bool QPanGesture::eventFilter(QObject *receiver, QEvent *event) +QGesture *QPanGestureRecognizer::createGesture(QObject *target) { - 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(); - QApplicationPrivate::WidgetStandardGesturesMap::iterator it; - it = qAppPriv->widgetGestures.find(static_cast<QWidget*>(receiver)); - if (it == qAppPriv->widgetGestures.end()) - return false; - if (this != it.value().pan) - return false; - Qt::GestureState nextState = Qt::NoGesture; - switch(ev->gestureType) { - case QNativeGestureEvent::GestureBegin: - // next we might receive the first gesture update event, so we - // prepare for it. - d->state = Qt::NoGesture; - return false; - case QNativeGestureEvent::Pan: - nextState = Qt::GestureUpdated; - event->accept(); - break; - case QNativeGestureEvent::GestureEnd: - if (state() == Qt::NoGesture) - return false; // some other gesture has ended - nextState = Qt::GestureFinished; - break; - default: - return false; - } - if (state() == Qt::NoGesture) { - d->lastOffset = d->totalOffset = d->offset = QSize(); - } else { - 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); - return true; + if (target && target->isWidgetType()) { + static_cast<QWidget *>(target)->setAttribute(Qt::WA_AcceptTouchEvents); } -#endif - return QGesture::eventFilter(receiver, event); + return new QPanGesture; } -/*! \internal */ -bool QPanGesture::filterEvent(QEvent *event) +QGestureRecognizer::Result QPanGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event) { - Q_D(QPanGesture); + QPanGesture *q = static_cast<QPanGesture*>(state); + QPanGesturePrivate *d = q->d_func(); - 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) { + QGestureRecognizer::Result result; + + switch (event->type()) { + case QEvent::TouchBegin: { + result = QGestureRecognizer::MaybeGesture; QTouchEvent::TouchPoint p = ev->touchPoints().at(0); d->lastPosition = p.pos().toPoint(); d->lastOffset = d->totalOffset = d->offset = QSize(); - } else if (event->type() == QEvent::TouchEnd) { - if (state() != Qt::NoGesture) { + break; + } + case QEvent::TouchEnd: { + if (q->state() != Qt::NoGesture) { if (ev->touchPoints().size() == 2) { QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0); QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1); @@ -216,11 +87,14 @@ bool QPanGesture::filterEvent(QEvent *event) p1.pos().y() - p1.lastPos().y() + p2.pos().y() - p2.lastPos().y()) / 2; d->totalOffset += d->offset; } - updateState(Qt::GestureFinished); + result = QGestureRecognizer::GestureFinished; + } else { + result = QGestureRecognizer::NotGesture; } - reset(); - } else if (event->type() == QEvent::TouchUpdate) { - if (ev->touchPoints().size() == 2) { + break; + } + case QEvent::TouchUpdate: { + if (ev->touchPoints().size() >= 2) { QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0); QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1); d->lastOffset = d->offset; @@ -230,10 +104,60 @@ bool QPanGesture::filterEvent(QEvent *event) d->totalOffset += d->offset; if (d->totalOffset.width() > 10 || d->totalOffset.height() > 10 || d->totalOffset.width() < -10 || d->totalOffset.height() < -10) { - updateState(Qt::GestureUpdated); + result = QGestureRecognizer::GestureTriggered; + } else { + result = QGestureRecognizer::MaybeGesture; } } + break; + } + case QEvent::MouseButtonPress: + case QEvent::MouseMove: + case QEvent::MouseButtonRelease: + result = QGestureRecognizer::Ignore; + break; + default: + result = QGestureRecognizer::Ignore; + break; + } + return result; +} + +void QPanGestureRecognizer::reset(QGesture *state) +{ + QPanGesture *pan = static_cast<QPanGesture*>(state); + QPanGesturePrivate *d = pan->d_func(); + + d->totalOffset = d->lastOffset = d->offset = QSizeF(); + d->lastPosition = QPoint(); + d->acceleration = 0; + +//#if defined(QT_MAC_USE_COCOA) +// d->singleTouchPanTimer.stop(); +// d->prevMousePos = QPointF(0, 0); +//#endif + + QGestureRecognizer::reset(state); +} + +/*! \internal */ +/* +bool QPanGestureRecognizer::event(QEvent *event) +{ +#if defined(QT_MAC_USE_COCOA) + Q_D(QPanGesture); + if (event->type() == QEvent::Timer) { + const QTimerEvent *te = static_cast<QTimerEvent *>(event); + if (te->timerId() == d->singleTouchPanTimer.timerId()) { + d->singleTouchPanTimer.stop(); + updateState(Qt::GestureStarted); + } } +#endif + + bool consume = false; + +#if defined(Q_WS_WIN) #elif defined(QT_MAC_USE_COCOA) // The following implements single touch // panning on Mac: @@ -244,16 +168,25 @@ bool QPanGesture::filterEvent(QEvent *event) switch (event->type()) { case QEvent::TouchBegin: { if (ev->touchPoints().size() == 1) { + d->delayManager->setEnabled(true); + consume = d->delayManager->append(d->gestureTarget, *event); d->lastPosition = QCursor::pos(); d->singleTouchPanTimer.start(panBeginDelay, this); } break;} case QEvent::TouchEnd: { - if (state() != Qt::NoGesture) + d->delayManager->setEnabled(false); + if (state() != Qt::NoGesture) { updateState(Qt::GestureFinished); + consume = true; + d->delayManager->clear(); + } else { + d->delayManager->replay(); + } reset(); break;} case QEvent::TouchUpdate: { + consume = d->delayManager->append(d->gestureTarget, *event); if (ev->touchPoints().size() == 1) { if (state() == Qt::NoGesture) { // INVARIANT: The singleTouchTimer has still not fired. @@ -261,11 +194,15 @@ bool QPanGesture::filterEvent(QEvent *event) // the starting point that it makes sense to cancel: const QPointF startPos = ev->touchPoints().at(0).startPos().toPoint(); const QPointF p = ev->touchPoints().at(0).pos().toPoint(); - if ((startPos - p).manhattanLength() > panBeginRadius) + if ((startPos - p).manhattanLength() > panBeginRadius) { + d->delayManager->replay(); + consume = false; reset(); - else + } else { d->lastPosition = QCursor::pos(); + } } else { + d->delayManager->clear(); QPointF mousePos = QCursor::pos(); QPointF dist = mousePos - d->lastPosition; d->lastPosition = mousePos; @@ -275,527 +212,25 @@ bool QPanGesture::filterEvent(QEvent *event) updateState(Qt::GestureUpdated); } } else if (state() == Qt::NoGesture) { + d->delayManager->replay(); + consume = false; reset(); } break;} + case QEvent::MouseButtonPress: + case QEvent::MouseMove: + case QEvent::MouseButtonRelease: + if (d->delayManager->isEnabled()) + consume = d->delayManager->append(d->gestureTarget, *event); + break; default: return false; } #else Q_UNUSED(event); #endif - return false; -} - -/*! \internal */ -void QPanGesture::reset() -{ - Q_D(QPanGesture); - d->lastOffset = d->totalOffset = d->offset = QSize(0, 0); - d->lastPosition = QPoint(0, 0); - -#if defined(QT_MAC_USE_COCOA) - d->singleTouchPanTimer.stop(); - d->prevMousePos = QPointF(0, 0); -#endif - - QGesture::reset(); -} - -/*! - \property QPanGesture::totalOffset - - Specifies a total pan offset since the start of the gesture. -*/ -QSizeF QPanGesture::totalOffset() const -{ - Q_D(const QPanGesture); - return d->totalOffset; -} - -/*! - \property QPanGesture::lastOffset - - Specifies a pan offset the last time the gesture was triggered. -*/ -QSizeF QPanGesture::lastOffset() const -{ - Q_D(const QPanGesture); - 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; -} - -////////////////////////////////////////////////////////////////////////////// - -/*! - \class QPinchGesture - \preliminary - \since 4.6 - - \brief The QPinchGesture class represents a Pinch gesture, - providing additional information related to zooming and/or rotation. -*/ - -/*! - Creates a new Pinch gesture handler object and marks it as a child - of \a parent. The pan gesture handler watches \a gestureTarget for its - events. - - On some platform like Windows it's necessary to provide a non-null - widget as \a parent to get native gesture support. -*/ -QPinchGesture::QPinchGesture(QWidget *gestureTarget, QObject *parent) - : QGesture(*new QPinchGesturePrivate, gestureTarget, parent) -{ - setObjectName(QLatin1String("QPinchGesture")); -} - -void QPinchGesturePrivate::setupGestureTarget(QObject *newGestureTarget) -{ - Q_Q(QPinchGesture); - if (gestureTarget && gestureTarget->isWidgetType()) { - QWidget *w = static_cast<QWidget*>(gestureTarget.data()); - QApplicationPrivate::instance()->widgetGestures[w].pinch = 0; -#ifdef Q_WS_WIN - qt_widget_private(w)->winSetupGestures(); -#endif - } - - if (newGestureTarget && newGestureTarget->isWidgetType()) { - QWidget *w = static_cast<QWidget*>(newGestureTarget); - QApplicationPrivate::instance()->widgetGestures[w].pinch = q; -#ifdef Q_WS_WIN - qt_widget_private(w)->winSetupGestures(); -#endif - } - QGesturePrivate::setupGestureTarget(newGestureTarget); -} - -/*! \internal */ -bool QPinchGesture::event(QEvent *event) -{ - return QObject::event(event); -} - -bool QPinchGesture::eventFilter(QObject *receiver, 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; - -#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) - QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); - QApplicationPrivate::WidgetStandardGesturesMap::iterator it; - it = qAppPriv->widgetGestures.find(static_cast<QWidget*>(receiver)); - if (it == qAppPriv->widgetGestures.end()) - return false; - if (this != it.value().pinch) - return false; -#endif - Qt::GestureState nextState = Qt::NoGesture; - - switch(ev->gestureType) { - case QNativeGestureEvent::GestureBegin: - // 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(); -#if defined(Q_WS_WIN) - d->initialDistance = 0; - d->lastSequenceId = ev->sequenceId; -#endif - return false; - case QNativeGestureEvent::Rotate: { - d->lastScaleFactor = d->scaleFactor; - d->lastRotationAngle = d->rotationAngle; -#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->lastRotationAngle = d->rotationAngle; - d->lastScaleFactor = d->scaleFactor; -#if defined(Q_WS_WIN) - if (d->initialDistance != 0) { - int distance = int(qint64(ev->argument)); - 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->scaleFactor += ev->percentage; -#endif - nextState = Qt::GestureUpdated; - d->changes = QPinchGesture::ScaleFactorChanged; - event->accept(); - break; - case QNativeGestureEvent::GestureEnd: - if (state() == Qt::NoGesture) - return false; // some other gesture has ended - nextState = Qt::GestureFinished; - break; - default: - return false; - } - if (d->startCenterPoint.isNull()) - 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; - } -#endif - return QGesture::eventFilter(receiver, 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; -} - -/*! \internal */ -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(); - QGesture::reset(); -} - -/*! \enum QPinchGesture::WhatChange - \value ScaleFactorChanged - \value RotationAngleChanged - \value CenterPointChanged -*/ - -/*! - \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 -{ - return d_func()->scaleFactor; -} - -/*! - \property QPinchGesture::lastScaleFactor - - Specifies a previous scale factor of the pinch gesture. -*/ -qreal QPinchGesture::lastScaleFactor() const -{ - return d_func()->lastScaleFactor; -} - -/*! - \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 -{ - return d_func()->rotationAngle; -} - -/*! - \property QPinchGesture::lastRotationAngle - - Specifies a previous rotation angle of the gesture. - - The angle is specified in degrees. -*/ -qreal QPinchGesture::lastRotationAngle() const -{ - return d_func()->lastRotationAngle; -} - -/*! - \property QPinchGesture::centerPoint - - Specifies a center point of the gesture. The point can be used as a center - point that the object is rotated around. -*/ -QPointF QPinchGesture::centerPoint() const -{ - return d_func()->centerPoint; -} - -/*! - \property QPinchGesture::lastCenterPoint - - Specifies a previous center point of the gesture. -*/ -QPointF QPinchGesture::lastCenterPoint() const -{ - return d_func()->lastCenterPoint; -} - -/*! - \property QPinchGesture::startCenterPoint - - Specifies an initial center point of the gesture. Difference between the - startCenterPoint and the centerPoint is the distance at which pinching - fingers has shifted. -*/ -QPointF QPinchGesture::startCenterPoint() const -{ - return d_func()->startCenterPoint; -} - -////////////////////////////////////////////////////////////////////////////// - -/*! - \class QSwipeGesture - \preliminary - \since 4.6 - - \brief The QSwipeGesture class represents a swipe gesture, - providing additional information related to swiping. -*/ - -/*! - Creates a new Swipe gesture handler object and marks it as a - child of \a parent. The swipe gesture handler watches \a - gestureTarget for its events. - - On some platform like Windows it's necessary to provide a non-null - widget as \a parent to get native gesture support. -*/ -QSwipeGesture::QSwipeGesture(QWidget *gestureTarget, QObject *parent) - : QGesture(*new QSwipeGesturePrivate, gestureTarget, parent) -{ - setObjectName(QLatin1String("QSwipeGesture")); -} - -void QSwipeGesturePrivate::setupGestureTarget(QObject *newGestureTarget) -{ - Q_Q(QSwipeGesture); - if (gestureTarget && gestureTarget->isWidgetType()) { - QWidget *w = static_cast<QWidget*>(gestureTarget.data()); - QApplicationPrivate::instance()->widgetGestures[w].swipe = 0; -#if defined(Q_WS_WIN) - qt_widget_private(w)->winSetupGestures(); -#endif - } - - if (newGestureTarget && newGestureTarget->isWidgetType()) { - QWidget *w = static_cast<QWidget*>(newGestureTarget); - QApplicationPrivate::instance()->widgetGestures[w].swipe = q; -#if defined(Q_WS_WIN) - qt_widget_private(w)->winSetupGestures(); -#endif - } - QGesturePrivate::setupGestureTarget(newGestureTarget); -} - -/*! - \property QSwipeGesture::swipeAngle - - Holds the angle of the swipe gesture, 0..360. -*/ -qreal QSwipeGesture::swipeAngle() const -{ - Q_D(const QSwipeGesture); - return d->swipeAngle; -} - -/*! - \property QSwipeGesture::horizontalDirection - - Holds the direction for the horizontal component of the swipe - gesture, SwipeDirection::Left or SwipeDirection::Right. - SwipeDirection::NoDirection if there is no horizontal - component to the swipe gesture. -*/ -QSwipeGesture::SwipeDirection QSwipeGesture::horizontalDirection() const -{ - Q_D(const QSwipeGesture); - if (d->swipeAngle < 0 || d->swipeAngle == 90 || d->swipeAngle == 270) - return QSwipeGesture::NoDirection; - else if (d->swipeAngle < 90 || d->swipeAngle > 270) - return QSwipeGesture::Right; - else - return QSwipeGesture::Left; -} - - -/*! - \property QSwipeGesture::verticalDirection - - Holds the direction for the vertical component of the swipe - gesture, SwipeDirection::Down or SwipeDirection::Up. - SwipeDirection::NoDirection if there is no vertical - component to the swipe gesture. -*/ -QSwipeGesture::SwipeDirection QSwipeGesture::verticalDirection() const -{ - Q_D(const QSwipeGesture); - if (d->swipeAngle <= 0 || d->swipeAngle == 180) - return QSwipeGesture::NoDirection; - else if (d->swipeAngle < 180) - return QSwipeGesture::Up; - else - return QSwipeGesture::Down; -} - -bool QSwipeGesture::eventFilter(QObject *receiver, QEvent *event) -{ - Q_D(QSwipeGesture); - if (receiver->isWidgetType() && event->type() == QEvent::NativeGesture) { - QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event); - switch (ev->gestureType) { - case QNativeGestureEvent::Swipe: - d->swipeAngle = ev->angle; - updateState(Qt::GestureStarted); - updateState(Qt::GestureUpdated); - updateState(Qt::GestureFinished); - break; - default: - return false; - } - return true; - } - return QGesture::eventFilter(receiver, event); -} - -/*! \internal */ -bool QSwipeGesture::filterEvent(QEvent *) -{ - return false; -} - -/*! \internal */ -void QSwipeGesture::reset() -{ - Q_D(QSwipeGesture); - d->swipeAngle = -1; - QGesture::reset(); + return QGestureRecognizer::Ignore; } + */ QT_END_NAMESPACE - -#include "moc_qstandardgestures.cpp" - diff --git a/src/gui/kernel/qstandardgestures.h b/src/gui/kernel/qstandardgestures.h deleted file mode 100644 index 9e8291b..0000000 --- a/src/gui/kernel/qstandardgestures.h +++ /dev/null @@ -1,174 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** No Commercial Usage -** This file contains pre-release code and may not be distributed. -** You may use this file in accordance with the terms and conditions -** contained in the Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QSTANDARDGESTURES_H -#define QSTANDARDGESTURES_H - -#include <QtGui/qevent.h> -#include <QtCore/qbasictimer.h> - -#include <QtGui/qgesture.h> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QPanGesturePrivate; -class Q_GUI_EXPORT QPanGesture : public QGesture -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QPanGesture) - - 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); - - bool filterEvent(QEvent *event); - - QSizeF totalOffset() const; - QSizeF lastOffset() const; - QSizeF offset() const; - -protected: - void reset(); - -private: - bool event(QEvent *event); - bool eventFilter(QObject *receiver, QEvent *event); - - friend class QWidget; - friend class QAbstractScrollAreaPrivate; -}; - -class QPinchGesturePrivate; -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) - - 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 totalScaleFactor() const; - qreal lastScaleFactor() const; - qreal scaleFactor() const; - - qreal totalRotationAngle() const; - qreal lastRotationAngle() const; - qreal rotationAngle() const; - -private: - bool event(QEvent *event); - bool eventFilter(QObject *receiver, QEvent *event); - - friend class QWidget; -}; - -class QSwipeGesturePrivate; -class Q_GUI_EXPORT QSwipeGesture : public QGesture -{ - Q_OBJECT - Q_ENUMS(SwipeDirection) - - Q_PROPERTY(SwipeDirection horizontalDirection READ horizontalDirection) - Q_PROPERTY(SwipeDirection verticalDirection READ verticalDirection) - Q_PROPERTY(qreal swipeAngle READ swipeAngle) - - Q_DECLARE_PRIVATE(QSwipeGesture) - -public: - enum SwipeDirection { NoDirection, Left, Right, Up, Down }; - QSwipeGesture(QWidget *gestureTarget, QObject *parent = 0); - - bool filterEvent(QEvent *event); - void reset(); - - SwipeDirection horizontalDirection() const; - SwipeDirection verticalDirection() const; - qreal swipeAngle() const; - -private: - bool eventFilter(QObject *receiver, QEvent *event); - - friend class QWidget; -}; -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSTANDARDGESTURES_H diff --git a/src/gui/kernel/qstandardgestures_p.h b/src/gui/kernel/qstandardgestures_p.h index 79aadfd..fec5c2f 100644 --- a/src/gui/kernel/qstandardgestures_p.h +++ b/src/gui/kernel/qstandardgestures_p.h @@ -53,83 +53,20 @@ // We mean it. // -#include "qevent.h" -#include "qbasictimer.h" -#include "qdebug.h" - -#include "qgesture.h" -#include "qgesture_p.h" - -#include "qstandardgestures.h" -#include "qbasictimer.h" +#include "qgesturerecognizer.h" +#include "private/qgesture_p.h" QT_BEGIN_NAMESPACE -class QPanGesturePrivate : public QGesturePrivate -{ - Q_DECLARE_PUBLIC(QPanGesture) - -public: - void setupGestureTarget(QObject *o); - - QSizeF totalOffset; - QSizeF lastOffset; - QSizeF offset; - QPointF lastPosition; - -#if defined(QT_MAC_USE_COCOA) - QBasicTimer singleTouchPanTimer; - QPointF prevMousePos; -#endif -}; - -class QPinchGesturePrivate : public QGesturePrivate +class QPanGestureRecognizer : public QGestureRecognizer { - Q_DECLARE_PUBLIC(QPinchGesture) - public: - QPinchGesturePrivate() - : changes(0), totalScaleFactor(0.), lastScaleFactor(0.), scaleFactor(0.), - totalRotationAngle(0.), lastRotationAngle(0.), rotationAngle(0.) -#ifdef Q_WS_WIN - ,initialDistance(0), lastSequenceId(0) -#endif - { - } + QPanGestureRecognizer(); - 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. - - 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 -}; - -class QSwipeGesturePrivate : public QGesturePrivate -{ - Q_DECLARE_PUBLIC(QSwipeGesture) - -public: - QSwipeGesturePrivate() - : swipeAngle(-1) - { - } + QGesture *createGesture(QObject *target); - void setupGestureTarget(QObject *o); - qreal swipeAngle; + QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event); + void reset(QGesture *state); }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 56602f7..bce06e0 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -115,6 +115,7 @@ #include "private/qevent_p.h" #include "private/qgraphicssystem_p.h" +#include "private/qgesturemanager_p.h" // widget/widget data creation count //#define QWIDGET_EXTRA_DEBUG @@ -8332,6 +8333,9 @@ bool QWidget::event(QEvent *event) (void) QApplication::sendEvent(this, &mouseEvent); break; } + case QEvent::Gesture: + event->ignore(); + break; #ifndef QT_NO_PROPERTIES case QEvent::DynamicPropertyChange: { const QByteArray &propName = static_cast<QDynamicPropertyChangeEvent *>(event)->propertyName(); @@ -11668,6 +11672,13 @@ QGraphicsProxyWidget *QWidget::graphicsProxyWidget() const Synonym for QList<QWidget *>. */ +void QWidget::grabGesture(Qt::GestureType type, Qt::GestureContext context) +{ + Q_D(QWidget); + d->gestureContext.insert(type, context); + (void)QGestureManager::instance(); // create a gesture manager +} + QT_END_NAMESPACE #include "moc_qwidget.cpp" diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index 76418af..3501c6e 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -96,7 +96,6 @@ class QIcon; class QWindowSurface; class QLocale; class QGraphicsProxyWidget; -class QGestureManager; class QGraphicsEffect; #if defined(Q_WS_X11) class QX11Info; @@ -355,6 +354,8 @@ public: QGraphicsEffect *graphicsEffect() const; void setGraphicsEffect(QGraphicsEffect *effect); + void grabGesture(Qt::GestureType type, Qt::GestureContext context = Qt::WidgetWithChildrenGesture); + public Q_SLOTS: void setWindowTitle(const QString &); #ifndef QT_NO_STYLE_STYLESHEET @@ -737,6 +738,8 @@ private: friend class QGraphicsProxyWidgetPrivate; friend class QStyleSheetStyle; friend struct QWidgetExceptionCleaner; + friend class QGestureManager; + friend class QWinNativePanGestureRecognizer; #ifdef Q_WS_MAC friend class QCoreGraphicsPaintEnginePrivate; diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index c06ef73..a549740 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -64,6 +64,8 @@ #include "QtGui/qapplication.h" #include <private/qgraphicseffect_p.h> +#include <private/qgesture_p.h> + #ifdef Q_WS_WIN #include "QtCore/qt_windows.h" #include <private/qdnd_p.h> @@ -578,6 +580,7 @@ public: #ifndef QT_NO_ACTION QList<QAction*> actions; #endif + QMap<Qt::GestureType, Qt::GestureContext> gestureContext; // Bit fields. uint high_attributes[3]; // the low ones are in QWidget::widget_attributes @@ -604,6 +607,7 @@ public: bool isBackgroundInherited() const; #elif defined(Q_WS_WIN) // <--------------------------------------------------------- WIN uint noPaintOnScreen : 1; // see qwidget_win.cpp ::paintEngine() + uint nativeGesturePanEnabled : 1; bool shouldShowMaximizeButton(); void winUpdateIsOpaque(); diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index a0982f4..2b11bec 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -2029,11 +2029,6 @@ void QWidgetPrivate::winSetupGestures() if (!q || !q->isVisible()) return; QApplicationPrivate *qAppPriv = QApplicationPrivate::instance(); - QApplicationPrivate::WidgetStandardGesturesMap::const_iterator it = - qAppPriv->widgetGestures.find(q); - if (it == qAppPriv->widgetGestures.end()) - return; - const QStandardGestures &gestures = it.value(); WId winid = q->effectiveWinId(); bool needh = false; @@ -2052,10 +2047,10 @@ void QWidgetPrivate::winSetupGestures() singleFingerPanEnabled = asa->d_func()->singleFingerPanEnabled; } if (winid && qAppPriv->SetGestureConfig) { - GESTURECONFIG gc[3]; + GESTURECONFIG gc[1]; memset(gc, 0, sizeof(gc)); gc[0].dwID = GID_PAN; - if (gestures.pan) { + if (nativeGesturePanEnabled) { gc[0].dwWant = GC_PAN; if (needv && singleFingerPanEnabled) gc[0].dwWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY; @@ -2069,16 +2064,16 @@ void QWidgetPrivate::winSetupGestures() gc[0].dwBlock = GC_PAN; } - gc[1].dwID = GID_ZOOM; - if (gestures.pinch) - gc[1].dwWant = GC_ZOOM; - else - gc[1].dwBlock = GC_ZOOM; - gc[2].dwID = GID_ROTATE; - if (gestures.pinch) - gc[2].dwWant = GC_ROTATE; - else - gc[2].dwBlock = GC_ROTATE; +// gc[1].dwID = GID_ZOOM; +// if (gestures.pinch) +// gc[1].dwWant = GC_ZOOM; +// else +// gc[1].dwBlock = GC_ZOOM; +// gc[2].dwID = GID_ROTATE; +// if (gestures.pinch) +// gc[2].dwWant = GC_ROTATE; +// else +// gc[2].dwBlock = GC_ROTATE; qAppPriv->SetGestureConfig(winid, 0, sizeof(gc)/sizeof(gc[0]), gc, sizeof(gc[0])); } diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp new file mode 100644 index 0000000..4619594 --- /dev/null +++ b/src/gui/kernel/qwinnativepangesturerecognizer_win.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "private/qwinnativepangesturerecognizer_win_p.h" + +#include "qevent.h" +#include "qgraphicsitem.h" +#include "qgesture.h" + +#include "private/qgesture_p.h" +#include "private/qevent_p.h" +#include "private/qapplication_p.h" +#include "private/qwidget_p.h" + +QT_BEGIN_NAMESPACE + +QWinNativePanGestureRecognizer::QWinNativePanGestureRecognizer() +{ +} + +QGesture* QWinNativePanGestureRecognizer::createGesture(QObject *target) const +{ + if (!target) + return new QPanGesture; // a special case + if (qobject_cast<QGraphicsObject*>(target)) + return 0; + if (!target->isWidgetType()) + return 0; + + QWidget *q = static_cast<QWidget*>(target); + QWidgetPrivate *d = q->d_func(); + d->nativeGesturePanEnabled = true; + d->winSetupGestures(); + + return new QPanGesture; +} + +QGestureRecognizer::Result QWinNativePanGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event) +{ + QPanGesture *q = static_cast<QPanGesture*>(state); + QPanGesturePrivate *d = q->d_func(); + + QGestureRecognizer::Result result = QGestureRecognizer::Ignore; + if (event->type() == QEvent::NativeGesture) { + QNativeGestureEvent *ev = static_cast<QNativeGestureEvent*>(event); + switch(ev->gestureType) { + case QNativeGestureEvent::GestureBegin: + break; + case QNativeGestureEvent::Pan: + result = QGestureRecognizer::GestureTriggered; + event->accept(); + break; + case QNativeGestureEvent::GestureEnd: + if (q->state() == Qt::NoGesture) + return QGestureRecognizer::Ignore; // some other gesture has ended + result = QGestureRecognizer::GestureFinished; + break; + default: + return QGestureRecognizer::Ignore; + } + if (q->state() == Qt::NoGesture) { + d->lastOffset = d->totalOffset = d->offset = QSize(); + } else { + 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; + } + return result; +} + +void QWinNativePanGestureRecognizer::reset(QGesture *state) +{ + QPanGesture *pan = static_cast<QPanGesture*>(state); + QPanGesturePrivate *d = pan->d_func(); + + d->totalOffset = d->lastOffset = d->offset = QSizeF(); + d->lastPosition = QPoint(); + d->acceleration = 0; + + QGestureRecognizer::reset(state); +} + +QT_END_NAMESPACE diff --git a/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h new file mode 100644 index 0000000..a1e8511 --- /dev/null +++ b/src/gui/kernel/qwinnativepangesturerecognizer_win_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QWINNATIVEPANGESTURERECOGNIZER_WIN_P_H +#define QWINNATIVEPANGESTURERECOGNIZER_WIN_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists for the convenience +// of other Qt classes. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QGestureRecognizer> + +QT_BEGIN_NAMESPACE + +class QWinNativePanGestureRecognizer : public QGestureRecognizer +{ +public: + QWinNativePanGestureRecognizer(); + + QGesture* createGesture(QObject *target) const; + + QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event); + void reset(QGesture *state); +}; + +QT_END_NAMESPACE + +#endif // QWINNATIVEPANGESTURERECOGNIZER_WIN_P_H diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index d9b824b..4da993b 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -176,22 +176,25 @@ QT_BEGIN_NAMESPACE \section1 Predefined Colors - There are 20 predefined QColors: Qt::white, Qt::black, - Qt::red, Qt::darkRed, Qt::green, Qt::darkGreen, Qt::blue, - Qt::darkBlue, Qt::cyan, Qt::darkCyan, Qt::magenta, - Qt::darkMagenta, Qt::yellow, Qt::darkYellow, Qt::gray, - Qt::darkGray, Qt::lightGray, Qt::color0, Qt::color1, and - Qt::transparent. + There are 20 predefined QColors described by the Qt::GlobalColor enum, + including black, white, primary and secondary colors, darker versions + of these colors and three shades of gray. QColor also recognizes a + variety of color names; the static colorNames() function returns a + QStringList color names that QColor knows about. \img qt-colors.png Qt Colors - QColor provides the static colorNames() function which returns a - QStringList containing the color names Qt knows about. + Additionally, the Qt::color0, Qt::color1 and Qt::transparent colors + are used for special purposes. - The colors Qt::color0 (zero pixel value) and Qt::color1 (non-zero - pixel value) are special colors for drawing in QBitmaps. Painting with - Qt::color0 sets the bitmap bits to 0 (transparent, i.e. background), and - painting with Qt::color1 sets the bits to 1 (opaque, i.e. foreground). + Qt::color0 (zero pixel value) and Qt::color1 (non-zero pixel value) + are special colors for drawing in QBitmaps. Painting with Qt::color0 + sets the bitmap bits to 0 (transparent; i.e., background), and painting + with Qt::color1 sets the bits to 1 (opaque; i.e., foreground). + + Qt::transparent is used to indicate a transparent pixel. When painting + with this value, a pixel value will be used that is appropriate for the + underlying pixel format in use. \section1 The HSV Color Model diff --git a/src/gui/painting/qpaintengineex_p.h b/src/gui/painting/qpaintengineex_p.h index 81ed06b..3ec9bd6 100644 --- a/src/gui/painting/qpaintengineex_p.h +++ b/src/gui/painting/qpaintengineex_p.h @@ -54,6 +54,7 @@ // #include <QtGui/qpaintengine.h> +#include <QtGui/qdrawutil.h> #include <private/qpaintengine_p.h> #include <private/qstroker_p.h> @@ -71,12 +72,6 @@ class QPainterState; class QPaintEngineExPrivate; struct StrokeHandler; -namespace QDrawPixmaps -{ - struct Data; - enum DrawingHint; -} - struct QIntRect { int x1, y1, x2, y2; inline void set(const QRect &r) { diff --git a/src/gui/styles/gtksymbols.cpp b/src/gui/styles/gtksymbols.cpp index d62f717..6ec5796 100644 --- a/src/gui/styles/gtksymbols.cpp +++ b/src/gui/styles/gtksymbols.cpp @@ -984,15 +984,18 @@ QIcon QGtk::getFilesystemIcon(const QFileInfo &info) if (QGtk::gnome_vfs_init && QGtk::gnome_icon_lookup_sync) { QGtk::gnome_vfs_init(); GtkIconTheme *theme = QGtk::gtk_icon_theme_get_default(); - QString fileurl = QUrl::fromLocalFile(info.absoluteFilePath()).toEncoded(); + QByteArray fileurl = QUrl::fromLocalFile(info.absoluteFilePath()).toEncoded(); char * icon_name = QGtk::gnome_icon_lookup_sync(theme, NULL, - qPrintable(fileurl), + fileurl.data(), NULL, GNOME_ICON_LOOKUP_FLAGS_NONE, NULL); - return QIcon::fromTheme(icon_name); + QString iconName = QString::fromUtf8(icon_name); g_free(icon_name); + if (iconName.startsWith(QLatin1Char('/'))) + return QIcon(iconName); + return QIcon::fromTheme(iconName); } return icon; } diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 0aed71a..e8f6d39 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -949,7 +949,7 @@ struct QtFontDesc #if !defined(Q_WS_MAC) static void match(int script, const QFontDef &request, const QString &family_name, const QString &foundry_name, int force_encoding_id, - QtFontDesc *desc, const QList<int> &blacklistedFamilies = QList<int>()); + QtFontDesc *desc, const QList<int> &blacklistedFamilies = QList<int>(), bool forceXLFD=false); #if defined(Q_WS_X11) || defined(Q_WS_QWS) static void initFontDef(const QtFontDesc &desc, const QFontDef &request, QFontDef *fontDef) @@ -1316,7 +1316,7 @@ unsigned int bestFoundry(int script, unsigned int score, int styleStrategy, */ static void match(int script, const QFontDef &request, const QString &family_name, const QString &foundry_name, int force_encoding_id, - QtFontDesc *desc, const QList<int> &blacklistedFamilies) + QtFontDesc *desc, const QList<int> &blacklistedFamilies, bool forceXLFD) { Q_UNUSED(force_encoding_id); @@ -1351,7 +1351,11 @@ static void match(int script, const QFontDef &request, unsigned int score = ~0u; +#ifdef Q_WS_X11 + load(family_name, script, forceXLFD); +#else load(family_name, script); +#endif QFontDatabasePrivate *db = privateDb(); for (int x = 0; x < db->count; ++x) { diff --git a/src/gui/text/qfontdatabase_x11.cpp b/src/gui/text/qfontdatabase_x11.cpp index ae93f90..382c4fe 100644 --- a/src/gui/text/qfontdatabase_x11.cpp +++ b/src/gui/text/qfontdatabase_x11.cpp @@ -1204,9 +1204,9 @@ static void loadFontConfig() static void initializeDb(); -static void load(const QString &family = QString(), int script = -1) +static void load(const QString &family = QString(), int script = -1, bool forceXLFD = false) { - if (X11->has_fontconfig) { + if (X11->has_fontconfig && !forceXLFD) { initializeDb(); return; } @@ -1784,7 +1784,7 @@ QFontEngine *QFontDatabase::loadXlfd(int screen, int script, const QFontDef &req QString family, foundry; QT_PREPEND_NAMESPACE(parseFontName)(families_and_foundries.at(i), foundry, family); FM_DEBUG("loadXlfd: >>>>>>>>>>>>>>trying to match '%s' encoding=%d", family.toLatin1().data(), force_encoding_id); - QT_PREPEND_NAMESPACE(match)(script, request, family, foundry, force_encoding_id, &desc); + QT_PREPEND_NAMESPACE(match)(script, request, family, foundry, force_encoding_id, &desc, QList<int>(), true); if (desc.family) break; } @@ -1847,23 +1847,26 @@ QFontEngine *QFontDatabase::loadXlfd(int screen, int script, const QFontDef &req } } else { QList<int> encodings; - if (desc.encoding) - encodings.append(int(desc.encoding->encoding)); + if (desc.encoding) { + if (desc.encoding->encoding >= 0) + encodings.append(int(desc.encoding->encoding)); + } if (desc.size) { // append all other encodings for the matched font for (int i = 0; i < desc.size->count; ++i) { QtFontEncoding *e = desc.size->encodings + i; - if (e == desc.encoding) - continue; + if (e == desc.encoding || e->encoding < 0) + continue; encodings.append(int(e->encoding)); } } // fill in the missing encodings const XlfdEncoding *enc = xlfd_encoding; for (; enc->name; ++enc) { - if (!encodings.contains(enc->id)) + if (!encodings.contains(enc->id) && enc->id >= 0) { encodings.append(enc->id); + } } #if defined(FONT_MATCH_DEBUG) @@ -1925,6 +1928,13 @@ void QFontDatabase::load(const QFontPrivate *d, int script) #ifndef QT_NO_FONTCONFIG } else if (X11->has_fontconfig) { fe = loadFc(d, script, req); + + if (fe != 0 && fe->fontDef.pixelSize != req.pixelSize) { + delete fe; + fe = loadXlfd(d->screen, script, req); + } + + #endif } else if (mainThread) { fe = loadXlfd(d->screen, script, req); diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp index 5ea4554..ffc0eb4 100644 --- a/src/gui/text/qfontengine_x11.cpp +++ b/src/gui/text/qfontengine_x11.cpp @@ -488,6 +488,7 @@ glyph_metrics_t QFontEngineXLFD::boundingBox(const QGlyphLayout &glyphs) QFixed y = overall.yoff + glyphs.offsets[i].y - xcs->ascent; overall.x = qMin(overall.x, x); overall.y = qMin(overall.y, y); + // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel xmax = qMax(xmax, overall.xoff + glyphs.offsets[i].x + xcs->rbearing); ymax = qMax(ymax, y + xcs->ascent + xcs->descent); overall.xoff += glyphs.advances_x[i]; @@ -511,6 +512,8 @@ glyph_metrics_t QFontEngineXLFD::boundingBox(glyph_t glyph) glyph_metrics_t gm; XCharStruct *xcs = charStruct(_fs, glyph); if (xcs) { + // XCharStruct::rbearing is defined as distance from left edge to rightmost pixel + // XCharStruct::width is defined as the advance gm = glyph_metrics_t(xcs->lbearing, -xcs->ascent, xcs->rbearing- xcs->lbearing, xcs->ascent + xcs->descent, xcs->width, 0); } else { diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index d8702cf..0896256 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -52,11 +52,6 @@ #include "qboxlayout.h" #include "qpainter.h" -#ifdef Q_WS_WIN -#include "qstandardgestures.h" -#include <private/qstandardgestures_p.h> -#endif - #include "qabstractscrollarea_p.h" #include <qwidget.h> @@ -165,7 +160,7 @@ QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate() viewport(0), cornerWidget(0), left(0), top(0), right(0), bottom(0), xoffset(0), yoffset(0), viewportFilter(0) #ifdef Q_WS_WIN - , panGesture(0), singleFingerPanEnabled(false) + , singleFingerPanEnabled(false) #endif { } @@ -298,14 +293,6 @@ void QAbstractScrollAreaPrivate::init() q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); layoutChildren(); - -#ifdef Q_WS_WIN - 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 } #ifdef Q_WS_WIN @@ -556,9 +543,6 @@ void QAbstractScrollArea::setViewport(QWidget *widget) if (isVisible()) d->viewport->show(); QMetaObject::invokeMethod(this, "setupViewport", Q_ARG(QWidget *, widget)); -#ifdef Q_WS_WIN - d->panGesture->setGestureTarget(widget); -#endif delete oldViewport; } } @@ -1351,26 +1335,24 @@ void QAbstractScrollArea::setupViewport(QWidget *viewport) Q_UNUSED(viewport); } -#ifdef Q_WS_WIN -void QAbstractScrollAreaPrivate::_q_gestureTriggered() -{ - Q_Q(QAbstractScrollArea); - QPanGesture *g = qobject_cast<QPanGesture*>(q->sender()); - if (!g) - return; - QScrollBar *hBar = q->horizontalScrollBar(); - QScrollBar *vBar = q->verticalScrollBar(); - QSizeF delta = g->lastOffset(); - if (!delta.isNull()) { - if (QApplication::isRightToLeft()) - delta.rwidth() *= -1; - int newX = hBar->value() - delta.width(); - int newY = vBar->value() - delta.height(); - hbar->setValue(newX); - vbar->setValue(newY); - } -} -#endif +//void QAbstractScrollAreaPrivate::_q_gestureTriggered() +//{ +// Q_Q(QAbstractScrollArea); +// QPanGesture *g = qobject_cast<QPanGesture*>(q->sender()); +// if (!g) +// return; +// QScrollBar *hBar = q->horizontalScrollBar(); +// QScrollBar *vBar = q->verticalScrollBar(); +// QSizeF delta = g->lastOffset(); +// if (!delta.isNull()) { +// if (QApplication::isRightToLeft()) +// delta.rwidth() *= -1; +// int newX = hBar->value() - delta.width(); +// int newY = vBar->value() - delta.height(); +// hbar->setValue(newX); +// vbar->setValue(newY); +// } +//} QT_END_NAMESPACE diff --git a/src/gui/widgets/qabstractscrollarea.h b/src/gui/widgets/qabstractscrollarea.h index 3773477..b3a1861 100644 --- a/src/gui/widgets/qabstractscrollarea.h +++ b/src/gui/widgets/qabstractscrollarea.h @@ -129,10 +129,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_vslide(int)) Q_PRIVATE_SLOT(d_func(), void _q_showOrHideScrollBars()) -#ifdef Q_WS_WIN - Q_PRIVATE_SLOT(d_func(), void _q_gestureTriggered()) -#endif - friend class QStyleSheetStyle; friend class QWidgetPrivate; }; diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h index 0bb2851..bfb8917 100644 --- a/src/gui/widgets/qabstractscrollarea_p.h +++ b/src/gui/widgets/qabstractscrollarea_p.h @@ -60,7 +60,6 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_SCROLLAREA -class QPanGesture; class QScrollBar; class QAbstractScrollAreaScrollBarContainer; class Q_AUTOTEST_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate @@ -102,8 +101,6 @@ public: QScopedPointer<QObject> viewportFilter; #ifdef Q_WS_WIN - QPanGesture *panGesture; - virtual void _q_gestureTriggered(); bool singleFingerPanEnabled; void setSingleFingerPanEnabled(bool on = true); #endif diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index 2ed6cd7..22438bf 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -65,11 +65,6 @@ #include <limits.h> #include <qtexttable.h> #include <qvariant.h> - -#ifdef Q_WS_WIN -#include <qstandardgestures.h> -#endif - #include <qinputcontext.h> #ifndef QT_NO_TEXTEDIT @@ -2937,33 +2932,29 @@ QAbstractTextDocumentLayout::PaintContext QPlainTextEdit::getPaintContext() cons (\a available is true) or unavailable (\a available is false). */ -#ifdef Q_WS_WIN - -void QPlainTextEditPrivate::_q_gestureTriggered() -{ - Q_Q(QPlainTextEdit); - QPanGesture *g = qobject_cast<QPanGesture*>(q->sender()); - if (!g) - return; - QScrollBar *hBar = q->horizontalScrollBar(); - QScrollBar *vBar = q->verticalScrollBar(); - if (g->state() == Qt::GestureStarted) - originalOffsetY = vBar->value(); - QSizeF totalOffset = g->totalOffset(); - if (!totalOffset.isNull()) { - if (QApplication::isRightToLeft()) - totalOffset.rwidth() *= -1; - // QPlainTextEdit scrolls by lines only in vertical direction - QFontMetrics fm(q->document()->defaultFont()); - int lineHeight = fm.height(); - int newX = hBar->value() - g->lastOffset().width(); - int newY = originalOffsetY - totalOffset.height()/lineHeight; - hbar->setValue(newX); - vbar->setValue(newY); - } -} - -#endif +//void QPlainTextEditPrivate::_q_gestureTriggered() +//{ +// Q_Q(QPlainTextEdit); +// QPanGesture *g = qobject_cast<QPanGesture*>(q->sender()); +// if (!g) +// return; +// QScrollBar *hBar = q->horizontalScrollBar(); +// QScrollBar *vBar = q->verticalScrollBar(); +// if (g->state() == Qt::GestureStarted) +// originalOffsetY = vBar->value(); +// QSizeF totalOffset = g->totalOffset(); +// if (!totalOffset.isNull()) { +// if (QApplication::isRightToLeft()) +// totalOffset.rwidth() *= -1; +// // QPlainTextEdit scrolls by lines only in vertical direction +// QFontMetrics fm(q->document()->defaultFont()); +// int lineHeight = fm.height(); +// int newX = hBar->value() - g->lastOffset().width(); +// int newY = originalOffsetY - totalOffset.height()/lineHeight; +// hbar->setValue(newX); +// vbar->setValue(newY); +// } +//} QT_END_NAMESPACE diff --git a/src/gui/widgets/qplaintextedit.h b/src/gui/widgets/qplaintextedit.h index 1d6881b..60aed1d 100644 --- a/src/gui/widgets/qplaintextedit.h +++ b/src/gui/widgets/qplaintextedit.h @@ -270,10 +270,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_verticalScrollbarActionTriggered(int)) Q_PRIVATE_SLOT(d_func(), void _q_cursorPositionChanged()) -#ifdef Q_WS_WIN - Q_PRIVATE_SLOT(d_func(), void _q_gestureTriggered()) -#endif - friend class QPlainTextEditControl; }; diff --git a/src/gui/widgets/qplaintextedit_p.h b/src/gui/widgets/qplaintextedit_p.h index 5fe6f4d..7adf403 100644 --- a/src/gui/widgets/qplaintextedit_p.h +++ b/src/gui/widgets/qplaintextedit_p.h @@ -72,7 +72,6 @@ class QMimeData; class QPlainTextEdit; class ExtraArea; -class QPanGesture; class QPlainTextEditControl : public QTextControl { @@ -179,10 +178,6 @@ public: void _q_modificationChanged(bool); int originalOffsetY; - -#ifdef Q_WS_WIN - void _q_gestureTriggered(); -#endif }; QT_END_NAMESPACE diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index 5585208..8fc95cf 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -451,6 +451,7 @@ void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz, QT_CHECK_GLERROR(); valid = checkFramebufferStatus(); + glBindTexture(target, 0); color_buffer = 0; } else { @@ -819,7 +820,8 @@ QGLFramebufferObject::~QGLFramebufferObject() if (isValid() && ctx) { QGLShareContextScope scope(ctx); - glDeleteTextures(1, &d->texture); + if (d->texture) + glDeleteTextures(1, &d->texture); if (d->color_buffer) glDeleteRenderbuffers(1, &d->color_buffer); if (d->depth_stencil_buffer) diff --git a/src/opengl/qglframebufferobject_p.h b/src/opengl/qglframebufferobject_p.h index 055a752..9fe80b8 100644 --- a/src/opengl/qglframebufferobject_p.h +++ b/src/opengl/qglframebufferobject_p.h @@ -127,7 +127,7 @@ private: class QGLFramebufferObjectPrivate { public: - QGLFramebufferObjectPrivate() : fbo_guard(0), depth_stencil_buffer(0), valid(false), previous_fbo(0), engine(0) {} + QGLFramebufferObjectPrivate() : fbo_guard(0), texture(0), depth_stencil_buffer(0), color_buffer(0), valid(false), previous_fbo(0), engine(0) {} ~QGLFramebufferObjectPrivate() {} void init(QGLFramebufferObject *q, const QSize& sz, diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 60da6c7..8e3ce81 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -399,7 +399,8 @@ SUBDIRS += \ selftests \ symbols \ qrand \ - utf8 + utf8 \ + gestures !wince*:SUBDIRS += $$Q3SUBDIRS diff --git a/tests/auto/gestures/gestures.pro b/tests/auto/gestures/gestures.pro new file mode 100644 index 0000000..da5610f --- /dev/null +++ b/tests/auto/gestures/gestures.pro @@ -0,0 +1,5 @@ +load(qttest_p4) +SOURCES += tst_gestures.cpp + + + diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp new file mode 100644 index 0000000..0a6caff --- /dev/null +++ b/tests/auto/gestures/tst_gestures.cpp @@ -0,0 +1,625 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** 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 Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + + +#include <QtTest/QtTest> +#include "../../shared/util.h" + +#include <qevent.h> +#include <qwidget.h> +#include <qlayout.h> +#include <qgesture.h> +#include <qgesturerecognizer.h> +#include <qgraphicsitem.h> +#include <qgraphicsview.h> + +#include <qdebug.h> + +//TESTED_CLASS= +//TESTED_FILES= + +class CustomGesture : public QGesture +{ + Q_OBJECT +public: + static Qt::GestureType GestureType; + + CustomGesture(QObject *parent = 0) + : QGesture(parent), target(0), serial(0) + { + } + + QObject *target; + int serial; + + static const int SerialMaybeThreshold; + static const int SerialStartedThreshold; + static const int SerialFinishedThreshold; +}; +Qt::GestureType CustomGesture::GestureType = Qt::CustomGesture; +const int CustomGesture::SerialMaybeThreshold = 1; +const int CustomGesture::SerialStartedThreshold = 3; +const int CustomGesture::SerialFinishedThreshold = 6; + +class CustomEvent : public QEvent +{ +public: + static int EventType; + + CustomEvent(int serial_ = 0) + : QEvent(QEvent::Type(CustomEvent::EventType)), + serial(serial_), targetObject(0) + { + } + + int serial; + QObject *targetObject; + QPoint hotSpot; +}; +int CustomEvent::EventType = 0; + +class CustomGestureRecognizer : public QGestureRecognizer +{ +public: + CustomGestureRecognizer() + { + CustomEvent::EventType = QEvent::registerEventType(); + eventsCounter = 0; + } + + QGesture* createGesture(QObject *) + { + return new CustomGesture; + } + + QGestureRecognizer::Result filterEvent(QGesture *state, QObject*, QEvent *event) + { + if (event->type() == CustomEvent::EventType) { + QGestureRecognizer::Result result = QGestureRecognizer::ConsumeEventHint; + CustomGesture *g = static_cast<CustomGesture*>(state); + CustomEvent *e = static_cast<CustomEvent*>(event); + g->serial = e->serial; + g->setTargetObject(e->targetObject); + g->setHotSpot(e->hotSpot); + ++eventsCounter; + if (g->serial >= CustomGesture::SerialFinishedThreshold) + result |= QGestureRecognizer::GestureFinished; + else if (g->serial >= CustomGesture::SerialStartedThreshold) + result |= QGestureRecognizer::GestureTriggered; + else if (g->serial >= CustomGesture::SerialMaybeThreshold) + result |= QGestureRecognizer::MaybeGesture; + else + result = QGestureRecognizer::NotGesture; + return result; + } + return QGestureRecognizer::Ignore; + } + + void reset(QGesture *state) + { + CustomGesture *g = static_cast<CustomGesture*>(state); + g->serial = 0; + QGestureRecognizer::reset(state); + } + + int eventsCounter; + QString name; +}; + +class GestureWidget : public QWidget +{ + Q_OBJECT +public: + GestureWidget(const char *name = 0) + { + if (name) + setObjectName(QLatin1String(name)); + reset(); + acceptGestureOverride = false; + } + void reset() + { + customEventsReceived = 0; + gestureEventsReceived = 0; + gestureOverrideEventsReceived = 0; + events.clear(); + overrideEvents.clear(); + } + + int customEventsReceived; + int gestureEventsReceived; + int gestureOverrideEventsReceived; + struct Events + { + QList<Qt::GestureType> all; + QList<Qt::GestureType> started; + QList<Qt::GestureType> updated; + QList<Qt::GestureType> finished; + QList<Qt::GestureType> canceled; + + void clear() + { + all.clear(); + started.clear(); + updated.clear(); + finished.clear(); + canceled.clear(); + } + } events, overrideEvents; + + bool acceptGestureOverride; + +protected: + bool event(QEvent *event) + { + Events *eventsPtr = 0; + if (event->type() == QEvent::Gesture) { + ++gestureEventsReceived; + eventsPtr = &events; + } else if (event->type() == QEvent::GestureOverride) { + ++gestureOverrideEventsReceived; + eventsPtr = &overrideEvents; + if (acceptGestureOverride) + event->accept(); + } + if (eventsPtr) { + QGestureEvent *e = static_cast<QGestureEvent*>(event); + QList<QGesture*> gestures = e->allGestures(); + foreach(QGesture *g, gestures) { + eventsPtr->all << g->gestureType(); + switch(g->state()) { + case Qt::GestureStarted: + eventsPtr->started << g->gestureType(); + break; + case Qt::GestureUpdated: + eventsPtr->updated << g->gestureType(); + break; + case Qt::GestureFinished: + eventsPtr->finished << g->gestureType(); + break; + case Qt::GestureCanceled: + eventsPtr->canceled << g->gestureType(); + break; + default: + Q_ASSERT(false); + } + } + } else if (event->type() == CustomEvent::EventType) { + ++customEventsReceived; + } else { + return QWidget::event(event); + } + return true; + } +}; + +static void sendCustomGesture(QObject *object) +{ + CustomEvent ev; + ev.targetObject = object; + for (int i = CustomGesture::SerialMaybeThreshold; + i <= CustomGesture::SerialFinishedThreshold; ++i) { + ev.serial = i; + QApplication::sendEvent(object, &ev); + } +} + +class tst_Gestures : public QObject +{ +Q_OBJECT + +public: + tst_Gestures(); + virtual ~tst_Gestures(); + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void customGesture(); + void autoCancelingGestures(); + void gestureOverChild(); + void multipleWidgetOnlyGestureInTree(); + void conflictingGestures(); + void finishedWithoutStarted(); + void unknownGesture(); + void graphicsItemGesture(); +}; + +tst_Gestures::tst_Gestures() +{ +} + +tst_Gestures::~tst_Gestures() +{ +} + +void tst_Gestures::initTestCase() +{ + CustomGesture::GestureType = qApp->registerGestureRecognizer(new CustomGestureRecognizer); + QVERIFY(CustomGesture::GestureType != Qt::GestureType(0)); + QVERIFY(CustomGesture::GestureType != Qt::CustomGesture); +} + +void tst_Gestures::cleanupTestCase() +{ +} + +void tst_Gestures::init() +{ +} + +void tst_Gestures::cleanup() +{ +} + +void tst_Gestures::customGesture() +{ + GestureWidget widget; + widget.grabGesture(CustomGesture::GestureType, Qt::WidgetGesture); + sendCustomGesture(&widget); + + static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1; + static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1; + QCOMPARE(widget.customEventsReceived, TotalCustomEventsCount); + QCOMPARE(widget.gestureEventsReceived, TotalGestureEventsCount); + QCOMPARE(widget.gestureOverrideEventsReceived, 0); + QCOMPARE(widget.events.all.size(), TotalGestureEventsCount); + for(int i = 0; i < widget.events.all.size(); ++i) + QCOMPARE(widget.events.all.at(i), CustomGesture::GestureType); + QCOMPARE(widget.events.started.size(), 1); + QCOMPARE(widget.events.updated.size(), TotalGestureEventsCount - 2); + QCOMPARE(widget.events.finished.size(), 1); + QCOMPARE(widget.events.canceled.size(), 0); +} + +void tst_Gestures::autoCancelingGestures() +{ + GestureWidget widget; + widget.grabGesture(CustomGesture::GestureType, Qt::WidgetGesture); + // send partial gesture. The gesture will be in the "maybe" state, but will + // never get enough events to fire, so Qt will have to kill it. + CustomEvent ev; + for (int i = CustomGesture::SerialMaybeThreshold; + i < CustomGesture::SerialStartedThreshold; ++i) { + ev.serial = i; + QApplication::sendEvent(&widget, &ev); + } + // wait long enough so the gesture manager will cancel the gesture + QTest::qWait(5000); + QCOMPARE(widget.customEventsReceived, CustomGesture::SerialStartedThreshold - CustomGesture::SerialMaybeThreshold); + QCOMPARE(widget.gestureEventsReceived, 0); + QCOMPARE(widget.gestureOverrideEventsReceived, 0); + QCOMPARE(widget.events.all.size(), 0); +} + +void tst_Gestures::gestureOverChild() +{ + GestureWidget widget("widget"); + QVBoxLayout *l = new QVBoxLayout(&widget); + GestureWidget *child = new GestureWidget("child"); + l->addWidget(child); + + widget.grabGesture(CustomGesture::GestureType, Qt::WidgetGesture); + + sendCustomGesture(child); + + static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1; + static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1; + + QCOMPARE(child->customEventsReceived, TotalCustomEventsCount); + QCOMPARE(widget.customEventsReceived, 0); + QCOMPARE(child->gestureEventsReceived, 0); + QCOMPARE(child->gestureOverrideEventsReceived, 0); + QCOMPARE(widget.gestureEventsReceived, 0); + QCOMPARE(widget.gestureOverrideEventsReceived, 0); + + // enable gestures over the children + widget.grabGesture(CustomGesture::GestureType, Qt::WidgetWithChildrenGesture); + + widget.reset(); + child->reset(); + + sendCustomGesture(child); + + QCOMPARE(child->customEventsReceived, TotalCustomEventsCount); + QCOMPARE(widget.customEventsReceived, 0); + + QCOMPARE(child->gestureEventsReceived, 0); + QCOMPARE(child->gestureOverrideEventsReceived, 0); + QCOMPARE(widget.gestureEventsReceived, TotalGestureEventsCount); + QCOMPARE(widget.gestureOverrideEventsReceived, 0); + for(int i = 0; i < widget.events.all.size(); ++i) + QCOMPARE(widget.events.all.at(i), CustomGesture::GestureType); + QCOMPARE(widget.events.started.size(), 1); + QCOMPARE(widget.events.updated.size(), TotalGestureEventsCount - 2); + QCOMPARE(widget.events.finished.size(), 1); + QCOMPARE(widget.events.canceled.size(), 0); +} + +void tst_Gestures::multipleWidgetOnlyGestureInTree() +{ + GestureWidget parent("parent"); + QVBoxLayout *l = new QVBoxLayout(&parent); + GestureWidget *child = new GestureWidget("child"); + l->addWidget(child); + + parent.grabGesture(CustomGesture::GestureType, Qt::WidgetGesture); + child->grabGesture(CustomGesture::GestureType, Qt::WidgetGesture); + + static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1; + static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1; + + // sending events to the child and making sure there is no conflict + sendCustomGesture(child); + + QCOMPARE(child->customEventsReceived, TotalCustomEventsCount); + QCOMPARE(parent.customEventsReceived, 0); + QCOMPARE(child->gestureEventsReceived, TotalGestureEventsCount); + QCOMPARE(child->gestureOverrideEventsReceived, 0); + QCOMPARE(parent.gestureEventsReceived, 0); + QCOMPARE(parent.gestureOverrideEventsReceived, 0); + + parent.reset(); + child->reset(); + + // same for the parent widget + sendCustomGesture(&parent); + + QCOMPARE(child->customEventsReceived, 0); + QCOMPARE(parent.customEventsReceived, TotalCustomEventsCount); + QCOMPARE(child->gestureEventsReceived, 0); + QCOMPARE(child->gestureOverrideEventsReceived, 0); + QCOMPARE(parent.gestureEventsReceived, TotalGestureEventsCount); + QCOMPARE(parent.gestureOverrideEventsReceived, 0); +} + +void tst_Gestures::conflictingGestures() +{ + GestureWidget parent("parent"); + QVBoxLayout *l = new QVBoxLayout(&parent); + GestureWidget *child = new GestureWidget("child"); + l->addWidget(child); + + parent.grabGesture(CustomGesture::GestureType, Qt::WidgetWithChildrenGesture); + child->grabGesture(CustomGesture::GestureType, Qt::WidgetWithChildrenGesture); + + static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1; + + // child accepts the override, parent will not receive anything + parent.acceptGestureOverride = false; + child->acceptGestureOverride = true; + + // sending events to the child and making sure there is no conflict + sendCustomGesture(child); + + QCOMPARE(child->gestureOverrideEventsReceived, TotalGestureEventsCount); + QCOMPARE(child->gestureEventsReceived, 0); + QCOMPARE(parent.gestureOverrideEventsReceived, 0); + QCOMPARE(parent.gestureEventsReceived, 0); + + parent.reset(); + child->reset(); + + // parent accepts the override + parent.acceptGestureOverride = true; + child->acceptGestureOverride = false; + + // sending events to the child and making sure there is no conflict + sendCustomGesture(child); + + QCOMPARE(child->gestureOverrideEventsReceived, TotalGestureEventsCount); + QCOMPARE(child->gestureEventsReceived, 0); + QCOMPARE(parent.gestureOverrideEventsReceived, TotalGestureEventsCount); + QCOMPARE(parent.gestureEventsReceived, 0); + + parent.reset(); + child->reset(); + + // nobody accepts the override, we will send normal events to the closest context (to the child) + parent.acceptGestureOverride = false; + child->acceptGestureOverride = false; + + // sending events to the child and making sure there is no conflict + sendCustomGesture(child); + + QCOMPARE(child->gestureOverrideEventsReceived, TotalGestureEventsCount); + QCOMPARE(child->gestureEventsReceived, TotalGestureEventsCount); + QCOMPARE(parent.gestureOverrideEventsReceived, TotalGestureEventsCount); + QCOMPARE(parent.gestureEventsReceived, 0); +} + +void tst_Gestures::finishedWithoutStarted() +{ + GestureWidget widget; + widget.grabGesture(CustomGesture::GestureType, Qt::WidgetGesture); + // the gesture will claim it finished, but it was never started. + CustomEvent ev; + QTest::ignoreMessage(QtWarningMsg, "QGestureManager::filterEvent: some gestures were finished even though they've never started"); + for (int i = CustomGesture::SerialFinishedThreshold; + i < CustomGesture::SerialFinishedThreshold+1; ++i) { + ev.serial = i; + QApplication::sendEvent(&widget, &ev); + } + + QCOMPARE(widget.gestureEventsReceived, 0); + QCOMPARE(widget.gestureOverrideEventsReceived, 0); +} + +void tst_Gestures::unknownGesture() +{ + GestureWidget widget; + widget.grabGesture(CustomGesture::GestureType, Qt::WidgetGesture); + widget.grabGesture(Qt::CustomGesture, Qt::WidgetGesture); + widget.grabGesture(Qt::GestureType(Qt::PanGesture+512), Qt::WidgetGesture); + + sendCustomGesture(&widget); + + static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1; + + QCOMPARE(widget.gestureEventsReceived, TotalGestureEventsCount); +} + +class GestureItem : public QGraphicsObject +{ +public: + GestureItem() + { + size = QRectF(0, 0, 100, 100); + customEventsReceived = 0; + gestureEventsReceived = 0; + gestureOverrideEventsReceived = 0; + events.clear(); + overrideEvents.clear(); + acceptGestureOverride = false; + } + + int customEventsReceived; + int gestureEventsReceived; + int gestureOverrideEventsReceived; + struct Events + { + QList<Qt::GestureType> all; + QList<Qt::GestureType> started; + QList<Qt::GestureType> updated; + QList<Qt::GestureType> finished; + QList<Qt::GestureType> canceled; + + void clear() + { + all.clear(); + started.clear(); + updated.clear(); + finished.clear(); + canceled.clear(); + } + } events, overrideEvents; + + bool acceptGestureOverride; + + QRectF size; + +protected: + QRectF boundingRect() const + { + return size; + } + void paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *) + { + p->fillRect(boundingRect(), Qt::blue); + } + + bool event(QEvent *event) + { + Events *eventsPtr = 0; + if (event->type() == QEvent::Gesture) { + ++gestureEventsReceived; + eventsPtr = &events; + } else if (event->type() == QEvent::GestureOverride) { + ++gestureOverrideEventsReceived; + eventsPtr = &overrideEvents; + if (acceptGestureOverride) + event->accept(); + } + if (eventsPtr) { + QGestureEvent *e = static_cast<QGestureEvent*>(event); + QList<QGesture*> gestures = e->allGestures(); + foreach(QGesture *g, gestures) { + eventsPtr->all << g->gestureType(); + switch(g->state()) { + case Qt::GestureStarted: + eventsPtr->started << g->gestureType(); + break; + case Qt::GestureUpdated: + eventsPtr->updated << g->gestureType(); + break; + case Qt::GestureFinished: + eventsPtr->finished << g->gestureType(); + break; + case Qt::GestureCanceled: + eventsPtr->canceled << g->gestureType(); + break; + default: + Q_ASSERT(false); + } + } + } else if (event->type() == CustomEvent::EventType) { + ++customEventsReceived; + } else { + return QGraphicsObject::event(event); + } + return true; + } +}; + +void tst_Gestures::graphicsItemGesture() +{ + QGraphicsScene scene; + QGraphicsView view(&scene); + + GestureItem *item = new GestureItem; + scene.addItem(item); + item->setPos(100, 100); + + item->grabGesture(CustomGesture::GestureType); + + sendCustomGesture(item); + + static const int TotalGestureEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialStartedThreshold + 1; + static const int TotalCustomEventsCount = CustomGesture::SerialFinishedThreshold - CustomGesture::SerialMaybeThreshold + 1; + + QCOMPARE(item->customEventsReceived, TotalCustomEventsCount); + QCOMPARE(item->gestureEventsReceived, TotalGestureEventsCount); + QCOMPARE(item->gestureOverrideEventsReceived, 0); + QCOMPARE(item->events.all.size(), TotalGestureEventsCount); + for(int i = 0; i < item->events.all.size(); ++i) + QCOMPARE(item->events.all.at(i), CustomGesture::GestureType); + QCOMPARE(item->events.started.size(), 1); + QCOMPARE(item->events.updated.size(), TotalGestureEventsCount - 2); + QCOMPARE(item->events.finished.size(), 1); + QCOMPARE(item->events.canceled.size(), 0); +} + +QTEST_MAIN(tst_Gestures) +#include "tst_gestures.moc" diff --git a/tests/auto/qinputcontext/tst_qinputcontext.cpp b/tests/auto/qinputcontext/tst_qinputcontext.cpp index c3c3db4..a1c4ef7 100644 --- a/tests/auto/qinputcontext/tst_qinputcontext.cpp +++ b/tests/auto/qinputcontext/tst_qinputcontext.cpp @@ -129,6 +129,9 @@ public: RequestSoftwareInputPanelStyle() : m_rsipBehavior(RSIP_OnMouseClickAndAlreadyFocused) { +#ifdef Q_OS_WINCE + qApp->setAutoSipEnabled(true); +#endif } ~RequestSoftwareInputPanelStyle() { diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index 4ea1b19..eab5a35 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -3569,17 +3569,14 @@ void tst_QTableView::mouseWheel_data() void tst_QTableView::mouseWheel() { +#ifdef Q_OS_WINCE + QSKIP("Since different Windows CE versions sport different taskbars, we skip this test", SkipAll); +#endif QFETCH(int, scrollMode); QFETCH(int, delta); QFETCH(int, horizontalPositon); QFETCH(int, verticalPosition); - if (scrollMode == int(QAbstractItemView::ScrollPerPixel)) - { -#ifdef Q_OS_WINCE - QSKIP("Since different Windows CE versions sport different taskbars, we skip this test", SkipSingle); -#endif - } QtTestTableModel model(100, 100); QtTestTableView view; view.resize(500, 500); diff --git a/tests/auto/quuid/tst_quuid.cpp b/tests/auto/quuid/tst_quuid.cpp index e262be7..d78fda5 100644 --- a/tests/auto/quuid/tst_quuid.cpp +++ b/tests/auto/quuid/tst_quuid.cpp @@ -72,6 +72,8 @@ private slots: void variants(); void versions(); + void threadUniqueness(); + public: // Variables QUuid uuidA; @@ -169,6 +171,30 @@ void tst_QUuid::versions() QVERIFY( NCS.version() == QUuid::VerUnknown ); } +class UuidThread : public QThread +{ +public: + QUuid uuid; + + void run() + { + uuid = QUuid::createUuid(); + } +}; + +void tst_QUuid::threadUniqueness() +{ + QVector<UuidThread *> threads(qMax(2, QThread::idealThreadCount())); + for (int i = 0; i < threads.count(); ++i) + threads[i] = new UuidThread; + for (int i = 0; i < threads.count(); ++i) + threads[i]->start(); + for (int i = 0; i < threads.count(); ++i) + QVERIFY(threads[i]->wait(1000)); + for (int i = 1; i < threads.count(); ++i) + QVERIFY(threads[0]->uuid != threads[i]->uuid); + qDeleteAll(threads); +} QTEST_MAIN(tst_QUuid) #include "tst_quuid.moc" diff --git a/tests/manual/gestures/graphicsview/gestures.cpp b/tests/manual/gestures/graphicsview/gestures.cpp new file mode 100644 index 0000000..5416457 --- /dev/null +++ b/tests/manual/gestures/graphicsview/gestures.cpp @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** 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 Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "gestures.h" + +#include <QTouchEvent> + +Qt::GestureType ThreeFingerSlideGesture::Type = Qt::CustomGesture; + +QGesture *ThreeFingerSlideGestureRecognizer::createGesture(QObject *) +{ + return new ThreeFingerSlideGesture; +} + +QGestureRecognizer::Result ThreeFingerSlideGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event) +{ + ThreeFingerSlideGesture *d = static_cast<ThreeFingerSlideGesture *>(state); + QGestureRecognizer::Result result; + switch (event->type()) { + case QEvent::TouchBegin: + result = QGestureRecognizer::MaybeGesture; + case QEvent::TouchEnd: + if (d->gestureFired) + result = QGestureRecognizer::GestureFinished; + else + result = QGestureRecognizer::NotGesture; + case QEvent::TouchUpdate: + if (d->state() != Qt::NoGesture) { + QTouchEvent *ev = static_cast<QTouchEvent*>(event); + if (ev->touchPoints().size() == 3) { + d->gestureFired = true; + result = QGestureRecognizer::GestureTriggered; + } else { + result = QGestureRecognizer::MaybeGesture; + for (int i = 0; i < ev->touchPoints().size(); ++i) { + const QTouchEvent::TouchPoint &pt = ev->touchPoints().at(i); + const int distance = (pt.pos().toPoint() - pt.startPos().toPoint()).manhattanLength(); + if (distance > 20) { + result = QGestureRecognizer::NotGesture; + } + } + } + } else { + result = QGestureRecognizer::NotGesture; + } + + break; + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + if (d->state() != Qt::NoGesture) + result = QGestureRecognizer::Ignore; + else + result = QGestureRecognizer::NotGesture; + break; + default: + result = QGestureRecognizer::Ignore; + break; + } + return result; +} + +void ThreeFingerSlideGestureRecognizer::reset(QGesture *state) +{ + static_cast<ThreeFingerSlideGesture *>(state)->gestureFired = false; + QGestureRecognizer::reset(state); +} + + +QGesture *RotateGestureRecognizer::createGesture(QObject *) +{ + return new QGesture; +} + +QGestureRecognizer::Result RotateGestureRecognizer::filterEvent(QGesture *, QObject *, QEvent *event) +{ + switch (event->type()) { + case QEvent::TouchBegin: + case QEvent::TouchEnd: + case QEvent::TouchUpdate: + break; + default: + break; + } + return QGestureRecognizer::Ignore; +} + +void RotateGestureRecognizer::reset(QGesture *state) +{ + QGestureRecognizer::reset(state); +} + +#include "moc_gestures.cpp" diff --git a/tests/manual/gestures/graphicsview/gestures.h b/tests/manual/gestures/graphicsview/gestures.h new file mode 100644 index 0000000..6140b12 --- /dev/null +++ b/tests/manual/gestures/graphicsview/gestures.h @@ -0,0 +1,78 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** 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 Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GESTURE_H +#define GESTURE_H + +#include <QGestureRecognizer> +#include <QGesture> + +class ThreeFingerSlideGesture : public QGesture +{ + Q_OBJECT +public: + static Qt::GestureType Type; + + ThreeFingerSlideGesture(QObject *parent = 0) : QGesture(parent) { } + + bool gestureFired; +}; + +class ThreeFingerSlideGestureRecognizer : public QGestureRecognizer +{ +private: + QGesture* createGesture(QObject *target); + QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event); + void reset(QGesture *state); +}; + +class RotateGestureRecognizer : public QGestureRecognizer +{ +public: + RotateGestureRecognizer(); + +private: + QGesture* createGesture(QObject *target); + QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event); + void reset(QGesture *state); +}; + +#endif // GESTURE_H diff --git a/tests/manual/gestures/graphicsview/graphicsview.pro b/tests/manual/gestures/graphicsview/graphicsview.pro new file mode 100644 index 0000000..a40c323 --- /dev/null +++ b/tests/manual/gestures/graphicsview/graphicsview.pro @@ -0,0 +1,17 @@ +# ##################################################################### +# Automatically generated by qmake (2.01a) Mon Sep 7 13:26:43 2009 +# ##################################################################### +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +SOURCES += main.cpp \ + imageitem.cpp \ + gestures.cpp \ + mousepangesturerecognizer.cpp + +HEADERS += imageitem.h \ + gestures.h \ + mousepangesturerecognizer.h diff --git a/tests/manual/gestures/graphicsview/imageitem.cpp b/tests/manual/gestures/graphicsview/imageitem.cpp new file mode 100644 index 0000000..307d7e4 --- /dev/null +++ b/tests/manual/gestures/graphicsview/imageitem.cpp @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** 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 Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "imageitem.h" +#include "gestures.h" + +#include <QPainter> +#include <QEvent> + +ImageItem::ImageItem(const QImage &image) +{ + setImage(image); +} + +void ImageItem::setImage(const QImage &image) +{ + image_ = image; + pixmap_ = QPixmap::fromImage(image.scaled(400, 400, Qt::KeepAspectRatio)); + update(); +} + +QImage ImageItem::image() const +{ + return image_; +} + +QRectF ImageItem::boundingRect() const +{ + const QSize size = pixmap_.size(); + return QRectF(0, 0, size.width(), size.height()); +} + +void ImageItem::paint(QPainter *painter, const QStyleOptionGraphicsItem*, QWidget*) +{ + painter->drawPixmap(0, 0, pixmap_); +} + + +GestureImageItem::GestureImageItem(const QImage &image) + : ImageItem(image) +{ + grabGesture(Qt::PanGesture); + grabGesture(ThreeFingerSlideGesture::Type); +} + +bool GestureImageItem::event(QEvent *event) +{ + if (event->type() == QEvent::Gesture) { + qDebug("gestureimageitem: gesture triggered"); + return true; + } + return ImageItem::event(event); +} + +#include "moc_imageitem.cpp" diff --git a/tests/manual/gestures/pinch/pinchwidget.h b/tests/manual/gestures/graphicsview/imageitem.h index 7628ffc..776c8d1 100644 --- a/tests/manual/gestures/pinch/pinchwidget.h +++ b/tests/manual/gestures/graphicsview/imageitem.h @@ -39,40 +39,39 @@ ** ****************************************************************************/ -#ifndef PINCHWIDGET_H -#define PINCHWIDGET_H +#ifndef IMAGEITEM_H +#define IMAGEITEM_H -#include <QWidget> +#include <QGraphicsItem> +#include <QImage> +#include <QPixmap> #include <QTransform> -class QPanGesture; -class QPinchGesture; - -class PinchWidget : public QWidget +class ImageItem : public QGraphicsObject { Q_OBJECT public: - PinchWidget(const QImage &image, QWidget *parent = 0); - -private Q_SLOTS: - void acceptTouchEvents(); - void onPanTriggered(); - void onPanFinished(); - void onPinchTriggered(); - void onPinchFinished(); + ImageItem(const QImage &image); + void setImage(const QImage &image); + QImage image() const; + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); private: - void paintEvent(QPaintEvent *); - QSize sizeHint() const; + QImage image_; + QPixmap pixmap_; + QTransform transform; +}; - QImage image; +class GestureImageItem : public ImageItem +{ + Q_OBJECT - QPanGesture *pan; - QPinchGesture *pinch; +public: + GestureImageItem(const QImage &image); - QTransform worldTransform; - QTransform currentPanTransform; - QTransform currentPinchTransform; +protected: + bool event(QEvent *event); }; -#endif // PINCHWIDGET_H +#endif // IMAGEITEM_H diff --git a/tests/manual/gestures/graphicsview/main.cpp b/tests/manual/gestures/graphicsview/main.cpp new file mode 100644 index 0000000..263a963 --- /dev/null +++ b/tests/manual/gestures/graphicsview/main.cpp @@ -0,0 +1,228 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** 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 Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> + +#include "imageitem.h" +#include "gestures.h" +#include "mousepangesturerecognizer.h" + +class GraphicsView : public QGraphicsView +{ +public: + GraphicsView(QGraphicsScene *scene, QWidget *parent = 0) + : QGraphicsView(scene, parent) + { + } +protected: + bool viewportEvent(QEvent *event) + { + if (event->type() == QEvent::Gesture) { + QGestureEvent *ge = static_cast<QGestureEvent *>(event); + if (QPanGesture *pan = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture))) { + switch (pan->state()) { + case Qt::GestureStarted: qDebug("view: Pan: started"); break; + case Qt::GestureFinished: qDebug("view: Pan: finished"); break; + case Qt::GestureCanceled: qDebug("view: Pan: canceled"); break; + case Qt::GestureUpdated: break; + default: qDebug("view: Pan: <unknown state>"); break; + } + + const QSizeF offset = pan->offset(); + QScrollBar *vbar = verticalScrollBar(); + QScrollBar *hbar = horizontalScrollBar(); + vbar->setValue(vbar->value() - offset.height()); + hbar->setValue(hbar->value() - offset.width()); + ge->accept(pan); + return true; + } + } + return QGraphicsView::viewportEvent(event); + } +}; + +class StandardGestures : public QWidget +{ +public: + StandardGestures(QWidget *parent = 0) + : QWidget(parent) + { + scene = new QGraphicsScene(this); + scene->setSceneRect(-2000, -2000, 4000, 4000); + view = new QGraphicsView(scene, 0); + QVBoxLayout *l = new QVBoxLayout(this); + l->addWidget(view); + } + + QGraphicsScene *scene; + QGraphicsView *view; +}; + +class GlobalViewGestures : public QWidget +{ + Q_OBJECT +public: + GlobalViewGestures(QWidget *parent = 0) + : QWidget(parent) + { + scene = new QGraphicsScene(this); + scene->setSceneRect(-2000, -2000, 4000, 4000); + view = new GraphicsView(scene, 0); + view->viewport()->grabGesture(Qt::PanGesture); + view->viewport()->grabGesture(ThreeFingerSlideGesture::Type); + QVBoxLayout *l = new QVBoxLayout(this); + l->addWidget(view); + } + + QGraphicsScene *scene; + QGraphicsView *view; +}; + +class GraphicsItemGestures : public QWidget +{ + Q_OBJECT +public: + GraphicsItemGestures(QWidget *parent = 0) + : QWidget(parent) + { + scene = new QGraphicsScene(this); + scene->setSceneRect(-2000, -2000, 4000, 4000); + view = new QGraphicsView(scene, 0); + QVBoxLayout *l = new QVBoxLayout(this); + l->addWidget(view); + } + + QGraphicsScene *scene; + QGraphicsView *view; +}; + +class MainWindow : public QMainWindow +{ +public: + MainWindow(); + + void setDirectory(const QString &path); + +private: + QTabWidget *tabWidget; + StandardGestures *standardGestures; + GlobalViewGestures *globalViewGestures; + GraphicsItemGestures *graphicsItemGestures; +}; + +MainWindow::MainWindow() +{ + (void)qApp->registerGestureRecognizer(new MousePanGestureRecognizer); + ThreeFingerSlideGesture::Type = qApp->registerGestureRecognizer(new ThreeFingerSlideGestureRecognizer); + + tabWidget = new QTabWidget; + + standardGestures = new StandardGestures; + tabWidget->addTab(standardGestures, "Standard gestures"); + + globalViewGestures = new GlobalViewGestures; + tabWidget->addTab(globalViewGestures , "Global gestures"); + + graphicsItemGestures = new GraphicsItemGestures; + tabWidget->addTab(graphicsItemGestures, "Graphics item gestures"); + + setCentralWidget(tabWidget); +} + +void MainWindow::setDirectory(const QString &path) +{ + QDir dir(path); + QStringList files = dir.entryList(QDir::Files | QDir::Readable | QDir::NoDotAndDotDot); + foreach(const QString &file, files) { + QImageReader img(path + QLatin1String("/")+file); + QImage image = img.read(); + if (!image.isNull()) { + { + ImageItem *item = new ImageItem(image); + item->setPos(0, 0); + item->setFlags(QGraphicsItem::ItemIsMovable); + standardGestures->scene->addItem(item); + } + { + ImageItem *item = new ImageItem(image); + item->setPos(0, 0); + item->setFlags(QGraphicsItem::ItemIsMovable); + globalViewGestures->scene->addItem(item); + } + { + GestureImageItem *item = new GestureImageItem(image); + item->setPos(0, 0); + item->setFlags(QGraphicsItem::ItemIsMovable); + graphicsItemGestures->scene->addItem(item); + } + } + } + + { + QList<QGraphicsItem*> items = standardGestures->scene->items(); + if (!items.isEmpty()) + standardGestures->view->ensureVisible(items.at(0)); + } + { + QList<QGraphicsItem*> items = globalViewGestures->scene->items(); + if (!items.isEmpty()) + globalViewGestures->view->ensureVisible(items.at(0)); + } + { + QList<QGraphicsItem*> items = graphicsItemGestures->scene->items(); + if (!items.isEmpty()) + graphicsItemGestures->view->ensureVisible(items.at(0)); + } +} + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + MainWindow window; + if (QApplication::arguments().size() > 1) + window.setDirectory(QApplication::arguments().at(1)); + else + window.setDirectory(QFileDialog::getExistingDirectory(0, "Select image folder")); + window.show(); + return app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/gestures/graphicsview/mousepangesturerecognizer.cpp b/tests/manual/gestures/graphicsview/mousepangesturerecognizer.cpp new file mode 100644 index 0000000..0e7f538 --- /dev/null +++ b/tests/manual/gestures/graphicsview/mousepangesturerecognizer.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** 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 Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mousepangesturerecognizer.h" + +#include <QEvent> +#include <QMouseEvent> +#include <QGesture> + +MousePanGestureRecognizer::MousePanGestureRecognizer() +{ +} + +QGesture* MousePanGestureRecognizer::createGesture(QObject *) +{ + return new QPanGesture; +} + +QGestureRecognizer::Result MousePanGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event) +{ + QPanGesture *g = static_cast<QPanGesture *>(state); + QMouseEvent *me = static_cast<QMouseEvent *>(event); + if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick + || event->type() == QEvent::GraphicsSceneMousePress || event->type() == QEvent::GraphicsSceneMouseDoubleClick) { + g->setHotSpot(me->globalPos()); + g->setProperty("lastPos", me->globalPos()); + g->setProperty("pressed", QVariant::fromValue<bool>(true)); + return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint; + } else if (event->type() == QEvent::MouseMove || event->type() == QEvent::GraphicsSceneMouseMove) { + if (g->property("pressed").toBool()) { + QPoint pos = me->globalPos(); + QPoint lastPos = g->property("lastPos").toPoint(); + g->setLastOffset(g->offset()); + lastPos = pos - lastPos; + g->setOffset(QSizeF(lastPos.x(), lastPos.y())); + g->setTotalOffset(g->totalOffset() + QSizeF(lastPos.x(), lastPos.y())); + g->setProperty("lastPos", pos); + return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint; + } + return QGestureRecognizer::NotGesture; + } else if (event->type() == QEvent::MouseButtonRelease || event->type() == QEvent::GraphicsSceneMouseRelease) { + return QGestureRecognizer::GestureFinished | QGestureRecognizer::ConsumeEventHint; + } + return QGestureRecognizer::Ignore; +} + +void MousePanGestureRecognizer::reset(QGesture *state) +{ + QPanGesture *g = static_cast<QPanGesture *>(state); + g->setTotalOffset(QSizeF()); + g->setLastOffset(QSizeF()); + g->setOffset(QSizeF()); + g->setAcceleration(0); + g->setProperty("lastPos", QVariant()); + g->setProperty("pressed", QVariant::fromValue<bool>(false)); + QGestureRecognizer::reset(state); +} diff --git a/tests/manual/gestures/graphicsview/mousepangesturerecognizer.h b/tests/manual/gestures/graphicsview/mousepangesturerecognizer.h new file mode 100644 index 0000000..b062fd0 --- /dev/null +++ b/tests/manual/gestures/graphicsview/mousepangesturerecognizer.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** 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 Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MOUSEPANGESTURERECOGNIZER_H +#define MOUSEPANGESTURERECOGNIZER_H + +#include <QGestureRecognizer> + +class MousePanGestureRecognizer : public QGestureRecognizer +{ +public: + MousePanGestureRecognizer(); + + QGesture* createGesture(QObject *target); + QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event); + void reset(QGesture *state); +}; + +#endif // MOUSEPANGESTURERECOGNIZER_H diff --git a/tests/manual/gestures/pinch/pinch.pro b/tests/manual/gestures/pinch/pinch.pro deleted file mode 100644 index d1f28cc..0000000 --- a/tests/manual/gestures/pinch/pinch.pro +++ /dev/null @@ -1,4 +0,0 @@ -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 deleted file mode 100644 index 0be9ba1..0000000 --- a/tests/manual/gestures/pinch/pinch.qrc +++ /dev/null @@ -1,5 +0,0 @@ -<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 deleted file mode 100644 index e93c8b5..0000000 --- a/tests/manual/gestures/pinch/pinchwidget.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** 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 Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "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/qt-logo.png b/tests/manual/gestures/pinch/qt-logo.png Binary files differdeleted file mode 100644 index 7d3e97e..0000000 --- a/tests/manual/gestures/pinch/qt-logo.png +++ /dev/null diff --git a/tests/manual/gestures/scrollarea/main.cpp b/tests/manual/gestures/scrollarea/main.cpp new file mode 100644 index 0000000..2796637 --- /dev/null +++ b/tests/manual/gestures/scrollarea/main.cpp @@ -0,0 +1,229 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** 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 Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtGui> + +#include "mousepangesturerecognizer.h" + +class ScrollArea : public QScrollArea +{ + Q_OBJECT +public: + ScrollArea(QWidget *parent = 0) + : QScrollArea(parent), outside(false) + { + viewport()->grabGesture(Qt::PanGesture); + } + +protected: + bool viewportEvent(QEvent *event) + { + if (event->type() == QEvent::Gesture) { + gestureEvent(static_cast<QGestureEvent *>(event)); + return true; + } else if (event->type() == QEvent::GestureOverride) { + QGestureEvent *ge = static_cast<QGestureEvent *>(event); + if (QPanGesture *pan = static_cast<QPanGesture *>(ge->gesture(Qt::PanGesture))) + if (pan->state() == Qt::GestureStarted) { + outside = false; + } + } + return QScrollArea::viewportEvent(event); + } + void gestureEvent(QGestureEvent *event) + { + QPanGesture *pan = static_cast<QPanGesture *>(event->gesture(Qt::PanGesture)); + if (pan) { + switch(pan->state()) { + case Qt::GestureStarted: qDebug("area: Pan: started"); break; + case Qt::GestureFinished: qDebug("area: Pan: finished"); break; + case Qt::GestureCanceled: qDebug("area: Pan: canceled"); break; + case Qt::GestureUpdated: break; + default: qDebug("area: Pan: <unknown state>"); break; + } + + if (pan->state() == Qt::GestureStarted) + outside = false; + event->ignore(); + event->ignore(pan); + if (outside) + return; + + const QSizeF offset = pan->offset(); + const QSizeF totalOffset = pan->totalOffset(); + QScrollBar *vbar = verticalScrollBar(); + QScrollBar *hbar = horizontalScrollBar(); + + if ((vbar->value() == vbar->minimum() && totalOffset.height() > 10) || + (vbar->value() == vbar->maximum() && totalOffset.height() < -10)) { + outside = true; + return; + } + if ((hbar->value() == hbar->minimum() && totalOffset.width() > 10) || + (hbar->value() == hbar->maximum() && totalOffset.width() < -10)) { + outside = true; + return; + } + vbar->setValue(vbar->value() - offset.height()); + hbar->setValue(hbar->value() - offset.width()); + event->accept(pan); + } + } + +private: + bool outside; +}; + +class Slider : public QSlider +{ +public: + Slider(Qt::Orientation orientation, QWidget *parent = 0) + : QSlider(orientation, parent) + { + grabGesture(Qt::PanGesture); + } +protected: + bool event(QEvent *event) + { + if (event->type() == QEvent::Gesture) { + gestureEvent(static_cast<QGestureEvent *>(event)); + return true; + } + return QSlider::event(event); + } + void gestureEvent(QGestureEvent *event) + { + QPanGesture *pan = static_cast<QPanGesture *>(event->gesture(Qt::PanGesture)); + if (pan) { + switch (pan->state()) { + case Qt::GestureStarted: qDebug("slider: Pan: started"); break; + case Qt::GestureFinished: qDebug("slider: Pan: finished"); break; + case Qt::GestureCanceled: qDebug("slider: Pan: canceled"); break; + case Qt::GestureUpdated: break; + default: qDebug("slider: Pan: <unknown state>"); break; + } + + if (pan->state() == Qt::GestureStarted) + outside = false; + event->ignore(); + event->ignore(pan); + if (outside) + return; + const QSizeF offset = pan->offset(); + const QSizeF totalOffset = pan->totalOffset(); + if (orientation() == Qt::Horizontal) { + if ((value() == minimum() && totalOffset.width() < -10) || + (value() == maximum() && totalOffset.width() > 10)) { + outside = true; + return; + } + if (totalOffset.height() < 40 && totalOffset.height() > -40) { + setValue(value() + offset.width()); + event->accept(pan); + } else { + outside = true; + } + } else if (orientation() == Qt::Vertical) { + if ((value() == maximum() && totalOffset.height() < -10) || + (value() == minimum() && totalOffset.height() > 10)) { + outside = true; + return; + } + if (totalOffset.width() < 40 && totalOffset.width() > -40) { + setValue(value() - offset.height()); + event->accept(pan); + } else { + outside = true; + } + } + } + } +private: + bool outside; +}; + +class MainWindow : public QMainWindow +{ +public: + MainWindow() + { + rootScrollArea = new ScrollArea; + setCentralWidget(rootScrollArea); + + QWidget *root = new QWidget; + root->setFixedSize(3000, 3000); + rootScrollArea->setWidget(root); + + Slider *verticalSlider = new Slider(Qt::Vertical, root); + verticalSlider ->move(650, 1100); + Slider *horizontalSlider = new Slider(Qt::Horizontal, root); + horizontalSlider ->move(600, 1000); + + childScrollArea = new ScrollArea(root); + childScrollArea->move(500, 500); + QWidget *w = new QWidget; + w->setMinimumWidth(400); + QVBoxLayout *l = new QVBoxLayout(w); + l->setMargin(20); + for (int i = 0; i < 100; ++i) { + QWidget *w = new QWidget; + QHBoxLayout *ll = new QHBoxLayout(w); + ll->addWidget(new QLabel(QString("Label %1").arg(i))); + ll->addWidget(new QPushButton(QString("Button %1").arg(i))); + l->addWidget(w); + } + childScrollArea->setWidget(w); + } +private: + ScrollArea *rootScrollArea; + ScrollArea *childScrollArea; +}; + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + app.registerGestureRecognizer(new MousePanGestureRecognizer); + MainWindow w; + w.show(); + return app.exec(); +} + +#include "main.moc" diff --git a/tests/manual/gestures/scrollarea/mousepangesturerecognizer.cpp b/tests/manual/gestures/scrollarea/mousepangesturerecognizer.cpp new file mode 100644 index 0000000..79b633e --- /dev/null +++ b/tests/manual/gestures/scrollarea/mousepangesturerecognizer.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** 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 Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mousepangesturerecognizer.h" + +#include <QEvent> +#include <QMouseEvent> +#include <QGesture> + +MousePanGestureRecognizer::MousePanGestureRecognizer() +{ +} + +QGesture* MousePanGestureRecognizer::createGesture(QObject *) const +{ + return new QPanGesture; +} + +QGestureRecognizer::Result MousePanGestureRecognizer::filterEvent(QGesture *state, QObject *, QEvent *event) +{ + QPanGesture *g = static_cast<QPanGesture *>(state); + QMouseEvent *me = static_cast<QMouseEvent *>(event); + if (event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonDblClick) { + g->setHotSpot(me->globalPos()); + g->setProperty("lastPos", me->globalPos()); + g->setProperty("pressed", QVariant::fromValue<bool>(true)); + return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint; + } else if (event->type() == QEvent::MouseMove) { + if (g->property("pressed").toBool()) { + QPoint pos = me->globalPos(); + QPoint lastPos = g->property("lastPos").toPoint(); + g->setLastOffset(g->offset()); + lastPos = pos - lastPos; + g->setOffset(QSizeF(lastPos.x(), lastPos.y())); + g->setTotalOffset(g->totalOffset() + QSizeF(lastPos.x(), lastPos.y())); + g->setProperty("lastPos", pos); + return QGestureRecognizer::GestureTriggered | QGestureRecognizer::ConsumeEventHint; + } + return QGestureRecognizer::NotGesture; + } else if (event->type() == QEvent::MouseButtonRelease) { + return QGestureRecognizer::GestureFinished | QGestureRecognizer::ConsumeEventHint; + } + return QGestureRecognizer::Ignore; +} + +void MousePanGestureRecognizer::reset(QGesture *state) +{ + QPanGesture *g = static_cast<QPanGesture *>(state); + g->setTotalOffset(QSizeF()); + g->setLastOffset(QSizeF()); + g->setOffset(QSizeF()); + g->setAcceleration(0); + g->setProperty("lastPos", QVariant()); + g->setProperty("pressed", QVariant::fromValue<bool>(false)); + QGestureRecognizer::reset(state); +} diff --git a/tests/manual/gestures/scrollarea/mousepangesturerecognizer.h b/tests/manual/gestures/scrollarea/mousepangesturerecognizer.h new file mode 100644 index 0000000..c92d477 --- /dev/null +++ b/tests/manual/gestures/scrollarea/mousepangesturerecognizer.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** 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 Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MOUSEPANGESTURERECOGNIZER_H +#define MOUSEPANGESTURERECOGNIZER_H + +#include <QGestureRecognizer> + +class MousePanGestureRecognizer : public QGestureRecognizer +{ +public: + MousePanGestureRecognizer(); + + QGesture* createGesture(QObject *target) const; + QGestureRecognizer::Result filterEvent(QGesture *state, QObject *watched, QEvent *event); + void reset(QGesture *state); +}; + +#endif // MOUSEPANGESTURERECOGNIZER_H diff --git a/tests/manual/gestures/scrollarea/scrollarea.pro b/tests/manual/gestures/scrollarea/scrollarea.pro new file mode 100644 index 0000000..554810e --- /dev/null +++ b/tests/manual/gestures/scrollarea/scrollarea.pro @@ -0,0 +1,3 @@ +SOURCES = main.cpp \ + mousepangesturerecognizer.cpp +HEADERS += mousepangesturerecognizer.h diff --git a/tests/manual/gestures/twopanwidgets/main.cpp b/tests/manual/gestures/twopanwidgets/main.cpp deleted file mode 100644 index 20a35fc..0000000 --- a/tests/manual/gestures/twopanwidgets/main.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** 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 Technology Preview License Agreement accompanying -** this package. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** -** -** -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <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 deleted file mode 100644 index 5254077..0000000 --- a/tests/manual/gestures/twopanwidgets/twopanwidgets.pro +++ /dev/null @@ -1 +0,0 @@ -SOURCES = main.cpp
\ No newline at end of file diff --git a/util/qlalr/cppgenerator.cpp b/util/qlalr/cppgenerator.cpp index dd5be57..39d94cd 100644 --- a/util/qlalr/cppgenerator.cpp +++ b/util/qlalr/cppgenerator.cpp @@ -46,7 +46,7 @@ #include "lalr.h" #include "recognizer.h" -QString CppGenerator::trollCopyrightHeader() const +QString CppGenerator::copyrightHeader() const { return QLatin1String( "/****************************************************************************\n" @@ -92,7 +92,7 @@ QString CppGenerator::trollCopyrightHeader() const "\n"); } -QString CppGenerator::trollPrivateCopyrightHeader() const +QString CppGenerator::privateCopyrightHeader() const { return QLatin1String( "//\n" @@ -343,10 +343,10 @@ void CppGenerator::operator () () QTextStream out (&f); out << "// This file was generated by qlalr - DO NOT EDIT!\n"; - if (troll_copyright) + if (copyright) { - out << trollCopyrightHeader() - << trollPrivateCopyrightHeader() + out << copyrightHeader() + << privateCopyrightHeader() << endl; } @@ -375,10 +375,10 @@ void CppGenerator::operator () () QString prot = declFileName.toUpper ().replace (QLatin1Char ('.'), QLatin1Char ('_')); - if (troll_copyright) + if (copyright) { - out << trollCopyrightHeader() - << trollPrivateCopyrightHeader() + out << copyrightHeader() + << privateCopyrightHeader() << endl; } @@ -397,8 +397,8 @@ void CppGenerator::operator () () QTextStream out (&f); out << "// This file was generated by qlalr - DO NOT EDIT!\n"; - if (troll_copyright) - out << trollCopyrightHeader(); + if (copyright) + out << copyrightHeader(); out << "#include \"" << declFileName << "\"" << endl << endl; generateImpl(out); diff --git a/util/qlalr/examples/glsl/glsl-lex.l b/util/qlalr/examples/glsl/glsl-lex.l index 2a4826d..b50a2e2 100644 --- a/util/qlalr/examples/glsl/glsl-lex.l +++ b/util/qlalr/examples/glsl/glsl-lex.l @@ -150,6 +150,9 @@ icst ({dec}|0{oct}*|0[xX]{hex}+) "while" { return WHILE; } "^=" { return XOR_ASSIGN; } "^" { return XOR_OP; } +"highp" { return HIGH_PRECISION; } +"mediump" { return MEDIUM_PRECISION; } +"lowp" { return LOW_PRECISION; } #[ \t]+[0-9]+.* { char *eptr = 0; diff --git a/util/qlalr/examples/glsl/glsl.g b/util/qlalr/examples/glsl/glsl.g index 44c24d8..3e825bc 100644 --- a/util/qlalr/examples/glsl/glsl.g +++ b/util/qlalr/examples/glsl/glsl.g @@ -132,6 +132,9 @@ %token XOR_ASSIGN %token XOR_OP %token ERROR +%token HIGH_PRECISION +%token MEDIUM_PRECISION +%token LOW_PRECISION %start translation_unit @@ -487,30 +490,37 @@ type_qualifier ::= ATTRIBUTE ; -- Vertex only. type_qualifier ::= VARYING ; type_qualifier ::= UNIFORM ; -type_specifier ::= VOID ; -type_specifier ::= FLOAT ; -type_specifier ::= INT ; -type_specifier ::= BOOL ; -type_specifier ::= VEC2 ; -type_specifier ::= VEC3 ; -type_specifier ::= VEC4 ; -type_specifier ::= BVEC2 ; -type_specifier ::= BVEC3 ; -type_specifier ::= BVEC4 ; -type_specifier ::= IVEC2 ; -type_specifier ::= IVEC3 ; -type_specifier ::= IVEC4 ; -type_specifier ::= MAT2 ; -type_specifier ::= MAT3 ; -type_specifier ::= MAT4 ; -type_specifier ::= SAMPLER1D ; -type_specifier ::= SAMPLER2D ; -type_specifier ::= SAMPLER3D ; -type_specifier ::= SAMPLERCUBE ; -type_specifier ::= SAMPLER1DSHADOW ; -type_specifier ::= SAMPLER2DSHADOW ; -type_specifier ::= struct_specifier ; -type_specifier ::= TYPE_NAME ; +type_specifier ::= type_specifier_no_prec ; +type_specifier ::= precision_qualifier type_specifier_no_prec ; + +type_specifier_no_prec ::= VOID ; +type_specifier_no_prec ::= FLOAT ; +type_specifier_no_prec ::= INT ; +type_specifier_no_prec ::= BOOL ; +type_specifier_no_prec ::= VEC2 ; +type_specifier_no_prec ::= VEC3 ; +type_specifier_no_prec ::= VEC4 ; +type_specifier_no_prec ::= BVEC2 ; +type_specifier_no_prec ::= BVEC3 ; +type_specifier_no_prec ::= BVEC4 ; +type_specifier_no_prec ::= IVEC2 ; +type_specifier_no_prec ::= IVEC3 ; +type_specifier_no_prec ::= IVEC4 ; +type_specifier_no_prec ::= MAT2 ; +type_specifier_no_prec ::= MAT3 ; +type_specifier_no_prec ::= MAT4 ; +type_specifier_no_prec ::= SAMPLER1D ; +type_specifier_no_prec ::= SAMPLER2D ; +type_specifier_no_prec ::= SAMPLER3D ; +type_specifier_no_prec ::= SAMPLERCUBE ; +type_specifier_no_prec ::= SAMPLER1DSHADOW ; +type_specifier_no_prec ::= SAMPLER2DSHADOW ; +type_specifier_no_prec ::= struct_specifier ; +type_specifier_no_prec ::= TYPE_NAME ; + +precision_qualifier ::= HIGH_PRECISION ; +precision_qualifier ::= MEDIUM_PRECISION ; +precision_qualifier ::= LOW_PRECISION ; struct_specifier ::= STRUCT IDENTIFIER LEFT_BRACE struct_declaration_list RIGHT_BRACE ; /. diff --git a/util/qlalr/main.cpp b/util/qlalr/main.cpp index 216dd3a..7041e4a 100644 --- a/util/qlalr/main.cpp +++ b/util/qlalr/main.cpp @@ -142,7 +142,7 @@ int main (int argc, char *argv[]) CppGenerator gen (p, grammar, aut, generate_report); gen.setDebugInfo (debug_info); - gen.setTrollCopyright (troll_copyright); + gen.setCopyright (troll_copyright); gen (); if (generate_dot) |