diff options
665 files changed, 19685 insertions, 11977 deletions
diff --git a/bin/createpackage.pl b/bin/createpackage.pl index b7457e1..aae20ae 100755 --- a/bin/createpackage.pl +++ b/bin/createpackage.pl @@ -238,11 +238,7 @@ if ($templatepkg =~ m/_installer\.pkg$/i && $onlyUnsigned) { my $unsigned_sis_name = $sisoutputbasename."_unsigned.sis"; my $stub_sis_name = $sisoutputbasename.".sis"; -# Store some utility variables -my $scriptpath = dirname(__FILE__); my $certtext = $certificate; -# certificates are one step up in hierarchy -my $certpath = File::Spec->catdir($scriptpath, File::Spec->updir(), "src/s60installs/"); # Check some pre-conditions and print error messages if needed. unless (length($templatepkg)) { @@ -265,6 +261,16 @@ if (length($certificate)) { } } else { #If no certificate is given, check default options + my $scriptpath = dirname(__FILE__); + my $certpath = File::Spec->catdir($scriptpath, File::Spec->updir(), "src/s60installs"); + + unless (-e $certpath) { + my $qmakeCmd = File::Spec->catfile($scriptpath, "qmake"); + $certpath = `$qmakeCmd -query QT_INSTALL_PREFIX`; + $certpath =~ s/\s+$//; + $certpath = File::Spec->catdir($certpath, "src/s60installs"); + } + $certtext = "RnD"; $certificate = File::Spec->catfile($certpath, "rd.cer"); $key = File::Spec->catfile($certpath, "rd-key.pem"); diff --git a/config.profiles/symbian/bld.inf b/config.profiles/symbian/bld.inf index ddb5157..6ccb11c 100644 --- a/config.profiles/symbian/bld.inf +++ b/config.profiles/symbian/bld.inf @@ -38,10 +38,12 @@ loc.prf /epoc32/tools/qt/mkspecs/features/loc.prf //For UDA image confml/qt.confml CONFML_EXPORT_PATH(qt.confml,uda_content) implml/qt_copy.implml CRML_EXPORT_PATH(qt_copy.implml,uda_content) -content/apps/qt.sisx CRML_EXPORT_PATH(../content/sis/,uda_content) -content/apps/qt_stub.sis /epoc32/data/z/system/install/qt_stub.sis +qt.sisx CRML_EXPORT_PATH(../content/sis/,uda_content) #endif +/* export stub sis to enable eclipsing */ +qt_stub.sis /epoc32/data/z/system/install/qt_stub.sis + //tools ../../bin/createpackage.bat /epoc32/tools/createpackage.bat ../../bin/createpackage.pl /epoc32/tools/createpackage.pl diff --git a/config.profiles/symbian/qt.sisx b/config.profiles/symbian/qt.sisx new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/config.profiles/symbian/qt.sisx @@ -0,0 +1 @@ +1
\ No newline at end of file diff --git a/config.profiles/symbian/qt_stub.pkg b/config.profiles/symbian/qt_stub.pkg index dadf696..0ac4439 100644 --- a/config.profiles/symbian/qt_stub.pkg +++ b/config.profiles/symbian/qt_stub.pkg @@ -15,56 +15,3 @@ ; Unique Vendor name :"Nokia, Qt" -; Dependencies of Qt libraries - -"" - "z:\sys\bin\QtCore.dll" -"" - "z:\sys\bin\QtXml.dll" -"" - "z:\sys\bin\QtGui.dll" -"" - "z:\sys\bin\QtNetwork.dll" -"" - "z:\sys\bin\QtTest.dll" -"" - "z:\sys\bin\QtSql.dll" -"" - "z:\sys\bin\QtSvg.dll" -"" - "z:\sys\bin\phonon.dll" -"" - "z:\sys\bin\QtScript.dll" -"" - "z:\sys\bin\QtXmlPatterns.dll" -"" - "z:\sys\bin\QtDeclarative.dll" -"" - "z:\sys\bin\QtOpenVG.dll" -"" - "z:\sys\bin\QtOpenGL.dll" -"" - "z:\sys\bin\QtMultimedia.dll" -"" - "z:\private\10202D56\import\packages\2001E61C\backup_registration.xml" -"" - "z:\sys\bin\qjpeg.dll" -"" - "z:\resource\qt\plugins\imageformats\qjpeg.qtplugin" -"" - "z:\sys\bin\qgif.dll" -"" - "z:\resource\qt\plugins\imageformats\qgif.qtplugin" -"" - "z:\sys\bin\qmng.dll" -"" - "z:\resource\qt\plugins\imageformats\qmng.qtplugin" -"" - "z:\sys\bin\qtiff.dll" -"" - "z:\resource\qt\plugins\imageformats\qtiff.qtplugin" -"" - "z:\sys\bin\qico.dll" -"" - "z:\resource\qt\plugins\imageformats\qico.qtplugin" -"" - "z:\sys\bin\qsvg.dll" -"" - "z:\resource\qt\plugins\imageformats\qsvg.qtplugin" -"" - "z:\sys\bin\qcncodecs.dll" -"" - "z:\resource\qt\plugins\codecs\qcncodecs.qtplugin" -"" - "z:\sys\bin\qjpcodecs.dll" -"" - "z:\resource\qt\plugins\codecs\qjpcodecs.qtplugin" -"" - "z:\sys\bin\qtwcodecs.dll" -"" - "z:\resource\qt\plugins\codecs\qtwcodecs.qtplugin" -"" - "z:\sys\bin\qkrcodecs.dll" -"" - "z:\resource\qt\plugins\codecs\qkrcodecs.qtplugin" -"" - "z:\sys\bin\qvggraphicssystem.dll" -"" - "z:\resource\qt\plugins\graphicssystems\qvggraphicssystem.qtplugin" -"" - "z:\sys\bin\qglgraphicssystem.dll" -"" - "z:\resource\qt\plugins\graphicssystems\qglgraphicssystem.qtplugin" -"" - "z:\sys\bin\qsvgicon.dll" -"" - "z:\resource\qt\plugins\iconengines\qsvgicon.qtplugin" -"" - "z:\sys\bin\qmlfolderlistmodelplugin.dll" -"" - "z:\resource\qt\imports\Qt\labs\folderlistmodel\qmlfolderlistmodelplugin.qtplugin" -"" - "z:\resource\qt\imports\Qt\labs\folderlistmodel\qmldir" -"" - "z:\sys\bin\qmlgesturesplugin.dll" -"" - "z:\resource\qt\imports\Qt\labs\gestures\qmlgesturesplugin.qtplugin" -"" - "z:\resource\qt\imports\Qt\labs\gestures\qmldir" -"" - "z:\sys\bin\qmlparticlesplugin.dll" -"" - "z:\resource\qt\imports\Qt\labs\particles\qmlparticlesplugin.qtplugin" -"" - "z:\resource\qt\imports\Qt\labs\particles\qmldir" - diff --git a/config.profiles/symbian/qt_stub.sis b/config.profiles/symbian/qt_stub.sis Binary files differnew file mode 100644 index 0000000..30d91a9 --- /dev/null +++ b/config.profiles/symbian/qt_stub.sis @@ -804,6 +804,7 @@ CFG_MAC_XARCH=auto CFG_MAC_CARBON=no CFG_MAC_COCOA=yes COMMANDLINE_MAC_CARBON=no +CFG_MAC_HARFBUZZ=no CFG_SXE=no CFG_PREFIX_INSTALL=yes CFG_SDK= @@ -1041,7 +1042,7 @@ while [ "$#" -gt 0 ]; do VAL=no ;; #Qt style yes options - -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles|-icu) + -incremental|-qvfb|-profile|-shared|-static|-sm|-xinerama|-xshape|-xsync|-xinput|-egl|-reduce-exports|-pch|-separate-debug-info|-stl|-freetype|-xcursor|-xfixes|-xrandr|-xrender|-mitshm|-fontconfig|-xkb|-nis|-qdbus|-dbus|-dbus-linked|-glib|-gstreamer|-gtkstyle|-cups|-iconv|-largefile|-h|-help|-v|-verbose|-debug|-release|-fast|-accessibility|-confirm-license|-gnumake|-framework|-qt3support|-debug-and-release|-exceptions|-cocoa|-carbon|-universal|-harfbuzz|-prefix-install|-silent|-armfpa|-optimized-qmake|-dwarf2|-reduce-relocations|-sse|-openssl|-openssl-linked|-ptmalloc|-xmlpatterns|-phonon|-phonon-backend|-multimedia|-audio-backend|-svg|-declarative|-declarative-debug|-javascript-jit|-script|-scripttools|-rpath|-force-pkg-config|-s60|-usedeffiles|-icu) VAR=`echo $1 | sed "s,^-\(.*\),\1,"` VAL=yes ;; @@ -1499,6 +1500,13 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; + harfbuzz) + if [ "$PLATFORM_MAC" = "yes" ] && [ "$CFG_MAC_CARBON" != "yes" ] && [ "$VAL" = "yes" ]; then + CFG_MAC_HARFBUZZ="$VAL" + else + UNKNOWN_OPT=yes + fi + ;; framework) if [ "$PLATFORM_MAC" = "yes" ] || [ "$PLATFORM_QPA" = "yes" ]; then @@ -4258,6 +4266,11 @@ Qt/Mac only: -sdk <sdk> ......... Build Qt using Apple provided SDK <sdk>. This option requires gcc 4. To use a different SDK with gcc 3.3, set the SDKROOT environment variable. + -harfbuzz .......... Use HarfBuzz to do text layout instead of Core Text when possible. + It is only available to Cocoa builds. + * -no-harfbuzz ....... Disable HarfBuzz on Mac. It can still be enabled by setting + QT_ENABLE_HARFBUZZ environment variable. + EOF fi @@ -5746,7 +5759,7 @@ if [ "$PLATFORM_X11" = "yes" -o "$PLATFORM_QWS" = "yes" -o "$PLATFORM_QPA" = "ye fi # X11/QWS/Lighthouse # X11 -if [ "$PLATFORM_X11" = "yes" ]; then +if [ "$PLATFORM_X11" = "yes" -a "$CFG_GUI" != "no" ]; then x11tests="$relpath/config.tests/x11" X11TESTS_FLAGS= @@ -7251,6 +7264,7 @@ fi [ "$CFG_NAS" = "system" ] && QT_CONFIG="$QT_CONFIG nas" [ "$CFG_OPENSSL" = "yes" ] && QT_CONFIG="$QT_CONFIG openssl" [ "$CFG_OPENSSL" = "linked" ] && QT_CONFIG="$QT_CONFIG openssl-linked" +[ "$CFG_MAC_HARFBUZZ" = "yes" ] && QT_CONFIG="$QT_CONFIG harfbuzz" if [ "$PLATFORM_X11" = "yes" ]; then [ "$CFG_SM" = "yes" ] && QT_CONFIG="$QT_CONFIG x11sm" @@ -7505,10 +7519,8 @@ EOF canBuildQtConcurrent="no" ;; symbian-gcce) - canBuildQtConcurrent="no" ;; symbian-armcc) - canBuildQtConcurrent="no" ;; esac @@ -8221,7 +8233,7 @@ if [ "$XPLATFORM_SYMBIAN" = "yes" ]; then # We cannot use Linux's default export rules since they export everything. QCONFIG_FLAGS="$QCONFIG_FLAGS QT_DLL" # Disable non-working features. - QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_CONCURRENT QT_NO_QFUTURE QT_NO_CRASHHANDLER QT_NO_PRINTER QT_NO_SYSTEMTRAYICON" + QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_CRASHHANDLER QT_NO_PRINTER QT_NO_SYSTEMTRAYICON" fi if [ -n "$QCONFIG_FLAGS" ]; then @@ -8390,7 +8402,7 @@ if [ -n "$QT_CFLAGS_FPU" ]; then fi if [ -n "$QMAKE_INCDIR_OPENGL_ES2" ]; then - echo "\n#Qt opengl include path" >> "$QTCONFIG.tmp" + echo "#Qt opengl include path" >> "$QTCONFIG.tmp" echo "QMAKE_INCDIR_OPENGL_ES2 = \"$QMAKE_INCDIR_OPENGL_ES2\"" >> "$QTCONFIG.tmp" fi diff --git a/configure.exe b/configure.exe Binary files differindex a1fceeb..fb6fad2 100755 --- a/configure.exe +++ b/configure.exe diff --git a/demos/declarative/samegame/SamegameCore/samegame.js b/demos/declarative/samegame/SamegameCore/samegame.js index bb587bc..d7b827a 100755 --- a/demos/declarative/samegame/SamegameCore/samegame.js +++ b/demos/declarative/samegame/SamegameCore/samegame.js @@ -8,6 +8,7 @@ var blockSrc = "SamegameCore/BoomBlock.qml"; var scoresURL = ""; var gameDuration; var component = Qt.createComponent(blockSrc); +var highScoreBar = 0; // Index function used instead of a 2D array function index(column, row) @@ -152,11 +153,15 @@ function victoryCheck() // Checks for game over if (deservesBonus || !(floodMoveCheck(0, maxRow - 1, -1))) { gameDuration = new Date() - gameDuration; - nameInputDialog.show("You won! Please enter your name: "); - nameInputDialog.initialWidth = nameInputDialog.text.width + 20; - if (nameInputDialog.name == "") - nameInputDialog.width = nameInputDialog.initialWidth; - nameInputDialog.text.opacity = 0; // Just a spacer + if(gameCanvas.score > highScoreBar){ + nameInputDialog.show("You won! Please enter your name: "); + nameInputDialog.initialWidth = nameInputDialog.text.width + 20; + if (nameInputDialog.name == "") + nameInputDialog.width = nameInputDialog.initialWidth; + nameInputDialog.text.opacity = 0; // Just a spacer + }else{ + dialog.show("You won!"); + } } } @@ -203,6 +208,30 @@ function createBlock(column,row) return true; } +function initHighScoreBar() +{ + if(scoresURL != "") + return true;//don't query remote scores + var db = openDatabaseSync( + "SameGameScores", + "1.0", + "Local SameGame High Scores", + 100 + ); + db.transaction( + function(tx) { + tx.executeSql('CREATE TABLE IF NOT EXISTS Scores(name TEXT, score NUMBER, gridSize TEXT, time NUMBER)'); + // Only show results for the current grid size + var rs = tx.executeSql('SELECT * FROM Scores WHERE gridSize = "' + + maxColumn + "x" + maxRow + '" ORDER BY score desc LIMIT 10'); + if(rs.rows.length < 10) + highScoreBar = 0; + else + highScoreBar = rs.rows.item(rs.rows.length - 1).score; + } + ); +} + function saveHighScore(name) { if (scoresURL != "") @@ -235,6 +264,8 @@ function saveHighScore(name) + rs.rows.item(i).score + ' points in ' + rs.rows.item(i).time + ' seconds.\n'; } + if(rs.rows.length == 10) + highScoreBar = rs.rows.item(9).score; dialog.show(r); } ); diff --git a/dist/changes-4.8.0 b/dist/changes-4.8.0 index fa50f24..b8cc626 100644 --- a/dist/changes-4.8.0 +++ b/dist/changes-4.8.0 @@ -97,9 +97,17 @@ Qt for Windows CE - Assistant - - Designer - + * [QTBUG-18631] Enabled the use of promoted QWidgets in the buddy editor. + * [QTBUG-18120] Fixed saving of the Z-order. + * [QTBUG-13683] Fixed saving of QGridLayout and QFormLayout + by QFormBuilder. + * [QTBUG-10890] Added a filter to the rich text editor dialog. + that simplifies the HTML markup generated. + * [QTBUG-7777] Added support for QIcon::fromTheme. + * [QTBUG-7169] Fixed QtUiTools to be built with the correct + lib-infix. + * [QTBUG-3120] Added support for alignment of box layout items. - Linguist - Linguist GUI diff --git a/doc/doc.pri b/doc/doc.pri index 68d729b..253e1b4 100644 --- a/doc/doc.pri +++ b/doc/doc.pri @@ -13,12 +13,14 @@ win32:!win32-g++* { unixstyle = true } +COPYWEBKITGUIDE = $$QT_SOURCE_TREE/examples/webkit/webkit-guide + $$unixstyle { QDOC = cd $$QT_SOURCE_TREE/tools/qdoc3/test && QT_BUILD_TREE=$$QT_BUILD_TREE QT_SOURCE_TREE=$$QT_SOURCE_TREE $$QT_BUILD_TREE/bin/qdoc3 $$DOCS_GENERATION_DEFINES - COPYWEBKITGUIDE = $$QT_SOURCE_TREE/examples/webkit/webkit-guide } else { QDOC = cd $$QT_SOURCE_TREE/tools/qdoc3/test && set QT_BUILD_TREE=$$QT_BUILD_TREE&& set QT_SOURCE_TREE=$$QT_SOURCE_TREE&& $$QT_BUILD_TREE/bin/qdoc3.exe $$DOCS_GENERATION_DEFINES QDOC = $$replace(QDOC, "/", "\\") + COPYWEBKITGUIDE = $$replace(COPYWEBKITGUIDE, "/", "\\") } ADP_DOCS_QDOCCONF_FILE = qt-build-docs-online.qdocconf QT_DOCUMENTATION = ($$QDOC qt-api-only.qdocconf assistant.qdocconf designer.qdocconf \ diff --git a/doc/src/declarative/modules.qdoc b/doc/src/declarative/modules.qdoc index dbc8806..f2e24f2 100644 --- a/doc/src/declarative/modules.qdoc +++ b/doc/src/declarative/modules.qdoc @@ -310,6 +310,7 @@ It is defined by a plain text file named "qmldir" that contains one or more line <TypeName> [<InitialVersion>] <File> internal <TypeName> <File> plugin <Name> [<Path>] +typeinfo <File> \endcode \bold {# <Comment>} lines are used for comments. They are ignored by the QML engine. @@ -350,6 +351,14 @@ plugin file, or a relative path from the directory containing the \c qmldir file containing the plugin file. By default the engine searches for the plugin library in the directory that contains the \c qmldir file. The plugin search path can be queried with QDeclarativeEngine::pluginPathList() and modified using QDeclarativeEngine::addPluginPath(). When running the \l {QML Viewer}, use the \c -P option to add paths to the plugin search path. +\bold {typeinfo <File>} lines add \l{Writing a qmltypes file}{type description files} to +the module that can be read by QML tools such as Qt Creator to get information about the +types defined by the module's plugins. <File> is the (relative) file name of a .qmltypes +file. + +Without such a file QML tools may be unable to offer features such as code completion +for the types defined in your plugins. + \section1 Debugging @@ -358,5 +367,119 @@ when there are problems with finding and loading modules. See \l{Debugging module imports} for more information. +\section1 Writing a qmltypes file + +QML modules may refer to one or more type information files in their +\l{Writing a qmldir file}{qmldir} file. These usually have the .qmltypes +extension and are read by external tools to gain information about +types defined in plugins. + +As such qmltypes files have no effect on the functionality of a QML module. +Their only use is to allow tools such as Qt Creator to provide code completion, +error checking and other functionality to users of your module. + +Any module that uses plugins should also ship a type description file. + +The best way to create a qmltypes file for your module is to generate it +using the \c qmlplugindump tool that is provided with Qt. + +Example: +If your module is in \c /tmp/imports/My/Module, you could run +\code +qmlplugindump My.Module 1.0 /tmp/imports > /tmp/imports/My/Module/mymodule.qmltypes +\endcode +to generate type information for your module. Afterwards, add the line +\code +typeinfo mymodule.qmltypes +\endcode +to \c /tmp/imports/My/Module/qmldir to register it. + +While the qmldump tool covers most cases, it does not work if: +\list +\o The plugin uses a \l{QDeclarativeCustomParser}. The component that uses + the custom parser will not get its members documented. +\o The plugin can not be loaded. In particular if you cross-compiled + the plugin for a different architecture, qmldump will not be able to + load it. +\endlist + +In case you have to create a qmltypes file manually or need to adjust +an existing one, this is the file format: + +\qml +import QtQuick.tooling 1.0 + +// There always is a single Module object that contains all +// Component objects. +Module { + // A Component object directly corresponds to a type exported + // in a plugin with a call to qmlRegisterType. + Component { + + // The name is a unique identifier used to refer to this type. + // It is recommended you simply use the C++ type name. + name: "QDeclarativeAbstractAnimation" + + // The name of the prototype Component. + prototype: "QObject" + + // The name of the default property. + defaultProperty: "animations" + + // The name of the type containing attached properties + // and methods. + attachedType: "QDeclarativeAnimationAttached" + + // The list of exports determines how a type can be imported. + // Each string has the format "URI/Name version" and matches the + // arguments to qmlRegisterType. Usually types are only exported + // once, if at all. + // If the "URI/" part of the string is missing that means the + // type should be put into the package defined by the URI the + // module was imported with. + // For example if this module was imported with 'import Foo 4.8' + // the Animation object would be found in the package Foo and + // QtQuick. + exports: [ + "Animation 4.7", + "QtQuick/Animation 1.0" + ] + + Property { + name: "animations"; + type: "QDeclarativeAbstractAnimation" + // defaults to false, whether this property is read only + isReadonly: true + // defaults to false, whether the type of this property was a pointer in C++ + isPointer: true + // defaults to false: whether the type actually is a QDeclarativeListProperty<type> + isList: true + } + Property { name: "loops"; type: "int" } + Property { name: "name"; type: "string" } + Property { name: "loopsEnum"; type: "Loops" } + + Enum { + name: "Loops" + values: { + "Infinite": -2, + "OnceOnly": 1 + } + } + + // Signal and Method work the same way. The inner Parameter + // declarations also support the isReadonly, isPointer and isList + // attributes which mean the same as for Property + Method { name: "restart" } + Signal { name: "started" } + Signal { + name: "runningChanged" + Parameter { type: "bool" } + Parameter { name: "foo"; type: "bool" } + } + } +} +\endqml + */ / diff --git a/doc/src/development/qmake-manual.qdoc b/doc/src/development/qmake-manual.qdoc index 2bc8a34..0149da2 100644 --- a/doc/src/development/qmake-manual.qdoc +++ b/doc/src/development/qmake-manual.qdoc @@ -1120,6 +1120,44 @@ \tableofcontents{3} + + \target BACKUP_REGISTRATION_FILE_MAEMO + \section1 BACKUP_REGISTRATION_FILE_MAEMO + + \e {This is only used on the Maemo platform.} + + This variable is used to specify the backup registration file to use with + \c enable_backup \c CONFIG value for Maemo platform. The default value is: + \c{$$_PRO_FILE_PWD_/backup_registration/maemo/$$basename(TARGET).conf}. + + Unfortunately it is not possible to have a common registration file for Maemo like there is + for Symbian, so the developer must always provide one if the platform default backup support is + not sufficient. + + For documentation about how to create backup registration files and how the device + backup works in general, see: + (\l{http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Generic_Platform_Components/Using_Backup_Application}{Using Backup Application}) + + \target BACKUP_REGISTRATION_FILE_SYMBIAN + \section1 BACKUP_REGISTRATION_FILE_SYMBIAN + + \e {This is only used on the Symbian platform.} + + This variable is used to specify the backup registration file to use with + \c enable_backup \c CONFIG value for Symbian platform. The default value is + determined as follows: + + If a custom registration file \c{$$_PRO_FILE_PWD_/backup_registration/symbian/backup_registration.xml} + exists, it is used. Otherwise, the common registration file \c{$$[QT_INSTALL_DATA]/mkspecs/common/symbian/backup_registration.xml} + is used. This common registration file will define backing up of application binaries, + resources, and all files under application private directory. Also note that \c{C:/Data} + contents are backed up by default on Symbian devices, so no registration is needed for any + files found there. + + For documentation about how to create backup registration files and how the device + backup works in general, see: + (\l{http://library.forum.nokia.com/index.jsp?topic=/S60_5th_Edition_Cpp_Developers_Library/GUID-35228542-8C95-4849-A73F-2B4F082F0C44/sdk/doc_source/guide/Connectivity-subsystem-guide/Connectivity/PC_Connectivity_How-To_Write_Backup_Aware_Software.html}{How-To Write Backup-aware Software}) + \target BLD_INF_RULES \section1 BLD_INF_RULES @@ -1341,6 +1379,17 @@ so some \c{.ts} files may be ignored by qmake. \endtable + These options only have an effect on Symbian and Maemo platforms: + + \table 95% + \header \o Option \o Description + \row \o enable_backup \o Generates deployment for backup registration file + to enable backing up the application during device backup. + See \l{#BACKUP_REGISTRATION_FILE_MAEMO}{BACKUP_REGISTRATION_FILE_MAEMO} + and \l{#BACKUP_REGISTRATION_FILE_SYMBIAN}{BACKUP_REGISTRATION_FILE_SYMBIAN} + for more information about backup. + \endtable + These options have an effect on Linux/Unix platforms: \table 95% diff --git a/doc/src/examples/ftp.qdoc b/doc/src/examples/ftp.qdoc index 4fa2cfd..841d298 100644 --- a/doc/src/examples/ftp.qdoc +++ b/doc/src/examples/ftp.qdoc @@ -131,7 +131,9 @@ \snippet examples/network/qftp/ftpwindow.cpp 5 - QFtp supports canceling the download of files. + QFtp supports canceling the download of files. We make sure that + any file that is currently being written to is closed and removed, + and tidy up by deleting the file object. \snippet examples/network/qftp/ftpwindow.cpp 6 diff --git a/doc/src/examples/wheel.qdoc b/doc/src/examples/wheel.qdoc deleted file mode 100644 index 995ff87..0000000 --- a/doc/src/examples/wheel.qdoc +++ /dev/null @@ -1,109 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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:FDL$ -** 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 Free Documentation License -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of this -** file. -** -** If you have questions regarding the use of this file, please contact -** Nokia at qt-info@nokia.com. -** $QT_END_LICENSE$ -** -****************************************************************************/ - -/*! - \example scroller/wheel - \title Wheel Scroller Example - - The Wheel Scroller Example shows how to use QScroller, QScrollEvent - and QScrollPrepareEvent to implement smooth scrolling for a - custom Widget. - - \section1 Basics - - The QScroller class is the main part of the smooth scrolling - mechanism in Qt. It keeps track of the current scroll position and - speed and updates the object through events. - QScroller will get touch events via the QFlickGesture. - It will query the target object through a QScrollPrepareEvent for - the scroll area and other information. - QScroller will send QScrollEvents to inform the target object about - the current scroll position. - The target object (usually a QWidget or a QGraphicsObject) will - then need to update it's graphical representation to reflect the - new scroll position. - - \section1 The Wheel Widget class - - To demonstrate how to use the QScroller we implement a QWidget that - looks and works like the wheel of a slot machine. - The wheel can be started via touch events and will continue getting - slower. - Additionally the wheel should appear as if no border exists (which - would seem unnatural) and the scrolling should snap to center one - item. - - In the widget we need to grab the QFlickGesture. The gesture itself - will setAcceptTouchEvents for us, so we don't need to do that here. - - \snippet examples/scroller/wheel/wheelwidget.cpp 0 - - The widget will get gesture events but in addition we also will - get the events from QScroller. - We will need to accept the QScrollPrepareEvent to indicate that - a scrolling should really be started from the given position. - - \snippet examples/scroller/wheel/wheelwidget.cpp 1 - - We should call all three set functions form QScrollPrepareEvent. - - \list - \o \c setViewportSize to indicate our viewport size. Actually the - given code could be improved by giving our size minus the borders. - \o \c setMaxContentPos to indicate the maximum values for the scroll - position. The minimum values are implicitely set to 0. - In our example we give a very high number here and hope that the user - is not patient enough to scroll until the very end. - \o \c setContentPos to indicate the current scroll position. - We give a position in the middle of the huge scroll area. - Actually we give this position every time a new scroll is started so - the user will only reach the end if he continuously scrolls in one - direction which is not very likely. - \endlist - - The handling of the QScrollEvent is a lengthly code not fully shown here. - \snippet examples/scroller/wheel/wheelwidget.cpp 2 - - In principle it does three steps. - \list - \o It calculates and updates the current scroll position as given by - QScroller. - \o It repaints the widget so that the new position is shown. - \o It centers the item as soon as the scrolling stopps. - \endlist - - The following code does the centering. - \snippet examples/scroller/wheel/wheelwidget.cpp 3 - - We check if the scrolling is finished which is indicated in the - QScrollEvent by the \c isLast flag. - We then check if the item is not already centered and if not start a new - scroll by calling QScroller::scrollTo. - - As you can see the QScroller can be used for other things besides simple - scroll areas. -*/ diff --git a/doc/src/platforms/platform-notes.qdoc b/doc/src/platforms/platform-notes.qdoc index 24b297f..aa39957 100644 --- a/doc/src/platforms/platform-notes.qdoc +++ b/doc/src/platforms/platform-notes.qdoc @@ -612,7 +612,7 @@ Qt::WA_MacNormalSize, Qt::WA_MacSmallSize, Qt::WA_MacMiniSize, Qt::WA_MacVariableSize, Qt::WA_MacBrushedMetal, Qt::WA_MacAlwaysShowToolWindow, Qt::WA_MacFrameworkScaled, Qt::WA_MacNoShadow, Qt::Sheet, Qt::Drawer, Qt::MacWindowToolBarButtonHint, - QMainWindow::unifiedTitleAndToolBarOnMac + QMainWindow::unifiedTitleAndToolBarOnMac, WA_MacNoCocoaChildWindow \section2 Mixing Qt with native code Two classes are awailable for either adding native Cocoa views/controls diff --git a/doc/src/snippets/qstring/stringbuilder.cpp b/doc/src/snippets/qstring/stringbuilder.cpp index 8ff1dd8..b8acbc1 100644 --- a/doc/src/snippets/qstring/stringbuilder.cpp +++ b/doc/src/snippets/qstring/stringbuilder.cpp @@ -49,14 +49,9 @@ //! [0] //! [3] - #define QT_USE_FAST_CONCATENATION + DEFINES *= QT_USE_QSTRINGBUILDER //! [3] -//! [4] - #define QT_USE_FAST_CONCATENATION - #define QT_USE_FAST_OPERATOR_PLUS -//! [4] - //! [5] #include <QStringBuilder> diff --git a/doc/src/template/scripts/functions.js b/doc/src/template/scripts/functions.js index 62bc535..3ab4a08 100755 --- a/doc/src/template/scripts/functions.js +++ b/doc/src/template/scripts/functions.js @@ -184,7 +184,7 @@ var blankRE=/^\s*$/; function CheckEmptyAndLoadList() { /* Start Extracting information for feedback and adding this to the feedback form */ - var pageUrl = window.location.href; + var pageUrl = window.location.pathname; var pageVal = $('title').html(); $('#pageType').removeClass('red'); $('#feedUrl').remove(); diff --git a/examples/examples.pro b/examples/examples.pro index 968740d..f233aba 100644 --- a/examples/examples.pro +++ b/examples/examples.pro @@ -20,7 +20,6 @@ SUBDIRS = \ mainwindows \ painting \ richtext \ - scroller \ sql \ tools \ tutorials \ diff --git a/examples/network/qftp/ftpwindow.cpp b/examples/network/qftp/ftpwindow.cpp index c3e629f..159cad6 100644 --- a/examples/network/qftp/ftpwindow.cpp +++ b/examples/network/qftp/ftpwindow.cpp @@ -243,6 +243,12 @@ void FtpWindow::downloadFile() void FtpWindow::cancelDownload() { ftp->abort(); + + if (file->exists()) { + file->close(); + file->remove(); + } + delete file; } //![5] diff --git a/examples/scroller/graphicsview/graphicsview.pro b/examples/scroller/graphicsview/graphicsview.pro deleted file mode 100644 index dcebe62..0000000 --- a/examples/scroller/graphicsview/graphicsview.pro +++ /dev/null @@ -1,8 +0,0 @@ -TEMPLATE = app -SOURCES = main.cpp - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/scroller/graphicsview -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS graphicsview.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/scroller/graphicsview -INSTALLS += target sources diff --git a/examples/scroller/graphicsview/main.cpp b/examples/scroller/graphicsview/main.cpp deleted file mode 100644 index 738a824..0000000 --- a/examples/scroller/graphicsview/main.cpp +++ /dev/null @@ -1,295 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor -** the names of its contributors may be used to endorse or promote -** products derived from this software without specific prior written -** permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore> -#include <QtGui> - -#define NUM_ITEMS 100 -#define NUM_LISTS 10 - -/*! - \class RectObject - Note that it needs to be a QGraphicsObject or else the gestures will not work correctly. -*/ -class RectObject : public QGraphicsObject -{ - Q_OBJECT - -public: - - RectObject(const QString &text, qreal x, qreal y, qreal width, qreal height, QBrush brush, QGraphicsItem *parent = 0) - : QGraphicsObject(parent) - , m_text(text) - , m_rect(x, y, width, height) - , m_pen(brush.color().lighter(), 3.0) - , m_brush(brush) - { - setFlag(QGraphicsItem::ItemClipsToShape, true); - } - - QRectF boundingRect() const - { - // here we only want the size of the children and not the size of the children of the children... - qreal halfpw = m_pen.widthF() / 2; - QRectF rect = m_rect; - if (halfpw > 0.0) - rect.adjust(-halfpw, -halfpw, halfpw, halfpw); - - return rect; - } - - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) - { - Q_UNUSED(option); - Q_UNUSED(widget); - painter->setPen(m_pen); - painter->setBrush(m_brush); - painter->drawRect(m_rect); - - painter->setPen(Qt::black); - QFont f; - f.setPixelSize(m_rect.height()); - painter->setFont(f); - painter->drawText(m_rect, Qt::AlignCenter, m_text); - } - - QString m_text; - QRectF m_rect; - QPen m_pen; - QBrush m_brush; -}; - -class ViewObject : public QGraphicsObject -{ - Q_OBJECT -public: - ViewObject(QGraphicsObject *parent) - : QGraphicsObject(parent) - { } - - QRectF boundingRect() const - { - QRectF rect; - foreach (QGraphicsItem *item, childItems()) - rect |= item->boundingRect().translated(item->pos()); - return rect; - } - - void paint(QPainter*, const QStyleOptionGraphicsItem*, QWidget*) - { } -}; - -class ListObject : public QGraphicsObject -{ - Q_OBJECT - -public: - ListObject(const QSizeF &size, bool useTouch) - { - m_size = size; - setFlag(QGraphicsItem::ItemClipsChildrenToShape, true); - // grab gesture via Touch or Mouse events - QScroller::grabGesture(this, useTouch ? QScroller::TouchGesture : QScroller::LeftMouseButtonGesture); - - // this needs to be QGraphicsOBJECT - otherwise gesture recognition - // will not work for the parent of the viewport (in this case the - // list) - m_viewport = new ViewObject(this); - - } - - QGraphicsObject *viewport() const - { - return m_viewport; - } - - bool event(QEvent *e) - { - switch (e->type()) { -// ![2] - case QEvent::ScrollPrepare: { - QScrollPrepareEvent *se = static_cast<QScrollPrepareEvent *>(e); - se->setViewportSize(m_size); - QRectF br = m_viewport->boundingRect(); - se->setContentPosRange(QRectF(0, 0, - qMax(qreal(0), br.width() - m_size.width()), - qMax(qreal(0), br.height() - m_size.height()))); - se->setContentPos(-m_viewport->pos()); - se->accept(); - return true; - } -// ![1] -// ![2] - case QEvent::Scroll: { - QScrollEvent *se = static_cast<QScrollEvent *>(e); - m_viewport->setPos(-se->contentPos() - se->overshootDistance()); - return true; - } -// ![2] - default: - break; - } - return QGraphicsObject::event(e); - } - - bool sceneEvent(QEvent *e) - { - switch (e->type()) { - case QEvent::TouchBegin: { - // We need to return true for the TouchBegin here in the - // top-most graphics object - otherwise gestures in our parent - // objects will NOT work at all (the accept() flag is already - // set due to our setAcceptTouchEvents(true) call in the c'tor - return true; - - } - case QEvent::GraphicsSceneMousePress: { - // We need to return true for the MousePress here in the - // top-most graphics object - otherwise gestures in our parent - // objects will NOT work at all (the accept() flag is already - // set to true by Qt) - return true; - - } - default: - break; - } - return QGraphicsObject::sceneEvent(e); - } - - QRectF boundingRect() const - { - return QRectF(0, 0, m_size.width() + 3, m_size.height()); - } - - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) - { - Q_UNUSED(option); - Q_UNUSED(widget); - painter->setPen(QPen(QColor(100, 100, 100), 3.0)); - painter->drawRect(QRect(1.5, 1.5, m_size.width() - 3, m_size.height() - 3)); - } - - QSizeF m_size; - ViewObject *m_viewport; -}; - -class MainWindow : public QMainWindow -{ - Q_OBJECT - -public: - MainWindow(bool useTouch) - { - m_scene = new QGraphicsScene(); - - // -- make the main list - ListObject *mainList = new ListObject(QSizeF(780, 400), useTouch); - mainList->setObjectName(QLatin1String("MainList")); - m_scene->addItem(mainList); -// ![3] - for (int i=0; i<NUM_LISTS; i++) { - ListObject *childList = new ListObject(QSizeF(mainList->m_size.width()/3, mainList->m_size.height()), useTouch); - childList->setObjectName(QString("ChildList %1").arg(i)); - fillList(childList); - childList->setParentItem(mainList->viewport()); - childList->setPos(i*mainList->m_size.width()/3, 0); - } - mainList->viewport()->setPos(0, 0); - - - /* - list1->setTransformOriginPoint(200, 200); - list1->setRotation(135); - list1->setPos(20 + 200 * .41, 20 + 200 * .41); - */ -// ![3] - - m_view = new QGraphicsView(m_scene); - setCentralWidget(m_view); - setWindowTitle(tr("Gesture example")); - m_scene->setSceneRect(0, 0, m_view->viewport()->width(), m_view->viewport()->height()); - } - - /** - * Fills the list object \a list with RectObjects. - */ - void fillList(ListObject *list) - { - qreal h = list->m_size.height() / 10; - for (int i=0; i<NUM_ITEMS; i++) { - QColor color = QColor(255*i/NUM_ITEMS, 255*(NUM_ITEMS-i)/NUM_ITEMS, 127*(i%2)+64*(i/2%2)); - QString text = QLatin1String("Item #") + QString::number(i); - QGraphicsItem *rect = new RectObject(text, 0, 0, list->m_size.width() - 6, h - 3, QBrush(color), list->viewport()); - rect->setPos(3, h*i+3); - } - list->viewport()->setPos(0, 0); - } - - -protected: - void resizeEvent(QResizeEvent *e) - { - // resize the scene according to our own size to prevent scrolling - m_scene->setSceneRect(0, 0, m_view->viewport()->width(), m_view->viewport()->height()); - QMainWindow::resizeEvent(e); - } - - QGraphicsScene *m_scene; - QGraphicsView *m_view; -}; - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - bool touch = (a.arguments().contains(QLatin1String("--touch"))); - MainWindow mw(touch); -#ifdef Q_WS_S60 - mw.showMaximized(); -#else - mw.show(); -#endif -#ifdef Q_WS_MAC - mw.raise(); -#endif - return a.exec(); -} - -#include "main.moc" diff --git a/examples/scroller/plot/main.cpp b/examples/scroller/plot/main.cpp deleted file mode 100644 index 178a094..0000000 --- a/examples/scroller/plot/main.cpp +++ /dev/null @@ -1,221 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor -** the names of its contributors may be used to endorse or promote -** products derived from this software without specific prior written -** permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QApplication> -#include <QListWidget> -#include <QListWidgetItem> -#include <QSplitter> -#include <QStackedWidget> -#include <QSignalMapper> -#include <QMainWindow> -#include <QMenuBar> -#include <QActionGroup> -#include <QWebView> -#include <QTimer> -#include <QScroller> - -#include <QtDebug> - -#include <QGesture> - -#include "settingswidget.h" -#include "plotwidget.h" - - -class MainWindow : public QMainWindow -{ - Q_OBJECT -public: - MainWindow(bool smallscreen, bool touch) - : QMainWindow(), m_touch(touch) - { - m_list = new QListWidget(); - m_list->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); - m_list_scroller = installKineticScroller(m_list); - - for (int i = 0; i < 1000; ++i) - new QListWidgetItem(QString("This is a test text %1 %2").arg(i).arg(QString("--------").left(i % 8)), m_list); - - connect(m_list, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(listItemActivated(QListWidgetItem*))); - connect(m_list, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(listItemClicked(QListWidgetItem*))); - connect(m_list, SIGNAL(itemPressed(QListWidgetItem*)), this, SLOT(listItemPressed(QListWidgetItem*))); - connect(m_list, SIGNAL(itemSelectionChanged()), this, SLOT(listItemSelectionChanged())); - connect(m_list, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), this, SLOT(listItemCurrentChanged(QListWidgetItem*))); - - m_web = new QWebView(); - m_web_scroller = installKineticScroller(m_web); - - QTimer::singleShot(1000, this, SLOT(loadUrl())); - - m_settings = new SettingsWidget(smallscreen); - installKineticScroller(m_settings); - m_plot = new PlotWidget(smallscreen); - - QStackedWidget *stack = new QStackedWidget(); - stack->addWidget(m_list); - stack->addWidget(m_web); - - QActionGroup *pages = new QActionGroup(this); - pages->setExclusive(true); - QSignalMapper *mapper = new QSignalMapper(this); - connect(mapper, SIGNAL(mapped(int)), stack, SLOT(setCurrentIndex(int))); - - createAction("List", pages, mapper, 0, true); - createAction("Web", pages, mapper, 1); - - if (smallscreen) { - stack->addWidget(m_settings); - stack->addWidget(m_plot); - - createAction("Settings", pages, mapper, 2); - createAction("Plot", pages, mapper, 3); - - setCentralWidget(stack); - } else { - QSplitter *split = new QSplitter(); - m_settings->setMinimumWidth(m_settings->sizeHint().width()); - split->addWidget(stack); - split->addWidget(m_settings); - split->addWidget(m_plot); - setCentralWidget(split); - } - menuBar()->addMenu(QLatin1String("Pages"))->addActions(pages->actions()); - connect(stack, SIGNAL(currentChanged(int)), this, SLOT(pageChanged(int))); - pageChanged(0); - } - -private slots: - void pageChanged(int page) - { - if (page < 0 || page > 1) - return; - switch (page) { - case 0: - m_settings->setScroller(m_list); - m_plot->setScroller(m_list); - break; - case 1: - m_settings->setScroller(m_web); - m_plot->setScroller(m_web); - break; - default: - break; - } - } - - void loadUrl() - { - m_web->load(QUrl("http://www.google.com")); - } - - void listItemActivated(QListWidgetItem *lwi) { qWarning() << "Item ACTIVATED: " << lwi->text(); } - void listItemClicked(QListWidgetItem *lwi) { qWarning() << "Item CLICKED: " << lwi->text(); } - void listItemPressed(QListWidgetItem *lwi) { qWarning() << "Item PRESSED: " << lwi->text(); } - void listItemCurrentChanged(QListWidgetItem *lwi) { qWarning() << "Item CURRENT: " << (lwi ? lwi->text() : QString("(none)")); } - void listItemSelectionChanged() - { - int n = m_list->selectedItems().count(); - qWarning("Item%s SELECTED: %d", n == 1 ? "" : "s", n); - foreach (QListWidgetItem *lwi, m_list->selectedItems()) - qWarning() << " " << lwi->text(); - } - -private: - QAction *createAction(const char *text, QActionGroup *group, QSignalMapper *mapper, int mapping, bool checked = false) - { - QAction *a = new QAction(QLatin1String(text), group); - a->setCheckable(true); - a->setChecked(checked); -#if defined(Q_WS_MAC) - a->setMenuRole(QAction::NoRole); -#endif - mapper->setMapping(a, mapping); - connect(a, SIGNAL(toggled(bool)), mapper, SLOT(map())); - return a; - } - - QScroller *installKineticScroller(QWidget *w) - { - if (QAbstractScrollArea *area = qobject_cast<QAbstractScrollArea *>(w)) { - QScroller::grabGesture(area->viewport(), m_touch ? QScroller::TouchGesture : QScroller::LeftMouseButtonGesture); - return QScroller::scroller(area->viewport()); - } else if (QWebView *web = qobject_cast<QWebView *>(w)) { - QScroller::grabGesture(web, m_touch ? QScroller::TouchGesture : QScroller::LeftMouseButtonGesture); - } - return QScroller::scroller(w); - } - -private: - QListWidget *m_list; - QWebView *m_web; - QScroller *m_list_scroller, *m_web_scroller; - SettingsWidget *m_settings; - PlotWidget *m_plot; - bool m_touch; -}; - -int main(int argc, char **argv) -{ - QApplication a(argc, argv); - -#if defined(Q_WS_MAEMO_5) || defined(Q_WS_S60) || defined(Q_WS_WINCE) - bool smallscreen = true; -#else - bool smallscreen = false; -#endif - bool touch = false; - - if (a.arguments().contains(QLatin1String("--small"))) - smallscreen = true; - if (a.arguments().contains(QLatin1String("--touch"))) - touch = true; - - MainWindow mw(smallscreen, touch); - if (smallscreen) - mw.showMaximized(); - else - mw.show(); -#if defined(Q_WS_MAC) - mw.raise(); -#endif - return a.exec(); -} - -#include "main.moc" diff --git a/examples/scroller/plot/plot.pro b/examples/scroller/plot/plot.pro deleted file mode 100644 index 04fdf70..0000000 --- a/examples/scroller/plot/plot.pro +++ /dev/null @@ -1,13 +0,0 @@ -HEADERS = settingswidget.h \ - plotwidget.h -SOURCES = settingswidget.cpp \ - plotwidget.cpp \ - main.cpp - -QT += webkit - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/scroller/plot -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS plot.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/scroller/plot -INSTALLS += target sources diff --git a/examples/scroller/plot/plotwidget.cpp b/examples/scroller/plot/plotwidget.cpp deleted file mode 100644 index e600652..0000000 --- a/examples/scroller/plot/plotwidget.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor -** the names of its contributors may be used to endorse or promote -** products derived from this software without specific prior written -** permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QPushButton> -#include <QTextStream> -#include <QColor> -#include <QPainter> -#include <QLabel> -#include <QResizeEvent> -#include <QPlastiqueStyle> -#include <QAbstractScrollArea> - -#include "plotwidget.h" -#include "qscroller.h" - -PlotWidget::PlotWidget(bool /*smallscreen*/) - : QWidget(), m_widget(0) -{ - setWindowTitle(QLatin1String("Plot")); - m_clear = new QPushButton(QLatin1String("Clear"), this); -#if defined(Q_WS_MAEMO_5) - m_clear->setStyle(new QPlastiqueStyle()); - m_clear->setFixedHeight(55); -#endif - connect(m_clear, SIGNAL(clicked()), this, SLOT(reset())); - m_legend = new QLabel(this); - QString legend; - QTextStream ts(&legend); - // ok. this wouldn't pass the w3c html verification... - ts << "<table style=\"color:#000;\" border=\"0\">"; - ts << "<tr><td width=\"30\" bgcolor=\"" << QColor(Qt::red).light().name() << "\" /><td>Velocity X</td></tr>"; - ts << "<tr><td width=\"30\" bgcolor=\"" << QColor(Qt::red).dark().name() << "\" /><td>Velocity Y</td></tr>"; - ts << "<tr><td width=\"30\" bgcolor=\"" << QColor(Qt::green).light().name() << "\" /><td>Content Position X</td></tr>"; - ts << "<tr><td width=\"30\" bgcolor=\"" << QColor(Qt::green).dark().name() << "\" /><td>Content Position Y</td></tr>"; - ts << "<tr><td width=\"30\" bgcolor=\"" << QColor(Qt::blue).light().name() << "\" /><td>Overshoot Position X</td></tr>"; - ts << "<tr><td width=\"30\" bgcolor=\"" << QColor(Qt::blue).dark().name() << "\" /><td>Overshoot Position Y</td></tr>"; - ts << "</table>"; - m_legend->setText(legend); -} - -void PlotWidget::setScroller(QWidget *widget) -{ - if (QAbstractScrollArea *area = qobject_cast<QAbstractScrollArea *>(widget)) - widget = area->viewport(); - - if (m_widget) - m_widget->removeEventFilter(this); - m_widget = widget; - reset(); - if (m_widget) - m_widget->installEventFilter(this); -} - -bool PlotWidget::eventFilter(QObject *obj, QEvent *ev) -{ - if (ev->type() == QEvent::Scroll) { - QScrollEvent *se = static_cast<QScrollEvent *>(ev); - QScroller *scroller = QScroller::scroller(m_widget); - - QPointF v = scroller->velocity(); - //v.rx() *= scroller->pixelPerMeter().x(); - //v.ry() *= scroller->pixelPerMeter().y(); - - PlotItem pi = { v, se->contentPos(), se->overshootDistance() }; - addPlotItem(pi); - } - - return QWidget::eventFilter(obj, ev); -} - -static inline void doMaxMin(const QPointF &v, qreal &minmaxv) -{ - minmaxv = qMax(minmaxv, qMax(qAbs(v.x()), qAbs(v.y()))); -} - -void PlotWidget::addPlotItem(const PlotItem &pi) -{ - m_plotitems.append(pi); - minMaxVelocity = minMaxPosition = 0; - - while (m_plotitems.size() > 500) - m_plotitems.removeFirst(); - - foreach (const PlotItem &pi, m_plotitems) { - doMaxMin(pi.velocity, minMaxVelocity); - doMaxMin(pi.contentPosition, minMaxPosition); - doMaxMin(pi.overshootPosition, minMaxPosition); - } - update(); -} - -void PlotWidget::reset() -{ - m_plotitems.clear(); - minMaxVelocity = minMaxPosition = 0; - update(); -} - -void PlotWidget::resizeEvent(QResizeEvent *) -{ - QSize cs = m_clear->sizeHint(); - QSize ls = m_legend->sizeHint(); - m_clear->setGeometry(4, 4, cs.width(), cs.height()); - m_legend->setGeometry(4, height() - ls.height() - 4, ls.width(), ls.height()); -} - -void PlotWidget::paintEvent(QPaintEvent *) -{ -#define SCALE(v, mm) ((qreal(1) - (v / mm)) * qreal(0.5) * height()) - - QColor rvColor = Qt::red; - QColor cpColor = Qt::green; - QColor opColor = Qt::blue; - - - QPainter p(this); - //p.setRenderHints(QPainter::Antialiasing); //too slow for 60fps - p.fillRect(rect(), Qt::white); - - p.setPen(Qt::black); - p.drawLine(0, SCALE(0, 1), width(), SCALE(0, 1)); - - if (m_plotitems.isEmpty()) - return; - - int x = 2; - int offset = m_plotitems.size() - width() / 2; - QList<PlotItem>::const_iterator it = m_plotitems.constBegin(); - if (offset > 0) - it += (offset - 1); - - const PlotItem *last = &(*it++); - - while (it != m_plotitems.constEnd()) { - p.setPen(rvColor.light()); - p.drawLine(qreal(x - 2), SCALE(last->velocity.x(), minMaxVelocity), - qreal(x), SCALE(it->velocity.x(), minMaxVelocity)); - p.setPen(rvColor.dark()); - p.drawLine(qreal(x - 2), SCALE(last->velocity.y(), minMaxVelocity), - qreal(x), SCALE(it->velocity.y(), minMaxVelocity)); - - p.setPen(cpColor.light()); - p.drawLine(qreal(x - 2), SCALE(last->contentPosition.x(), minMaxPosition), - qreal(x), SCALE(it->contentPosition.x(), minMaxPosition)); - p.setPen(cpColor.dark()); - p.drawLine(qreal(x - 2), SCALE(last->contentPosition.y(), minMaxPosition), - qreal(x), SCALE(it->contentPosition.y(), minMaxPosition)); - - p.setPen(opColor.light()); - p.drawLine(qreal(x - 2), SCALE(last->overshootPosition.x(), minMaxPosition), - qreal(x), SCALE(it->overshootPosition.x(), minMaxPosition)); - p.setPen(opColor.dark()); - p.drawLine(qreal(x - 2), SCALE(last->overshootPosition.y(), minMaxPosition), - qreal(x), SCALE(it->overshootPosition.y(), minMaxPosition)); - - last = &(*it++); - x += 2; - } - - QString toptext = QString("%1 [m/s] / %2 [pix]").arg(minMaxVelocity, 0, 'f', 2).arg(minMaxPosition, 0, 'f', 2); - QString bottomtext = QString("-%1 [m/s] / -%2 [pix]").arg(minMaxVelocity, 0, 'f', 2).arg(minMaxPosition, 0, 'f', 2); - - p.setPen(Qt::black); - p.drawText(rect(), Qt::AlignTop | Qt::AlignHCenter, toptext); - p.drawText(rect(), Qt::AlignBottom | Qt::AlignHCenter, bottomtext); -#undef SCALE -} diff --git a/examples/scroller/plot/plotwidget.h b/examples/scroller/plot/plotwidget.h deleted file mode 100644 index 3c36be9..0000000 --- a/examples/scroller/plot/plotwidget.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor -** the names of its contributors may be used to endorse or promote -** products derived from this software without specific prior written -** permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef PLOTWIDGET_H -#define PLOTWIDGET_H - -#include <QWidget> -#include <QPointF> - -QT_BEGIN_NAMESPACE -class QPushButton; -class QLabel; -class QScroller; -QT_END_NAMESPACE - -class PlotWidget : public QWidget -{ - Q_OBJECT - -public: - PlotWidget(bool smallscreen = false); - - void setScroller(QWidget *widget); - -public slots: - void reset(); - -protected: - void resizeEvent(QResizeEvent *); - void paintEvent(QPaintEvent *); - - bool eventFilter(QObject *obj, QEvent *ev); - -private: - - struct PlotItem { - QPointF velocity; - QPointF contentPosition; - QPointF overshootPosition; - }; - - void addPlotItem(const PlotItem &pi); - - QWidget *m_widget; - QList<PlotItem> m_plotitems; - qreal minMaxVelocity, minMaxPosition; - QPushButton *m_clear; - QLabel *m_legend; -}; - -#endif diff --git a/examples/scroller/plot/settingswidget.cpp b/examples/scroller/plot/settingswidget.cpp deleted file mode 100644 index c9de008..0000000 --- a/examples/scroller/plot/settingswidget.cpp +++ /dev/null @@ -1,689 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor -** the names of its contributors may be used to endorse or promote -** products derived from this software without specific prior written -** permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QVariant> -#include <QSlider> -#include <QHBoxLayout> -#include <QLabel> -#include <QPushButton> -#include <QComboBox> -#include <QSpinBox> -#include <QGroupBox> -#include <QToolButton> -#include <QCheckBox> -#include <QScrollBar> -#include <QPainter> -#include <QScrollArea> -#include <QScrollPrepareEvent> -#include <QApplication> -#include <QPlainTextEdit> -#include <QTextBlock> -#include <qnumeric.h> - -#include <QEasingCurve> - -#include <QDebug> - -#include "math.h" - -#include "settingswidget.h" -#include "qscroller.h" -#include "qscrollerproperties.h" - -class SnapOverlay : public QWidget -{ - Q_OBJECT -public: - SnapOverlay(QWidget *w) - : QWidget(w) - { - setAttribute(Qt::WA_TransparentForMouseEvents); - - if (QAbstractScrollArea *area = qobject_cast<QAbstractScrollArea *>(w)) { - connect(area->horizontalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(update())); - connect(area->verticalScrollBar(), SIGNAL(valueChanged(int)), this, SLOT(update())); - area->viewport()->installEventFilter(this); - } - } - void clear(Qt::Orientation o) - { - m_snap[o].clear(); - update(); - } - - void set(Qt::Orientation o, qreal first, qreal step) - { - m_snap[o] = QList<qreal>() << -Q_INFINITY << first << step; - update(); - } - - void set(Qt::Orientation o, const QList<qreal> &list) - { - m_snap[o] = list; - update(); - } - -protected: - bool eventFilter(QObject *o, QEvent *e) - { - if (QAbstractScrollArea *area = qobject_cast<QAbstractScrollArea *>(parentWidget())) { - if (area->viewport() == o) { - if (e->type() == QEvent::Move || e->type() == QEvent::Resize) { - setGeometry(area->viewport()->rect()); - } - } - } - return false; - } - - void paintEvent(QPaintEvent *e) - { - if (QAbstractScrollArea *area = qobject_cast<QAbstractScrollArea *>(parentWidget())) { - int dx = area->horizontalScrollBar()->value(); - int dy = area->verticalScrollBar()->value(); - - QPainter paint(this); - paint.fillRect(e->rect(), Qt::transparent); - paint.setPen(QPen(Qt::red, 9)); - - if (m_snap[Qt::Horizontal].isEmpty()) { - } else if (m_snap[Qt::Horizontal][0] == -Q_INFINITY) { - int start = int(m_snap[Qt::Horizontal][1]); - int step = int(m_snap[Qt::Horizontal][2]); - if (step > 0) { - for (int i = start; i < area->horizontalScrollBar()->maximum(); i += step) - paint.drawPoint(i - dx, 5); - } - } else { - foreach (qreal r, m_snap[Qt::Horizontal]) - paint.drawPoint(int(r) - dx, 5); - } - paint.setPen(QPen(Qt::green, 9)); - if (m_snap[Qt::Vertical].isEmpty()) { - } else if (m_snap[Qt::Vertical][0] == -Q_INFINITY) { - int start = int(m_snap[Qt::Vertical][1]); - int step = int(m_snap[Qt::Vertical][2]); - if (step > 0) { - for (int i = start; i < area->verticalScrollBar()->maximum(); i += step) - paint.drawPoint(5, i - dy); - } - } else { - foreach (qreal r, m_snap[Qt::Vertical]) - paint.drawPoint(5, int(r) - dy); - } - } - } - -private: - QMap<Qt::Orientation, QList<qreal> > m_snap; -}; - -struct MetricItem -{ - QScrollerProperties::ScrollMetric metric; - const char *name; - int scaling; - const char *unit; - QVariant min, max; - QVariant step; -}; - -class MetricItemUpdater : public QObject -{ - Q_OBJECT -public: - MetricItemUpdater(MetricItem *item) - : m_item(item) - , m_widget(0) - , m_slider(0) - , m_combo(0) - , m_valueLabel(0) - { - m_frameRateType = QVariant::fromValue(QScrollerProperties::Standard).userType(); - m_overshootPolicyType = QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable).userType(); - - if (m_item->min.type() == QVariant::EasingCurve) { - m_combo = new QComboBox(); - m_combo->addItem("OutQuad", QEasingCurve::OutQuad); - m_combo->addItem("OutCubic", QEasingCurve::OutCubic); - m_combo->addItem("OutQuart", QEasingCurve::OutQuart); - m_combo->addItem("OutQuint", QEasingCurve::OutQuint); - m_combo->addItem("OutExpo", QEasingCurve::OutExpo); - m_combo->addItem("OutSine", QEasingCurve::OutSine); - m_combo->addItem("OutCirc", QEasingCurve::OutCirc); - } else if (m_item->min.userType() == m_frameRateType) { - m_combo = new QComboBox(); - m_combo->addItem("Standard", QScrollerProperties::Standard); - m_combo->addItem("60 FPS", QScrollerProperties::Fps60); - m_combo->addItem("30 FPS", QScrollerProperties::Fps30); - m_combo->addItem("20 FPS", QScrollerProperties::Fps20); - } else if (m_item->min.userType() == m_overshootPolicyType) { - m_combo = new QComboBox(); - m_combo->addItem("When Scrollable", QScrollerProperties::OvershootWhenScrollable); - m_combo->addItem("Always On", QScrollerProperties::OvershootAlwaysOn); - m_combo->addItem("Always Off", QScrollerProperties::OvershootAlwaysOff); - } else { - m_slider = new QSlider(Qt::Horizontal); - m_slider->setSingleStep(1); - m_slider->setMinimum(-1); - m_slider->setMaximum(qRound((m_item->max.toReal() - m_item->min.toReal()) / m_item->step.toReal())); - m_slider->setValue(-1); - m_valueLabel = new QLabel(); - } - m_nameLabel = new QLabel(QLatin1String(m_item->name)); - if (m_item->unit && m_item->unit[0]) - m_nameLabel->setText(m_nameLabel->text() + QLatin1String(" [") + QLatin1String(m_item->unit) + QLatin1String("]")); - m_resetButton = new QToolButton(); - m_resetButton->setText(QLatin1String("Reset")); - m_resetButton->setEnabled(false); - - connect(m_resetButton, SIGNAL(clicked()), this, SLOT(reset())); - if (m_slider) { - connect(m_slider, SIGNAL(valueChanged(int)), this, SLOT(controlChanged(int))); - m_slider->setMinimum(0); - } else if (m_combo) { - connect(m_combo, SIGNAL(currentIndexChanged(int)), this, SLOT(controlChanged(int))); - } - } - - void setScroller(QWidget *widget) - { - m_widget = widget; - QScroller *scroller = QScroller::scroller(widget); - QScrollerProperties properties = QScroller::scroller(widget)->scrollerProperties(); - - if (m_slider) - m_slider->setEnabled(scroller); - if (m_combo) - m_combo->setEnabled(scroller); - m_nameLabel->setEnabled(scroller); - if (m_valueLabel) - m_valueLabel->setEnabled(scroller); - m_resetButton->setEnabled(scroller); - - if (!scroller) - return; - - m_default_value = properties.scrollMetric(m_item->metric); - valueChanged(m_default_value); - } - - QWidget *nameLabel() { return m_nameLabel; } - QWidget *valueLabel() { return m_valueLabel; } - QWidget *valueControl() { if (m_combo) return m_combo; else return m_slider; } - QWidget *resetButton() { return m_resetButton; } - -private slots: - void valueChanged(const QVariant &v) - { - m_value = v; - if (m_slider) { - switch (m_item->min.type()) { - case QMetaType::Float: - case QVariant::Double: { - m_slider->setValue(qRound((m_value.toReal() * m_item->scaling - m_item->min.toReal()) / m_item->step.toReal())); - break; - } - case QVariant::Int: { - m_slider->setValue(qRound((m_value.toInt() * m_item->scaling - m_item->min.toInt()) / m_item->step.toInt())); - break; - } - default: break; - } - } else if (m_combo) { - if (m_item->min.type() == QVariant::EasingCurve) { - m_combo->setCurrentIndex(m_combo->findData(v.toEasingCurve().type())); - } else if (m_item->min.userType() == m_overshootPolicyType) { - m_combo->setCurrentIndex(m_combo->findData(v.value<QScrollerProperties::OvershootPolicy>())); - } else if (m_item->min.userType() == m_frameRateType) { - m_combo->setCurrentIndex(m_combo->findData(v.value<QScrollerProperties::FrameRates>())); - } - } - } - - void controlChanged(int value) - { - bool combo = (m_combo && (sender() == m_combo)); - QString text; - - if (m_slider && !combo) { - switch (m_item->min.type()) { - case QMetaType::Float: - case QVariant::Double: { - qreal d = m_item->min.toReal() + qreal(value) * m_item->step.toReal(); - text = QString::number(d); - m_value = d / qreal(m_item->scaling); - break; - } - case QVariant::Int: { - int i = m_item->min.toInt() + qRound(qreal(value) * m_item->step.toReal()); - text = QString::number(i); - m_value = i / m_item->scaling; - break; - } - default: break; - } - } else if (m_combo && combo) { - if (m_item->min.type() == QVariant::EasingCurve) { - m_value = QVariant(QEasingCurve(static_cast<QEasingCurve::Type>(m_combo->itemData(value).toInt()))); - } else if (m_item->min.userType() == m_overshootPolicyType) { - m_value = QVariant::fromValue(static_cast<QScrollerProperties::OvershootPolicy>(m_combo->itemData(value).toInt())); - } else if (m_item->min.userType() == m_frameRateType) { - m_value = QVariant::fromValue(static_cast<QScrollerProperties::FrameRates>(m_combo->itemData(value).toInt())); - } - } - if (m_valueLabel) - m_valueLabel->setText(text); - if (m_widget && QScroller::scroller(m_widget)) { - QScrollerProperties properties = QScroller::scroller(m_widget)->scrollerProperties(); - properties.setScrollMetric(m_item->metric, m_value); - QScroller::scroller(m_widget)->setScrollerProperties(properties); - } - - m_resetButton->setEnabled(m_value != m_default_value); - } - - void reset() - { - QScrollerProperties properties = QScroller::scroller(m_widget)->scrollerProperties(); - properties.setScrollMetric(m_item->metric, m_value); - QScroller::scroller(m_widget)->setScrollerProperties(properties); - valueChanged(m_default_value); - } - -private: - MetricItem *m_item; - int m_frameRateType; - int m_overshootPolicyType; - - QWidget *m_widget; - QSlider *m_slider; - QComboBox *m_combo; - QLabel *m_nameLabel, *m_valueLabel; - QToolButton *m_resetButton; - - QVariant m_value, m_default_value; -}; - -#define METRIC(x) QScrollerProperties::x, #x - -MetricItem items[] = { - { METRIC(MousePressEventDelay), 1000, "ms", qreal(0), qreal(2000), qreal(10) }, - { METRIC(DragStartDistance), 1000, "mm", qreal(1), qreal(20), qreal(0.1) }, - { METRIC(DragVelocitySmoothingFactor), 1, "", qreal(0), qreal(1), qreal(0.1) }, - { METRIC(AxisLockThreshold), 1, "", qreal(0), qreal(1), qreal(0.01) }, - - { METRIC(ScrollingCurve), 1, "", QEasingCurve(), 0, 0 }, - { METRIC(DecelerationFactor), 1, "", qreal(0), qreal(3), qreal(0.01) }, - - { METRIC(MinimumVelocity), 1, "m/s", qreal(0), qreal(7), qreal(0.01) }, - { METRIC(MaximumVelocity), 1, "m/s", qreal(0), qreal(7), qreal(0.01) }, - { METRIC(MaximumClickThroughVelocity), 1, "m/s", qreal(0), qreal(7), qreal(0.01) }, - - { METRIC(AcceleratingFlickMaximumTime), 1000, "ms", qreal(100), qreal(5000), qreal(100) }, - { METRIC(AcceleratingFlickSpeedupFactor), 1, "", qreal(1), qreal(7), qreal(0.1) }, - - { METRIC(SnapPositionRatio), 1, "", qreal(0.1), qreal(0.9), qreal(0.1) }, - { METRIC(SnapTime), 1000, "ms", qreal(0), qreal(2000), qreal(10) }, - - { METRIC(OvershootDragResistanceFactor), 1, "", qreal(0), qreal(1), qreal(0.01) }, - { METRIC(OvershootDragDistanceFactor), 1, "", qreal(0), qreal(1), qreal(0.01) }, - { METRIC(OvershootScrollDistanceFactor), 1, "", qreal(0), qreal(1), qreal(0.01) }, - { METRIC(OvershootScrollTime), 1000, "ms", qreal(0), qreal(2000), qreal(10) }, - - { METRIC(HorizontalOvershootPolicy), 1, "", QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable), 0, 0 }, - { METRIC(VerticalOvershootPolicy), 1, "", QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable), 0, 0 }, - { METRIC(FrameRate), 1, "", QVariant::fromValue(QScrollerProperties::Standard), 0, 0 }, -}; - -#undef METRIC - -void SettingsWidget::addToGrid(QGridLayout *grid, QWidget *label, int widgetCount, ...) -{ - va_list args; - va_start(args, widgetCount); - - int rows = grid->rowCount(); - int cols = grid->columnCount(); - - if (label) { - if (m_smallscreen) - grid->addWidget(label, rows++, 0, 1, qMax(cols, widgetCount)); - else - grid->addWidget(label, rows, 0); - } - for (int i = 0; i < widgetCount; i++) { - if (QWidget *w = va_arg(args, QWidget *)) - grid->addWidget(w, rows, m_smallscreen ? i : i + 1); - } - va_end(args); -} - -SettingsWidget::SettingsWidget(bool smallscreen) - : QScrollArea() - , m_widget(0) - , m_snapoverlay(0) - , m_smallscreen(smallscreen) -{ - setWindowTitle(QLatin1String("Settings")); - QWidget *view = new QWidget(); - QVBoxLayout *layout = new QVBoxLayout(view); - QGroupBox *grp; - QGridLayout *grid; - - // GROUP: SCROLL METRICS - - grp = new QGroupBox(QLatin1String("Scroll Metrics")); - grid = new QGridLayout(); - grid->setVerticalSpacing(m_smallscreen ? 4 : 2); - - for (int i = 0; i < int(sizeof(items) / sizeof(items[0])); i++) { - MetricItemUpdater *u = new MetricItemUpdater(items + i); - u->setParent(this); - addToGrid(grid, u->nameLabel(), 3, u->valueControl(), u->valueLabel(), u->resetButton()); - m_metrics.append(u); - } - grp->setLayout(grid); - layout->addWidget(grp); - - // GROUP: SCROLL TO - - grp = new QGroupBox(QLatin1String("Scroll To")); - grid = new QGridLayout(); - grid->setVerticalSpacing(m_smallscreen ? 4 : 2); - - m_scrollx = new QSpinBox(); - m_scrolly = new QSpinBox(); - m_scrolltime = new QSpinBox(); - m_scrolltime->setRange(0, 10000); - m_scrolltime->setValue(1000); - m_scrolltime->setSuffix(QLatin1String(" ms")); - QPushButton *go = new QPushButton(QLatin1String("Go")); - connect(go, SIGNAL(clicked()), this, SLOT(scrollTo())); - connect(m_scrollx, SIGNAL(editingFinished()), this, SLOT(scrollTo())); - connect(m_scrolly, SIGNAL(editingFinished()), this, SLOT(scrollTo())); - connect(m_scrolltime, SIGNAL(editingFinished()), this, SLOT(scrollTo())); - grid->addWidget(new QLabel(QLatin1String("X:")), 0, 0); - grid->addWidget(m_scrollx, 0, 1); - grid->addWidget(new QLabel(QLatin1String("Y:")), 0, 2); - grid->addWidget(m_scrolly, 0, 3); - int row = smallscreen ? 1 : 0; - int col = smallscreen ? 0 : 4; - grid->addWidget(new QLabel(QLatin1String("in")), row, col++); - grid->addWidget(m_scrolltime, row, col++); - if (smallscreen) { - grid->addWidget(go, row, col + 1); - } else { - grid->addWidget(go, row, col); - grid->setColumnStretch(5, 1); - grid->setColumnStretch(6, 1); - } - grid->setColumnStretch(1, 1); - grid->setColumnStretch(3, 1); - grp->setLayout(grid); - layout->addWidget(grp); - - QLayout *snapbox = new QHBoxLayout(); - - // GROUP: SNAP POINTS X - - grp = new QGroupBox(QLatin1String("Snap Positions X")); - QBoxLayout *vbox = new QVBoxLayout(); - vbox->setSpacing(m_smallscreen ? 4 : 2); - m_snapx = new QComboBox(); - m_snapx->addItem(QLatin1String("No Snapping"), NoSnap); - m_snapx->addItem(QLatin1String("Snap to Interval"), SnapToInterval); - m_snapx->addItem(QLatin1String("Snap to List"), SnapToList); - connect(m_snapx, SIGNAL(currentIndexChanged(int)), this, SLOT(snapModeChanged(int))); - vbox->addWidget(m_snapx); - - m_snapxinterval = new QWidget(); - grid = new QGridLayout(); - grid->setVerticalSpacing(m_smallscreen ? 4 : 2); - m_snapxfirst = new QSpinBox(); - connect(m_snapxfirst, SIGNAL(valueChanged(int)), this, SLOT(snapPositionsChanged())); - grid->addWidget(new QLabel("First:"), 0, 0); - grid->addWidget(m_snapxfirst, 0, 1); - m_snapxstep = new QSpinBox(); - connect(m_snapxstep, SIGNAL(valueChanged(int)), this, SLOT(snapPositionsChanged())); - grid->addWidget(new QLabel("Interval:"), 0, 2); - grid->addWidget(m_snapxstep, 0, 3); - m_snapxinterval->setLayout(grid); - vbox->addWidget(m_snapxinterval); - m_snapxinterval->hide(); - - m_snapxlist = new QPlainTextEdit(); - m_snapxlist->setToolTip(QLatin1String("One snap position per line. Empty lines are ignored.")); - m_snapxlist->installEventFilter(this); - connect(m_snapxlist, SIGNAL(textChanged()), this, SLOT(snapPositionsChanged())); - vbox->addWidget(m_snapxlist); - m_snapxlist->hide(); - - vbox->addStretch(100); - grp->setLayout(vbox); - snapbox->addWidget(grp); - - // GROUP: SNAP POINTS Y - - grp = new QGroupBox(QLatin1String("Snap Positions Y")); - vbox = new QVBoxLayout(); - vbox->setSpacing(m_smallscreen ? 4 : 2); - m_snapy = new QComboBox(); - m_snapy->addItem(QLatin1String("No Snapping"), NoSnap); - m_snapy->addItem(QLatin1String("Snap to Interval"), SnapToInterval); - m_snapy->addItem(QLatin1String("Snap to List"), SnapToList); - connect(m_snapy, SIGNAL(currentIndexChanged(int)), this, SLOT(snapModeChanged(int))); - vbox->addWidget(m_snapy); - - m_snapyinterval = new QWidget(); - grid = new QGridLayout(); - grid->setVerticalSpacing(m_smallscreen ? 4 : 2); - m_snapyfirst = new QSpinBox(); - connect(m_snapyfirst, SIGNAL(valueChanged(int)), this, SLOT(snapPositionsChanged())); - grid->addWidget(new QLabel("First:"), 0, 0); - grid->addWidget(m_snapyfirst, 0, 1); - m_snapystep = new QSpinBox(); - connect(m_snapystep, SIGNAL(valueChanged(int)), this, SLOT(snapPositionsChanged())); - grid->addWidget(new QLabel("Interval:"), 0, 2); - grid->addWidget(m_snapystep, 0, 3); - m_snapyinterval->setLayout(grid); - vbox->addWidget(m_snapyinterval); - m_snapyinterval->hide(); - - m_snapylist = new QPlainTextEdit(); - m_snapylist->setToolTip(QLatin1String("One snap position per line. Empty lines are ignored.")); - m_snapylist->installEventFilter(this); - connect(m_snapylist, SIGNAL(textChanged()), this, SLOT(snapPositionsChanged())); - vbox->addWidget(m_snapylist); - m_snapylist->hide(); - - vbox->addStretch(100); - grp->setLayout(vbox); - snapbox->addWidget(grp); - - layout->addLayout(snapbox); - - layout->addStretch(100); - setWidget(view); - setWidgetResizable(true); -} - -void SettingsWidget::setScroller(QWidget *widget) -{ - delete m_snapoverlay; - if (m_widget) - m_widget->removeEventFilter(this); - QAbstractScrollArea *area = qobject_cast<QAbstractScrollArea *>(widget); - if (area) - widget = area->viewport(); - m_widget = widget; - m_widget->installEventFilter(this); - m_snapoverlay = new SnapOverlay(area); - QScrollerProperties properties = QScroller::scroller(widget)->scrollerProperties(); - - QMutableListIterator<MetricItemUpdater *> it(m_metrics); - while (it.hasNext()) - it.next()->setScroller(widget); - - if (!widget) - return; - - updateScrollRanges(); -} - -bool SettingsWidget::eventFilter(QObject *o, QEvent *e) -{ - if (o == m_widget && e->type() == QEvent::Resize) - updateScrollRanges(); - return false; -} - -void SettingsWidget::updateScrollRanges() -{ - QScrollPrepareEvent spe(QPoint(0, 0)); - QApplication::sendEvent(m_widget, &spe); - - QSizeF vp = spe.viewportSize(); - QRectF maxc = spe.contentPosRange(); - - m_scrollx->setRange(qRound(-vp.width()), qRound(maxc.width() + vp.width())); - m_scrolly->setRange(qRound(-vp.height()), qRound(maxc.height() + vp.height())); - - m_snapxfirst->setRange(maxc.left(), maxc.right()); - m_snapxstep->setRange(0, maxc.width()); - m_snapyfirst->setRange(maxc.top(), maxc.bottom()); - m_snapystep->setRange(0, maxc.height()); -} - -void SettingsWidget::scrollTo() -{ - if (QApplication::activePopupWidget()) - return; - if ((sender() == m_scrollx) && !m_scrollx->hasFocus()) - return; - if ((sender() == m_scrolly) && !m_scrolly->hasFocus()) - return; - if ((sender() == m_scrolltime) && !m_scrolltime->hasFocus()) - return; - - if (QScroller *scroller = QScroller::scroller(m_widget)) - scroller->scrollTo(QPointF(m_scrollx->value(), m_scrolly->value()), m_scrolltime->value()); -} - -void SettingsWidget::snapModeChanged(int mode) -{ - if (sender() == m_snapx) { - m_snapxmode = static_cast<SnapMode>(mode); - m_snapxinterval->setVisible(mode == SnapToInterval); - m_snapxlist->setVisible(mode == SnapToList); - snapPositionsChanged(); - } else if (sender() == m_snapy) { - m_snapymode = static_cast<SnapMode>(mode); - m_snapyinterval->setVisible(mode == SnapToInterval); - m_snapylist->setVisible(mode == SnapToList); - snapPositionsChanged(); - } -} - -void SettingsWidget::snapPositionsChanged() -{ - QScroller *s = QScroller::scroller(m_widget); - if (!s) - return; - - switch (m_snapxmode) { - case NoSnap: - s->setSnapPositionsX(QList<qreal>()); - m_snapoverlay->clear(Qt::Horizontal); - break; - case SnapToInterval: - s->setSnapPositionsX(m_snapxfirst->value(), m_snapxstep->value()); - m_snapoverlay->set(Qt::Horizontal, m_snapxfirst->value(), m_snapxstep->value()); - break; - case SnapToList: - s->setSnapPositionsX(toPositionList(m_snapxlist, m_snapxfirst->minimum(), m_snapxfirst->maximum())); - m_snapoverlay->set(Qt::Horizontal, toPositionList(m_snapxlist, m_snapxfirst->minimum(), m_snapxfirst->maximum())); - break; - } - switch (m_snapymode) { - case NoSnap: - s->setSnapPositionsY(QList<qreal>()); - m_snapoverlay->clear(Qt::Vertical); - break; - case SnapToInterval: - s->setSnapPositionsY(m_snapyfirst->value(), m_snapystep->value()); - m_snapoverlay->set(Qt::Vertical, m_snapyfirst->value(), m_snapystep->value()); - break; - case SnapToList: - s->setSnapPositionsY(toPositionList(m_snapylist, m_snapyfirst->minimum(), m_snapyfirst->maximum())); - m_snapoverlay->set(Qt::Vertical, toPositionList(m_snapylist, m_snapyfirst->minimum(), m_snapyfirst->maximum())); - break; - } -} - -QList<qreal> SettingsWidget::toPositionList(QPlainTextEdit *list, int vmin, int vmax) -{ - QList<qreal> snaps; - QList<QTextEdit::ExtraSelection> extrasel; - QTextEdit::ExtraSelection uline; - uline.format.setUnderlineColor(Qt::red); - uline.format.setUnderlineStyle(QTextCharFormat::WaveUnderline); - int line = 0; - - foreach (const QString &str, list->toPlainText().split(QLatin1Char('\n'))) { - ++line; - if (str.isEmpty()) - continue; - bool ok = false; - double d = str.toDouble(&ok); - if (ok && d >= vmin && d <= vmax) { - snaps << d; - } else { - QTextEdit::ExtraSelection esel = uline; - esel.cursor = QTextCursor(list->document()->findBlockByLineNumber(line - 1)); - esel.cursor.select(QTextCursor::LineUnderCursor); - extrasel << esel; - } - } - list->setExtraSelections(extrasel); - return snaps; -} - -#include "settingswidget.moc" diff --git a/examples/scroller/plot/settingswidget.h b/examples/scroller/plot/settingswidget.h deleted file mode 100644 index fc0acff..0000000 --- a/examples/scroller/plot/settingswidget.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor -** the names of its contributors may be used to endorse or promote -** products derived from this software without specific prior written -** permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SETTINGSWIDGET_H -#define SETTINGSWIDGET_H - -#include <QScrollArea> - -QT_BEGIN_NAMESPACE -class QScroller; -class QGridLayout; -class QSpinBox; -class QComboBox; -class QCheckBox; -class QPlainTextEdit; -QT_END_NAMESPACE - -class MetricItemUpdater; -class SnapOverlay; - -class SettingsWidget : public QScrollArea -{ - Q_OBJECT - -public: - SettingsWidget(bool smallscreen = false); - - void setScroller(QWidget *widget); - -protected: - bool eventFilter(QObject *, QEvent *); - -private slots: - void scrollTo(); - void snapModeChanged(int); - void snapPositionsChanged(); - -private: - enum SnapMode { - NoSnap, - SnapToInterval, - SnapToList - }; - - void addToGrid(QGridLayout *grid, QWidget *label, int widgetCount, ...); - QList<qreal> toPositionList(QPlainTextEdit *list, int vmin, int vmax); - void updateScrollRanges(); - - QWidget *m_widget; - QSpinBox *m_scrollx, *m_scrolly, *m_scrolltime; - QList<MetricItemUpdater *> m_metrics; - - SnapMode m_snapxmode; - QComboBox *m_snapx; - QWidget *m_snapxinterval; - QPlainTextEdit *m_snapxlist; - QSpinBox *m_snapxfirst; - QSpinBox *m_snapxstep; - - SnapMode m_snapymode; - QComboBox *m_snapy; - QWidget *m_snapyinterval; - QPlainTextEdit *m_snapylist; - QSpinBox *m_snapyfirst; - QSpinBox *m_snapystep; - SnapOverlay *m_snapoverlay; - - bool m_smallscreen; -}; - -#endif diff --git a/examples/scroller/scroller.pro b/examples/scroller/scroller.pro deleted file mode 100644 index 9a9991a..0000000 --- a/examples/scroller/scroller.pro +++ /dev/null @@ -1,11 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS = graphicsview - -contains(QT_CONFIG, webkit):SUBDIRS += plot wheel - -# install -sources.files = *.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/scroller -INSTALLS += sources - -symbian: include($$QT_SOURCE_TREE/examples/symbianpkgrules.pri) diff --git a/examples/scroller/wheel/main.cpp b/examples/scroller/wheel/main.cpp deleted file mode 100644 index 4205baf..0000000 --- a/examples/scroller/wheel/main.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor -** the names of its contributors may be used to endorse or promote -** products derived from this software without specific prior written -** permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtGui> -#include <qmath.h> - -#include "wheelwidget.h" - -class MainWindow : public QMainWindow -{ - Q_OBJECT -public: - MainWindow(bool touch) - : QMainWindow() - { - makeSlotMachine(touch); - setCentralWidget(m_slotMachine); - } - - void makeSlotMachine(bool touch) - { - if (QApplication::desktop()->width() > 1000) { - QFont f = font(); - f.setPointSize(f.pointSize() * 2); - setFont(f); - } - - m_slotMachine = new QWidget(this); - QGridLayout *grid = new QGridLayout(m_slotMachine); - grid->setSpacing(20); - - QStringList colors; - colors << "Red" << "Magenta" << "Peach" << "Orange" << "Yellow" << "Citro" << "Green" << "Cyan" << "Blue" << "Violet"; - - m_wheel1 = new StringWheelWidget(touch); - m_wheel1->setItems( colors ); - grid->addWidget( m_wheel1, 0, 0 ); - - m_wheel2 = new StringWheelWidget(touch); - m_wheel2->setItems( colors ); - grid->addWidget( m_wheel2, 0, 1 ); - - m_wheel3 = new StringWheelWidget(touch); - m_wheel3->setItems( colors ); - grid->addWidget( m_wheel3, 0, 2 ); - - QPushButton *shakeButton = new QPushButton(tr("Shake")); - connect(shakeButton, SIGNAL(clicked()), this, SLOT(rotateRandom())); - - grid->addWidget( shakeButton, 1, 0, 1, 3 ); - } - -private slots: - void rotateRandom() - { - m_wheel1->scrollTo(m_wheel1->currentIndex() + (qrand() % 200)); - m_wheel2->scrollTo(m_wheel2->currentIndex() + (qrand() % 200)); - m_wheel3->scrollTo(m_wheel3->currentIndex() + (qrand() % 200)); - } - -private: - QWidget *m_slotMachine; - - StringWheelWidget *m_wheel1; - StringWheelWidget *m_wheel2; - StringWheelWidget *m_wheel3; -}; - -int main(int argc, char **argv) -{ - QApplication a(argc, argv); - bool touch = a.arguments().contains(QLatin1String("--touch")); - MainWindow mw(touch); -#ifdef Q_WS_S60 - mw.showMaximized(); -#else - mw.show(); -#endif -#ifdef Q_WS_MAC - mw.raise(); -#endif - return a.exec(); -} - -#include "main.moc" diff --git a/examples/scroller/wheel/wheel.pro b/examples/scroller/wheel/wheel.pro deleted file mode 100644 index 48fe171..0000000 --- a/examples/scroller/wheel/wheel.pro +++ /dev/null @@ -1,11 +0,0 @@ -HEADERS = wheelwidget.h -SOURCES = wheelwidget.cpp \ - main.cpp - -QT += webkit - -# install -target.path = $$[QT_INSTALL_EXAMPLES]/scroller/wheel -sources.files = $$SOURCES $$HEADERS $$RESOURCES $$FORMS wheel.pro -sources.path = $$[QT_INSTALL_EXAMPLES]/scroller/wheel -INSTALLS += target sources diff --git a/examples/scroller/wheel/wheelwidget.cpp b/examples/scroller/wheel/wheelwidget.cpp deleted file mode 100644 index 10eaefb..0000000 --- a/examples/scroller/wheel/wheelwidget.cpp +++ /dev/null @@ -1,275 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor -** the names of its contributors may be used to endorse or promote -** products derived from this software without specific prior written -** permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtGui> - -#include "wheelwidget.h" - -#define WHEEL_SCROLL_OFFSET 50000.0 - -AbstractWheelWidget::AbstractWheelWidget(bool touch, QWidget *parent) - : QWidget(parent) - , m_currentItem(0) - , m_itemOffset(0) -{ -// ![0] - QScroller::grabGesture(this, touch ? QScroller::TouchGesture : QScroller::LeftMouseButtonGesture); -// ![0] -} - -AbstractWheelWidget::~AbstractWheelWidget() -{ } - -int AbstractWheelWidget::currentIndex() const -{ - return m_currentItem; -} - -void AbstractWheelWidget::setCurrentIndex(int index) -{ - if (index >= 0 && index < itemCount()) { - m_currentItem = index; - m_itemOffset = 0; - update(); - } -} - -bool AbstractWheelWidget::event(QEvent *e) -{ - switch (e->type()) { -// ![1] - case QEvent::ScrollPrepare: - { - // We set the snap positions as late as possible so that we are sure - // we get the correct itemHeight - QScroller *scroller = QScroller::scroller(this); - scroller->setSnapPositionsY( WHEEL_SCROLL_OFFSET, itemHeight() ); - - QScrollPrepareEvent *se = static_cast<QScrollPrepareEvent *>(e); - se->setViewportSize(QSizeF(size())); - // we claim a huge scrolling area and a huge content position and - // hope that the user doesn't notice that the scroll area is restricted - se->setContentPosRange(QRectF(0.0, 0.0, 0.0, WHEEL_SCROLL_OFFSET * 2)); - se->setContentPos(QPointF(0.0, WHEEL_SCROLL_OFFSET + m_currentItem * itemHeight() + m_itemOffset)); - se->accept(); - return true; - } -// ![1] -// ![2] - case QEvent::Scroll: - { - QScrollEvent *se = static_cast<QScrollEvent *>(e); - - qreal y = se->contentPos().y(); - int iy = y - WHEEL_SCROLL_OFFSET; - int ih = itemHeight(); - -// ![2] - - // -- calculate the current item position and offset and redraw the widget - int ic = itemCount(); - if (ic>0) { - m_currentItem = iy / ih % ic; - m_itemOffset = iy % ih; - - // take care when scrolling backwards. Modulo returns negative numbers - if (m_itemOffset < 0) { - m_itemOffset += ih; - m_currentItem--; - } - - if (m_currentItem < 0) - m_currentItem += ic; - } - // -- repaint - update(); - - se->accept(); - return true; - } - default: - return QWidget::event(e); - } - return true; -} - -void AbstractWheelWidget::paintEvent(QPaintEvent* event) -{ - Q_UNUSED( event ); - - // -- first calculate size and position. - int w = width(); - int h = height(); - - QPainter painter(this); - QPalette palette = QApplication::palette(); - QPalette::ColorGroup colorGroup = isEnabled() ? QPalette::Active : QPalette::Disabled; - - // linear gradient brush - QLinearGradient grad(0.5, 0, 0.5, 1.0); - grad.setColorAt(0, palette.color(colorGroup, QPalette::ButtonText)); - grad.setColorAt(0.2, palette.color(colorGroup, QPalette::Button)); - grad.setColorAt(0.8, palette.color(colorGroup, QPalette::Button)); - grad.setColorAt(1.0, palette.color(colorGroup, QPalette::ButtonText)); - grad.setCoordinateMode( QGradient::ObjectBoundingMode ); - QBrush gBrush( grad ); - - // paint a border and background - painter.setPen(palette.color(colorGroup, QPalette::ButtonText)); - painter.setBrush(gBrush); - // painter.setBrushOrigin( QPointF( 0.0, 0.0 ) ); - painter.drawRect( 0, 0, w-1, h-1 ); - - // paint inner border - painter.setPen(palette.color(colorGroup, QPalette::Button)); - painter.setBrush(Qt::NoBrush); - painter.drawRect( 1, 1, w-3, h-3 ); - - // paint the items - painter.setClipRect( QRect( 3, 3, w-6, h-6 ) ); - painter.setPen(palette.color(colorGroup, QPalette::ButtonText)); - - int iH = itemHeight(); - int iC = itemCount(); - if (iC > 0) { - - m_itemOffset = m_itemOffset % iH; - - for (int i=-h/2/iH; i<=h/2/iH+1; i++) { - - int itemNum = m_currentItem + i; - while (itemNum < 0) - itemNum += iC; - while (itemNum >= iC) - itemNum -= iC; - - paintItem(&painter, itemNum, QRect(6, h/2 +i*iH - m_itemOffset - iH/2, w-6, iH )); - } - } - - // draw a transparent bar over the center - QColor highlight = palette.color(colorGroup, QPalette::Highlight); - highlight.setAlpha(150); - - QLinearGradient grad2(0.5, 0, 0.5, 1.0); - grad2.setColorAt(0, highlight); - grad2.setColorAt(1.0, highlight.lighter()); - grad2.setCoordinateMode( QGradient::ObjectBoundingMode ); - QBrush gBrush2( grad2 ); - - QLinearGradient grad3(0.5, 0, 0.5, 1.0); - grad3.setColorAt(0, highlight); - grad3.setColorAt(1.0, highlight.darker()); - grad3.setCoordinateMode( QGradient::ObjectBoundingMode ); - QBrush gBrush3( grad3 ); - - painter.fillRect( QRect( 0, h/2 - iH/2, w, iH/2 ), gBrush2 ); - painter.fillRect( QRect( 0, h/2, w, iH/2 ), gBrush3 ); -} - -/*! - Rotates the wheel widget to a given index. - You can also give an index greater than itemCount or less than zero in which - case the wheel widget will scroll in the given direction and end up with - (index % itemCount) -*/ -void AbstractWheelWidget::scrollTo(int index) -{ - QScroller *scroller = QScroller::scroller(this); - - scroller->scrollTo(QPointF(0, WHEEL_SCROLL_OFFSET + index * itemHeight()), 5000); -} - -/*! - \class StringWheelWidget - \brief The StringWheelWidget class is an implementation of the AbstractWheelWidget class that draws QStrings as items. - \sa AbstractWheelWidget -*/ - -StringWheelWidget::StringWheelWidget(bool touch) - : AbstractWheelWidget(touch) -{ } - -QStringList StringWheelWidget::items() const -{ - return m_items; -} - -void StringWheelWidget::setItems( const QStringList &items ) -{ - m_items = items; - if (m_currentItem >= items.count()) - m_currentItem = items.count()-1; - update(); -} - - -QSize StringWheelWidget::sizeHint() const -{ - // determine font size - QFontMetrics fm(font()); - - return QSize( fm.width("m") * 10 + 6, fm.height() * 7 + 6 ); -} - -QSize StringWheelWidget::minimumSizeHint() const -{ - QFontMetrics fm(font()); - - return QSize( fm.width("m") * 5 + 6, fm.height() * 3 + 6 ); -} - -void StringWheelWidget::paintItem(QPainter* painter, int index, const QRect &rect) -{ - painter->drawText(rect, Qt::AlignCenter, m_items.at(index)); -} - -int StringWheelWidget::itemHeight() const -{ - QFontMetrics fm(font()); - return fm.height(); -} - -int StringWheelWidget::itemCount() const -{ - return m_items.count(); -} - - diff --git a/examples/scroller/wheel/wheelwidget.h b/examples/scroller/wheel/wheelwidget.h deleted file mode 100644 index 96dcebf..0000000 --- a/examples/scroller/wheel/wheelwidget.h +++ /dev/null @@ -1,103 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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:BSD$ -** You may use this file under the terms of the BSD license as follows: -** -** "Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are -** met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * Redistributions in binary form must reproduce the above copyright -** notice, this list of conditions and the following disclaimer in -** the documentation and/or other materials provided with the -** distribution. -** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor -** the names of its contributors may be used to endorse or promote -** products derived from this software without specific prior written -** permission. -** -** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef WHEELWIDGET_H -#define WHEELWIDGET_H - -#include <QWidget> -#include <QStringList> - -QT_BEGIN_NAMESPACE -class QPainter; -class QRect; -QT_END_NAMESPACE - -class AbstractWheelWidget : public QWidget { - Q_OBJECT - -public: - AbstractWheelWidget(bool touch, QWidget *parent = 0); - virtual ~AbstractWheelWidget(); - - int currentIndex() const; - void setCurrentIndex(int index); - - bool event(QEvent*); - void paintEvent(QPaintEvent *e); - virtual void paintItem(QPainter* painter, int index, const QRect &rect) = 0; - - virtual int itemHeight() const = 0; - virtual int itemCount() const = 0; - -public slots: - void scrollTo(int index); - -signals: - void stopped(int index); - -protected: - int m_currentItem; - int m_itemOffset; // 0-itemHeight() - qreal m_lastY; -}; - - -class StringWheelWidget : public AbstractWheelWidget { - Q_OBJECT - -public: - StringWheelWidget(bool touch); - - QStringList items() const; - void setItems( const QStringList &items ); - - QSize sizeHint() const; - QSize minimumSizeHint() const; - - void paintItem(QPainter* painter, int index, const QRect &rect); - - int itemHeight() const; - int itemCount() const; - -private: - QStringList m_items; -}; - -#endif // WHEELWIDGET_H diff --git a/mkspecs/common/symbian/backup_registration.xml b/mkspecs/common/symbian/backup_registration.xml new file mode 100644 index 0000000..794e11d --- /dev/null +++ b/mkspecs/common/symbian/backup_registration.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" standalone="yes"?> +<backup_registration> + <passive_backup> + <include_directory name = "\" /> + </passive_backup> + <system_backup/> + <restore requires_reboot = "no"/> +</backup_registration> diff --git a/mkspecs/common/symbian/template.applite b/mkspecs/common/symbian/template.applite new file mode 100644 index 0000000..73a1999 --- /dev/null +++ b/mkspecs/common/symbian/template.applite @@ -0,0 +1 @@ +// This is an auto-generated lite registration file
\ No newline at end of file diff --git a/mkspecs/features/declarative_debug.prf b/mkspecs/features/declarative_debug.prf new file mode 100644 index 0000000..b0248f0 --- /dev/null +++ b/mkspecs/features/declarative_debug.prf @@ -0,0 +1 @@ +contains(QT, declarative):DEFINES += QT_DECLARATIVE_DEBUG diff --git a/mkspecs/features/enable_backup.prf b/mkspecs/features/enable_backup.prf new file mode 100644 index 0000000..7700ca2 --- /dev/null +++ b/mkspecs/features/enable_backup.prf @@ -0,0 +1,43 @@ +# Generate deployment for backup registration file for mobile devices +symbian|maemo5|linux-g++-maemo { + symbian { + isEmpty(BACKUP_REGISTRATION_FILE_SYMBIAN) { + # Do not require a custom registration file in Symbian builds as the + # default file can be used as is in vast majority of projects. + # However, if the custom file exists in the default location, use that. + + CUSTOM_BACKUP_REG_FILE = $$_PRO_FILE_PWD_/backup_registration/symbian/backup_registration.xml + + exists($$CUSTOM_BACKUP_REG_FILE) { + BACKUP_REGISTRATION_FILE = $$CUSTOM_BACKUP_REG_FILE + } else { + BACKUP_REGISTRATION_FILE = $$[QT_INSTALL_DATA]/mkspecs/common/symbian/backup_registration.xml + } + } else { + BACKUP_REGISTRATION_FILE = $$BACKUP_REGISTRATION_FILE_SYMBIAN + } + + contains(TEMPLATE, app) { + enable_backup_deployment.path = /private/$$replace(TARGET.UID3, 0x,) + } else { + enable_backup_deployment.path = /private/10202D56/import/packages/$$replace(TARGET.UID3, 0x,) + } + DEPLOYMENT += enable_backup_deployment + } else { + isEmpty(BACKUP_REGISTRATION_FILE_MAEMO) { + BACKUP_REGISTRATION_FILE = $$_PRO_FILE_PWD_/backup_registration/maemo/$$basename(TARGET).conf + } else { + BACKUP_REGISTRATION_FILE = $$BACKUP_REGISTRATION_FILE_MAEMO + } + + enable_backup_deployment.path = /etc/osso-backup/applications + INSTALLS += enable_backup_deployment + } + + # Make sure that BACKUP_REGISTRATION_FILE has absolute path, otherwise the following exists check will not work. + !contains(BACKUP_REGISTRATION_FILE, "(^/|^\\\\|^.:).*"): BACKUP_REGISTRATION_FILE = $$_PRO_FILE_PWD_/$$BACKUP_REGISTRATION_FILE + + !exists($$BACKUP_REGISTRATION_FILE): warning(The backup registration file \'$$BACKUP_REGISTRATION_FILE\' was not found. Please provide a valid backup registration file.) + + enable_backup_deployment.files = $$BACKUP_REGISTRATION_FILE +} diff --git a/mkspecs/features/symbian/sis_targets.prf b/mkspecs/features/symbian/sis_targets.prf index d0fe881..f3452b7 100644 --- a/mkspecs/features/symbian/sis_targets.prf +++ b/mkspecs/features/symbian/sis_targets.prf @@ -26,7 +26,11 @@ equals(GENERATE_SIS_TARGETS, true) { qtPrepareTool(QMAKE_CREATEPACKAGE, createpackage) - CREATEPACKAGE_DIR = $$OBJECTS_DIR/createpackage_tmp + sis_objects_dir = $$OBJECTS_DIR + isEmpty(sis_objects_dir):sis_objects_dir = . + + CREATEPACKAGE_DIR = $$sis_objects_dir/createpackage_tmp + QMAKE_CLEAN += $$CREATEPACKAGE_DIR/* symbian-abld|symbian-sbsv2 { diff --git a/mkspecs/features/symbian/symbian_appbooster.prf b/mkspecs/features/symbian/symbian_appbooster.prf new file mode 100644 index 0000000..080f4d0 --- /dev/null +++ b/mkspecs/features/symbian/symbian_appbooster.prf @@ -0,0 +1,32 @@ +contains(TEMPLATE, ".*app") { + baseTarget = $$symbianRemoveSpecialCharacters($$basename(TARGET)) + + symbian-abld|symbian-sbsv2 { + LITE_REG_TARGET = $$_PRO_FILE_PWD_ + } else { + contains(DESTDIR, "/.*") { + LITE_REG_TARGET = $$DESTDIR + } else:isEmpty(DESTDIR) { + LITE_REG_TARGET = $$OUT_PWD + } else { + LITE_REG_TARGET = $$OUT_PWD/$$DESTDIR + } + } + + LITE_REG_TARGET = $${LITE_REG_TARGET}/$${baseTarget}.applite + LITE_REG_TEMPLATE = $$[QT_INSTALL_DATA]/mkspecs/common/symbian/template.applite + + lite_reg_copy.input = LITE_REG_TEMPLATE + lite_reg_copy.output = $$LITE_REG_TARGET + lite_reg_copy.variable_out = PRE_TARGETDEPS + lite_reg_copy.commands = $$QMAKE_COPY ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT} + lite_reg_copy.CONFIG += no_link + QMAKE_EXTRA_COMPILERS += lite_reg_copy + + isEmpty(LITE_IMPORT_DIR): LITE_IMPORT_DIR = /private/20034884/import/apps + lite_deployment.sources += $$LITE_REG_TARGET + lite_deployment.path = $$LITE_IMPORT_DIR + DEPLOYMENT += lite_deployment + + LIBS += -lqDeclarativeBooster.dll +} diff --git a/mkspecs/hurd-g++/qmake.conf b/mkspecs/hurd-g++/qmake.conf index d89f2e4..09a72fa 100644 --- a/mkspecs/hurd-g++/qmake.conf +++ b/mkspecs/hurd-g++/qmake.conf @@ -1,90 +1,74 @@ # # qmake configuration for hurd-g++ # -# Submitted by uch@nop.or.jp as "gnu-g++". -# Renamed to "hurd-g++" because people were confusing GNU/Hurd with GNU/Linux. -# MAKEFILE_GENERATOR = UNIX TARGET_PLATFORM = unix TEMPLATE = app +CONFIG += qt warn_on release incremental link_prl gdb_dwarf_index QT += core gui -CONFIG += qt warn_on release link_prl - -QMAKE_CC = gcc -QMAKE_LEX = flex -QMAKE_LEXFLAGS = -QMAKE_YACC = yacc -QMAKE_YACCFLAGS = -d -QMAKE_CFLAGS = -pipe -QMAKE_CFLAGS_DEPS = -M -QMAKE_CFLAGS_WARN_ON = -Wall -W -QMAKE_CFLAGS_WARN_OFF = -w -QMAKE_CFLAGS_RELEASE = -O2 -QMAKE_CFLAGS_DEBUG = -g -QMAKE_CFLAGS_SHLIB = -fPIC -QMAKE_CFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_SHLIB -QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses -QMAKE_CFLAGS_THREAD = -D_REENTRANT +QMAKE_INCREMENTAL_STYLE = sublib -QMAKE_CXX = g++ -QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS -QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF -QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE -QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG -QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB -QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB -QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC -QMAKE_CXXFLAGS_THREAD = $$QMAKE_CXXFLAGS_THREAD +QMAKE_CFLAGS_THREAD += -D_REENTRANT +QMAKE_CXXFLAGS_THREAD += $$QMAKE_CFLAGS_THREAD -QMAKE_INCDIR = -QMAKE_LIBDIR = -QMAKE_INCDIR_X11 = /usr/X11R6/include -QMAKE_LIBDIR_X11 = /usr/X11R6/lib -QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] -QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] -QMAKE_INCDIR_OPENGL = /usr/X11R6/include -QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib +QMAKE_INCDIR = +QMAKE_LIBDIR = +QMAKE_INCDIR_X11 = /usr/X11R6/include +QMAKE_LIBDIR_X11 = /usr/X11R6/lib +QMAKE_INCDIR_QT = $$[QT_INSTALL_HEADERS] +QMAKE_LIBDIR_QT = $$[QT_INSTALL_LIBS] +QMAKE_INCDIR_OPENGL = /usr/X11R6/include +QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib +QMAKE_INCDIR_OPENGL_ES1 = $$QMAKE_INCDIR_OPENGL +QMAKE_LIBDIR_OPENGL_ES1 = $$QMAKE_LIBDIR_OPENGL +QMAKE_INCDIR_OPENGL_ES2 = $$QMAKE_INCDIR_OPENGL +QMAKE_LIBDIR_OPENGL_ES2 = $$QMAKE_LIBDIR_OPENGL +QMAKE_INCDIR_EGL = +QMAKE_LIBDIR_EGL = +QMAKE_INCDIR_OPENVG = +QMAKE_LIBDIR_OPENVG = -QMAKE_LINK = g++ -QMAKE_LINK_SHLIB = g++ -QMAKE_LINK_C = gcc -QMAKE_LINK_C_SHLIB = gcc -QMAKE_LFLAGS = -Wl,-rpath=/lib:/usr/X11R6/lib:$$[QT_INSTALL_LIBS] -QMAKE_LFLAGS_RELEASE = -QMAKE_LFLAGS_DEBUG = -QMAKE_LFLAGS_SHLIB = -shared -QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB -QMAKE_LFLAGS_SONAME = -Wl,-soname, +QMAKE_LIBS = +QMAKE_LIBS_DYNLOAD = -ldl +QMAKE_LIBS_X11 = -lXext -lX11 -lm +QMAKE_LIBS_X11SM = -lSM -lICE +QMAKE_LIBS_NIS = -lnsl +QMAKE_LIBS_EGL = -lEGL +QMAKE_LIBS_OPENGL = -lGL +QMAKE_LIBS_OPENGL_QT = -lGL +QMAKE_LIBS_OPENGL_ES1 = -lGLES_CM +QMAKE_LIBS_OPENGL_ES2 = -lGLESv2 +QMAKE_LIBS_OPENVG = -lOpenVG +QMAKE_LIBS_THREAD = -lpthread -QMAKE_LIBS = -lpthread # This is tricky but needed -QMAKE_LIBS_DYNLOAD = -ldl -QMAKE_LIBS_X11 = -lXext -lX11 -lm -QMAKE_LIBS_X11SM = -lSM -lICE -QMAKE_LIBS_NIS = -lnsl -QMAKE_LIBS_QT_THREAD = -lqt-mt -QMAKE_LIBS_THREAD = +QMAKE_MOC = $$[QT_INSTALL_BINS]/moc +QMAKE_UIC = $$[QT_INSTALL_BINS]/uic -QMAKE_LIBS_OPENGL = -lGL -QMAKE_LIBS_OPENGL_QT = -lGL +QMAKE_AR = ar cqs +QMAKE_OBJCOPY = objcopy +QMAKE_RANLIB = -QMAKE_MOC = $$[QT_INSTALL_BINS]/moc -QMAKE_UIC = $$[QT_INSTALL_BINS]/uic +QMAKE_TAR = tar -cf +QMAKE_GZIP = gzip -9f -QMAKE_AR = ar cqs -QMAKE_OBJCOPY = objcopy -QMAKE_RANLIB = +QMAKE_COPY = cp -f +QMAKE_COPY_FILE = $(COPY) +QMAKE_COPY_DIR = $(COPY) -r +QMAKE_MOVE = mv -f +QMAKE_DEL_FILE = rm -f +QMAKE_DEL_DIR = rmdir +QMAKE_STRIP = strip +QMAKE_STRIPFLAGS_LIB += --strip-unneeded +QMAKE_CHK_DIR_EXISTS = test -d +QMAKE_MKDIR = mkdir -p +QMAKE_INSTALL_FILE = install -m 644 -p +QMAKE_INSTALL_PROGRAM = install -m 755 -p -QMAKE_TAR = tar -cf -QMAKE_GZIP = gzip -9f - -QMAKE_COPY = cp -f -QMAKE_MOVE = mv -f -QMAKE_DEL_FILE = rm -f -QMAKE_DEL_DIR = rmdir -QMAKE_CHK_DIR_EXISTS = test -d -QMAKE_MKDIR = mkdir -p include(../common/unix.conf) +include(../common/gcc-base-unix.conf) +include(../common/g++-unix.conf) load(qt_config) + +# This is tricky but needed +QMAKE_LIBS += $$QMAKE_LIBS_THREAD diff --git a/qmake/generators/makefile.cpp b/qmake/generators/makefile.cpp index 4f3b113..79c71dd 100644 --- a/qmake/generators/makefile.cpp +++ b/qmake/generators/makefile.cpp @@ -1109,7 +1109,7 @@ MakefileGenerator::writePrlFile() && project->isActiveConfig("create_prl") && (project->first("TEMPLATE") == "lib" || project->first("TEMPLATE") == "vclib") - && !project->isActiveConfig("plugin")) { //write prl file + && (!project->isActiveConfig("plugin") || project->isActiveConfig("static"))) { //write prl file QString local_prl = prlFileName(); QString prl = fileFixify(local_prl); mkdir(fileInfo(local_prl).path()); @@ -2376,6 +2376,14 @@ MakefileGenerator::writeSubDirs(QTextStream &t) qDeleteAll(targets); } +void MakefileGenerator::writeSubMakeCall(QTextStream &t, const QString &callPrefix, + const QString &makeArguments, const QString &callPostfix) +{ + t << callPrefix + << "$(MAKE)" << makeArguments + << callPostfix << endl; +} + void MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubTarget*> targets, int flags) { @@ -2499,9 +2507,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT t << " " << valList(subtarget->depends); if(project->isEmpty("QMAKE_NOFORCE")) t << " FORCE"; - t << out_directory_cdin - << "$(MAKE)" << makefilein - << out_directory_cdout << endl; + writeSubMakeCall(t, out_directory_cdin, makefilein, out_directory_cdout); } for(int suffix = 0; suffix < targetSuffixes.size(); ++suffix) { @@ -2521,9 +2527,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT t << " " << targets.at(target-1)->target << "-" << targetSuffixes.at(suffix) << "-ordered "; if(project->isEmpty("QMAKE_NOFORCE")) t << " FORCE"; - t << out_directory_cdin - << "$(MAKE)" << makefilein << " " << s - << out_directory_cdout << endl; + writeSubMakeCall(t, out_directory_cdin, makefilein + " " + s, out_directory_cdout); } t << subtarget->target << "-" << targetSuffixes.at(suffix) << ": " << mkfile; if(!subtarget->depends.isEmpty()) @@ -2531,9 +2535,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT "-"+targetSuffixes.at(suffix)); if(project->isEmpty("QMAKE_NOFORCE")) t << " FORCE"; - t << out_directory_cdin - << "$(MAKE)" << makefilein << " " << s - << out_directory_cdout << endl; + writeSubMakeCall(t, out_directory_cdin, makefilein + " " + s, out_directory_cdout); } } t << endl; @@ -2641,10 +2643,7 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT QString out_directory_cdin, out_directory_cdout; MAKE_CD_IN_AND_OUT(out_directory); - //don't need the makefile arg if it isn't changed - QString makefilein; - if(subtarget->makefile != "$(MAKEFILE)") - makefilein = " -f " + subtarget->makefile; + QString makefilein = " -f " + subtarget->makefile; //write the rule/depends if(flags & SubTargetOrdered) { @@ -2667,12 +2666,10 @@ MakefileGenerator::writeSubTargets(QTextStream &t, QList<MakefileGenerator::SubT //write the commands if(!out_directory.isEmpty()) { - t << out_directory_cdin - << "$(MAKE)" << makefilein << " " << sub_targ - << out_directory_cdout << endl; + writeSubMakeCall(t, out_directory_cdin, makefilein + " " + sub_targ, + out_directory_cdout); } else { - t << "\n\t" - << "$(MAKE)" << makefilein << " " << sub_targ << endl; + writeSubMakeCall(t, "\n\t", makefilein + " " + sub_targ, QString()); } } } diff --git a/qmake/generators/makefile.h b/qmake/generators/makefile.h index e0ef52d..417370a 100644 --- a/qmake/generators/makefile.h +++ b/qmake/generators/makefile.h @@ -127,6 +127,8 @@ protected: SubTargetsNoFlags=0x00 }; QList<MakefileGenerator::SubTarget*> findSubDirsSubTargets() const; + virtual void writeSubMakeCall(QTextStream &t, const QString &outDirectory_cdin, + const QString &makeFileIn, const QString &outDirectory_cdout); void writeSubTargets(QTextStream &t, QList<SubTarget*> subtargets, int flags); //extra compiler interface diff --git a/qmake/generators/unix/unixmake2.cpp b/qmake/generators/unix/unixmake2.cpp index 9f14492..82f2366 100644 --- a/qmake/generators/unix/unixmake2.cpp +++ b/qmake/generators/unix/unixmake2.cpp @@ -96,7 +96,8 @@ UnixMakefileGenerator::writeMakefile(QTextStream &t) } if (project->values("TEMPLATE").first() == "app" || - project->values("TEMPLATE").first() == "lib") { + project->values("TEMPLATE").first() == "lib" || + project->values("TEMPLATE").first() == "aux") { if(Option::mkfile::do_stub_makefile && MakefileGenerator::writeStubMakefile(t)) return true; writeMakeParts(t); @@ -1017,6 +1018,9 @@ void UnixMakefileGenerator::init2() if(project->isEmpty("QMAKE_FRAMEWORK_VERSION")) project->values("QMAKE_FRAMEWORK_VERSION").append(project->values("VER_MAJ").first()); + if (project->values("TEMPLATE").first() == "aux") + return; + if (!project->values("QMAKE_APP_FLAG").isEmpty()) { if(!project->isEmpty("QMAKE_BUNDLE")) { QString bundle_loc = project->first("QMAKE_BUNDLE_LOCATION"); diff --git a/qmake/generators/win32/borland_bmake.cpp b/qmake/generators/win32/borland_bmake.cpp index 585a0f4..1f7de00 100644 --- a/qmake/generators/win32/borland_bmake.cpp +++ b/qmake/generators/win32/borland_bmake.cpp @@ -68,7 +68,8 @@ BorlandMakefileGenerator::writeMakefile(QTextStream &t) } if(project->first("TEMPLATE") == "app" || - project->first("TEMPLATE") == "lib") { + project->first("TEMPLATE") == "lib" || + project->first("TEMPLATE") == "aux") { writeBorlandParts(t); return MakefileGenerator::writeMakefile(t); } @@ -136,6 +137,11 @@ BorlandMakefileGenerator::init() void BorlandMakefileGenerator::writeBuildRulesPart(QTextStream &t) { + if (project->first("TEMPLATE") == "aux") { + t << "first:" << endl; + return; + } + t << "first: all" << endl; t << "all: " << fileFixify(Option::output.fileName()) << " " << varGlue("ALL_DEPS"," "," "," ") << " $(DESTDIR_TARGET)" << endl << endl; t << "$(DESTDIR_TARGET): " << var("PRE_TARGETDEPS") << " $(OBJECTS) " << var("POST_TARGETDEPS"); diff --git a/qmake/generators/win32/mingw_make.cpp b/qmake/generators/win32/mingw_make.cpp index 462920e..0d15cfb 100644 --- a/qmake/generators/win32/mingw_make.cpp +++ b/qmake/generators/win32/mingw_make.cpp @@ -141,7 +141,8 @@ bool MingwMakefileGenerator::writeMakefile(QTextStream &t) } if(project->first("TEMPLATE") == "app" || - project->first("TEMPLATE") == "lib") { + project->first("TEMPLATE") == "lib" || + project->first("TEMPLATE") == "aux") { if(project->isActiveConfig("create_pc") && project->first("TEMPLATE") == "lib") writePkgConfigFile(); @@ -436,6 +437,11 @@ void MingwMakefileGenerator::writeObjectsPart(QTextStream &t) void MingwMakefileGenerator::writeBuildRulesPart(QTextStream &t) { + if (project->first("TEMPLATE") == "aux") { + t << "first:" << endl; + return; + } + t << "first: all" << endl; t << "all: " << escapeDependencyPath(fileFixify(Option::output.fileName())) << " " << valGlue(escapeDependencyPaths(project->values("ALL_DEPS"))," "," "," ") << " $(DESTDIR_TARGET)" << endl << endl; t << "$(DESTDIR_TARGET): " << var("PRE_TARGETDEPS") << " $(OBJECTS) " << var("POST_TARGETDEPS"); diff --git a/qmake/generators/win32/msvc_nmake.cpp b/qmake/generators/win32/msvc_nmake.cpp index c55806d..52eaace 100644 --- a/qmake/generators/win32/msvc_nmake.cpp +++ b/qmake/generators/win32/msvc_nmake.cpp @@ -70,7 +70,8 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) } if(project->first("TEMPLATE") == "app" || - project->first("TEMPLATE") == "lib") { + project->first("TEMPLATE") == "lib" || + project->first("TEMPLATE") == "aux") { #if 0 if(Option::mkfile::do_stub_makefile) return MakefileGenerator::writeStubMakefile(t); @@ -85,6 +86,15 @@ NmakeMakefileGenerator::writeMakefile(QTextStream &t) return false; } +void NmakeMakefileGenerator::writeSubMakeCall(QTextStream &t, const QString &callPrefix, + const QString &makeArguments, const QString &callPostfix) +{ + // Pass MAKEFLAGS as environment variable to sub-make calls. + // Unlike other make tools nmake doesn't do this automatically. + t << "\n\t@set MAKEFLAGS=$(MAKEFLAGS)"; + Win32MakefileGenerator::writeSubMakeCall(t, callPrefix, makeArguments, callPostfix); +} + QString NmakeMakefileGenerator::getPdbTarget() { return QString(project->first("TARGET") + project->first("TARGET_VERSION_EXT") + ".pdb"); @@ -332,6 +342,11 @@ void NmakeMakefileGenerator::writeImplicitRulesPart(QTextStream &t) void NmakeMakefileGenerator::writeBuildRulesPart(QTextStream &t) { + if (project->first("TEMPLATE") == "aux") { + t << "first:" << endl; + return; + } + t << "first: all" << endl; t << "all: " << fileFixify(Option::output.fileName()) << " " << varGlue("ALL_DEPS"," "," "," ") << "$(DESTDIR_TARGET)" << endl << endl; t << "$(DESTDIR_TARGET): " << var("PRE_TARGETDEPS") << " $(OBJECTS) " << var("POST_TARGETDEPS"); diff --git a/qmake/generators/win32/msvc_nmake.h b/qmake/generators/win32/msvc_nmake.h index 8954655..689cc19 100644 --- a/qmake/generators/win32/msvc_nmake.h +++ b/qmake/generators/win32/msvc_nmake.h @@ -57,6 +57,8 @@ class NmakeMakefileGenerator : public Win32MakefileGenerator void init(); protected: + virtual void writeSubMakeCall(QTextStream &t, const QString &callPrefix, + const QString &makeArguments, const QString &callPostfix); virtual QString getPdbTarget(); virtual QString defaultInstall(const QString &t); virtual QStringList &findDependencies(const QString &file); diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp index 56f3bfd..5807787 100644 --- a/qmake/generators/win32/msvc_vcproj.cpp +++ b/qmake/generators/win32/msvc_vcproj.cpp @@ -208,6 +208,7 @@ const char _slnExtSections[] = "\n\tGlobalSection(ExtensibilityGlobals) = pos VcprojGenerator::VcprojGenerator() : Win32MakefileGenerator(), init_flag(false), + is64Bit(false), projectWriter(0) { } @@ -597,14 +598,16 @@ nextfile: } } t << _slnGlobalBeg; + + QString slnConf = _slnSolutionConf; if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH")) { - QString slnConfCE = _slnSolutionConf; - QString platform = QString("|") + project->values("CE_SDK").join(" ") + " (" + project->first("CE_ARCH") + ")"; - slnConfCE.replace(QString("|Win32"), platform); - t << slnConfCE; - } else { - t << _slnSolutionConf; + QString slnPlatform = QString("|") + project->values("CE_SDK").join(" ") + " (" + project->first("CE_ARCH") + ")"; + slnConf.replace(QString("|Win32"), slnPlatform); + } else if (is64Bit) { + slnConf.replace(QString("|Win32"), "|x64"); } + t << slnConf; + t << _slnProjDepBeg; // Restore previous after_user_var options @@ -621,7 +624,7 @@ nextfile: t << _slnProjDepEnd; t << _slnProjConfBeg; for(QList<VcsolutionDepend*>::Iterator it = solution_cleanup.begin(); it != solution_cleanup.end(); ++it) { - QString platform = "Win32"; + QString platform = is64Bit ? "x64" : "Win32"; if (!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH")) platform = project->values("CE_SDK").join(" ") + " (" + project->first("CE_ARCH") + ")"; t << "\n\t\t" << (*it)->uuid << QString(_slnProjDbgConfTag1).arg(platform) << platform; @@ -661,6 +664,7 @@ void VcprojGenerator::init() if (init_flag) return; init_flag = true; + is64Bit = (project->first("QMAKE_TARGET.arch") == "x86_64"); projectWriter = createProjectWriter(); if(project->first("TEMPLATE") == "vcsubdirs") //too much work for subdirs @@ -831,7 +835,7 @@ void VcprojGenerator::initProject() vcProject.Keyword = project->first("VCPROJ_KEYWORD"); if (project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) { - vcProject.PlatformName = (vcProject.Configuration.idl.TargetEnvironment == midlTargetWin64 ? "Win64" : "Win32"); + vcProject.PlatformName = (is64Bit ? "x64" : "Win32"); } else { vcProject.PlatformName = project->values("CE_SDK").join(" ") + " (" + project->first("CE_ARCH") + ")"; } @@ -895,7 +899,7 @@ void VcprojGenerator::initConfiguration() conf.Name = isDebug ? "Debug" : "Release"; conf.ConfigurationName = conf.Name; if (project->isEmpty("CE_SDK") || project->isEmpty("CE_ARCH")) { - conf.Name += (conf.idl.TargetEnvironment == midlTargetWin64 ? "|Win64" : "|Win32"); + conf.Name += (is64Bit ? "|x64" : "|Win32"); } else { conf.Name += "|" + project->values("CE_SDK").join(" ") + " (" + project->first("CE_ARCH") + ")"; } diff --git a/qmake/generators/win32/msvc_vcproj.h b/qmake/generators/win32/msvc_vcproj.h index afe8f9f..c7f5c1b 100644 --- a/qmake/generators/win32/msvc_vcproj.h +++ b/qmake/generators/win32/msvc_vcproj.h @@ -57,6 +57,7 @@ struct QUuid; class VcprojGenerator : public Win32MakefileGenerator { bool init_flag; + bool is64Bit; bool writeVcprojParts(QTextStream &); bool writeMakefile(QTextStream &); diff --git a/qmake/generators/win32/msvc_vcxproj.cpp b/qmake/generators/win32/msvc_vcxproj.cpp index 1e7c4b7..5b75cfa 100644 --- a/qmake/generators/win32/msvc_vcxproj.cpp +++ b/qmake/generators/win32/msvc_vcxproj.cpp @@ -41,26 +41,9 @@ #include "msvc_vcxproj.h" #include "msbuild_objectmodel.h" -#include <qdir.h> -#include <qdiriterator.h> -#include <quuid.h> - - -QT_BEGIN_NAMESPACE -// Filter GUIDs (Do NOT change these!) ------------------------------ -const char _GUIDSourceFiles[] = "{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"; -const char _GUIDHeaderFiles[] = "{93995380-89BD-4b04-88EB-625FBE52EBFB}"; -const char _GUIDGeneratedFiles[] = "{71ED8ED8-ACB9-4CE9-BBE1-E00B30144E11}"; -const char _GUIDResourceFiles[] = "{D9D6E242-F8AF-46E4-B9FD-80ECBC20BA3E}"; -const char _GUIDLexYaccFiles[] = "{E12AE0D2-192F-4d59-BD23-7D3FA58D3183}"; -const char _GUIDTranslationFiles[] = "{639EADAA-A684-42e4-A9AD-28FC9BCB8F7C}"; -const char _GUIDFormFiles[] = "{99349809-55BA-4b9d-BF79-8FDBB0286EB3}"; -const char _GUIDExtraCompilerFiles[] = "{E0D8C965-CC5F-43d7-AD63-FAEF0BBC0F85}"; -QT_END_NAMESPACE QT_BEGIN_NAMESPACE - VcxprojGenerator::VcxprojGenerator() : VcprojGenerator() { } @@ -71,4 +54,3 @@ VCProjectWriter *VcxprojGenerator::createProjectWriter() } QT_END_NAMESPACE - diff --git a/qmake/generators/win32/msvc_vcxproj.h b/qmake/generators/win32/msvc_vcxproj.h index 3283cc7..90f6652 100644 --- a/qmake/generators/win32/msvc_vcxproj.h +++ b/qmake/generators/win32/msvc_vcxproj.h @@ -42,8 +42,6 @@ #ifndef MSVC_VCXPROJ_H #define MSVC_VCXPROJ_H -#include "winmakefile.h" -#include "msbuild_objectmodel.h" #include "msvc_vcproj.h" QT_BEGIN_NAMESPACE @@ -52,19 +50,11 @@ class VcxprojGenerator : public VcprojGenerator { public: VcxprojGenerator(); - ~VcxprojGenerator(); protected: virtual VCProjectWriter *createProjectWriter(); - -private: - friend class VCFilter; - }; -inline VcxprojGenerator::~VcxprojGenerator() -{ } - QT_END_NAMESPACE #endif // MSVC_VCXPROJ_H diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp index c202e1f..3410782 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp +++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp @@ -655,6 +655,7 @@ void HB_GetCharAttributes(const HB_UChar16 *string, hb_uint32 stringLength, const HB_ScriptItem *items, hb_uint32 numItems, HB_CharAttributes *attributes) { + memset(attributes, 0, stringLength * sizeof(HB_CharAttributes)); calcLineBreaks(string, stringLength, attributes); for (hb_uint32 i = 0; i < numItems; ++i) { diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp index fcb8d86..1015923 100644 --- a/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp +++ b/src/3rdparty/javascriptcore/JavaScriptCore/yarr/RegexJIT.cpp @@ -1312,6 +1312,9 @@ class RegexGenerator : private MacroAssembler { push(ARMRegisters::r4); push(ARMRegisters::r5); push(ARMRegisters::r6); +#if CPU(ARM_TRADITIONAL) + push(ARMRegisters::r8); // scratch register +#endif move(ARMRegisters::r3, output); #endif } @@ -1327,6 +1330,9 @@ class RegexGenerator : private MacroAssembler { pop(X86Registers::ebx); pop(X86Registers::ebp); #elif CPU(ARM) +#if CPU(ARM_TRADITIONAL) + pop(ARMRegisters::r8); // scratch register +#endif pop(ARMRegisters::r6); pop(ARMRegisters::r5); pop(ARMRegisters::r4); diff --git a/src/3rdparty/phonon/phonon/audiooutputadaptor.cpp b/src/3rdparty/phonon/phonon/audiooutputadaptor.cpp index 2c01773..959172d 100644 --- a/src/3rdparty/phonon/phonon/audiooutputadaptor.cpp +++ b/src/3rdparty/phonon/phonon/audiooutputadaptor.cpp @@ -1,3 +1,28 @@ +/* This file is part of the KDE project + The following license applies to the edits made to the generated + source code: + + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + Copyright (C) 2009 Matthias Kretz. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ /* * This file was generated by dbusidl2cpp version 0.4 * when processing input file org.kde.Phonon.AudioOutput.xml diff --git a/src/3rdparty/phonon/phonon/audiooutputadaptor_p.h b/src/3rdparty/phonon/phonon/audiooutputadaptor_p.h index 7178e9b..140a74f 100644 --- a/src/3rdparty/phonon/phonon/audiooutputadaptor_p.h +++ b/src/3rdparty/phonon/phonon/audiooutputadaptor_p.h @@ -1,3 +1,28 @@ +/* This file is part of the KDE project + The following license applies to the edits made to the generated + source code: + + Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). + Copyright (C) 2009 Matthias Kretz. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) version 3, or any + later version accepted by the membership of KDE e.V. (or its + successor approved by the membership of KDE e.V.), Nokia Corporation + (or its successors, if any) and the KDE Free Qt Foundation, which shall + act as a proxy defined in Section 6 of version 3 of the license. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library. If not, see <http://www.gnu.org/licenses/>. + +*/ /* * This file was generated by dbusidl2cpp version 0.4 * when processing input file org.kde.Phonon.AudioOutput.xml diff --git a/src/activeqt/shared/qaxtypes.cpp b/src/activeqt/shared/qaxtypes.cpp index c48b55b..8835caf 100644 --- a/src/activeqt/shared/qaxtypes.cpp +++ b/src/activeqt/shared/qaxtypes.cpp @@ -265,7 +265,7 @@ bool QVariantToVARIANT(const QVariant &var, VARIANT &arg, const QByteArray &type return QVariantToVARIANT(var, *arg.pvarVal, typeName, false); } - if (out && proptype == QVariant::Invalid && typeName == "QVariant") { + if (out && proptype == QVariant::UserType && typeName == "QVariant") { VARIANT *pVariant = new VARIANT; QVariantToVARIANT(var, *pVariant, QByteArray(), false); arg.vt = VT_VARIANT|VT_BYREF; diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 602cf8a..0a1f5d7 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -260,7 +260,8 @@ void QUnifiedTimer::restartAnimationTimer() } else if (!driver->isRunning() || isPauseTimerActive) { driver->start(); isPauseTimerActive = false; - } + } else if (runningLeafAnimations == 0) + driver->stop(); } void QUnifiedTimer::setTimingInterval(int interval) diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index ba92960..0ccc502 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -184,6 +184,9 @@ public: void restartAnimationTimer(); void updateAnimationsTime(); + //useful for profiling/debugging + int runningAnimationCount() { return animations.count(); } + protected: void timerEvent(QTimerEvent *); diff --git a/src/corelib/concurrent/qfuturewatcher.cpp b/src/corelib/concurrent/qfuturewatcher.cpp index ea12bc9..728714a 100644 --- a/src/corelib/concurrent/qfuturewatcher.cpp +++ b/src/corelib/concurrent/qfuturewatcher.cpp @@ -589,4 +589,16 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event) QT_END_NAMESPACE -#endif // QT_NO_CONCURRENT +#else + +// On Symbian winscw target QT_NO_QFUTURE and QT_NO_CONCURRENT are both defined. +// However moc will be run without having them set, so provide a dummy stub at +// least for the slots to prevent linker errors. + +void QFutureWatcherBase::cancel() { } +void QFutureWatcherBase::setPaused(bool) { } +void QFutureWatcherBase::pause() { } +void QFutureWatcherBase::resume() { } +void QFutureWatcherBase::togglePaused() { } + +#endif // QT_NO_QFUTURE diff --git a/src/corelib/concurrent/qfuturewatcher.h b/src/corelib/concurrent/qfuturewatcher.h index 5fe2007..26e549d 100644 --- a/src/corelib/concurrent/qfuturewatcher.h +++ b/src/corelib/concurrent/qfuturewatcher.h @@ -44,8 +44,6 @@ #include <QtCore/qfuture.h> -#ifndef QT_NO_QFUTURE - #include <QtCore/qobject.h> QT_BEGIN_HEADER @@ -56,6 +54,11 @@ QT_MODULE(Core) class QEvent; class QFutureWatcherBasePrivate; + +#ifdef QT_NO_QFUTURE +class QFutureInterfaceBase; +#endif + class Q_CORE_EXPORT QFutureWatcherBase : public QObject { Q_OBJECT @@ -114,6 +117,8 @@ private: virtual QFutureInterfaceBase &futureInterface() = 0; }; +#ifndef QT_NO_QFUTURE + template <typename T> class QFutureWatcher : public QFutureWatcherBase { @@ -214,9 +219,9 @@ Q_INLINE_TEMPLATE void QFutureWatcher<void>::setFuture(const QFuture<void> &_fut connectOutputInterface(); } +#endif // QT_NO_QFUTURE + QT_END_NAMESPACE QT_END_HEADER -#endif // QT_NO_CONCURRENT - #endif // QFUTUREWATCHER_H diff --git a/src/corelib/concurrent/qtconcurrentfilter.h b/src/corelib/concurrent/qtconcurrentfilter.h index e392212..63dcc4b 100644 --- a/src/corelib/concurrent/qtconcurrentfilter.h +++ b/src/corelib/concurrent/qtconcurrentfilter.h @@ -115,19 +115,7 @@ ThreadEngineStarter<void> filterInternal(Sequence &sequence, KeepFunctor keep, T template <typename Sequence, typename KeepFunctor> QFuture<void> filter(Sequence &sequence, KeepFunctor keep) { - return filterInternal(sequence, keep, &Sequence::push_back); -} - -template <typename Sequence, typename T> -QFuture<void> filter(Sequence &sequence, bool (keep)(T)) -{ - return filterInternal(sequence, FunctionWrapper1<bool, T>(keep), &Sequence::push_back); -} - -template <typename Sequence, typename C> -QFuture<void> filter(Sequence &sequence, bool (C::*keep)() const) -{ - return filterInternal(sequence, ConstMemberFunctionWrapper<bool, C>(keep), &Sequence::push_back); + return filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back); } // filteredReduced() on sequences @@ -137,103 +125,20 @@ QFuture<ResultType> filteredReduced(const Sequence &sequence, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced<ResultType>(sequence, keep, reduce, options); - } - -template <typename ResultType, typename Sequence, typename T, typename ReduceFunctor> -QFuture<ResultType> filteredReduced(const Sequence &sequence, - bool (filter)(T), - ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<ResultType>(sequence, - FunctionWrapper1<bool, T>(filter), - reduce, - options); + return startFilteredReduced<ResultType>(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options); } -template <typename ResultType, typename Sequence, typename C, typename ReduceFunctor> -QFuture<ResultType> filteredReduced(const Sequence &sequence, - bool (C::*filter)() const, +template <typename Sequence, typename KeepFunctor, typename ReduceFunctor> +QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> filteredReduced(const Sequence &sequence, + KeepFunctor keep, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return filteredReduced<ResultType>(sequence, - ConstMemberFunctionWrapper<bool, C>(filter), - reduce, - options); -} - -template <typename Sequence, typename KeepFunctor, typename T, typename U, typename V> -QFuture<U> filteredReduced(const Sequence &sequence, - KeepFunctor keep, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<U>(sequence, - keep, - FunctionWrapper2<T, U &, V>(reduce), - options); -} - -template <typename Sequence, typename KeepFunctor, typename T, typename C, typename U> -QFuture<C> filteredReduced(const Sequence &sequence, - KeepFunctor keep, - T (C::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<C>(sequence, - keep, - MemberFunctionWrapper1<T, C, U>(reduce), - options); -} - -template <typename Sequence, typename T, typename U, typename V, typename W> -QFuture<V> filteredReduced(const Sequence &sequence, - bool (keep)(T), - U (reduce)(V &, W), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<V>(sequence, - FunctionWrapper1<bool, T>(keep), - FunctionWrapper2<U, V &, W>(reduce), - options); -} - -template <typename Sequence, typename C, typename T, typename U, typename V> -QFuture<U> filteredReduced(const Sequence &sequence, - bool (C::*keep)() const, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<U>(sequence, - ConstMemberFunctionWrapper<bool, C>(keep), - FunctionWrapper2<T, U &, V>(reduce), - options); -} - -template <typename Sequence, typename T, typename U, typename C, typename V> -QFuture<C> filteredReduced(const Sequence &sequence, - bool (keep)(T), - U (C::*reduce)(V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<C>(sequence, - FunctionWrapper1<bool, T>(keep), - MemberFunctionWrapper1<U, C, V>(reduce), - options); -} - -template <typename Sequence, typename C, typename T, typename D, typename U> -QFuture<D> filteredReduced(const Sequence &sequence, - bool (C::*keep)() const, - T (D::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<D>(sequence, - ConstMemberFunctionWrapper<bool, C>(keep), - MemberFunctionWrapper1<T, D, U>(reduce), - options); + return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> + (sequence, + QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + options); } // filteredReduced() on iterators @@ -244,184 +149,42 @@ QFuture<ResultType> filteredReduced(Iterator begin, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced<ResultType>(begin, end, keep, reduce, options); -} - -template <typename ResultType, typename Iterator, typename T, typename ReduceFunctor> -QFuture<ResultType> filteredReduced(Iterator begin, - Iterator end, - bool (filter)(T), - ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<ResultType>(begin, - end, - FunctionWrapper1<bool, T>(filter), - reduce, - options); + return startFilteredReduced<ResultType>(begin, end, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options); } -template <typename ResultType, typename Iterator, typename C, typename ReduceFunctor> -QFuture<ResultType> filteredReduced(Iterator begin, +template <typename Iterator, typename KeepFunctor, typename ReduceFunctor> +QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> filteredReduced(Iterator begin, Iterator end, - bool (C::*filter)() const, + KeepFunctor keep, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return filteredReduced<ResultType>(begin, - end, - ConstMemberFunctionWrapper<bool, C>(filter), - reduce, - options); -} - -template <typename Iterator, typename KeepFunctor, typename T, typename U, typename V> -QFuture<U> filteredReduced(Iterator begin, - Iterator end, - KeepFunctor keep, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<U>(begin, - end, - keep, - FunctionWrapper2<T, U &, V>(reduce), - options); -} - -template <typename Iterator, typename KeepFunctor, typename T, typename C, typename U> -QFuture<C> filteredReduced(Iterator begin, - Iterator end, - KeepFunctor keep, - T (C::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<C>(begin, - end, - keep, - MemberFunctionWrapper1<T, C, U>(reduce), - options); -} - -template <typename Iterator, typename T, typename U, typename V, typename W> -QFuture<V> filteredReduced(Iterator begin, - Iterator end, - bool (keep)(T), - U (reduce)(V &, W), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<V>(begin, - end, - FunctionWrapper1<bool, T>(keep), - FunctionWrapper2<U, V &, W>(reduce), - options); -} - -template <typename Iterator, typename C, typename T, typename U, typename V> -QFuture<U> filteredReduced(Iterator begin, - Iterator end, - bool (C::*keep)() const, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<U>(begin, - end, - ConstMemberFunctionWrapper<bool, C>(keep), - FunctionWrapper2<T, U &, V>(reduce), - options); -} - -template <typename Iterator, typename T, typename U, typename C, typename V> -QFuture<C> filteredReduced(Iterator begin, - Iterator end, - bool (keep)(T), - U (C::*reduce)(V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<C>(begin, - end, - FunctionWrapper1<bool, T>(keep), - MemberFunctionWrapper1<U, C, V>(reduce), - options); + return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> + (begin, end, + QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + options); } -template <typename Iterator, typename C, typename T, typename D, typename U> -QFuture<D> filteredReduced(Iterator begin, - Iterator end, - bool (C::*keep)() const, - T (D::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return filteredReduced<D>(begin, - end, - ConstMemberFunctionWrapper<bool, C>(keep), - MemberFunctionWrapper1<T, D, U>(reduce), - options); -} - - // filtered() on sequences template <typename Sequence, typename KeepFunctor> QFuture<typename Sequence::value_type> filtered(const Sequence &sequence, KeepFunctor keep) { - return startFiltered(sequence, keep); -} - -template <typename Sequence, typename T> -QFuture<typename Sequence::value_type> filtered(const Sequence &sequence, bool (keep)(T)) -{ - return startFiltered(sequence, FunctionWrapper1<bool, T>(keep)); -} - -template <typename Sequence, typename C> -QFuture<typename Sequence::value_type> filtered(const Sequence &sequence, bool (C::*keep)() const) -{ - return startFiltered(sequence, ConstMemberFunctionWrapper<bool, C>(keep)); + return startFiltered(sequence, QtPrivate::createFunctionWrapper(keep)); } // filtered() on iterators template <typename Iterator, typename KeepFunctor> QFuture<typename qValueType<Iterator>::value_type> filtered(Iterator begin, Iterator end, KeepFunctor keep) { - return startFiltered(begin, end, keep); + return startFiltered(begin, end, QtPrivate::createFunctionWrapper(keep)); } -template <typename Iterator, typename T> -QFuture<typename qValueType<Iterator>::value_type> filtered(Iterator begin, Iterator end, bool (keep)(T)) -{ - return startFiltered(begin, end, FunctionWrapper1<bool, T>(keep)); -} - -template <typename Iterator, typename C> -QFuture<typename qValueType<Iterator>::value_type> filtered(Iterator begin, - Iterator end, - bool (C::*keep)() const) -{ - return startFiltered(begin, end, ConstMemberFunctionWrapper<bool, C>(keep)); -} - - // blocking filter() on sequences template <typename Sequence, typename KeepFunctor> void blockingFilter(Sequence &sequence, KeepFunctor keep) { - filterInternal(sequence, keep, &Sequence::push_back).startBlocking(); -} - -template <typename Sequence, typename T> -void blockingFilter(Sequence &sequence, bool (keep)(T)) -{ - filterInternal(sequence, FunctionWrapper1<bool, T>(keep), &Sequence::push_back) - .startBlocking(); -} - -template <typename Sequence, typename C> -void blockingFilter(Sequence &sequence, bool (C::*keep)() const) -{ - filterInternal(sequence, - ConstMemberFunctionWrapper<bool, C>(keep), - &Sequence::push_back) - .startBlocking(); + filterInternal(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back).startBlocking(); } // blocking filteredReduced() on sequences @@ -431,111 +194,20 @@ ResultType blockingFilteredReduced(const Sequence &sequence, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced<ResultType>(sequence, keep, reduce, options) + return startFilteredReduced<ResultType>(sequence, QtPrivate::createFunctionWrapper(keep), QtPrivate::createFunctionWrapper(reduce), options) .startBlocking(); } -template <typename ResultType, typename Sequence, typename T, typename ReduceFunctor> -ResultType blockingFilteredReduced(const Sequence &sequence, - bool (filter)(T), - ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<ResultType> - (sequence, - FunctionWrapper1<bool, T>(filter), - reduce, - options); -} - -template <typename ResultType, typename Sequence, typename C, typename ReduceFunctor> -ResultType blockingFilteredReduced(const Sequence &sequence, - bool (C::*filter)() const, +template <typename Sequence, typename KeepFunctor, typename ReduceFunctor> +typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFilteredReduced(const Sequence &sequence, + KeepFunctor keep, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return blockingFilteredReduced<ResultType> - (sequence, - ConstMemberFunctionWrapper<bool, C>(filter), - reduce, - options); -} - -template <typename Sequence, typename KeepFunctor, typename T, typename U, typename V> -U blockingFilteredReduced(const Sequence &sequence, - KeepFunctor keep, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<U> - (sequence, - keep, - FunctionWrapper2<T, U &, V>(reduce), - options); -} - -template <typename Sequence, typename KeepFunctor, typename T, typename C, typename U> -C blockingFilteredReduced(const Sequence &sequence, - KeepFunctor keep, - T (C::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<C> + return blockingFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> (sequence, - keep, - MemberFunctionWrapper1<T, C, U>(reduce), - options); -} - -template <typename Sequence, typename T, typename U, typename V, typename W> -V blockingFilteredReduced(const Sequence &sequence, - bool (keep)(T), - U (reduce)(V &, W), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<V> - (sequence, - FunctionWrapper1<bool, T>(keep), - FunctionWrapper2<U, V &, W>(reduce), - options); -} - -template <typename Sequence, typename C, typename T, typename U, typename V> -U blockingFilteredReduced(const Sequence &sequence, - bool (C::*keep)() const, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<U> - (sequence, - ConstMemberFunctionWrapper<bool, C>(keep), - FunctionWrapper2<T, U &, V>(reduce), - options); -} - -template <typename Sequence, typename T, typename U, typename C, typename V> -C blockingFilteredReduced(const Sequence &sequence, - bool (keep)(T), - U (C::*reduce)(V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<C> - (sequence, - FunctionWrapper1<bool, T>(keep), - MemberFunctionWrapper1<U, C, V>(reduce), - options); -} - -template <typename Sequence, typename C, typename T, typename D, typename U> -D blockingFilteredReduced(const Sequence &sequence, - bool (C::*keep)() const, - T (D::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<D> - (sequence, - ConstMemberFunctionWrapper<bool, C>(keep), - MemberFunctionWrapper1<T, D, U>(reduce), + QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), options); } @@ -547,150 +219,34 @@ ResultType blockingFilteredReduced(Iterator begin, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startFilteredReduced<ResultType>(begin, end, keep, reduce, options) + return startFilteredReduced<ResultType> + (begin, end, + QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + options) .startBlocking(); } -template <typename ResultType, typename Iterator, typename T, typename ReduceFunctor> -ResultType blockingFilteredReduced(Iterator begin, - Iterator end, - bool (filter)(T), - ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<ResultType> - (begin, - end, - FunctionWrapper1<bool, T>(filter), - reduce, - options); -} - -template <typename ResultType, typename Iterator, typename C, typename ReduceFunctor> -ResultType blockingFilteredReduced(Iterator begin, +template <typename Iterator, typename KeepFunctor, typename ReduceFunctor> +typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingFilteredReduced(Iterator begin, Iterator end, - bool (C::*filter)() const, + KeepFunctor keep, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return blockingFilteredReduced<ResultType> - (begin, - end, - ConstMemberFunctionWrapper<bool, C>(filter), - reduce, - options); -} - -template <typename Iterator, typename KeepFunctor, typename T, typename U, typename V> -U blockingFilteredReduced(Iterator begin, - Iterator end, - KeepFunctor keep, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<U> - (begin, - end, - keep, - FunctionWrapper2<T, U &, V>(reduce), - options); -} - -template <typename Iterator, typename KeepFunctor, typename T, typename C, typename U> -C blockingFilteredReduced(Iterator begin, - Iterator end, - KeepFunctor keep, - T (C::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<C> - (begin, - end, - keep, - MemberFunctionWrapper1<T, C, U>(reduce), - options); -} - -template <typename Iterator, typename T, typename U, typename V, typename W> -V blockingFilteredReduced(Iterator begin, - Iterator end, - bool (keep)(T), - U (reduce)(V &, W), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<V> - (begin, - end, - FunctionWrapper1<bool, T>(keep), - FunctionWrapper2<U, V &, W>(reduce), - options); -} - -template <typename Iterator, typename C, typename T, typename U, typename V> -U blockingFilteredReduced(Iterator begin, - Iterator end, - bool (C::*keep)() const, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<U> - (begin, - end, - ConstMemberFunctionWrapper<bool, C>(keep), - FunctionWrapper2<T, U &, V>(reduce), - options); -} - -template <typename Iterator, typename T, typename U, typename C, typename V> -C blockingFilteredReduced(Iterator begin, - Iterator end, - bool (keep)(T), - U (C::*reduce)(V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<C> - (begin, - end, - FunctionWrapper1<bool, T>(keep), - MemberFunctionWrapper1<U, C, V>(reduce), - options); -} - -template <typename Iterator, typename C, typename T, typename D, typename U> -D blockingFilteredReduced(Iterator begin, - Iterator end, - bool (C::*keep)() const, - T (D::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return blockingFilteredReduced<D> - (begin, - end, - ConstMemberFunctionWrapper<bool, C>(keep), - MemberFunctionWrapper1<T, D, U>(reduce), - options); + return startFilteredReduced<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> + (begin, end, + QtPrivate::createFunctionWrapper(keep), + QtPrivate::createFunctionWrapper(reduce), + options) + .startBlocking(); } // blocking filtered() on sequences template <typename Sequence, typename KeepFunctor> Sequence blockingFiltered(const Sequence &sequence, KeepFunctor keep) { - return blockingFilteredReduced(sequence, keep, &Sequence::push_back, OrderedReduce); -} - -template <typename Sequence, typename T> -Sequence blockingFiltered(const Sequence &sequence, bool (keep)(T)) -{ - return blockingFilteredReduced(sequence, keep, &Sequence::push_back, OrderedReduce); -} - -template <typename Sequence, typename C> -Sequence blockingFiltered(const Sequence &sequence, bool (C::*filter)() const) -{ - return blockingFilteredReduced(sequence, - filter, - &Sequence::push_back, - OrderedReduce); + return blockingFilteredReduced(sequence, QtPrivate::createFunctionWrapper(keep), &Sequence::push_back, OrderedReduce); } // blocking filtered() on iterators @@ -699,27 +255,7 @@ OutputSequence blockingFiltered(Iterator begin, Iterator end, KeepFunctor keep) { return blockingFilteredReduced(begin, end, - keep, - &OutputSequence::push_back, - OrderedReduce); -} - -template <typename OutputSequence, typename Iterator, typename T> -OutputSequence blockingFiltered(Iterator begin, Iterator end, bool (keep)(T)) -{ - return blockingFilteredReduced(begin, - end, - keep, - &OutputSequence::push_back, - OrderedReduce); -} - -template <typename OutputSequence, typename Iterator, typename C> -OutputSequence blockingFiltered(Iterator begin, Iterator end, bool (C::*filter)() const) -{ - return blockingFilteredReduced(begin, - end, - filter, + QtPrivate::createFunctionWrapper(keep), &OutputSequence::push_back, OrderedReduce); } diff --git a/src/corelib/concurrent/qtconcurrentfunctionwrappers.h b/src/corelib/concurrent/qtconcurrentfunctionwrappers.h index f31f7d2..98506a5 100644 --- a/src/corelib/concurrent/qtconcurrentfunctionwrappers.h +++ b/src/corelib/concurrent/qtconcurrentfunctionwrappers.h @@ -163,6 +163,125 @@ private: } // namespace QtConcurrent. +namespace QtPrivate { + +template <typename T> +const T& createFunctionWrapper(const T& t) +{ + return t; +} + +template <typename T, typename U> +QtConcurrent::FunctionWrapper1<T, U> createFunctionWrapper(T (*func)(U)) +{ + return QtConcurrent::FunctionWrapper1<T, U>(func); +} + +template <typename T, typename C> +QtConcurrent::MemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)()) +{ + return QtConcurrent::MemberFunctionWrapper<T, C>(func); +} + +template <typename T, typename C, typename U> +QtConcurrent::MemberFunctionWrapper1<T, C, U> createFunctionWrapper(T (C::*func)(U)) +{ + return QtConcurrent::MemberFunctionWrapper1<T, C, U>(func); +} + +template <typename T, typename C> +QtConcurrent::ConstMemberFunctionWrapper<T, C> createFunctionWrapper(T (C::*func)() const) +{ + return QtConcurrent::ConstMemberFunctionWrapper<T, C>(func); +} + + +template<typename T> +void *lazyResultType_helper(int, typename T::result_type * = 0); +template<typename T> +char lazyResultType_helper(double); + +template <typename Functor, bool foo = sizeof(lazyResultType_helper<Functor>(0)) != sizeof(void*)> +struct LazyResultType { typedef typename Functor::result_type Type; }; +template <typename Functor> +struct LazyResultType<Functor, true> { typedef void Type; }; + + +template <class T> +struct ReduceResultType; + +template <class U, class V> +struct ReduceResultType<void(*)(U&,V)> +{ + typedef U ResultType; +}; + +template <class T, class C, class U> +struct ReduceResultType<T(C::*)(U)> +{ + typedef C ResultType; +}; + +template <class InputSequence, class MapFunctor> +struct MapResultType +{ + typedef typename LazyResultType<MapFunctor>::Type ResultType; +}; + +template <class U, class V> +struct MapResultType<void, U (*)(V)> +{ + typedef U ResultType; +}; + +template <class T, class C> +struct MapResultType<void, T(C::*)() const> +{ + typedef T ResultType; +}; + +#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS + +template <template <typename> class InputSequence, typename MapFunctor, typename T> +struct MapResultType<InputSequence<T>, MapFunctor> +{ + typedef InputSequence<typename LazyResultType<MapFunctor>::Type> ResultType; +}; + +template <template <typename> class InputSequence, class T, class U, class V> +struct MapResultType<InputSequence<T>, U (*)(V)> +{ + typedef InputSequence<U> ResultType; +}; + +template <template <typename> class InputSequence, class T, class U, class C> +struct MapResultType<InputSequence<T>, U(C::*)() const> +{ + typedef InputSequence<U> ResultType; +}; + +#endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER + +template <class MapFunctor> +struct MapResultType<QStringList, MapFunctor> +{ + typedef QList<typename LazyResultType<MapFunctor>::Type> ResultType; +}; + +template <class U, class V> +struct MapResultType<QStringList, U (*)(V)> +{ + typedef QList<U> ResultType; +}; + +template <class U, class C> +struct MapResultType<QStringList, U(C::*)() const> +{ + typedef QList<U> ResultType; +}; + +} // namespace QtPrivate. + #endif //qdoc QT_END_NAMESPACE diff --git a/src/corelib/concurrent/qtconcurrentmap.h b/src/corelib/concurrent/qtconcurrentmap.h index 80edf7e..a857ab5 100644 --- a/src/corelib/concurrent/qtconcurrentmap.h +++ b/src/corelib/concurrent/qtconcurrentmap.h @@ -110,38 +110,14 @@ namespace QtConcurrent { template <typename Sequence, typename MapFunctor> QFuture<void> map(Sequence &sequence, MapFunctor map) { - return startMap(sequence.begin(), sequence.end(), map); -} - -template <typename Sequence, typename T, typename U> -QFuture<void> map(Sequence &sequence, T (map)(U)) -{ - return startMap(sequence.begin(), sequence.end(), FunctionWrapper1<T, U>(map)); -} - -template <typename Sequence, typename T, typename C> -QFuture<void> map(Sequence &sequence, T (C::*map)()) -{ - return startMap(sequence.begin(), sequence.end(), MemberFunctionWrapper<T, C>(map)); + return startMap(sequence.begin(), sequence.end(), QtPrivate::createFunctionWrapper(map)); } // map() on iterators template <typename Iterator, typename MapFunctor> QFuture<void> map(Iterator begin, Iterator end, MapFunctor map) { - return startMap(begin, end, map); -} - -template <typename Iterator, typename T, typename U> -QFuture<void> map(Iterator begin, Iterator end, T (map)(U)) -{ - return startMap(begin, end, FunctionWrapper1<T, U>(map)); -} - -template <typename Iterator, typename T, typename C> -QFuture<void> map(Iterator begin, Iterator end, T (C::*map)()) -{ - return startMap(begin, end, MemberFunctionWrapper<T, C>(map)); + return startMap(begin, end, QtPrivate::createFunctionWrapper(map)); } // mappedReduced() for sequences. @@ -151,88 +127,24 @@ QFuture<ResultType> mappedReduced(const Sequence &sequence, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startMappedReduced<typename MapFunctor::result_type, ResultType> - (sequence, map, reduce, options); -} - -template <typename Sequence, typename MapFunctor, typename T, typename U, typename V> -QFuture<U> mappedReduced(const Sequence &sequence, - MapFunctor map, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<typename MapFunctor::result_type, U> - (sequence, map, FunctionWrapper2<T, U &, V>(reduce), options); -} - -template <typename Sequence, typename MapFunctor, typename T, typename C, typename U> -QFuture<C> mappedReduced(const Sequence &sequence, - MapFunctor map, - T (C::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<typename MapFunctor::result_type, C> - (sequence, map, MemberFunctionWrapper1<T, C, U>(reduce), options); -} - -template <typename ResultType, typename Sequence, typename T, typename U, typename ReduceFunctor> -QFuture<ResultType> mappedReduced(const Sequence &sequence, - T (map)(U), - ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<T, ResultType> - (sequence, FunctionWrapper1<T, U>(map), reduce, options); + return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType> + (sequence, + QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), + options); } -template <typename ResultType, typename Sequence, typename T, typename C, typename ReduceFunctor> -QFuture<ResultType> mappedReduced(const Sequence &sequence, - T (C::*map)() const, +template <typename Sequence, typename MapFunctor, typename ReduceFunctor> +QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedReduced(const Sequence &sequence, + MapFunctor map, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startMappedReduced<T, ResultType> - (sequence, ConstMemberFunctionWrapper<T, C>(map), reduce, options); -} - -template <typename Sequence, typename T, typename U, typename V, typename W, typename X> -QFuture<W> mappedReduced(const Sequence &sequence, - T (map)(U), - V (reduce)(W &, X), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<T, W> - (sequence, FunctionWrapper1<T, U>(map), FunctionWrapper2<V, W &, X>(reduce), options); -} - -template <typename Sequence, typename T, typename C, typename U, typename V, typename W> -QFuture<V> mappedReduced(const Sequence &sequence, - T (C::*map)() const, - U (reduce)(V &, W), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<T, V> (sequence, ConstMemberFunctionWrapper<T, C>(map), - FunctionWrapper2<U, V &, W>(reduce), options); -} - -template <typename Sequence, typename T, typename U, typename V, typename C, typename W> -QFuture<C> mappedReduced(const Sequence &sequence, - T (map)(U), - V (C::*reduce)(W), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<T, C> (sequence, FunctionWrapper1<T, U>(map), - MemberFunctionWrapper1<V, C, W>(reduce), options); -} - -template <typename Sequence, typename T, typename C, typename U,typename D, typename V> -QFuture<D> mappedReduced(const Sequence &sequence, - T (C::*map)() const, - U (D::*reduce)(V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<T, D>(sequence, ConstMemberFunctionWrapper<T, C>(map), - MemberFunctionWrapper1<U, D, V>(reduce), options); + return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> + (sequence, + QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), + options); } // mappedReduced() for iterators @@ -243,295 +155,85 @@ QFuture<ResultType> mappedReduced(Iterator begin, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startMappedReduced<ResultType, typename MapFunctor::result_type> - (begin, end, map, reduce, options); -} - -template <typename Iterator, typename MapFunctor, typename T, typename U, typename V> -QFuture<U> mappedReduced(Iterator begin, - Iterator end, - MapFunctor map, - T (reduce)(U &, V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<typename MapFunctor::result_type, U> - (begin, end, map, FunctionWrapper2<T, U &, V>(reduce), options); -} - -template <typename Iterator, typename MapFunctor, typename T, typename C, typename U> -QFuture<C> mappedReduced(Iterator begin, - Iterator end, - MapFunctor map, - T (C::*reduce)(U), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<typename MapFunctor::result_type, C> - (begin, end, map, MemberFunctionWrapper1<T, C, U>(reduce), options); + return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType> + (begin, end, + QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), + options); } -template <typename ResultType, typename Iterator, typename T, typename U, typename ReduceFunctor> -QFuture<ResultType> mappedReduced(Iterator begin, +template <typename Iterator, typename MapFunctor, typename ReduceFunctor> +QFuture<typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> mappedReduced(Iterator begin, Iterator end, - T (map)(U), - ReduceFunctor reduce, - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<T, ResultType> - (begin, end, FunctionWrapper1<T, U>(map), reduce, options); -} - -template <typename ResultType, typename Iterator, typename T, typename C, typename ReduceFunctor> -QFuture<ResultType> mappedReduced(Iterator begin, - Iterator end, - T (C::*map)() const, + MapFunctor map, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return startMappedReduced<T, ResultType> - (begin, end, ConstMemberFunctionWrapper<T, C>(map), reduce, options); -} - -template <typename Iterator, typename T, typename U, typename V, typename W, typename X> -QFuture<W> mappedReduced(Iterator begin, - Iterator end, - T (map)(U), - V (reduce)(W &, X), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<T, W> - (begin, end, FunctionWrapper1<T, U>(map), FunctionWrapper2<V, W &, X>(reduce), options); -} - -template <typename Iterator, typename T, typename C, typename U, typename V, typename W> -QFuture<V> mappedReduced(Iterator begin, - Iterator end, - T (C::*map)() const, - U (reduce)(V &, W), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<T, V>(begin, end, ConstMemberFunctionWrapper<T, C>(map), - FunctionWrapper2<U, V &, W>(reduce), options); -} - -template <typename Iterator, typename T, typename U, typename V, typename C, typename W> -QFuture<C> mappedReduced(Iterator begin, - Iterator end, - T (map)(U), - V (C::*reduce)(W), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<T, C> - (begin, end, FunctionWrapper1<T, U>(map), MemberFunctionWrapper1<V, C, W>(reduce), options); -} - -template <typename Iterator, typename T, typename C, typename U,typename D, typename V> -QFuture<D> mappedReduced(Iterator begin, - Iterator end, - T (C::*map)() const, - U (D::*reduce)(V), - ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) -{ - return startMappedReduced<T, D>(begin, end, ConstMemberFunctionWrapper<T, C>(map), - MemberFunctionWrapper1<U, D, V>(reduce), options); + return startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> + (begin, end, + QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), + options); } // mapped() for sequences template <typename Sequence, typename MapFunctor> -QFuture<typename MapFunctor::result_type> mapped(const Sequence &sequence, MapFunctor map) +QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> mapped(const Sequence &sequence, MapFunctor map) { - return startMapped<typename MapFunctor::result_type>(sequence, map); -} - -template <typename Sequence, typename T, typename U> -QFuture<T> mapped(const Sequence &sequence, T (map)(U)) -{ - return startMapped<T>(sequence, FunctionWrapper1<T, U>(map)); -} - -template <typename Sequence, typename T, typename C> -QFuture<T> mapped(const Sequence &sequence, T (C::*map)() const) -{ - return startMapped<T>(sequence, ConstMemberFunctionWrapper<T, C>(map)); + return startMapped<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType>(sequence, QtPrivate::createFunctionWrapper(map)); } // mapped() for iterator ranges. template <typename Iterator, typename MapFunctor> -QFuture<typename MapFunctor::result_type> mapped(Iterator begin, Iterator end, MapFunctor map) -{ - return startMapped<Q_TYPENAME MapFunctor::result_type>(begin, end, map); -} - -template <typename Iterator, typename T, typename U> -QFuture<T> mapped(Iterator begin, Iterator end, T (map)(U)) +QFuture<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType> mapped(Iterator begin, Iterator end, MapFunctor map) { - return startMapped<T>(begin, end, FunctionWrapper1<T, U>(map)); + return startMapped<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType>(begin, end, QtPrivate::createFunctionWrapper(map)); } -template <typename Iterator, typename T, typename C> -QFuture<T> mapped(Iterator begin, Iterator end, T (C::*map)() const) -{ - return startMapped<T>(begin, end, ConstMemberFunctionWrapper<T, C>(map)); -} - - +// blockingMap() for sequences template <typename Sequence, typename MapFunctor> void blockingMap(Sequence &sequence, MapFunctor map) { - startMap(sequence.begin(), sequence.end(), map).startBlocking(); -} - -template <typename Sequence, typename T, typename U> -void blockingMap(Sequence &sequence, T (map)(U)) -{ - startMap(sequence.begin(), sequence.end(), QtConcurrent::FunctionWrapper1<T, U>(map)).startBlocking(); -} - -template <typename Sequence, typename T, typename C> -void blockingMap(Sequence &sequence, T (C::*map)()) -{ - startMap(sequence.begin(), sequence.end(), QtConcurrent::MemberFunctionWrapper<T, C>(map)).startBlocking(); + startMap(sequence.begin(), sequence.end(), QtPrivate::createFunctionWrapper(map)).startBlocking(); } +// blockingMap() for iterator ranges template <typename Iterator, typename MapFunctor> void blockingMap(Iterator begin, Iterator end, MapFunctor map) { - startMap(begin, end, map).startBlocking(); -} - -template <typename Iterator, typename T, typename U> -void blockingMap(Iterator begin, Iterator end, T (map)(U)) -{ - startMap(begin, end, QtConcurrent::FunctionWrapper1<T, U>(map)).startBlocking(); -} - -template <typename Iterator, typename T, typename C> -void blockingMap(Iterator begin, Iterator end, T (C::*map)()) -{ - startMap(begin, end, QtConcurrent::MemberFunctionWrapper<T, C>(map)).startBlocking(); + startMap(begin, end, QtPrivate::createFunctionWrapper(map)).startBlocking(); } +// blockingMappedReduced() for sequences template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor> ResultType blockingMappedReduced(const Sequence &sequence, MapFunctor map, ReduceFunctor reduce, ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return QtConcurrent::startMappedReduced<typename MapFunctor::result_type, ResultType> - (sequence, map, reduce, options).startBlocking(); -} - -template <typename Sequence, typename MapFunctor, typename T, typename U, typename V> -U blockingMappedReduced(const Sequence &sequence, - MapFunctor map, - T (reduce)(U &, V), - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<typename MapFunctor::result_type, U> - (sequence, - map, - QtConcurrent::FunctionWrapper2<T, U &, V>(reduce), - options) - .startBlocking(); -} - -template <typename Sequence, typename MapFunctor, typename T, typename C, typename U> -C blockingMappedReduced(const Sequence &sequence, - MapFunctor map, - T (C::*reduce)(U), - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<typename MapFunctor::result_type, C> - (sequence, - map, - QtConcurrent::MemberFunctionWrapper1<T, C, U>(reduce), - options) - .startBlocking(); -} - -template <typename ResultType, typename Sequence, typename T, typename U, typename ReduceFunctor> -ResultType blockingMappedReduced(const Sequence &sequence, - T (map)(U), - ReduceFunctor reduce, - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<T, ResultType> + return QtConcurrent::startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType> (sequence, - QtConcurrent::FunctionWrapper1<T, U>(map), - reduce, + QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), options) .startBlocking(); } -template <typename ResultType, typename Sequence, typename T, typename C, typename ReduceFunctor> -ResultType blockingMappedReduced(const Sequence &sequence, - T (C::*map)() const, +template <typename MapFunctor, typename ReduceFunctor, typename Sequence> +typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedReduced(const Sequence &sequence, + MapFunctor map, ReduceFunctor reduce, - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<T, ResultType> - (sequence, - QtConcurrent::ConstMemberFunctionWrapper<T, C>(map), - reduce, - options) - .startBlocking(); -} - -template <typename Sequence, typename T, typename U, typename V, typename W, typename X> -W blockingMappedReduced(const Sequence &sequence, - T (map)(U), - V (reduce)(W &, X), - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<T, W> - (sequence, - QtConcurrent::FunctionWrapper1<T, U>(map), - QtConcurrent::FunctionWrapper2<V, W &, X>(reduce), - options) - .startBlocking(); -} - -template <typename Sequence, typename T, typename C, typename U, typename V, typename W> -V blockingMappedReduced(const Sequence &sequence, - T (C::*map)() const, - U (reduce)(V &, W), - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<T, V> - (sequence, - QtConcurrent::ConstMemberFunctionWrapper<T, C>(map), - QtConcurrent::FunctionWrapper2<U, V &, W>(reduce), - options) - .startBlocking(); -} - -template <typename Sequence, typename T, typename U, typename V, typename C, typename W> -C blockingMappedReduced(const Sequence &sequence, - T (map)(U), - V (C::*reduce)(W), - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<T, C> - (sequence, - QtConcurrent::FunctionWrapper1<T, U>(map), - QtConcurrent::MemberFunctionWrapper1<V, C, W>(reduce), - options) - .startBlocking(); -} - -template <typename Sequence, typename T, typename C, typename U,typename D, typename V> -D blockingMappedReduced(const Sequence &sequence, - T (C::*map)() const, - U (D::*reduce)(V), - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) + ReduceOptions options = ReduceOptions(UnorderedReduce | SequentialReduce)) { - return QtConcurrent::startMappedReduced<T, D> + return QtConcurrent::startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> (sequence, - QtConcurrent::ConstMemberFunctionWrapper<T, C>(map), - QtConcurrent::MemberFunctionWrapper1<U, D, V>(reduce), + QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), options) .startBlocking(); } +// blockingMappedReduced() for iterator ranges template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor> ResultType blockingMappedReduced(Iterator begin, Iterator end, @@ -539,134 +241,25 @@ ResultType blockingMappedReduced(Iterator begin, ReduceFunctor reduce, QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) { - return QtConcurrent::startMappedReduced<typename MapFunctor::result_type, ResultType> - (begin, end, map, reduce, options).startBlocking(); -} - -template <typename Iterator, typename MapFunctor, typename T, typename U, typename V> -U blockingMappedReduced(Iterator begin, - Iterator end, - MapFunctor map, - T (reduce)(U &, V), - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<typename MapFunctor::result_type, U> - (begin, - end, - map, - QtConcurrent::FunctionWrapper2<T, U &, V>(reduce), - options) - .startBlocking(); -} - -template <typename Iterator, typename MapFunctor, typename T, typename C, typename U> -C blockingMappedReduced(Iterator begin, - Iterator end, - MapFunctor map, - T (C::*reduce)(U), - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<typename MapFunctor::result_type, C> - (begin, - end, - map, - QtConcurrent::MemberFunctionWrapper1<T, C, U>(reduce), + return QtConcurrent::startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, ResultType> + (begin, end, + QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), options) .startBlocking(); } -template <typename ResultType, typename Iterator, typename T, typename U, typename ReduceFunctor> -ResultType blockingMappedReduced(Iterator begin, +template <typename Iterator, typename MapFunctor, typename ReduceFunctor> +typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType blockingMappedReduced(Iterator begin, Iterator end, - T (map)(U), - ReduceFunctor reduce, - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<T, ResultType> - (begin, - end, - QtConcurrent::FunctionWrapper1<T, U>(map), - reduce, - options) - .startBlocking(); -} - -template <typename ResultType, typename Iterator, typename T, typename C, typename ReduceFunctor> -ResultType blockingMappedReduced(Iterator begin, - Iterator end, - T (C::*map)() const, + MapFunctor map, ReduceFunctor reduce, QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) { - return QtConcurrent::startMappedReduced<T, ResultType> - (begin, - end, - QtConcurrent::ConstMemberFunctionWrapper<T, C>(map), - reduce, - options) - .startBlocking(); -} - -template <typename Iterator, typename T, typename U, typename V, typename W, typename X> -W blockingMappedReduced(Iterator begin, - Iterator end, - T (map)(U), - V (reduce)(W &, X), - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<T, W> - (begin, - end, - QtConcurrent::FunctionWrapper1<T, U>(map), - QtConcurrent::FunctionWrapper2<V, W &, X>(reduce), - options) - .startBlocking(); -} - -template <typename Iterator, typename T, typename C, typename U, typename V, typename W> -V blockingMappedReduced(Iterator begin, - Iterator end, - T (C::*map)() const, - U (reduce)(V &, W), - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<T, V> - (begin, - end, - QtConcurrent::ConstMemberFunctionWrapper<T, C>(map), - QtConcurrent::FunctionWrapper2<U, V &, W>(reduce), - options) - .startBlocking(); -} - -template <typename Iterator, typename T, typename U, typename V, typename C, typename W> -C blockingMappedReduced(Iterator begin, - Iterator end, - T (map)(U), - V (C::*reduce)(W), - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<T, C> - (begin, - end, - QtConcurrent::FunctionWrapper1<T, U>(map), - QtConcurrent::MemberFunctionWrapper1<V, C, W>(reduce), - options) - .startBlocking(); -} - -template <typename Iterator, typename T, typename C, typename U,typename D, typename V> -D blockingMappedReduced(Iterator begin, - Iterator end, - T (C::*map)() const, - U (D::*reduce)(V), - QtConcurrent::ReduceOptions options = QtConcurrent::ReduceOptions(QtConcurrent::UnorderedReduce | QtConcurrent::SequentialReduce)) -{ - return QtConcurrent::startMappedReduced<T, D> - (begin, - end, - QtConcurrent::ConstMemberFunctionWrapper<T, C>(map), - QtConcurrent::MemberFunctionWrapper1<U, D, V>(reduce), + return QtConcurrent::startMappedReduced<typename QtPrivate::MapResultType<void, MapFunctor>::ResultType, typename QtPrivate::ReduceResultType<ReduceFunctor>::ResultType> + (begin, end, + QtPrivate::createFunctionWrapper(map), + QtPrivate::createFunctionWrapper(reduce), options) .startBlocking(); } @@ -675,97 +268,44 @@ D blockingMappedReduced(Iterator begin, template <typename OutputSequence, typename InputSequence, typename MapFunctor> OutputSequence blockingMapped(const InputSequence &sequence, MapFunctor map) { - return blockingMappedReduced(sequence, map, &OutputSequence::push_back, - QtConcurrent::OrderedReduce); -} - -template <typename OutputSequence, typename InputSequence, typename T, typename U> -OutputSequence blockingMapped(const InputSequence &sequence, T (map)(U)) -{ - return blockingMappedReduced(sequence, map, &OutputSequence::push_back, - QtConcurrent::OrderedReduce); -} - -template <typename OutputSequence, typename InputSequence, typename T, typename C> -OutputSequence blockingMapped(const InputSequence &sequence, T (C::*map)() const) -{ - return blockingMappedReduced(sequence, map, &OutputSequence::push_back, - QtConcurrent::OrderedReduce); -} -#ifndef QT_NO_TEMPLATE_TEMPLATE_PARAMETERS - -// overloads for changing the container value type: -template <template <typename> class Sequence, typename MapFunctor, typename T> -Sequence<typename MapFunctor::result_type> blockingMapped(const Sequence<T> &sequence, MapFunctor map) -{ - typedef Sequence<typename MapFunctor::result_type> OutputSequence; - return blockingMappedReduced(sequence, map, &OutputSequence::push_back, - QtConcurrent::OrderedReduce); -} - -template <template <typename> class Sequence, typename T, typename U, typename V> -Sequence<U> blockingMapped(const Sequence<T> &sequence, U (map)(V)) -{ - typedef Sequence<U> OutputSequence; - return blockingMappedReduced(sequence, map, &OutputSequence::push_back, - QtConcurrent::OrderedReduce); -} - -template <template <typename> class Sequence, typename T, typename U, typename C> -Sequence<U> blockingMapped(const Sequence<T> &sequence, U (C::*map)() const) -{ - typedef Sequence<U> OutputSequence; - return blockingMappedReduced(sequence, map, &OutputSequence::push_back, - QtConcurrent::OrderedReduce); -} - -#endif // QT_NO_TEMPLATE_TEMPLATE_PARAMETER - -// overloads for changing the container value type from a QStringList: -template <typename MapFunctor> -QList<typename MapFunctor::result_type> blockingMapped(const QStringList &sequence, MapFunctor map) -{ - typedef QList<typename MapFunctor::result_type> OutputSequence; - return blockingMappedReduced(sequence, map, &OutputSequence::push_back, - QtConcurrent::OrderedReduce); -} - -template <typename U, typename V> -QList<U> blockingMapped(const QStringList &sequence, U (map)(V)) -{ - typedef QList<U> OutputSequence; - return blockingMappedReduced(sequence, map, &OutputSequence::push_back, - QtConcurrent::OrderedReduce); + return blockingMappedReduced<OutputSequence> + (sequence, + QtPrivate::createFunctionWrapper(map), + &OutputSequence::push_back, + QtConcurrent::OrderedReduce); } -template <typename U, typename C> -QList<U> blockingMapped(const QStringList &sequence, U (C::*map)() const) +template <typename MapFunctor, typename InputSequence> +typename QtPrivate::MapResultType<InputSequence, MapFunctor>::ResultType blockingMapped(const InputSequence &sequence, MapFunctor map) { - typedef QList<U> OutputSequence; - return blockingMappedReduced(sequence, map, &OutputSequence::push_back, - QtConcurrent::OrderedReduce); + typedef typename QtPrivate::MapResultType<InputSequence, MapFunctor>::ResultType OutputSequence; + return blockingMappedReduced<OutputSequence> + (sequence, + QtPrivate::createFunctionWrapper(map), + &OutputSequence::push_back, + QtConcurrent::OrderedReduce); } // mapped() for iterator ranges template <typename Sequence, typename Iterator, typename MapFunctor> Sequence blockingMapped(Iterator begin, Iterator end, MapFunctor map) { - return blockingMappedReduced(begin, end, map, &Sequence::push_back, - QtConcurrent::OrderedReduce); -} - -template <typename Sequence, typename Iterator, typename T, typename U> -Sequence blockingMapped(Iterator begin, Iterator end, T (map)(U)) -{ - return blockingMappedReduced(begin, end, map, &Sequence::push_back, - QtConcurrent::OrderedReduce); + return blockingMappedReduced<Sequence> + (begin, end, + QtPrivate::createFunctionWrapper(map), + &Sequence::push_back, + QtConcurrent::OrderedReduce); } -template <typename Sequence, typename Iterator, typename T, typename C> -Sequence blockingMapped(Iterator begin, Iterator end, T (C::*map)() const) -{ - return blockingMappedReduced(begin, end, map, &Sequence::push_back, - QtConcurrent::OrderedReduce); +template <typename Iterator, typename MapFunctor> +typename QtPrivate::MapResultType<Iterator, MapFunctor>::ResultType blockingMapped(Iterator begin, Iterator end, MapFunctor map) +{ + typedef typename QtPrivate::MapResultType<Iterator, MapFunctor>::ResultType OutputSequence; + return blockingMappedReduced<OutputSequence> + (begin, end, + QtPrivate::createFunctionWrapper(map), + &OutputSequence::push_back, + QtConcurrent::OrderedReduce); } } // namespace QtConcurrent diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 9434eb2..3e1f011 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2545,6 +2545,16 @@ QT3_SUPPORT Q_CORE_EXPORT const char *qInstallPathSysconf(); //Symbian does not support data imports from a DLL #define Q_NO_DATA_RELOCATION +// Winscw compiler is unable to compile QtConcurrent. +#ifdef Q_CC_NOKIAX86 +#ifndef QT_NO_CONCURRENT +#define QT_NO_CONCURRENT +#endif +#ifndef QT_NO_QFUTURE +#define QT_NO_QFUTURE +#endif +#endif + QT_END_NAMESPACE // forward declare std::exception #ifdef __cplusplus @@ -2755,7 +2765,8 @@ QT_LICENSED_MODULE(DBus) #if !(defined(Q_WS_WIN) && !defined(Q_WS_WINCE)) \ && !(defined(Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) \ - && !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE)) + && !(defined(Q_WS_X11) && !defined(QT_NO_FREETYPE)) \ + && !(defined(Q_WS_QPA)) # define QT_NO_RAWFONT #endif diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index aca1cb1..005e90a 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -450,10 +450,11 @@ QLibraryInfo::location(LibraryLocation loc) } if (QDir::isRelativePath(ret)) { + QString baseDir; if (loc == PrefixPath) { // we make the prefix path absolute to the executable's directory #ifdef BOOTSTRAPPING - return QFileInfo(qmake_libraryInfoFile()).absolutePath(); + baseDir = QFileInfo(qmake_libraryInfoFile()).absolutePath(); #else if (QCoreApplication::instance()) { #ifdef Q_OS_MAC @@ -466,15 +467,16 @@ QLibraryInfo::location(LibraryLocation loc) } } #endif - return QDir(QCoreApplication::applicationDirPath()).absoluteFilePath(ret); + baseDir = QCoreApplication::applicationDirPath(); } else { - return QDir::current().absoluteFilePath(ret); + baseDir = QDir::currentPath(); } #endif } else { // we make any other path absolute to the prefix directory - return QDir(location(PrefixPath)).absoluteFilePath(ret); + baseDir = location(PrefixPath); } + ret = QDir::cleanPath(baseDir + QLatin1Char('/') + ret); } return ret; } diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index 75ce68a..f086513 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -94,6 +94,7 @@ Qt { Q_ENUMS(GestureState) Q_ENUMS(GestureType) #endif + Q_ENUMS(CursorMoveStyle) #endif // (defined(Q_MOC_RUN) || defined(QT_JAMBI_RUN)) #if defined(Q_MOC_RUN) @@ -1784,6 +1785,11 @@ public: NavigationModeCursorAuto, NavigationModeCursorForceVisible }; + + enum CursorMoveStyle { + LogicalMoveStyle, + VisualMoveStyle + }; } #ifdef Q_MOC_RUN ; diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index c9ebaa4..030b845 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -356,6 +356,7 @@ bool QFileSystemEngine::fillMetaData(const QFileSystemEntry &entry, QFileSystemM const QByteArray &path = entry.nativeFilePath(); nativeFilePath = path.constData(); nativeFilePathLength = path.size(); + Q_UNUSED(nativeFilePathLength); } bool entryExists = true; // innocent until proven otherwise @@ -638,7 +639,7 @@ QFileSystemEntry QFileSystemEngine::currentPath() #if defined(__GLIBC__) && !defined(PATH_MAX) char *currentName = ::get_current_dir_name(); if (currentName) { - result = QFile::decodeName(QByteArray(currentName)); + result = QFileSystemEntry(QByteArray(currentName), QFileSystemEntry::FromNativePath()); ::free(currentName); } #else diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index 82c6eba..1dbc40f 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -583,6 +583,7 @@ QString QFileSystemEngine::owner(const QFileSystemEntry &entry, QAbstractFileEng } } #else + Q_UNUSED(entry); Q_UNUSED(own); #endif return name; diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index a45225f..c2234e9 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -143,55 +143,13 @@ QT_BEGIN_NAMESPACE \sa QProcess, QProcess::systemEnvironment(), QProcess::setProcessEnvironment() */ -#ifdef Q_OS_WIN -static inline QProcessEnvironmentPrivate::Unit prepareName(const QString &name) -{ return name.toUpper(); } -static inline QProcessEnvironmentPrivate::Unit prepareName(const QByteArray &name) -{ return QString::fromLocal8Bit(name).toUpper(); } -static inline QString nameToString(const QProcessEnvironmentPrivate::Unit &name) -{ return name; } -static inline QProcessEnvironmentPrivate::Unit prepareValue(const QString &value) -{ return value; } -static inline QProcessEnvironmentPrivate::Unit prepareValue(const QByteArray &value) -{ return QString::fromLocal8Bit(value); } -static inline QString valueToString(const QProcessEnvironmentPrivate::Unit &value) -{ return value; } -static inline QByteArray valueToByteArray(const QProcessEnvironmentPrivate::Unit &value) -{ return value.toLocal8Bit(); } -#else -static inline QProcessEnvironmentPrivate::Unit prepareName(const QByteArray &name) -{ return name; } -static inline QProcessEnvironmentPrivate::Unit prepareName(const QString &name) -{ return name.toLocal8Bit(); } -static inline QString nameToString(const QProcessEnvironmentPrivate::Unit &name) -{ return QString::fromLocal8Bit(name); } -static inline QProcessEnvironmentPrivate::Unit prepareValue(const QByteArray &value) -{ return value; } -static inline QProcessEnvironmentPrivate::Unit prepareValue(const QString &value) -{ return value.toLocal8Bit(); } -static inline QString valueToString(const QProcessEnvironmentPrivate::Unit &value) -{ return QString::fromLocal8Bit(value); } -static inline QByteArray valueToByteArray(const QProcessEnvironmentPrivate::Unit &value) -{ return value; } -#endif - -template<> void QSharedDataPointer<QProcessEnvironmentPrivate>::detach() -{ - if (d && d->ref == 1) - return; - QProcessEnvironmentPrivate *x = (d ? new QProcessEnvironmentPrivate(*d) - : new QProcessEnvironmentPrivate); - x->ref.ref(); - if (d && !d->ref.deref()) - delete d; - d = x; -} QStringList QProcessEnvironmentPrivate::toList() const { QStringList result; - QHash<Unit, Unit>::ConstIterator it = hash.constBegin(), - end = hash.constEnd(); + result.reserve(hash.size()); + Hash::ConstIterator it = hash.constBegin(), + end = hash.constEnd(); for ( ; it != end; ++it) { QString data = nameToString(it.key()); QString value = valueToString(it.value()); @@ -224,19 +182,27 @@ QProcessEnvironment QProcessEnvironmentPrivate::fromList(const QStringList &list QStringList QProcessEnvironmentPrivate::keys() const { QStringList result; - QHash<Unit, Unit>::ConstIterator it = hash.constBegin(), - end = hash.constEnd(); + result.reserve(hash.size()); + Hash::ConstIterator it = hash.constBegin(), + end = hash.constEnd(); for ( ; it != end; ++it) result << nameToString(it.key()); return result; } -void QProcessEnvironmentPrivate::insert(const Hash &h) +void QProcessEnvironmentPrivate::insert(const QProcessEnvironmentPrivate &other) { - QHash<Unit, Unit>::ConstIterator it = h.constBegin(), - end = h.constEnd(); + Hash::ConstIterator it = other.hash.constBegin(), + end = other.hash.constEnd(); for ( ; it != end; ++it) hash.insert(it.key(), it.value()); + +#ifdef Q_OS_UNIX + QHash<QString, Key>::ConstIterator nit = other.nameMap.constBegin(), + nend = other.nameMap.constEnd(); + for ( ; nit != nend; ++nit) + nameMap.insert(nit.key(), nit.value()); +#endif } /*! @@ -317,6 +283,8 @@ void QProcessEnvironment::clear() { if (d) d->hash.clear(); + // Unix: Don't clear d->nameMap, as the environment is likely to be + // re-populated with the same keys again. } /*! @@ -331,7 +299,7 @@ void QProcessEnvironment::clear() */ bool QProcessEnvironment::contains(const QString &name) const { - return d ? d->hash.contains(prepareName(name)) : false; + return d ? d->hash.contains(d->prepareName(name)) : false; } /*! @@ -353,7 +321,7 @@ bool QProcessEnvironment::contains(const QString &name) const void QProcessEnvironment::insert(const QString &name, const QString &value) { // d detaches from null - d->hash.insert(prepareName(name), prepareValue(value)); + d->hash.insert(d->prepareName(name), d->prepareValue(value)); } /*! @@ -370,7 +338,7 @@ void QProcessEnvironment::insert(const QString &name, const QString &value) void QProcessEnvironment::remove(const QString &name) { if (d) - d->hash.remove(prepareName(name)); + d->hash.remove(d->prepareName(name)); } /*! @@ -389,11 +357,11 @@ QString QProcessEnvironment::value(const QString &name, const QString &defaultVa if (!d) return defaultValue; - QProcessEnvironmentPrivate::Hash::ConstIterator it = d->hash.constFind(prepareName(name)); + QProcessEnvironmentPrivate::Hash::ConstIterator it = d->hash.constFind(d->prepareName(name)); if (it == d->hash.constEnd()) return defaultValue; - return valueToString(it.value()); + return d->valueToString(it.value()); } /*! @@ -438,7 +406,7 @@ void QProcessEnvironment::insert(const QProcessEnvironment &e) return; // d detaches from null - d->insert(e.d->hash); + d->insert(*e.d); } void QProcessPrivate::Channel::clear() @@ -2321,6 +2289,8 @@ QStringList QProcess::systemEnvironment() } /*! + \fn QProcessEnvironment QProcessEnvironment::systemEnvironment() + \since 4.6 \brief The systemEnvironment function returns the environment of @@ -2336,21 +2306,6 @@ QStringList QProcess::systemEnvironment() \sa QProcess::systemEnvironment() */ -QProcessEnvironment QProcessEnvironment::systemEnvironment() -{ - QProcessEnvironment env; - const char *entry; - for (int count = 0; (entry = environ[count]); ++count) { - const char *equal = strchr(entry, '='); - if (!equal) - continue; - - QByteArray name(entry, equal - entry); - QByteArray value(equal + 1); - env.insert(QString::fromLocal8Bit(name), QString::fromLocal8Bit(value)); - } - return env; -} /*! \typedef Q_PID diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h index 7bfcb31..54d4936 100644 --- a/src/corelib/io/qprocess_p.h +++ b/src/corelib/io/qprocess_p.h @@ -81,23 +81,119 @@ class QTimer; class RProcess; #endif +#ifdef Q_OS_WIN +class QProcEnvKey : public QString +{ +public: + QProcEnvKey() {} + explicit QProcEnvKey(const QString &other) : QString(other) {} + QProcEnvKey(const QProcEnvKey &other) : QString(other) {} + bool operator==(const QProcEnvKey &other) const { return !compare(other, Qt::CaseInsensitive); } +}; +inline uint qHash(const QProcEnvKey &key) { return qHash(key.toCaseFolded()); } + +typedef QString QProcEnvValue; +#else +class QProcEnvKey +{ +public: + QProcEnvKey() : hash(0) {} + explicit QProcEnvKey(const QByteArray &other) : key(other), hash(qHash(key)) {} + QProcEnvKey(const QProcEnvKey &other) { *this = other; } + bool operator==(const QProcEnvKey &other) const { return key == other.key; } + + QByteArray key; + uint hash; +}; +inline uint qHash(const QProcEnvKey &key) { return key.hash; } + +class QProcEnvValue +{ +public: + QProcEnvValue() {} + QProcEnvValue(const QProcEnvValue &other) { *this = other; } + explicit QProcEnvValue(const QString &value) : stringValue(value) {} + explicit QProcEnvValue(const QByteArray &value) : byteValue(value) {} + bool operator==(const QProcEnvValue &other) const + { + return byteValue.isEmpty() && other.byteValue.isEmpty() + ? stringValue == other.stringValue + : bytes() == other.bytes(); + } + QByteArray bytes() const + { + if (byteValue.isEmpty() && !stringValue.isEmpty()) + byteValue = stringValue.toLocal8Bit(); + return byteValue; + } + QString string() const + { + if (stringValue.isEmpty() && !byteValue.isEmpty()) + stringValue = QString::fromLocal8Bit(byteValue); + return stringValue; + } + + mutable QByteArray byteValue; + mutable QString stringValue; +}; +Q_DECLARE_TYPEINFO(QProcEnvValue, Q_MOVABLE_TYPE); +#endif +Q_DECLARE_TYPEINFO(QProcEnvKey, Q_MOVABLE_TYPE); + class QProcessEnvironmentPrivate: public QSharedData { public: + typedef QProcEnvKey Key; + typedef QProcEnvValue Value; #ifdef Q_OS_WIN - typedef QString Unit; + inline Key prepareName(const QString &name) const { return Key(name); } + inline QString nameToString(const Key &name) const { return name; } + inline Value prepareValue(const QString &value) const { return value; } + inline QString valueToString(const Value &value) const { return value; } #else - typedef QByteArray Unit; + inline Key prepareName(const QString &name) const + { + Key &ent = nameMap[name]; + if (ent.key.isEmpty()) + ent = Key(name.toLocal8Bit()); + return ent; + } + inline QString nameToString(const Key &name) const + { + const QString sname = QString::fromLocal8Bit(name.key); + nameMap[sname] = name; + return sname; + } + inline Value prepareValue(const QString &value) const { return Value(value); } + inline QString valueToString(const Value &value) const { return value.string(); } #endif - typedef QHash<Unit, Unit> Hash; + + typedef QHash<Key, Value> Hash; Hash hash; +#ifdef Q_OS_UNIX + typedef QHash<QString, Key> NameHash; + mutable NameHash nameMap; +#endif + static QProcessEnvironment fromList(const QStringList &list); QStringList toList() const; QStringList keys() const; - void insert(const Hash &hash); + void insert(const QProcessEnvironmentPrivate &other); }; +template<> Q_INLINE_TEMPLATE void QSharedDataPointer<QProcessEnvironmentPrivate>::detach() +{ + if (d && d->ref == 1) + return; + QProcessEnvironmentPrivate *x = (d ? new QProcessEnvironmentPrivate(*d) + : new QProcessEnvironmentPrivate); + x->ref.ref(); + if (d && !d->ref.deref()) + delete d; + d = x; +} + class QProcessPrivate : public QIODevicePrivate { public: diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp index 8a74c7b..2ce7a00 100644 --- a/src/corelib/io/qprocess_symbian.cpp +++ b/src/corelib/io/qprocess_symbian.cpp @@ -1062,6 +1062,11 @@ void QProcessPrivate::initializeProcessManager() (void) processManager(); } +QProcessEnvironment QProcessEnvironment::systemEnvironment() +{ + return QProcessEnvironment(); +} + QT_END_NAMESPACE #endif // QT_NO_PROCESS diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 3af9b46..5616d39 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -453,7 +453,35 @@ bool QProcessPrivate::createChannel(Channel &channel) } } -static char **_q_dupEnvironment(const QHash<QByteArray, QByteArray> &environment, int *envc) +QT_BEGIN_INCLUDE_NAMESPACE +#if defined(Q_OS_MAC) && !defined(QT_NO_CORESERVICES) +# include <crt_externs.h> +# define environ (*_NSGetEnviron()) +#else + extern char **environ; +#endif +QT_END_INCLUDE_NAMESPACE + +QProcessEnvironment QProcessEnvironment::systemEnvironment() +{ + QProcessEnvironment env; +#if !defined(Q_OS_MAC) || !defined(QT_NO_CORESERVICES) + const char *entry; + for (int count = 0; (entry = environ[count]); ++count) { + const char *equal = strchr(entry, '='); + if (!equal) + continue; + + QByteArray name(entry, equal - entry); + QByteArray value(equal + 1); + env.d->hash.insert(QProcessEnvironmentPrivate::Key(name), + QProcessEnvironmentPrivate::Value(value)); + } +#endif + return env; +} + +static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Hash &environment, int *envc) { *envc = 0; if (environment.isEmpty()) @@ -469,17 +497,17 @@ static char **_q_dupEnvironment(const QHash<QByteArray, QByteArray> &environment #endif const QByteArray envLibraryPath = qgetenv(libraryPath); bool needToAddLibraryPath = !envLibraryPath.isEmpty() && - !environment.contains(libraryPath); + !environment.contains(QProcessEnvironmentPrivate::Key(QByteArray(libraryPath))); char **envp = new char *[environment.count() + 2]; envp[environment.count()] = 0; envp[environment.count() + 1] = 0; - QHash<QByteArray, QByteArray>::ConstIterator it = environment.constBegin(); - const QHash<QByteArray, QByteArray>::ConstIterator end = environment.constEnd(); + QProcessEnvironmentPrivate::Hash::ConstIterator it = environment.constBegin(); + const QProcessEnvironmentPrivate::Hash::ConstIterator end = environment.constEnd(); for ( ; it != end; ++it) { - QByteArray key = it.key(); - QByteArray value = it.value(); + QByteArray key = it.key().key; + QByteArray value = it.value().bytes(); key.reserve(key.length() + 1 + value.length()); key.append('='); key.append(value); diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 625ed98..bb23954 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -278,29 +278,55 @@ static QString qt_create_commandline(const QString &program, const QStringList & return args; } -static QByteArray qt_create_environment(const QHash<QString, QString> &environment) +QProcessEnvironment QProcessEnvironment::systemEnvironment() +{ + QProcessEnvironment env; +#if !defined(Q_OS_WINCE) + // Calls to setenv() affect the low-level environment as well. + // This is not the case the other way round. + if (wchar_t *envStrings = GetEnvironmentStringsW()) { + for (const wchar_t *entry = envStrings; *entry; ) { + int entryLen = wcslen(entry); + if (const wchar_t *equal = wcschr(entry, L'=')) { + int nameLen = equal - entry; + QString name = QString::fromWCharArray(entry, nameLen); + QString value = QString::fromWCharArray(equal + 1, entryLen - nameLen - 1); + env.d->hash.insert(QProcessEnvironmentPrivate::Key(name), value); + } + entry += entryLen + 1; + } + FreeEnvironmentStringsW(envStrings); + } +#endif + return env; +} + +#if !defined(Q_OS_WINCE) +static QByteArray qt_create_environment(const QProcessEnvironmentPrivate::Hash &environment) { QByteArray envlist; if (!environment.isEmpty()) { - QHash<QString, QString> copy = environment; + QProcessEnvironmentPrivate::Hash copy = environment; // add PATH if necessary (for DLL loading) - if (!copy.contains(QLatin1String("PATH"))) { + QProcessEnvironmentPrivate::Key pathKey(QLatin1String("PATH")); + if (!copy.contains(pathKey)) { QByteArray path = qgetenv("PATH"); if (!path.isEmpty()) - copy.insert(QLatin1String("PATH"), QString::fromLocal8Bit(path)); + copy.insert(pathKey, QString::fromLocal8Bit(path)); } // add systemroot if needed - if (!copy.contains(QLatin1String("SYSTEMROOT"))) { - QByteArray systemRoot = qgetenv("SYSTEMROOT"); + QProcessEnvironmentPrivate::Key rootKey(QLatin1String("SystemRoot")); + if (!copy.contains(rootKey)) { + QByteArray systemRoot = qgetenv("SystemRoot"); if (!systemRoot.isEmpty()) - copy.insert(QLatin1String("SYSTEMROOT"), QString::fromLocal8Bit(systemRoot)); + copy.insert(rootKey, QString::fromLocal8Bit(systemRoot)); } int pos = 0; - QHash<QString, QString>::ConstIterator it = copy.constBegin(), - end = copy.constEnd(); + QProcessEnvironmentPrivate::Hash::ConstIterator it = copy.constBegin(), + end = copy.constEnd(); static const wchar_t equal = L'='; static const wchar_t nul = L'\0'; @@ -335,6 +361,7 @@ static QByteArray qt_create_environment(const QHash<QString, QString> &environme } return envlist; } +#endif void QProcessPrivate::startProcess() { diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index b084ca5..f43fb31 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -981,23 +981,6 @@ QStringList QSettingsPrivate::splitArgs(const QString &s, int idx) // ************************************************************************ // QConfFileSettingsPrivate -/* - If we don't have the permission to read the file, returns false. - If the file doesn't exist, returns true. -*/ -static bool checkAccess(const QString &name) -{ - QFileInfo fileInfo(name); - - if (fileInfo.exists()) { - QFile file(name); - // if the file exists but we can't open it, report an error - return file.open(QFile::ReadOnly); - } else { - return true; - } -} - void QConfFileSettingsPrivate::initFormat() { extension = (format == QSettings::NativeFormat) ? QLatin1String(".conf") : QLatin1String(".ini"); @@ -1026,18 +1009,13 @@ void QConfFileSettingsPrivate::initFormat() void QConfFileSettingsPrivate::initAccess() { - bool readAccess = false; if (confFiles[spec]) { - readAccess = checkAccess(confFiles[spec]->name); if (format > QSettings::IniFormat) { if (!readFunc) - readAccess = false; + setStatus(QSettings::AccessError); } } - if (!readAccess) - setStatus(QSettings::AccessError); - sync(); // loads the files the first time } @@ -1432,7 +1410,7 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo) We can often optimize the read-only case, if the file on disk hasn't changed. */ - if (readOnly) { + if (readOnly && confFile->size > 0) { QFileInfo fileInfo(confFile->name); if (confFile->size == fileInfo.size() && confFile->timeStamp == fileInfo.lastModified()) return; @@ -1455,6 +1433,9 @@ void QConfFileSettingsPrivate::syncConfFile(int confFileNo) if (!file.isOpen()) file.open(QFile::ReadOnly); + if (!createFile && !file.isOpen()) + setStatus(QSettings::AccessError); + #ifdef Q_OS_WIN HANDLE readSemaphore = 0; HANDLE writeSemaphore = 0; diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index be86c58..c0b1748 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -270,6 +270,17 @@ bool QCoreApplicationPrivate::is_app_closing = false; Q_CORE_EXPORT bool qt_locale_initialized = false; +/* + Create an instance of Trolltech.conf. This ensures that the settings will not + be thrown out of QSetting's cache for unused settings. + */ +Q_GLOBAL_STATIC_WITH_ARGS(QSettings, staticTrolltechConf, (QSettings::UserScope, QLatin1String("Trolltech"))) + +QSettings *QCoreApplicationPrivate::trolltechConf() +{ + return staticTrolltechConf(); +} + Q_CORE_EXPORT uint qGlobalPostedEventsCount() { QThreadData *currentThreadData = QThreadData::current(); diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h index add2a35..eb46ae5 100644 --- a/src/corelib/kernel/qcoreapplication_p.h +++ b/src/corelib/kernel/qcoreapplication_p.h @@ -55,6 +55,7 @@ #include "QtCore/qcoreapplication.h" #include "QtCore/qtranslator.h" +#include "QtCore/qsettings.h" #include "private/qobject_p.h" #ifdef Q_OS_SYMBIAN @@ -139,6 +140,7 @@ public: #if defined(QT3_SUPPORT) static bool useQt3Support; #endif + static QSettings *trolltechConf(); }; QT_END_NAMESPACE diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp index fbb08fa..a8cf5f1 100644 --- a/src/corelib/kernel/qcoreevent.cpp +++ b/src/corelib/kernel/qcoreevent.cpp @@ -231,8 +231,6 @@ QT_BEGIN_NAMESPACE \value WinIdChange The window system identifer for this native widget has changed \value Gesture A gesture was triggered (QGestureEvent) \value GestureOverride A gesture override was triggered (QGestureEvent) - \value ScrollPrepare The object needs to fill in its geometry information (QScrollPrepareEvent) - \value Scroll The object needs to scroll to the supplied position (QScrollEvent) 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 c9d311a..c151c5e 100644 --- a/src/corelib/kernel/qcoreevent.h +++ b/src/corelib/kernel/qcoreevent.h @@ -288,9 +288,6 @@ public: Gesture = 198, GestureOverride = 202, #endif - ScrollPrepare = 204, - Scroll = 205, - // 512 reserved for Qt Jambi's MetaCall event // 513 reserved for Qt Jambi's DeleteOnMainThread event diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index e0eeb08..bd12726 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -1111,6 +1111,12 @@ bool QEventDispatcherSymbian::hasPendingEvents() void QEventDispatcherSymbian::registerSocketNotifier ( QSocketNotifier * notifier ) { + //check socket descriptor is usable + if (notifier->socket() >= FD_SETSIZE || notifier->socket() < 0) { + //same warning message as the unix event dispatcher for easy testing + qWarning("QSocketNotifier: Internal error"); + return; + } //note - this is only for "open C" file descriptors //for native sockets, an active object in the symbian socket engine handles this QSocketActiveObject *socketAO = new QSocketActiveObject(this, notifier); diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 80e927b..d9aac00 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -52,6 +52,7 @@ #include <qmap.h> #include <qsettings.h> #include <qdatetime.h> +#include <private/qcoreapplication_p.h> #ifdef Q_OS_MAC # include <private/qcore_mac_p.h> #endif @@ -408,12 +409,6 @@ static bool qt_unix_query(const QString &library, uint *version, bool *debug, QB typedef QMap<QString, QLibraryPrivate*> LibraryMap; struct LibraryData { - LibraryData() : settings(0) { } - ~LibraryData() { - delete settings; - } - - QSettings *settings; LibraryMap libraryMap; QSet<QLibraryPrivate*> loadedLibs; }; @@ -711,11 +706,7 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) QStringList reg; #ifndef QT_NO_SETTINGS if (!settings) { - settings = libraryData()->settings; - if (!settings) { - settings = new QSettings(QSettings::UserScope, QLatin1String("Trolltech")); - libraryData()->settings = settings; - } + settings = QCoreApplicationPrivate::trolltechConf(); } reg = settings->value(regkey).toStringList(); #endif diff --git a/src/corelib/thread/qmutex_unix.cpp b/src/corelib/thread/qmutex_unix.cpp index 11e2060..b584ae5 100644 --- a/src/corelib/thread/qmutex_unix.cpp +++ b/src/corelib/thread/qmutex_unix.cpp @@ -107,18 +107,21 @@ bool QMutexPrivate::wait(int timeout) // lock acquired without waiting return true; } - bool returnValue; + kern_return_t r; if (timeout < 0) { - returnValue = semaphore_wait(mach_semaphore) == KERN_SUCCESS; + do { + r = semaphore_wait(mach_semaphore); + } while (r == KERN_ABORTED); + if (r != KERN_SUCCESS) + qWarning("QMutex: infinite wait failed, error %d", r); } else { mach_timespec_t ts; ts.tv_nsec = ((timeout % 1000) * 1000) * 1000; ts.tv_sec = (timeout / 1000); - kern_return_t r = semaphore_timedwait(mach_semaphore, ts); - returnValue = r == KERN_SUCCESS; + r = semaphore_timedwait(mach_semaphore, ts); } contenders.deref(); - return returnValue; + return r == KERN_SUCCESS; } void QMutexPrivate::wakeUp() diff --git a/src/corelib/thread/qthread_symbian.cpp b/src/corelib/thread/qthread_symbian.cpp index 5d8b5cb..665aadd 100644 --- a/src/corelib/thread/qthread_symbian.cpp +++ b/src/corelib/thread/qthread_symbian.cpp @@ -329,6 +329,8 @@ void *QThreadPrivate::start(void *arg) data->quitNow = thr->d_func()->exited; } + CTrapCleanup *cleanup = CTrapCleanup::New(); + // ### TODO: allow the user to create a custom event dispatcher createEventDispatcher(data); @@ -337,6 +339,8 @@ void *QThreadPrivate::start(void *arg) QThreadPrivate::finish(arg); + delete cleanup; + return 0; } diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 0627b4e..df58d95 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -57,9 +57,10 @@ # ifdef QT_USE_FAST_OPERATOR_PLUS # undef QT_USE_FAST_OPERATOR_PLUS # endif -# ifdef QT_USE_FAST_CONCATENATION -# undef QT_USE_FAST_CONCATENATION +# ifdef QT_USE_QSTRINGBUILDER +# undef QT_USE_QSTRINGBUILDER # endif + #endif @@ -559,8 +560,7 @@ inline bool operator>=(const QByteArray &a1, const char *a2) { return qstrcmp(a1, a2) >= 0; } inline bool operator>=(const char *a1, const QByteArray &a2) { return qstrcmp(a1, a2) >= 0; } -#ifndef QT_USE_FAST_OPERATOR_PLUS -# ifndef QT_USE_FAST_CONCATENATION +#if !defined(QT_USE_QSTRINGBUILDER) inline const QByteArray operator+(const QByteArray &a1, const QByteArray &a2) { return QByteArray(a1) += a2; } inline const QByteArray operator+(const QByteArray &a1, const char *a2) @@ -571,8 +571,7 @@ inline const QByteArray operator+(const char *a1, const QByteArray &a2) { return QByteArray(a1) += a2; } inline const QByteArray operator+(char a1, const QByteArray &a2) { return QByteArray(&a1, 1) += a2; } -# endif // QT_USE_FAST_CONCATENATION -#endif // QT_USE_FAST_OPERATOR_PLUS +#endif // QT_USE_QSTRINGBUILDER inline QBool QByteArray::contains(const char *c) const { return QBool(indexOf(c) != -1); } inline QByteArray &QByteArray::replace(char before, const char *c) @@ -615,7 +614,7 @@ QT_END_NAMESPACE QT_END_HEADER -#ifdef QT_USE_FAST_CONCATENATION +#ifdef QT_USE_QSTRINGBUILDER #include <QtCore/qstring.h> #endif diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index a3a8884..d9a054a 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2460,7 +2460,11 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC) If the \a format is Qt::ISODate, the string format corresponds to the ISO 8601 extended specification for representations of - dates and times, taking the form YYYY-MM-DDTHH:MM:SS. + dates and times, taking the form YYYY-MM-DDTHH:MM:SS[Z|[+|-]HH:MM], + depending on the timeSpec() of the QDateTime. If the timeSpec() + is Qt::UTC, Z will be appended to the string; if the timeSpec() is + Qt::OffsetFromUTC the offset in hours and minutes from UTC will + be appended to the string. If the \a format is Qt::SystemLocaleShortDate or Qt::SystemLocaleLongDate, the string format depends on the locale @@ -2497,6 +2501,21 @@ QString QDateTime::toString(Qt::DateFormat f) const return QString(); // failed to convert buf += QLatin1Char('T'); buf += d->time.toString(Qt::ISODate); + switch (d->spec) { + case QDateTimePrivate::UTC: + buf += QLatin1Char('Z'); + break; + case QDateTimePrivate::OffsetFromUTC: { + int sign = d->utcOffset >= 0 ? 1: -1; + buf += QString::fromLatin1("%1%2:%3"). + arg(sign == 1 ? QLatin1Char('+') : QLatin1Char('-')). + arg(d->utcOffset * sign / SECS_PER_HOUR, 2, 10, QLatin1Char('0')). + arg((d->utcOffset / 60) % 60, 2, 10, QLatin1Char('0')); + break; + } + default: + break; + } } #ifndef QT_NO_TEXTDATE else if (f == Qt::TextDate) { diff --git a/src/corelib/tools/qelapsedtimer_symbian.cpp b/src/corelib/tools/qelapsedtimer_symbian.cpp index b831e03..3667b05 100644 --- a/src/corelib/tools/qelapsedtimer_symbian.cpp +++ b/src/corelib/tools/qelapsedtimer_symbian.cpp @@ -95,7 +95,7 @@ qint64 QElapsedTimer::restart() qint64 oldt1 = t1; t1 = getMicrosecondFromTick(); t2 = 0; - return t1 - oldt1; + return (t1 - oldt1) / 1000; } qint64 QElapsedTimer::nsecsElapsed() const diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 5c4085a..c8ed94b 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -2782,8 +2782,6 @@ bool QLocalePrivate::numberToCLocale(const QString &num, if (idx == l) return false; - const QChar _group = group(); - while (idx < l) { const QChar &in = uc[idx]; diff --git a/src/corelib/tools/qlocale_symbian.cpp b/src/corelib/tools/qlocale_symbian.cpp index 09d74d0..5dca7b7 100644 --- a/src/corelib/tools/qlocale_symbian.cpp +++ b/src/corelib/tools/qlocale_symbian.cpp @@ -44,6 +44,7 @@ #include <QTime> #include <QVariant> #include <QThread> +#include <QStringList> #include <e32std.h> #include <e32const.h> @@ -86,6 +87,7 @@ static TPtrC defaultFormatSpec(TExtendedLocale&) struct symbianToISO { int symbian_language; char iso_name[8]; + char uilanguage[8]; }; @@ -94,77 +96,80 @@ struct symbianToISO { NOTE: This array should be sorted by the first column! */ static const symbianToISO symbian_to_iso_list[] = { - { ELangEnglish, "en_GB" }, // 1 - { ELangFrench, "fr_FR" }, // 2 - { ELangGerman, "de_DE" }, // 3 - { ELangSpanish, "es_ES" }, // 4 - { ELangItalian, "it_IT" }, // 5 - { ELangSwedish, "sv_SE" }, // 6 - { ELangDanish, "da_DK" }, // 7 - { ELangNorwegian, "no_NO" }, // 8 - { ELangFinnish, "fi_FI" }, // 9 - { ELangAmerican, "en_US" }, // 10 - { ELangPortuguese, "pt_PT" }, // 13 - { ELangTurkish, "tr_TR" }, // 14 - { ELangIcelandic, "is_IS" }, // 15 - { ELangRussian, "ru_RU" }, // 16 - { ELangHungarian, "hu_HU" }, // 17 - { ELangDutch, "nl_NL" }, // 18 - { ELangBelgianFlemish, "nl_BE" }, // 19 - { ELangCzech, "cs_CZ" }, // 25 - { ELangSlovak, "sk_SK" }, // 26 - { ELangPolish, "pl_PL" }, // 27 - { ELangSlovenian, "sl_SI" }, // 28 - { ELangTaiwanChinese, "zh_TW" }, // 29 - { ELangHongKongChinese, "zh_HK" }, // 30 - { ELangPrcChinese, "zh_CN" }, // 31 - { ELangJapanese, "ja_JP" }, // 32 - { ELangThai, "th_TH" }, // 33 - { ELangArabic, "ar_AE" }, // 37 - { ELangTagalog, "tl_PH" }, // 39 - { ELangBulgarian, "bg_BG" }, // 42 - { ELangCatalan, "ca_ES" }, // 44 - { ELangCroatian, "hr_HR" }, // 45 - { ELangEstonian, "et_EE" }, // 49 - { ELangFarsi, "fa_IR" }, // 50 - { ELangCanadianFrench, "fr_CA" }, // 51 - { ELangGreek, "el_GR" }, // 54 - { ELangHebrew, "he_IL" }, // 57 - { ELangHindi, "hi_IN" }, // 58 - { ELangIndonesian, "id_ID" }, // 59 - { ELangKorean, "ko_KO" }, // 65 - { ELangLatvian, "lv_LV" }, // 67 - { ELangLithuanian, "lt_LT" }, // 68 - { ELangMalay, "ms_MY" }, // 70 - { ELangNorwegianNynorsk, "nn_NO" }, // 75 - { ELangBrazilianPortuguese, "pt_BR" }, // 76 - { ELangRomanian, "ro_RO" }, // 78 - { ELangSerbian, "sr_RS" }, // 79 - { ELangLatinAmericanSpanish,"es_419" }, // 83 - { ELangUkrainian, "uk_UA" }, // 93 - { ELangUrdu, "ur_PK" }, // 94 - India/Pakistan - { ELangVietnamese, "vi_VN" }, // 96 + { ELangEnglish, "en_GB", "en" }, // 1 + { ELangFrench, "fr_FR", "fr" }, // 2 + { ELangGerman, "de_DE", "de" }, // 3 + { ELangSpanish, "es_ES", "es" }, // 4 + { ELangItalian, "it_IT", "it" }, // 5 + { ELangSwedish, "sv_SE", "sv" }, // 6 + { ELangDanish, "da_DK", "da" }, // 7 + { ELangNorwegian, "nb_NO", "nb" }, // 8 + { ELangFinnish, "fi_FI", "fi" }, // 9 + { ELangAmerican, "en_US", "en-US" }, // 10 + { ELangPortuguese, "pt_PT", "pt" }, // 13 + { ELangTurkish, "tr_TR", "tr" }, // 14 + { ELangIcelandic, "is_IS", "is" }, // 15 + { ELangRussian, "ru_RU", "ru" }, // 16 + { ELangHungarian, "hu_HU", "hu" }, // 17 + { ELangDutch, "nl_NL", "nl" }, // 18 + { ELangCzech, "cs_CZ", "cs" }, // 25 + { ELangSlovak, "sk_SK", "sk" }, // 26 + { ELangPolish, "pl_PL", "pl" }, // 27 + { ELangSlovenian, "sl_SI", "sl" }, // 28 + { ELangTaiwanChinese, "zh_TW", "zh-TW" }, // 29 + { ELangHongKongChinese, "zh_HK", "zh-HK" }, // 30 + { ELangPrcChinese, "zh_CN", "zh" }, // 31 + { ELangJapanese, "ja_JP", "ja" }, // 32 + { ELangThai, "th_TH", "th" }, // 33 + { ELangArabic, "ar_AE", "ar" }, // 37 + { ELangTagalog, "tl_PH", "tl" }, // 39 + { ELangBulgarian, "bg_BG", "bg" }, // 42 + { ELangCatalan, "ca_ES", "ca" }, // 44 + { ELangCroatian, "hr_HR", "hr" }, // 45 + { ELangEstonian, "et_EE", "et" }, // 49 + { ELangFarsi, "fa_IR", "fa" }, // 50 + { ELangCanadianFrench, "fr_CA", "fr-CA" }, // 51 + { ELangGreek, "el_GR", "el" }, // 54 + { ELangHebrew, "he_IL", "he" }, // 57 + { ELangHindi, "hi_IN", "hi" }, // 58 + { ELangIndonesian, "id_ID", "id" }, // 59 + { 63/*ELangKazakh*/, "kk_KZ", "kk" }, // 63 + { ELangKorean, "ko_KO", "ko" }, // 65 + { ELangLatvian, "lv_LV", "lv" }, // 67 + { ELangLithuanian, "lt_LT", "lt" }, // 68 + { ELangMalay, "ms_MY", "ms" }, // 70 + { ELangNorwegianNynorsk, "nn_NO", "nn" }, // 75 + { ELangBrazilianPortuguese, "pt_BR", "pt-BR" }, // 76 + { ELangRomanian, "ro_RO", "ro" }, // 78 + { ELangSerbian, "sr_RS", "sr" }, // 79 + { ELangLatinAmericanSpanish,"es_419", "es-419" },// 83 + { ELangUkrainian, "uk_UA", "uk" }, // 93 + { ELangUrdu, "ur_PK", "ur" }, // 94 - India/Pakistan + { ELangVietnamese, "vi_VN", "vi" }, // 96 #ifdef __E32LANG_H__ // 5.0 - { ELangBasque, "eu_ES" }, // 102 - { ELangGalician, "gl_ES" }, // 103 + { ELangBasque, "eu_ES", "eu" }, // 102 + { ELangGalician, "gl_ES", "gl" }, // 103 #endif #if !defined(__SERIES60_31__) - { ELangEnglish_Apac, "en" }, // 129 - { ELangEnglish_Taiwan, "en_TW" }, // 157 ### Not supported by CLDR - { ELangEnglish_HongKong, "en_HK" }, // 158 - { ELangEnglish_Prc, "en_CN" }, // 159 ### Not supported by CLDR - { ELangEnglish_Japan, "en_JP"}, // 160 ### Not supported by CLDR - { ELangEnglish_Thailand, "en_TH" }, // 161 ### Not supported by CLDR - { ELangMalay_Apac, "ms" }, // 326 + { ELangEnglish_Apac, "en_GB", "en" }, // 129 + { ELangEnglish_Taiwan, "en_TW", "en-TW" }, // 157 ### Not supported by CLDR + { ELangEnglish_HongKong, "en_HK", "en-HK" }, // 158 + { ELangEnglish_Prc, "en_CN", "en-CN" }, // 159 ### Not supported by CLDR + { ELangEnglish_Japan, "en_JP", "en" }, // 160 ### Not supported by CLDR + { ELangEnglish_Thailand, "en_TH", "en" }, // 161 ### Not supported by CLDR + { 230/*ELangEnglish_India*/,"en_IN", "en" }, // 230 + { ELangMalay_Apac, "ms_MY", "ms" }, // 326 #endif - { 327/*ELangIndonesian_Apac*/,"id_ID" } // 327 - appeared in Symbian^3 + { 327/*ELangIndonesian_Apac*/, "id_ID", "id" } // 327 - appeared in Symbian^3 }; -/*! - Returns ISO name corresponding to the Symbian locale code \a sys_fmt. -*/ -QByteArray qt_symbianLocaleName(int code) +enum LocaleNameType { + ISO, + UILanguage +}; + +QByteArray qt_resolveSymbianLocaleName(int code, LocaleNameType type) { //Number of Symbian to ISO locale mappings static const int symbian_to_iso_count @@ -174,8 +179,11 @@ QByteArray qt_symbianLocaleName(int code) if (cmp < 0) return 0; - if (cmp == 0) - return symbian_to_iso_list[0].iso_name; + if (cmp == 0) { + if (type == ISO) + return symbian_to_iso_list[0].iso_name; + return symbian_to_iso_list[0].uilanguage; + } int begin = 0; int end = symbian_to_iso_count; @@ -185,17 +193,27 @@ QByteArray qt_symbianLocaleName(int code) const symbianToISO *elt = symbian_to_iso_list + mid; int cmp = code - elt->symbian_language; - if (cmp < 0) + if (cmp < 0) { end = mid; - else if (cmp > 0) + } else if (cmp > 0) { begin = mid; - else - return elt->iso_name; + } else { + if (type == ISO) + return elt->iso_name; + return elt->uilanguage; + } } return 0; } +/*! + Returns ISO name corresponding to the Symbian locale code \a sys_fmt. +*/ +QByteArray qt_symbianLocaleName(int code) +{ + return qt_resolveSymbianLocaleName(code, ISO); +} // order is: normal, abbr, nmode, nmode+abbr static const char *us_locale_dep[] = { @@ -822,6 +840,13 @@ QLocale QSystemLocale::fallbackLocale() const return QLocale(locale); } +static QStringList symbianUILanguages() +{ + TLanguage lang = User::Language(); + QString s = QLatin1String(qt_resolveSymbianLocaleName(lang, UILanguage)); + return QStringList(s); +} + QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const { switch(type) { @@ -889,6 +914,8 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const return qt_TDes2QString(TAmPmName(TAmPm(EAm))); case PMText: return qt_TDes2QString(TAmPmName(TAmPm(EPm))); + case UILanguages: + return QVariant(symbianUILanguages()); default: break; } diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 5493ba9..3b3f715 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -777,16 +777,12 @@ const QString::Null QString::null = { }; \snippet doc/src/snippets/qstring/stringbuilder.cpp 5 - A more global approach is to include this define: + A more global approach which is the most convenient but + not entirely source compatible, is to this define in your + .pro file: \snippet doc/src/snippets/qstring/stringbuilder.cpp 3 - and use \c{'%'} instead of \c{'+'} for string concatenation - everywhere. The third approach, which is the most convenient but - not entirely source compatible, is to include two defines: - - \snippet doc/src/snippets/qstring/stringbuilder.cpp 4 - and the \c{'+'} will automatically be performed as the \c{QStringBuilder} \c{'%'} everywhere. diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 66cfa74..7c4367e 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -695,9 +695,9 @@ inline QString::QString(const QLatin1String &aLatin1) : d(fromLatin1_helper(aLat inline int QString::length() const { return d->size; } inline const QChar QString::at(int i) const -{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; } +{ Q_ASSERT(uint(i) < uint(size())); return d->data[i]; } inline const QChar QString::operator[](int i) const -{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; } +{ Q_ASSERT(uint(i) < uint(size())); return d->data[i]; } inline const QChar QString::operator[](uint i) const { Q_ASSERT(i < uint(size())); return d->data[i]; } inline bool QString::isEmpty() const @@ -1016,8 +1016,7 @@ inline int QByteArray::findRev(const QString &s, int from) const # endif // QT3_SUPPORT #endif // QT_NO_CAST_TO_ASCII -#ifndef QT_USE_FAST_OPERATOR_PLUS -# ifndef QT_USE_FAST_CONCATENATION +#if !defined(QT_USE_FAST_OPERATOR_PLUS) && !defined(QT_USE_QSTRINGBUILDER) inline const QString operator+(const QString &s1, const QString &s2) { QString t(s1); t += s2; return t; } inline const QString operator+(const QString &s1, QChar s2) @@ -1038,8 +1037,7 @@ inline QT_ASCII_CAST_WARN const QString operator+(const QByteArray &ba, const QS inline QT_ASCII_CAST_WARN const QString operator+(const QString &s, const QByteArray &ba) { QString t(s); t += QString::fromAscii(ba.constData(), qstrnlen(ba.constData(), ba.size())); return t; } # endif // QT_NO_CAST_FROM_ASCII -# endif // QT_USE_FAST_CONCATENATION -#endif // QT_USE_FAST_OPERATOR_PLUS +#endif // QT_USE_QSTRINGBUILDER #ifndef QT_NO_STL inline std::string QString::toStdString() const @@ -1288,7 +1286,7 @@ QT_END_NAMESPACE QT_END_HEADER -#ifdef QT_USE_FAST_CONCATENATION +#if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER) #include <QtCore/qstringbuilder.h> #endif diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index 2d3475f..029aa0b 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -410,7 +410,9 @@ operator%(const A &a, const B &b) return QStringBuilder<typename QConcatenable<A>::type, typename QConcatenable<B>::type>(a, b); } -#ifdef QT_USE_FAST_OPERATOR_PLUS +// QT_USE_FAST_OPERATOR_PLUS was introduced in 4.7, QT_USE_QSTRINGBUILDER is to be used from 4.8 onwards +// QT_USE_FAST_OPERATOR_PLUS does not remove the normal operator+ for QByteArray +#if defined(QT_USE_FAST_OPERATOR_PLUS) || defined(QT_USE_QSTRINGBUILDER) template <typename A, typename B> QStringBuilder<typename QConcatenable<A>::type, typename QConcatenable<B>::type> operator+(const A &a, const B &b) diff --git a/src/corelib/tools/qtextboundaryfinder.cpp b/src/corelib/tools/qtextboundaryfinder.cpp index 34bc406..47319d4 100644 --- a/src/corelib/tools/qtextboundaryfinder.cpp +++ b/src/corelib/tools/qtextboundaryfinder.cpp @@ -199,11 +199,11 @@ QTextBoundaryFinder &QTextBoundaryFinder::operator=(const QTextBoundaryFinder &o chars = other.chars; length = other.length; pos = other.pos; - freePrivate = true; QTextBoundaryFinderPrivate *newD = (QTextBoundaryFinderPrivate *) - realloc(d, length*sizeof(HB_CharAttributes)); + realloc(freePrivate ? d : 0, length*sizeof(HB_CharAttributes)); Q_CHECK_PTR(newD); + freePrivate = true; d = newD; memcpy(d, other.d, length*sizeof(HB_CharAttributes)); diff --git a/src/declarative/debugger/debugger.pri b/src/declarative/debugger/debugger.pri index 75287b4..044db3c 100644 --- a/src/declarative/debugger/debugger.pri +++ b/src/declarative/debugger/debugger.pri @@ -8,7 +8,10 @@ SOURCES += \ $$PWD/qdeclarativedebug.cpp \ $$PWD/qdeclarativedebugtrace.cpp \ $$PWD/qdeclarativedebughelper.cpp \ - $$PWD/qdeclarativedebugserver.cpp + $$PWD/qdeclarativedebugserver.cpp \ + $$PWD/qdeclarativeobserverservice.cpp \ + $$PWD/qjsdebuggeragent.cpp \ + $$PWD/qjsdebugservice.cpp HEADERS += \ $$PWD/qdeclarativedebuggerstatus_p.h \ @@ -20,4 +23,8 @@ HEADERS += \ $$PWD/qdeclarativedebugtrace_p.h \ $$PWD/qdeclarativedebughelper_p.h \ $$PWD/qdeclarativedebugserver_p.h \ - debugger/qdeclarativedebugserverconnection_p.h + $$PWD/qdeclarativedebugserverconnection_p.h \ + $$PWD/qdeclarativeobserverservice_p.h \ + $$PWD/qdeclarativeobserverinterface_p.h \ + $$PWD/qjsdebuggeragent_p.h \ + $$PWD/qjsdebugservice_p.h diff --git a/src/declarative/debugger/qdeclarativedebug.cpp b/src/declarative/debugger/qdeclarativedebug.cpp index 62eb8fe..049e05e 100644 --- a/src/declarative/debugger/qdeclarativedebug.cpp +++ b/src/declarative/debugger/qdeclarativedebug.cpp @@ -84,6 +84,7 @@ public: static void remove(QDeclarativeEngineDebug *, QDeclarativeDebugRootContextQuery *); static void remove(QDeclarativeEngineDebug *, QDeclarativeDebugObjectQuery *); static void remove(QDeclarativeEngineDebug *, QDeclarativeDebugExpressionQuery *); + static void remove(QDeclarativeEngineDebug *, QDeclarativeDebugWatch *); QHash<int, QDeclarativeDebugEnginesQuery *> enginesQuery; QHash<int, QDeclarativeDebugRootContextQuery *> rootContextQuery; @@ -120,6 +121,41 @@ QDeclarativeEngineDebugPrivate::~QDeclarativeEngineDebugPrivate() { if (client) client->priv = 0; + delete client; + + QHash<int, QDeclarativeDebugEnginesQuery*>::iterator enginesIter = enginesQuery.begin(); + for (; enginesIter != enginesQuery.end(); ++enginesIter) { + enginesIter.value()->m_client = 0; + if (enginesIter.value()->state() == QDeclarativeDebugQuery::Waiting) + enginesIter.value()->setState(QDeclarativeDebugQuery::Error); + } + + QHash<int, QDeclarativeDebugRootContextQuery*>::iterator rootContextIter = rootContextQuery.begin(); + for (; rootContextIter != rootContextQuery.end(); ++rootContextIter) { + rootContextIter.value()->m_client = 0; + if (rootContextIter.value()->state() == QDeclarativeDebugQuery::Waiting) + rootContextIter.value()->setState(QDeclarativeDebugQuery::Error); + } + + QHash<int, QDeclarativeDebugObjectQuery*>::iterator objectIter = objectQuery.begin(); + for (; objectIter != objectQuery.end(); ++objectIter) { + objectIter.value()->m_client = 0; + if (objectIter.value()->state() == QDeclarativeDebugQuery::Waiting) + objectIter.value()->setState(QDeclarativeDebugQuery::Error); + } + + QHash<int, QDeclarativeDebugExpressionQuery*>::iterator exprIter = expressionQuery.begin(); + for (; exprIter != expressionQuery.end(); ++exprIter) { + exprIter.value()->m_client = 0; + if (exprIter.value()->state() == QDeclarativeDebugQuery::Waiting) + exprIter.value()->setState(QDeclarativeDebugQuery::Error); + } + + QHash<int, QDeclarativeDebugWatch*>::iterator watchIter = watched.begin(); + for (; watchIter != watched.end(); ++watchIter) { + watchIter.value()->m_client = 0; + watchIter.value()->setState(QDeclarativeDebugWatch::Dead); + } } int QDeclarativeEngineDebugPrivate::getId() @@ -160,6 +196,14 @@ void QDeclarativeEngineDebugPrivate::remove(QDeclarativeEngineDebug *c, QDeclara } } +void QDeclarativeEngineDebugPrivate::remove(QDeclarativeEngineDebug *c, QDeclarativeDebugWatch *w) +{ + if (c && w) { + QDeclarativeEngineDebugPrivate *p = (QDeclarativeEngineDebugPrivate *)QObjectPrivate::get(c); + p->watched.remove(w->m_queryId); + } +} + void QDeclarativeEngineDebugPrivate::decode(QDataStream &ds, QDeclarativeDebugObjectReference &o, bool simple) { @@ -647,6 +691,8 @@ QDeclarativeDebugWatch::QDeclarativeDebugWatch(QObject *parent) QDeclarativeDebugWatch::~QDeclarativeDebugWatch() { + if (m_client && m_queryId != -1) + QDeclarativeEngineDebugPrivate::remove(m_client, this); } int QDeclarativeDebugWatch::queryId() const diff --git a/src/declarative/debugger/qdeclarativedebugserver.cpp b/src/declarative/debugger/qdeclarativedebugserver.cpp index c7bdcb6..4343870 100644 --- a/src/declarative/debugger/qdeclarativedebugserver.cpp +++ b/src/declarative/debugger/qdeclarativedebugserver.cpp @@ -90,7 +90,11 @@ public: QHash<QString, QDeclarativeDebugService *> plugins; QStringList clientPlugins; bool gotHello; + QString waitingForMsgFromService; +private: + // private slot + void _q_deliverMessage(const QString &serviceName, const QByteArray &message); static QDeclarativeDebugServerConnection *loadConnectionPlugin(const QString &pluginName); }; @@ -116,6 +120,7 @@ void QDeclarativeDebugServerPrivate::advertisePlugins() QDeclarativeDebugServerConnection *QDeclarativeDebugServerPrivate::loadConnectionPlugin( const QString &pluginName) { +#ifndef QT_NO_LIBRARY QStringList pluginCandidates; const QStringList paths = QCoreApplication::libraryPaths(); foreach (const QString &libPath, paths) { @@ -142,6 +147,7 @@ QDeclarativeDebugServerConnection *QDeclarativeDebugServerPrivate::loadConnectio return connection; loader.unload(); } +#endif return 0; } @@ -235,7 +241,6 @@ void QDeclarativeDebugServer::receiveMessage(const QByteArray &message) QDataStream in(message); if (!d->gotHello) { - QString name; int op; in >> name >> op; @@ -250,6 +255,17 @@ void QDeclarativeDebugServer::receiveMessage(const QByteArray &message) int version; in >> version >> d->clientPlugins; + // Send the hello answer immediately, since it needs to arrive before + // the plugins below start sending messages. + QByteArray helloAnswer; + { + QDataStream out(&helloAnswer, QIODevice::WriteOnly); + out << QString(QLatin1String("QDeclarativeDebugClient")) << 0 << protocolVersion << d->plugins.keys(); + } + d->connection->send(helloAnswer); + + d->gotHello = true; + QHash<QString, QDeclarativeDebugService*>::Iterator iter = d->plugins.begin(); for (; iter != d->plugins.end(); ++iter) { QDeclarativeDebugService::Status newStatus = QDeclarativeDebugService::Unavailable; @@ -259,14 +275,6 @@ void QDeclarativeDebugServer::receiveMessage(const QByteArray &message) iter.value()->statusChanged(newStatus); } - QByteArray helloAnswer; - { - QDataStream out(&helloAnswer, QIODevice::WriteOnly); - out << QString(QLatin1String("QDeclarativeDebugClient")) << 0 << protocolVersion << d->plugins.keys(); - } - d->connection->send(helloAnswer); - - d->gotHello = true; qWarning("QDeclarativeDebugServer: Connection established"); } else { @@ -304,17 +312,33 @@ void QDeclarativeDebugServer::receiveMessage(const QByteArray &message) QByteArray message; in >> message; - QHash<QString, QDeclarativeDebugService *>::Iterator iter = - d->plugins.find(name); - if (iter == d->plugins.end()) { - qWarning() << "QDeclarativeDebugServer: Message received for missing plugin" << name; + if (d->waitingForMsgFromService == name) { + // deliver directly so that it is delivered before waitForMessage is returning. + d->_q_deliverMessage(name, message); + d->waitingForMsgFromService.clear(); } else { - (*iter)->messageReceived(message); + // deliver message in next event loop run. + // Fixes the case that the service does start it's own event loop ..., + // but the networking code doesn't deliver any new messages because readyRead + // hasn't returned. + QMetaObject::invokeMethod(this, "_q_deliverMessage", Qt::QueuedConnection, + Q_ARG(QString, name), + Q_ARG(QByteArray, message)); } } } } +void QDeclarativeDebugServerPrivate::_q_deliverMessage(const QString &serviceName, const QByteArray &message) +{ + QHash<QString, QDeclarativeDebugService *>::Iterator iter = plugins.find(serviceName); + if (iter == plugins.end()) { + qWarning() << "QDeclarativeDebugServer: Message received for missing plugin" << serviceName; + } else { + (*iter)->messageReceived(message); + } +} + QList<QDeclarativeDebugService*> QDeclarativeDebugServer::services() const { const Q_D(QDeclarativeDebugServer); @@ -372,4 +396,23 @@ void QDeclarativeDebugServer::sendMessage(QDeclarativeDebugService *service, d->connection->send(msg); } +bool QDeclarativeDebugServer::waitForMessage(QDeclarativeDebugService *service) +{ + Q_D(QDeclarativeDebugServer); + + if (!service + || !d->plugins.contains(service->name()) + || !d->waitingForMsgFromService.isEmpty()) + return false; + + d->waitingForMsgFromService = service->name(); + + do { + d->connection->waitForMessage(); + } while (!d->waitingForMsgFromService.isEmpty()); + return true; +} + QT_END_NAMESPACE + +#include "moc_qdeclarativedebugserver_p.cpp" diff --git a/src/declarative/debugger/qdeclarativedebugserver_p.h b/src/declarative/debugger/qdeclarativedebugserver_p.h index 68ea4d8..72c664c 100644 --- a/src/declarative/debugger/qdeclarativedebugserver_p.h +++ b/src/declarative/debugger/qdeclarativedebugserver_p.h @@ -75,10 +75,13 @@ public: void sendMessage(QDeclarativeDebugService *service, const QByteArray &message); void receiveMessage(const QByteArray &message); + bool waitForMessage(QDeclarativeDebugService *service); + private: friend class QDeclarativeDebugService; friend class QDeclarativeDebugServicePrivate; QDeclarativeDebugServer(); + Q_PRIVATE_SLOT(d_func(), void _q_deliverMessage(QString, QByteArray)) }; QT_END_NAMESPACE diff --git a/src/declarative/debugger/qdeclarativedebugserverconnection_p.h b/src/declarative/debugger/qdeclarativedebugserverconnection_p.h index 0c2bdb4..ca267e0 100644 --- a/src/declarative/debugger/qdeclarativedebugserverconnection_p.h +++ b/src/declarative/debugger/qdeclarativedebugserverconnection_p.h @@ -62,6 +62,7 @@ public: virtual bool isConnected() const = 0; virtual void send(const QByteArray &message) = 0; virtual void disconnect() = 0; + virtual bool waitForMessage() = 0; }; Q_DECLARE_INTERFACE(QDeclarativeDebugServerConnection, "com.trolltech.Qt.QDeclarativeDebugServerConnection/1.0") diff --git a/src/declarative/debugger/qdeclarativedebugservice.cpp b/src/declarative/debugger/qdeclarativedebugservice.cpp index 1b39f1c..c7e6615 100644 --- a/src/declarative/debugger/qdeclarativedebugservice.cpp +++ b/src/declarative/debugger/qdeclarativedebugservice.cpp @@ -209,6 +209,16 @@ void QDeclarativeDebugService::sendMessage(const QByteArray &message) d->server->sendMessage(this, message); } +bool QDeclarativeDebugService::waitForMessage() +{ + Q_D(QDeclarativeDebugService); + + if (status() != Enabled) + return false; + + return d->server->waitForMessage(this); +} + void QDeclarativeDebugService::statusChanged(Status) { } diff --git a/src/declarative/debugger/qdeclarativedebugservice_p.h b/src/declarative/debugger/qdeclarativedebugservice_p.h index 5e30350..f3d1919 100644 --- a/src/declarative/debugger/qdeclarativedebugservice_p.h +++ b/src/declarative/debugger/qdeclarativedebugservice_p.h @@ -69,6 +69,7 @@ public: Status status() const; void sendMessage(const QByteArray &); + bool waitForMessage(); static int idForObject(QObject *); static QObject *objectForId(int); @@ -84,6 +85,7 @@ protected: private: friend class QDeclarativeDebugServer; + friend class QDeclarativeDebugServerPrivate; }; QT_END_NAMESPACE diff --git a/src/declarative/debugger/qdeclarativedebugtrace.cpp b/src/declarative/debugger/qdeclarativedebugtrace.cpp index 6f28736..edbbe78 100644 --- a/src/declarative/debugger/qdeclarativedebugtrace.cpp +++ b/src/declarative/debugger/qdeclarativedebugtrace.cpp @@ -65,9 +65,14 @@ QByteArray QDeclarativeDebugData::toByteArray() const QDeclarativeDebugTrace::QDeclarativeDebugTrace() : QDeclarativeDebugService(QLatin1String("CanvasFrameRate")), - m_enabled(false), m_deferredSend(true) + m_enabled(false), m_deferredSend(true), m_messageReceived(false) { m_timer.start(); + if (status() == Enabled) { + // wait for first message indicating whether to trace or not + while (!m_messageReceived) + waitForMessage(); + } } void QDeclarativeDebugTrace::addEvent(EventType t) @@ -213,6 +218,8 @@ void QDeclarativeDebugTrace::messageReceived(const QByteArray &message) stream >> m_enabled; + m_messageReceived = true; + if (!m_enabled) sendMessages(); } diff --git a/src/declarative/debugger/qdeclarativedebugtrace_p.h b/src/declarative/debugger/qdeclarativedebugtrace_p.h index ae0653e..c74cbe0 100644 --- a/src/declarative/debugger/qdeclarativedebugtrace_p.h +++ b/src/declarative/debugger/qdeclarativedebugtrace_p.h @@ -120,6 +120,7 @@ private: QPerformanceTimer m_timer; bool m_enabled; bool m_deferredSend; + bool m_messageReceived; QList<QDeclarativeDebugData> m_data; }; diff --git a/src/declarative/debugger/qdeclarativeobserverinterface_p.h b/src/declarative/debugger/qdeclarativeobserverinterface_p.h new file mode 100644 index 0000000..501c132 --- /dev/null +++ b/src/declarative/debugger/qdeclarativeobserverinterface_p.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 QDECLARATIVEOBSERVERINTERFACE_H +#define QDECLARATIVEOBSERVERINTERFACE_H + +#include <QtDeclarative/private/qdeclarativeglobal_p.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class Q_DECLARATIVE_EXPORT QDeclarativeObserverInterface +{ +public: + QDeclarativeObserverInterface() {} + virtual ~QDeclarativeObserverInterface() {} + + virtual void activate() = 0; + virtual void deactivate() = 0; +}; + +Q_DECLARE_INTERFACE(QDeclarativeObserverInterface, "com.trolltech.Qt.QDeclarativeObserverInterface/1.0") + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QDECLARATIVEOBSERVERINTERFACE_H diff --git a/src/declarative/debugger/qdeclarativeobserverservice.cpp b/src/declarative/debugger/qdeclarativeobserverservice.cpp new file mode 100644 index 0000000..a623c55 --- /dev/null +++ b/src/declarative/debugger/qdeclarativeobserverservice.cpp @@ -0,0 +1,137 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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/qdeclarativeobserverservice_p.h" +#include "private/qdeclarativeobserverinterface_p.h" + +#include <QtCore/QCoreApplication> +#include <QtCore/QDebug> +#include <QtCore/QDir> +#include <QtCore/QPluginLoader> + +#include <QtDeclarative/QDeclarativeView> + +QT_BEGIN_NAMESPACE + +Q_GLOBAL_STATIC(QDeclarativeObserverService, serviceInstance) + +QDeclarativeObserverService::QDeclarativeObserverService() + : QDeclarativeDebugService(QLatin1String("QDeclarativeObserverMode")) + , m_observer(0) +{ +} + +QDeclarativeObserverService *QDeclarativeObserverService::instance() +{ + return serviceInstance(); +} + +void QDeclarativeObserverService::addView(QDeclarativeView *view) +{ + m_views.append(view); +} + +void QDeclarativeObserverService::removeView(QDeclarativeView *view) +{ + m_views.removeAll(view); +} + +void QDeclarativeObserverService::sendMessage(const QByteArray &message) +{ + if (status() != Enabled) + return; + + QDeclarativeDebugService::sendMessage(message); +} + +void QDeclarativeObserverService::statusChanged(Status status) +{ + if (m_views.isEmpty()) + return; + + if (status == Enabled) { + if (!m_observer) + m_observer = loadObserverPlugin(); + + if (!m_observer) { + qWarning() << "Error while loading observer plugin"; + return; + } + + m_observer->activate(); + } else { + if (m_observer) + m_observer->deactivate(); + } +} + +void QDeclarativeObserverService::messageReceived(const QByteArray &message) +{ + emit gotMessage(message); +} + +QDeclarativeObserverInterface *QDeclarativeObserverService::loadObserverPlugin() +{ + QStringList pluginCandidates; + const QStringList paths = QCoreApplication::libraryPaths(); + foreach (const QString &libPath, paths) { + const QDir dir(libPath + QLatin1String("/qmltooling")); + if (dir.exists()) + foreach (const QString &pluginPath, dir.entryList(QDir::Files)) + pluginCandidates << dir.absoluteFilePath(pluginPath); + } + + foreach (const QString &pluginPath, pluginCandidates) { + QPluginLoader loader(pluginPath); + if (!loader.load()) + continue; + + QDeclarativeObserverInterface *observer = + qobject_cast<QDeclarativeObserverInterface*>(loader.instance()); + + if (observer) + return observer; + loader.unload(); + } + return 0; +} + +QT_END_NAMESPACE diff --git a/src/declarative/debugger/qdeclarativeobserverservice_p.h b/src/declarative/debugger/qdeclarativeobserverservice_p.h new file mode 100644 index 0000000..36f31dc --- /dev/null +++ b/src/declarative/debugger/qdeclarativeobserverservice_p.h @@ -0,0 +1,91 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 QDECLARATIVEOBSERVERSERVICE_H +#define QDECLARATIVEOBSERVERSERVICE_H + +#include "private/qdeclarativedebugservice_p.h" +#include <private/qdeclarativeglobal_p.h> + +#include <QtCore/QList> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeView; +class QDeclarativeObserverInterface; + +class Q_DECLARATIVE_EXPORT QDeclarativeObserverService : public QDeclarativeDebugService +{ + Q_OBJECT + +public: + QDeclarativeObserverService(); + static QDeclarativeObserverService *instance(); + + void addView(QDeclarativeView *); + void removeView(QDeclarativeView *); + QList<QDeclarativeView*> views() const { return m_views; } + + void sendMessage(const QByteArray &message); + +Q_SIGNALS: + void gotMessage(const QByteArray &message); + +protected: + virtual void statusChanged(Status status); + virtual void messageReceived(const QByteArray &); + +private: + static QDeclarativeObserverInterface *loadObserverPlugin(); + + QList<QDeclarativeView*> m_views; + QDeclarativeObserverInterface *m_observer; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QDECLARATIVEOBSERVERSERVICE_H diff --git a/src/declarative/debugger/qjsdebuggeragent.cpp b/src/declarative/debugger/qjsdebuggeragent.cpp new file mode 100644 index 0000000..601c8c8 --- /dev/null +++ b/src/declarative/debugger/qjsdebuggeragent.cpp @@ -0,0 +1,576 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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/qjsdebuggeragent_p.h" +#include "private/qdeclarativedebughelper_p.h" + +#include <QtCore/qdatetime.h> +#include <QtCore/qcoreapplication.h> +#include <QtCore/qset.h> +#include <QtCore/qurl.h> +#include <QtScript/qscriptcontextinfo.h> +#include <QtScript/qscriptengine.h> +#include <QtScript/qscriptvalueiterator.h> + +QT_BEGIN_NAMESPACE + +class QJSDebuggerAgentPrivate +{ +public: + QJSDebuggerAgentPrivate(QJSDebuggerAgent *q) + : q(q), state(NoState) + {} + + void continueExec(); + void recordKnownObjects(const QList<JSAgentWatchData> &); + QList<JSAgentWatchData> getLocals(QScriptContext *); + void positionChange(qint64 scriptId, int lineNumber, int columnNumber); + QScriptEngine *engine() { return q->engine(); } + void stopped(); + +public: + QJSDebuggerAgent *q; + JSDebuggerState state; + int stepDepth; + int stepCount; + + QEventLoop loop; + QHash<qint64, QString> filenames; + JSAgentBreakpoints breakpoints; + // breakpoints by filename (without path) + QHash<QString, JSAgentBreakpointData> fileNameToBreakpoints; + QStringList watchExpressions; + QSet<qint64> knownObjectIds; +}; + +namespace { + +class SetupExecEnv +{ +public: + SetupExecEnv(QJSDebuggerAgentPrivate *a) + : agent(a), + previousState(a->state), + hadException(a->engine()->hasUncaughtException()) + { + agent->state = StoppedState; + } + + ~SetupExecEnv() + { + if (!hadException && agent->engine()->hasUncaughtException()) + agent->engine()->clearExceptions(); + agent->state = previousState; + } + +private: + QJSDebuggerAgentPrivate *agent; + JSDebuggerState previousState; + bool hadException; +}; + +} // anonymous namespace + +static JSAgentWatchData fromScriptValue(const QString &expression, + const QScriptValue &value) +{ + static const QString arrayStr = QCoreApplication::translate + ("Debugger::JSAgentWatchData", "[Array of length %1]"); + static const QString undefinedStr = QCoreApplication::translate + ("Debugger::JSAgentWatchData", "<undefined>"); + + JSAgentWatchData data; + data.exp = expression.toUtf8(); + data.name = data.exp; + data.hasChildren = false; + data.value = value.toString().toUtf8(); + data.objectId = value.objectId(); + if (value.isArray()) { + data.type = "Array"; + data.value = arrayStr.arg(value.property(QLatin1String("length")).toString()).toUtf8(); + data.hasChildren = true; + } else if (value.isBool()) { + data.type = "Bool"; + // data.value = value.toBool() ? "true" : "false"; + } else if (value.isDate()) { + data.type = "Date"; + data.value = value.toDateTime().toString().toUtf8(); + } else if (value.isError()) { + data.type = "Error"; + } else if (value.isFunction()) { + data.type = "Function"; + } else if (value.isUndefined()) { + data.type = undefinedStr.toUtf8(); + } else if (value.isNumber()) { + data.type = "Number"; + } else if (value.isRegExp()) { + data.type = "RegExp"; + } else if (value.isString()) { + data.type = "String"; + } else if (value.isVariant()) { + data.type = "Variant"; + } else if (value.isQObject()) { + const QObject *obj = value.toQObject(); + data.type = "Object"; + data.value += '['; + data.value += obj->metaObject()->className(); + data.value += ']'; + data.hasChildren = true; + } else if (value.isObject()) { + data.type = "Object"; + data.hasChildren = true; + data.value = "[Object]"; + } else if (value.isNull()) { + data.type = "<null>"; + } else { + data.type = "<unknown>"; + } + return data; +} + +static QList<JSAgentWatchData> expandObject(const QScriptValue &object) +{ + QList<JSAgentWatchData> result; + QScriptValueIterator it(object); + while (it.hasNext()) { + it.next(); + if (it.flags() & QScriptValue::SkipInEnumeration) + continue; + if (/*object.isQObject() &&*/ it.value().isFunction()) { + // Cosmetics: skip all functions and slot, there are too many of them, + // and it is not useful information in the debugger. + continue; + } + JSAgentWatchData data = fromScriptValue(it.name(), it.value()); + result.append(data); + } + if (result.isEmpty()) { + JSAgentWatchData data; + data.name = "<no initialized data>"; + data.hasChildren = false; + data.value = " "; + data.objectId = 0; + result.append(data); + } + return result; +} + +static QString fileName(const QString &fileUrl) +{ + int lastDelimiterPos = fileUrl.lastIndexOf(QLatin1Char('/')); + return fileUrl.mid(lastDelimiterPos, fileUrl.size() - lastDelimiterPos); +} + +void QJSDebuggerAgentPrivate::recordKnownObjects(const QList<JSAgentWatchData>& list) +{ + foreach (const JSAgentWatchData &data, list) + knownObjectIds << data.objectId; +} + +QList<JSAgentWatchData> QJSDebuggerAgentPrivate::getLocals(QScriptContext *ctx) +{ + QList<JSAgentWatchData> locals; + if (ctx) { + QScriptValue activationObject = ctx->activationObject(); + QScriptValue thisObject = ctx->thisObject(); + locals = expandObject(activationObject); + if (thisObject.isObject() + && thisObject.objectId() != engine()->globalObject().objectId() + && QScriptValueIterator(thisObject).hasNext()) + locals.prepend(fromScriptValue(QLatin1String("this"), thisObject)); + recordKnownObjects(locals); + knownObjectIds << activationObject.objectId(); + } + return locals; +} + +/*! + Constructs a new agent for the given \a engine. The agent will + report debugging-related events (e.g. step completion) to the given + \a backend. +*/ +QJSDebuggerAgent::QJSDebuggerAgent(QScriptEngine *engine, QObject *parent) + : QObject(parent) + , QScriptEngineAgent(engine) + , d(new QJSDebuggerAgentPrivate(this)) +{ + QJSDebuggerAgent::engine()->setAgent(this); +} + +QJSDebuggerAgent::QJSDebuggerAgent(QDeclarativeEngine *engine, QObject *parent) + : QObject(parent) + , QScriptEngineAgent(QDeclarativeDebugHelper::getScriptEngine(engine)) + , d(new QJSDebuggerAgentPrivate(this)) +{ + QJSDebuggerAgent::engine()->setAgent(this); +} + +/*! + Destroys this QJSDebuggerAgent. +*/ +QJSDebuggerAgent::~QJSDebuggerAgent() +{ + engine()->setAgent(0); + delete d; +} + +void QJSDebuggerAgent::setBreakpoints(const JSAgentBreakpoints &breakpoints) +{ + d->breakpoints = breakpoints; + + d->fileNameToBreakpoints.clear(); + foreach (const JSAgentBreakpointData &bp, breakpoints) + d->fileNameToBreakpoints.insertMulti(fileName(QString::fromUtf8(bp.fileUrl)), bp); +} + +void QJSDebuggerAgent::setWatchExpressions(const QStringList &watchExpressions) +{ + d->watchExpressions = watchExpressions; +} + +void QJSDebuggerAgent::stepOver() +{ + d->stepDepth = 0; + d->state = SteppingOverState; + d->continueExec(); +} + +void QJSDebuggerAgent::stepInto() +{ + d->stepDepth = 0; + d->state = SteppingIntoState; + d->continueExec(); +} + +void QJSDebuggerAgent::stepOut() +{ + d->stepDepth = 0; + d->state = SteppingOutState; + d->continueExec(); +} + +void QJSDebuggerAgent::continueExecution() +{ + d->state = NoState; + d->continueExec(); +} + +JSAgentWatchData QJSDebuggerAgent::executeExpression(const QString &expr) +{ + SetupExecEnv execEnv(d); + + JSAgentWatchData data = fromScriptValue(expr, engine()->evaluate(expr)); + d->knownObjectIds << data.objectId; + return data; +} + +QList<JSAgentWatchData> QJSDebuggerAgent::expandObjectById(quint64 objectId) +{ + SetupExecEnv execEnv(d); + + QScriptValue v; + if (d->knownObjectIds.contains(objectId)) + v = engine()->objectById(objectId); + + QList<JSAgentWatchData> result = expandObject(v); + d->recordKnownObjects(result); + return result; +} + +QList<JSAgentWatchData> QJSDebuggerAgent::locals() +{ + SetupExecEnv execEnv(d); + return d->getLocals(engine()->currentContext()); +} + +QList<JSAgentWatchData> QJSDebuggerAgent::localsAtFrame(int frameId) +{ + SetupExecEnv execEnv(d); + + int deep = 0; + QScriptContext *ctx = engine()->currentContext(); + while (ctx && deep < frameId) { + ctx = ctx->parentContext(); + deep++; + } + + return d->getLocals(ctx); +} + +QList<JSAgentStackData> QJSDebuggerAgent::backtrace() +{ + SetupExecEnv execEnv(d); + + QList<JSAgentStackData> backtrace; + + for (QScriptContext *ctx = engine()->currentContext(); ctx; ctx = ctx->parentContext()) { + QScriptContextInfo info(ctx); + + JSAgentStackData frame; + frame.functionName = info.functionName().toUtf8(); + if (frame.functionName.isEmpty()) { + if (ctx->parentContext()) { + switch (info.functionType()) { + case QScriptContextInfo::ScriptFunction: + frame.functionName = "<anonymous>"; + break; + case QScriptContextInfo::NativeFunction: + frame.functionName = "<native>"; + break; + case QScriptContextInfo::QtFunction: + case QScriptContextInfo::QtPropertyFunction: + frame.functionName = "<native slot>"; + break; + } + } else { + frame.functionName = "<global>"; + } + } + frame.lineNumber = info.lineNumber(); + // if the line number is unknown, fallback to the function line number + if (frame.lineNumber == -1) + frame.lineNumber = info.functionStartLineNumber(); + + frame.fileUrl = info.fileName().toUtf8(); + backtrace.append(frame); + } + + return backtrace; +} + +QList<JSAgentWatchData> QJSDebuggerAgent::watches() +{ + SetupExecEnv execEnv(d); + + QList<JSAgentWatchData> watches; + foreach (const QString &expr, d->watchExpressions) + watches << fromScriptValue(expr, engine()->evaluate(expr)); + d->recordKnownObjects(watches); + return watches; +} + +void QJSDebuggerAgent::setProperty(qint64 objectId, + const QString &property, + const QString &value) +{ + SetupExecEnv execEnv(d); + + if (d->knownObjectIds.contains(objectId)) { + QScriptValue object = engine()->objectById(objectId); + if (object.isObject()) { + QScriptValue result = engine()->evaluate(value); + object.setProperty(property, result); + } + } +} + +/*! + \reimp +*/ +void QJSDebuggerAgent::scriptLoad(qint64 id, const QString &program, + const QString &fileName, int) +{ + Q_UNUSED(program); + d->filenames.insert(id, fileName); +} + +/*! + \reimp +*/ +void QJSDebuggerAgent::scriptUnload(qint64 id) +{ + d->filenames.remove(id); +} + +/*! + \reimp +*/ +void QJSDebuggerAgent::contextPush() +{ +} + +/*! + \reimp +*/ +void QJSDebuggerAgent::contextPop() +{ +} + +/*! + \reimp +*/ +void QJSDebuggerAgent::functionEntry(qint64 scriptId) +{ + Q_UNUSED(scriptId); + d->stepDepth++; +} + +/*! + \reimp +*/ +void QJSDebuggerAgent::functionExit(qint64 scriptId, const QScriptValue &returnValue) +{ + Q_UNUSED(scriptId); + Q_UNUSED(returnValue); + d->stepDepth--; +} + +/*! + \reimp +*/ +void QJSDebuggerAgent::positionChange(qint64 scriptId, int lineNumber, int columnNumber) +{ + d->positionChange(scriptId, lineNumber, columnNumber); +} + +void QJSDebuggerAgentPrivate::positionChange(qint64 scriptId, int lineNumber, int columnNumber) +{ + Q_UNUSED(columnNumber); + + if (state == StoppedState) + return; //no re-entrency + + // check breakpoints + if (!breakpoints.isEmpty()) { + QHash<qint64, QString>::const_iterator it = filenames.constFind(scriptId); + QScriptContext *ctx = engine()->currentContext(); + QScriptContextInfo info(ctx); + if (it == filenames.constEnd()) { + // It is possible that the scripts are loaded before the agent is attached + QString filename = info.fileName(); + + JSAgentStackData frame; + frame.functionName = info.functionName().toUtf8(); + + QPair<QString, qint32> key = qMakePair(filename, lineNumber); + it = filenames.insert(scriptId, filename); + } + + const QString filePath = it.value(); + JSAgentBreakpoints bps = fileNameToBreakpoints.values(fileName(filePath)).toSet(); + + foreach (const JSAgentBreakpointData &bp, bps) { + if (bp.lineNumber == lineNumber) { + stopped(); + return; + } + } + } + + switch (state) { + case NoState: + case StoppedState: + // Do nothing + break; + case SteppingOutState: + if (stepDepth >= 0) + break; + //fallthough + case SteppingOverState: + if (stepDepth > 0) + break; + //fallthough + case SteppingIntoState: + stopped(); + break; + } + +} + +/*! + \reimp +*/ +void QJSDebuggerAgent::exceptionThrow(qint64 scriptId, + const QScriptValue &exception, + bool hasHandler) +{ + Q_UNUSED(scriptId); + Q_UNUSED(exception); + Q_UNUSED(hasHandler); +// qDebug() << Q_FUNC_INFO << exception.toString() << hasHandler; +#if 0 //sometimes, we get exceptions that we should just ignore. + if (!hasHandler && state != StoppedState) + stopped(true, exception); +#endif +} + +/*! + \reimp +*/ +void QJSDebuggerAgent::exceptionCatch(qint64 scriptId, const QScriptValue &exception) +{ + Q_UNUSED(scriptId); + Q_UNUSED(exception); +} + +bool QJSDebuggerAgent::supportsExtension(Extension extension) const +{ + return extension == QScriptEngineAgent::DebuggerInvocationRequest; +} + +QVariant QJSDebuggerAgent::extension(Extension extension, const QVariant &argument) +{ + if (extension == QScriptEngineAgent::DebuggerInvocationRequest) { + d->stopped(); + return QVariant(); + } + return QScriptEngineAgent::extension(extension, argument); +} + +void QJSDebuggerAgentPrivate::stopped() +{ + bool becauseOfException = false; + const QScriptValue &exception = QScriptValue(); + + knownObjectIds.clear(); + state = StoppedState; + + emit q->stopped(becauseOfException, exception.toString()); + + loop.exec(QEventLoop::ExcludeUserInputEvents); +} + +void QJSDebuggerAgentPrivate::continueExec() +{ + loop.quit(); +} + +QT_END_NAMESPACE diff --git a/src/declarative/debugger/qjsdebuggeragent_p.h b/src/declarative/debugger/qjsdebuggeragent_p.h new file mode 100644 index 0000000..ce5a044 --- /dev/null +++ b/src/declarative/debugger/qjsdebuggeragent_p.h @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 QJSDEBUGGERAGENT_P_H +#define QJSDEBUGGERAGENT_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtScript/qscriptengineagent.h> +#include <QtCore/qset.h> + +QT_BEGIN_NAMESPACE +class QScriptValue; +class QDeclarativeEngine; +QT_END_NAMESPACE + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QJSDebuggerAgentPrivate; + +enum JSDebuggerState +{ + NoState, + SteppingIntoState, + SteppingOverState, + SteppingOutState, + StoppedState +}; + +struct JSAgentWatchData +{ + QByteArray exp; + QByteArray name; + QByteArray value; + QByteArray type; + bool hasChildren; + quint64 objectId; +}; + +inline QDataStream &operator<<(QDataStream &s, const JSAgentWatchData &data) +{ + return s << data.exp << data.name << data.value + << data.type << data.hasChildren << data.objectId; +} + +struct JSAgentStackData +{ + QByteArray functionName; + QByteArray fileUrl; + qint32 lineNumber; +}; + +inline QDataStream &operator<<(QDataStream &s, const JSAgentStackData &data) +{ + return s << data.functionName << data.fileUrl << data.lineNumber; +} + +struct JSAgentBreakpointData +{ + QByteArray functionName; + QByteArray fileUrl; + qint32 lineNumber; +}; + +typedef QSet<JSAgentBreakpointData> JSAgentBreakpoints; + +inline QDataStream &operator<<(QDataStream &s, const JSAgentBreakpointData &data) +{ + return s << data.functionName << data.fileUrl << data.lineNumber; +} + +inline QDataStream &operator>>(QDataStream &s, JSAgentBreakpointData &data) +{ + return s >> data.functionName >> data.fileUrl >> data.lineNumber; +} + +inline bool operator==(const JSAgentBreakpointData &b1, const JSAgentBreakpointData &b2) +{ + return b1.lineNumber == b2.lineNumber && b1.fileUrl == b2.fileUrl; +} + +inline uint qHash(const JSAgentBreakpointData &b) +{ + return b.lineNumber ^ qHash(b.fileUrl); +} + + +class QJSDebuggerAgent : public QObject, public QScriptEngineAgent +{ + Q_OBJECT + +public: + QJSDebuggerAgent(QScriptEngine *engine, QObject *parent = 0); + QJSDebuggerAgent(QDeclarativeEngine *engine, QObject *parent = 0); + ~QJSDebuggerAgent(); + + void setBreakpoints(const JSAgentBreakpoints &); + void setWatchExpressions(const QStringList &); + + void stepOver(); + void stepInto(); + void stepOut(); + void continueExecution(); + + JSAgentWatchData executeExpression(const QString &expr); + QList<JSAgentWatchData> expandObjectById(quint64 objectId); + QList<JSAgentWatchData> locals(); + QList<JSAgentWatchData> localsAtFrame(int frameId); + QList<JSAgentStackData> backtrace(); + QList<JSAgentWatchData> watches(); + void setProperty(qint64 objectId, + const QString &property, + const QString &value); + + // reimplemented + void scriptLoad(qint64 id, const QString &program, + const QString &fileName, int baseLineNumber); + void scriptUnload(qint64 id); + + void contextPush(); + void contextPop(); + + void functionEntry(qint64 scriptId); + void functionExit(qint64 scriptId, + const QScriptValue &returnValue); + + void positionChange(qint64 scriptId, + int lineNumber, int columnNumber); + + void exceptionThrow(qint64 scriptId, + const QScriptValue &exception, + bool hasHandler); + void exceptionCatch(qint64 scriptId, + const QScriptValue &exception); + + bool supportsExtension(Extension extension) const; + QVariant extension(Extension extension, + const QVariant &argument = QVariant()); + +Q_SIGNALS: + void stopped(bool becauseOfException, + const QString &exception); + +private: + friend class QJSDebuggerAgentPrivate; + QJSDebuggerAgentPrivate *d; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QJSDEBUGGERAGENT_P_H diff --git a/src/declarative/debugger/qjsdebugservice.cpp b/src/declarative/debugger/qjsdebugservice.cpp new file mode 100644 index 0000000..f8cd095 --- /dev/null +++ b/src/declarative/debugger/qjsdebugservice.cpp @@ -0,0 +1,198 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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/qjsdebugservice_p.h" +#include "private/qjsdebuggeragent_p.h" + +#include <QtCore/qdatastream.h> +#include <QtCore/qdebug.h> +#include <QtCore/qstringlist.h> +#include <QtDeclarative/qdeclarativeengine.h> + +Q_GLOBAL_STATIC(QJSDebugService, serviceInstance) + +QJSDebugService::QJSDebugService(QObject *parent) + : QDeclarativeDebugService(QLatin1String("JSDebugger"), parent) + , m_agent(0) +{ +} + +QJSDebugService::~QJSDebugService() +{ + delete m_agent; +} + +QJSDebugService *QJSDebugService::instance() +{ + return serviceInstance(); +} + +void QJSDebugService::addEngine(QDeclarativeEngine *engine) +{ + Q_ASSERT(engine); + Q_ASSERT(!m_engines.contains(engine)); + + m_engines.append(engine); +} + +void QJSDebugService::removeEngine(QDeclarativeEngine *engine) +{ + Q_ASSERT(engine); + Q_ASSERT(m_engines.contains(engine)); + + m_engines.removeAll(engine); +} + +void QJSDebugService::statusChanged(Status status) +{ + if (status == Enabled && !m_engines.isEmpty() && !m_agent) { + // Multiple engines are currently unsupported + QDeclarativeEngine *engine = m_engines.first(); + m_agent = new QJSDebuggerAgent(engine, engine); + + connect(m_agent, SIGNAL(stopped(bool,QString)), + this, SLOT(executionStopped(bool,QString))); + + } else if (status != Enabled && m_agent) { + delete m_agent; + m_agent = 0; + } +} + +void QJSDebugService::messageReceived(const QByteArray &message) +{ + if (!m_agent) { + qWarning() << "QJSDebugService::messageReceived: No QJSDebuggerAgent available"; + return; + } + + QDataStream ds(message); + QByteArray command; + ds >> command; + if (command == "BREAKPOINTS") { + JSAgentBreakpoints breakpoints; + ds >> breakpoints; + m_agent->setBreakpoints(breakpoints); + + //qDebug() << "BREAKPOINTS"; + //foreach (const JSAgentBreakpointData &bp, breakpoints) + // qDebug() << "BREAKPOINT: " << bp.fileUrl << bp.lineNumber; + } else if (command == "WATCH_EXPRESSIONS") { + QStringList watchExpressions; + ds >> watchExpressions; + m_agent->setWatchExpressions(watchExpressions); + } else if (command == "STEPOVER") { + m_agent->stepOver(); + } else if (command == "STEPINTO" || command == "INTERRUPT") { + m_agent->stepInto(); + } else if (command == "STEPOUT") { + m_agent->stepOut(); + } else if (command == "CONTINUE") { + m_agent->continueExecution(); + } else if (command == "EXEC") { + QByteArray id; + QString expr; + ds >> id >> expr; + + JSAgentWatchData data = m_agent->executeExpression(expr); + + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("RESULT") << id << data; + sendMessage(reply); + } else if (command == "EXPAND") { + QByteArray requestId; + quint64 objectId; + ds >> requestId >> objectId; + + QList<JSAgentWatchData> result = m_agent->expandObjectById(objectId); + + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("EXPANDED") << requestId << result; + sendMessage(reply); + } else if (command == "ACTIVATE_FRAME") { + int frameId; + ds >> frameId; + + QList<JSAgentWatchData> locals = m_agent->localsAtFrame(frameId); + + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("LOCALS") << frameId << locals; + sendMessage(reply); + } else if (command == "SET_PROPERTY") { + QByteArray id; + qint64 objectId; + QString property; + QString value; + ds >> id >> objectId >> property >> value; + + m_agent->setProperty(objectId, property, value); + + //TODO: feedback + } else if (command == "PING") { + int ping; + ds >> ping; + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("PONG") << ping; + sendMessage(reply); + } else { + qDebug() << Q_FUNC_INFO << "Unknown command" << command; + } + + QDeclarativeDebugService::messageReceived(message); +} + +void QJSDebugService::executionStopped(bool becauseOfException, + const QString &exception) +{ + const QList<JSAgentStackData> backtrace = m_agent->backtrace(); + const QList<JSAgentWatchData> watches = m_agent->watches(); + const QList<JSAgentWatchData> locals = m_agent->locals(); + + QByteArray reply; + QDataStream rs(&reply, QIODevice::WriteOnly); + rs << QByteArray("STOPPED") << backtrace << watches << locals + << becauseOfException << exception; + sendMessage(reply); +} diff --git a/src/declarative/debugger/qjsdebugservice_p.h b/src/declarative/debugger/qjsdebugservice_p.h new file mode 100644 index 0000000..6839ca8 --- /dev/null +++ b/src/declarative/debugger/qjsdebugservice_p.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 QJSDEBUGSERVICE_P_H +#define QJSDEBUGSERVICE_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtCore/QPointer> + +#include "private/qdeclarativedebugservice_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeEngine; +class QJSDebuggerAgent; + +class QJSDebugService : public QDeclarativeDebugService +{ + Q_OBJECT + +public: + QJSDebugService(QObject *parent = 0); + ~QJSDebugService(); + + static QJSDebugService *instance(); + + void addEngine(QDeclarativeEngine *); + void removeEngine(QDeclarativeEngine *); + +protected: + void statusChanged(Status status); + void messageReceived(const QByteArray &); + +private Q_SLOTS: + void executionStopped(bool becauseOfException, + const QString &exception); + +private: + QList<QDeclarativeEngine *> m_engines; + QPointer<QJSDebuggerAgent> m_agent; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QJSDEBUGSERVICE_P_H diff --git a/src/declarative/debugger/qpacketprotocol.cpp b/src/declarative/debugger/qpacketprotocol.cpp index 15a14cf..c1034a7 100644 --- a/src/declarative/debugger/qpacketprotocol.cpp +++ b/src/declarative/debugger/qpacketprotocol.cpp @@ -42,6 +42,7 @@ #include "private/qpacketprotocol_p.h" #include <QBuffer> +#include <QElapsedTimer> QT_BEGIN_NAMESPACE @@ -114,7 +115,7 @@ Q_OBJECT public: QPacketProtocolPrivate(QPacketProtocol * parent, QIODevice * _dev) : QObject(parent), inProgressSize(-1), maxPacketSize(MAX_PACKET_SIZE), - dev(_dev) + waitingForPacket(false), dev(_dev) { Q_ASSERT(4 == sizeof(qint32)); @@ -125,7 +126,7 @@ public: QObject::connect(this, SIGNAL(invalidPacket()), parent, SIGNAL(invalidPacket())); QObject::connect(dev, SIGNAL(readyRead()), - this, SLOT(readyToRead()), Qt::QueuedConnection); + this, SLOT(readyToRead())); QObject::connect(dev, SIGNAL(aboutToClose()), this, SLOT(aboutToClose())); QObject::connect(dev, SIGNAL(bytesWritten(qint64)), @@ -200,6 +201,7 @@ public Q_SLOTS: inProgress.clear(); emit readyRead(); + waitingForPacket = false; // Need to get trailing data readyToRead(); @@ -213,6 +215,7 @@ public: QByteArray inProgress; qint32 inProgressSize; qint32 maxPacketSize; + bool waitingForPacket; QIODevice * dev; }; @@ -324,6 +327,48 @@ QPacket QPacketProtocol::read() return rv; } +/* + Returns the difference between msecs and elapsed. If msecs is -1, + however, -1 is returned. +*/ +static int qt_timeout_value(int msecs, int elapsed) +{ + if (msecs == -1) + return -1; + + int timeout = msecs - elapsed; + return timeout < 0 ? 0 : timeout; +} + +/*! + This function locks until a new packet is available for reading and the + \l{QIODevice::}{readyRead()} signal has been emitted. The function + will timeout after \a msecs milliseconds; the default timeout is + 30000 milliseconds. + + The function returns true if the readyRead() signal is emitted and + there is new data available for reading; otherwise it returns false + (if an error occurred or the operation timed out). + */ + +bool QPacketProtocol::waitForReadyRead(int msecs) +{ + if (!d->packets.isEmpty()) + return true; + + QElapsedTimer stopWatch; + stopWatch.start(); + + d->waitingForPacket = true; + do { + if (!d->dev->waitForReadyRead(msecs)) + return false; + if (!d->waitingForPacket) + return true; + msecs = qt_timeout_value(msecs, stopWatch.elapsed()); + } while (true); +} + /*! Return the QIODevice passed to the QPacketProtocol constructor. */ diff --git a/src/declarative/debugger/qpacketprotocol_p.h b/src/declarative/debugger/qpacketprotocol_p.h index accb8ef..22bc3c2 100644 --- a/src/declarative/debugger/qpacketprotocol_p.h +++ b/src/declarative/debugger/qpacketprotocol_p.h @@ -75,6 +75,8 @@ public: qint64 packetsAvailable() const; QPacket read(); + bool waitForReadyRead(int msecs = 3000); + void clear(); QIODevice * device(); diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index f30831d..a3395a4 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1499,6 +1499,7 @@ void QDeclarativeGridView::setDelegate(QDeclarativeComponent *delegate) d->ownModel = true; } if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model)) { + int oldCount = dataModel->count(); dataModel->setDelegate(delegate); if (isComponentComplete()) { for (int i = 0; i < d->visibleItems.count(); ++i) @@ -1516,6 +1517,8 @@ void QDeclarativeGridView::setDelegate(QDeclarativeComponent *delegate) } d->moveReason = QDeclarativeGridViewPrivate::Other; } + if (oldCount != dataModel->count()) + emit countChanged(); emit delegateChanged(); } } diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp index 3190d7e..ef6b032 100644 --- a/src/declarative/graphicsitems/qdeclarativelistview.cpp +++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp @@ -733,6 +733,7 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) if (doBuffer && (bufferMode & BufferBefore)) fillFrom = bufferFrom; + bool haveValidItems = false; int modelIndex = visibleIndex; qreal itemEnd = visiblePos-1; if (!visibleItems.isEmpty()) { @@ -741,11 +742,13 @@ void QDeclarativeListViewPrivate::refill(qreal from, qreal to, bool doBuffer) int i = visibleItems.count() - 1; while (i > 0 && visibleItems.at(i)->index == -1) --i; - if (visibleItems.at(i)->index != -1) + if (visibleItems.at(i)->index != -1) { + haveValidItems = true; modelIndex = visibleItems.at(i)->index + 1; + } } - if (visibleItems.count() && (fillFrom > itemEnd+averageSize+spacing + if (haveValidItems && (fillFrom > itemEnd+averageSize+spacing || fillTo < visiblePos - averageSize - spacing)) { // We've jumped more than a page. Estimate which items are now // visible and fill from there. @@ -1813,6 +1816,7 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) d->ownModel = true; } if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model)) { + int oldCount = dataModel->count(); dataModel->setDelegate(delegate); if (isComponentComplete()) { for (int i = 0; i < d->visibleItems.count(); ++i) @@ -1831,6 +1835,8 @@ void QDeclarativeListView::setDelegate(QDeclarativeComponent *delegate) } d->updateViewport(); } + if (oldCount != dataModel->count()) + emit countChanged(); } emit delegateChanged(); } @@ -3403,9 +3409,9 @@ void QDeclarativeListView::itemsRemoved(int modelIndex, int count) } } - if (removedVisible && !haveVisibleIndex) { + if (!haveVisibleIndex) { d->timeline.clear(); - if (d->itemCount == 0) { + if (removedVisible && d->itemCount == 0) { d->visibleIndex = 0; d->visiblePos = d->header ? d->header->size() : 0; d->setPosition(0); diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp index d4e7f7b..6633256 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp +++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp @@ -660,6 +660,32 @@ void QDeclarativeMouseArea::hoverLeaveEvent(QGraphicsSceneHoverEvent *event) setHovered(false); } +#ifndef QT_NO_CONTEXTMENU +void QDeclarativeMouseArea::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) +{ + bool acceptsContextMenuButton; +#if defined(Q_OS_SYMBIAN) + // In Symbian a Long Tap on the screen will trigger. See QSymbianControl::HandleLongTapEventL(). + acceptsContextMenuButton = acceptedButtons() & Qt::LeftButton; +#elif defined(Q_WS_WINCE) + // ### WinCE can trigger context menu event with a gesture in the left button or a + // click with the right button. Since we have no way here to differentiate them when + // event happens, accepting either of the them will block the event. + acceptsContextMenuButton = acceptedButtons() & (Qt::LeftButton | Qt::RightButton); +#else + acceptsContextMenuButton = acceptedButtons() & Qt::RightButton; +#endif + + if (isEnabled() && event->reason() == QGraphicsSceneContextMenuEvent::Mouse + && acceptsContextMenuButton) { + // Do not let the context menu event propagate to items behind. + return; + } + + QDeclarativeItem::contextMenuEvent(event); +} +#endif // QT_NO_CONTEXTMENU + bool QDeclarativeMouseArea::sceneEvent(QEvent *event) { bool rv = QDeclarativeItem::sceneEvent(event); diff --git a/src/declarative/graphicsitems/qdeclarativemousearea_p.h b/src/declarative/graphicsitems/qdeclarativemousearea_p.h index 351d4de..0fe8c6a 100644 --- a/src/declarative/graphicsitems/qdeclarativemousearea_p.h +++ b/src/declarative/graphicsitems/qdeclarativemousearea_p.h @@ -190,6 +190,9 @@ protected: void hoverEnterEvent(QGraphicsSceneHoverEvent *event); void hoverMoveEvent(QGraphicsSceneHoverEvent *event); void hoverLeaveEvent(QGraphicsSceneHoverEvent *event); +#ifndef QT_NO_CONTEXTMENU + void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); +#endif // QT_NO_CONTEXTMENU bool sceneEvent(QEvent *); bool sendMouseEvent(QGraphicsSceneMouseEvent *event); bool sceneEventFilter(QGraphicsItem *i, QEvent *e); diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index aed849b..be2bd60 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -1021,9 +1021,12 @@ void QDeclarativePathView::setDelegate(QDeclarativeComponent *delegate) d->ownModel = true; } if (QDeclarativeVisualDataModel *dataModel = qobject_cast<QDeclarativeVisualDataModel*>(d->model)) { + int oldCount = dataModel->count(); dataModel->setDelegate(delegate); d->modelCount = dataModel->count(); d->regenerate(); + if (oldCount != dataModel->count()) + emit countChanged(); emit delegateChanged(); } } diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp index af2c8f3..ca78593 100644 --- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp @@ -273,7 +273,6 @@ void QDeclarativeTextEdit::setText(const QString &text) \o TextEdit.AutoText \o TextEdit.PlainText \o TextEdit.RichText - \o TextEdit.StyledText \endlist The default is TextEdit.AutoText. If the text format is TextEdit.AutoText the text edit diff --git a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp index 97ce059..4c839a1 100644 --- a/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp +++ b/src/declarative/graphicsitems/qdeclarativevisualitemmodel.cpp @@ -1398,7 +1398,12 @@ void QDeclarativeVisualDataModel::_q_layoutChanged() void QDeclarativeVisualDataModel::_q_modelReset() { + Q_D(QDeclarativeVisualDataModel); + d->m_root = QModelIndex(); emit modelReset(); + emit rootIndexChanged(); + if (d->m_abstractItemModel && d->m_abstractItemModel->canFetchMore(d->m_root)) + d->m_abstractItemModel->fetchMore(d->m_root); } void QDeclarativeVisualDataModel::_q_createdPackage(int index, QDeclarativePackage *package) diff --git a/src/declarative/qml/qdeclarative.h b/src/declarative/qml/qdeclarative.h index 5da7901..28a6be4 100644 --- a/src/declarative/qml/qdeclarative.h +++ b/src/declarative/qml/qdeclarative.h @@ -405,6 +405,17 @@ QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true) return qmlAttachedPropertiesObject(&idx, obj, &T::staticMetaObject, create); } +// Enable debugging before any QDeclarativeEngine is created +struct Q_DECLARATIVE_EXPORT QDeclarativeDebuggingEnabler +{ + QDeclarativeDebuggingEnabler(); +}; + +// Execute code in constructor before first QDeclarativeEngine is instantiated +#if defined(QT_DECLARATIVE_DEBUG) +static QDeclarativeDebuggingEnabler qmlEnableDebuggingHelper; +#endif + QT_END_NAMESPACE QML_DECLARE_TYPE(QObject) diff --git a/src/declarative/qml/qdeclarativedirparser.cpp b/src/declarative/qml/qdeclarativedirparser.cpp index b5ad33d..362b99c 100644 --- a/src/declarative/qml/qdeclarativedirparser.cpp +++ b/src/declarative/qml/qdeclarativedirparser.cpp @@ -160,6 +160,16 @@ bool QDeclarativeDirParser::parse() Component entry(sections[1], sections[2], -1, -1); entry.internal = true; _components.append(entry); + } else if (sections[0] == QLatin1String("typeinfo")) { + if (sectionCount != 2) { + reportError(lineNumber, -1, + QString::fromUtf8("typeinfo requires 1 argument, but %1 were provided").arg(sectionCount - 1)); + continue; + } +#ifdef QT_CREATOR + TypeInfo typeInfo(sections[1]); + _typeInfos.append(typeInfo); +#endif } else if (sectionCount == 2) { // No version specified (should only be used for relative qmldir files) @@ -229,4 +239,11 @@ QList<QDeclarativeDirParser::Component> QDeclarativeDirParser::components() cons return _components; } +#ifdef QT_CREATOR +QList<TypeInfo> QDeclarativeDirParser::typeInfos() const +{ + return _typeInfos; +} +#endif + QT_END_NAMESPACE diff --git a/src/declarative/qml/qdeclarativedirparser_p.h b/src/declarative/qml/qdeclarativedirparser_p.h index 95f14bc..d09b90e 100644 --- a/src/declarative/qml/qdeclarativedirparser_p.h +++ b/src/declarative/qml/qdeclarativedirparser_p.h @@ -109,6 +109,19 @@ public: QList<Component> components() const; QList<Plugin> plugins() const; +#ifdef QT_CREATOR + struct TypeInfo + { + TypeInfo() {} + TypeInfo(const QString &fileName) + : fileName(fileName) {} + + QString fileName; + }; + + QList<TypeInfo> typeInfos() const; +#endif + private: void reportError(int line, int column, const QString &message); @@ -118,6 +131,9 @@ private: QString _source; QList<Component> _components; QList<Plugin> _plugins; +#ifdef QT_CREATOR + QList<TypeInfo> _typeInfos; +#endif unsigned _isParsed: 1; }; diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp index 9fde18c..aa4bcd4 100644 --- a/src/declarative/qml/qdeclarativeengine.cpp +++ b/src/declarative/qml/qdeclarativeengine.cpp @@ -71,6 +71,7 @@ #include "private/qdeclarativenotifier_p.h" #include "private/qdeclarativedebugtrace_p.h" #include "private/qdeclarativeapplication_p.h" +#include "private/qjsdebugservice_p.h" #include <QtCore/qmetaobject.h> #include <QScriptClass> @@ -123,7 +124,7 @@ QT_BEGIN_NAMESPACE \brief The QtObject element is the most basic element in QML. The QtObject element is a non-visual element which contains only the - objectName property. + objectName property. It can be useful to create a QtObject if you need an extremely lightweight element to enclose a set of custom properties: @@ -138,7 +139,7 @@ QT_BEGIN_NAMESPACE This property holds the QObject::objectName for this specific object instance. This allows a C++ application to locate an item within a QML component - using the QObject::findChild() method. For example, the following C++ + using the QObject::findChild() method. For example, the following C++ application locates the child \l Rectangle item and dynamically changes its \c color value: @@ -152,7 +153,7 @@ QT_BEGIN_NAMESPACE Rectangle { anchors.fill: parent - color: "red" + color: "red" objectName: "myRect" } } @@ -166,7 +167,7 @@ QT_BEGIN_NAMESPACE view.show(); QDeclarativeItem *item = view.rootObject()->findChild<QDeclarativeItem*>("myRect"); - if (item) + if (item) item->setProperty("color", QColor(Qt::yellow)); \endcode */ @@ -202,7 +203,7 @@ void QDeclarativeEnginePrivate::defineModule() \keyword QmlGlobalQtObject -\brief The \c Qt object provides useful enums and functions from Qt, for use in all QML files. +\brief The \c Qt object provides useful enums and functions from Qt, for use in all QML files. The \c Qt object is a global object with utility functions, properties and enums. @@ -583,6 +584,7 @@ void QDeclarativeEnginePrivate::init() QDeclarativeEngineDebugServer::isDebuggingEnabled()) { isDebugging = true; QDeclarativeEngineDebugServer::instance()->addEngine(q); + QJSDebugService::instance()->addEngine(q); } } @@ -645,8 +647,10 @@ QDeclarativeEngine::QDeclarativeEngine(QObject *parent) QDeclarativeEngine::~QDeclarativeEngine() { Q_D(QDeclarativeEngine); - if (d->isDebugging) + if (d->isDebugging) { QDeclarativeEngineDebugServer::instance()->remEngine(this); + QJSDebugService::instance()->removeEngine(this); + } } /*! \fn void QDeclarativeEngine::quit() @@ -757,7 +761,7 @@ QNetworkAccessManager *QDeclarativeEngine::networkAccessManager() const /*! Sets the \a provider to use for images requested via the \e - image: url scheme, with host \a providerId. The QDeclarativeEngine + image: url scheme, with host \a providerId. The QDeclarativeEngine takes ownership of \a provider. Image providers enable support for pixmap and threaded image @@ -1066,7 +1070,7 @@ QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool cre rv = pf(const_cast<QObject *>(object)); - if (rv) + if (rv) data->attachedProperties()->insert(id, rv); return rv; @@ -1084,6 +1088,17 @@ QObject *qmlAttachedPropertiesObject(int *idCache, const QObject *object, return qmlAttachedPropertiesObjectById(*idCache, object, create); } +QDeclarativeDebuggingEnabler::QDeclarativeDebuggingEnabler() +{ +#ifndef QDECLARATIVE_NO_DEBUG_PROTOCOL + if (!QDeclarativeEnginePrivate::qml_debugging_enabled) { + qWarning("Qml debugging is enabled. Only use this in a safe environment!"); + } + QDeclarativeEnginePrivate::qml_debugging_enabled = true; +#endif +} + + class QDeclarativeDataExtended { public: QDeclarativeDataExtended(); @@ -1258,7 +1273,7 @@ Returns a \l Component object created using the QML file at the specified \a url or \c null if an empty string was given. The returned component's \l Component::status property indicates whether the -component was successfully created. If the status is \c Component.Error, +component was successfully created. If the status is \c Component.Error, see \l Component::errorString() for an error description. Call \l {Component::createObject()}{Component.createObject()} on the returned @@ -1311,6 +1326,8 @@ Example (where \c parentItem is the id of an existing QML item): In the case of an error, a QtScript Error object is thrown. This object has an additional property, \c qmlErrors, which is an array of the errors encountered. Each object in this array has the members \c lineNumber, \c columnNumber, \c fileName and \c message. +For example, if the above snippet had misspelled color as 'colro' then the array would contain an object like the following: +{ "lineNumber" : 1, "columnNumber" : 32, "fileName" : "dynamicSnippet1", "message" : "Cannot assign to non-existent property \"colro\""}. Note that this function returns immediately, and therefore may not work if the \a qml string loads new components (that is, external QML files that have not yet been loaded). @@ -1618,7 +1635,7 @@ QScriptValue QDeclarativeEnginePrivate::formatDateTime(QScriptContext*ctxt, QScr return engine->newVariant(QVariant::fromValue(date.toString(format))); } else if (formatArg.isNumber()) { enumFormat = Qt::DateFormat(formatArg.toUInt32()); - } else { + } else { return ctxt->throwError(QLatin1String("Qt.formatDateTime(): Invalid datetime format")); } } @@ -1683,7 +1700,7 @@ QScriptValue QDeclarativeEnginePrivate::hsla(QScriptContext *ctxt, QScriptEngine } /*! -\qmlmethod rect Qt::rect(int x, int y, int width, int height) +\qmlmethod rect Qt::rect(int x, int y, int width, int height) Returns a \c rect with the top-left corner at \c x, \c y and the specified \c width and \c height. @@ -1855,7 +1872,7 @@ Binary to ASCII - this function returns a base64 encoding of \c data. */ QScriptValue QDeclarativeEnginePrivate::btoa(QScriptContext *ctxt, QScriptEngine *) { - if (ctxt->argumentCount() != 1) + if (ctxt->argumentCount() != 1) return ctxt->throwError(QLatin1String("Qt.btoa(): Invalid arguments")); QByteArray data = ctxt->argument(0).toString().toUtf8(); @@ -1870,7 +1887,7 @@ ASCII to binary - this function returns a base64 decoding of \c data. QScriptValue QDeclarativeEnginePrivate::atob(QScriptContext *ctxt, QScriptEngine *) { - if (ctxt->argumentCount() != 1) + if (ctxt->argumentCount() != 1) return ctxt->throwError(QLatin1String("Qt.atob(): Invalid arguments")); QByteArray data = ctxt->argument(0).toString().toUtf8(); @@ -2289,7 +2306,7 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(const QMetaObj } } -QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion, +QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeType *type, int minorVersion, QDeclarativeError &error) { QList<QDeclarativeType *> types; @@ -2298,7 +2315,7 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeTy const QMetaObject *metaObject = type->metaObject(); while (metaObject) { - QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(), + QDeclarativeType *t = QDeclarativeMetaType::qmlType(metaObject, type->module(), type->majorVersion(), minorVersion); if (t) { maxMinorVersion = qMax(maxMinorVersion, t->minorVersion()); @@ -2342,7 +2359,7 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeTy // Signals override: // * other signals and methods of the same name. - // * properties named on<Signal Name> + // * properties named on<Signal Name> // * automatic <property name>Changed notify signals // Methods override: @@ -2367,7 +2384,7 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeTy QDeclarativePropertyCache::Data *current = d; while (!overloadError && current) { current = d->overrideData(current); - if (current && raw->isAllowedInRevision(current)) + if (current && raw->isAllowedInRevision(current)) overloadError = true; } } @@ -2375,7 +2392,7 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::createCache(QDeclarativeTy if (overloadError) { if (hasCopied) raw->release(); - + error.setDescription(QLatin1String("Type ") + QString::fromUtf8(type->qmlTypeName()) + QLatin1String(" ") + QString::number(type->majorVersion()) + QLatin1String(".") + QString::number(minorVersion) + QLatin1String(" contains an illegal property \"") + overloadName + QLatin1String("\". This is an error in the type's implementation.")); return 0; } diff --git a/src/declarative/qml/qdeclarativeengine_p.h b/src/declarative/qml/qdeclarativeengine_p.h index 88b4e80..fd851f7 100644 --- a/src/declarative/qml/qdeclarativeengine_p.h +++ b/src/declarative/qml/qdeclarativeengine_p.h @@ -95,7 +95,6 @@ class QDeclarativeImportDatabase; class QDeclarativeObjectScriptClass; class QDeclarativeTypeNameScriptClass; class QDeclarativeValueTypeScriptClass; -class QScriptEngineDebugger; class QNetworkReply; class QNetworkAccessManager; class QDeclarativeNetworkAccessManagerFactory; @@ -332,14 +331,14 @@ public: /*! Returns a QDeclarativePropertyCache for \a obj if one is available. -If \a obj is null, being deleted or contains a dynamic meta object 0 +If \a obj is null, being deleted or contains a dynamic meta object 0 is returned. The returned cache is not referenced, so if it is to be stored, call addref(). */ -QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(QObject *obj) +QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(QObject *obj) { - if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted) + if (!obj || QObjectPrivate::get(obj)->metaObject || QObjectPrivate::get(obj)->wasDeleted) return 0; const QMetaObject *mo = obj->metaObject(); @@ -349,10 +348,10 @@ QDeclarativePropertyCache *QDeclarativeEnginePrivate::cache(QObject *obj) } /*! -Returns a QDeclarativePropertyCache for \a metaObject. +Returns a QDeclarativePropertyCache for \a metaObject. As the cache is persisted for the life of the engine, \a metaObject must be -a static "compile time" meta-object, or a meta-object that is otherwise known to +a static "compile time" meta-object, or a meta-object that is otherwise known to exist for the lifetime of the QDeclarativeEngine. The returned cache is not referenced, so if it is to be stored, call addref(). diff --git a/src/declarative/qml/qdeclarativeenginedebug.cpp b/src/declarative/qml/qdeclarativeenginedebug.cpp index b2a05c3..b7b88c9 100644 --- a/src/declarative/qml/qdeclarativeenginedebug.cpp +++ b/src/declarative/qml/qdeclarativeenginedebug.cpp @@ -524,8 +524,13 @@ void QDeclarativeEngineDebugServer::messageReceived(const QByteArray &message) QString propertyName; QVariant expr; bool isLiteralValue; + QString filename; + int line; ds >> objectId >> propertyName >> expr >> isLiteralValue; - setBinding(objectId, propertyName, expr, isLiteralValue); + if (!ds.atEnd()) { // backward compatibility from 2.1, 2.2 + ds >> filename >> line; + } + setBinding(objectId, propertyName, expr, isLiteralValue, filename, line); } else if (type == "RESET_BINDING") { int objectId; QString propertyName; @@ -543,7 +548,9 @@ void QDeclarativeEngineDebugServer::messageReceived(const QByteArray &message) void QDeclarativeEngineDebugServer::setBinding(int objectId, const QString &propertyName, const QVariant &expression, - bool isLiteralValue) + bool isLiteralValue, + QString filename, + int line) { QObject *object = objectForId(objectId); QDeclarativeContext *context = qmlContext(object); @@ -565,6 +572,7 @@ void QDeclarativeEngineDebugServer::setBinding(int objectId, newBinding = new QDeclarativeBinding(expression.toString(), object, context); newBinding->setTarget(property); newBinding->setNotifyOnValueChanged(true); + newBinding->setSourceLocation(filename, line); } state->changeBindingInRevertList(object, propertyName, newBinding); @@ -580,11 +588,12 @@ void QDeclarativeEngineDebugServer::setBinding(int objectId, property.write(expression); } else if (hasValidSignal(object, propertyName)) { QDeclarativeExpression *declarativeExpression = new QDeclarativeExpression(context, object, expression.toString()); - QDeclarativeExpression *oldExpression = QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression); - declarativeExpression->setSourceLocation(oldExpression->sourceFile(), oldExpression->lineNumber()); + QDeclarativePropertyPrivate::setSignalExpression(property, declarativeExpression); + declarativeExpression->setSourceLocation(filename, line); } else if (property.isProperty()) { QDeclarativeBinding *binding = new QDeclarativeBinding(expression.toString(), object, context); binding->setTarget(property); + binding->setSourceLocation(filename, line); binding->setNotifyOnValueChanged(true); QDeclarativeAbstractBinding *oldBinding = QDeclarativePropertyPrivate::setBinding(property, binding); if (oldBinding) @@ -644,7 +653,10 @@ void QDeclarativeEngineDebugServer::resetBinding(int objectId, const QString &pr } } } - } else { + } else if (hasValidSignal(object, propertyName)) { + QDeclarativeProperty property(object, propertyName, context); + QDeclarativePropertyPrivate::setSignalExpression(property, 0); + } else { if (QDeclarativePropertyChanges *propertyChanges = qobject_cast<QDeclarativePropertyChanges *>(object)) { propertyChanges->removeProperty(propertyName); } diff --git a/src/declarative/qml/qdeclarativeenginedebug_p.h b/src/declarative/qml/qdeclarativeenginedebug_p.h index e95676c..64b2724 100644 --- a/src/declarative/qml/qdeclarativeenginedebug_p.h +++ b/src/declarative/qml/qdeclarativeenginedebug_p.h @@ -115,7 +115,7 @@ private: QDeclarativeObjectData objectData(QObject *); QDeclarativeObjectProperty propertyData(QObject *, int); QVariant valueContents(const QVariant &defaultValue) const; - void setBinding(int objectId, const QString &propertyName, const QVariant &expression, bool isLiteralValue); + void setBinding(int objectId, const QString &propertyName, const QVariant &expression, bool isLiteralValue, QString filename = QString(), int line = -1); void resetBinding(int objectId, const QString &propertyName); void setMethodBody(int objectId, const QString &method, const QString &body); diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index 9eecc65..edc1755 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -403,6 +403,33 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj, } else if (value.isFunction() && !value.isRegExp()) { // this is handled by the binding creation above } else { + //### expand optimization for other known types + if (lastData->propType == QMetaType::Int && value.isNumber()) { + int rawValue = qRound(value.toNumber()); + int status = -1; + int flags = 0; + void *a[] = { (void *)&rawValue, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, + lastData->coreIndex, a); + return; + } else if (lastData->propType == QMetaType::QReal && value.isNumber()) { + qreal rawValue = qreal(value.toNumber()); + int status = -1; + int flags = 0; + void *a[] = { (void *)&rawValue, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, + lastData->coreIndex, a); + return; + } else if (lastData->propType == QMetaType::QString && value.isString()) { + const QString &rawValue = value.toString(); + int status = -1; + int flags = 0; + void *a[] = { (void *)&rawValue, 0, &status, &flags }; + QMetaObject::metacall(obj, QMetaObject::WriteProperty, + lastData->coreIndex, a); + return; + } + QVariant v; if (lastData->flags & QDeclarativePropertyCache::Data::IsQList) v = enginePriv->scriptValueToVariant(value, qMetaTypeId<QList<QObject *> >()); diff --git a/src/declarative/qml/qdeclarativeproperty.cpp b/src/declarative/qml/qdeclarativeproperty.cpp index 7f74da4..253d744 100644 --- a/src/declarative/qml/qdeclarativeproperty.cpp +++ b/src/declarative/qml/qdeclarativeproperty.cpp @@ -1451,6 +1451,7 @@ QByteArray QDeclarativePropertyPrivate::saveValueType(const QMetaObject *metaObj QMetaProperty subProp = subObject->property(subIndex); ValueTypeSerializedData sd; + memset(&sd, 0, sizeof(sd)); sd.isValueType = true; sd.core.load(metaObject->property(index)); sd.valueType.flags = QDeclarativePropertyCache::Data::flagsForProperty(subProp); @@ -1465,6 +1466,7 @@ QByteArray QDeclarativePropertyPrivate::saveValueType(const QMetaObject *metaObj QByteArray QDeclarativePropertyPrivate::saveProperty(const QMetaObject *metaObject, int index) { SerializedData sd; + memset(&sd, 0, sizeof(sd)); sd.isValueType = false; sd.core.load(metaObject->property(index)); diff --git a/src/declarative/qml/qmetaobjectbuilder.cpp b/src/declarative/qml/qmetaobjectbuilder.cpp index dc941e2..d8a7b77 100644 --- a/src/declarative/qml/qmetaobjectbuilder.cpp +++ b/src/declarative/qml/qmetaobjectbuilder.cpp @@ -101,7 +101,7 @@ bool isVariantType(const char* type) return qvariant_nameToType(type) != 0; } -// copied from qmetaobject.cpp +// copied from qmetaobject_p.h // do not touch without touching the moc as well enum PropertyFlags { Invalid = 0x00000000, @@ -111,6 +111,8 @@ enum PropertyFlags { EnumOrFlag = 0x00000008, StdCppSet = 0x00000100, // Override = 0x00000200, + Constant = 0x00000400, + Final = 0x00000800, Designable = 0x00001000, ResolveDesignable = 0x00002000, Scriptable = 0x00004000, @@ -618,6 +620,8 @@ QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty& protot property.setUser(prototype.isUser()); property.setStdCppSet(prototype.hasStdCppSet()); property.setEnumOrFlag(prototype.isEnumType()); + property.setConstant(prototype.isConstant()); + property.setFinal(prototype.isFinal()); if (prototype.hasNotifySignal()) { // Find an existing method for the notify signal, or add a new one. QMetaMethod method = prototype.notifySignal(); @@ -1448,6 +1452,7 @@ QMetaObject *QMetaObjectBuilder::toMetaObject() const { int size = buildMetaObject(d, 0, false); char *buf = reinterpret_cast<char *>(qMalloc(size)); + memset(buf, 0, size); buildMetaObject(d, buf, false); return reinterpret_cast<QMetaObject *>(buf); } @@ -1477,6 +1482,7 @@ QByteArray QMetaObjectBuilder::toRelocatableData(bool *ok) const QByteArray data; data.resize(size); char *buf = data.data(); + memset(buf, 0, size); buildMetaObject(d, buf, true); if (ok) *ok = true; return data; @@ -2278,6 +2284,32 @@ bool QMetaPropertyBuilder::isEnumOrFlag() const } /*! + Returns true if the property is constant; otherwise returns false. + The default value is false. +*/ +bool QMetaPropertyBuilder::isConstant() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Constant); + else + return false; +} + +/*! + Returns true if the property is final; otherwise returns false. + The default value is false. +*/ +bool QMetaPropertyBuilder::isFinal() const +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + return d->flag(Final); + else + return false; +} + +/*! Sets this property to readable if \a value is true. \sa isReadable(), setWritable() @@ -2401,6 +2433,31 @@ void QMetaPropertyBuilder::setEnumOrFlag(bool value) } /*! + Sets the \c CONSTANT flag on this property to \a value. + + \sa isConstant() +*/ +void QMetaPropertyBuilder::setConstant(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Constant, value); +} + +/*! + Sets the \c FINAL flag on this property to \a value. + + \sa isFinal() +*/ +void QMetaPropertyBuilder::setFinal(bool value) +{ + QMetaPropertyBuilderPrivate *d = d_func(); + if (d) + d->setFlag(Final, value); +} + + +/*! \class QMetaEnumBuilder \internal \brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder. diff --git a/src/declarative/qml/qmetaobjectbuilder_p.h b/src/declarative/qml/qmetaobjectbuilder_p.h index d7085f8..335a825 100644 --- a/src/declarative/qml/qmetaobjectbuilder_p.h +++ b/src/declarative/qml/qmetaobjectbuilder_p.h @@ -258,6 +258,8 @@ public: bool isUser() const; bool hasStdCppSet() const; bool isEnumOrFlag() const; + bool isConstant() const; + bool isFinal() const; void setReadable(bool value); void setWritable(bool value); @@ -269,6 +271,8 @@ public: void setUser(bool value); void setStdCppSet(bool value); void setEnumOrFlag(bool value); + void setConstant(bool value); + void setFinal(bool value); private: const QMetaObjectBuilder *_mobj; diff --git a/src/declarative/util/qdeclarativeview.cpp b/src/declarative/util/qdeclarativeview.cpp index e24f80f..628c82c 100644 --- a/src/declarative/util/qdeclarativeview.cpp +++ b/src/declarative/util/qdeclarativeview.cpp @@ -49,6 +49,7 @@ #include <qdeclarativeguard_p.h> #include <private/qdeclarativedebugtrace_p.h> +#include <private/qdeclarativeobserverservice_p.h> #include <qscriptvalueiterator.h> #include <qdebug.h> @@ -299,6 +300,8 @@ void QDeclarativeViewPrivate::init() q->viewport()->setAttribute(Qt::WA_OpaquePaintEvent); q->viewport()->setAttribute(Qt::WA_NoSystemBackground); #endif + + QDeclarativeObserverService::instance()->addView(q); } /*! @@ -306,6 +309,7 @@ void QDeclarativeViewPrivate::init() */ QDeclarativeView::~QDeclarativeView() { + QDeclarativeObserverService::instance()->removeView(this); } /*! \property QDeclarativeView::source @@ -558,7 +562,6 @@ void QDeclarativeView::continueExecute() emit statusChanged(status()); } - /*! \internal */ diff --git a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp index 48cbec3..78918cc 100644 --- a/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp +++ b/src/gui/graphicsview/qgraphicsanchorlayout_p.cpp @@ -451,8 +451,8 @@ static QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> getFactor(qreal valu static qreal interpolate(const QPair<QGraphicsAnchorLayoutPrivate::Interval, qreal> &factor, qreal min, qreal minPref, qreal pref, qreal maxPref, qreal max) { - qreal lower; - qreal upper; + qreal lower = 0; + qreal upper = 0; switch (factor.first) { case QGraphicsAnchorLayoutPrivate::MinimumToMinPreferred: diff --git a/src/gui/graphicsview/qgraphicslayout.cpp b/src/gui/graphicsview/qgraphicslayout.cpp index 904a3de..a67ae48 100644 --- a/src/gui/graphicsview/qgraphicslayout.cpp +++ b/src/gui/graphicsview/qgraphicslayout.cpp @@ -167,7 +167,7 @@ QGraphicsLayout::QGraphicsLayout(QGraphicsLayoutItem *parent) " neither a QGraphicsWidget nor QGraphicsLayout"); } } - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, QSizePolicy::DefaultType); + d_func()->sizePolicy = QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, QSizePolicy::DefaultType); setOwnedByLayout(true); } @@ -188,7 +188,7 @@ QGraphicsLayout::QGraphicsLayout(QGraphicsLayoutPrivate &dd, QGraphicsLayoutItem " neither a QGraphicsWidget nor QGraphicsLayout"); } } - setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, QSizePolicy::DefaultType); + d_func()->sizePolicy = QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding, QSizePolicy::DefaultType); setOwnedByLayout(true); } @@ -269,12 +269,20 @@ void QGraphicsLayout::activate() return; Q_ASSERT(!parentItem->isLayout()); - setGeometry(parentItem->contentsRect()); // relayout children + if (QGraphicsLayout::instantInvalidatePropagation()) { + QGraphicsWidget *parentWidget = static_cast<QGraphicsWidget*>(parentItem); + if (!parentWidget->parentLayoutItem()) { + // we've reached the topmost widget, resize it + bool wasResized = parentWidget->testAttribute(Qt::WA_Resized); + parentWidget->resize(parentWidget->size()); + parentWidget->setAttribute(Qt::WA_Resized, wasResized); + } - // ### bug, should be parentItem ? - parentLayoutItem()->updateGeometry(); // bubble up; will set activated to false - // ### too many resizes? maybe we should walk up the chain to the - // ### top-level layouted layoutItem and call activate there. + setGeometry(parentItem->contentsRect()); // relayout children + } else { + setGeometry(parentItem->contentsRect()); // relayout children + parentLayoutItem()->updateGeometry(); + } } /*! @@ -300,32 +308,36 @@ bool QGraphicsLayout::isActivated() const */ void QGraphicsLayout::invalidate() { - // only mark layouts as invalid (activated = false) if we can post a LayoutRequest event. - QGraphicsLayoutItem *layoutItem = this; - while (layoutItem && layoutItem->isLayout()) { - // we could call updateGeometry(), but what if that method - // does not call the base implementation? In addition, updateGeometry() - // does more than we need. - layoutItem->d_func()->sizeHintCacheDirty = true; - layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; - layoutItem = layoutItem->parentLayoutItem(); - } - if (layoutItem) { - layoutItem->d_func()->sizeHintCacheDirty = true; - layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; - } - - bool postIt = layoutItem ? !layoutItem->isLayout() : false; - if (postIt) { - layoutItem = this; - while (layoutItem && layoutItem->isLayout() - && static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated) { - static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated = false; + if (QGraphicsLayout::instantInvalidatePropagation()) { + updateGeometry(); + } else { + // only mark layouts as invalid (activated = false) if we can post a LayoutRequest event. + QGraphicsLayoutItem *layoutItem = this; + while (layoutItem && layoutItem->isLayout()) { + // we could call updateGeometry(), but what if that method + // does not call the base implementation? In addition, updateGeometry() + // does more than we need. + layoutItem->d_func()->sizeHintCacheDirty = true; + layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; layoutItem = layoutItem->parentLayoutItem(); } - if (layoutItem && !layoutItem->isLayout()) { - // If a layout has a parent that is not a layout it must be a QGraphicsWidget. - QApplication::postEvent(static_cast<QGraphicsWidget *>(layoutItem), new QEvent(QEvent::LayoutRequest)); + if (layoutItem) { + layoutItem->d_func()->sizeHintCacheDirty = true; + layoutItem->d_func()->sizeHintWithConstraintCacheDirty = true; + } + + bool postIt = layoutItem ? !layoutItem->isLayout() : false; + if (postIt) { + layoutItem = this; + while (layoutItem && layoutItem->isLayout() + && static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated) { + static_cast<QGraphicsLayout*>(layoutItem)->d_func()->activated = false; + layoutItem = layoutItem->parentLayoutItem(); + } + if (layoutItem && !layoutItem->isLayout()) { + // If a layout has a parent that is not a layout it must be a QGraphicsWidget. + QApplication::postEvent(static_cast<QGraphicsWidget *>(layoutItem), new QEvent(QEvent::LayoutRequest)); + } } } } @@ -335,12 +347,27 @@ void QGraphicsLayout::invalidate() */ void QGraphicsLayout::updateGeometry() { - QGraphicsLayoutItem::updateGeometry(); - if (QGraphicsLayoutItem *parentItem = parentLayoutItem()) { - if (parentItem->isLayout()) { + Q_D(QGraphicsLayout); + if (QGraphicsLayout::instantInvalidatePropagation()) { + d->activated = false; + QGraphicsLayoutItem::updateGeometry(); + + QGraphicsLayoutItem *parentItem = parentLayoutItem(); + if (!parentItem) + return; + + if (parentItem->isLayout()) + static_cast<QGraphicsLayout *>(parentItem)->invalidate(); + else parentItem->updateGeometry(); - } else { - invalidate(); + } else { + QGraphicsLayoutItem::updateGeometry(); + if (QGraphicsLayoutItem *parentItem = parentLayoutItem()) { + if (parentItem->isLayout()) { + parentItem->updateGeometry(); + } else { + invalidate(); + } } } } @@ -446,6 +473,50 @@ void QGraphicsLayout::addChildLayoutItem(QGraphicsLayoutItem *layoutItem) d->addChildLayoutItem(layoutItem); } +static bool g_instantInvalidatePropagation = false; + +/*! + \internal + \since 4.8 + \see instantInvalidatePropagation + + Calling this function with \a enable set to true will enable a feature that + makes propagation of invalidation up to ancestor layout items to be done in + one go. It will propagate up the parentLayoutItem() hierarchy until it has + reached the root. If the root item is a QGraphicsWidget, it will *post* a + layout request to it. When the layout request is consumed it will traverse + down the hierarchy of layouts and widgets and activate all layouts that is + invalid (not activated). This is the recommended behaviour. + + If not set it will also propagate up the parentLayoutItem() hierarchy, but + it will stop at the \i first \i widget it encounters, and post a layout + request to the widget. When the layout request is consumed, this might + cause it to continue propagation up to the parentLayoutItem() of the + widget. It will continue in this fashion until it has reached a widget with + no parentLayoutItem(). This strategy might cause drawing artifacts, since + it is not done in one go, and the consumption of layout requests might be + interleaved by consumption of paint events, which might cause significant + flicker. + Note, this is not the recommended behavior, but for compatibility reasons + this is the default behaviour. +*/ +void QGraphicsLayout::setInstantInvalidatePropagation(bool enable) +{ + g_instantInvalidatePropagation = enable; +} + +/*! + \internal + \since 4.8 + \see setInstantInvalidatePropagation + + returns true if the complete widget/layout hierarchy is rearranged in one go. +*/ +bool QGraphicsLayout::instantInvalidatePropagation() +{ + return g_instantInvalidatePropagation; +} + QT_END_NAMESPACE #endif //QT_NO_GRAPHICSVIEW diff --git a/src/gui/graphicsview/qgraphicslayout.h b/src/gui/graphicsview/qgraphicslayout.h index c622fb8..6031174 100644 --- a/src/gui/graphicsview/qgraphicslayout.h +++ b/src/gui/graphicsview/qgraphicslayout.h @@ -76,6 +76,8 @@ public: virtual QGraphicsLayoutItem *itemAt(int i) const = 0; virtual void removeAt(int index) = 0; + static void setInstantInvalidatePropagation(bool enable); + static bool instantInvalidatePropagation(); protected: QGraphicsLayout(QGraphicsLayoutPrivate &, QGraphicsLayoutItem *); void addChildLayoutItem(QGraphicsLayoutItem *layoutItem); diff --git a/src/gui/graphicsview/qgraphicslayout_p.cpp b/src/gui/graphicsview/qgraphicslayout_p.cpp index c325602..f73fb6a 100644 --- a/src/gui/graphicsview/qgraphicslayout_p.cpp +++ b/src/gui/graphicsview/qgraphicslayout_p.cpp @@ -180,8 +180,13 @@ void QGraphicsLayoutPrivate::activateRecursive(QGraphicsLayoutItem *item) { if (item->isLayout()) { QGraphicsLayout *layout = static_cast<QGraphicsLayout *>(item); - if (layout->d_func()->activated) - layout->invalidate(); + if (layout->d_func()->activated) { + if (QGraphicsLayout::instantInvalidatePropagation()) { + return; + } else { + layout->invalidate(); // ### LOOKS SUSPICIOUSLY WRONG!!??? + } + } for (int i = layout->count() - 1; i >= 0; --i) { QGraphicsLayoutItem *childItem = layout->itemAt(i); diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp index 5591638..40f9b1d 100644 --- a/src/gui/graphicsview/qgraphicslinearlayout.cpp +++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp @@ -275,17 +275,13 @@ void QGraphicsLinearLayout::insertItem(int index, QGraphicsLayoutItem *item) qWarning("QGraphicsLinearLayout::insertItem: cannot insert itself"); return; } - Q_ASSERT(item); - - //the order of the following instructions is very important because - //invalidating the layout before adding the child item will make the layout happen - //before we try to paint the item - invalidate(); d->addChildLayoutItem(item); + Q_ASSERT(item); d->fixIndex(&index); d->engine.insertRow(index, d->orientation); new QGridLayoutItem(&d->engine, item, d->gridRow(index), d->gridColumn(index), 1, 1, 0, index); + invalidate(); } /*! diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 675a5c5..141e305 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -354,8 +354,10 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) newGeom = rect; newGeom.setSize(rect.size().expandedTo(effectiveSizeHint(Qt::MinimumSize)) .boundedTo(effectiveSizeHint(Qt::MaximumSize))); - if (newGeom == d->geom) - return; + + if (newGeom == d->geom) { + goto relayoutChildrenAndReturn; + } // setPos triggers ItemPositionChange, which can adjust position wd->inSetGeometry = 1; @@ -363,8 +365,9 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) wd->inSetGeometry = 0; newGeom.moveTopLeft(pos()); - if (newGeom == d->geom) - return; + if (newGeom == d->geom) { + goto relayoutChildrenAndReturn; + } // Update and prepare to change the geometry (remove from index) if the size has changed. if (wd->scene) { @@ -375,35 +378,54 @@ void QGraphicsWidget::setGeometry(const QRectF &rect) } // Update the layout item geometry - bool moved = oldPos != pos(); - if (moved) { - // Send move event. - QGraphicsSceneMoveEvent event; - event.setOldPos(oldPos); - event.setNewPos(pos()); - QApplication::sendEvent(this, &event); - if (wd->inSetPos) { - //set the new pos - d->geom.moveTopLeft(pos()); - emit geometryChanged(); - return; + { + bool moved = oldPos != pos(); + if (moved) { + // Send move event. + QGraphicsSceneMoveEvent event; + event.setOldPos(oldPos); + event.setNewPos(pos()); + QApplication::sendEvent(this, &event); + if (wd->inSetPos) { + //set the new pos + d->geom.moveTopLeft(pos()); + emit geometryChanged(); + goto relayoutChildrenAndReturn; + } + } + QSizeF oldSize = size(); + QGraphicsLayoutItem::setGeometry(newGeom); + // Send resize event + bool resized = newGeom.size() != oldSize; + if (resized) { + QGraphicsSceneResizeEvent re; + re.setOldSize(oldSize); + re.setNewSize(newGeom.size()); + if (oldSize.width() != newGeom.size().width()) + emit widthChanged(); + if (oldSize.height() != newGeom.size().height()) + emit heightChanged(); + QGraphicsLayout *lay = wd->layout; + if (QGraphicsLayout::instantInvalidatePropagation()) { + if (!lay || lay->isActivated()) { + QApplication::sendEvent(this, &re); + } + } else { + QApplication::sendEvent(this, &re); + } } } - QSizeF oldSize = size(); - QGraphicsLayoutItem::setGeometry(newGeom); - // Send resize event - bool resized = newGeom.size() != oldSize; - if (resized) { - QGraphicsSceneResizeEvent re; - re.setOldSize(oldSize); - re.setNewSize(newGeom.size()); - if (oldSize.width() != newGeom.size().width()) - emit widthChanged(); - if (oldSize.height() != newGeom.size().height()) - emit heightChanged(); - QApplication::sendEvent(this, &re); - } + emit geometryChanged(); +relayoutChildrenAndReturn: + if (QGraphicsLayout::instantInvalidatePropagation()) { + if (QGraphicsLayout *lay = wd->layout) { + if (!lay->isActivated()) { + QEvent layoutRequest(QEvent::LayoutRequest); + QApplication::sendEvent(this, &layoutRequest); + } + } + } } /*! @@ -1052,16 +1074,31 @@ void QGraphicsWidget::updateGeometry() QGraphicsLayoutItem *parentItem = parentLayoutItem(); if (parentItem && parentItem->isLayout()) { - parentItem->updateGeometry(); + if (QGraphicsLayout::instantInvalidatePropagation()) { + static_cast<QGraphicsLayout *>(parentItem)->invalidate(); + } else { + parentItem->updateGeometry(); + } } else { if (parentItem) { + // This is for custom layouting QGraphicsWidget *parentWid = parentWidget(); //### if (parentWid->isVisible()) QApplication::postEvent(parentWid, new QEvent(QEvent::LayoutRequest)); + } else { + /** + * If this is the topmost widget, post a LayoutRequest event to the widget. + * When the event is received, it will start flowing all the way down to the leaf + * widgets in one go. This will make a relayout flicker-free. + */ + if (QGraphicsLayout::instantInvalidatePropagation()) + QApplication::postEvent(static_cast<QGraphicsWidget *>(this), new QEvent(QEvent::LayoutRequest)); + } + if (!QGraphicsLayout::instantInvalidatePropagation()) { + bool wasResized = testAttribute(Qt::WA_Resized); + resize(size()); // this will restrict the size + setAttribute(Qt::WA_Resized, wasResized); } - bool wasResized = testAttribute(Qt::WA_Resized); - resize(size()); // this will restrict the size - setAttribute(Qt::WA_Resized, wasResized); } } diff --git a/src/gui/graphicsview/qgraphicswidget_p.cpp b/src/gui/graphicsview/qgraphicswidget_p.cpp index 4580055..63d7298 100644 --- a/src/gui/graphicsview/qgraphicswidget_p.cpp +++ b/src/gui/graphicsview/qgraphicswidget_p.cpp @@ -857,8 +857,6 @@ void QGraphicsWidgetPrivate::setWidth(qreal w) if (q->geometry().width() == w) return; - QRectF oldGeom = q->geometry(); - q->setGeometry(QRectF(q->x(), q->y(), w, height())); } @@ -882,8 +880,6 @@ void QGraphicsWidgetPrivate::setHeight(qreal h) if (q->geometry().height() == h) return; - QRectF oldGeom = q->geometry(); - q->setGeometry(QRectF(q->x(), q->y(), width(), h)); } diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 50b372e..25f6295 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -4449,6 +4449,8 @@ QImage QImage::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::Transf QSize newSize = size(); newSize.scale(s, aspectMode); + newSize.rwidth() = qMax(newSize.width(), 1); + newSize.rheight() = qMax(newSize.height(), 1); if (newSize == size()) return *this; diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 34804e5..640864d 100644 --- a/src/gui/image/qpixmap.cpp +++ b/src/gui/image/qpixmap.cpp @@ -1224,12 +1224,8 @@ Qt::HANDLE QPixmap::handle() const { #if defined(Q_WS_X11) const QPixmapData *pd = pixmapData(); - if (pd) { - if (pd->classId() == QPixmapData::X11Class) - return static_cast<const QX11PixmapData*>(pd)->handle(); - else - qWarning("QPixmap::handle(): Pixmap is not an X11 class pixmap"); - } + if (pd && pd->classId() == QPixmapData::X11Class) + return static_cast<const QX11PixmapData*>(pd)->handle(); #endif return 0; } @@ -1518,6 +1514,8 @@ QPixmap QPixmap::scaled(const QSize& s, Qt::AspectRatioMode aspectMode, Qt::Tran QSize newSize = size(); newSize.scale(s, aspectMode); + newSize.rwidth() = qMax(newSize.width(), 1); + newSize.rheight() = qMax(newSize.height(), 1); if (newSize == size()) return *this; diff --git a/src/gui/image/qpixmap_mac.cpp b/src/gui/image/qpixmap_mac.cpp index 72e2aa6..e107d88 100644 --- a/src/gui/image/qpixmap_mac.cpp +++ b/src/gui/image/qpixmap_mac.cpp @@ -54,6 +54,7 @@ #include <private/qpaintengine_mac_p.h> #include <private/qt_mac_p.h> #include <private/qt_cocoa_helpers_mac_p.h> +#include <private/qapplication_p.h> #include <limits.h> #include <string.h> @@ -73,12 +74,18 @@ static int qt_pixmap_serial = 0; Q_GUI_EXPORT quint32 *qt_mac_pixmap_get_base(const QPixmap *pix) { - return static_cast<QMacPixmapData*>(pix->data.data())->pixels; + if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) + return reinterpret_cast<quint32 *>(static_cast<QRasterPixmapData*>(pix->data.data())->buffer()->bits()); + else + return static_cast<QMacPixmapData*>(pix->data.data())->pixels; } Q_GUI_EXPORT int qt_mac_pixmap_get_bytes_per_line(const QPixmap *pix) { - return static_cast<QMacPixmapData*>(pix->data.data())->bytesPerRow; + if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) + return static_cast<QRasterPixmapData*>(pix->data.data())->buffer()->bytesPerLine(); + else + return static_cast<QMacPixmapData*>(pix->data.data())->bytesPerRow; } void qt_mac_cgimage_data_free(void *info, const void *memoryToFree, size_t) diff --git a/src/gui/image/qvolatileimage.cpp b/src/gui/image/qvolatileimage.cpp index 098e9a1..f5076e1 100644 --- a/src/gui/image/qvolatileimage.cpp +++ b/src/gui/image/qvolatileimage.cpp @@ -103,6 +103,11 @@ QVolatileImage &QVolatileImage::operator=(const QVolatileImage &rhs) return *this; } +bool QVolatileImage::paintingActive() const +{ + return d->pengine && d->pengine->isActive(); +} + bool QVolatileImage::isNull() const { return d->image.isNull(); diff --git a/src/gui/image/qvolatileimage_p.h b/src/gui/image/qvolatileimage_p.h index fc5d6b1..d835f45 100644 --- a/src/gui/image/qvolatileimage_p.h +++ b/src/gui/image/qvolatileimage_p.h @@ -71,6 +71,7 @@ public: ~QVolatileImage(); QVolatileImage &operator=(const QVolatileImage &rhs); + bool paintingActive() const; bool isNull() const; QImage::Format format() const; int width() const; diff --git a/src/gui/inputmethod/qcoefepinputcontext_p.h b/src/gui/inputmethod/qcoefepinputcontext_p.h index de3577f..57c1e45 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_p.h +++ b/src/gui/inputmethod/qcoefepinputcontext_p.h @@ -168,6 +168,7 @@ private: }; Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable); +Q_GUI_EXPORT void qt_s60_setPartialScreenAutomaticTranslation(bool enable); QT_END_NAMESPACE diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 06dc25c..23109e1 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -88,6 +88,11 @@ Q_GUI_EXPORT void qt_s60_setPartialScreenInputMode(bool enable) ic->update(); } +Q_GUI_EXPORT void qt_s60_setPartialScreenAutomaticTranslation(bool enable) +{ + S60->partial_keyboardAutoTranslation = enable; +} + QCoeFepInputContext::QCoeFepInputContext(QObject *parent) : QInputContext(parent), m_fepState(q_check_ptr(new CAknEdwinState)), // CBase derived object needs check on new @@ -235,21 +240,6 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) return false; switch (event->type()) { - case QEvent::MouseButtonPress: - // Alphanumeric keypad doesn't like it when we click and text is still getting displayed - // It ignores the mouse event, so we need to commit and send a selection event (which will get triggered - // after the commit) - if (!m_preeditString.isEmpty()) { - commitCurrentString(true); - - int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt(); - - QList<QInputMethodEvent::Attribute> selectAttributes; - selectAttributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos, 0, QVariant()); - QInputMethodEvent selectEvent(QLatin1String(""), selectAttributes); - sendEvent(selectEvent); - } - break; case QEvent::KeyPress: commitTemporaryPreeditString(); // fall through intended @@ -328,7 +318,10 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) if (sControl) { sControl->setIgnoreFocusChanged(false); } - return true; + //If m_pointerHandler has already been set, it means that fep inline editing is in progress. + //When this is happening, do not filter out pointer events. + if (!m_pointerHandler) + return true; } return false; @@ -380,18 +373,31 @@ void QCoeFepInputContext::commitTemporaryPreeditString() commitCurrentString(false); } -void QCoeFepInputContext::mouseHandler( int x, QMouseEvent *event) +void QCoeFepInputContext::mouseHandler(int x, QMouseEvent *event) { Q_ASSERT(focusWidget()); if (event->type() == QEvent::MouseButtonPress && event->button() == Qt::LeftButton) { - commitCurrentString(true); - int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt(); + QWidget *proxy = focusWidget()->focusProxy(); + Qt::InputMethodHints currentHints = proxy ? proxy->inputMethodHints() : focusWidget()->inputMethodHints(); + + //If splitview is open and T9 word is tapped, pass the pointer event to pointer handler. + //This will open the "suggested words" list. Pass pointer position always as zero, to make + //full word replacement in case user makes a selection. + if (S60->partial_keyboard && S60->partialKeyboardOpen + && m_pointerHandler + && !(currentHints & Qt::ImhNoPredictiveText) + && (x > 0 && x < m_preeditString.length())) { + m_pointerHandler->HandlePointerEventInInlineTextL(TPointerEvent::EButton1Up, 0, 0); + } else { + commitCurrentString(true); + int pos = focusWidget()->inputMethodQuery(Qt::ImCursorPosition).toInt(); - QList<QInputMethodEvent::Attribute> attributes; - attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos + x, 0, QVariant()); - QInputMethodEvent event(QLatin1String(""), attributes); - sendEvent(event); + QList<QInputMethodEvent::Attribute> attributes; + attributes << QInputMethodEvent::Attribute(QInputMethodEvent::Selection, pos + x, 0, QVariant()); + QInputMethodEvent event(QLatin1String(""), attributes); + sendEvent(event); + } } } @@ -559,12 +565,13 @@ void QCoeFepInputContext::ensureFocusWidgetVisible(QWidget *widget) widget->resize(widget->width(), splitViewRect.height() - windowTop); } - if (gv->scene()) { + if (gv->scene() && S60->partial_keyboardAutoTranslation) { const QRectF microFocusRect = gv->scene()->inputMethodQuery(Qt::ImMicroFocus).toRectF(); gv->ensureVisible(microFocusRect); } } else { - translateInputWidget(); + if (S60->partial_keyboardAutoTranslation) + translateInputWidget(); } if (alwaysResize) diff --git a/src/gui/itemviews/qabstractitemview.cpp b/src/gui/itemviews/qabstractitemview.cpp index d671496..0bf85c6 100644 --- a/src/gui/itemviews/qabstractitemview.cpp +++ b/src/gui/itemviews/qabstractitemview.cpp @@ -62,9 +62,6 @@ #include <qaccessible.h> #endif #include <private/qsoftkeymanager_p.h> -#ifndef QT_NO_GESTURE -# include <qscroller.h> -#endif QT_BEGIN_NAMESPACE @@ -194,40 +191,6 @@ void QAbstractItemViewPrivate::checkMouseMove(const QPersistentModelIndex &index } } -#ifndef QT_NO_GESTURES - -// stores and restores the selection and current item when flicking -void QAbstractItemViewPrivate::_q_scrollerStateChanged() -{ - Q_Q(QAbstractItemView); - - if (QScroller *scroller = QScroller::scroller(viewport)) { - switch (scroller->state()) { - case QScroller::Pressed: - // store the current selection in case we start scrolling - if (q->selectionModel()) { - oldSelection = q->selectionModel()->selection(); - oldCurrent = q->selectionModel()->currentIndex(); - } - break; - - case QScroller::Dragging: - // restore the old selection if we really start scrolling - if (q->selectionModel()) { - q->selectionModel()->select(oldSelection, QItemSelectionModel::ClearAndSelect); - q->selectionModel()->setCurrentIndex(oldCurrent, QItemSelectionModel::NoUpdate); - } - // fall through - - default: - oldSelection = QItemSelection(); - oldCurrent = QModelIndex(); - break; - } - } -} - -#endif // QT_NO_GESTURES /*! \class QAbstractItemView @@ -1662,13 +1625,6 @@ bool QAbstractItemView::viewportEvent(QEvent *event) case QEvent::WindowDeactivate: d->viewport->update(); break; - case QEvent::ScrollPrepare: - executeDelayedItemsLayout(); -#ifndef QT_NO_GESTURES - connect(QScroller::scroller(d->viewport), SIGNAL(stateChanged(QScroller::State)), this, SLOT(_q_scrollerStateChanged()), Qt::UniqueConnection); -#endif - break; - default: break; } diff --git a/src/gui/itemviews/qabstractitemview.h b/src/gui/itemviews/qabstractitemview.h index f11f209..7043a5f 100644 --- a/src/gui/itemviews/qabstractitemview.h +++ b/src/gui/itemviews/qabstractitemview.h @@ -359,9 +359,6 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_modelDestroyed()) Q_PRIVATE_SLOT(d_func(), void _q_layoutChanged()) Q_PRIVATE_SLOT(d_func(), void _q_headerDataChanged()) -#ifndef QT_NO_GESTURES - Q_PRIVATE_SLOT(d_func(), void _q_scrollerStateChanged()) -#endif friend class QTreeViewPrivate; // needed to compile with MSVC friend class QAccessibleItemRow; diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 6041e5e..d5a0d37 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -114,7 +114,6 @@ public: virtual void _q_modelDestroyed(); virtual void _q_layoutChanged(); void _q_headerDataChanged() { doDelayedItemsLayout(); } - void _q_scrollerStateChanged(); void fetchMore(); @@ -415,12 +414,6 @@ public: QAbstractItemView::ScrollMode verticalScrollMode; QAbstractItemView::ScrollMode horizontalScrollMode; -#ifndef QT_NO_GESTURES - // the selection before the last mouse down. In case we have to restore it for scrolling - QItemSelection oldSelection; - QModelIndex oldCurrent; -#endif - bool currentIndexSet; bool wrapItemText; diff --git a/src/gui/itemviews/qdatawidgetmapper.cpp b/src/gui/itemviews/qdatawidgetmapper.cpp index 745ef5a..dac4613 100644 --- a/src/gui/itemviews/qdatawidgetmapper.cpp +++ b/src/gui/itemviews/qdatawidgetmapper.cpp @@ -291,7 +291,7 @@ void QDataWidgetMapperPrivate::_q_modelDestroyed() \snippet doc/src/snippets/code/src_gui_itemviews_qdatawidgetmapper.cpp 0 After the call to toFirst(), \c mySpinBox displays the value \c{1}, \c myLineEdit - displays \c {Nokia Corporation and/or its subsidiary(-ies)} and \c myCountryChooser displays \c{Oslo}. The + displays \c{Qt Norway} and \c myCountryChooser displays \c{Oslo}. The navigational functions toFirst(), toNext(), toPrevious(), toLast() and setCurrentIndex() can be used to navigate in the model and update the widgets with contents from the model. diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index 59a3d15..e70f356 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -1300,7 +1300,6 @@ void QTableView::paintEvent(QPaintEvent *event) const QPen gridPen = QPen(gridColor, 0, d->gridStyle); const QHeaderView *verticalHeader = d->verticalHeader; const QHeaderView *horizontalHeader = d->horizontalHeader; - const QStyle::State state = option.state; const bool alternate = d->alternatingColors; const bool rightToLeft = isRightToLeft(); diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 408c3b5..815d221 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -1360,6 +1360,23 @@ void QSymbianControl::PositionChanged() } } +// Search recursively if there is a child widget that is both visible and focused. +bool QSymbianControl::hasFocusedAndVisibleChild(QWidget *parentWidget) +{ + for (int i = 0; i < parentWidget->children().size(); ++i) { + QObject *object = parentWidget->children().at(i); + if (object && object->isWidgetType()) { + QWidget *w = static_cast<QWidget *>(object); + WId winId = w->internalWinId(); + if (winId && winId->IsFocused() && winId->IsVisible()) + return true; + if (hasFocusedAndVisibleChild(w)) + return true; + } + } + return false; +} + void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */) { if (m_ignoreFocusChanged || (qwidget->windowType() & Qt::WindowType_Mask) == Qt::Desktop) @@ -1392,17 +1409,9 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */) if (qwidget->isWindow()) S60->setRecursiveDecorationsVisibility(qwidget, qwidget->windowState()); #endif - } else if (QApplication::activeWindow() == qwidget->window()) { - bool focusedControlFound = false; - WId winId = 0; - for (QWidget *w = qwidget->parentWidget(); w && (winId = w->internalWinId()); w = w->parentWidget()) { - if (winId->IsFocused() && winId->IsVisible()) { - focusedControlFound = true; - break; - } else if (w->isWindow()) - break; - } - if (!focusedControlFound) { + } else { + QWidget *parentWindow = qwidget->window(); + if (QApplication::activeWindow() == parentWindow && !hasFocusedAndVisibleChild(parentWindow)) { if (CCoeEnv::Static()->AppUi()->IsDisplayingMenuOrDialog() || S60->menuBeingConstructed) { QWidget *fw = QApplication::focusWidget(); if (fw) { @@ -1481,8 +1490,10 @@ void QSymbianControl::HandleResourceChange(int resourceType) } if (ic && isSplitViewWidget(widget)) { if (resourceType == KSplitViewCloseEvent) { + S60->partialKeyboardOpen = false; ic->resetSplitViewWidget(); } else { + S60->partialKeyboardOpen = true; ic->ensureFocusWidgetVisible(widget); } } @@ -1509,6 +1520,10 @@ void QSymbianControl::HandleResourceChange(int resourceType) #ifdef Q_WS_S60 case KEikDynamicLayoutVariantSwitch: { +#ifdef QT_SOFTKEYS_ENABLED + // Update needed just in case softkeys contain icons + QSoftKeyManager::updateSoftKeys(); +#endif handleClientAreaChange(); // Send resize event to trigger desktopwidget workAreaResized signal if (qt_desktopWidget) { @@ -2703,6 +2718,9 @@ QS60ThreadLocalData::QS60ThreadLocalData() QS60ThreadLocalData::~QS60ThreadLocalData() { + for (int i = 0; i < releaseFuncs.count(); ++i) + releaseFuncs[i](); + releaseFuncs.clear(); if (!usingCONEinstances) { delete screenDevice; wsSession.Close(); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 6658300..63e2319 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -237,6 +237,7 @@ static void resolveAygLibs() # define FE_FONTSMOOTHINGCLEARTYPE 0x0002 #endif +Q_GUI_EXPORT qreal qt_fontsmoothing_gamma; Q_GUI_EXPORT bool qt_cleartype_enabled; Q_GUI_EXPORT bool qt_win_owndc_required; // CS_OWNDC is required if we use the GL graphicssystem as default @@ -653,8 +654,18 @@ static void qt_win_read_cleartype_settings() if (SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &result, 0)) qt_cleartype_enabled = (result == FE_FONTSMOOTHINGCLEARTYPE); #endif -} + int winSmooth; + if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) { + qt_fontsmoothing_gamma = winSmooth / qreal(1000.0); + } else { + qt_fontsmoothing_gamma = 1.0; + } + + // Safeguard ourselves against corrupt registry values... + if (qt_fontsmoothing_gamma > 5 || qt_fontsmoothing_gamma < 1) + qt_fontsmoothing_gamma = qreal(1.4); +} static void qt_set_windows_resources() { diff --git a/src/gui/kernel/qapplication_x11.cpp b/src/gui/kernel/qapplication_x11.cpp index 20542ea..577d93b 100644 --- a/src/gui/kernel/qapplication_x11.cpp +++ b/src/gui/kernel/qapplication_x11.cpp @@ -2018,15 +2018,12 @@ void qt_init(QApplicationPrivate *priv, int, (PtrXRRRootToScreen) xrandrLib.resolve("XRRRootToScreen"); X11->ptrXRRQueryExtension = (PtrXRRQueryExtension) xrandrLib.resolve("XRRQueryExtension"); - X11->ptrXRRSizes = - (PtrXRRSizes) xrandrLib.resolve("XRRSizes"); } # else X11->ptrXRRSelectInput = XRRSelectInput; X11->ptrXRRUpdateConfiguration = XRRUpdateConfiguration; X11->ptrXRRRootToScreen = XRRRootToScreen; X11->ptrXRRQueryExtension = XRRQueryExtension; - X11->ptrXRRSizes = XRRSizes; # endif if (X11->ptrXRRQueryExtension diff --git a/src/gui/kernel/qclipboard.h b/src/gui/kernel/qclipboard.h index b55bdc6..019917e 100644 --- a/src/gui/kernel/qclipboard.h +++ b/src/gui/kernel/qclipboard.h @@ -112,6 +112,7 @@ protected: friend class QBaseApplication; friend class QDragManager; friend class QMimeSource; + friend class QPlatformClipboard; private: Q_DISABLE_COPY(QClipboard) diff --git a/src/gui/kernel/qcursor_x11.cpp b/src/gui/kernel/qcursor_x11.cpp index d0ed98e..0bc7250 100644 --- a/src/gui/kernel/qcursor_x11.cpp +++ b/src/gui/kernel/qcursor_x11.cpp @@ -55,6 +55,9 @@ #endif // QT_NO_XCURSOR #ifndef QT_NO_XFIXES +#ifndef Status +#define Status int +#endif # include <X11/extensions/Xfixes.h> #endif // QT_NO_XFIXES diff --git a/src/gui/kernel/qdesktopwidget_qpa.cpp b/src/gui/kernel/qdesktopwidget_qpa.cpp index cff05f5..6257a8b 100644 --- a/src/gui/kernel/qdesktopwidget_qpa.cpp +++ b/src/gui/kernel/qdesktopwidget_qpa.cpp @@ -51,6 +51,8 @@ QT_USE_NAMESPACE void QDesktopWidgetPrivate::updateScreenList() { + Q_Q(QDesktopWidget); + QList<QPlatformScreen *> screenList = QApplicationPrivate::platformIntegration()->screens(); int targetLength = screenList.length(); int currentLength = screens.length(); @@ -72,19 +74,15 @@ void QDesktopWidgetPrivate::updateScreenList() } QRegion virtualGeometry; - bool doVirtualGeometry = QApplicationPrivate::platformIntegration()->isVirtualDesktop(); // update the geometry of each screen widget for (int i = 0; i < screens.length(); i++) { QRect screenGeometry = screenList.at(i)->geometry(); screens.at(i)->setGeometry(screenGeometry); - if (doVirtualGeometry) - virtualGeometry += screenGeometry; + virtualGeometry += screenGeometry; } - virtualScreen.setGeometry(virtualGeometry.boundingRect()); - Q_Q(QDesktopWidget); - q->setGeometry(virtualScreen.geometry()); + q->setGeometry(virtualGeometry.boundingRect()); } QDesktopWidget::QDesktopWidget() @@ -118,8 +116,6 @@ int QDesktopWidget::numScreens() const QWidget *QDesktopWidget::screen(int screen) { Q_D(QDesktopWidget); - if (QApplicationPrivate::platformIntegration()->isVirtualDesktop()) - return &d->virtualScreen; if (screen < 0 || screen >= d->screens.length()) return d->screens.at(0); return d->screens.at(screen); diff --git a/src/gui/kernel/qdesktopwidget_qpa_p.h b/src/gui/kernel/qdesktopwidget_qpa_p.h index abee8a1..d6ed686 100644 --- a/src/gui/kernel/qdesktopwidget_qpa_p.h +++ b/src/gui/kernel/qdesktopwidget_qpa_p.h @@ -76,7 +76,6 @@ public: void updateScreenList(); QList<QDesktopScreenWidget *> screens; - QDesktopScreenWidget virtualScreen; }; #endif // QDESKTOPWIDGET_QPA_P_H diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp index 277a5e8..807c385 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -4629,223 +4629,4 @@ const QGestureEventPrivate *QGestureEvent::d_func() const #endif // QT_NO_GESTURES -/*! - \class QScrollPrepareEvent - \since 4.8 - \ingroup events - - \brief The QScrollPrepareEvent class is send in preparation of a scrolling. - - The scroll prepare event is send before scrolling (usually by QScroller) is started. - The object receiving this event should set viewportSize, maxContentPos and contentPos. - It also should accept this event to indicate that scrolling should be started. - - It is not guaranteed that a QScrollEvent will be send after an acceepted - QScrollPrepareEvent, e.g. in a case where the maximum content position is (0,0). - - \sa QScrollEvent, QScroller -*/ - -/*! - Creates new QScrollPrepareEvent - The \a startPos is the position of a touch or mouse event that started the scrolling. -*/ -QScrollPrepareEvent::QScrollPrepareEvent(const QPointF &startPos) - : QEvent(QEvent::ScrollPrepare) -{ - d = reinterpret_cast<QEventPrivate *>(new QScrollPrepareEventPrivate()); - d_func()->startPos = startPos; -} - -/*! - Destroys QScrollEvent. -*/ -QScrollPrepareEvent::~QScrollPrepareEvent() -{ - delete reinterpret_cast<QScrollPrepareEventPrivate *>(d); -} - -/*! - Returns the position of the touch or mouse event that started the scrolling. -*/ -QPointF QScrollPrepareEvent::startPos() const -{ - return d_func()->startPos; -} - -/*! - Returns size of the area that is to be scrolled as set by setViewportSize - - \sa setViewportSize() -*/ -QSizeF QScrollPrepareEvent::viewportSize() const -{ - return d_func()->viewportSize; -} - -/*! - Returns the range of coordinates for the content as set by setContentPosRange(). -*/ -QRectF QScrollPrepareEvent::contentPosRange() const -{ - return d_func()->contentPosRange; -} - -/*! - Returns the current position of the content as set by setContentPos. -*/ -QPointF QScrollPrepareEvent::contentPos() const -{ - return d_func()->contentPos; -} - - -/*! - Sets the size of the area that is to be scrolled to \a size. - - \sa viewportSize() -*/ -void QScrollPrepareEvent::setViewportSize(const QSizeF &size) -{ - d_func()->viewportSize = size; -} - -/*! - Sets the range of content coordinates to \a rect. - - \sa contentPosRange() -*/ -void QScrollPrepareEvent::setContentPosRange(const QRectF &rect) -{ - d_func()->contentPosRange = rect; -} - -/*! - Sets the current content position to \a pos. - - \sa contentPos() -*/ -void QScrollPrepareEvent::setContentPos(const QPointF &pos) -{ - d_func()->contentPos = pos; -} - - -/*! - \internal -*/ -QScrollPrepareEventPrivate *QScrollPrepareEvent::d_func() -{ - return reinterpret_cast<QScrollPrepareEventPrivate *>(d); -} - -/*! - \internal -*/ -const QScrollPrepareEventPrivate *QScrollPrepareEvent::d_func() const -{ - return reinterpret_cast<const QScrollPrepareEventPrivate *>(d); -} - -/*! - \class QScrollEvent - \since 4.8 - \ingroup events - - \brief The QScrollEvent class is send when scrolling. - - The scroll event is send to indicate that the receiver should be scrolled. - Usually the receiver should be something visual like QWidget or QGraphicsObject. - - Some care should be taken that no conflicting QScrollEvents are sent from two - sources. Using QScroller::scrollTo is save however. - - \sa QScrollPrepareEvent, QScroller -*/ - -/*! - \enum QScrollEvent::ScrollState - - This enum describes the states a scroll event can have. - - \value ScrollStarted Set for the first scroll event of a scroll activity. - - \value ScrollUpdated Set for all but the first and the last scroll event of a scroll activity. - - \value ScrollFinished Set for the last scroll event of a scroll activity. - - \sa QScrollEvent::scrollState() -*/ - -/*! - Creates a new QScrollEvent - \a contentPos is the new content position, \a overshootDistance is the - new overshoot distance while \a scrollState indicates if this scroll - event is the first one, the last one or some event in between. -*/ -QScrollEvent::QScrollEvent(const QPointF &contentPos, const QPointF &overshootDistance, ScrollState scrollState) - : QEvent(QEvent::Scroll) -{ - d = reinterpret_cast<QEventPrivate *>(new QScrollEventPrivate()); - d_func()->contentPos = contentPos; - d_func()->overshoot= overshootDistance; - d_func()->state = scrollState; -} - -/*! - Destroys QScrollEvent. -*/ -QScrollEvent::~QScrollEvent() -{ - delete reinterpret_cast<QScrollEventPrivate *>(d); -} - -/*! - Returns the new scroll position. -*/ -QPointF QScrollEvent::contentPos() const -{ - return d_func()->contentPos; -} - -/*! - Returns the new overshoot distance. - See QScroller for an explanation of the term overshoot. - - \sa QScroller -*/ -QPointF QScrollEvent::overshootDistance() const -{ - return d_func()->overshoot; -} - -/*! - Returns the current scroll state as a combination of ScrollStateFlag values. - ScrollStarted (or ScrollFinished) will be set, if this scroll event is the first (or last) event in a scrolling activity. - Please note that both values can be set at the same time, if the activity consists of a single QScrollEvent. - All other scroll events in between will have their state set to ScrollUpdated. - - A widget could for example revert selections when scrolling is started and stopped. -*/ -QScrollEvent::ScrollState QScrollEvent::scrollState() const -{ - return d_func()->state; -} - -/*! - \internal -*/ -QScrollEventPrivate *QScrollEvent::d_func() -{ - return reinterpret_cast<QScrollEventPrivate *>(d); -} - -/*! - \internal -*/ -const QScrollEventPrivate *QScrollEvent::d_func() const -{ - return reinterpret_cast<const QScrollEventPrivate *>(d); -} - QT_END_NAMESPACE diff --git a/src/gui/kernel/qevent.h b/src/gui/kernel/qevent.h index 93c2bc5..830f037 100644 --- a/src/gui/kernel/qevent.h +++ b/src/gui/kernel/qevent.h @@ -889,52 +889,6 @@ private: }; #endif // QT_NO_GESTURES -class QScrollPrepareEventPrivate; -class Q_GUI_EXPORT QScrollPrepareEvent : public QEvent -{ -public: - QScrollPrepareEvent(const QPointF &startPos); - ~QScrollPrepareEvent(); - - QPointF startPos() const; - - QSizeF viewportSize() const; - QRectF contentPosRange() const; - QPointF contentPos() const; - - void setViewportSize(const QSizeF &size); - void setContentPosRange(const QRectF &rect); - void setContentPos(const QPointF &pos); - -private: - QScrollPrepareEventPrivate *d_func(); - const QScrollPrepareEventPrivate *d_func() const; -}; - - -class QScrollEventPrivate; -class Q_GUI_EXPORT QScrollEvent : public QEvent -{ -public: - enum ScrollState - { - ScrollStarted, - ScrollUpdated, - ScrollFinished - }; - - QScrollEvent(const QPointF &contentPos, const QPointF &overshoot, ScrollState scrollState); - ~QScrollEvent(); - - QPointF contentPos() const; - QPointF overshootDistance() const; - ScrollState scrollState() const; - -private: - QScrollEventPrivate *d_func(); - const QScrollEventPrivate *d_func() const; -}; - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/gui/kernel/qevent_p.h b/src/gui/kernel/qevent_p.h index b79f372..36655e8 100644 --- a/src/gui/kernel/qevent_p.h +++ b/src/gui/kernel/qevent_p.h @@ -186,34 +186,6 @@ public: #endif }; - -class QScrollPrepareEventPrivate -{ -public: - inline QScrollPrepareEventPrivate() - : target(0) - { - } - - QObject* target; - QPointF startPos; - QSizeF viewportSize; - QRectF contentPosRange; - QPointF contentPos; -}; - -class QScrollEventPrivate -{ -public: - inline QScrollEventPrivate() - { - } - - QPointF contentPos; - QPointF overshoot; - QScrollEvent::ScrollState state; -}; - QT_END_NAMESPACE #endif // QEVENT_P_H diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp index 5359fb3..7aa7dffd 100644 --- a/src/gui/kernel/qgesturemanager.cpp +++ b/src/gui/kernel/qgesturemanager.cpp @@ -566,7 +566,6 @@ void QGestureManager::getGestureTargets(const QSet<QGesture*> &gestures, = w->d_func()->gestureContext.find(type); if (it != w->d_func()->gestureContext.end()) { // i.e. 'w' listens to gesture 'type' - Qt::GestureFlags flags = it.value(); if (!(it.value() & Qt::DontStartGestureOnChildren) && w != widget) { // conflicting gesture! (*conflicts)[widget].append(gestures[widget]); diff --git a/src/gui/kernel/qplatformclipboard_qpa.cpp b/src/gui/kernel/qplatformclipboard_qpa.cpp index 957a4df..33d2afc 100644 --- a/src/gui/kernel/qplatformclipboard_qpa.cpp +++ b/src/gui/kernel/qplatformclipboard_qpa.cpp @@ -42,6 +42,8 @@ #ifndef QT_NO_CLIPBOARD +#include <QtGui/private/qapplication_p.h> + QT_BEGIN_NAMESPACE class QClipboardData @@ -100,6 +102,11 @@ bool QPlatformClipboard::supportsMode(QClipboard::Mode mode) const return mode == QClipboard::Clipboard; } +void QPlatformClipboard::emitChanged(QClipboard::Mode mode) +{ + QApplication::clipboard()->emitChanged(mode); +} + QT_END_NAMESPACE #endif //QT_NO_CLIPBOARD diff --git a/src/gui/kernel/qplatformclipboard_qpa.h b/src/gui/kernel/qplatformclipboard_qpa.h index 3381c06..5444a1f 100644 --- a/src/gui/kernel/qplatformclipboard_qpa.h +++ b/src/gui/kernel/qplatformclipboard_qpa.h @@ -62,6 +62,7 @@ public: virtual const QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard ) const; virtual void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard); virtual bool supportsMode(QClipboard::Mode mode) const; + void emitChanged(QClipboard::Mode mode); }; QT_END_NAMESPACE diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp index d559c53..8ff12eb 100644 --- a/src/gui/kernel/qplatformintegration_qpa.cpp +++ b/src/gui/kernel/qplatformintegration_qpa.cpp @@ -214,6 +214,7 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const bool QPlatformIntegration::hasCapability(Capability cap) const { + Q_UNUSED(cap); return false; } diff --git a/src/gui/kernel/qplatformwindow_qpa.cpp b/src/gui/kernel/qplatformwindow_qpa.cpp index 19bf7a9..f3654b6 100644 --- a/src/gui/kernel/qplatformwindow_qpa.cpp +++ b/src/gui/kernel/qplatformwindow_qpa.cpp @@ -150,7 +150,7 @@ void QPlatformWindow::setParent(const QPlatformWindow *parent) /*! Reimplement to set the window title to \a title */ -void QPlatformWindow::setWindowTitle(const QString &title) {} +void QPlatformWindow::setWindowTitle(const QString &) {} /*! Reimplement to be able to let Qt rais windows to the top of the desktop diff --git a/src/gui/kernel/qsessionmanager_qpa.cpp b/src/gui/kernel/qsessionmanager_qpa.cpp index ef532d7..68685b4 100644 --- a/src/gui/kernel/qsessionmanager_qpa.cpp +++ b/src/gui/kernel/qsessionmanager_qpa.cpp @@ -42,6 +42,8 @@ #include <qsessionmanager.h> #include <private/qobject_p.h> +#include <qapplication.h> + #ifndef QT_NO_SESSIONMANAGER QT_BEGIN_NAMESPACE diff --git a/src/gui/kernel/qsoftkeymanager_s60.cpp b/src/gui/kernel/qsoftkeymanager_s60.cpp index 79ed91a..71ae520 100644 --- a/src/gui/kernel/qsoftkeymanager_s60.cpp +++ b/src/gui/kernel/qsoftkeymanager_s60.cpp @@ -176,22 +176,27 @@ void QSoftKeyManagerPrivateS60::setNativeSoftkey(CEikButtonGroupContainer &cba, QPoint QSoftKeyManagerPrivateS60::softkeyIconPosition(int position, QSize sourceSize, QSize targetSize) { QPoint iconPosition(0,0); - switch( AknLayoutUtils::CbaLocation() ) - { - case AknLayoutUtils::EAknCbaLocationBottom: - // RSK must be moved to right, LSK in on correct position by default - if (position == RSK_POSITION) - iconPosition.setX(targetSize.width() - sourceSize.width()); - break; - case AknLayoutUtils::EAknCbaLocationRight: - case AknLayoutUtils::EAknCbaLocationLeft: - // Already in correct position - default: - break; - } - // Align horizontally to center - iconPosition.setY((targetSize.height() - sourceSize.height()) >> 1); + // Prior to S60 5.3 icons need to be properly positioned to buttons, but starting with 5.3 + // positioning is done on Avkon side. + if (QSysInfo::s60Version() < QSysInfo::SV_S60_5_3) { + switch (AknLayoutUtils::CbaLocation()) + { + case AknLayoutUtils::EAknCbaLocationBottom: + // RSK must be moved to right, LSK in on correct position by default + if (position == RSK_POSITION) + iconPosition.setX(targetSize.width() - sourceSize.width()); + break; + case AknLayoutUtils::EAknCbaLocationRight: + case AknLayoutUtils::EAknCbaLocationLeft: + // Already in correct position + default: + break; + } + + // Align horizontally to center + iconPosition.setY((targetSize.height() - sourceSize.height()) >> 1); + } return iconPosition; } @@ -278,12 +283,6 @@ bool QSoftKeyManagerPrivateS60::setSoftkeyImage(CEikButtonGroupContainer *cba, EikSoftkeyImage::SetImage(cba, *myimage, left); // Takes myimage ownership cbaHasImage[position] = true; ret = true; - } else { - // Restore softkey to text based - if (cbaHasImage[position]) { - EikSoftkeyImage::SetLabel(cba, left); - cbaHasImage[position] = false; - } } } return ret; @@ -294,7 +293,7 @@ bool QSoftKeyManagerPrivateS60::setSoftkey(CEikButtonGroupContainer &cba, { QAction *action = highestPrioritySoftkey(role); if (action) { - setSoftkeyImage(&cba, *action, position); + bool hasImage = setSoftkeyImage(&cba, *action, position); QString text = softkeyText(*action); TPtrC nativeText = qt_QString2TPtrC(text); int command = S60_COMMAND_START + position; @@ -303,6 +302,11 @@ bool QSoftKeyManagerPrivateS60::setSoftkey(CEikButtonGroupContainer &cba, command = softKeyCommandActions.value(action); #endif setNativeSoftkey(cba, position, command, nativeText); + if (!hasImage && cbaHasImage[position]) { + EikSoftkeyImage::SetLabel(&cba, (position == LSK_POSITION)); + cbaHasImage[position] = false; + } + const bool dimmed = !action->isEnabled() && !QSoftKeyManager::isForceEnabledInSofkeys(action); cba.DimCommand(command, dimmed); realSoftKeyActions.insert(command, action); @@ -313,7 +317,18 @@ bool QSoftKeyManagerPrivateS60::setSoftkey(CEikButtonGroupContainer &cba, bool QSoftKeyManagerPrivateS60::setLeftSoftkey(CEikButtonGroupContainer &cba) { - return setSoftkey(cba, QAction::PositiveSoftKey, LSK_POSITION); + if (!setSoftkey(cba, QAction::PositiveSoftKey, LSK_POSITION)) { + if (cbaHasImage[LSK_POSITION]) { + // Clear any residual icon if LSK has no action. A real softkey + // is needed for SetLabel command to work, so do a temporary dummy + setNativeSoftkey(cba, LSK_POSITION, EAknSoftkeyExit, KNullDesC); + EikSoftkeyImage::SetLabel(&cba, true); + setNativeSoftkey(cba, LSK_POSITION, EAknSoftkeyEmpty, KNullDesC); + cbaHasImage[LSK_POSITION] = false; + } + return false; + } + return true; } bool QSoftKeyManagerPrivateS60::setMiddleSoftkey(CEikButtonGroupContainer &cba) @@ -332,16 +347,26 @@ bool QSoftKeyManagerPrivateS60::setRightSoftkey(CEikButtonGroupContainer &cba) if (windowType != Qt::Dialog && windowType != Qt::Popup) { QString text(QSoftKeyManager::tr("Exit")); TPtrC nativeText = qt_QString2TPtrC(text); + setNativeSoftkey(cba, RSK_POSITION, EAknSoftkeyExit, nativeText); if (cbaHasImage[RSK_POSITION]) { EikSoftkeyImage::SetLabel(&cba, false); cbaHasImage[RSK_POSITION] = false; } - setNativeSoftkey(cba, RSK_POSITION, EAknSoftkeyExit, nativeText); cba.DimCommand(EAknSoftkeyExit, false); return true; + } else { + if (cbaHasImage[RSK_POSITION]) { + // Clear any residual icon if RSK has no action. A real softkey + // is needed for SetLabel command to work, so do a temporary dummy + setNativeSoftkey(cba, RSK_POSITION, EAknSoftkeyExit, KNullDesC); + EikSoftkeyImage::SetLabel(&cba, false); + setNativeSoftkey(cba, RSK_POSITION, EAknSoftkeyEmpty, KNullDesC); + cbaHasImage[RSK_POSITION] = false; + } + return false; } } - return false; + return true; } void QSoftKeyManagerPrivateS60::setSoftkeys(CEikButtonGroupContainer &cba) diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index 8aba53a..0023649 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -97,6 +97,10 @@ static const int qt_symbian_max_screens = 4; //this macro exists because EColor16MAP enum value doesn't exist in Symbian OS 9.2 #define Q_SYMBIAN_ECOLOR16MAP TDisplayMode(13) +class QSymbianTypeFaceExtras; +typedef QHash<QString, const QSymbianTypeFaceExtras *> QSymbianTypeFaceExtrasHash; +typedef void (*QThreadLocalReleaseFunc)(); + class Q_AUTOTEST_EXPORT QS60ThreadLocalData { public: @@ -105,6 +109,8 @@ public: bool usingCONEinstances; RWsSession wsSession; CWsScreenDevice *screenDevice; + QSymbianTypeFaceExtrasHash fontData; + QVector<QThreadLocalReleaseFunc> releaseFuncs; }; class QS60Data @@ -153,6 +159,8 @@ public: int menuBeingConstructed : 1; int orientationSet : 1; int partial_keyboard : 1; + int partial_keyboardAutoTranslation : 1; + int partialKeyboardOpen : 1; QApplication::QS60MainApplicationFactory s60ApplicationFactory; // typedef'ed pointer type QPointer<QWidget> splitViewLastWidget; @@ -175,6 +183,8 @@ public: inline CWsScreenDevice* screenDevice(const QWidget *widget); inline CWsScreenDevice* screenDevice(int screenNumber); static inline int screenNumberForWidget(const QWidget *widget); + inline QSymbianTypeFaceExtrasHash& fontData(); + inline void addThreadLocalReleaseFunc(QThreadLocalReleaseFunc func); static inline CCoeAppUi* appUi(); static inline CEikMenuBar* menuBar(); #ifdef Q_WS_S60 @@ -291,6 +301,7 @@ private: void translateAdvancedPointerEvent(const TAdvancedPointerEvent *event); #endif bool isSplitViewWidget(QWidget *widget); + bool hasFocusedAndVisibleChild(QWidget *parentWidget); public: void handleClientAreaChange(); @@ -340,6 +351,8 @@ inline QS60Data::QS60Data() menuBeingConstructed(0), orientationSet(0), partial_keyboard(0), + partial_keyboardAutoTranslation(1), + partialKeyboardOpen(0), s60ApplicationFactory(0) #ifdef Q_OS_SYMBIAN ,s60InstalledTrapHandler(0) @@ -470,6 +483,24 @@ inline int QS60Data::screenNumberForWidget(const QWidget *widget) return qt_widget_private(const_cast<QWidget *>(w))->symbianScreenNumber; } +inline QSymbianTypeFaceExtrasHash& QS60Data::fontData() +{ + if (!tls.hasLocalData()) { + tls.setLocalData(new QS60ThreadLocalData); + } + return tls.localData()->fontData; +} + +inline void QS60Data::addThreadLocalReleaseFunc(QThreadLocalReleaseFunc func) +{ + if (!tls.hasLocalData()) { + tls.setLocalData(new QS60ThreadLocalData); + } + QS60ThreadLocalData *data = tls.localData(); + if (!data->releaseFuncs.contains(func)) + data->releaseFuncs.append(func); +} + inline CCoeAppUi* QS60Data::appUi() { return CCoeEnv::Static()-> AppUi(); diff --git a/src/gui/kernel/qt_x11_p.h b/src/gui/kernel/qt_x11_p.h index 69079cf..8ab129c 100644 --- a/src/gui/kernel/qt_x11_p.h +++ b/src/gui/kernel/qt_x11_p.h @@ -226,7 +226,6 @@ typedef void (*PtrXRRSelectInput)(Display *, Window, int); typedef int (*PtrXRRUpdateConfiguration)(XEvent *); typedef int (*PtrXRRRootToScreen)(Display *, Window); typedef Bool (*PtrXRRQueryExtension)(Display *, int *, int *); -typedef XRRScreenSize *(*PtrXRRSizes)(Display *, int, int *); #endif // QT_NO_XRANDR #ifndef QT_NO_XINPUT @@ -711,7 +710,6 @@ struct QX11Data PtrXRRUpdateConfiguration ptrXRRUpdateConfiguration; PtrXRRRootToScreen ptrXRRRootToScreen; PtrXRRQueryExtension ptrXRRQueryExtension; - PtrXRRSizes ptrXRRSizes; #endif // QT_NO_XRANDR }; diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index c5ea239..9556169 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -299,6 +299,7 @@ QWidgetPrivate::QWidgetPrivate(int version) #ifndef QT_NO_IM , inheritsInputMethodHints(0) #endif + , inSetParent(0) #if defined(Q_WS_X11) , picture(0) #elif defined(Q_WS_WIN) @@ -612,7 +613,7 @@ void QWidget::setAutoFillBackground(bool enabled) \brief The QWidget class is the base class of all user interface objects. \ingroup basicwidgets - + The widget is the atom of the user interface: it receives mouse, keyboard and other events from the window system, and paints a representation of itself on the screen. Every widget is rectangular, and they are sorted in a @@ -1389,16 +1390,6 @@ void QWidgetPrivate::init(QWidget *parentWidget, Qt::WindowFlags f) QApplication::postEvent(q, new QEvent(QEvent::PolishRequest)); extraPaintEngine = 0; - -#ifdef QT_MAC_USE_COCOA - // If we add a child to the unified toolbar, we have to redirect the painting. - if (parentWidget && parentWidget->d_func() && parentWidget->d_func()->isInUnifiedToolbar) { - if (parentWidget->d_func()->unifiedSurface) { - QWidget *toolbar = parentWidget->d_func()->toolbar_ancestor; - parentWidget->d_func()->unifiedSurface->recursiveRedirect(toolbar, toolbar, toolbar->d_func()->toolbar_offset); - } - } -#endif // QT_MAC_USE_COCOA } @@ -1588,6 +1579,7 @@ QWidget::~QWidget() // delete layout while we still are a valid widget delete d->layout; + d->layout = 0; // Remove myself from focus list Q_ASSERT(d->focus_next->d_func()->focus_prev == this); @@ -2598,6 +2590,22 @@ WId QWidget::effectiveWinId() const if (id || !testAttribute(Qt::WA_WState_Created)) return id; QWidget *realParent = nativeParentWidget(); + if (!realParent && d_func()->inSetParent) { + // In transitional state. This is really just a workaround. The real problem + // is that QWidgetPrivate::setParent_sys (platform specific code) first sets + // the window id to 0 (setWinId(0)) before it sets the Qt::WA_WState_Created + // attribute to false. The correct way is to do it the other way around, and + // in that case the Qt::WA_WState_Created logic above will kick in and + // return 0 whenever the widget is in a transitional state. However, changing + // the original logic for all platforms is far more intrusive and might + // break existing applications. + // Note: The widget can only be in a transitional state when changing its + // parent -- everything else is an internal error -- hence explicitly checking + // against 'inSetParent' rather than doing an unconditional return whenever + // 'realParent' is 0 (which may cause strange artifacts and headache later). + return 0; + } + // This widget *must* have a native parent widget. Q_ASSERT(realParent); Q_ASSERT(realParent->internalWinId()); return realParent->internalWinId(); @@ -10110,6 +10118,7 @@ void QWidget::setParent(QWidget *parent) void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) { Q_D(QWidget); + d->inSetParent = true; bool resized = testAttribute(Qt::WA_Resized); bool wasCreated = testAttribute(Qt::WA_WState_Created); QWidget *oldtlw = window(); @@ -10270,6 +10279,8 @@ void QWidget::setParent(QWidget *parent, Qt::WindowFlags f) ancestorProxy->d_func()->embedSubWindow(this); } #endif + + d->inSetParent = false; } /*! diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 354f05b..468de22 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2733,7 +2733,7 @@ QWidget::macCGHandle() const return handle(); } -void qt_mac_repaintParentUnderAlienWidget(QWidget *alienWidget) +void qt_mac_updateParentUnderAlienWidget(QWidget *alienWidget) { QWidget *nativeParent = alienWidget->nativeParentWidget(); if (!nativeParent) @@ -2741,7 +2741,7 @@ void qt_mac_repaintParentUnderAlienWidget(QWidget *alienWidget) QPoint globalPos = alienWidget->mapToGlobal(QPoint(0, 0)); QRect dirtyRect = QRect(nativeParent->mapFromGlobal(globalPos), alienWidget->size()); - nativeParent->repaint(dirtyRect); + nativeParent->update(dirtyRect); } void QWidget::destroy(bool destroyWindow, bool destroySubWindows) @@ -2752,7 +2752,7 @@ void QWidget::destroy(bool destroyWindow, bool destroySubWindows) if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); if (!internalWinId()) - qt_mac_repaintParentUnderAlienWidget(this); + qt_mac_updateParentUnderAlienWidget(this); d->deactivateWidgetCleanup(); qt_mac_event_release(this); if(testAttribute(Qt::WA_WState_Created)) { @@ -3032,6 +3032,16 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f) q->setAttribute(Qt::WA_WState_Hidden); q->setAttribute(Qt::WA_WState_ExplicitShowHide, explicitlyHidden); +#ifdef QT_MAC_USE_COCOA + // If we add a child to the unified toolbar, we have to redirect the painting. + if (parent && parent->d_func() && parent->d_func()->isInUnifiedToolbar) { + if (parent->d_func()->unifiedSurface) { + QWidget *toolbar = parent->d_func()->toolbar_ancestor; + parent->d_func()->unifiedSurface->recursiveRedirect(toolbar, toolbar, toolbar->d_func()->toolbar_offset); + } + } +#endif // QT_MAC_USE_COCOA + if (wasCreated) { transferChildren(); #ifndef QT_MAC_USE_COCOA @@ -3526,8 +3536,8 @@ void QWidgetPrivate::show_sys() // INVARIANT: q is native. Just show the view: [view setHidden:NO]; } else { - // INVARIANT: q is alien. Repaint q instead: - q->repaint(); + // INVARIANT: q is alien. Update q instead: + q->update(); } #endif } @@ -3683,7 +3693,7 @@ void QWidgetPrivate::hide_sys() [view setHidden:YES]; } else { // INVARIANT: q is alien. Repaint where q is placed instead: - qt_mac_repaintParentUnderAlienWidget(q); + qt_mac_updateParentUnderAlienWidget(q); } #endif } diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 919f8bc..acf1860 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -232,6 +232,7 @@ struct QTLWExtra { #elif defined(Q_OS_SYMBIAN) uint inExpose : 1; // Prevents drawing recursion uint nativeWindowTransparencyEnabled : 1; // Tracks native window transparency + uint forcedToRaster : 1; #elif defined(Q_WS_QPA) QPlatformWindow *platformWindow; QPlatformWindowFormat platformWindowFormat; @@ -770,6 +771,7 @@ public: #ifndef QT_NO_IM uint inheritsInputMethodHints : 1; #endif + uint inSetParent : 1; // *************************** Platform specific ************************************ #if defined(Q_WS_X11) // <----------------------------------------------------------- X11 diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index e28a75a..c011cf1 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -235,11 +235,22 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) QSize oldSize(q->size()); QRect oldGeom(data.crect); + bool checkExtra = true; + if (q->isWindow() && (data.window_state & (Qt::WindowFullScreen | Qt::WindowMaximized))) { + // Do not allow fullscreen/maximized windows to expand beyond client rect + TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect(); + w = qMin(w, r.Width()); + h = qMin(h, r.Height()); + + if (w == r.Width() && h == r.Height()) + checkExtra = false; + } + // Lose maximized status if deliberate resize if (w != oldSize.width() || h != oldSize.height()) data.window_state &= ~Qt::WindowMaximized; - if (extra) { // any size restrictions? + if (checkExtra && extra) { // any size restrictions? w = qMin(w,extra->maxw); h = qMin(h,extra->maxh); w = qMax(w,extra->minw); @@ -567,6 +578,11 @@ void QWidgetPrivate::show_sys() if (isFullscreen) { const bool cbaVisible = S60->buttonGroupContainer() && S60->buttonGroupContainer()->IsVisible(); S60->setStatusPaneAndButtonGroupVisibility(false, cbaVisible); + if (cbaVisible) { + // Fix window dimensions as without screen furniture they will have + // defaulted to full screen dimensions initially. + id->handleClientAreaChange(); + } } } } @@ -781,7 +797,7 @@ void QWidgetPrivate::setParent_sys(QWidget *parent, Qt::WindowFlags f) adjustFlags(data.window_flags, q); // keep compatibility with previous versions, we need to preserve the created state // (but we recreate the winId for the widget being reparented, again for compatibility) - if (wasCreated || (!q->isWindow() && parent->testAttribute(Qt::WA_WState_Created))) + if (wasCreated || (!q->isWindow() && parent && parent->testAttribute(Qt::WA_WState_Created))) createWinId(); if (q->isWindow() || (!parent || parent->isVisible()) || explicitlyHidden) q->setAttribute(Qt::WA_WState_Hidden); @@ -824,7 +840,8 @@ void QWidgetPrivate::s60UpdateIsOpaque() RWindow *const window = static_cast<RWindow *>(q->effectiveWinId()->DrawableWindow()); #ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE - if (QApplicationPrivate::instance()->useTranslucentEGLSurfaces) { + if (QApplicationPrivate::instance()->useTranslucentEGLSurfaces + && !extra->topextra->forcedToRaster) { window->SetSurfaceTransparency(!isOpaque); extra->topextra->nativeWindowTransparencyEnabled = !isOpaque; return; @@ -1008,6 +1025,7 @@ void QWidgetPrivate::createTLSysExtra() { extra->topextra->inExpose = 0; extra->topextra->nativeWindowTransparencyEnabled = 0; + extra->topextra->forcedToRaster = 0; } void QWidgetPrivate::deleteTLSysExtra() diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 5ece7d6..3eec5c7 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -486,8 +486,6 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO bool topLevel = (flags & Qt::Window); bool popup = (type == Qt::Popup); - bool dialog = (type == Qt::Dialog - || type == Qt::Sheet); bool desktop = (type == Qt::Desktop); bool tool = (type == Qt::Tool || type == Qt::SplashScreen || type == Qt::ToolTip || type == Qt::Drawer); @@ -553,7 +551,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO int sh = DisplayHeight(dpy,scr); if (desktop) { // desktop widget - dialog = popup = false; // force these flags off + popup = false; // force these flags off data.crect.setRect(0, 0, sw, sh); } else if (topLevel && !q->testAttribute(Qt::WA_Resized)) { QDesktopWidget *desktopWidget = qApp->desktop(); @@ -954,8 +952,13 @@ static void qt_x11_recreateWidget(QWidget *widget) // recreate their GL context, which in turn causes them to choose // their visual again. Now that WA_TranslucentBackground is set, // QGLContext::chooseVisual will select an ARGB visual. - QEvent e(QEvent::ParentChange); - QApplication::sendEvent(widget, &e); + + // QGLWidget expects a ParentAboutToChange to be sent first + QEvent aboutToChangeEvent(QEvent::ParentAboutToChange); + QApplication::sendEvent(widget, &aboutToChangeEvent); + + QEvent parentChangeEvent(QEvent::ParentChange); + QApplication::sendEvent(widget, &parentChangeEvent); } else { // For regular widgets, reparent them with their parent which // also triggers a recreation of the native window diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 65e7af4..f1496b1 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -9,6 +9,7 @@ HEADERS += \ painting/qdrawutil.h \ painting/qemulationpaintengine_p.h \ painting/qgraphicssystem_p.h \ + painting/qgraphicssystemex_p.h \ painting/qmatrix.h \ painting/qmemrotate_p.h \ painting/qoutlinemapper_p.h \ @@ -249,8 +250,10 @@ embedded { symbian { HEADERS += painting/qwindowsurface_s60_p.h \ - painting/qdrawhelper_arm_simd_p.h - SOURCES += painting/qwindowsurface_s60.cpp + painting/qdrawhelper_arm_simd_p.h \ + painting/qgraphicssystemex_symbian_p.h + SOURCES += painting/qwindowsurface_s60.cpp \ + painting/qgraphicssystemex_symbian.cpp armccIfdefBlock = \ "$${LITERAL_HASH}if defined(ARMV6)" \ "MACRO QT_HAVE_ARM_SIMD" \ diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index bf5764a..3ff7eb8 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -840,6 +840,22 @@ const QGradient *QBrush::gradient() const return 0; } +Q_GUI_EXPORT bool qt_isExtendedRadialGradient(const QBrush &brush) +{ + if (brush.style() == Qt::RadialGradientPattern) { + const QGradient *g = brush.gradient(); + const QRadialGradient *rg = static_cast<const QRadialGradient *>(g); + + if (!qFuzzyIsNull(rg->focalRadius())) + return true; + + QPointF delta = rg->focalPoint() - rg->center(); + if (delta.x() * delta.x() + delta.y() * delta.y() > rg->radius() * rg->radius()) + return true; + } + + return false; +} /*! Returns true if the brush is fully opaque otherwise false. A brush @@ -849,6 +865,7 @@ const QGradient *QBrush::gradient() const \i The alpha component of the color() is 255. \i Its texture() does not have an alpha channel and is not a QBitmap. \i The colors in the gradient() all have an alpha component that is 255. + \i It is an extended radial gradient. \endlist */ @@ -860,6 +877,9 @@ bool QBrush::isOpaque() const if (d->style == Qt::SolidPattern) return opaqueColor; + if (qt_isExtendedRadialGradient(*this)) + return false; + if (d->style == Qt::LinearGradientPattern || d->style == Qt::RadialGradientPattern || d->style == Qt::ConicalGradientPattern) { @@ -1209,8 +1229,10 @@ QDataStream &operator>>(QDataStream &s, QBrush &b) \list \o \e Linear gradients interpolate colors between start and end points. - \o \e Radial gradients interpolate colors between a focal point and end - points on a circle surrounding it. + \o \e Simple radial gradients interpolate colors between a focal point + and end points on a circle surrounding it. + \o \e Extended radial gradients interpolate colors between a center and + a focal circle. \o \e Conical gradients interpolate colors around a center point. \endlist @@ -1506,8 +1528,6 @@ void QGradient::setInterpolationMode(InterpolationMode mode) dummy = p; } -#undef Q_DUMMY_ACCESSOR - /*! \fn bool QGradient::operator!=(const QGradient &gradient) const \since 4.2 @@ -1541,7 +1561,7 @@ bool QGradient::operator==(const QGradient &gradient) const || m_data.radial.cy != gradient.m_data.radial.cy || m_data.radial.fx != gradient.m_data.radial.fx || m_data.radial.fy != gradient.m_data.radial.fy - || m_data.radial.radius != gradient.m_data.radial.radius) + || m_data.radial.cradius != gradient.m_data.radial.cradius) return false; } else { // m_type == ConicalGradient if (m_data.conical.cx != gradient.m_data.conical.cx @@ -1747,10 +1767,17 @@ void QLinearGradient::setFinalStop(const QPointF &stop) \brief The QRadialGradient class is used in combination with QBrush to specify a radial gradient brush. - Radial gradients interpolate colors between a focal point and end - points on a circle surrounding it. Outside the end points the - gradient is either padded, reflected or repeated depending on the - currently set \l {QGradient::Spread}{spread} method: + Qt supports both simple and extended radial gradients. + + Simple radial gradients interpolate colors between a focal point and end + points on a circle surrounding it. Extended radial gradients interpolate + colors between a focal circle and a center circle. Points outside the cone + defined by the two circles will be transparent. For simple radial gradients + the focal point is adjusted to lie inside the center circle, whereas the + focal point can have any position in an extended radial gradient. + + Outside the end points the gradient is either padded, reflected or repeated + depending on the currently set \l {QGradient::Spread}{spread} method: \table \row @@ -1795,9 +1822,14 @@ static QPointF qt_radial_gradient_adapt_focal_point(const QPointF ¢er, } /*! - Constructs a radial gradient with the given \a center, \a + Constructs a simple radial gradient with the given \a center, \a radius and \a focalPoint. + \note If the given focal point is outside the circle defined by the + center (\a cx, \a cy) and the \a radius it will be re-adjusted to + the intersection between the line from the center to the focal point + and the circle. + \sa QGradient::setColorAt(), QGradient::setStops() */ @@ -1807,7 +1839,7 @@ QRadialGradient::QRadialGradient(const QPointF ¢er, qreal radius, const QPoi m_spread = PadSpread; m_data.radial.cx = center.x(); m_data.radial.cy = center.y(); - m_data.radial.radius = radius; + m_data.radial.cradius = radius; QPointF adapted_focal = qt_radial_gradient_adapt_focal_point(center, radius, focalPoint); m_data.radial.fx = adapted_focal.x(); @@ -1815,7 +1847,7 @@ QRadialGradient::QRadialGradient(const QPointF ¢er, qreal radius, const QPoi } /*! - Constructs a radial gradient with the given \a center, \a + Constructs a simple radial gradient with the given \a center, \a radius and the focal point in the circle center. \sa QGradient::setColorAt(), QGradient::setStops() @@ -1826,16 +1858,21 @@ QRadialGradient::QRadialGradient(const QPointF ¢er, qreal radius) m_spread = PadSpread; m_data.radial.cx = center.x(); m_data.radial.cy = center.y(); - m_data.radial.radius = radius; + m_data.radial.cradius = radius; m_data.radial.fx = center.x(); m_data.radial.fy = center.y(); } /*! - Constructs a radial gradient with the given center (\a cx, \a cy), + Constructs a simple radial gradient with the given center (\a cx, \a cy), \a radius and focal point (\a fx, \a fy). + \note If the given focal point is outside the circle defined by the + center (\a cx, \a cy) and the \a radius it will be re-adjusted to + the intersection between the line from the center to the focal point + and the circle. + \sa QGradient::setColorAt(), QGradient::setStops() */ @@ -1845,7 +1882,7 @@ QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius, qreal fx, qre m_spread = PadSpread; m_data.radial.cx = cx; m_data.radial.cy = cy; - m_data.radial.radius = radius; + m_data.radial.cradius = radius; QPointF adapted_focal = qt_radial_gradient_adapt_focal_point(QPointF(cx, cy), radius, @@ -1856,7 +1893,7 @@ QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius, qreal fx, qre } /*! - Constructs a radial gradient with the center at (\a cx, \a cy) and the + Constructs a simple radial gradient with the center at (\a cx, \a cy) and the specified \a radius. The focal point lies at the center of the circle. \sa QGradient::setColorAt(), QGradient::setStops() @@ -1867,14 +1904,14 @@ QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal radius) m_spread = PadSpread; m_data.radial.cx = cx; m_data.radial.cy = cy; - m_data.radial.radius = radius; + m_data.radial.cradius = radius; m_data.radial.fx = cx; m_data.radial.fy = cy; } /*! - Constructs a radial gradient with the center and focal point at + Constructs a simple radial gradient with the center and focal point at (0, 0) with a radius of 1. */ QRadialGradient::QRadialGradient() @@ -1883,11 +1920,51 @@ QRadialGradient::QRadialGradient() m_spread = PadSpread; m_data.radial.cx = 0; m_data.radial.cy = 0; - m_data.radial.radius = 1; + m_data.radial.cradius = 1; m_data.radial.fx = 0; m_data.radial.fy = 0; } +/*! + \since 4.8 + + Constructs an extended radial gradient with the given \a center, \a + centerRadius, \a focalPoint, and \a focalRadius. +*/ +QRadialGradient::QRadialGradient(const QPointF ¢er, qreal centerRadius, const QPointF &focalPoint, qreal focalRadius) +{ + m_type = RadialGradient; + m_spread = PadSpread; + m_data.radial.cx = center.x(); + m_data.radial.cy = center.y(); + m_data.radial.cradius = centerRadius; + + m_data.radial.fx = focalPoint.x(); + m_data.radial.fy = focalPoint.y(); + setFocalRadius(focalRadius); +} + +/*! + \since 4.8 + + Constructs an extended radial gradient with the given \a center, \a + centerRadius, \a focalPoint, and \a focalRadius. + Constructs a radial gradient with the given center (\a cx, \a cy), + center radius \a centerRadius, focal point (\a fx, \a fy), and + focal radius \a focalRadius. +*/ +QRadialGradient::QRadialGradient(qreal cx, qreal cy, qreal centerRadius, qreal fx, qreal fy, qreal focalRadius) +{ + m_type = RadialGradient; + m_spread = PadSpread; + m_data.radial.cx = cx; + m_data.radial.cy = cy; + m_data.radial.cradius = centerRadius; + + m_data.radial.fx = fx; + m_data.radial.fy = fy; + setFocalRadius(focalRadius); +} /*! Returns the center of this radial gradient in logical coordinates. @@ -1932,13 +2009,15 @@ void QRadialGradient::setCenter(const QPointF ¢er) /*! Returns the radius of this radial gradient in logical coordinates. + Equivalent to centerRadius() + \sa QGradient::stops() */ qreal QRadialGradient::radius() const { Q_ASSERT(m_type == RadialGradient); - return m_data.radial.radius; + return m_data.radial.cradius; } @@ -1947,13 +2026,81 @@ qreal QRadialGradient::radius() const Sets the radius of this radial gradient in logical coordinates to \a radius + + Equivalent to setCenterRadius() */ void QRadialGradient::setRadius(qreal radius) { Q_ASSERT(m_type == RadialGradient); - m_data.radial.radius = radius; + m_data.radial.cradius = radius; +} + +/*! + \since 4.8 + + Returns the center radius of this radial gradient in logical + coordinates. + + \sa QGradient::stops() +*/ +qreal QRadialGradient::centerRadius() const +{ + Q_ASSERT(m_type == RadialGradient); + return m_data.radial.cradius; +} + +/* + \since 4.8 + + Sets the center radius of this radial gradient in logical coordinates + to \a radius +*/ +void QRadialGradient::setCenterRadius(qreal radius) +{ + Q_ASSERT(m_type == RadialGradient); + m_data.radial.cradius = radius; +} + +/*! + \since 4.8 + + Returns the focal radius of this radial gradient in logical + coordinates. + + \sa QGradient::stops() +*/ +qreal QRadialGradient::focalRadius() const +{ + Q_ASSERT(m_type == RadialGradient); + Q_DUMMY_ACCESSOR + + // mask away low three bits + union { float f; quint32 i; } u; + u.i = i & ~0x07; + return u.f; } +/* + \since 4.8 + + Sets the focal radius of this radial gradient in logical coordinates + to \a radius +*/ +void QRadialGradient::setFocalRadius(qreal radius) +{ + Q_ASSERT(m_type == RadialGradient); + Q_DUMMY_ACCESSOR + + // Since there's no QGradientData, we only have the dummy void * to + // store additional data in. The three lowest bits are already + // taken, thus we cut the three lowest bits from the significand + // and store the radius as a float. + union { float f; quint32 i; } u; + u.f = float(radius); + // add 0x04 to round up when we drop the three lowest bits + i |= (u.i + 0x04) & ~0x07; + dummy = p; +} /*! Returns the focal point of this radial gradient in logical @@ -2193,4 +2340,6 @@ void QConicalGradient::setAngle(qreal angle) \sa setTransform() */ +#undef Q_DUMMY_ACCESSOR + QT_END_NAMESPACE diff --git a/src/gui/painting/qbrush.h b/src/gui/painting/qbrush.h index 8b31319..d914c8c 100644 --- a/src/gui/painting/qbrush.h +++ b/src/gui/painting/qbrush.h @@ -255,6 +255,7 @@ private: friend class QLinearGradient; friend class QRadialGradient; friend class QConicalGradient; + friend class QBrush; Type m_type; Spread m_spread; @@ -264,7 +265,7 @@ private: qreal x1, y1, x2, y2; } linear; struct { - qreal cx, cy, fx, fy, radius; + qreal cx, cy, fx, fy, cradius; } radial; struct { qreal cx, cy, angle; @@ -303,6 +304,9 @@ public: QRadialGradient(const QPointF ¢er, qreal radius); QRadialGradient(qreal cx, qreal cy, qreal radius); + QRadialGradient(const QPointF ¢er, qreal centerRadius, const QPointF &focalPoint, qreal focalRadius); + QRadialGradient(qreal cx, qreal cy, qreal centerRadius, qreal fx, qreal fy, qreal focalRadius); + QPointF center() const; void setCenter(const QPointF ¢er); inline void setCenter(qreal x, qreal y) { setCenter(QPointF(x, y)); } @@ -313,6 +317,12 @@ public: qreal radius() const; void setRadius(qreal radius); + + qreal centerRadius() const; + void setCenterRadius(qreal radius); + + qreal focalRadius() const; + void setFocalRadius(qreal radius); }; diff --git a/src/gui/painting/qcolor.cpp b/src/gui/painting/qcolor.cpp index ff6c24e..cd87d21 100644 --- a/src/gui/painting/qcolor.cpp +++ b/src/gui/painting/qcolor.cpp @@ -532,8 +532,7 @@ QString QColor::name() const void QColor::setNamedColor(const QString &name) { - if (!setColorFromString(name)) - qWarning("QColor::setNamedColor: Unknown color name '%s'", name.toLatin1().constData()); + setColorFromString(name); } /*! diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 5e75e4a..360292c 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -75,43 +75,9 @@ enum { fixed_scale = 1 << 16, half_point = 1 << 15 }; -static const int buffer_size = 2048; - -struct LinearGradientValues -{ - qreal dx; - qreal dy; - qreal l; - qreal off; -}; - -struct RadialGradientValues -{ - qreal dx; - qreal dy; - qreal a; -}; - -struct Operator; -typedef uint* (QT_FASTCALL *DestFetchProc)(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length); -typedef void (QT_FASTCALL *DestStoreProc)(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length); -typedef const uint* (QT_FASTCALL *SourceFetchProc)(uint *buffer, const Operator *o, const QSpanData *data, int y, int x, int length); - -struct Operator -{ - QPainter::CompositionMode mode; - DestFetchProc dest_fetch; - DestStoreProc dest_store; - SourceFetchProc src_fetch; - CompositionFunctionSolid funcSolid; - CompositionFunction func; - union { - LinearGradientValues linear; - RadialGradientValues radial; -// TextureValues texture; - }; -}; +// must be multiple of 4 for easier SIMD implementations +static const int buffer_size = 2048; /* Destination fetch. This is simple as we don't have to do bounds checks or @@ -1346,64 +1312,13 @@ static const SourceFetchProc sourceFetch[NBlendTypes][QImage::NImageFormats] = { }, }; - -static inline uint qt_gradient_pixel(const QGradientData *data, qreal pos) -{ - int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5)); - - // calculate the actual offset. - if (ipos < 0 || ipos >= GRADIENT_STOPTABLE_SIZE) { - if (data->spread == QGradient::RepeatSpread) { - ipos = ipos % GRADIENT_STOPTABLE_SIZE; - ipos = ipos < 0 ? GRADIENT_STOPTABLE_SIZE + ipos : ipos; - - } else if (data->spread == QGradient::ReflectSpread) { - const int limit = GRADIENT_STOPTABLE_SIZE * 2 - 1; - ipos = ipos % limit; - ipos = ipos < 0 ? limit + ipos : ipos; - ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - ipos : ipos; - - } else { - if (ipos < 0) ipos = 0; - else if (ipos >= GRADIENT_STOPTABLE_SIZE) ipos = GRADIENT_STOPTABLE_SIZE-1; - } - } - - Q_ASSERT(ipos >= 0); - Q_ASSERT(ipos < GRADIENT_STOPTABLE_SIZE); - - return data->colorTable[ipos]; -} - #define FIXPT_BITS 8 #define FIXPT_SIZE (1<<FIXPT_BITS) static uint qt_gradient_pixel_fixed(const QGradientData *data, int fixed_pos) { int ipos = (fixed_pos + (FIXPT_SIZE / 2)) >> FIXPT_BITS; - - // calculate the actual offset. - if (ipos < 0 || ipos >= GRADIENT_STOPTABLE_SIZE) { - if (data->spread == QGradient::RepeatSpread) { - ipos = ipos % GRADIENT_STOPTABLE_SIZE; - ipos = ipos < 0 ? GRADIENT_STOPTABLE_SIZE + ipos : ipos; - - } else if (data->spread == QGradient::ReflectSpread) { - const int limit = GRADIENT_STOPTABLE_SIZE * 2 - 1; - ipos = ipos % limit; - ipos = ipos < 0 ? limit + ipos : ipos; - ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - ipos : ipos; - - } else { - if (ipos < 0) ipos = 0; - else if (ipos >= GRADIENT_STOPTABLE_SIZE) ipos = GRADIENT_STOPTABLE_SIZE-1; - } - } - - Q_ASSERT(ipos >= 0); - Q_ASSERT(ipos < GRADIENT_STOPTABLE_SIZE); - - return data->colorTable[ipos]; + return data->colorTable[qt_gradient_clamp(data, ipos)]; } static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v, const QSpanData *data) @@ -1419,8 +1334,8 @@ static void QT_FASTCALL getLinearGradientValues(LinearGradientValues *v, const Q } } -static const uint * QT_FASTCALL fetchLinearGradient(uint *buffer, const Operator *op, const QSpanData *data, - int y, int x, int length) +static const uint * QT_FASTCALL qt_fetch_linear_gradient(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length) { const uint *b = buffer; qreal t, inc; @@ -1487,110 +1402,65 @@ static const uint * QT_FASTCALL fetchLinearGradient(uint *buffer, const Operator return b; } -static inline qreal determinant(qreal a, qreal b, qreal c) -{ - return (b * b) - (4 * a * c); -} - -// function to evaluate real roots -static inline qreal realRoots(qreal a, qreal b, qreal detSqrt) -{ - return (-b + detSqrt)/(2 * a); -} - -static inline qreal qSafeSqrt(qreal x) -{ - return x > 0 ? qSqrt(x) : 0; -} - static void QT_FASTCALL getRadialGradientValues(RadialGradientValues *v, const QSpanData *data) { v->dx = data->gradient.radial.center.x - data->gradient.radial.focal.x; v->dy = data->gradient.radial.center.y - data->gradient.radial.focal.y; - v->a = data->gradient.radial.radius*data->gradient.radial.radius - v->dx*v->dx - v->dy*v->dy; -} - -static const uint * QT_FASTCALL fetchRadialGradient(uint *buffer, const Operator *op, const QSpanData *data, - int y, int x, int length) -{ - const uint *b = buffer; - qreal rx = data->m21 * (y + qreal(0.5)) - + data->dx + data->m11 * (x + qreal(0.5)); - qreal ry = data->m22 * (y + qreal(0.5)) - + data->dy + data->m12 * (x + qreal(0.5)); - bool affine = !data->m13 && !data->m23; - //qreal r = data->gradient.radial.radius; - - const uint *end = buffer + length; - if (affine) { - rx -= data->gradient.radial.focal.x; - ry -= data->gradient.radial.focal.y; - - qreal inv_a = 1 / qreal(2 * op->radial.a); - - const qreal delta_rx = data->m11; - const qreal delta_ry = data->m12; - - qreal b = 2*(rx * op->radial.dx + ry * op->radial.dy); - qreal delta_b = 2*(delta_rx * op->radial.dx + delta_ry * op->radial.dy); - const qreal b_delta_b = 2 * b * delta_b; - const qreal delta_b_delta_b = 2 * delta_b * delta_b; - const qreal bb = b * b; - const qreal delta_bb = delta_b * delta_b; + v->dr = data->gradient.radial.center.radius - data->gradient.radial.focal.radius; + v->sqrfr = data->gradient.radial.focal.radius * data->gradient.radial.focal.radius; - b *= inv_a; - delta_b *= inv_a; + v->a = v->dr * v->dr - v->dx*v->dx - v->dy*v->dy; + v->inv2a = 1 / (2 * v->a); - const qreal rxrxryry = rx * rx + ry * ry; - const qreal delta_rxrxryry = delta_rx * delta_rx + delta_ry * delta_ry; - const qreal rx_plus_ry = 2*(rx * delta_rx + ry * delta_ry); - const qreal delta_rx_plus_ry = 2 * delta_rxrxryry; - - inv_a *= inv_a; - - qreal det = (bb + 4 * op->radial.a * rxrxryry) * inv_a; - qreal delta_det = (b_delta_b + delta_bb + 4 * op->radial.a * (rx_plus_ry + delta_rxrxryry)) * inv_a; - const qreal delta_delta_det = (delta_b_delta_b + 4 * op->radial.a * delta_rx_plus_ry) * inv_a; + v->extended = !qFuzzyIsNull(data->gradient.radial.focal.radius) || v->a <= 0; +} - while (buffer < end) { - *buffer = qt_gradient_pixel(&data->gradient, qSafeSqrt(det) - b); +class RadialFetchPlain +{ +public: + static inline void fetch(uint *buffer, uint *end, const Operator *op, const QSpanData *data, qreal det, + qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b) + { + if (op->radial.extended) { + while (buffer < end) { + quint32 result = 0; + if (det >= 0) { + qreal w = qSqrt(det) - b; + if (data->gradient.radial.focal.radius + op->radial.dr * w >= 0) + result = qt_gradient_pixel(&data->gradient, w); + } - det += delta_det; - delta_det += delta_delta_det; - b += delta_b; + *buffer = result; - ++buffer; - } - } else { - qreal rw = data->m23 * (y + qreal(0.5)) - + data->m33 + data->m13 * (x + qreal(0.5)); - if (!rw) - rw = 1; - while (buffer < end) { - qreal gx = rx/rw - data->gradient.radial.focal.x; - qreal gy = ry/rw - data->gradient.radial.focal.y; - qreal b = 2*(gx*op->radial.dx + gy*op->radial.dy); - qreal det = determinant(op->radial.a, b , -(gx*gx + gy*gy)); - qreal s = realRoots(op->radial.a, b, qSafeSqrt(det)); + det += delta_det; + delta_det += delta_delta_det; + b += delta_b; - *buffer = qt_gradient_pixel(&data->gradient, s); + ++buffer; + } + } else { + while (buffer < end) { + *buffer++ = qt_gradient_pixel(&data->gradient, qSqrt(det) - b); - rx += data->m11; - ry += data->m12; - rw += data->m13; - if (!rw) { - rw += data->m13; + det += delta_det; + delta_det += delta_delta_det; + b += delta_b; } - ++buffer; } } +}; - return b; +const uint * QT_FASTCALL qt_fetch_radial_gradient_plain(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length) +{ + return qt_fetch_radial_gradient_template<RadialFetchPlain>(buffer, op, data, y, x, length); } -static const uint * QT_FASTCALL fetchConicalGradient(uint *buffer, const Operator *, const QSpanData *data, - int y, int x, int length) +static SourceFetchProc qt_fetch_radial_gradient = qt_fetch_radial_gradient_plain; + +static const uint * QT_FASTCALL qt_fetch_conical_gradient(uint *buffer, const Operator *, const QSpanData *data, + int y, int x, int length) { const uint *b = buffer; qreal rx = data->m21 * (y + qreal(0.5)) @@ -3347,16 +3217,16 @@ static inline Operator getOperator(const QSpanData *data, const QSpan *spans, in case QSpanData::LinearGradient: solidSource = !data->gradient.alphaColor; getLinearGradientValues(&op.linear, data); - op.src_fetch = fetchLinearGradient; + op.src_fetch = qt_fetch_linear_gradient; break; case QSpanData::RadialGradient: solidSource = !data->gradient.alphaColor; getRadialGradientValues(&op.radial, data); - op.src_fetch = fetchRadialGradient; + op.src_fetch = qt_fetch_radial_gradient; break; case QSpanData::ConicalGradient: solidSource = !data->gradient.alphaColor; - op.src_fetch = fetchConicalGradient; + op.src_fetch = qt_fetch_conical_gradient; break; case QSpanData::Texture: op.src_fetch = sourceFetch[getBlendType(data)][data->texture.format]; @@ -7198,14 +7068,8 @@ void qt_build_pow_tables() { #endif #ifdef Q_WS_WIN - int winSmooth; - if (SystemParametersInfo(0x200C /* SPI_GETFONTSMOOTHINGCONTRAST */, 0, &winSmooth, 0)) - smoothing = winSmooth / qreal(1000.0); - - // Safeguard ourselves against corrupt registry values... - if (smoothing > 5 || smoothing < 1) - smoothing = qreal(1.4); - + extern qreal qt_fontsmoothing_gamma; // qapplication_win.cpp + smoothing = qt_fontsmoothing_gamma; #endif #ifdef Q_WS_X11 @@ -7888,6 +7752,11 @@ void qInitDrawhelperAsm() qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_RGB32] = qt_blend_rgb32_on_rgb32_sse2; qBlendFunctions[QImage::Format_RGB32][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; qBlendFunctions[QImage::Format_ARGB32_Premultiplied][QImage::Format_ARGB32_Premultiplied] = qt_blend_argb32_on_argb32_sse2; + + extern const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length); + + qt_fetch_radial_gradient = qt_fetch_radial_gradient_sse2; } #ifdef QT_HAVE_SSSE3 @@ -7983,6 +7852,11 @@ void qInitDrawhelperAsm() qMemRotateFunctions[QImage::Format_RGB16][0] = qt_memrotate90_16_neon; qMemRotateFunctions[QImage::Format_RGB16][2] = qt_memrotate270_16_neon; qt_memfill32 = qt_memfill32_neon; + + extern const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length); + + qt_fetch_radial_gradient = qt_fetch_radial_gradient_neon; } #endif diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp index debca37..e673dd9 100644 --- a/src/gui/painting/qdrawhelper_neon.cpp +++ b/src/gui/painting/qdrawhelper_neon.cpp @@ -955,6 +955,46 @@ void qt_memrotate270_16_neon(const uchar *srcPixels, int w, int h, } } +class QSimdNeon +{ +public: + typedef int32x4_t Int32x4; + typedef float32x4_t Float32x4; + + union Vect_buffer_i { Int32x4 v; int i[4]; }; + union Vect_buffer_f { Float32x4 v; float f[4]; }; + + static inline Float32x4 v_dup(float x) { return vdupq_n_f32(x); } + static inline Int32x4 v_dup(int x) { return vdupq_n_s32(x); } + static inline Int32x4 v_dup(uint x) { return vdupq_n_s32(x); } + + static inline Float32x4 v_add(Float32x4 a, Float32x4 b) { return vaddq_f32(a, b); } + static inline Int32x4 v_add(Int32x4 a, Int32x4 b) { return vaddq_s32(a, b); } + + static inline Float32x4 v_max(Float32x4 a, Float32x4 b) { return vmaxq_f32(a, b); } + static inline Float32x4 v_min(Float32x4 a, Float32x4 b) { return vminq_f32(a, b); } + static inline Int32x4 v_min_16(Int32x4 a, Int32x4 b) { return vminq_s32(a, b); } + + static inline Int32x4 v_and(Int32x4 a, Int32x4 b) { return vandq_s32(a, b); } + + static inline Float32x4 v_sub(Float32x4 a, Float32x4 b) { return vsubq_f32(a, b); } + static inline Int32x4 v_sub(Int32x4 a, Int32x4 b) { return vsubq_s32(a, b); } + + static inline Float32x4 v_mul(Float32x4 a, Float32x4 b) { return vmulq_f32(a, b); } + + static inline Float32x4 v_sqrt(Float32x4 x) { Float32x4 y = vrsqrteq_f32(x); y = vmulq_f32(y, vrsqrtsq_f32(x, vmulq_f32(y, y))); return vmulq_f32(x, y); } + + static inline Int32x4 v_toInt(Float32x4 x) { return vcvtq_s32_f32(x); } + + static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return vcge_f32(a, b); } +}; + +const uint * QT_FASTCALL qt_fetch_radial_gradient_neon(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length) +{ + return qt_fetch_radial_gradient_template<QRadialFetchSimd<QSimdNeon> >(buffer, op, data, y, x, length); +} + QT_END_NAMESPACE #endif // QT_HAVE_NEON diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h index d4e731b..fa6ad0b 100644 --- a/src/gui/painting/qdrawhelper_p.h +++ b/src/gui/painting/qdrawhelper_p.h @@ -63,6 +63,7 @@ #endif #include "private/qrasterdefs_p.h" #include <private/qsimd_p.h> +#include <private/qmath_p.h> #ifdef Q_WS_QWS #include "QtGui/qscreen_qws.h" @@ -178,6 +179,44 @@ void qBlendTextureCallback(int count, const QSpan *spans, void *userData); typedef void (QT_FASTCALL *CompositionFunction)(uint *dest, const uint *src, int length, uint const_alpha); typedef void (QT_FASTCALL *CompositionFunctionSolid)(uint *dest, int length, uint color, uint const_alpha); +struct LinearGradientValues +{ + qreal dx; + qreal dy; + qreal l; + qreal off; +}; + +struct RadialGradientValues +{ + qreal dx; + qreal dy; + qreal dr; + qreal sqrfr; + qreal a; + qreal inv2a; + bool extended; +}; + +struct Operator; +typedef uint* (QT_FASTCALL *DestFetchProc)(uint *buffer, QRasterBuffer *rasterBuffer, int x, int y, int length); +typedef void (QT_FASTCALL *DestStoreProc)(QRasterBuffer *rasterBuffer, int x, int y, const uint *buffer, int length); +typedef const uint* (QT_FASTCALL *SourceFetchProc)(uint *buffer, const Operator *o, const QSpanData *data, int y, int x, int length); + +struct Operator +{ + QPainter::CompositionMode mode; + DestFetchProc dest_fetch; + DestStoreProc dest_store; + SourceFetchProc src_fetch; + CompositionFunctionSolid funcSolid; + CompositionFunction func; + union { + LinearGradientValues linear; + RadialGradientValues radial; + }; +}; + void qInitDrawhelperAsm(); class QRasterPaintEngine; @@ -204,12 +243,13 @@ struct QRadialGradientData struct { qreal x; qreal y; + qreal radius; } center; struct { qreal x; qreal y; + qreal radius; } focal; - qreal radius; }; struct QConicalGradientData @@ -233,8 +273,10 @@ struct QGradientData #ifdef Q_WS_QWS #define GRADIENT_STOPTABLE_SIZE 256 +#define GRADIENT_STOPTABLE_SIZE_SHIFT 8 #else #define GRADIENT_STOPTABLE_SIZE 1024 +#define GRADIENT_STOPTABLE_SIZE_SHIFT 10 #endif uint* colorTable; //[GRADIENT_STOPTABLE_SIZE]; @@ -308,6 +350,218 @@ struct QSpanData void adjustSpanMethods(); }; +static inline uint qt_gradient_clamp(const QGradientData *data, int ipos) +{ + if (ipos < 0 || ipos >= GRADIENT_STOPTABLE_SIZE) { + if (data->spread == QGradient::RepeatSpread) { + ipos = ipos % GRADIENT_STOPTABLE_SIZE; + ipos = ipos < 0 ? GRADIENT_STOPTABLE_SIZE + ipos : ipos; + } else if (data->spread == QGradient::ReflectSpread) { + const int limit = GRADIENT_STOPTABLE_SIZE * 2; + ipos = ipos % limit; + ipos = ipos < 0 ? limit + ipos : ipos; + ipos = ipos >= GRADIENT_STOPTABLE_SIZE ? limit - 1 - ipos : ipos; + } else { + if (ipos < 0) + ipos = 0; + else if (ipos >= GRADIENT_STOPTABLE_SIZE) + ipos = GRADIENT_STOPTABLE_SIZE-1; + } + } + + Q_ASSERT(ipos >= 0); + Q_ASSERT(ipos < GRADIENT_STOPTABLE_SIZE); + + return ipos; +} + +static inline uint qt_gradient_pixel(const QGradientData *data, qreal pos) +{ + int ipos = int(pos * (GRADIENT_STOPTABLE_SIZE - 1) + qreal(0.5)); + return data->colorTable[qt_gradient_clamp(data, ipos)]; +} + +static inline qreal qRadialDeterminant(qreal a, qreal b, qreal c) +{ + return (b * b) - (4 * a * c); +} + +template <class RadialFetchFunc> +const uint * QT_FASTCALL qt_fetch_radial_gradient_template(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length) +{ + // avoid division by zero + if (qFuzzyIsNull(op->radial.a)) { + extern void (*qt_memfill32)(quint32 *dest, quint32 value, int count); + qt_memfill32(buffer, 0, length); + return buffer; + } + + const uint *b = buffer; + qreal rx = data->m21 * (y + qreal(0.5)) + + data->dx + data->m11 * (x + qreal(0.5)); + qreal ry = data->m22 * (y + qreal(0.5)) + + data->dy + data->m12 * (x + qreal(0.5)); + bool affine = !data->m13 && !data->m23; + + uint *end = buffer + length; + if (affine) { + rx -= data->gradient.radial.focal.x; + ry -= data->gradient.radial.focal.y; + + qreal inv_a = 1 / qreal(2 * op->radial.a); + + const qreal delta_rx = data->m11; + const qreal delta_ry = data->m12; + + qreal b = 2*(op->radial.dr*data->gradient.radial.focal.radius + rx * op->radial.dx + ry * op->radial.dy); + qreal delta_b = 2*(delta_rx * op->radial.dx + delta_ry * op->radial.dy); + const qreal b_delta_b = 2 * b * delta_b; + const qreal delta_b_delta_b = 2 * delta_b * delta_b; + + const qreal bb = b * b; + const qreal delta_bb = delta_b * delta_b; + + b *= inv_a; + delta_b *= inv_a; + + const qreal rxrxryry = rx * rx + ry * ry; + const qreal delta_rxrxryry = delta_rx * delta_rx + delta_ry * delta_ry; + const qreal rx_plus_ry = 2*(rx * delta_rx + ry * delta_ry); + const qreal delta_rx_plus_ry = 2 * delta_rxrxryry; + + inv_a *= inv_a; + + qreal det = (bb - 4 * op->radial.a * (op->radial.sqrfr - rxrxryry)) * inv_a; + qreal delta_det = (b_delta_b + delta_bb + 4 * op->radial.a * (rx_plus_ry + delta_rxrxryry)) * inv_a; + const qreal delta_delta_det = (delta_b_delta_b + 4 * op->radial.a * delta_rx_plus_ry) * inv_a; + + RadialFetchFunc::fetch(buffer, end, op, data, det, delta_det, delta_delta_det, b, delta_b); + } else { + qreal rw = data->m23 * (y + qreal(0.5)) + + data->m33 + data->m13 * (x + qreal(0.5)); + + while (buffer < end) { + if (rw == 0) { + *buffer = 0; + } else { + qreal invRw = 1 / rw; + qreal gx = rx * invRw - data->gradient.radial.focal.x; + qreal gy = ry * invRw - data->gradient.radial.focal.y; + qreal b = 2*(op->radial.dr*data->gradient.radial.focal.radius + gx*op->radial.dx + gy*op->radial.dy); + qreal det = qRadialDeterminant(op->radial.a, b, op->radial.sqrfr - (gx*gx + gy*gy)); + + quint32 result = 0; + if (det >= 0) { + qreal detSqrt = qSqrt(det); + + qreal s0 = (-b - detSqrt) * op->radial.inv2a; + qreal s1 = (-b + detSqrt) * op->radial.inv2a; + + qreal s = qMax(s0, s1); + + if (data->gradient.radial.focal.radius + op->radial.dr * s >= 0) + result = qt_gradient_pixel(&data->gradient, s); + } + + *buffer = result; + } + + rx += data->m11; + ry += data->m12; + rw += data->m13; + + ++buffer; + } + } + + return b; +} + +template <class Simd> +class QRadialFetchSimd +{ +public: + static void fetch(uint *buffer, uint *end, const Operator *op, const QSpanData *data, qreal det, + qreal delta_det, qreal delta_delta_det, qreal b, qreal delta_b) + { + typename Simd::Vect_buffer_f det_vec; + typename Simd::Vect_buffer_f delta_det4_vec; + typename Simd::Vect_buffer_f b_vec; + + for (int i = 0; i < 4; ++i) { + det_vec.f[i] = det; + delta_det4_vec.f[i] = 4 * delta_det; + b_vec.f[i] = b; + + det += delta_det; + delta_det += delta_delta_det; + b += delta_b; + } + + const typename Simd::Float32x4 v_delta_delta_det16 = Simd::v_dup(16 * delta_delta_det); + const typename Simd::Float32x4 v_delta_delta_det6 = Simd::v_dup(6 * delta_delta_det); + const typename Simd::Float32x4 v_delta_b4 = Simd::v_dup(4 * delta_b); + + const typename Simd::Float32x4 v_r0 = Simd::v_dup(data->gradient.radial.focal.radius); + const typename Simd::Float32x4 v_dr = Simd::v_dup(op->radial.dr); + + const typename Simd::Float32x4 v_min = Simd::v_dup(0.0f); + const typename Simd::Float32x4 v_max = Simd::v_dup(float(GRADIENT_STOPTABLE_SIZE-1)); + const typename Simd::Float32x4 v_half = Simd::v_dup(0.5f); + + const typename Simd::Int32x4 v_repeat_mask = Simd::v_dup(~(uint(0xffffff) << GRADIENT_STOPTABLE_SIZE_SHIFT)); + const typename Simd::Int32x4 v_reflect_mask = Simd::v_dup(~(uint(0xffffff) << (GRADIENT_STOPTABLE_SIZE_SHIFT+1))); + + const typename Simd::Int32x4 v_reflect_limit = Simd::v_dup(2 * GRADIENT_STOPTABLE_SIZE - 1); + + const int extended_mask = op->radial.extended ? 0x0 : ~0x0; + +#define FETCH_RADIAL_LOOP_PROLOGUE \ + while (buffer < end) { \ + typename Simd::Vect_buffer_i v_buffer_mask; \ + v_buffer_mask.v = Simd::v_greaterOrEqual(det_vec.v, v_min); \ + const typename Simd::Float32x4 v_index_local = Simd::v_sub(Simd::v_sqrt(Simd::v_max(v_min, det_vec.v)), b_vec.v); \ + const typename Simd::Float32x4 v_index = Simd::v_add(Simd::v_mul(v_index_local, v_max), v_half); \ + v_buffer_mask.v = Simd::v_and(v_buffer_mask.v, Simd::v_greaterOrEqual(Simd::v_add(v_r0, Simd::v_mul(v_dr, v_index_local)), v_min)); \ + typename Simd::Vect_buffer_i index_vec; +#define FETCH_RADIAL_LOOP_CLAMP_REPEAT \ + index_vec.v = Simd::v_and(v_repeat_mask, Simd::v_toInt(v_index)); +#define FETCH_RADIAL_LOOP_CLAMP_REFLECT \ + const typename Simd::Int32x4 v_index_i = Simd::v_and(v_reflect_mask, Simd::v_toInt(v_index)); \ + const typename Simd::Int32x4 v_index_i_inv = Simd::v_sub(v_reflect_limit, v_index_i); \ + index_vec.v = Simd::v_min_16(v_index_i, v_index_i_inv); +#define FETCH_RADIAL_LOOP_CLAMP_PAD \ + index_vec.v = Simd::v_toInt(Simd::v_min(v_max, Simd::v_max(v_min, v_index))); +#define FETCH_RADIAL_LOOP_EPILOGUE \ + det_vec.v = Simd::v_add(Simd::v_add(det_vec.v, delta_det4_vec.v), v_delta_delta_det6); \ + delta_det4_vec.v = Simd::v_add(delta_det4_vec.v, v_delta_delta_det16); \ + b_vec.v = Simd::v_add(b_vec.v, v_delta_b4); \ + for (int i = 0; i < 4; ++i) \ + *buffer++ = (extended_mask | v_buffer_mask.i[i]) & data->gradient.colorTable[index_vec.i[i]]; \ + } + +#define FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP) \ + FETCH_RADIAL_LOOP_PROLOGUE \ + FETCH_RADIAL_LOOP_CLAMP \ + FETCH_RADIAL_LOOP_EPILOGUE + + switch (data->gradient.spread) { + case QGradient::RepeatSpread: + FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP_REPEAT) + break; + case QGradient::ReflectSpread: + FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP_REFLECT) + break; + case QGradient::PadSpread: + FETCH_RADIAL_LOOP(FETCH_RADIAL_LOOP_CLAMP_PAD) + break; + default: + Q_ASSERT(false); + } + } +}; + #if defined(Q_CC_RVCT) # pragma push # pragma arm diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp index aad6bc9..75bb619 100644 --- a/src/gui/painting/qdrawhelper_sse2.cpp +++ b/src/gui/painting/qdrawhelper_sse2.cpp @@ -112,8 +112,6 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, // First, align dest to 16 bytes: ALIGNMENT_PROLOGUE_16BYTES(dst, x, w) { - quint32 s = src[x]; - s = BYTE_MUL(s, const_alpha); dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha); } @@ -127,8 +125,6 @@ void qt_blend_rgb32_on_rgb32_sse2(uchar *destPixels, int dbpl, } } for (; x<w; ++x) { - quint32 s = src[x]; - s = BYTE_MUL(s, const_alpha); dst[x] = INTERPOLATE_PIXEL_255(src[x], const_alpha, dst[x], one_minus_const_alpha); } dst = (quint32 *)(((uchar *) dst) + dbpl); @@ -491,6 +487,58 @@ void qt_bitmapblit16_sse2(QRasterBuffer *rasterBuffer, int x, int y, } } +class QSimdSse2 +{ +public: + typedef __m128i Int32x4; + typedef __m128 Float32x4; + + union Vect_buffer_i { Int32x4 v; int i[4]; }; + union Vect_buffer_f { Float32x4 v; float f[4]; }; + + static inline Float32x4 v_dup(float x) { return _mm_set1_ps(x); } + static inline Float32x4 v_dup(double x) { return _mm_set1_ps(x); } + static inline Int32x4 v_dup(int x) { return _mm_set1_epi32(x); } + static inline Int32x4 v_dup(uint x) { return _mm_set1_epi32(x); } + + static inline Float32x4 v_add(Float32x4 a, Float32x4 b) { return _mm_add_ps(a, b); } + static inline Int32x4 v_add(Int32x4 a, Int32x4 b) { return _mm_add_epi32(a, b); } + + static inline Float32x4 v_max(Float32x4 a, Float32x4 b) { return _mm_max_ps(a, b); } + static inline Float32x4 v_min(Float32x4 a, Float32x4 b) { return _mm_min_ps(a, b); } + static inline Int32x4 v_min_16(Int32x4 a, Int32x4 b) { return _mm_min_epi16(a, b); } + + static inline Int32x4 v_and(Int32x4 a, Int32x4 b) { return _mm_and_si128(a, b); } + + static inline Float32x4 v_sub(Float32x4 a, Float32x4 b) { return _mm_sub_ps(a, b); } + static inline Int32x4 v_sub(Int32x4 a, Int32x4 b) { return _mm_sub_epi32(a, b); } + + static inline Float32x4 v_mul(Float32x4 a, Float32x4 b) { return _mm_mul_ps(a, b); } + + static inline Float32x4 v_sqrt(Float32x4 x) { return _mm_sqrt_ps(x); } + + static inline Int32x4 v_toInt(Float32x4 x) { return _mm_cvttps_epi32(x); } + + // pre-VS 2008 doesn't have cast intrinsics, whereas 2008 and later requires it +#if defined(Q_CC_MSVC) && _MSC_VER < 1500 + static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) + { + union Convert { Int32x4 vi; Float32x4 vf; } convert; + convert.vf = _mm_cmpgt_ps(a, b); + return convert.vi; + } +#else + static inline Int32x4 v_greaterOrEqual(Float32x4 a, Float32x4 b) { return _mm_castps_si128(_mm_cmpgt_ps(a, b)); } +#endif +}; + +const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Operator *op, const QSpanData *data, + int y, int x, int length) +{ + return qt_fetch_radial_gradient_template<QRadialFetchSimd<QSimdSse2> >(buffer, op, data, y, x, length); +} + + QT_END_NAMESPACE #endif // QT_HAVE_SSE2 diff --git a/src/gui/painting/qgraphicssystem.cpp b/src/gui/painting/qgraphicssystem.cpp index 171ef46..d82fdc9 100644 --- a/src/gui/painting/qgraphicssystem.cpp +++ b/src/gui/painting/qgraphicssystem.cpp @@ -55,6 +55,9 @@ #endif #ifdef Q_OS_SYMBIAN # include <private/qpixmap_s60_p.h> +# include <private/qgraphicssystemex_symbian_p.h> +#else +# include <private/qgraphicssystemex_p.h> #endif QT_BEGIN_NAMESPACE @@ -89,9 +92,18 @@ QPixmapData *QGraphicsSystem::createPixmapData(QPixmapData *origin) return createPixmapData(origin->pixelType()); } -void QGraphicsSystem::releaseCachedResources() +#ifdef Q_OS_SYMBIAN +Q_GLOBAL_STATIC(QSymbianGraphicsSystemEx, symbianPlatformExtension) +#endif + +QGraphicsSystemEx* QGraphicsSystem::platformExtension() { - // Do nothing here +#ifdef Q_OS_SYMBIAN + // this is used on raster graphics systems. HW accelerated + // graphics systems will overwrite this function. + return symbianPlatformExtension(); +#endif + return 0; } QT_END_NAMESPACE diff --git a/src/gui/painting/qgraphicssystem_p.h b/src/gui/painting/qgraphicssystem_p.h index 0f99a31..275f9eb 100644 --- a/src/gui/painting/qgraphicssystem_p.h +++ b/src/gui/painting/qgraphicssystem_p.h @@ -63,6 +63,7 @@ QT_BEGIN_NAMESPACE class QPixmapFilter; class QBlittable; +class QGraphicsSystemEx; class Q_GUI_EXPORT QGraphicsSystem { @@ -77,7 +78,7 @@ public: // to have a graphics system. static QPixmapData *createDefaultPixmapData(QPixmapData::PixelType type); - virtual void releaseCachedResources(); + virtual QGraphicsSystemEx* platformExtension(); }; QT_END_NAMESPACE diff --git a/src/gui/painting/qgraphicssystemex_p.h b/src/gui/painting/qgraphicssystemex_p.h new file mode 100644 index 0000000..6feb116 --- /dev/null +++ b/src/gui/painting/qgraphicssystemex_p.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 QGRAPHICSSYSTEMEX_P_H +#define QGRAPHICSSYSTEMEX_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <qglobal.h> + +QT_BEGIN_NAMESPACE + +class Q_GUI_EXPORT QGraphicsSystemEx +{ +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/gui/painting/qgraphicssystemex_symbian.cpp b/src/gui/painting/qgraphicssystemex_symbian.cpp new file mode 100644 index 0000000..2d3f137 --- /dev/null +++ b/src/gui/painting/qgraphicssystemex_symbian.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 "qgraphicssystemex_symbian_p.h" +#include "private/qwidget_p.h" +#include "private/qbackingstore_p.h" +#include "private/qapplication_p.h" + +#include <QDebug> + +QT_BEGIN_NAMESPACE + +void QSymbianGraphicsSystemEx::releaseCachedGpuResources() +{ + // Do nothing here + // This is implemented in graphics system specific plugin +} + +void QSymbianGraphicsSystemEx::releaseAllGpuResources() +{ + releaseCachedGpuResources(); + + foreach (QWidget *widget, QApplication::topLevelWidgets()) { + if (QTLWExtra *topExtra = qt_widget_private(widget)->maybeTopData()) + topExtra->backingStore.destroy(); + } +} + +bool QSymbianGraphicsSystemEx::hasBCM2727() +{ + return !QApplicationPrivate::instance()->useTranslucentEGLSurfaces; +} + +void QSymbianGraphicsSystemEx::forceToRaster(QWidget *window) +{ + if (window && window->isWindow()) { + qt_widget_private(window)->createTLExtra(); + if (QTLWExtra *topExtra = qt_widget_private(window)->maybeTopData()) { + topExtra->forcedToRaster = 1; + if (topExtra->backingStore.data()) { + topExtra->backingStore.create(window); + topExtra->backingStore.registerWidget(window); + } + } + } +} + +QT_END_NAMESPACE diff --git a/src/gui/util/qscrollerproperties_p.h b/src/gui/painting/qgraphicssystemex_symbian_p.h index 76d8b0a..0b1e39e 100644 --- a/src/gui/util/qscrollerproperties_p.h +++ b/src/gui/painting/qgraphicssystemex_symbian_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QSCROLLERPROPERTIES_P_H -#define QSCROLLERPROPERTIES_P_H +#ifndef QSYMBIANGRAPHICSSYSTEMEX_P_H +#define QSYMBIANGRAPHICSSYSTEMEX_P_H // // W A R N I N G @@ -53,42 +53,21 @@ // We mean it. // -#include <QPointF> -#include <QEasingCurve> -#include <qscrollerproperties.h> +#include "private/qgraphicssystemex_p.h" QT_BEGIN_NAMESPACE -class QScrollerPropertiesPrivate +class QWidget; + +class Q_GUI_EXPORT QSymbianGraphicsSystemEx : public QGraphicsSystemEx { public: - static QScrollerPropertiesPrivate *defaults(); - - bool operator==(const QScrollerPropertiesPrivate &) const; - - qreal mousePressEventDelay; - qreal dragStartDistance; - qreal dragVelocitySmoothingFactor; - qreal axisLockThreshold; - QEasingCurve scrollingCurve; - qreal decelerationFactor; - qreal minimumVelocity; - qreal maximumVelocity; - qreal maximumClickThroughVelocity; - qreal acceleratingFlickMaximumTime; - qreal acceleratingFlickSpeedupFactor; - qreal snapPositionRatio; - qreal snapTime; - qreal overshootDragResistanceFactor; - qreal overshootDragDistanceFactor; - qreal overshootScrollDistanceFactor; - qreal overshootScrollTime; - QScrollerProperties::OvershootPolicy hOvershootPolicy; - QScrollerProperties::OvershootPolicy vOvershootPolicy; - QScrollerProperties::FrameRates frameRate; + virtual void releaseCachedGpuResources(); + virtual void releaseAllGpuResources(); + virtual bool hasBCM2727(); + virtual void forceToRaster(QWidget *window); }; QT_END_NAMESPACE -#endif // QSCROLLERPROPERTIES_P_H - +#endif diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp index 62a60d7..6212674 100644 --- a/src/gui/painting/qgraphicssystemfactory.cpp +++ b/src/gui/painting/qgraphicssystemfactory.cpp @@ -74,7 +74,7 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key) if (system.isEmpty()) { system = QLatin1String("runtime"); } -#elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) || defined(Q_WS_X11) +#elif defined (QT_GRAPHICSSYSTEM_RASTER) && !defined(Q_WS_WIN) && !defined(Q_OS_SYMBIAN) || defined(Q_WS_X11) || (defined (Q_WS_MAC) && defined(QT_MAC_USE_COCOA)) if (system.isEmpty()) { system = QLatin1String("raster"); } diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp index 7870def..6f6cd6f 100644 --- a/src/gui/painting/qpaintbuffer.cpp +++ b/src/gui/painting/qpaintbuffer.cpp @@ -535,16 +535,6 @@ QString QPaintBuffer::commandDescription(int command) const QTextItemInt &ti = (*tiCopy)(); QString text(ti.text()); - QFont font(ti.font()); - font.setUnderline(false); - font.setStrikeOut(false); - font.setOverline(false); - - const QTextItemInt &si = static_cast<const QTextItemInt &>(ti); - qreal justificationWidth = 0; - if (si.justified) - justificationWidth = si.width.toReal(); - debug << "Cmd_DrawTextItem:" << pos << " " << text; break; } case QPaintBufferPrivate::Cmd_SystemStateChanged: { @@ -1778,12 +1768,12 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd) rawFontD->fontEngine = fontD->engineForScript(QUnicodeTables::Common); rawFontD->fontEngine->ref.ref(); - QGlyphs glyphs; - glyphs.setFont(rawFont); + QGlyphRun glyphs; + glyphs.setRawFont(rawFont); glyphs.setGlyphIndexes(glyphIndexes); glyphs.setPositions(positions); - painter->drawGlyphs(QPointF(), glyphs); + painter->drawGlyphRun(QPointF(), glyphs); break; } #endif diff --git a/src/gui/painting/qpaintengine_mac.cpp b/src/gui/painting/qpaintengine_mac.cpp index 8aab7c7..cc75b86 100644 --- a/src/gui/painting/qpaintengine_mac.cpp +++ b/src/gui/painting/qpaintengine_mac.cpp @@ -1544,8 +1544,9 @@ void QCoreGraphicsPaintEnginePrivate::setFillBrush(const QPointF &offset) QPointF center(radialGrad->center()); QPointF focal(radialGrad->focalPoint()); qreal radius = radialGrad->radius(); + qreal focalRadius = radialGrad->focalRadius(); shading = CGShadingCreateRadial(colorspace, CGPointMake(focal.x(), focal.y()), - 0.0, CGPointMake(center.x(), center.y()), radius, fill_func, false, true); + focalRadius, CGPointMake(center.x(), center.y()), radius, fill_func, false, true); } CGFunctionRelease(fill_func); diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 6902543..2119e30 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -5033,6 +5033,84 @@ void QGradientCache::generateGradientColorTable(const QGradient& gradient, uint bool colorInterpolation = (gradient.interpolationMode() == QGradient::ColorInterpolation); + if (stopCount == 2) { + uint first_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity); + uint second_color = ARGB_COMBINE_ALPHA(stops[1].second.rgba(), opacity); + + qreal first_stop = stops[0].first; + qreal second_stop = stops[1].first; + + if (second_stop < first_stop) { + qSwap(first_color, second_color); + qSwap(first_stop, second_stop); + } + + if (colorInterpolation) { + first_color = PREMUL(first_color); + second_color = PREMUL(second_color); + } + + int first_index = qRound(first_stop * (GRADIENT_STOPTABLE_SIZE-1)); + int second_index = qRound(second_stop * (GRADIENT_STOPTABLE_SIZE-1)); + + uint red_first = qRed(first_color) << 16; + uint green_first = qGreen(first_color) << 16; + uint blue_first = qBlue(first_color) << 16; + uint alpha_first = qAlpha(first_color) << 16; + + uint red_second = qRed(second_color) << 16; + uint green_second = qGreen(second_color) << 16; + uint blue_second = qBlue(second_color) << 16; + uint alpha_second = qAlpha(second_color) << 16; + + int i = 0; + for (; i <= qMin(GRADIENT_STOPTABLE_SIZE, first_index); ++i) { + if (colorInterpolation) + colorTable[i] = first_color; + else + colorTable[i] = PREMUL(first_color); + } + + if (i < second_index) { + qreal reciprocal = qreal(1) / (second_index - first_index); + + int red_delta = qRound(int(red_second - red_first) * reciprocal); + int green_delta = qRound(int(green_second - green_first) * reciprocal); + int blue_delta = qRound(int(blue_second - blue_first) * reciprocal); + int alpha_delta = qRound(int(alpha_second - alpha_first) * reciprocal); + + // rounding + red_first += 1 << 15; + green_first += 1 << 15; + blue_first += 1 << 15; + alpha_first += 1 << 15; + + for (; i < qMin(GRADIENT_STOPTABLE_SIZE, second_index); ++i) { + red_first += red_delta; + green_first += green_delta; + blue_first += blue_delta; + alpha_first += alpha_delta; + + const uint color = ((alpha_first << 8) & 0xff000000) | (red_first & 0xff0000) + | ((green_first >> 8) & 0xff00) | (blue_first >> 16); + + if (colorInterpolation) + colorTable[i] = color; + else + colorTable[i] = PREMUL(color); + } + } + + for (; i < GRADIENT_STOPTABLE_SIZE; ++i) { + if (colorInterpolation) + colorTable[i] = second_color; + else + colorTable[i] = PREMUL(second_color); + } + + return; + } + uint current_color = ARGB_COMBINE_ALPHA(stops[0].second.rgba(), opacity); if (stopCount == 1) { current_color = PREMUL(current_color); @@ -5204,10 +5282,11 @@ void QSpanData::setup(const QBrush &brush, int alpha, QPainter::CompositionMode QPointF center = g->center(); radialData.center.x = center.x(); radialData.center.y = center.y(); + radialData.center.radius = g->centerRadius(); QPointF focal = g->focalPoint(); radialData.focal.x = focal.x(); radialData.focal.y = focal.y(); - radialData.radius = g->radius(); + radialData.focal.radius = g->focalRadius(); } break; diff --git a/src/gui/painting/qpaintengine_x11.cpp b/src/gui/painting/qpaintengine_x11.cpp index 94828fb..6ba9a99 100644 --- a/src/gui/painting/qpaintengine_x11.cpp +++ b/src/gui/painting/qpaintengine_x11.cpp @@ -1611,8 +1611,6 @@ void QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int p && (fill.style() != Qt::NoBrush) && ((has_fill_texture && fill.texture().hasAlpha()) || antialias || !solid_fill || has_alpha_pen != has_alpha_brush)) { - QRect br = tessellator->tessellate((QPointF *)clippedPoints, clippedCount, - mode == QPaintEngine::WindingMode); if (tessellator->size > 0) { XRenderPictureAttributes attrs; attrs.poly_edge = antialias ? PolyEdgeSmooth : PolyEdgeSharp; @@ -1771,7 +1769,6 @@ void QX11PaintEngine::drawPath(const QPainterPath &path) Q_D(QX11PaintEngine); if (path.isEmpty()) return; - QTransform old_matrix = d->matrix; if (d->has_brush) d->fillPath(path, QX11PaintEnginePrivate::BrushGC, true); diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp index 509fb77..7f601eb 100644 --- a/src/gui/painting/qpaintengineex.cpp +++ b/src/gui/painting/qpaintengineex.cpp @@ -1012,4 +1012,50 @@ void QPaintEngineEx::updateState(const QPaintEngineState &) // do nothing... } +Q_GUI_EXPORT QPainterPath qt_painterPathFromVectorPath(const QVectorPath &path) +{ + const qreal *points = path.points(); + const QPainterPath::ElementType *types = path.elements(); + + QPainterPath p; + if (types) { + int id = 0; + for (int i=0; i<path.elementCount(); ++i) { + switch(types[i]) { + case QPainterPath::MoveToElement: + p.moveTo(QPointF(points[id], points[id+1])); + id+=2; + break; + case QPainterPath::LineToElement: + p.lineTo(QPointF(points[id], points[id+1])); + id+=2; + break; + case QPainterPath::CurveToElement: { + QPointF p1(points[id], points[id+1]); + QPointF p2(points[id+2], points[id+3]); + QPointF p3(points[id+4], points[id+5]); + p.cubicTo(p1, p2, p3); + id+=6; + break; + } + case QPainterPath::CurveToDataElement: + ; + break; + } + } + } else { + p.moveTo(QPointF(points[0], points[1])); + int id = 2; + for (int i=1; i<path.elementCount(); ++i) { + p.lineTo(QPointF(points[id], points[id+1])); + id+=2; + } + } + if (path.hints() & QVectorPath::WindingFill) + p.setFillRule(Qt::WindingFill); + + return p; +} + + QT_END_NAMESPACE diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 9fafba5..a965c15 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -62,7 +62,7 @@ #include "qthread.h" #include "qvarlengtharray.h" #include "qstatictext.h" -#include "qglyphs.h" +#include "qglyphrun.h" #include <private/qfontengine_p.h> #include <private/qpaintengine_p.h> @@ -73,7 +73,7 @@ #include <private/qpaintengine_raster_p.h> #include <private/qmath_p.h> #include <private/qstatictext_p.h> -#include <private/qglyphs_p.h> +#include <private/qglyphrun_p.h> #include <private/qstylehelper_p.h> #include <private/qrawfont_p.h> @@ -156,7 +156,8 @@ static bool qt_paintengine_supports_transformations(QPaintEngine::Type type) { return type == QPaintEngine::OpenGL2 || type == QPaintEngine::OpenVG - || type == QPaintEngine::OpenGL; + || type == QPaintEngine::OpenGL + || type == QPaintEngine::CoreGraphics; } #ifndef QT_NO_DEBUG @@ -503,8 +504,12 @@ void QPainterPrivate::draw_helper(const QPainterPath &originalPath, DrawOperatio q->save(); state->matrix = QTransform(); - state->dirtyFlags |= QPaintEngine::DirtyTransform; - updateState(state); + if (extended) { + extended->transformChanged(); + } else { + state->dirtyFlags |= QPaintEngine::DirtyTransform; + updateState(state); + } engine->drawImage(absPathRect, image, QRectF(0, 0, absPathRect.width(), absPathRect.height()), @@ -687,11 +692,14 @@ void QPainterPrivate::updateInvMatrix() invMatrix = state->matrix.inverted(); } +Q_GUI_EXPORT bool qt_isExtendedRadialGradient(const QBrush &brush); + void QPainterPrivate::updateEmulationSpecifier(QPainterState *s) { bool alpha = false; bool linearGradient = false; bool radialGradient = false; + bool extendedRadialGradient = false; bool conicalGradient = false; bool patternBrush = false; bool xform = false; @@ -723,6 +731,7 @@ void QPainterPrivate::updateEmulationSpecifier(QPainterState *s) (brushStyle == Qt::LinearGradientPattern)); radialGradient = ((penBrushStyle == Qt::RadialGradientPattern) || (brushStyle == Qt::RadialGradientPattern)); + extendedRadialGradient = radialGradient && (qt_isExtendedRadialGradient(penBrush) || qt_isExtendedRadialGradient(s->brush)); conicalGradient = ((penBrushStyle == Qt::ConicalGradientPattern) || (brushStyle == Qt::ConicalGradientPattern)); patternBrush = (((penBrushStyle > Qt::SolidPattern @@ -806,7 +815,7 @@ void QPainterPrivate::updateEmulationSpecifier(QPainterState *s) s->emulationSpecifier &= ~QPaintEngine::LinearGradientFill; // Radial gradient emulation - if (radialGradient && !engine->hasFeature(QPaintEngine::RadialGradientFill)) + if (extendedRadialGradient || (radialGradient && !engine->hasFeature(QPaintEngine::RadialGradientFill))) s->emulationSpecifier |= QPaintEngine::RadialGradientFill; else s->emulationSpecifier &= ~QPaintEngine::RadialGradientFill; @@ -5789,19 +5798,19 @@ void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QR \since 4.8 - \sa QGlyphs::setFont(), QGlyphs::setPositions(), QGlyphs::setGlyphIndexes() + \sa QGlyphRun::setRawFont(), QGlyphRun::setPositions(), QGlyphRun::setGlyphIndexes() */ #if !defined(QT_NO_RAWFONT) -void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs) +void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun) { Q_D(QPainter); - QRawFont font = glyphs.font(); + QRawFont font = glyphRun.rawFont(); if (!font.isValid()) return; - QVector<quint32> glyphIndexes = glyphs.glyphIndexes(); - QVector<QPointF> glyphPositions = glyphs.positions(); + QVector<quint32> glyphIndexes = glyphRun.glyphIndexes(); + QVector<QPointF> glyphPositions = glyphRun.positions(); int count = qMin(glyphIndexes.size(), glyphPositions.size()); QVarLengthArray<QFixedPoint, 128> fixedPointPositions(count); @@ -5809,7 +5818,14 @@ void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs) bool paintEngineSupportsTransformations = d->extended != 0 ? qt_paintengine_supports_transformations(d->extended->type()) - : false; + : qt_paintengine_supports_transformations(d->engine->type()); + + // If the matrix is not affine, the paint engine will fall back to + // drawing the glyphs as paths, which in turn means we should not + // preprocess the glyph positions + if (!d->state->matrix.isAffine()) + paintEngineSupportsTransformations = true; + for (int i=0; i<count; ++i) { QPointF processedPosition = position + glyphPositions.at(i); if (!paintEngineSupportsTransformations) @@ -5817,8 +5833,8 @@ void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs) fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition); } - d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count, font, glyphs.overline(), - glyphs.underline(), glyphs.strikeOut()); + d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count, font, glyphRun.overline(), + glyphRun.underline(), glyphRun.strikeOut()); } void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, int glyphCount, @@ -5853,7 +5869,7 @@ void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, in QFixed width = rightMost - leftMost; - if (extended != 0) { + if (extended != 0 && state->matrix.isAffine()) { QStaticTextItem staticTextItem; staticTextItem.color = state->pen.color(); staticTextItem.font = state->font; diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index 4b2c447..601c386 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -79,7 +79,7 @@ class QTextItem; class QMatrix; class QTransform; class QStaticText; -class QGlyphs; +class QGlyphRun; class QPainterPrivateDeleter; @@ -400,7 +400,7 @@ public: Qt::LayoutDirection layoutDirection() const; #if !defined(QT_NO_RAWFONT) - void drawGlyphs(const QPointF &position, const QGlyphs &glyphs); + void drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun); #endif void drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText); @@ -553,6 +553,7 @@ private: friend class QPaintEngine; friend class QPaintEngineExPrivate; friend class QOpenGLPaintEngine; + friend class QVGPaintEngine; friend class QX11PaintEngine; friend class QX11PaintEnginePrivate; friend class QWin32PaintEngine; diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index 27aed32..9fbac13 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -1126,6 +1126,7 @@ void QPainterPath::addText(const QPointF &point, const QFont &f, const QString & QTextEngine *eng = layout.engine(); layout.beginLayout(); QTextLine line = layout.createLine(); + Q_UNUSED(line); layout.endLayout(); const QScriptLine &sl = eng->lines[0]; if (!sl.length || !eng->layoutData) diff --git a/src/gui/painting/qprintengine_pdf.cpp b/src/gui/painting/qprintengine_pdf.cpp index b7f5160..353869f 100644 --- a/src/gui/painting/qprintengine_pdf.cpp +++ b/src/gui/painting/qprintengine_pdf.cpp @@ -534,7 +534,10 @@ int QPdfEnginePrivate::addImage(const QImage &img, bool *bitmap, qint64 serial_n QImage image = img; QImage::Format format = image.format(); - if (image.depth() == 1 && *bitmap && img.colorTable().size() == 0) { + if (image.depth() == 1 && *bitmap && img.colorTable().size() == 2 + && img.colorTable().at(0) == QColor(Qt::black).rgba() + && img.colorTable().at(1) == QColor(Qt::white).rgba()) + { if (format == QImage::Format_MonoLSB) image = image.convertToFormat(QImage::Format_Mono); format = QImage::Format_Mono; diff --git a/src/gui/painting/qstroker.cpp b/src/gui/painting/qstroker.cpp index fca46b4..dd723ed 100644 --- a/src/gui/painting/qstroker.cpp +++ b/src/gui/painting/qstroker.cpp @@ -552,6 +552,7 @@ void QStroker::joinPoints(qfixed focal_x, qfixed focal_y, const QLineF &nextLine // // line to the beginning of the arc segment, (should not be needed). // emitLineTo(qt_real_to_fixed(curve_start.x()), qt_real_to_fixed(curve_start.y())); + Q_UNUSED(curve_start); for (int i=0; i<point_count; i+=3) { emitCubicTo(qt_real_to_fixed(curves[i].x()), diff --git a/src/gui/painting/qtextureglyphcache.cpp b/src/gui/painting/qtextureglyphcache.cpp index 53f025f..e9e56a2 100644 --- a/src/gui/painting/qtextureglyphcache.cpp +++ b/src/gui/painting/qtextureglyphcache.cpp @@ -296,7 +296,7 @@ void QTextureGlyphCache::fillInPendingGlyphs() QImage QTextureGlyphCache::textureMapForGlyph(glyph_t g, QFixed subPixelPosition) const { #if defined(Q_WS_X11) - if (m_transform.type() > QTransform::TxTranslate) { + if (m_transform.type() > QTransform::TxTranslate && m_current_fontengine->type() == QFontEngine::Freetype) { QFontEngineFT::GlyphFormat format = QFontEngineFT::Format_None; QImage::Format imageFormat = QImage::Format_Invalid; switch (m_type) { diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp index 3876c3d..2fda6b9 100644 --- a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp +++ b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp @@ -152,7 +152,8 @@ void QUnifiedToolbarSurface::beginPaint(const QRegion &rgn) void QUnifiedToolbarSurface::updateToolbarOffset(QWidget *widget) { QMainWindowLayout *mlayout = qobject_cast<QMainWindowLayout*> (widget->window()->layout()); - mlayout->updateUnifiedToolbarOffset(); + if (mlayout) + mlayout->updateUnifiedToolbarOffset(); } void QUnifiedToolbarSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h index 0a7ebf1..ce07f5c 100644 --- a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h +++ b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h @@ -65,6 +65,39 @@ QT_BEGIN_NAMESPACE class QNativeImage; +// +// This is the implementation of the unified toolbar on Mac OS X +// with the graphics system raster. +// +// General idea: +// ------------- +// We redirect the painting of widgets inside the unified toolbar +// to a special window surface, the QUnifiedToolbarSurface. +// We need a separate window surface because the unified toolbar +// is out of the content view. +// The input system is the same as for the unified toolbar with the +// native (CoreGraphics) engine. +// +// Execution flow: +// --------------- +// The unified toolbar is triggered by QMainWindow::setUnifiedTitleAndToolBarOnMac(). +// It calls QMainWindowLayout::insertIntoMacToolbar() which will +// set all the appropriate variables (offsets, redirection, ...). +// When Qt tells a widget to repaint, QWidgetPrivate::drawWidget() +// checks if the widget is inside the unified toolbar and exits without +// painting is that is the case. +// We trigger the rendering of the unified toolbar in QWidget::repaint() +// and QWidget::update(). +// We keep track of flush requests via "flushRequested" variable. That +// allow flush() to be a no-op if no repaint occurred for a widget. +// We rely on the needsDisplay: and drawRect: mecanism for drawing our +// content into the graphics context. +// +// Notes: +// ------ +// The painting of items inside the unified toolbar is expensive. +// Too many repaints will drastically slow down the whole application. +// class QUnifiedToolbarSurfacePrivate { diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp index cc5fe10..786aab3 100644 --- a/src/gui/styles/qcleanlooksstyle.cpp +++ b/src/gui/styles/qcleanlooksstyle.cpp @@ -841,7 +841,6 @@ void QCleanlooksStyle::drawPrimitive(PrimitiveElement elem, case PE_PanelButtonTool: painter->save(); if ((option->state & State_Enabled || option->state & State_On) || !(option->state & State_AutoRaise)) { - QRect rect = option->rect; QPen oldPen = painter->pen(); if (widget && widget->inherits("QDockWidgetTitleButton")) { @@ -1241,7 +1240,6 @@ void QCleanlooksStyle::drawPrimitive(PrimitiveElement elem, if (const QStyleOptionTabWidgetFrame *twf = qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) { QColor borderColor = darkOutline.lighter(110); QColor alphaCornerColor = mergedColors(borderColor, option->palette.background().color()); - QColor innerShadow = mergedColors(borderColor, option->palette.base().color()); int borderThickness = proxy()->pixelMetric(PM_TabBarBaseOverlap, twf, widget); bool reverse = (twf->direction == Qt::RightToLeft); @@ -1879,7 +1877,6 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o } else { alphaCornerColor = mergedColors(option->palette.background().color(), borderColor); } - QColor alphaTextColor = mergedColors(option->palette.background().color(), option->palette.text().color()); if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) { painter->fillRect(menuItem->rect, menuBackground); int w = 0; @@ -2220,7 +2217,6 @@ void QCleanlooksStyle::drawControl(ControlElement element, const QStyleOption *o && tabBarAlignment == Qt::AlignLeft); QColor light = tab->palette.light().color(); - QColor midlight = tab->palette.midlight().color(); QColor background = tab->palette.background().color(); int borderThinkness = proxy()->pixelMetric(PM_TabBarBaseOverlap, tab, widget); @@ -2444,14 +2440,6 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp QColor gradientStartColor = option->palette.button().color().lighter(108); QColor gradientStopColor = mergedColors(option->palette.button().color().darker(108), dark.lighter(150), 70); - QColor highlightedGradientStartColor = option->palette.button().color(); - QColor highlightedGradientStopColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 85); - - QColor highlightedDarkInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 35); - QColor highlightedLightInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 58); - - QColor buttonShadowAlpha = option->palette.background().color().darker(105); - QPalette palette = option->palette; switch (control) { @@ -3437,7 +3425,6 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) { QRect groove = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget); QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget); - QRect ticks = proxy()->subControlRect(CC_Slider, option, SC_SliderTickmarks, widget); bool horizontal = slider->orientation == Qt::Horizontal; bool ticksAbove = slider->tickPosition & QSlider::TicksAbove; @@ -3539,8 +3526,6 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp QRect pixmapRect(0, 0, handle.width(), handle.height()); QPainter handlePainter(&cache); - QColor highlightedGradientStartColor = option->palette.button().color(); - QColor highlightedGradientStopColor = option->palette.light().color(); QColor gradientStartColor = mergedColors(option->palette.button().color().lighter(155), dark.lighter(155), 50); QColor gradientStopColor = gradientStartColor.darker(108); @@ -3557,7 +3542,6 @@ void QCleanlooksStyle::drawComplexControl(ComplexControl control, const QStyleOp } // gradient fill - QRect innerBorder = gradRect; QRect r = pixmapRect.adjusted(1, 1, -1, -1); qt_cleanlooks_draw_gradient(&handlePainter, gradRect, diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp index 3d04c9a..95ebdb4 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -916,6 +916,7 @@ static QSizeF viewItemTextLayout(QTextLayout &textLayout, int lineWidth) return QSizeF(widthUsed, height); } + void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewItemV4 *option, const QRect &rect) const { Q_Q(const QCommonStyle); @@ -933,7 +934,7 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt textLayout.setFont(option->font); textLayout.setText(option->text); - QSizeF textLayoutSize = viewItemTextLayout(textLayout, textRect.width()); + viewItemTextLayout(textLayout, textRect.width()); QString elidedText; qreal height = 0; diff --git a/src/gui/styles/qgtkpainter.cpp b/src/gui/styles/qgtkpainter.cpp index 68ade04..6258fe4 100644 --- a/src/gui/styles/qgtkpainter.cpp +++ b/src/gui/styles/qgtkpainter.cpp @@ -586,7 +586,6 @@ void QGtkPainter::paintShadow(GtkWidget *gtkWidget, const gchar* part, if (!rect.isValid()) return; - QRect r = rect; QPixmap cache; QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { @@ -605,7 +604,6 @@ void QGtkPainter::paintFlatBox(GtkWidget *gtkWidget, const gchar* part, { if (!rect.isValid()) return; - QRect r = rect; QPixmap cache; QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size()) % pmKey; if (!m_usePixmapCache || !QPixmapCache::find(pixmapName, cache)) { @@ -632,7 +630,6 @@ void QGtkPainter::paintExtention(GtkWidget *gtkWidget, if (!rect.isValid()) return; - QRect r = rect; QPixmap cache; QString pixmapName = uniqueName(QLS(part), state, shadow, rect.size(), gtkWidget) % HexString<uchar>(gap_pos); @@ -660,7 +657,6 @@ void QGtkPainter::paintOption(GtkWidget *gtkWidget, const QRect &radiorect, if (!rect.isValid()) return; - QRect r = rect; QPixmap cache; QString pixmapName = uniqueName(detail, state, shadow, rect.size()); GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()}; @@ -692,7 +688,6 @@ void QGtkPainter::paintCheckbox(GtkWidget *gtkWidget, const QRect &checkrect, if (!rect.isValid()) return; - QRect r = rect; QPixmap cache; QString pixmapName = uniqueName(detail, state, shadow, rect.size()); GdkRectangle gtkCliprect = {0, 0, rect.width(), rect.height()}; diff --git a/src/gui/styles/qgtkstyle.cpp b/src/gui/styles/qgtkstyle.cpp index 277e302..d6dd527 100644 --- a/src/gui/styles/qgtkstyle.cpp +++ b/src/gui/styles/qgtkstyle.cpp @@ -782,7 +782,6 @@ void QGtkStyle::drawPrimitive(PrimitiveElement element, GtkStateType state = gtkPainter.gtkState(option); style = gtkTreeHeader->style; GtkArrowType type = GTK_ARROW_UP; - QRect r = header->rect; QImage arrow; // This sorting indicator inversion is intentional, and follows the GNOME HIG. // See http://library.gnome.org/devel/hig-book/stable/controls-lists.html.en#controls-lists-sortable @@ -1857,7 +1856,6 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom editArea.setRight(upRect.left()); } if (spinBox->frame) { - GtkShadowType shadow = GTK_SHADOW_OUT; GtkStateType state = gtkPainter.gtkState(option); if (!(option->state & State_Enabled)) @@ -1867,7 +1865,6 @@ void QGtkStyle::drawComplexControl(ComplexControl control, const QStyleOptionCom else if (state == GTK_STATE_PRELIGHT) state = GTK_STATE_NORMAL; - shadow = GTK_SHADOW_IN; style = gtkPainter.getStyle(gtkSpinButton); diff --git a/src/gui/styles/qplastiquestyle.cpp b/src/gui/styles/qplastiquestyle.cpp index 02ce60e..1d33212 100644 --- a/src/gui/styles/qplastiquestyle.cpp +++ b/src/gui/styles/qplastiquestyle.cpp @@ -2007,14 +2007,10 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op } else { alphaCornerColor = mergedColors(option->palette.background().color(), borderColor); } - QColor alphaTextColor = mergedColors(option->palette.background().color(), option->palette.text().color()); QColor gradientStartColor = option->palette.button().color().lighter(104); QColor gradientStopColor = option->palette.button().color().darker(105); - QColor shadowGradientStartColor = option->palette.button().color().darker(115); - QColor shadowGradientStopColor = option->palette.button().color().darker(120); - QColor highlightedGradientStartColor = option->palette.button().color().lighter(101); QColor highlightedGradientStopColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 85); @@ -2025,8 +2021,6 @@ void QPlastiqueStyle::drawControl(ControlElement element, const QStyleOption *op QColor highlightedLightInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 58); QColor alphaInnerColor = mergedColors(highlightedDarkInnerBorderColor, option->palette.base().color()); - QColor lightShadow = lightShadowGradientStartColor; - QColor shadow = shadowGradientStartColor; switch (element) { #ifndef QT_NO_TABBAR @@ -3786,10 +3780,6 @@ void QPlastiqueStyle::drawComplexControl(ComplexControl control, const QStyleOpt } QColor gradientStartColor = option->palette.button().color().lighter(104); QColor gradientStopColor = option->palette.button().color().darker(105); - QColor highlightedGradientStartColor = option->palette.button().color().lighter(101); - QColor highlightedGradientStopColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 85); - QColor highlightedDarkInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 35); - QColor highlightedLightInnerBorderColor = mergedColors(option->palette.button().color(), option->palette.highlight().color(), 58); switch (control) { #ifndef QT_NO_SLIDER @@ -3797,7 +3787,6 @@ void QPlastiqueStyle::drawComplexControl(ComplexControl control, const QStyleOpt if (const QStyleOptionSlider *slider = qstyleoption_cast<const QStyleOptionSlider *>(option)) { QRect grooveRegion = proxy()->subControlRect(CC_Slider, option, SC_SliderGroove, widget); QRect handle = proxy()->subControlRect(CC_Slider, option, SC_SliderHandle, widget); - QRect ticks = proxy()->subControlRect(CC_Slider, option, SC_SliderTickmarks, widget); bool horizontal = slider->orientation == Qt::Horizontal; bool ticksAbove = slider->tickPosition & QSlider::TicksAbove; bool ticksBelow = slider->tickPosition & QSlider::TicksBelow; diff --git a/src/gui/styles/qwindowsstyle.cpp b/src/gui/styles/qwindowsstyle.cpp index 1dcfd00..754486e 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -2028,10 +2028,8 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai && tabBarAlignment == Qt::AlignLeft); QColor light = tab->palette.light().color(); - QColor midlight = tab->palette.midlight().color(); QColor dark = tab->palette.dark().color(); QColor shadow = tab->palette.shadow().color(); - QColor background = tab->palette.background().color(); int borderThinkness = proxy()->pixelMetric(PM_TabBarBaseOverlap, tab, widget); if (selected) borderThinkness /= 2; diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h index 8dbc746..0c7b6f8 100644 --- a/src/gui/text/qfont.h +++ b/src/gui/text/qfont.h @@ -239,7 +239,7 @@ public: bool isCopyOf(const QFont &) const; #ifdef Q_COMPILER_RVALUE_REFS inline QFont &operator=(QFont &&other) - { qSwap(d, other.d); return *this; } + { qSwap(d, other.d); qSwap(resolve_mask, other.resolve_mask); return *this; } #endif #ifdef Q_WS_WIN diff --git a/src/gui/text/qfont_mac.cpp b/src/gui/text/qfont_mac.cpp index daf68c0..044fd84 100644 --- a/src/gui/text/qfont_mac.cpp +++ b/src/gui/text/qfont_mac.cpp @@ -43,6 +43,7 @@ #include "qfont_p.h" #include "qfontengine_p.h" #include "qfontengine_mac_p.h" +#include "qfontengine_coretext_p.h" #include "qfontinfo.h" #include "qfontmetrics.h" #include "qpaintdevice.h" @@ -119,10 +120,10 @@ quint32 QFont::macFontID() const // ### need 64-bit version // Returns an ATSUFonFamilyRef Qt::HANDLE QFont::handle() const { -#if 0 +#ifdef QT_MAC_USE_COCOA QFontEngine *fe = d->engineForScript(QUnicodeTables::Common); - if (fe && fe->type() == QFontEngine::Mac) - return (Qt::HANDLE)static_cast<QFontEngineMacMulti*>(fe)->fontFamilyRef(); + if (fe && fe->type() == QFontEngine::Multi) + return (Qt::HANDLE)static_cast<QCoreTextFontEngineMulti*>(fe)->macFontID(); #endif return 0; } diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp index 1db4a7d..3ab1ac8 100644 --- a/src/gui/text/qfontdatabase_s60.cpp +++ b/src/gui/text/qfontdatabase_s60.cpp @@ -152,7 +152,6 @@ public: COpenFontRasterizer *m_rasterizer; mutable QList<const QSymbianTypeFaceExtras *> m_extras; - mutable QHash<QString, const QSymbianTypeFaceExtras *> m_extrasHash; mutable QSet<QString> m_applicationFontFamilies; }; @@ -255,8 +254,9 @@ void QSymbianFontDatabaseExtrasImplementation::clear() static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras); if (!dbExtras) return; // initializeDb() has never been called + QSymbianTypeFaceExtrasHash &extrasHash = S60->fontData(); if (QSymbianTypeFaceExtras::symbianFontTableApiAvailable()) { - qDeleteAll(dbExtras->m_extrasHash); + qDeleteAll(extrasHash); } else { typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator; for (iterator p = dbExtras->m_extras.begin(); p != dbExtras->m_extras.end(); ++p) { @@ -265,11 +265,16 @@ void QSymbianFontDatabaseExtrasImplementation::clear() } dbExtras->m_extras.clear(); } - dbExtras->m_extrasHash.clear(); + extrasHash.clear(); } void qt_cleanup_symbianFontDatabase() { + static bool cleanupDone = false; + if (cleanupDone) + return; + cleanupDone = true; + QFontDatabasePrivate *db = privateDb(); if (!db) return; @@ -320,9 +325,12 @@ COpenFont* OpenFontFromBitmapFont(const CBitmapFont* aBitmapFont) const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &aTypeface, bool bold, bool italic) const { + QSymbianTypeFaceExtrasHash &extrasHash = S60->fontData(); + if (extrasHash.isEmpty() && QThread::currentThread() != QApplication::instance()->thread()) + S60->addThreadLocalReleaseFunc(clear); const QString typeface = qt_symbian_fontNameWithAppFontMarker(aTypeface); const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic)); - if (!m_extrasHash.contains(searchKey)) { + if (!extrasHash.contains(searchKey)) { TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1); if (bold) searchSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold); @@ -336,7 +344,7 @@ const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(c QScopedPointer<CFont, CFontFromScreenDeviceReleaser> sFont(font); QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font); sFont.take(); - m_extrasHash.insert(searchKey, extras); + extrasHash.insert(searchKey, extras); } else { const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec); Q_ASSERT(err == KErrNone && font); @@ -350,20 +358,20 @@ const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(c const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib(); const QString foundKey = QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length()); - if (!m_extrasHash.contains(foundKey)) { + if (!extrasHash.contains(foundKey)) { QScopedPointer<CFont, CFontFromFontStoreReleaser> sFont(font); QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont); sFont.take(); m_extras.append(extras); - m_extrasHash.insert(searchKey, extras); - m_extrasHash.insert(foundKey, extras); + extrasHash.insert(searchKey, extras); + extrasHash.insert(foundKey, extras); } else { m_store->ReleaseFont(font); - m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey)); + extrasHash.insert(searchKey, extrasHash.value(foundKey)); } } } - return m_extrasHash.value(searchKey); + return extrasHash.value(searchKey); } void QSymbianFontDatabaseExtrasImplementation::removeAppFontData( @@ -956,7 +964,7 @@ bool QFontDatabase::removeAllApplicationFonts() bool QFontDatabase::supportsThreadedFontRendering() { - return false; + return QSymbianTypeFaceExtras::symbianFontTableApiAvailable(); } static diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index 20b3730..cbf51e6 100644 --- a/src/gui/text/qfontengine_coretext.mm +++ b/src/gui/text/qfontengine_coretext.mm @@ -162,8 +162,10 @@ uint QCoreTextFontEngineMulti::fontIndexForFont(CTFontRef font) const return engines.count() - 1; } -bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, - unsigned short *logClusters, const HB_CharAttributes *) const +bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, + int *nglyphs, QTextEngine::ShaperFlags flags, + unsigned short *logClusters, const HB_CharAttributes *, + QScriptItem *si) const { QCFType<CFStringRef> cfstring = CFStringCreateWithCharactersNoCopy(0, reinterpret_cast<const UniChar *>(str), @@ -180,6 +182,8 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay &kCFCopyStringDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); typeSetter = CTTypesetterCreateWithAttributedStringAndOptions(attributedString, options); } else +#else + Q_UNUSED(flags); #endif typeSetter = CTTypesetterCreateWithAttributedString(attributedString); @@ -219,6 +223,25 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay Q_ASSERT((CTRunGetStatus(run) & kCTRunStatusRightToLeft) == rtl); CFRange stringRange = CTRunGetStringRange(run); + int prepend = 0; +#if MAC_OS_X_VERSION_MAX_ALLOWED == MAC_OS_X_VERSION_10_5 + UniChar beginGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location); + QChar dir = QChar::direction(beginGlyph); + bool beginWithOverride = dir == QChar::DirLRO || dir == QChar::DirRLO || dir == QChar::DirLRE || dir == QChar::DirRLE; + if (beginWithOverride) { + logClusters[stringRange.location] = 0; + outGlyphs[0] = 0xFFFF; + outAdvances_x[0] = 0; + outAdvances_y[0] = 0; + outAttributes[0].clusterStart = true; + outAttributes[0].dontPrint = true; + outGlyphs++; + outAdvances_x++; + outAdvances_y++; + outAttributes++; + prepend = 1; + } +#endif UniChar endGlyph = CFStringGetCharacterAtIndex(cfstring, stringRange.location + stringRange.length - 1); bool endWithPDF = QChar::direction(endGlyph) == QChar::DirPDF; if (endWithPDF) @@ -233,7 +256,12 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay if (!runAttribs) runAttribs = attributeDict; CTFontRef runFont = static_cast<CTFontRef>(CFDictionaryGetValue(runAttribs, NSFontAttributeName)); - const uint fontIndex = (fontIndexForFont(runFont) << 24); + uint fontIndex = fontIndexForFont(runFont); + const QFontEngine *engine = engineAt(fontIndex); + fontIndex <<= 24; + si->ascent = qMax(engine->ascent(), si->ascent); + si->descent = qMax(engine->descent(), si->descent); + si->leading = qMax(engine->leading(), si->leading); //NSLog(@"Run Font Name = %@", CTFontCopyFamilyName(runFont)); if (endWithPDF) glyphCount--; @@ -271,9 +299,9 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay CFIndex k = 0; CFIndex i = 0; - for (i = stringRange.location; + for (i = stringRange.location + prepend; (i < stringRange.location + stringRange.length) && (k < glyphCount); ++i) { - if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location) { + if (tmpIndices[k * rtlSign + rtlOffset] == i || i == stringRange.location + prepend) { logClusters[i] = k + firstGlyphIndex; outAttributes[k].clusterStart = true; ++k; @@ -308,7 +336,7 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay : QFixed::fromReal(lastGlyphAdvance.width); if (endWithPDF) { - logClusters[stringRange.location + stringRange.length - 1] = glyphCount; + logClusters[stringRange.location + stringRange.length - 1] = glyphCount + prepend; outGlyphs[glyphCount] = 0xFFFF; outAdvances_x[glyphCount] = 0; outAdvances_y[glyphCount] = 0; @@ -837,6 +865,15 @@ QFixed QCoreTextFontEngine::emSquareSize() const return QFixed::QFixed(int(CTFontGetUnitsPerEm(ctfont))); } +QFontEngine *QCoreTextFontEngine::cloneWithSize(qreal pixelSize) const +{ + QFontDef newFontDef = fontDef; + newFontDef.pixelSize = pixelSize; + newFontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi(); + + return new QCoreTextFontEngine(cgFont, newFontDef); +} + QT_END_NAMESPACE #endif// !defined(Q_WS_MAC) || (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) diff --git a/src/gui/text/qfontengine_coretext_p.h b/src/gui/text/qfontengine_coretext_p.h index 1503c3f..3775bc6 100644 --- a/src/gui/text/qfontengine_coretext_p.h +++ b/src/gui/text/qfontengine_coretext_p.h @@ -91,6 +91,8 @@ public: virtual qreal minLeftBearing() const; virtual QFixed emSquareSize() const; + virtual QFontEngine *cloneWithSize(qreal pixelSize) const; + private: friend class QRawFontPrivate; @@ -118,9 +120,12 @@ public: QTextEngine::ShaperFlags flags) const; bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, - unsigned short *logClusters, const HB_CharAttributes *charAttributes) const; + unsigned short *logClusters, const HB_CharAttributes *charAttributes, + QScriptItem *si) const; virtual const char *name() const { return "CoreText"; } + inline CTFontRef macFontID() const { return ctfont; } + protected: virtual void loadEngine(int at); diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 8f2da9b..9d4a21a 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -803,106 +803,6 @@ int QFontEngineFT::loadFlags(QGlyphSet *set, GlyphFormat format, int flags, return load_flags; } -QFontEngineFT::Glyph *QFontEngineFT::loadGlyphMetrics(QGlyphSet *set, uint glyph, GlyphFormat format) const -{ - Glyph *g = set->getGlyph(glyph); - if (g && g->format == format) - return g; - - bool hsubpixel = false; - int vfactor = 1; - int load_flags = loadFlags(set, format, 0, hsubpixel, vfactor); - - // apply our matrix to this, but note that the metrics will not be affected by this. - FT_Face face = lockFace(); - FT_Matrix matrix = this->matrix; - FT_Matrix_Multiply(&set->transformationMatrix, &matrix); - FT_Set_Transform(face, &matrix, 0); - freetype->matrix = matrix; - - bool transform = matrix.xx != 0x10000 || matrix.yy != 0x10000 || matrix.xy != 0 || matrix.yx != 0; - if (transform) - load_flags |= FT_LOAD_NO_BITMAP; - - FT_Error err = FT_Load_Glyph(face, glyph, load_flags); - if (err && (load_flags & FT_LOAD_NO_BITMAP)) { - load_flags &= ~FT_LOAD_NO_BITMAP; - err = FT_Load_Glyph(face, glyph, load_flags); - } - if (err == FT_Err_Too_Few_Arguments) { - // this is an error in the bytecode interpreter, just try to run without it - load_flags |= FT_LOAD_FORCE_AUTOHINT; - err = FT_Load_Glyph(face, glyph, load_flags); - } - if (err != FT_Err_Ok) - qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph); - - unlockFace(); - if (set->outline_drawing) - return 0; - - if (!g) { - g = new Glyph; - g->uploadedToServer = false; - g->data = 0; - } - - FT_GlyphSlot slot = face->glyph; - if (embolden) Q_FT_GLYPHSLOT_EMBOLDEN(slot); - int left = slot->metrics.horiBearingX; - int right = slot->metrics.horiBearingX + slot->metrics.width; - int top = slot->metrics.horiBearingY; - int bottom = slot->metrics.horiBearingY - slot->metrics.height; - if (transform && slot->format != FT_GLYPH_FORMAT_BITMAP) { // freetype doesn't apply the transformation on the metrics - int l, r, t, b; - FT_Vector vector; - vector.x = left; - vector.y = top; - FT_Vector_Transform(&vector, &matrix); - l = r = vector.x; - t = b = vector.y; - vector.x = right; - vector.y = top; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - vector.x = right; - vector.y = bottom; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - vector.x = left; - vector.y = bottom; - FT_Vector_Transform(&vector, &matrix); - if (l > vector.x) l = vector.x; - if (r < vector.x) r = vector.x; - if (t < vector.y) t = vector.y; - if (b > vector.y) b = vector.y; - left = l; - right = r; - top = t; - bottom = b; - } - left = FLOOR(left); - right = CEIL(right); - bottom = FLOOR(bottom); - top = CEIL(top); - - g->linearAdvance = face->glyph->linearHoriAdvance >> 10; - g->width = TRUNC(right-left); - g->height = TRUNC(top-bottom); - g->x = TRUNC(left); - g->y = TRUNC(top); - g->advance = TRUNC(ROUND(face->glyph->advance.x)); - g->format = Format_None; - - return g; -} - QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, QFixed subPixelPosition, GlyphFormat format, @@ -1697,7 +1597,7 @@ void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFlag FT_Face face = 0; bool design = (default_hint_style == HintNone || default_hint_style == HintLight || - (flags & HB_ShaperFlag_UseDesignMetrics)); + (flags & HB_ShaperFlag_UseDesignMetrics)) && FT_IS_SCALABLE(freetype->face); for (int i = 0; i < glyphs->numGlyphs; i++) { Glyph *g = defaultGlyphSet.getGlyph(glyphs->glyphs[i]); if (g) { @@ -1851,6 +1751,7 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe } else { glyphSet = &defaultGlyphSet; } + bool needsDelete = false; Glyph * g = glyphSet->getGlyph(glyph); if (!g || g->format != format) { face = lockFace(); @@ -1858,6 +1759,7 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe FT_Matrix_Multiply(&glyphSet->transformationMatrix, &m); freetype->matrix = m; g = loadGlyph(glyphSet, glyph, subPixelPosition, format); + needsDelete = true; } if (g) { @@ -1866,6 +1768,8 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe overall.width = g->width; overall.height = g->height; overall.xoff = g->advance; + if (needsDelete) + delete g; } else { int left = FLOOR(face->glyph->metrics.horiBearingX); int right = CEIL(face->glyph->metrics.horiBearingX + face->glyph->metrics.width); @@ -2069,6 +1973,41 @@ HB_Error QFontEngineFT::getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 p return result; } +bool QFontEngineFT::initFromFontEngine(const QFontEngineFT *fe) +{ + if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype)) + return false; + + // Increase the reference of this QFreetypeFace since one more QFontEngineFT + // will be using it + freetype->ref.ref(); + + default_load_flags = fe->default_load_flags; + default_hint_style = fe->default_hint_style; + antialias = fe->antialias; + transform = fe->transform; + embolden = fe->embolden; + subpixelType = fe->subpixelType; + lcdFilterType = fe->lcdFilterType; + canUploadGlyphsToServer = fe->canUploadGlyphsToServer; + embeddedbitmap = fe->embeddedbitmap; + + return true; +} + +QFontEngine *QFontEngineFT::cloneWithSize(qreal pixelSize) const +{ + QFontDef fontDef; + fontDef.pixelSize = pixelSize; + QFontEngineFT *fe = new QFontEngineFT(fontDef); + if (!fe->initFromFontEngine(this)) { + delete fe; + return 0; + } else { + return fe; + } +} + QT_END_NAMESPACE #endif // QT_NO_FREETYPE diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 887efed..a620006 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -122,7 +122,7 @@ struct QFreetypeFace static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool = false); private: - friend class QFontEngineFTRawFont; + friend class QFontEngineFT; friend class QScopedPointerDeleter<QFreetypeFace>; QFreetypeFace() : _lock(QMutex::Recursive) {} ~QFreetypeFace() {} @@ -319,6 +319,10 @@ private: }; void setDefaultHintStyle(HintStyle style); + + virtual QFontEngine *cloneWithSize(qreal pixelSize) const; + bool initFromFontEngine(const QFontEngineFT *fontEngine); + HintStyle defaultHintStyle() const { return default_hint_style; } protected: @@ -345,7 +349,6 @@ protected: private: friend class QFontEngineFTRawFont; - QFontEngineFT::Glyph *loadGlyphMetrics(QGlyphSet *set, uint glyph, GlyphFormat format) const; int loadFlags(QGlyphSet *set, GlyphFormat format, int flags, bool &hsubpixel, int &vfactor) const; GlyphFormat defaultFormat; diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 673a7c8..9f094ad 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -377,7 +377,7 @@ bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout * } bool QFontEngineMacMulti::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, - unsigned short *logClusters, const HB_CharAttributes *charAttributes) const + unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const { if (*nglyphs < len) { *nglyphs = len; diff --git a/src/gui/text/qfontengine_mac_p.h b/src/gui/text/qfontengine_mac_p.h index 385fa83..292ea98 100644 --- a/src/gui/text/qfontengine_mac_p.h +++ b/src/gui/text/qfontengine_mac_p.h @@ -131,7 +131,7 @@ public: virtual bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const; bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags, - unsigned short *logClusters, const HB_CharAttributes *charAttributes) const; + unsigned short *logClusters, const HB_CharAttributes *charAttributes, QScriptItem *) const; virtual void recalcAdvances(QGlyphLayout *, QTextEngine::ShaperFlags) const; virtual void doKerning(QGlyphLayout *, QTextEngine::ShaperFlags) const; diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 5b39fd3..6db0aa6 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -235,6 +235,8 @@ public: virtual int glyphCount() const; + virtual QFontEngine *cloneWithSize(qreal /*pixelSize*/) const { return 0; } + HB_Font harfbuzzFont() const; HB_Face harfbuzzFace() const; diff --git a/src/gui/text/qfontengine_win.cpp b/src/gui/text/qfontengine_win.cpp index 82d9da0..54d7ec2 100644 --- a/src/gui/text/qfontengine_win.cpp +++ b/src/gui/text/qfontengine_win.cpp @@ -1284,6 +1284,23 @@ QImage QFontEngineWin::alphaRGBMapForGlyph(glyph_t glyph, QFixed, int margin, co return rgbMask; } +// From qfontdatabase_win.cpp +extern QFontEngine *qt_load_font_engine_win(const QFontDef &request); +QFontEngine *QFontEngineWin::cloneWithSize(qreal pixelSize) const +{ + QFontDef request = fontDef; + QString actualFontName = request.family; + if (!uniqueFamilyName.isEmpty()) + request.family = uniqueFamilyName; + request.pixelSize = pixelSize; + + QFontEngine *fontEngine = qt_load_font_engine_win(request); + if (fontEngine != NULL) + fontEngine->fontDef.family = actualFontName; + + return fontEngine; +} + // -------------------------------------- Multi font engine QFontEngineMultiWin::QFontEngineMultiWin(QFontEngine *first, const QStringList &fallbacks) diff --git a/src/gui/text/qfontengine_win_p.h b/src/gui/text/qfontengine_win_p.h index 28d8000..114149d 100644 --- a/src/gui/text/qfontengine_win_p.h +++ b/src/gui/text/qfontengine_win_p.h @@ -106,6 +106,8 @@ public: virtual QImage alphaMapForGlyph(glyph_t, const QTransform &xform); virtual QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform); + virtual QFontEngine *cloneWithSize(qreal pixelSize) const; + #ifndef Q_CC_MINGW virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0); #endif @@ -118,6 +120,7 @@ public: #endif QString _name; + QString uniqueFamilyName; HFONT hfont; LOGFONT logfont; uint stockFont : 1; diff --git a/src/gui/text/qfontengine_x11.cpp b/src/gui/text/qfontengine_x11.cpp index 9f3f8d3..4260b85 100644 --- a/src/gui/text/qfontengine_x11.cpp +++ b/src/gui/text/qfontengine_x11.cpp @@ -1196,6 +1196,20 @@ bool QFontEngineX11FT::uploadGlyphToServer(QGlyphSet *set, uint glyphid, Glyph * #endif } +QFontEngine *QFontEngineX11FT::cloneWithSize(qreal pixelSize) const +{ + QFontDef fontDef; + fontDef.pixelSize = pixelSize; + QFontEngineX11FT *fe = new QFontEngineX11FT(fontDef); + if (!fe->initFromFontEngine(this)) { + delete fe; + return 0; + } else { + fe->xglyph_format = xglyph_format; + return fe; + } +} + #endif // QT_NO_FONTCONFIG QT_END_NAMESPACE diff --git a/src/gui/text/qfontengine_x11_p.h b/src/gui/text/qfontengine_x11_p.h index ad68fac..d7eb39d 100644 --- a/src/gui/text/qfontengine_x11_p.h +++ b/src/gui/text/qfontengine_x11_p.h @@ -161,6 +161,8 @@ public: explicit QFontEngineX11FT(FcPattern *pattern, const QFontDef &fd, int screen); ~QFontEngineX11FT(); + QFontEngine *cloneWithSize(qreal pixelSize) const; + #ifndef QT_NO_XRENDER int xglyph_format; #endif diff --git a/src/gui/text/qfontenginedirectwrite.cpp b/src/gui/text/qfontenginedirectwrite.cpp index f0a3644..aab00c0 100644 --- a/src/gui/text/qfontenginedirectwrite.cpp +++ b/src/gui/text/qfontenginedirectwrite.cpp @@ -630,6 +630,17 @@ QFontEngine::Type QFontEngineDirectWrite::type() const return QFontEngine::DirectWrite; } +QFontEngine *QFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const +{ + QFontEngine *fontEngine = new QFontEngineDirectWrite(m_directWriteFactory, m_directWriteFontFace, + pixelSize); + + fontEngine->fontDef = fontDef; + fontEngine->fontDef.pixelSize = pixelSize; + + return fontEngine; +} + QT_END_NAMESPACE #endif // QT_NO_DIRECTWRITE diff --git a/src/gui/text/qfontenginedirectwrite_p.h b/src/gui/text/qfontenginedirectwrite_p.h index c440a6c..53a4b0a 100644 --- a/src/gui/text/qfontenginedirectwrite_p.h +++ b/src/gui/text/qfontenginedirectwrite_p.h @@ -101,6 +101,8 @@ public: QImage alphaRGBMapForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform); + QFontEngine *cloneWithSize(qreal pixelSize) const; + bool canRender(const QChar *string, int len); Type type() const; diff --git a/src/gui/text/qglyphs.cpp b/src/gui/text/qglyphrun.cpp index b8a418d..ea52788 100644 --- a/src/gui/text/qglyphs.cpp +++ b/src/gui/text/qglyphrun.cpp @@ -43,14 +43,14 @@ #if !defined(QT_NO_RAWFONT) -#include "qglyphs.h" -#include "qglyphs_p.h" +#include "qglyphrun.h" +#include "qglyphrun_p.h" QT_BEGIN_NAMESPACE /*! - \class QGlyphs - \brief the QGlyphs class provides direct access to the internal glyphs in a font + \class QGlyphRun + \brief The QGlyphRun class provides direct access to the internal glyphs in a font. \since 4.8 \ingroup text @@ -67,42 +67,43 @@ QT_BEGIN_NAMESPACE Under certain circumstances, it can be useful as an application developer to have more low-level control over which glyphs in a specific font are drawn to the screen. This could for instance be the case in applications that use an external font engine and text shaper together with Qt. - QGlyphs provides an interface to the raw data needed to get text on the screen. It + QGlyphRun provides an interface to the raw data needed to get text on the screen. It contains a list of glyph indexes, a position for each glyph and a font. It is the user's responsibility to ensure that the selected font actually contains the provided glyph indexes. - QTextLayout::glyphs() or QTextFragment::glyphs() can be used to convert unicode encoded text - into a list of QGlyphs objects, and QPainter::drawGlyphs() can be used to draw the glyphs. + QTextLayout::glyphRuns() or QTextFragment::glyphRuns() can be used to convert unicode encoded + text into a list of QGlyphRun objects, and QPainter::drawGlyphRun() can be used to draw the + glyphs. - \note Please note that QRawFont is considered local to the thread in which it is constructed, - which in turn means that a new QRawFont will have to be created and set on the QGlyphs if it is - moved to a different thread. If the QGlyphs contains a reference to a QRawFont from a different + \note Please note that QRawFont is considered local to the thread in which it is constructed. + This in turn means that a new QRawFont will have to be created and set on the QGlyphRun if it is + moved to a different thread. If the QGlyphRun contains a reference to a QRawFont from a different thread than the current, it will not be possible to draw the glyphs using a QPainter, as the QRawFont is considered invalid and inaccessible in this case. */ /*! - Constructs an empty QGlyphs object. + Constructs an empty QGlyphRun object. */ -QGlyphs::QGlyphs() : d(new QGlyphsPrivate) +QGlyphRun::QGlyphRun() : d(new QGlyphRunPrivate) { } /*! - Constructs a QGlyphs object which is a copy of \a other. + Constructs a QGlyphRun object which is a copy of \a other. */ -QGlyphs::QGlyphs(const QGlyphs &other) +QGlyphRun::QGlyphRun(const QGlyphRun &other) { d = other.d; } /*! - Destroys the QGlyphs. + Destroys the QGlyphRun. */ -QGlyphs::~QGlyphs() +QGlyphRun::~QGlyphRun() { // Required for QExplicitlySharedDataPointer } @@ -110,26 +111,26 @@ QGlyphs::~QGlyphs() /*! \internal */ -void QGlyphs::detach() +void QGlyphRun::detach() { if (d->ref != 1) d.detach(); } /*! - Assigns \a other to this QGlyphs object. + Assigns \a other to this QGlyphRun object. */ -QGlyphs &QGlyphs::operator=(const QGlyphs &other) +QGlyphRun &QGlyphRun::operator=(const QGlyphRun &other) { d = other.d; return *this; } /*! - Compares \a other to this QGlyphs object. Returns true if the list of glyph indexes, + Compares \a other to this QGlyphRun object. Returns true if the list of glyph indexes, the list of positions and the font are all equal, otherwise returns false. */ -bool QGlyphs::operator==(const QGlyphs &other) const +bool QGlyphRun::operator==(const QGlyphRun &other) const { return ((d == other.d) || (d->glyphIndexes == other.d->glyphIndexes @@ -137,14 +138,14 @@ bool QGlyphs::operator==(const QGlyphs &other) const && d->overline == other.d->overline && d->underline == other.d->underline && d->strikeOut == other.d->strikeOut - && d->font == other.d->font)); + && d->rawFont == other.d->rawFont)); } /*! - Compares \a other to this QGlyphs object. Returns true if any of the list of glyph + Compares \a other to this QGlyphRun object. Returns true if any of the list of glyph indexes, the list of positions or the font are different, otherwise returns false. */ -bool QGlyphs::operator!=(const QGlyphs &other) const +bool QGlyphRun::operator!=(const QGlyphRun &other) const { return !(*this == other); } @@ -152,13 +153,13 @@ bool QGlyphs::operator!=(const QGlyphs &other) const /*! \internal - Adds together the lists of glyph indexes and positions in \a other and this QGlyphs - object and returns the result. The font in the returned QGlyphs will be the same as in - this QGlyphs object. + Adds together the lists of glyph indexes and positions in \a other and this QGlyphRun + object and returns the result. The font in the returned QGlyphRun will be the same as in + this QGlyphRun object. */ -QGlyphs QGlyphs::operator+(const QGlyphs &other) const +QGlyphRun QGlyphRun::operator+(const QGlyphRun &other) const { - QGlyphs ret(*this); + QGlyphRun ret(*this); ret += other; return ret; } @@ -166,10 +167,10 @@ QGlyphs QGlyphs::operator+(const QGlyphs &other) const /*! \internal - Appends the glyph indexes and positions in \a other to this QGlyphs object and returns + Appends the glyph indexes and positions in \a other to this QGlyphRun object and returns a reference to the current object. */ -QGlyphs &QGlyphs::operator+=(const QGlyphs &other) +QGlyphRun &QGlyphRun::operator+=(const QGlyphRun &other) { detach(); @@ -180,41 +181,41 @@ QGlyphs &QGlyphs::operator+=(const QGlyphs &other) } /*! - Returns the font selected for this QGlyphs object. + Returns the font selected for this QGlyphRun object. - \sa setFont() + \sa setRawFont() */ -QRawFont QGlyphs::font() const +QRawFont QGlyphRun::rawFont() const { - return d->font; + return d->rawFont; } /*! Sets the font in which to look up the glyph indexes to \a font. - \sa font(), setGlyphIndexes() + \sa rawFont(), setGlyphIndexes() */ -void QGlyphs::setFont(const QRawFont &font) +void QGlyphRun::setRawFont(const QRawFont &rawFont) { detach(); - d->font = font; + d->rawFont = rawFont; } /*! - Returns the glyph indexes for this QGlyphs object. + Returns the glyph indexes for this QGlyphRun object. \sa setGlyphIndexes(), setPositions() */ -QVector<quint32> QGlyphs::glyphIndexes() const +QVector<quint32> QGlyphRun::glyphIndexes() const { return d->glyphIndexes; } /*! - Set the glyph indexes for this QGlyphs object to \a glyphIndexes. The glyph indexes must + Set the glyph indexes for this QGlyphRun object to \a glyphIndexes. The glyph indexes must be valid for the selected font. */ -void QGlyphs::setGlyphIndexes(const QVector<quint32> &glyphIndexes) +void QGlyphRun::setGlyphIndexes(const QVector<quint32> &glyphIndexes) { detach(); d->glyphIndexes = glyphIndexes; @@ -223,7 +224,7 @@ void QGlyphs::setGlyphIndexes(const QVector<quint32> &glyphIndexes) /*! Returns the position of the edge of the baseline for each glyph in this set of glyph indexes. */ -QVector<QPointF> QGlyphs::positions() const +QVector<QPointF> QGlyphRun::positions() const { return d->glyphPositions; } @@ -232,87 +233,87 @@ QVector<QPointF> QGlyphs::positions() const Sets the positions of the edge of the baseline for each glyph in this set of glyph indexes to \a positions. */ -void QGlyphs::setPositions(const QVector<QPointF> &positions) +void QGlyphRun::setPositions(const QVector<QPointF> &positions) { detach(); d->glyphPositions = positions; } /*! - Clears all data in the QGlyphs object. + Clears all data in the QGlyphRun object. */ -void QGlyphs::clear() +void QGlyphRun::clear() { detach(); d->glyphPositions = QVector<QPointF>(); d->glyphIndexes = QVector<quint32>(); - d->font = QRawFont(); + d->rawFont = QRawFont(); d->strikeOut = false; d->overline = false; d->underline = false; } /*! - Returns true if this QGlyphs should be painted with an overline decoration. + Returns true if this QGlyphRun should be painted with an overline decoration. \sa setOverline() */ -bool QGlyphs::overline() const +bool QGlyphRun::overline() const { return d->overline; } /*! - Indicates that this QGlyphs should be painted with an overline decoration if \a overline is true. - Otherwise the QGlyphs should be painted with no overline decoration. + Indicates that this QGlyphRun should be painted with an overline decoration if \a overline is true. + Otherwise the QGlyphRun should be painted with no overline decoration. \sa overline() */ -void QGlyphs::setOverline(bool overline) +void QGlyphRun::setOverline(bool overline) { detach(); d->overline = overline; } /*! - Returns true if this QGlyphs should be painted with an underline decoration. + Returns true if this QGlyphRun should be painted with an underline decoration. \sa setUnderline() */ -bool QGlyphs::underline() const +bool QGlyphRun::underline() const { return d->underline; } /*! - Indicates that this QGlyphs should be painted with an underline decoration if \a underline is - true. Otherwise the QGlyphs should be painted with no underline decoration. + Indicates that this QGlyphRun should be painted with an underline decoration if \a underline is + true. Otherwise the QGlyphRun should be painted with no underline decoration. \sa underline() */ -void QGlyphs::setUnderline(bool underline) +void QGlyphRun::setUnderline(bool underline) { detach(); d->underline = underline; } /*! - Returns true if this QGlyphs should be painted with a strike out decoration. + Returns true if this QGlyphRun should be painted with a strike out decoration. \sa setStrikeOut() */ -bool QGlyphs::strikeOut() const +bool QGlyphRun::strikeOut() const { return d->strikeOut; } /*! - Indicates that this QGlyphs should be painted with an strike out decoration if \a strikeOut is - true. Otherwise the QGlyphs should be painted with no strike out decoration. + Indicates that this QGlyphRun should be painted with an strike out decoration if \a strikeOut is + true. Otherwise the QGlyphRun should be painted with no strike out decoration. \sa strikeOut() */ -void QGlyphs::setStrikeOut(bool strikeOut) +void QGlyphRun::setStrikeOut(bool strikeOut) { detach(); d->strikeOut = strikeOut; diff --git a/src/gui/text/qglyphs.h b/src/gui/text/qglyphrun.h index 4d7dcaf..dcc166e 100644 --- a/src/gui/text/qglyphs.h +++ b/src/gui/text/qglyphrun.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QGLYPHS_H -#define QGLYPHS_H +#ifndef QGLYPHRUN_H +#define QGLYPHRUN_H #include <QtCore/qsharedpointer.h> #include <QtCore/qvector.h> @@ -55,16 +55,16 @@ QT_BEGIN_NAMESPACE QT_MODULE(Gui) -class QGlyphsPrivate; -class Q_GUI_EXPORT QGlyphs +class QGlyphRunPrivate; +class Q_GUI_EXPORT QGlyphRun { public: - QGlyphs(); - QGlyphs(const QGlyphs &other); - ~QGlyphs(); + QGlyphRun(); + QGlyphRun(const QGlyphRun &other); + ~QGlyphRun(); - QRawFont font() const; - void setFont(const QRawFont &font); + QRawFont rawFont() const; + void setRawFont(const QRawFont &rawFont); QVector<quint32> glyphIndexes() const; void setGlyphIndexes(const QVector<quint32> &glyphIndexes); @@ -74,9 +74,9 @@ public: void clear(); - QGlyphs &operator=(const QGlyphs &other); - bool operator==(const QGlyphs &other) const; - bool operator!=(const QGlyphs &other) const; + QGlyphRun &operator=(const QGlyphRun &other); + bool operator==(const QGlyphRun &other) const; + bool operator!=(const QGlyphRun &other) const; void setOverline(bool overline); bool overline() const; @@ -88,14 +88,14 @@ public: bool strikeOut() const; private: - friend class QGlyphsPrivate; + friend class QGlyphRunPrivate; friend class QTextLine; - QGlyphs operator+(const QGlyphs &other) const; - QGlyphs &operator+=(const QGlyphs &other); + QGlyphRun operator+(const QGlyphRun &other) const; + QGlyphRun &operator+=(const QGlyphRun &other); void detach(); - QExplicitlySharedDataPointer<QGlyphsPrivate> d; + QExplicitlySharedDataPointer<QGlyphRunPrivate> d; }; QT_END_NAMESPACE diff --git a/src/gui/text/qglyphs_p.h b/src/gui/text/qglyphrun_p.h index 944f777..4aa01d6 100644 --- a/src/gui/text/qglyphs_p.h +++ b/src/gui/text/qglyphrun_p.h @@ -39,8 +39,8 @@ ** ****************************************************************************/ -#ifndef QGLYPHS_P_H -#define QGLYPHS_P_H +#ifndef QGLYPHRUN_P_H +#define QGLYPHRUN_P_H // // W A R N I N G @@ -53,7 +53,7 @@ // We mean it. // -#include "qglyphs.h" +#include "qglyphrun.h" #include "qrawfont.h" #include <qfont.h> @@ -64,21 +64,21 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -class QGlyphsPrivate: public QSharedData +class QGlyphRunPrivate: public QSharedData { public: - QGlyphsPrivate() + QGlyphRunPrivate() : overline(false) , underline(false) , strikeOut(false) { } - QGlyphsPrivate(const QGlyphsPrivate &other) + QGlyphRunPrivate(const QGlyphRunPrivate &other) : QSharedData(other) , glyphIndexes(other.glyphIndexes) , glyphPositions(other.glyphPositions) - , font(other.font) + , rawFont(other.rawFont) , overline(other.overline) , underline(other.underline) , strikeOut(other.strikeOut) @@ -87,7 +87,7 @@ public: QVector<quint32> glyphIndexes; QVector<QPointF> glyphPositions; - QRawFont font; + QRawFont rawFont; uint overline : 1; uint underline : 1; diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp index 6fa25e7..82ec279 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.cpp +++ b/src/gui/text/qplatformfontdatabase_qpa.cpp @@ -218,6 +218,16 @@ QFontEngine *QPlatformFontDatabase::fontEngine(const QFontDef &fontDef, QUnicode return engine; } +QFontEngine *QPlatformFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, + QFont::HintingPreference hintingPreference) +{ + Q_UNUSED(fontData); + Q_UNUSED(pixelSize); + Q_UNUSED(hintingPreference); + qWarning("This plugin does not support font engines created directly from font data"); + return 0; +} + /*! */ diff --git a/src/gui/text/qplatformfontdatabase_qpa.h b/src/gui/text/qplatformfontdatabase_qpa.h index e0e4f04..046311f 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.h +++ b/src/gui/text/qplatformfontdatabase_qpa.h @@ -92,6 +92,8 @@ public: virtual QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); virtual void releaseHandle(void *handle); + virtual QFontEngine *fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference); + virtual QString fontDir() const; //callback diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 4a715c2..44ddfd2 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -78,7 +78,7 @@ QT_BEGIN_NAMESPACE A QRawFont object represents a single, physical instance of a given font in a given pixel size. I.e. in the typical case it represents a set of TrueType or OpenType font tables and uses a user specified pixel size to convert metrics into logical pixel units. In can be used in - combination with the QGlyphs class to draw specific glyph indexes at specific positions, and + combination with the QGlyphRun class to draw specific glyph indexes at specific positions, and also have accessors to some relevant data in the physical font. QRawFont only provides support for the main font technologies: GDI and DirectWrite on Windows @@ -87,9 +87,9 @@ QT_BEGIN_NAMESPACE QRawFont can be constructed in a number of ways: \list - \o \l It can be constructed by calling QTextLayout::glyphs() or QTextFragment::glyphs(). The - returned QGlyphs objects will contain QRawFont objects which represent the actual fonts - used to render each portion of the text. + \o \l It can be constructed by calling QTextLayout::glyphRuns() or QTextFragment::glyphRuns(). + The returned QGlyphRun objects will contain QRawFont objects which represent the actual + fonts used to render each portion of the text. \o \l It can be constructed by passing a QFont object to QRawFont::fromFont(). The function will return a QRawFont object representing the font that will be selected as response to the QFont query and the selected writing system. @@ -234,7 +234,7 @@ void QRawFont::loadFromData(const QByteArray &fontData, the pixel in the rasterization of the glyph. Otherwise, the image will be in the format of QImage::Format_A8 and each pixel will contain the opacity of the pixel in the rasterization. - \sa pathForGlyph(), QPainter::drawGlyphs() + \sa pathForGlyph(), QPainter::drawGlyphRun() */ QImage QRawFont::alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType, const QTransform &transform) const @@ -302,16 +302,68 @@ qreal QRawFont::descent() const } /*! + Returns the xHeight of this QRawFont in pixel units. + + \sa QFontMetricsF::xHeight() +*/ +qreal QRawFont::xHeight() const +{ + if (!isValid()) + return 0.0; + + return d->fontEngine->xHeight().toReal(); +} + +/*! + Returns the leading of this QRawFont in pixel units. + + \sa QFontMetricsF::leading() +*/ +qreal QRawFont::leading() const +{ + if (!isValid()) + return 0.0; + + return d->fontEngine->leading().toReal(); +} + +/*! + Returns the average character width of this QRawFont in pixel units. + + \sa QFontMetricsF::averageCharWidth() +*/ +qreal QRawFont::averageCharWidth() const +{ + if (!isValid()) + return 0.0; + + return d->fontEngine->averageCharWidth().toReal(); +} + +/*! + Returns the width of the widest character in the font. + + \sa QFontMetricsF::maxWidth() +*/ +qreal QRawFont::maxCharWidth() const +{ + if (!isValid()) + return 0.0; + + return d->fontEngine->maxCharWidth(); +} + +/*! Returns the pixel size set for this QRawFont. The pixel size affects how glyphs are rasterized, the size of glyphs returned by pathForGlyph(), and is used to convert internal metrics from design units to logical pixel units. \sa setPixelSize() */ -int QRawFont::pixelSize() const +qreal QRawFont::pixelSize() const { if (!isValid()) - return -1; + return 0.0; return d->fontEngine->fontDef.pixelSize; } @@ -374,9 +426,9 @@ int QRawFont::weight() const underlying font. Note that in cases where there are other tables in the font that affect the shaping of the text, the returned glyph indexes will not correctly represent the rendering of the text. To get the correctly shaped text, you can use QTextLayout to lay out and shape the - text, and then call QTextLayout::glyphs() to get the set of glyph index list and QRawFont pairs. + text, and then call QTextLayout::glyphRuns() to get the set of glyph index list and QRawFont pairs. - \sa advancesForGlyphIndexes(), QGlyphs, QTextLayout::glyphs(), QTextFragment::glyphs() + \sa advancesForGlyphIndexes(), glyphIndexesForChars(), QGlyphRun, QTextLayout::glyphRuns(), QTextFragment::glyphRuns() */ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const { @@ -385,11 +437,9 @@ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const int nglyphs = text.size(); QVarLengthGlyphLayoutArray glyphs(nglyphs); - if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &nglyphs, - QTextEngine::GlyphIndicesOnly)) { + if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) { glyphs.resize(nglyphs); - if (!d->fontEngine->stringToCMap(text.data(), text.size(), &glyphs, &nglyphs, - QTextEngine::GlyphIndicesOnly)) { + if (!glyphIndexesForChars(text.data(), text.size(), glyphs.glyphs, &nglyphs)) { Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice"); return QVector<quint32>(); } @@ -403,6 +453,26 @@ QVector<quint32> QRawFont::glyphIndexesForString(const QString &text) const } /*! + Converts a string of unicode points to glyph indexes using the CMAP table in the + underlying font. The function works like glyphIndexesForString() except it take + an array (\a chars), the results will be returned though \a glyphIndexes array + and number of glyphs will be set in \a numGlyphs. The size of \a glyphIndexes array + must be at least \a numChars, if that's still not enough, this function will return + false, then you can resize \a glyphIndexes from the size returned in \a numGlyphs. + + \sa glyphIndexesForString(), advancesForGlyphIndexes(), QGlyphs, QTextLayout::glyphs(), QTextFragment::glyphs() +*/ +bool QRawFont::glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const +{ + if (!isValid()) + return false; + + QGlyphLayout glyphs; + glyphs.glyphs = glyphIndexes; + return d->fontEngine->stringToCMap(chars, numChars, &glyphs, numGlyphs, QTextEngine::GlyphIndicesOnly); +} + +/*! Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances give the distance from the position of a given glyph to where the next glyph should be drawn to make it appear as if the two glyphs are unspaced. @@ -428,6 +498,36 @@ QVector<QPointF> QRawFont::advancesForGlyphIndexes(const QVector<quint32> &glyph } /*! + Returns the QRawFont's advances for each of the \a glyphIndexes in pixel units. The advances + give the distance from the position of a given glyph to where the next glyph should be drawn + to make it appear as if the two glyphs are unspaced. The glyph indexes are given with the + array \a glyphIndexes while the results are returned through \a advances, both of them must + have \a numGlyphs elements. + + \sa QTextLine::horizontalAdvance(), QFontMetricsF::width() +*/ +bool QRawFont::advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const +{ + if (!isValid()) + return false; + + QGlyphLayout glyphs; + glyphs.glyphs = const_cast<HB_Glyph *>(glyphIndexes); + glyphs.numGlyphs = numGlyphs; + QVarLengthArray<QFixed> advances_x(numGlyphs); + QVarLengthArray<QFixed> advances_y(numGlyphs); + glyphs.advances_x = advances_x.data(); + glyphs.advances_y = advances_y.data(); + + d->fontEngine->recalcAdvances(&glyphs, 0); + + for (int i=0; i<numGlyphs; ++i) + advances[i] = QPointF(glyphs.advances_x[i].toReal(), glyphs.advances_y[i].toReal()); + + return true; +} + +/*! Returns the hinting preference used to construct this QRawFont. \sa QFont::hintingPreference() @@ -535,17 +635,17 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ layout.beginLayout(); QTextLine line = layout.createLine(); layout.endLayout(); - QList<QGlyphs> list = layout.glyphs(); + QList<QGlyphRun> list = layout.glyphRuns(); if (list.size()) { // Pick the one matches the family name we originally requested, // if none of them match, just pick the first one for (int i = 0; i < list.size(); i++) { - QGlyphs glyphs = list.at(i); - QRawFont rawfont = glyphs.font(); + QGlyphRun glyphs = list.at(i); + QRawFont rawfont = glyphs.rawFont(); if (rawfont.familyName() == font.family()) return rawfont; } - return list.at(0).font(); + return list.at(0).rawFont(); } return QRawFont(); #else @@ -577,10 +677,21 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ /*! Sets the pixel size with which this font should be rendered to \a pixelSize. */ -void QRawFont::setPixelSize(int pixelSize) +void QRawFont::setPixelSize(qreal pixelSize) { + if (d->fontEngine == 0) + return; + detach(); - d->platformSetPixelSize(pixelSize); + QFontEngine *oldFontEngine = d->fontEngine; + + d->fontEngine = d->fontEngine->cloneWithSize(pixelSize); + if (d->fontEngine != 0) + d->fontEngine->ref.ref(); + + oldFontEngine->ref.deref(); + if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0) + delete oldFontEngine; } /*! diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h index 96dc838..3875fec 100644 --- a/src/gui/text/qrawfont.h +++ b/src/gui/text/qrawfont.h @@ -90,19 +90,25 @@ public: QVector<quint32> glyphIndexesForString(const QString &text) const; QVector<QPointF> advancesForGlyphIndexes(const QVector<quint32> &glyphIndexes) const; + bool glyphIndexesForChars(const QChar *chars, int numChars, quint32 *glyphIndexes, int *numGlyphs) const; + bool advancesForGlyphIndexes(const quint32 *glyphIndexes, QPointF *advances, int numGlyphs) const; QImage alphaMapForGlyph(quint32 glyphIndex, AntialiasingType antialiasingType = SubPixelAntialiasing, const QTransform &transform = QTransform()) const; QPainterPath pathForGlyph(quint32 glyphIndex) const; - void setPixelSize(int pixelSize); - int pixelSize() const; + void setPixelSize(qreal pixelSize); + qreal pixelSize() const; QFont::HintingPreference hintingPreference() const; qreal ascent() const; qreal descent() const; + qreal leading() const; + qreal xHeight() const; + qreal averageCharWidth() const; + qreal maxCharWidth() const; qreal unitsPerEm() const; diff --git a/src/gui/text/qrawfont_ft.cpp b/src/gui/text/qrawfont_ft.cpp index eefbd92..23d47eb 100644 --- a/src/gui/text/qrawfont_ft.cpp +++ b/src/gui/text/qrawfont_ft.cpp @@ -90,32 +90,6 @@ public: return init(faceId, true, Format_None, fontData); } - - bool initFromFontEngine(QFontEngine *oldFontEngine) - { - QFontEngineFT *fe = static_cast<QFontEngineFT *>(oldFontEngine); - - // Increase the reference of this QFreetypeFace since one more QFontEngineFT - // will be using it - fe->freetype->ref.ref(); - if (!init(fe->faceId(), fe->antialias, fe->defaultFormat, fe->freetype)) - return false; - - default_load_flags = fe->default_load_flags; - default_hint_style = fe->default_hint_style; - antialias = fe->antialias; - transform = fe->transform; - embolden = fe->embolden; - subpixelType = fe->subpixelType; - lcdFilterType = fe->lcdFilterType; - canUploadGlyphsToServer = fe->canUploadGlyphsToServer; - embeddedbitmap = fe->embeddedbitmap; - -#if defined(Q_WS_X11) - xglyph_format = static_cast<QFontEngineX11FT *>(fe)->xglyph_format; -#endif - return true; - } }; @@ -159,31 +133,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixel fontEngine->ref.ref(); } -void QRawFontPrivate::platformSetPixelSize(int pixelSize) -{ - if (fontEngine == NULL) - return; - - QFontEngine *oldFontEngine = fontEngine; - - QFontDef fontDef; - fontDef.pixelSize = pixelSize; - QFontEngineFTRawFont *fe = new QFontEngineFTRawFont(fontDef); - if (!fe->initFromFontEngine(oldFontEngine)) { - delete fe; - return; - } - - fontEngine = fe; - fontEngine->fontDef = oldFontEngine->fontDef; - fontEngine->fontDef.pixelSize = pixelSize; - fontEngine->ref.ref(); - Q_ASSERT(fontEngine != oldFontEngine); - oldFontEngine->ref.deref(); - if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0) - delete oldFontEngine; -} - QT_END_NAMESPACE #endif // QT_NO_RAWFONT diff --git a/src/gui/text/qrawfont_mac.cpp b/src/gui/text/qrawfont_mac.cpp index 56005c6..1ed4185 100644 --- a/src/gui/text/qrawfont_mac.cpp +++ b/src/gui/text/qrawfont_mac.cpp @@ -78,28 +78,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, } } -void QRawFontPrivate::platformSetPixelSize(int pixelSize) -{ - if (fontEngine == NULL) - return; - - QFontEngine *oldFontEngine = fontEngine; - - QFontDef fontDef = oldFontEngine->fontDef; - fontDef.pixelSize = pixelSize; - fontDef.pointSize = pixelSize * 72.0 / qt_defaultDpi(); - - QCoreTextFontEngine *ctFontEngine = static_cast<QCoreTextFontEngine *>(oldFontEngine); - Q_ASSERT(ctFontEngine->cgFont); - - fontEngine = new QCoreTextFontEngine(ctFontEngine->cgFont, fontDef); - fontEngine->ref.ref(); - Q_ASSERT(fontEngine != oldFontEngine); - oldFontEngine->ref.deref(); - if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0) - delete oldFontEngine; -} - QT_END_NAMESPACE #endif // QT_NO_RAWFONT diff --git a/src/gui/text/qrawfont_p.h b/src/gui/text/qrawfont_p.h index f9a9ab5..e29ea9c 100644 --- a/src/gui/text/qrawfont_p.h +++ b/src/gui/text/qrawfont_p.h @@ -83,7 +83,6 @@ public: , fontHandle(NULL) , ptrAddFontMemResourceEx(other.ptrAddFontMemResourceEx) , ptrRemoveFontMemResourceEx(other.ptrRemoveFontMemResourceEx) - , uniqueFamilyName(other.uniqueFamilyName) #endif { fontEngine = other.fontEngine; @@ -102,7 +101,6 @@ public: void platformLoadFromData(const QByteArray &fontData, int pixelSize, QFont::HintingPreference hintingPreference); - void platformSetPixelSize(int pixelSize); static QRawFontPrivate *get(const QRawFont &font) { return font.d.data(); } @@ -120,8 +118,6 @@ public: PtrAddFontMemResourceEx ptrAddFontMemResourceEx; PtrRemoveFontMemResourceEx ptrRemoveFontMemResourceEx; - QString uniqueFamilyName; - #endif // Q_WS_WIN }; diff --git a/src/gui/util/qscroller_mac.mm b/src/gui/text/qrawfont_qpa.cpp index 4bf69c1..103619c 100644 --- a/src/gui/util/qscroller_mac.mm +++ b/src/gui/text/qrawfont_qpa.cpp @@ -41,31 +41,29 @@ #include <QtCore/qglobal.h> -#ifdef Q_WS_MAC +#if !defined(QT_NO_RAWFONT) -#import <Cocoa/Cocoa.h> +#include "qrawfont_p.h" +#include <QtGui/qplatformfontdatabase_qpa.h> +#include <private/qapplication_p.h> -#include "qscroller_p.h" +QT_BEGIN_NAMESPACE -QPointF QScrollerPrivate::realDpi(int screen) +void QRawFontPrivate::platformCleanUp() { - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - NSArray *nsscreens = [NSScreen screens]; - - if (screen < 0 || screen >= int([nsscreens count])) - screen = 0; +} - NSScreen *nsscreen = [nsscreens objectAtIndex:screen]; - CGDirectDisplayID display = [[[nsscreen deviceDescription] objectForKey:@"NSScreenNumber"] intValue]; +void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixelSize, + QFont::HintingPreference hintingPreference) +{ + Q_ASSERT(fontEngine == 0); - CGSize mmsize = CGDisplayScreenSize(display); - if (mmsize.width > 0 && mmsize.height > 0) { - return QPointF(CGDisplayPixelsWide(display) / mmsize.width, - CGDisplayPixelsHigh(display) / mmsize.height) * qreal(25.4); - } else { - return QPointF(); - } - [pool release]; + QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase(); + fontEngine = pfdb->fontEngine(fontData, pixelSize, hintingPreference); + if (fontEngine != 0) + fontEngine->ref.ref(); } -#endif +QT_END_NAMESPACE + +#endif // QT_NO_RAWFONT diff --git a/src/gui/text/qrawfont_win.cpp b/src/gui/text/qrawfont_win.cpp index fb5c6f4..d8acf57 100644 --- a/src/gui/text/qrawfont_win.cpp +++ b/src/gui/text/qrawfont_win.cpp @@ -559,7 +559,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData, GUID guid; CoCreateGuid(&guid); - uniqueFamilyName = QString::fromLatin1("f") + QString uniqueFamilyName = QString::fromLatin1("f") + QString::number(guid.Data1, 36) + QLatin1Char('-') + QString::number(guid.Data2, 36) + QLatin1Char('-') + QString::number(guid.Data3, 36) + QLatin1Char('-') @@ -613,6 +613,7 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData, Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref == 0); // Override the generated font name + static_cast<QFontEngineWin *>(fontEngine)->uniqueFamilyName = uniqueFamilyName; fontEngine->fontDef.family = actualFontName; fontEngine->ref.ref(); } @@ -701,50 +702,6 @@ void QRawFontPrivate::platformLoadFromData(const QByteArray &_fontData, } } -void QRawFontPrivate::platformSetPixelSize(int pixelSize) -{ - if (fontEngine == NULL) - return; - - QFontEngine *oldFontEngine = fontEngine; - -#if !defined(QT_NO_DIRECTWRITE) - if (fontEngine->type() == QFontEngine::Win) -#endif - - { - QFontDef request = fontEngine->fontDef; - QString actualFontName = request.family; - if (!uniqueFamilyName.isEmpty()) - request.family = uniqueFamilyName; - request.pixelSize = pixelSize; - - fontEngine = qt_load_font_engine_win(request); - if (fontEngine != NULL) { - fontEngine->fontDef.family = actualFontName; - fontEngine->ref.ref(); - } - } - -#if !defined(QT_NO_DIRECTWRITE) - else { - QFontEngineDirectWrite *dWriteFE = static_cast<QFontEngineDirectWrite *>(fontEngine); - fontEngine = new QFontEngineDirectWrite(dWriteFE->m_directWriteFactory, - dWriteFE->m_directWriteFontFace, - pixelSize); - - fontEngine->fontDef = dWriteFE->fontDef; - fontEngine->fontDef.pixelSize = pixelSize; - fontEngine->ref.ref(); - } -#endif - - Q_ASSERT(fontEngine != oldFontEngine); - oldFontEngine->ref.deref(); - if (oldFontEngine->cache_count == 0 && oldFontEngine->ref == 0) - delete oldFontEngine; -} - QT_END_NAMESPACE #endif // QT_NO_RAWFONT diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp index 4396730..a8bf763 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -677,7 +677,7 @@ void QTextControlPrivate::extendWordwiseSelection(int suggestedNewPosition, qrea const qreal wordEndX = line.cursorToX(curs.position() - blockPos) + blockCoordinates.x(); - if (mouseXPosition < wordStartX || mouseXPosition > wordEndX) + if (!wordSelectionEnabled && (mouseXPosition < wordStartX || mouseXPosition > wordEndX)) return; // keep the already selected word even when moving to the left @@ -1579,8 +1579,10 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con emit q->cursorPositionChanged(); _q_updateCurrentCharFormatAndSelection(); } else { - if (cursor.position() != oldCursorPos) + if (cursor.position() != oldCursorPos) { emit q->cursorPositionChanged(); + emit q->microFocusChanged(); + } selectionChanged(); } repaintOldAndNewSelection(oldSelection); diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 6ddfdb0..17bcc6c 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -362,20 +362,23 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor currentCharFormat = -1; bool adjustX = true; QTextBlock blockIt = block(); + bool visualMovement = priv->defaultCursorMoveStyle == Qt::VisualMoveStyle; if (!blockIt.isValid()) return false; - if (op >= QTextCursor::Left && op <= QTextCursor::WordRight - && blockIt.textDirection() == Qt::RightToLeft) { - if (op == QTextCursor::Left) - op = QTextCursor::NextCharacter; - else if (op == QTextCursor::Right) - op = QTextCursor::PreviousCharacter; - else if (op == QTextCursor::WordLeft) + if (blockIt.textDirection() == Qt::RightToLeft) { + if (op == QTextCursor::WordLeft) op = QTextCursor::NextWord; else if (op == QTextCursor::WordRight) op = QTextCursor::PreviousWord; + + if (!visualMovement) { + if (op == QTextCursor::Left) + op = QTextCursor::NextCharacter; + else if (op == QTextCursor::Right) + op = QTextCursor::PreviousCharacter; + } } const QTextLayout *layout = blockLayout(blockIt); @@ -418,9 +421,12 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor break; } case QTextCursor::PreviousCharacter: - case QTextCursor::Left: newPosition = priv->previousCursorPosition(position, QTextLayout::SkipCharacters); break; + case QTextCursor::Left: + newPosition = visualMovement ? priv->leftCursorPosition(position) + : priv->previousCursorPosition(position, QTextLayout::SkipCharacters); + break; case QTextCursor::StartOfWord: { if (relativePos == 0) break; @@ -529,9 +535,12 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor break; } case QTextCursor::NextCharacter: - case QTextCursor::Right: newPosition = priv->nextCursorPosition(position, QTextLayout::SkipCharacters); break; + case QTextCursor::Right: + newPosition = visualMovement ? priv->rightCursorPosition(position) + : priv->nextCursorPosition(position, QTextLayout::SkipCharacters); + break; case QTextCursor::NextWord: case QTextCursor::WordRight: newPosition = priv->nextCursorPosition(position, QTextLayout::SkipWords); @@ -2558,4 +2567,19 @@ QTextDocument *QTextCursor::document() const return 0; // document went away } +/*! + \enum Qt::CursorMoveStyle + + This enum describes the movement style available to text cursors. The options + are: + + \value LogicalMoveStyle Within a left-to-right text block, decrease cursor + position when pressing left arrow key, increase cursor position when pressing + the right arrow key. If the text block is right-to-left, the opposite behavior + applies. + \value VisualMoveStyle Pressing the left arrow key will always cause the cursor + to move left, regardless of the text's writing direction. Pressing the right + arrow key will always cause the cursor to move right. +*/ + QT_END_NAMESPACE diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 6dbd755..0d33912 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -586,6 +586,29 @@ void QTextDocument::setDefaultTextOption(const QTextOption &option) } /*! + \since 4.8 + + The default cursor movement style is used by all QTextCursor objects + created from the document. The default is Qt::LogicalMoveStyle. +*/ +Qt::CursorMoveStyle QTextDocument::defaultCursorMoveStyle() const +{ + Q_D(const QTextDocument); + return d->defaultCursorMoveStyle; +} + +/*! + \since 4.8 + + Set the default cursor movement style. +*/ +void QTextDocument::setDefaultCursorMoveStyle(Qt::CursorMoveStyle style) +{ + Q_D(QTextDocument); + d->defaultCursorMoveStyle = style; +} + +/*! \fn void QTextDocument::markContentsDirty(int position, int length) Marks the contents specified by the given \a position and \a length @@ -2076,6 +2099,10 @@ QString QTextHtmlExporter::toHtml(const QByteArray &encoding, ExportMode mode) html += QLatin1String(" font-size:"); html += QString::number(defaultCharFormat.fontPointSize()); html += QLatin1String("pt;"); + } else if (defaultCharFormat.hasProperty(QTextFormat::FontPixelSize)) { + html += QLatin1String(" font-size:"); + html += QString::number(defaultCharFormat.intProperty(QTextFormat::FontPixelSize)); + html += QLatin1String("px;"); } html += QLatin1String(" font-weight:"); @@ -2156,6 +2183,10 @@ bool QTextHtmlExporter::emitCharFormatStyle(const QTextCharFormat &format) html += QLatin1Char(';'); attributesEmitted = true; } + } else if (format.hasProperty(QTextFormat::FontPixelSize)) { + html += QLatin1String(" font-size:"); + html += QString::number(format.intProperty(QTextFormat::FontPixelSize)); + html += QLatin1String("px;"); } if (format.hasProperty(QTextFormat::FontWeight) diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h index f87ccc9..b826dc1 100644 --- a/src/gui/text/qtextdocument.h +++ b/src/gui/text/qtextdocument.h @@ -60,7 +60,6 @@ class QPainter; class QPrinter; class QAbstractTextDocumentLayout; class QPoint; -class QTextCursor; class QTextObject; class QTextFormat; class QTextFrame; @@ -70,6 +69,7 @@ class QUrl; class QVariant; class QRectF; class QTextOption; +class QTextCursor; template<typename T> class QVector; @@ -269,6 +269,9 @@ public: QTextOption defaultTextOption() const; void setDefaultTextOption(const QTextOption &option); + Qt::CursorMoveStyle defaultCursorMoveStyle() const; + void setDefaultCursorMoveStyle(Qt::CursorMoveStyle style); + Q_SIGNALS: void contentsChange(int from, int charsRemoves, int charsAdded); void contentsChanged(); diff --git a/src/gui/text/qtextdocument_p.cpp b/src/gui/text/qtextdocument_p.cpp index a997720..640f7aa 100644 --- a/src/gui/text/qtextdocument_p.cpp +++ b/src/gui/text/qtextdocument_p.cpp @@ -209,6 +209,7 @@ QTextDocumentPrivate::QTextDocumentPrivate() defaultTextOption.setTabStop(80); // same as in qtextengine.cpp defaultTextOption.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); + defaultCursorMoveStyle = Qt::LogicalMoveStyle; indentWidth = 40; documentMargin = 4; @@ -1382,6 +1383,20 @@ int QTextDocumentPrivate::previousCursorPosition(int position, QTextLayout::Curs return it.layout()->previousCursorPosition(position-start, mode) + start; } +int QTextDocumentPrivate::leftCursorPosition(int position) const +{ + QTextBlock it = blocksFind(position); + int start = it.position(); + return it.layout()->leftCursorPosition(position-start) + start; +} + +int QTextDocumentPrivate::rightCursorPosition(int position) const +{ + QTextBlock it = blocksFind(position); + int start = it.position(); + return it.layout()->rightCursorPosition(position-start) + start; +} + void QTextDocumentPrivate::changeObjectFormat(QTextObject *obj, int format) { beginEditBlock(); diff --git a/src/gui/text/qtextdocument_p.h b/src/gui/text/qtextdocument_p.h index b464f2e..e72d676 100644 --- a/src/gui/text/qtextdocument_p.h +++ b/src/gui/text/qtextdocument_p.h @@ -64,6 +64,7 @@ #include "private/qtextformat_p.h" #include "QtGui/qtextdocument.h" #include "QtGui/qtextobject.h" +#include "QtGui/qtextcursor.h" #include "QtCore/qmap.h" #include "QtCore/qvariant.h" #include "QtCore/qurl.h" @@ -244,6 +245,8 @@ public: int nextCursorPosition(int position, QTextLayout::CursorMode mode) const; int previousCursorPosition(int position, QTextLayout::CursorMode mode) const; + int leftCursorPosition(int position) const; + int rightCursorPosition(int position) const; void changeObjectFormat(QTextObject *group, int format); @@ -339,6 +342,7 @@ private: public: QTextOption defaultTextOption; + Qt::CursorMoveStyle defaultCursorMoveStyle; #ifndef QT_NO_CSSPARSER QCss::StyleSheet parsedDefaultStyleSheet; #endif diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index ce157be..f3dc975 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -2996,10 +2996,19 @@ void QTextDocumentLayout::resizeInlineObject(QTextInlineObject item, int posInDo QSizeF inlineSize = (pos == QTextFrameFormat::InFlow ? intrinsic : QSizeF(0, 0)); item.setWidth(inlineSize.width()); - if (f.verticalAlignment() == QTextCharFormat::AlignMiddle) { + + QFontMetrics m(f.font()); + switch (f.verticalAlignment()) + { + case QTextCharFormat::AlignMiddle: item.setDescent(inlineSize.height() / 2); item.setAscent(inlineSize.height() / 2 - 1); - } else { + break; + case QTextCharFormat::AlignBaseline: + item.setDescent(m.descent()); + item.setAscent(inlineSize.height() - m.descent() - 1); + break; + default: item.setDescent(0); item.setAscent(inlineSize.height() - 1); } @@ -3081,6 +3090,7 @@ void QTextDocumentLayoutPrivate::ensureLayouted(QFixed y) const if (currentLazyLayoutPosition == -1) return; const QSizeF oldSize = q->dynamicDocumentSize(); + Q_UNUSED(oldSize); if (checkPoints.isEmpty()) layoutStep(); diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 08d0eca..ff27bc6 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -856,6 +856,21 @@ void QTextEngine::shapeLine(const QScriptLine &line) } } +#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC) +static bool enableHarfBuzz() +{ + static enum { Yes, No, Unknown } status = Unknown; + + if (status == Unknown) { + QByteArray v = qgetenv("QT_ENABLE_HARFBUZZ"); + bool value = !v.isEmpty() && v != "0" && v != "false"; + if (value) status = Yes; + else status = No; + } + return status == Yes; +} +#endif + void QTextEngine::shapeText(int item) const { Q_ASSERT(item < layoutData->items.size()); @@ -865,7 +880,24 @@ void QTextEngine::shapeText(int item) const return; #if defined(Q_WS_MAC) - shapeTextMac(item); +#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC) + if (enableHarfBuzz()) { +#endif + QFontEngine *actualFontEngine = fontEngine(si, &si.ascent, &si.descent, &si.leading); + if (actualFontEngine->type() == QFontEngine::Multi) + actualFontEngine = static_cast<QFontEngineMulti *>(actualFontEngine)->engine(0); + + HB_Face face = actualFontEngine->harfbuzzFace(); + HB_Script script = (HB_Script) si.analysis.script; + if (face->supported_scripts[script]) + shapeTextWithHarfbuzz(item); + else + shapeTextMac(item); +#if !defined(QT_ENABLE_HARFBUZZ_FOR_MAC) + } else { + shapeTextMac(item); + } +#endif #elif defined(Q_WS_WINCE) shapeTextWithCE(item); #else @@ -1242,6 +1274,10 @@ void QTextEngine::shapeTextWithHarfbuzz(int item) const actualFontEngine = static_cast<QFontEngineMulti *>(font)->engine(engineIdx); } + si.ascent = qMax(actualFontEngine->ascent(), si.ascent); + si.descent = qMax(actualFontEngine->descent(), si.descent); + si.leading = qMax(actualFontEngine->leading(), si.leading); + shaper_item.font = actualFontEngine->harfbuzzFont(); shaper_item.face = actualFontEngine->harfbuzzFace(); @@ -1304,6 +1340,7 @@ static void init(QTextEngine *e) e->ignoreBidi = false; e->cacheGlyphs = false; e->forceJustification = false; + e->visualMovement = false; e->layoutData = 0; @@ -1565,6 +1602,8 @@ bool QTextEngine::isRightToLeft() const default: break; } + if (!layoutData) + itemize(); // this places the cursor in the right position depending on the keyboard layout if (layoutData->string.isEmpty()) return QApplication::keyboardInputDirection() == Qt::RightToLeft; @@ -2737,6 +2776,182 @@ QFixed QTextEngine::leadingSpaceWidth(const QScriptLine &line) return width(line.from + pos, line.length - pos); } +QFixed QTextEngine::alignLine(const QScriptLine &line) +{ + QFixed x = 0; + justify(line); + // if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned. + if (!line.justified && line.width != QFIXED_MAX) { + int align = option.alignment(); + if (align & Qt::AlignLeft) + x -= leadingSpaceWidth(line); + if (align & Qt::AlignJustify && isRightToLeft()) + align = Qt::AlignRight; + if (align & Qt::AlignRight) + x = line.width - (line.textAdvance + leadingSpaceWidth(line)); + else if (align & Qt::AlignHCenter) + x = (line.width - (line.textAdvance + leadingSpaceWidth(line)))/2; + } + return x; +} + +QFixed QTextEngine::offsetInLigature(const QScriptItem *si, int pos, int max, int glyph_pos) +{ + unsigned short *logClusters = this->logClusters(si); + const QGlyphLayout &glyphs = shapedGlyphs(si); + + int offsetInCluster = 0; + for (int i = pos - 1; i >= 0; i--) { + if (logClusters[i] == glyph_pos) + offsetInCluster++; + else + break; + } + + // in the case that the offset is inside a (multi-character) glyph, + // interpolate the position. + if (offsetInCluster > 0) { + int clusterLength = 0; + for (int i = pos - offsetInCluster; i < max; i++) { + if (logClusters[i] == glyph_pos) + clusterLength++; + else + break; + } + if (clusterLength) + return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength; + } + + return 0; +} + +int QTextEngine::previousLogicalPosition(int oldPos) const +{ + const HB_CharAttributes *attrs = attributes(); + if (!attrs || oldPos < 0) + return oldPos; + + if (oldPos <= 0) + return 0; + oldPos--; + while (oldPos && !attrs[oldPos].charStop) + oldPos--; + return oldPos; +} + +int QTextEngine::nextLogicalPosition(int oldPos) const +{ + const HB_CharAttributes *attrs = attributes(); + int len = block.isValid() ? block.length() - 1 + : layoutData->string.length(); + Q_ASSERT(len <= layoutData->string.length()); + if (!attrs || oldPos < 0 || oldPos >= len) + return oldPos; + + oldPos++; + while (oldPos < len && !attrs[oldPos].charStop) + oldPos++; + return oldPos; +} + +int QTextEngine::lineNumberForTextPosition(int pos) +{ + if (!layoutData) + itemize(); + if (pos == layoutData->string.length() && lines.size()) + return lines.size() - 1; + for (int i = 0; i < lines.size(); ++i) { + const QScriptLine& line = lines[i]; + if (line.from + line.length > pos) + return i; + } + return -1; +} + +void QTextEngine::insertionPointsForLine(int lineNum, QVector<int> &insertionPoints) +{ + QTextLineItemIterator iterator(this, lineNum); + bool rtl = isRightToLeft(); + bool lastLine = lineNum >= lines.size() - 1; + + while (!iterator.atEnd()) { + iterator.next(); + const QScriptItem *si = &layoutData->items[iterator.item]; + if (si->analysis.bidiLevel % 2) { + int i = iterator.itemEnd - 1, min = iterator.itemStart; + if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd())) + i++; + for (; i >= min; i--) + insertionPoints.push_back(i); + } else { + int i = iterator.itemStart, max = iterator.itemEnd; + if (lastLine && (rtl ? iterator.atBeginning() : iterator.atEnd())) + max++; + for (; i < max; i++) + insertionPoints.push_back(i); + } + } +} + +int QTextEngine::endOfLine(int lineNum) +{ + QVector<int> insertionPoints; + insertionPointsForLine(lineNum, insertionPoints); + + if (insertionPoints.size() > 0) + return insertionPoints.last(); + return 0; +} + +int QTextEngine::beginningOfLine(int lineNum) +{ + QVector<int> insertionPoints; + insertionPointsForLine(lineNum, insertionPoints); + + if (insertionPoints.size() > 0) + return insertionPoints.first(); + return 0; +} + +int QTextEngine::positionAfterVisualMovement(int pos, QTextCursor::MoveOperation op) +{ + if (!layoutData) + itemize(); + + bool moveRight = (op == QTextCursor::Right); + bool alignRight = isRightToLeft(); + if (!layoutData->hasBidi) + return moveRight ^ alignRight ? nextLogicalPosition(pos) : previousLogicalPosition(pos); + + int lineNum = lineNumberForTextPosition(pos); + Q_ASSERT(lineNum >= 0); + + QVector<int> insertionPoints; + insertionPointsForLine(lineNum, insertionPoints); + int i, max = insertionPoints.size(); + for (i = 0; i < max; i++) + if (pos == insertionPoints[i]) { + if (moveRight) { + if (i + 1 < max) + return insertionPoints[i + 1]; + } else { + if (i > 0) + return insertionPoints[i - 1]; + } + + if (moveRight ^ alignRight) { + if (lineNum + 1 < lines.size()) + return alignRight ? endOfLine(lineNum + 1) : beginningOfLine(lineNum + 1); + } + else { + if (lineNum > 0) + return alignRight ? beginningOfLine(lineNum - 1) : endOfLine(lineNum - 1); + } + } + + return pos; +} + QStackTextEngine::QStackTextEngine(const QString &string, const QFont &f) : QTextEngine(string, f), _layoutData(string, _memory, MemSize) @@ -2841,5 +3056,127 @@ glyph_metrics_t glyph_metrics_t::transformed(const QTransform &matrix) const return m; } +QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int _lineNum, const QPointF &pos, + const QTextLayout::FormatRange *_selection) + : eng(_eng), + line(eng->lines[_lineNum]), + si(0), + lineNum(_lineNum), + lineEnd(line.from + line.length), + firstItem(eng->findItem(line.from)), + lastItem(eng->findItem(lineEnd - 1)), + nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0), + logicalItem(-1), + item(-1), + visualOrder(nItems), + levels(nItems), + selection(_selection) +{ + pos_x = x = QFixed::fromReal(pos.x()); + + x += line.x; + + x += eng->alignLine(line); + + for (int i = 0; i < nItems; ++i) + levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel; + QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data()); + + eng->shapeLine(line); +} + +QScriptItem &QTextLineItemIterator::next() +{ + x += itemWidth; + + ++logicalItem; + item = visualOrder[logicalItem] + firstItem; + itemLength = eng->length(item); + si = &eng->layoutData->items[item]; + if (!si->num_glyphs) + eng->shape(item); + + if (si->analysis.flags >= QScriptAnalysis::TabOrObject) { + itemWidth = si->width; + return *si; + } + + unsigned short *logClusters = eng->logClusters(si); + QGlyphLayout glyphs = eng->shapedGlyphs(si); + + itemStart = qMax(line.from, si->position); + glyphsStart = logClusters[itemStart - si->position]; + if (lineEnd < si->position + itemLength) { + itemEnd = lineEnd; + glyphsEnd = logClusters[itemEnd-si->position]; + } else { + itemEnd = si->position + itemLength; + glyphsEnd = si->num_glyphs; + } + // show soft-hyphen at line-break + if (si->position + itemLength >= lineEnd + && eng->layoutData->string.at(lineEnd - 1) == 0x00ad) + glyphs.attributes[glyphsEnd - 1].dontPrint = false; + + itemWidth = 0; + for (int g = glyphsStart; g < glyphsEnd; ++g) + itemWidth += glyphs.effectiveAdvance(g); + + return *si; +} + +bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const +{ + *selectionX = *selectionWidth = 0; + + if (!selection) + return false; + + if (si->analysis.flags >= QScriptAnalysis::TabOrObject) { + if (si->position >= selection->start + selection->length + || si->position + itemLength <= selection->start) + return false; + + *selectionX = x; + *selectionWidth = itemWidth; + } else { + unsigned short *logClusters = eng->logClusters(si); + QGlyphLayout glyphs = eng->shapedGlyphs(si); + + int from = qMax(itemStart, selection->start) - si->position; + int to = qMin(itemEnd, selection->start + selection->length) - si->position; + if (from >= to) + return false; + + int start_glyph = logClusters[from]; + int end_glyph = (to == eng->length(item)) ? si->num_glyphs : logClusters[to]; + QFixed soff; + QFixed swidth; + if (si->analysis.bidiLevel %2) { + for (int g = glyphsEnd - 1; g >= end_glyph; --g) + soff += glyphs.effectiveAdvance(g); + for (int g = end_glyph - 1; g >= start_glyph; --g) + swidth += glyphs.effectiveAdvance(g); + } else { + for (int g = glyphsStart; g < start_glyph; ++g) + soff += glyphs.effectiveAdvance(g); + for (int g = start_glyph; g < end_glyph; ++g) + swidth += glyphs.effectiveAdvance(g); + } + + // If the starting character is in the middle of a ligature, + // selection should only contain the right part of that ligature + // glyph, so we need to get the width of the left part here and + // add it to *selectionX + QFixed leftOffsetInLigature = eng->offsetInLigature(si, from, to, start_glyph); + *selectionX = x + soff + leftOffsetInLigature; + *selectionWidth = swidth - leftOffsetInLigature; + // If the ending character is also part of a ligature, swidth does + // not contain that part yet, we also need to find out the width of + // that left part + *selectionWidth += eng->offsetInLigature(si, to, eng->length(item), end_glyph); + } + return true; +} QT_END_NAMESPACE diff --git a/src/gui/text/qtextengine_mac.cpp b/src/gui/text/qtextengine_mac.cpp index 97e8c5b..2c6e579 100644 --- a/src/gui/text/qtextengine_mac.cpp +++ b/src/gui/text/qtextengine_mac.cpp @@ -605,11 +605,11 @@ void QTextEngine::shapeTextMac(int item) const unsigned short *log_clusters = logClusters(&si); bool stringToCMapFailed = false; - if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes())) { + if (!fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, attributes(), &si)) { ensureSpace(num_glyphs); g = availableGlyphs(&si); stringToCMapFailed = !fe->stringToCMap(str, len, &g, &num_glyphs, flags, log_clusters, - attributes()); + attributes(), &si); } if (!stringToCMapFailed) { diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 366c5c3..e06ca1c 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -64,6 +64,7 @@ #include "QtGui/qpaintengine.h" #include "QtGui/qtextobject.h" #include "QtGui/qtextoption.h" +#include "QtGui/qtextcursor.h" #include "QtCore/qset.h" #include "QtCore/qdebug.h" #ifndef QT_BUILD_COMPAT_LIB @@ -471,6 +472,7 @@ public: void shape(int item) const; void justify(const QScriptLine &si); + QFixed alignLine(const QScriptLine &line); QFixed width(int charFrom, int numChars) const; glyph_metrics_t boundingBox(int from, int len) const; @@ -586,12 +588,18 @@ public: uint cacheGlyphs : 1; uint stackEngine : 1; uint forceJustification : 1; + uint visualMovement : 1; int *underlinePositions; mutable LayoutData *layoutData; inline bool hasFormats() const { return (block.docHandle() || specialData); } + inline bool visualCursorMovement() const + { + return (visualMovement || + (block.docHandle() ? block.docHandle()->defaultCursorMoveStyle == Qt::VisualMoveStyle : false)); + } struct SpecialData { int preeditPosition; @@ -611,6 +619,13 @@ public: void shapeLine(const QScriptLine &line); QFixed leadingSpaceWidth(const QScriptLine &line); + QFixed offsetInLigature(const QScriptItem *si, int pos, int max, int glyph_pos); + int previousLogicalPosition(int oldPos) const; + int nextLogicalPosition(int oldPos) const; + int lineNumberForTextPosition(int pos); + int positionAfterVisualMovement(int oldPos, QTextCursor::MoveOperation op); + void insertionPointsForLine(int lineNum, QVector<int> &insertionPoints); + private: void setBoundary(int strPos) const; void addRequiredBoundaries() const; @@ -625,6 +640,8 @@ private: void splitItem(int item, int pos) const; void resolveAdditionalFormats() const; + int endOfLine(int lineNum); + int beginningOfLine(int lineNum); }; class QStackTextEngine : public QTextEngine { @@ -635,6 +652,49 @@ public: void *_memory[MemSize]; }; +struct QTextLineItemIterator +{ + QTextLineItemIterator(QTextEngine *eng, int lineNum, const QPointF &pos = QPointF(), + const QTextLayout::FormatRange *_selection = 0); + + inline bool atEnd() const { return logicalItem >= nItems - 1; } + inline bool atBeginning() const { return logicalItem <= 0; } + QScriptItem &next(); + + bool getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const; + inline bool isOutsideSelection() const { + QFixed tmp1, tmp2; + return !getSelectionBounds(&tmp1, &tmp2); + } + + QTextEngine *eng; + + QFixed x; + QFixed pos_x; + const QScriptLine &line; + QScriptItem *si; + + int lineNum; + int lineEnd; + int firstItem; + int lastItem; + int nItems; + int logicalItem; + int item; + int itemLength; + + int glyphsStart; + int glyphsEnd; + int itemStart; + int itemEnd; + + QFixed itemWidth; + + QVarLengthArray<int> visualOrder; + QVarLengthArray<uchar> levels; + + const QTextLayout::FormatRange *selection; +}; Q_DECLARE_OPERATORS_FOR_FLAGS(QTextEngine::ShaperFlags) diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index ff28eaa..4f4752a 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -378,7 +378,8 @@ public: AlignSubScript, AlignMiddle, AlignTop, - AlignBottom + AlignBottom, + AlignBaseline }; enum UnderlineStyle { // keep in sync with Qt::PenStyle! NoUnderline, diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 93f71d3..07aeb72 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -52,8 +52,8 @@ #include "qtextformat_p.h" #include "qstyleoption.h" #include "qpainterpath.h" -#include "qglyphs.h" -#include "qglyphs_p.h" +#include "qglyphrun.h" +#include "qglyphrun_p.h" #include "qrawfont.h" #include "qrawfont_p.h" #include <limits.h> @@ -72,23 +72,6 @@ QT_BEGIN_NAMESPACE #define SuppressText 0x5012 #define SuppressBackground 0x513 -static QFixed alignLine(QTextEngine *eng, const QScriptLine &line) -{ - QFixed x = 0; - eng->justify(line); - // if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned. - if (!line.justified && line.width != QFIXED_MAX) { - int align = eng->option.alignment(); - if (align & Qt::AlignJustify && eng->isRightToLeft()) - align = Qt::AlignRight; - if (align & Qt::AlignRight) - x = line.width - (line.textAdvance + eng->leadingSpaceWidth(line)); - else if (align & Qt::AlignHCenter) - x = (line.width - line.textAdvance)/2; - } - return x; -} - /*! \class QTextLayout::FormatRange \reentrant @@ -596,6 +579,30 @@ bool QTextLayout::cacheEnabled() const } /*! + Set the cursor movement style. If the QTextLayout is backed by + a document, you can ignore this and use the option in QTextDocument, + this option is for widgets like QLineEdit or custom widgets without + a QTextDocument. Default value is Qt::LogicalMoveStyle. + + \sa setCursorMoveStyle() +*/ +void QTextLayout::setCursorMoveStyle(Qt::CursorMoveStyle style) +{ + d->visualMovement = style == Qt::VisualMoveStyle ? true : false; +} + +/*! + The cursor movement style of this QTextLayout. The default is + Qt::LogicalMoveStyle. + + \sa setCursorMoveStyle() +*/ +Qt::CursorMoveStyle QTextLayout::cursorMoveStyle() const +{ + return d->visualMovement ? Qt::VisualMoveStyle : Qt::LogicalMoveStyle; +} + +/*! Begins the layout process. \sa endLayout() @@ -718,6 +725,34 @@ int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const } /*! + Returns the cursor position to the right of \a oldPos, next to it. + It's dependent on the visual position of characters, after bi-directional + reordering. + + \sa leftCursorPosition(), nextCursorPosition() +*/ +int QTextLayout::rightCursorPosition(int oldPos) const +{ + int newPos = d->positionAfterVisualMovement(oldPos, QTextCursor::Right); +// qDebug("%d -> %d", oldPos, newPos); + return newPos; +} + +/*! + Returns the cursor position to the left of \a oldPos, next to it. + It's dependent on the visual position of characters, after bi-directional + reordering. + + \sa rightCursorPosition(), previousCursorPosition() +*/ +int QTextLayout::leftCursorPosition(int oldPos) const +{ + int newPos = d->positionAfterVisualMovement(oldPos, QTextCursor::Left); +// qDebug("%d -> %d", oldPos, newPos); + return newPos; +} + +/*!/ Returns true if position \a pos is a valid cursor position. In a Unicode context some positions in the text are not valid @@ -815,16 +850,8 @@ QTextLine QTextLayout::lineAt(int i) const */ QTextLine QTextLayout::lineForTextPosition(int pos) const { - for (int i = 0; i < d->lines.size(); ++i) { - const QScriptLine& line = d->lines[i]; - if (line.from + (int)line.length > pos) - return QTextLine(i, d); - } - if (!d->layoutData) - d->itemize(); - if (pos == d->layoutData->string.length() && d->lines.size()) - return QTextLine(d->lines.size()-1, d); - return QTextLine(); + int lineNum = d->lineNumberForTextPosition(pos); + return lineNum >= 0 ? lineAt(lineNum) : QTextLine(); } /*! @@ -919,201 +946,6 @@ void QTextLayout::setFlags(int flags) } } -struct QTextLineItemIterator -{ - QTextLineItemIterator(QTextEngine *eng, int lineNum, const QPointF &pos = QPointF(), - const QTextLayout::FormatRange *_selection = 0); - - inline bool atEnd() const { return logicalItem >= nItems - 1; } - QScriptItem &next(); - - bool getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const; - inline bool isOutsideSelection() const { - QFixed tmp1, tmp2; - return !getSelectionBounds(&tmp1, &tmp2); - } - - QTextEngine *eng; - - QFixed x; - QFixed pos_x; - const QScriptLine &line; - QScriptItem *si; - - int lineEnd; - int firstItem; - int lastItem; - int nItems; - int logicalItem; - int item; - int itemLength; - - int glyphsStart; - int glyphsEnd; - int itemStart; - int itemEnd; - - QFixed itemWidth; - - QVarLengthArray<int> visualOrder; - QVarLengthArray<uchar> levels; - - const QTextLayout::FormatRange *selection; -}; - -QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int lineNum, const QPointF &pos, - const QTextLayout::FormatRange *_selection) - : eng(_eng), - line(eng->lines[lineNum]), - si(0), - lineEnd(line.from + line.length), - firstItem(eng->findItem(line.from)), - lastItem(eng->findItem(lineEnd - 1)), - nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0), - logicalItem(-1), - item(-1), - visualOrder(nItems), - levels(nItems), - selection(_selection) -{ - pos_x = x = QFixed::fromReal(pos.x()); - - x += line.x; - - x += alignLine(eng, line); - - for (int i = 0; i < nItems; ++i) - levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel; - QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data()); - - eng->shapeLine(line); -} - -QScriptItem &QTextLineItemIterator::next() -{ - x += itemWidth; - - ++logicalItem; - item = visualOrder[logicalItem] + firstItem; - itemLength = eng->length(item); - si = &eng->layoutData->items[item]; - if (!si->num_glyphs) - eng->shape(item); - - if (si->analysis.flags >= QScriptAnalysis::TabOrObject) { - itemWidth = si->width; - return *si; - } - - unsigned short *logClusters = eng->logClusters(si); - QGlyphLayout glyphs = eng->shapedGlyphs(si); - - itemStart = qMax(line.from, si->position); - glyphsStart = logClusters[itemStart - si->position]; - if (lineEnd < si->position + itemLength) { - itemEnd = lineEnd; - glyphsEnd = logClusters[itemEnd-si->position]; - } else { - itemEnd = si->position + itemLength; - glyphsEnd = si->num_glyphs; - } - // show soft-hyphen at line-break - if (si->position + itemLength >= lineEnd - && eng->layoutData->string.at(lineEnd - 1) == 0x00ad) - glyphs.attributes[glyphsEnd - 1].dontPrint = false; - - itemWidth = 0; - for (int g = glyphsStart; g < glyphsEnd; ++g) - itemWidth += glyphs.effectiveAdvance(g); - - return *si; -} - -static QFixed offsetInLigature(const unsigned short *logClusters, - const QGlyphLayout &glyphs, - int pos, int max, int glyph_pos) -{ - int offsetInCluster = 0; - for (int i = pos - 1; i >= 0; i--) { - if (logClusters[i] == glyph_pos) - offsetInCluster++; - else - break; - } - - // in the case that the offset is inside a (multi-character) glyph, - // interpolate the position. - if (offsetInCluster > 0) { - int clusterLength = 0; - for (int i = pos - offsetInCluster; i < max; i++) { - if (logClusters[i] == glyph_pos) - clusterLength++; - else - break; - } - if (clusterLength) - return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength; - } - - return 0; -} - -bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const -{ - *selectionX = *selectionWidth = 0; - - if (!selection) - return false; - - if (si->analysis.flags >= QScriptAnalysis::TabOrObject) { - if (si->position >= selection->start + selection->length - || si->position + itemLength <= selection->start) - return false; - - *selectionX = x; - *selectionWidth = itemWidth; - } else { - unsigned short *logClusters = eng->logClusters(si); - QGlyphLayout glyphs = eng->shapedGlyphs(si); - - int from = qMax(itemStart, selection->start) - si->position; - int to = qMin(itemEnd, selection->start + selection->length) - si->position; - if (from >= to) - return false; - - int start_glyph = logClusters[from]; - int end_glyph = (to == eng->length(item)) ? si->num_glyphs : logClusters[to]; - QFixed soff; - QFixed swidth; - if (si->analysis.bidiLevel %2) { - for (int g = glyphsEnd - 1; g >= end_glyph; --g) - soff += glyphs.effectiveAdvance(g); - for (int g = end_glyph - 1; g >= start_glyph; --g) - swidth += glyphs.effectiveAdvance(g); - } else { - for (int g = glyphsStart; g < start_glyph; ++g) - soff += glyphs.effectiveAdvance(g); - for (int g = start_glyph; g < end_glyph; ++g) - swidth += glyphs.effectiveAdvance(g); - } - - // If the starting character is in the middle of a ligature, - // selection should only contain the right part of that ligature - // glyph, so we need to get the width of the left part here and - // add it to *selectionX - QFixed leftOffsetInLigature = offsetInLigature(logClusters, glyphs, from, - to, start_glyph); - *selectionX = x + soff + leftOffsetInLigature; - *selectionWidth = swidth - leftOffsetInLigature; - // If the ending character is also part of a ligature, swidth does - // not contain that part yet, we also need to find out the width of - // that left part - *selectionWidth += offsetInLigature(logClusters, glyphs, to, - eng->length(item), end_glyph); - } - return true; -} - static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPointF &pos, QTextLayout::FormatRange *selection, QPainterPath *region, QRectF boundingRect) { @@ -1162,12 +994,12 @@ static inline QRectF clipIfValid(const QRectF &rect, const QRectF &clip) \since 4.8 - \sa draw(), QPainter::drawGlyphs() + \sa draw(), QPainter::drawGlyphRun() */ #if !defined(QT_NO_RAWFONT) -QList<QGlyphs> QTextLayout::glyphs() const +QList<QGlyphRun> QTextLayout::glyphRuns() const { - QList<QGlyphs> glyphs; + QList<QGlyphRun> glyphs; for (int i=0; i<d->lines.size(); ++i) glyphs += QTextLine(i, d).glyphs(-1, -1); @@ -1228,6 +1060,7 @@ void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVector<FormatRang QRectF lineRect(tl.naturalTextRect()); lineRect.translate(position); + lineRect.adjust(0, 0, d->leadingSpaceWidth(sl).toReal(), 0); bool isLastLineInBlock = (line == d->lines.size()-1); int sl_length = sl.length + (isLastLineInBlock? 1 : 0); // the infamous newline @@ -1378,22 +1211,11 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition d->itemize(); QPointF position = pos + d->position; - QFixed pos_x = QFixed::fromReal(position.x()); - QFixed pos_y = QFixed::fromReal(position.y()); cursorPosition = qBound(0, cursorPosition, d->layoutData->string.length()); - int line = 0; - if (cursorPosition == d->layoutData->string.length()) { - line = d->lines.size() - 1; - } else { - // ### binary search - for (line = 0; line < d->lines.size(); line++) { - const QScriptLine &sl = d->lines[line]; - if (sl.from <= cursorPosition && sl.from + (int)sl.length > cursorPosition) - break; - } - } - + int line = d->lineNumberForTextPosition(cursorPosition); + if (line < 0) + line = 0; if (line >= d->lines.size()) return; @@ -1402,7 +1224,15 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition qreal x = position.x() + l.cursorToX(cursorPosition); - int itm = d->findItem(cursorPosition - 1); + int itm; + + if (d->visualCursorMovement()) { + if (cursorPosition == sl.from + sl.length) + cursorPosition--; + itm = d->findItem(cursorPosition); + } else + itm = d->findItem(cursorPosition - 1); + QFixed base = sl.base(); QFixed descent = sl.descent; bool rightToLeft = d->isRightToLeft(); @@ -1512,7 +1342,7 @@ QRectF QTextLine::rect() const QRectF QTextLine::naturalTextRect() const { const QScriptLine& sl = eng->lines[i]; - QFixed x = sl.x + alignLine(eng, sl); + QFixed x = sl.x + eng->alignLine(sl); QFixed width = sl.textWidth; if (sl.justified) @@ -2263,15 +2093,15 @@ namespace { \since 4.8 - \sa QTextLayout::glyphs() + \sa QTextLayout::glyphRuns() */ #if !defined(QT_NO_RAWFONT) -QList<QGlyphs> QTextLine::glyphs(int from, int length) const +QList<QGlyphRun> QTextLine::glyphs(int from, int length) const { const QScriptLine &line = eng->lines[i]; if (line.length == 0) - return QList<QGlyphs>(); + return QList<QGlyphRun>(); QHash<QFontEngine *, GlyphInfo> glyphLayoutHash; @@ -2317,6 +2147,9 @@ QList<QGlyphs> QTextLine::glyphs(int from, int length) const QGlyphLayout subLayout = glyphLayout.mid(start, end - start); glyphLayoutHash.insertMulti(multiFontEngine->engine(which), GlyphInfo(subLayout, pos, flags)); + for (int i = 0; i < subLayout.numGlyphs; i++) + pos += QPointF(subLayout.advances_x[i].toReal(), + subLayout.advances_y[i].toReal()); start = end; which = e; @@ -2333,7 +2166,7 @@ QList<QGlyphs> QTextLine::glyphs(int from, int length) const } } - QHash<QPair<QFontEngine *, int>, QGlyphs> glyphsHash; + QHash<QPair<QFontEngine *, int>, QGlyphRun> glyphsHash; QList<QFontEngine *> keys = glyphLayoutHash.uniqueKeys(); for (int i=0; i<keys.size(); ++i) { @@ -2390,14 +2223,14 @@ QList<QGlyphs> QTextLine::glyphs(int from, int length) const positions.append(positionsArray.at(i).toPointF() + pos); } - QGlyphs glyphIndexes; + QGlyphRun glyphIndexes; glyphIndexes.setGlyphIndexes(glyphs); glyphIndexes.setPositions(positions); glyphIndexes.setOverline(flags.testFlag(QTextItem::Overline)); glyphIndexes.setUnderline(flags.testFlag(QTextItem::Underline)); glyphIndexes.setStrikeOut(flags.testFlag(QTextItem::StrikeOut)); - glyphIndexes.setFont(font); + glyphIndexes.setRawFont(font); QPair<QFontEngine *, int> key(fontEngine, int(flags)); if (!glyphsHash.contains(key)) @@ -2632,9 +2465,10 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const eng->itemize(); const QScriptLine &line = eng->lines[i]; + bool lastLine = i >= eng->lines.size() - 1; QFixed x = line.x; - x += alignLine(eng, line); + x += eng->alignLine(line); if (!i && !eng->layoutData->items.size()) { *cursorPos = 0; @@ -2720,21 +2554,29 @@ qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const logClusters = eng->logClusters(si); glyphs = eng->shapedGlyphs(si); if (si->analysis.flags >= QScriptAnalysis::TabOrObject) { - if(pos == l) + if (pos == (reverse ? 0 : l)) x += si->width; } else { + bool rtl = eng->isRightToLeft(); + bool visual = eng->visualCursorMovement(); if (reverse) { int end = qMin(lineEnd, si->position + l) - si->position; int glyph_end = end == l ? si->num_glyphs : logClusters[end]; - for (int i = glyph_end - 1; i >= glyph_pos; i--) + int glyph_start = glyph_pos; + if (visual && !rtl && !(lastLine && itm == (visualOrder[nItems - 1] + firstItem))) + glyph_start++; + for (int i = glyph_end - 1; i >= glyph_start; i--) x += glyphs.effectiveAdvance(i); } else { int start = qMax(line.from - si->position, 0); int glyph_start = logClusters[start]; - for (int i = glyph_start; i < glyph_pos; i++) + int glyph_end = glyph_pos; + if (!visual || !rtl || (lastLine && itm == visualOrder[0] + firstItem)) + glyph_end--; + for (int i = glyph_start; i <= glyph_end; i++) x += glyphs.effectiveAdvance(i); } - x += offsetInLigature(logClusters, glyphs, pos, line.length, glyph_pos); + x += eng->offsetInLigature(si, pos, line.length, glyph_pos); } *cursorPos = pos + si->position; @@ -2753,6 +2595,8 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const { QFixed x = QFixed::fromReal(_x); const QScriptLine &line = eng->lines[i]; + bool lastLine = i >= eng->lines.size() - 1; + int lineNum = i; if (!eng->layoutData) eng->itemize(); @@ -2770,7 +2614,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const return 0; x -= line.x; - x -= alignLine(eng, line); + x -= eng->alignLine(line); // qDebug("xToCursor: x=%f, cpos=%d", x.toReal(), cpos); QVarLengthArray<int> visualOrder(nItems); @@ -2779,6 +2623,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel; QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data()); + bool visual = eng->visualCursorMovement(); if (x <= 0) { // left of first item int item = visualOrder[0]+firstItem; @@ -2795,8 +2640,13 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const || (line.justified && x < line.width)) { // has to be in one of the runs QFixed pos; + bool rtl = eng->isRightToLeft(); eng->shapeLine(line); + QVector<int> insertionPoints; + if (visual && rtl) + eng->insertionPointsForLine(lineNum, insertionPoints); + int nchars = 0; for (int i = 0; i < nItems; ++i) { int item = visualOrder[i]+firstItem; QScriptItem &si = eng->layoutData->items[item]; @@ -2826,6 +2676,7 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const if (pos + item_width < x) { pos += item_width; + nchars += end; continue; } // qDebug(" inside run"); @@ -2870,27 +2721,60 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const } else { QFixed dist = INT_MAX/256; if (si.analysis.bidiLevel % 2) { - pos += item_width; - while (gs <= ge) { - if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) { - glyph_pos = gs; - dist = qAbs(x-pos); + if (!visual || rtl || (lastLine && i == nItems - 1)) { + pos += item_width; + while (gs <= ge) { + if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) { + glyph_pos = gs; + dist = qAbs(x-pos); + } + pos -= glyphs.effectiveAdvance(gs); + ++gs; + } + } else { + while (ge >= gs) { + if (glyphs.attributes[ge].clusterStart && qAbs(x-pos) < dist) { + glyph_pos = ge; + dist = qAbs(x-pos); + } + pos += glyphs.effectiveAdvance(ge); + --ge; } - pos -= glyphs.effectiveAdvance(gs); - ++gs; } } else { - while (gs <= ge) { - if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) { - glyph_pos = gs; - dist = qAbs(x-pos); + if (!visual || !rtl || (lastLine && i == 0)) { + while (gs <= ge) { + if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) { + glyph_pos = gs; + dist = qAbs(x-pos); + } + pos += glyphs.effectiveAdvance(gs); + ++gs; } - pos += glyphs.effectiveAdvance(gs); - ++gs; + } else { + QFixed oldPos = pos; + while (gs <= ge) { + pos += glyphs.effectiveAdvance(gs); + if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) { + glyph_pos = gs; + dist = qAbs(x-pos); + } + ++gs; + } + pos = oldPos; } } - if (qAbs(x-pos) < dist) + if (qAbs(x-pos) < dist) { + if (visual) { + if (!rtl && i < nItems - 1) { + nchars += end; + continue; + } + if (rtl && nchars > 0) + return insertionPoints[lastLine ? nchars : nchars - 1]; + } return si.position + end; + } } Q_ASSERT(glyph_pos != -1); int j; diff --git a/src/gui/text/qtextlayout.h b/src/gui/text/qtextlayout.h index 9dd8ebd..89fbfb2 100644 --- a/src/gui/text/qtextlayout.h +++ b/src/gui/text/qtextlayout.h @@ -49,7 +49,8 @@ #include <QtCore/qobject.h> #include <QtGui/qevent.h> #include <QtGui/qtextformat.h> -#include <QtGui/qglyphs.h> +#include <QtGui/qglyphrun.h> +#include <QtGui/qtextcursor.h> QT_BEGIN_HEADER @@ -136,6 +137,9 @@ public: void setCacheEnabled(bool enable); bool cacheEnabled() const; + void setCursorMoveStyle(Qt::CursorMoveStyle style); + Qt::CursorMoveStyle cursorMoveStyle() const; + void beginLayout(); void endLayout(); void clearLayout(); @@ -153,6 +157,8 @@ public: bool isValidCursorPosition(int pos) const; int nextCursorPosition(int oldPos, CursorMode mode = SkipCharacters) const; int previousCursorPosition(int oldPos, CursorMode mode = SkipCharacters) const; + int leftCursorPosition(int oldPos) const; + int rightCursorPosition(int oldPos) const; void draw(QPainter *p, const QPointF &pos, const QVector<FormatRange> &selections = QVector<FormatRange>(), const QRectF &clip = QRectF()) const; @@ -168,7 +174,7 @@ public: qreal maximumWidth() const; #if !defined(QT_NO_RAWFONT) - QList<QGlyphs> glyphs() const; + QList<QGlyphRun> glyphRuns() const; #endif QTextEngine *engine() const { return d; } @@ -243,7 +249,7 @@ private: void layout_helper(int numGlyphs); #if !defined(QT_NO_RAWFONT) - QList<QGlyphs> glyphs(int from, int length) const; + QList<QGlyphRun> glyphs(int from, int length) const; #endif friend class QTextLayout; diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index 5c1c8b9..b7e05d2 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -891,11 +891,6 @@ QTextBlockUserData::~QTextBlockUserData() Returns true if this text block is valid; otherwise returns false. */ -bool QTextBlock::isValid() const -{ - return p != 0 && p->blockMap().isValid(n); -} - /*! \fn QTextBlock &QTextBlock::operator=(const QTextBlock &other) @@ -1493,7 +1488,7 @@ QTextBlock::iterator QTextBlock::end() const */ QTextBlock QTextBlock::next() const { - if (!isValid()) + if (!isValid() || !p->blockMap().isValid(n)) return QTextBlock(); return QTextBlock(p, p->blockMap().next(n)); @@ -1664,25 +1659,25 @@ QTextBlock::iterator &QTextBlock::iterator::operator--() Returns the glyphs of this text fragment. The positions of the glyphs are relative to the position of the QTextBlock's layout. - \sa QGlyphs, QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphs() + \sa QGlyphRun, QTextBlock::layout(), QTextLayout::position(), QPainter::drawGlyphRun() */ #if !defined(QT_NO_RAWFONT) -QList<QGlyphs> QTextFragment::glyphs() const +QList<QGlyphRun> QTextFragment::glyphRuns() const { if (!p || !n) - return QList<QGlyphs>(); + return QList<QGlyphRun>(); int pos = position(); int len = length(); if (len == 0) - return QList<QGlyphs>(); + return QList<QGlyphRun>(); int blockNode = p->blockMap().findNode(pos); const QTextBlockData *blockData = p->blockMap().fragment(blockNode); QTextLayout *layout = blockData->layout; - QList<QGlyphs> ret; + QList<QGlyphRun> ret; for (int i=0; i<layout->lineCount(); ++i) { QTextLine textLine = layout->lineAt(i); ret += textLine.glyphs(pos, len); diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h index ad8e657..a443e79 100644 --- a/src/gui/text/qtextobject.h +++ b/src/gui/text/qtextobject.h @@ -44,7 +44,7 @@ #include <QtCore/qobject.h> #include <QtGui/qtextformat.h> -#include <QtGui/qglyphs.h> +#include <QtGui/qglyphrun.h> QT_BEGIN_HEADER @@ -205,7 +205,7 @@ public: inline QTextBlock(const QTextBlock &o) : p(o.p), n(o.n) {} inline QTextBlock &operator=(const QTextBlock &o) { p = o.p; n = o.n; return *this; } - bool isValid() const; + inline bool isValid() const { return p != 0 && n != 0; } inline bool operator==(const QTextBlock &o) const { return p == o.p && n == o.n; } inline bool operator!=(const QTextBlock &o) const { return p != o.p || n != o.n; } @@ -317,7 +317,7 @@ public: QString text() const; #if !defined(QT_NO_RAWFONT) - QList<QGlyphs> glyphs() const; + QList<QGlyphRun> glyphRuns() const; #endif private: diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index df9398c..b6cdc52 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -40,10 +40,10 @@ HEADERS += \ text/qtextodfwriter_p.h \ text/qstatictext_p.h \ text/qstatictext.h \ - text/qglyphs.h \ - text/qglyphs_p.h \ text/qrawfont.h \ - text/qrawfont_p.h + text/qrawfont_p.h \ + text/qglyphrun.h \ + text/qglyphrun_p.h SOURCES += \ text/qfont.cpp \ @@ -74,8 +74,8 @@ SOURCES += \ text/qzip.cpp \ text/qtextodfwriter.cpp \ text/qstatictext.cpp \ - text/qglyphs.cpp \ - text/qrawfont.cpp + text/qrawfont.cpp \ + text/qglyphrun.cpp win32 { SOURCES += \ @@ -114,6 +114,9 @@ unix:x11 { OBJECTIVE_SOURCES += \ text/qfontengine_coretext.mm \ text/qfontengine_mac.mm + contains(QT_CONFIG, harfbuzz) { + DEFINES += QT_ENABLE_HARFBUZZ_FOR_MAC + } } embedded { @@ -136,7 +139,8 @@ qpa { SOURCES += \ text/qfont_qpa.cpp \ text/qfontengine_qpa.cpp \ - text/qplatformfontdatabase_qpa.cpp + text/qplatformfontdatabase_qpa.cpp \ + text/qrawfont_qpa.cpp HEADERS += \ text/qplatformfontdatabase_qpa.h diff --git a/src/gui/util/qflickgesture.cpp b/src/gui/util/qflickgesture.cpp deleted file mode 100644 index fdd2a95..0000000 --- a/src/gui/util/qflickgesture.cpp +++ /dev/null @@ -1,715 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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 "qgesture.h" -#include "qapplication.h" -#include "qevent.h" -#include "qwidget.h" -#include "qgraphicsitem.h" -#include "qgraphicsscene.h" -#include "qgraphicssceneevent.h" -#include "qgraphicsview.h" -#include "qscroller.h" -#include "private/qevent_p.h" -#include "private/qflickgesture_p.h" -#include "qdebug.h" - -#ifndef QT_NO_GESTURES - -QT_BEGIN_NAMESPACE - -//#define QFLICKGESTURE_DEBUG - -#ifdef QFLICKGESTURE_DEBUG -# define qFGDebug qDebug -#else -# define qFGDebug while (false) qDebug -#endif - -extern bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); - -static QMouseEvent *copyMouseEvent(QEvent *e) -{ - switch (e->type()) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseMove: { - QMouseEvent *me = static_cast<QMouseEvent *>(e); - return new QMouseEvent(me->type(), QPoint(0, 0), me->globalPos(), me->button(), me->buttons(), me->modifiers()); - } -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMousePress: - case QEvent::GraphicsSceneMouseRelease: - case QEvent::GraphicsSceneMouseMove: { - QGraphicsSceneMouseEvent *me = static_cast<QGraphicsSceneMouseEvent *>(e); -#if 1 - QEvent::Type met = me->type() == QEvent::GraphicsSceneMousePress ? QEvent::MouseButtonPress : - (me->type() == QEvent::GraphicsSceneMouseRelease ? QEvent::MouseButtonRelease : QEvent::MouseMove); - return new QMouseEvent(met, QPoint(0, 0), me->screenPos(), me->button(), me->buttons(), me->modifiers()); -#else - QGraphicsSceneMouseEvent *copy = new QGraphicsSceneMouseEvent(me->type()); - copy->setPos(me->pos()); - copy->setScenePos(me->scenePos()); - copy->setScreenPos(me->screenPos()); - for (int i = 0x1; i <= 0x10; i <<= 1) { - Qt::MouseButton button = Qt::MouseButton(i); - copy->setButtonDownPos(button, me->buttonDownPos(button)); - copy->setButtonDownScenePos(button, me->buttonDownScenePos(button)); - copy->setButtonDownScreenPos(button, me->buttonDownScreenPos(button)); - } - copy->setLastPos(me->lastPos()); - copy->setLastScenePos(me->lastScenePos()); - copy->setLastScreenPos(me->lastScreenPos()); - copy->setButtons(me->buttons()); - copy->setButton(me->button()); - copy->setModifiers(me->modifiers()); - return copy; -#endif - } -#endif // QT_NO_GRAPHICSVIEW - default: - return 0; - } -} - -class PressDelayHandler : public QObject -{ -private: - PressDelayHandler(QObject *parent = 0) - : QObject(parent) - , pressDelayTimer(0) - , sendingEvent(false) - , mouseButton(Qt::NoButton) - , mouseTarget(0) - { } - - static PressDelayHandler *inst; - -public: - enum { - UngrabMouseBefore = 1, - RegrabMouseAfterwards = 2 - }; - - static PressDelayHandler *instance() - { - static PressDelayHandler *inst = 0; - if (!inst) - inst = new PressDelayHandler(QCoreApplication::instance()); - return inst; - } - - bool shouldEventBeIgnored(QEvent *) const - { - return sendingEvent; - } - - bool isDelaying() const - { - return !pressDelayEvent.isNull(); - } - - void pressed(QEvent *e, int delay) - { - if (!pressDelayEvent) { - pressDelayEvent.reset(copyMouseEvent(e)); - pressDelayTimer = startTimer(delay); - mouseTarget = QApplication::widgetAt(pressDelayEvent->globalPos()); - mouseButton = pressDelayEvent->button(); - qFGDebug() << "QFG: consuming/delaying mouse press"; - } else { - qFGDebug() << "QFG: NOT consuming/delaying mouse press"; - } - e->setAccepted(true); - } - - bool released(QEvent *e, bool scrollerWasActive, bool scrollerIsActive) - { - // consume this event if the scroller was or is active - bool result = scrollerWasActive || scrollerIsActive; - - // stop the timer - if (pressDelayTimer) { - killTimer(pressDelayTimer); - pressDelayTimer = 0; - } - // we still haven't even sent the press, so do it now - if (pressDelayEvent && mouseTarget && !scrollerIsActive) { - QScopedPointer<QMouseEvent> releaseEvent(copyMouseEvent(e)); - - qFGDebug() << "QFG: re-sending mouse press (due to release) for " << mouseTarget; - sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore); - - qFGDebug() << "QFG: faking mouse release (due to release) for " << mouseTarget; - sendMouseEvent(releaseEvent.data()); - - result = true; // consume this event - } else if (mouseTarget && scrollerIsActive) { - // we grabbed the mouse expicitly when the scroller became active, so undo that now - sendMouseEvent(0, UngrabMouseBefore); - } - pressDelayEvent.reset(0); - mouseTarget = 0; - return result; - } - - void scrollerWasIntercepted() - { - qFGDebug() << "QFG: deleting delayed mouse press, since scroller was only intercepted"; - if (pressDelayEvent) { - // we still haven't even sent the press, so just throw it away now - if (pressDelayTimer) { - killTimer(pressDelayTimer); - pressDelayTimer = 0; - } - pressDelayEvent.reset(0); - } - mouseTarget = 0; - } - - void scrollerBecameActive() - { - if (pressDelayEvent) { - // we still haven't even sent the press, so just throw it away now - qFGDebug() << "QFG: deleting delayed mouse press, since scroller is active now"; - if (pressDelayTimer) { - killTimer(pressDelayTimer); - pressDelayTimer = 0; - } - pressDelayEvent.reset(0); - mouseTarget = 0; - } else if (mouseTarget) { - // we did send a press, so we need to fake a release now - Qt::MouseButtons mouseButtons = QApplication::mouseButtons(); - - // release all pressed mouse buttons - /*for (int i = 0; i < 32; ++i) { - if (mouseButtons & (1 << i)) { - Qt::MouseButton b = static_cast<Qt::MouseButton>(1 << i); - mouseButtons &= ~b; - QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX); - - qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget; - QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway, - b, mouseButtons, QApplication::keyboardModifiers()); - sendMouseEvent(&re); - } - }*/ - - QPoint farFarAway(-QWIDGETSIZE_MAX, -QWIDGETSIZE_MAX); - - qFGDebug() << "QFG: sending a fake mouse release at far-far-away to " << mouseTarget; - QMouseEvent re(QEvent::MouseButtonRelease, QPoint(), farFarAway, - mouseButton, QApplication::mouseButtons() & ~mouseButton, - QApplication::keyboardModifiers()); - sendMouseEvent(&re, RegrabMouseAfterwards); - // don't clear the mouseTarget just yet, since we need to explicitly ungrab the mouse on release! - } - } - -protected: - void timerEvent(QTimerEvent *e) - { - if (e->timerId() == pressDelayTimer) { - if (pressDelayEvent && mouseTarget) { - qFGDebug() << "QFG: timer event: re-sending mouse press to " << mouseTarget; - sendMouseEvent(pressDelayEvent.data(), UngrabMouseBefore); - } - pressDelayEvent.reset(0); - - if (pressDelayTimer) { - killTimer(pressDelayTimer); - pressDelayTimer = 0; - } - } - } - - void sendMouseEvent(QMouseEvent *me, int flags = 0) - { - if (mouseTarget) { - sendingEvent = true; - -#ifndef QT_NO_GRAPHICSVIEW - QGraphicsItem *grabber = 0; - if (mouseTarget->parentWidget()) { - if (QGraphicsView *gv = qobject_cast<QGraphicsView *>(mouseTarget->parentWidget())) { - if (gv->scene()) - grabber = gv->scene()->mouseGrabberItem(); - } - } - - if (grabber && (flags & UngrabMouseBefore)) { - // GraphicsView Mouse Handling Workaround #1: - // we need to ungrab the mouse before re-sending the press, - // since the scene had already set the mouse grabber to the - // original (and consumed) event's receiver - qFGDebug() << "QFG: ungrabbing" << grabber; - grabber->ungrabMouse(); - } -#endif // QT_NO_GRAPHICSVIEW - - if (me) { - QMouseEvent copy(me->type(), mouseTarget->mapFromGlobal(me->globalPos()), me->globalPos(), me->button(), me->buttons(), me->modifiers()); - qt_sendSpontaneousEvent(mouseTarget, ©); - } - -#ifndef QT_NO_GRAPHICSVIEW - if (grabber && (flags & RegrabMouseAfterwards)) { - // GraphicsView Mouse Handling Workaround #2: - // we need to re-grab the mouse after sending a faked mouse - // release, since we still need the mouse moves for the gesture - // (the scene will clear the item's mouse grabber status on - // release). - qFGDebug() << "QFG: re-grabbing" << grabber; - grabber->grabMouse(); - } -#endif - sendingEvent = false; - } - } - - -private: - int pressDelayTimer; - QScopedPointer<QMouseEvent> pressDelayEvent; - bool sendingEvent; - Qt::MouseButton mouseButton; - QPointer<QWidget> mouseTarget; -}; - - -/*! - \internal - \class QFlickGesture - \since 4.8 - \brief The QFlickGesture class describes a flicking gesture made by the user. - \ingroup gestures - The QFlickGesture is more complex than the QPanGesture that uses QScroller and QScrollerProperties - to decide if it is triggered. - This gesture is reacting on touch event as compared to the QMouseFlickGesture. - - \sa {Gestures Programming}, QScroller, QScrollerProperties, QMouseFlickGesture -*/ - -/*! - \internal -*/ -QFlickGesture::QFlickGesture(QObject *receiver, Qt::MouseButton button, QObject *parent) - : QGesture(*new QFlickGesturePrivate, parent) -{ - d_func()->q_ptr = this; - d_func()->receiver = receiver; - d_func()->receiverScroller = (receiver && QScroller::hasScroller(receiver)) ? QScroller::scroller(receiver) : 0; - d_func()->button = button; -} - -QFlickGesture::~QFlickGesture() -{ } - -QFlickGesturePrivate::QFlickGesturePrivate() - : receiverScroller(0), button(Qt::NoButton), macIgnoreWheel(false) -{ } - - -// -// QFlickGestureRecognizer -// - - -QFlickGestureRecognizer::QFlickGestureRecognizer(Qt::MouseButton button) -{ - this->button = button; -} - -/*! \reimp - */ -QGesture *QFlickGestureRecognizer::create(QObject *target) -{ -#ifndef QT_NO_GRAPHICSVIEW - QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target); - if (go && button == Qt::NoButton) { - go->setAcceptTouchEvents(true); - } -#endif - return new QFlickGesture(target, button); -} - -/*! \internal - The recognize function detects a touch event suitable to start the attached QScroller. - The QFlickGesture will be triggered as soon as the scroller is no longer in the state - QScroller::Inactive or QScroller::Pressed. It will be finished or canceled - at the next QEvent::TouchEnd. - Note that the QScroller might continue scrolling (kinetically) at this point. - */ -QGestureRecognizer::Result QFlickGestureRecognizer::recognize(QGesture *state, - QObject *watched, - QEvent *event) -{ - Q_UNUSED(watched); - - static QElapsedTimer monotonicTimer; - if (!monotonicTimer.isValid()) - monotonicTimer.start(); - - QFlickGesture *q = static_cast<QFlickGesture *>(state); - QFlickGesturePrivate *d = q->d_func(); - - QScroller *scroller = d->receiverScroller; - if (!scroller) - return Ignore; // nothing to do without a scroller? - - QWidget *receiverWidget = qobject_cast<QWidget *>(d->receiver); -#ifndef QT_NO_GRAPHICSVIEW - QGraphicsObject *receiverGraphicsObject = qobject_cast<QGraphicsObject *>(d->receiver); -#endif - - // this is only set for events that we inject into the event loop via sendEvent() - if (PressDelayHandler::instance()->shouldEventBeIgnored(event)) { - //qFGDebug() << state << "QFG: ignored event: " << event->type(); - return Ignore; - } - - const QMouseEvent *me = 0; -#ifndef QT_NO_GRAPHICSVIEW - const QGraphicsSceneMouseEvent *gsme = 0; -#endif - const QTouchEvent *te = 0; - QPoint globalPos; - - // qFGDebug() << "FlickGesture "<<state<<"watched:"<<watched<<"receiver"<<d->receiver<<"event"<<event->type()<<"button"<<button; - - switch (event->type()) { - case QEvent::MouseButtonPress: - case QEvent::MouseButtonRelease: - case QEvent::MouseMove: - if (!receiverWidget) - return Ignore; - if (button != Qt::NoButton) { - me = static_cast<const QMouseEvent *>(event); - globalPos = me->globalPos(); - } - break; -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMousePress: - case QEvent::GraphicsSceneMouseRelease: - case QEvent::GraphicsSceneMouseMove: - if (!receiverGraphicsObject) - return Ignore; - if (button != Qt::NoButton) { - gsme = static_cast<const QGraphicsSceneMouseEvent *>(event); - globalPos = gsme->screenPos(); - } - break; -#endif - case QEvent::TouchBegin: - case QEvent::TouchEnd: - case QEvent::TouchUpdate: - if (button == Qt::NoButton) { - te = static_cast<const QTouchEvent *>(event); - if (!te->touchPoints().isEmpty()) - globalPos = te->touchPoints().at(0).screenPos().toPoint(); - } - break; - -#if defined(Q_WS_MAC) - // the only way to distinguish between real mouse wheels and wheel - // events generated by the native 2 finger swipe gesture is to listen - // for these events (according to Apple's Cocoa Event-Handling Guide) - - case QEvent::NativeGesture: { - QNativeGestureEvent *nge = static_cast<QNativeGestureEvent *>(event); - if (nge->gestureType == QNativeGestureEvent::GestureBegin) - d->macIgnoreWheel = true; - else if (nge->gestureType == QNativeGestureEvent::GestureEnd) - d->macIgnoreWheel = false; - break; - } -#endif - - // consume all wheel events if the scroller is active - case QEvent::Wheel: - if (d->macIgnoreWheel || (scroller->state() != QScroller::Inactive)) - return Ignore | ConsumeEventHint; - break; - - // consume all dbl click events if the scroller is active - case QEvent::MouseButtonDblClick: - if (scroller->state() != QScroller::Inactive) - return Ignore | ConsumeEventHint; - break; - - default: - break; - } - - if (!me -#ifndef QT_NO_GRAPHICSVIEW - && !gsme -#endif - && !te) // Neither mouse nor touch - return Ignore; - - // get the current pointer position in local coordinates. - QPointF point; - QScroller::Input inputType = (QScroller::Input) 0; - - switch (event->type()) { - case QEvent::MouseButtonPress: - if (me && me->button() == button && me->buttons() == button) { - point = me->globalPos(); - inputType = QScroller::InputPress; - } else if (me) { - scroller->stop(); - return CancelGesture; - } - break; - case QEvent::MouseButtonRelease: - if (me && me->button() == button) { - point = me->globalPos(); - inputType = QScroller::InputRelease; - } - break; - case QEvent::MouseMove: -#ifdef Q_OS_SYMBIAN - // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix - // relies on the windowing system to report the current buttons state. - if (me && (me->buttons() == button || !me->buttons())) { -#else - if (me && me->buttons() == button) { -#endif - point = me->globalPos(); - inputType = QScroller::InputMove; - } - break; - -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMousePress: - if (gsme && gsme->button() == button && gsme->buttons() == button) { - point = gsme->scenePos(); - inputType = QScroller::InputPress; - } else if (gsme) { - scroller->stop(); - return CancelGesture; - } - break; - case QEvent::GraphicsSceneMouseRelease: - if (gsme && gsme->button() == button) { - point = gsme->scenePos(); - inputType = QScroller::InputRelease; - } - break; - case QEvent::GraphicsSceneMouseMove: -#ifdef Q_OS_SYMBIAN - // Qt on Symbian tracks the button state internally, while Qt on Win/Mac/Unix - // relies on the windowing system to report the current buttons state. - if (gsme && (gsme->buttons() == button || !me->buttons())) { -#else - if (gsme && gsme->buttons() == button) { -#endif - point = gsme->scenePos(); - inputType = QScroller::InputMove; - } - break; -#endif - - case QEvent::TouchBegin: - inputType = QScroller::InputPress; - // fall through - case QEvent::TouchEnd: - if (!inputType) - inputType = QScroller::InputRelease; - // fallthrough - case QEvent::TouchUpdate: - if (!inputType) - inputType = QScroller::InputMove; - - if (te->deviceType() == QTouchEvent::TouchPad) { - if (te->touchPoints().count() != 2) // 2 fingers on pad - return Ignore; - - point = te->touchPoints().at(0).startScenePos() + - ((te->touchPoints().at(0).scenePos() - te->touchPoints().at(0).startScenePos()) + - (te->touchPoints().at(1).scenePos() - te->touchPoints().at(1).startScenePos())) / 2; - } else { // TouchScreen - if (te->touchPoints().count() != 1) // 1 finger on screen - return Ignore; - - point = te->touchPoints().at(0).scenePos(); - } - break; - - default: - break; - } - - // Check for an active scroller at globalPos - if (inputType == QScroller::InputPress) { - foreach (QScroller *as, QScroller::activeScrollers()) { - if (as != scroller) { - QRegion scrollerRegion; - - if (QWidget *w = qobject_cast<QWidget *>(as->target())) { - scrollerRegion = QRect(w->mapToGlobal(QPoint(0, 0)), w->size()); -#ifndef QT_NO_GRAPHICSVIEW - } else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(as->target())) { - if (go->scene() && !go->scene()->views().isEmpty()) { - foreach (QGraphicsView *gv, go->scene()->views()) - scrollerRegion |= gv->mapFromScene(go->mapToScene(go->boundingRect())) - .translated(gv->mapToGlobal(QPoint(0, 0))); - } -#endif - } - // active scrollers always have priority - if (scrollerRegion.contains(globalPos)) - return Ignore; - } - } - } - - bool scrollerWasDragging = (scroller->state() == QScroller::Dragging); - bool scrollerWasScrolling = (scroller->state() == QScroller::Scrolling); - - if (inputType) { - if (QWidget *w = qobject_cast<QWidget *>(d->receiver)) - point = w->mapFromGlobal(point.toPoint()); -#ifndef QT_NO_GRAPHICSVIEW - else if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(d->receiver)) - point = go->mapFromScene(point); -#endif - - // inform the scroller about the new event - scroller->handleInput(inputType, point, monotonicTimer.elapsed()); - } - - // depending on the scroller state return the gesture state - Result result(0); - bool scrollerIsActive = (scroller->state() == QScroller::Dragging || - scroller->state() == QScroller::Scrolling); - - // Consume all mouse events while dragging or scrolling to avoid nasty - // side effects with Qt's standard widgets. - if ((me -#ifndef QT_NO_GRAPHICSVIEW - || gsme -#endif - ) && scrollerIsActive) - result |= ConsumeEventHint; - - // The only problem with this approach is that we consume the - // MouseRelease when we start the scrolling with a flick gesture, so we - // have to fake a MouseRelease "somewhere" to not mess with the internal - // states of Qt's widgets (a QPushButton would stay in 'pressed' state - // forever, if it doesn't receive a MouseRelease). - if (me -#ifndef QT_NO_GRAPHICSVIEW - || gsme -#endif - ) { - if (!scrollerWasDragging && !scrollerWasScrolling && scrollerIsActive) - PressDelayHandler::instance()->scrollerBecameActive(); - else if (scrollerWasScrolling && (scroller->state() == QScroller::Dragging || scroller->state() == QScroller::Inactive)) - PressDelayHandler::instance()->scrollerWasIntercepted(); - } - - if (!inputType) { - result |= Ignore; - } else { - switch (event->type()) { - case QEvent::MouseButtonPress: -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMousePress: -#endif - if (scroller->state() == QScroller::Pressed) { - int pressDelay = int(1000 * scroller->scrollerProperties().scrollMetric(QScrollerProperties::MousePressEventDelay).toReal()); - if (pressDelay > 0) { - result |= ConsumeEventHint; - - PressDelayHandler::instance()->pressed(event, pressDelay); - event->accept(); - } - } - // fall through - case QEvent::TouchBegin: - q->setHotSpot(globalPos); - result |= scrollerIsActive ? TriggerGesture : MayBeGesture; - break; - - case QEvent::MouseMove: -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMouseMove: -#endif - if (PressDelayHandler::instance()->isDelaying()) - result |= ConsumeEventHint; - // fall through - case QEvent::TouchUpdate: - result |= scrollerIsActive ? TriggerGesture : Ignore; - break; - -#ifndef QT_NO_GRAPHICSVIEW - case QEvent::GraphicsSceneMouseRelease: -#endif - case QEvent::MouseButtonRelease: - if (PressDelayHandler::instance()->released(event, scrollerWasDragging || scrollerWasScrolling, scrollerIsActive)) - result |= ConsumeEventHint; - // fall through - case QEvent::TouchEnd: - result |= scrollerIsActive ? FinishGesture : CancelGesture; - break; - - default: - result |= Ignore; - break; - } - } - return result; -} - - -/*! \reimp - */ -void QFlickGestureRecognizer::reset(QGesture *state) -{ - QGestureRecognizer::reset(state); -} - -QT_END_NAMESPACE - -#endif // QT_NO_GESTURES diff --git a/src/gui/util/qflickgesture_p.h b/src/gui/util/qflickgesture_p.h deleted file mode 100644 index 451b579..0000000 --- a/src/gui/util/qflickgesture_p.h +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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 QFLICKGESTURE_P_H -#define QFLICKGESTURE_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 "qevent.h" -#include "qgesturerecognizer.h" -#include "private/qgesture_p.h" -#include "qscroller.h" -#include "qscopedpointer.h" - -#ifndef QT_NO_GESTURES - -QT_BEGIN_NAMESPACE - -class QFlickGesturePrivate; -class QGraphicsItem; - -class Q_GUI_EXPORT QFlickGesture : public QGesture -{ - Q_OBJECT - Q_DECLARE_PRIVATE(QFlickGesture) - -public: - QFlickGesture(QObject *receiver, Qt::MouseButton button, QObject *parent = 0); - ~QFlickGesture(); - - friend class QFlickGestureRecognizer; -}; - -class PressDelayHandler; - -class QFlickGesturePrivate : public QGesturePrivate -{ - Q_DECLARE_PUBLIC(QFlickGesture) -public: - QFlickGesturePrivate(); - - QPointer<QObject> receiver; - QScroller *receiverScroller; - Qt::MouseButton button; // NoButton == Touch - bool macIgnoreWheel; - static PressDelayHandler *pressDelayHandler; -}; - -class QFlickGestureRecognizer : public QGestureRecognizer -{ -public: - QFlickGestureRecognizer(Qt::MouseButton button); - - QGesture *create(QObject *target); - QGestureRecognizer::Result recognize(QGesture *state, QObject *watched, QEvent *event); - void reset(QGesture *state); - -private: - Qt::MouseButton button; // NoButton == Touch -}; - -QT_END_NAMESPACE - -#endif // QT_NO_GESTURES - -#endif // QFLICKGESTURE_P_H diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp deleted file mode 100644 index db128c1..0000000 --- a/src/gui/util/qscroller.cpp +++ /dev/null @@ -1,2059 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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 "qevent.h" -#include "qwidget.h" -#include "qscroller.h" -#include "private/qflickgesture_p.h" -#include "private/qscroller_p.h" -#include "qscrollerproperties.h" -#include "private/qscrollerproperties_p.h" -#include "qnumeric.h" -#include "math.h" - -#include <QTime> -#include <QElapsedTimer> -#include <QMap> -#include <QApplication> -#include <QAbstractScrollArea> -#include <QGraphicsObject> -#include <QGraphicsScene> -#include <QGraphicsView> -#include <QDesktopWidget> -#include <QtCore/qmath.h> -#include <QtGui/qevent.h> -#include <qnumeric.h> - -#include <QtDebug> - -#if defined(Q_WS_X11) -# include "private/qt_x11_p.h" -#endif - - -QT_BEGIN_NAMESPACE - -bool qt_sendSpontaneousEvent(QObject *receiver, QEvent *event); - -//#define QSCROLLER_DEBUG - -#ifdef QSCROLLER_DEBUG -# define qScrollerDebug qDebug -#else -# define qScrollerDebug while (false) qDebug -#endif - -QDebug &operator<<(QDebug &dbg, const QScrollerPrivate::ScrollSegment &s) -{ - dbg << "\n Time: start:" << s.startTime << " duration:" << s.deltaTime << " stop progress:" << s.stopProgress; - dbg << "\n Pos: start:" << s.startPos << " delta:" << s.deltaPos << " stop:" << s.stopPos; - dbg << "\n Curve: type:" << s.curve.type() << "\n"; - return dbg; -} - - -// a few helper operators to make the code below a lot more readable: -// otherwise a lot of ifs would have to be multi-line to check both the x -// and y coordinate separately. - -// returns true only if the abs. value of BOTH x and y are <= f -inline bool operator<=(const QPointF &p, qreal f) -{ - return (qAbs(p.x()) <= f) && (qAbs(p.y()) <= f); -} - -// returns true only if the abs. value of BOTH x and y are < f -inline bool operator<(const QPointF &p, qreal f) -{ - return (qAbs(p.x()) < f) && (qAbs(p.y()) < f); -} - -// returns true if the abs. value of EITHER x or y are >= f -inline bool operator>=(const QPointF &p, qreal f) -{ - return (qAbs(p.x()) >= f) || (qAbs(p.y()) >= f); -} - -// returns true if the abs. value of EITHER x or y are > f -inline bool operator>(const QPointF &p, qreal f) -{ - return (qAbs(p.x()) > f) || (qAbs(p.y()) > f); -} - -// returns a new point with both coordinates having the abs. value of the original one -inline QPointF qAbs(const QPointF &p) -{ - return QPointF(qAbs(p.x()), qAbs(p.y())); -} - -// returns a new point with all components of p1 multiplied by the corresponding components of p2 -inline QPointF operator*(const QPointF &p1, const QPointF &p2) -{ - return QPointF(p1.x() * p2.x(), p1.y() * p2.y()); -} - -// returns a new point with all components of p1 divided by the corresponding components of p2 -inline QPointF operator/(const QPointF &p1, const QPointF &p2) -{ - return QPointF(p1.x() / p2.x(), p1.y() / p2.y()); -} - -inline QPointF clampToRect(const QPointF &p, const QRectF &rect) -{ - qreal x = qBound(rect.left(), p.x(), rect.right()); - qreal y = qBound(rect.top(), p.y(), rect.bottom()); - return QPointF(x, y); -} - -// returns -1, 0 or +1 according to r being <0, ==0 or >0 -inline int qSign(qreal r) -{ - return (r < 0) ? -1 : ((r > 0) ? 1 : 0); -} - -// this version is not mathematically exact, but it just works for every -// easing curve type (even custom ones) - -static qreal differentialForProgress(const QEasingCurve &curve, qreal pos) -{ - const qreal dx = 0.01; - qreal left = (pos < qreal(0.5)) ? pos : pos - qreal(dx); - qreal right = (pos >= qreal(0.5)) ? pos : pos + qreal(dx); - qreal d = (curve.valueForProgress(right) - curve.valueForProgress(left)) / qreal(dx); - - //qScrollerDebug() << "differentialForProgress(type: " << curve.type() << ", pos: " << pos << ") = " << d; - - return d; -} - -// this version is not mathematically exact, but it just works for every -// easing curve type (even custom ones) - -static qreal progressForValue(const QEasingCurve &curve, qreal value) -{ - if (curve.type() >= QEasingCurve::InElastic && - curve.type() < QEasingCurve::Custom) { - qWarning("progressForValue(): QEasingCurves of type %d do not have an inverse, since they are not injective.", curve.type()); - return value; - } - if (value < qreal(0) || value > qreal(1)) - return value; - - qreal progress = value, left(0), right(1); - for (int iterations = 6; iterations; --iterations) { - qreal v = curve.valueForProgress(progress); - if (v < value) - left = progress; - else if (v > value) - right = progress; - else - break; - progress = (left + right) / qreal(2); - } - return progress; -} - - -#ifndef QT_NO_ANIMATION -class QScrollTimer : public QAbstractAnimation -{ -public: - QScrollTimer(QScrollerPrivate *_d) - : d(_d), ignoreUpdate(false), skip(0) - { } - - int duration() const - { - return -1; - } - - void start() - { - // QAbstractAnimation::start() will immediately call - // updateCurrentTime(), but our state is not set correctly yet - ignoreUpdate = true; - QAbstractAnimation::start(); - ignoreUpdate = false; - skip = 0; - } - -protected: - void updateCurrentTime(int /*currentTime*/) - { - if (!ignoreUpdate) { - if (++skip >= d->frameRateSkip()) { - skip = 0; - d->timerTick(); - } - } - } - -private: - QScrollerPrivate *d; - bool ignoreUpdate; - int skip; -}; -#endif // QT_NO_ANIMATION - -/*! - \class QScroller - \brief The QScroller class enables kinetic scrolling for any scrolling widget or graphics item. - \since 4.8 - - With kinetic scrolling, the user can push the widget in a given - direction and it will continue to scroll in this direction until it is - stopped either by the user or by friction. Aspects of inertia, friction - and other physical concepts can be changed in order to fine-tune an - intuitive user experience. - - The QScroller object is the object that stores the current position and - scrolling speed and takes care of updates. - QScroller can be triggered by a flick gesture - - \code - QWidget *w = ...; - QScroller::grabGesture(w, QScroller::LeftMouseButtonGesture); - \endcode - - or directly like this: - - \code - QWidget *w = ...; - QScroller *scroller = QScroller::scroller(w); - scroller->scrollTo(QPointF(100, 100)); - \endcode - - The scrolled QObjects receive a QScrollPrepareEvent whenever the scroller needs to - update its geometry information and a QScrollEvent whenever the content of the object should - actually be scrolled. - - The scroller uses the global QAbstractAnimation timer to generate its QScrollEvents. This - can be changed with QScrollerProperties::FrameRate on a per-QScroller basis. - - Several examples in the \c scroller examples directory show how QScroller, - QScrollEvent and the scroller gesture can be used. - - Even though this kinetic scroller has a large number of settings available via - QScrollerProperties, we recommend that you leave them all at their default, platform optimized - values. Before changing them you can experiment with the \c plot example in - the \c scroller examples directory. - - \sa QScrollEvent, QScrollPrepareEvent, QScrollerProperties -*/ - -typedef QMap<QObject *, QScroller *> ScrollerHash; -typedef QSet<QScroller *> ScrollerSet; - -Q_GLOBAL_STATIC(ScrollerHash, qt_allScrollers) -Q_GLOBAL_STATIC(ScrollerSet, qt_activeScrollers) - -/*! - Returns \c true if a QScroller object was already created for \a target; \c false otherwise. - - \sa scroller() -*/ -bool QScroller::hasScroller(QObject *target) -{ - return (qt_allScrollers()->value(target)); -} - -/*! - Returns the scroller for the given \a target. - As long as the object exists this function will always return the same QScroller instance. - If no QScroller exists for the \a target, one will implicitly be created. - At no point more than one QScroller will be active on an object. - - \sa hasScroller(), target() -*/ -QScroller *QScroller::scroller(QObject *target) -{ - if (!target) { - qWarning("QScroller::scroller() was called with a null target."); - return 0; - } - - if (qt_allScrollers()->contains(target)) - return qt_allScrollers()->value(target); - - QScroller *s = new QScroller(target); - qt_allScrollers()->insert(target, s); - return s; -} - -/*! - \overload - This is the const version of scroller(). -*/ -const QScroller *QScroller::scroller(const QObject *target) -{ - return scroller(const_cast<QObject*>(target)); -} - -/*! - Returns an application wide list of currently active QScroller objects. - Active QScroller objects are in a state() that is not QScroller::Inactive. - This function is useful when writing your own gesture recognizer. -*/ -QList<QScroller *> QScroller::activeScrollers() -{ - return qt_activeScrollers()->toList(); -} - -/*! - Returns the target object of this scroller. - \sa hasScroller(), scroller() - */ -QObject *QScroller::target() const -{ - Q_D(const QScroller); - return d->target; -} - -/*! - \fn QScroller::scrollerPropertiesChanged(const QScrollerProperties &newProperties); - - QScroller emits this signal whenever its scroller properties change. - \a newProperties are the new scroller properties. - - \sa scrollerProperties -*/ - - -/*! \property QScroller::scrollerProperties - \brief The scroller properties of this scroller. - The properties are used by the QScroller to determine its scrolling behavior. -*/ -QScrollerProperties QScroller::scrollerProperties() const -{ - Q_D(const QScroller); - return d->properties; -} - -void QScroller::setScrollerProperties(const QScrollerProperties &sp) -{ - Q_D(QScroller); - if (d->properties != sp) { - d->properties = sp; - emit scrollerPropertiesChanged(sp); - - // we need to force the recalculation here, since the overshootPolicy may have changed and - // existing segments may include an overshoot animation. - d->recalcScrollingSegments(true); - } -} - -#ifndef QT_NO_GESTURES - -/*! - Registers a custom scroll gesture recognizer, grabs it for the \a - target and returns the resulting gesture type. If \a scrollGestureType is - set to TouchGesture the gesture triggers on touch events. If it is set to - one of LeftMouseButtonGesture, RightMouseButtonGesture or - MiddleMouseButtonGesture it triggers on mouse events of the - corresponding button. - - Only one scroll gesture can be active on a single object at the same - time. If you call this function twice on the same object, it will - ungrab the existing gesture before grabbing the new one. - - \note To avoid unwanted side-effects, mouse events are consumed while - the gesture is triggered. Since the initial mouse press event is - not consumed, the gesture sends a fake mouse release event - at the global position \c{(INT_MIN, INT_MIN)}. This ensures that - internal states of the widget that received the original mouse press - are consistent. - - \sa ungrabGesture, grabbedGesture -*/ -Qt::GestureType QScroller::grabGesture(QObject *target, ScrollerGestureType scrollGestureType) -{ - // ensure that a scroller for target is created - QScroller *s = scroller(target); - if (!s) - return Qt::GestureType(0); - - QScrollerPrivate *sp = s->d_ptr; - if (sp->recognizer) - ungrabGesture(target); // ungrab the old gesture - - Qt::MouseButton button; - switch (scrollGestureType) { - case LeftMouseButtonGesture : button = Qt::LeftButton; break; - case RightMouseButtonGesture : button = Qt::RightButton; break; - case MiddleMouseButtonGesture: button = Qt::MiddleButton; break; - default : - case TouchGesture : button = Qt::NoButton; break; // NoButton == Touch - } - - sp->recognizer = new QFlickGestureRecognizer(button); - sp->recognizerType = QGestureRecognizer::registerRecognizer(sp->recognizer); - - if (target->isWidgetType()) { - QWidget *widget = static_cast<QWidget *>(target); - widget->grabGesture(sp->recognizerType); - if (scrollGestureType == TouchGesture) - widget->setAttribute(Qt::WA_AcceptTouchEvents); -#ifndef QT_NO_GRAPHICSVIEW - } else if (QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target)) { - if (scrollGestureType == TouchGesture) - go->setAcceptTouchEvents(true); - go->grabGesture(sp->recognizerType); -#endif // QT_NO_GRAPHICSVIEW - } - return sp->recognizerType; -} - -/*! - Returns the gesture type currently grabbed for the \a target or 0 if no - gesture is grabbed. - - \sa grabGesture, ungrabGesture -*/ -Qt::GestureType QScroller::grabbedGesture(QObject *target) -{ - QScroller *s = scroller(target); - if (s && s->d_ptr) - return s->d_ptr->recognizerType; - else - return Qt::GestureType(0); -} - -/*! - Ungrabs the gesture for the \a target. - Does nothing if no gesture is grabbed. - - \sa grabGesture, grabbedGesture -*/ -void QScroller::ungrabGesture(QObject *target) -{ - QScroller *s = scroller(target); - if (!s) - return; - - QScrollerPrivate *sp = s->d_ptr; - if (!sp->recognizer) - return; // nothing to do - - if (target->isWidgetType()) { - QWidget *widget = static_cast<QWidget *>(target); - widget->ungrabGesture(sp->recognizerType); -#ifndef QT_NO_GRAPHICSVIEW - } else if (QGraphicsObject *go = qobject_cast<QGraphicsObject*>(target)) { - go->ungrabGesture(sp->recognizerType); -#endif - } - - QGestureRecognizer::unregisterRecognizer(sp->recognizerType); - // do not delete the recognizer. The QGestureManager is doing this. - sp->recognizer = 0; -} - -#endif // QT_NO_GESTURES - -/*! - \internal -*/ -QScroller::QScroller(QObject *target) - : d_ptr(new QScrollerPrivate(this, target)) -{ - Q_ASSERT(target); // you can't create a scroller without a target in any normal way - Q_D(QScroller); - d->init(); -} - -/*! - \internal -*/ -QScroller::~QScroller() -{ - Q_D(QScroller); -#ifndef QT_NO_GESTURES - QGestureRecognizer::unregisterRecognizer(d->recognizerType); - // do not delete the recognizer. The QGestureManager is doing this. - d->recognizer = 0; -#endif - qt_allScrollers()->remove(d->target); - qt_activeScrollers()->remove(this); - - delete d_ptr; -} - - -/*! - \fn QScroller::stateChanged(QScroller::State newState); - - QScroller emits this signal whenever the state changes. \a newState is the new State. - - \sa state -*/ - -/*! - \property QScroller::state - \brief the state of the scroller - - \sa QScroller::State -*/ -QScroller::State QScroller::state() const -{ - Q_D(const QScroller); - return d->state; -} - -/*! - Stops the scroller and resets its state back to Inactive. -*/ -void QScroller::stop() -{ - Q_D(QScroller); - if (d->state != Inactive) { - QPointF here = clampToRect(d->contentPosition, d->contentPosRange); - qreal snapX = d->nextSnapPos(here.x(), 0, Qt::Horizontal); - qreal snapY = d->nextSnapPos(here.y(), 0, Qt::Vertical); - QPointF snap = here; - if (!qIsNaN(snapX)) - snap.setX(snapX); - if (!qIsNaN(snapY)) - snap.setY(snapY); - d->contentPosition = snap; - d->overshootPosition = QPointF(0, 0); - - d->setState(Inactive); - } -} - -/*! - Returns the pixel per meter metric for the scrolled widget. - - The value is reported for both the x and y axis separately by using a QPointF. - - \note Please note that this value should be physically correct. The actual DPI settings - that Qt returns for the display may be reported wrongly on purpose by the underlying - windowing system, for example on Mac OS X or Maemo 5. -*/ -QPointF QScroller::pixelPerMeter() const -{ - Q_D(const QScroller); - QPointF ppm = d->pixelPerMeter; - -#ifndef QT_NO_GRAPHICSVIEW - if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(d->target)) { - QTransform viewtr; - //TODO: the first view isn't really correct - maybe use an additional field in the prepare event? - if (go->scene() && !go->scene()->views().isEmpty()) - viewtr = go->scene()->views().first()->viewportTransform(); - QTransform tr = go->deviceTransform(viewtr); - if (tr.isScaling()) { - QPointF p0 = tr.map(QPointF(0, 0)); - QPointF px = tr.map(QPointF(1, 0)); - QPointF py = tr.map(QPointF(0, 1)); - ppm.rx() /= QLineF(p0, px).length(); - ppm.ry() /= QLineF(p0, py).length(); - } - } -#endif // QT_NO_GRAPHICSVIEW - return ppm; -} - -/*! - Returns the current scrolling velocity in meter per second when the state is Scrolling or Dragging. - Returns a zero velocity otherwise. - - The velocity is reported for both the x and y axis separately by using a QPointF. - - \sa pixelPerMeter() -*/ -QPointF QScroller::velocity() const -{ - Q_D(const QScroller); - const QScrollerPropertiesPrivate *sp = d->properties.d.data(); - - switch (state()) { - case Dragging: - return d->releaseVelocity; - case Scrolling: { - QPointF vel; - qint64 now = d->monotonicTimer.elapsed(); - - if (!d->xSegments.isEmpty()) { - const QScrollerPrivate::ScrollSegment &s = d->xSegments.head(); - qreal progress = qreal(now - s.startTime) / qreal(s.deltaTime); - qreal v = qSign(s.deltaPos) * qreal(s.deltaTime) / qreal(1000) * sp->decelerationFactor * qreal(0.5) * differentialForProgress(s.curve, progress); - vel.setX(v); - } - - if (!d->ySegments.isEmpty()) { - const QScrollerPrivate::ScrollSegment &s = d->ySegments.head(); - qreal progress = qreal(now - s.startTime) / qreal(s.deltaTime); - qreal v = qSign(s.deltaPos) * qreal(s.deltaTime) / qreal(1000) * sp->decelerationFactor * qreal(0.5) * differentialForProgress(s.curve, progress); - vel.setY(v); - } - return vel; - } - default: - return QPointF(0, 0); - } -} - -/*! - Returns the estimated final position for the current scroll movement. - Returns the current position if the scroller state is not Scrolling. - The result is undefined when the scroller state is Inactive. - - The target position is in pixel. - - \sa pixelPerMeter(), scrollTo() -*/ -QPointF QScroller::finalPosition() const -{ - Q_D(const QScroller); - return QPointF(d->scrollingSegmentsEndPos(Qt::Horizontal), - d->scrollingSegmentsEndPos(Qt::Vertical)); -} - -/*! - Starts scrolling the widget so that point \a pos is at the top-left position in - the viewport. - - The behaviour when scrolling outside the valid scroll area is undefined. - In this case the scroller might or might not overshoot. - - The scrolling speed will be calculated so that the given position will - be reached after a platform-defined time span. - - \a pos is given in viewport coordinates. - - \sa ensureVisible() -*/ -void QScroller::scrollTo(const QPointF &pos) -{ - // we could make this adjustable via QScrollerProperties - scrollTo(pos, 300); -} - -/*! \overload - - This version will reach its destination position in \a scrollTime milliseconds. -*/ -void QScroller::scrollTo(const QPointF &pos, int scrollTime) -{ - Q_D(QScroller); - - if (d->state == Pressed || d->state == Dragging ) - return; - - // no need to resend a prepare event if we are already scrolling - if (d->state == Inactive && !d->prepareScrolling(QPointF())) - return; - - QPointF newpos = clampToRect(pos, d->contentPosRange); - qreal snapX = d->nextSnapPos(newpos.x(), 0, Qt::Horizontal); - qreal snapY = d->nextSnapPos(newpos.y(), 0, Qt::Vertical); - if (!qIsNaN(snapX)) - newpos.setX(snapX); - if (!qIsNaN(snapY)) - newpos.setY(snapY); - - qScrollerDebug() << "QScroller::scrollTo(req:" << pos << " [pix] / snap:" << newpos << ", " << scrollTime << " [ms])"; - - if (newpos == d->contentPosition + d->overshootPosition) - return; - - QPointF vel = velocity(); - - if (scrollTime < 0) - scrollTime = 0; - qreal time = qreal(scrollTime) / 1000; - - d->createScrollToSegments(vel.x(), time, newpos.x(), Qt::Horizontal, QScrollerPrivate::ScrollTypeScrollTo); - d->createScrollToSegments(vel.y(), time, newpos.y(), Qt::Vertical, QScrollerPrivate::ScrollTypeScrollTo); - - if (!scrollTime) - d->setContentPositionHelperScrolling(); - d->setState(scrollTime ? Scrolling : Inactive); -} - -/*! - Starts scrolling so that the rectangle \a rect is visible inside the - viewport with additional margins specified in pixels by \a xmargin and \a ymargin around - the rect. - - In cases where it is not possible to fit the rect plus margins inside the viewport the contents - are scrolled so that as much as possible is visible from \a rect. - - The scrolling speed is calculated so that the given position is reached after a platform-defined - time span. - - This function performs the actual scrolling by calling scrollTo(). - - \sa scrollTo -*/ -void QScroller::ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin) -{ - // we could make this adjustable via QScrollerProperties - ensureVisible(rect, xmargin, ymargin, 1000); -} - -/*! \overload - - This version will reach its destination position in \a scrollTime milliseconds. -*/ -void QScroller::ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin, int scrollTime) -{ - Q_D(QScroller); - - if (d->state == Pressed || d->state == Dragging ) - return; - - if (d->state == Inactive && !d->prepareScrolling(QPointF())) - return; - - // -- calculate the current pos (or the position after the current scroll) - QPointF startPos = d->contentPosition + d->overshootPosition; - startPos = QPointF(d->scrollingSegmentsEndPos(Qt::Horizontal), - d->scrollingSegmentsEndPos(Qt::Vertical)); - - QRectF marginRect(rect.x() - xmargin, rect.y() - ymargin, - rect.width() + 2 * xmargin, rect.height() + 2 * ymargin); - - QSizeF visible = d->viewportSize; - QRectF visibleRect(startPos, visible); - - qScrollerDebug() << "QScroller::ensureVisible(" << rect << " [pix], " << xmargin << " [pix], " << ymargin << " [pix], " << scrollTime << "[ms])"; - qScrollerDebug() << " --> content position:" << d->contentPosition; - - if (visibleRect.contains(marginRect)) - return; - - QPointF newPos = startPos; - - if (visibleRect.width() < rect.width()) { - // at least try to move the rect into view - if (rect.left() > visibleRect.left()) - newPos.setX(rect.left()); - else if (rect.right() < visibleRect.right()) - newPos.setX(rect.right() - visible.width()); - - } else if (visibleRect.width() < marginRect.width()) { - newPos.setX(rect.center().x() - visibleRect.width() / 2); - } else if (marginRect.left() > visibleRect.left()) { - newPos.setX(marginRect.left()); - } else if (marginRect.right() < visibleRect.right()) { - newPos.setX(marginRect.right() - visible.width()); - } - - if (visibleRect.height() < rect.height()) { - // at least try to move the rect into view - if (rect.top() > visibleRect.top()) - newPos.setX(rect.top()); - else if (rect.bottom() < visibleRect.bottom()) - newPos.setX(rect.bottom() - visible.height()); - - } else if (visibleRect.height() < marginRect.height()) { - newPos.setY(rect.center().y() - visibleRect.height() / 2); - } else if (marginRect.top() > visibleRect.top()) { - newPos.setY(marginRect.top()); - } else if (marginRect.bottom() < visibleRect.bottom()) { - newPos.setY(marginRect.bottom() - visible.height()); - } - - // clamp to maximum content position - newPos = clampToRect(newPos, d->contentPosRange); - if (newPos == startPos) - return; - - scrollTo(newPos, scrollTime); -} - -/*! This function resends the QScrollPrepareEvent. - Calling resendPrepareEvent triggers a QScrollPrepareEvent from the scroller. - This allows the receiver to re-set content position and content size while - scrolling. - Calling this function while in the Inactive state is useless as the prepare event - is sent again before scrolling starts. - */ -void QScroller::resendPrepareEvent() -{ - Q_D(QScroller); - d->prepareScrolling(d->pressPosition); -} - -/*! Set the snap positions for the horizontal axis to a list of \a positions. - This overwrites all previously set snap positions and also a previously - set snapping interval. - Snapping can be deactivated by setting an empty list of positions. - */ -void QScroller::setSnapPositionsX(const QList<qreal> &positions) -{ - Q_D(QScroller); - d->snapPositionsX = positions; - d->snapIntervalX = 0.0; - - d->recalcScrollingSegments(); -} - -/*! Set the snap positions for the horizontal axis to regular spaced intervals. - The first snap position is at \a first. The next at \a first + \a interval. - This can be used to implement a list header. - This overwrites all previously set snap positions and also a previously - set snapping interval. - Snapping can be deactivated by setting an interval of 0.0 - */ -void QScroller::setSnapPositionsX(qreal first, qreal interval) -{ - Q_D(QScroller); - d->snapFirstX = first; - d->snapIntervalX = interval; - d->snapPositionsX.clear(); - - d->recalcScrollingSegments(); -} - -/*! Set the snap positions for the vertical axis to a list of \a positions. - This overwrites all previously set snap positions and also a previously - set snapping interval. - Snapping can be deactivated by setting an empty list of positions. - */ -void QScroller::setSnapPositionsY(const QList<qreal> &positions) -{ - Q_D(QScroller); - d->snapPositionsY = positions; - d->snapIntervalY = 0.0; - - d->recalcScrollingSegments(); -} - -/*! Set the snap positions for the vertical axis to regular spaced intervals. - The first snap position is at \a first. The next at \a first + \a interval. - This overwrites all previously set snap positions and also a previously - set snapping interval. - Snapping can be deactivated by setting an interval of 0.0 - */ -void QScroller::setSnapPositionsY(qreal first, qreal interval) -{ - Q_D(QScroller); - d->snapFirstY = first; - d->snapIntervalY = interval; - d->snapPositionsY.clear(); - - d->recalcScrollingSegments(); -} - - - -// -------------- private ------------ - -QScrollerPrivate::QScrollerPrivate(QScroller *q, QObject *_target) - : target(_target) -#ifndef QT_NO_GESTURES - , recognizer(0) - , recognizerType(Qt::CustomGesture) -#endif - , state(QScroller::Inactive) - , firstScroll(true) - , pressTimestamp(0) - , lastTimestamp(0) - , snapFirstX(-1.0) - , snapIntervalX(0.0) - , snapFirstY(-1.0) - , snapIntervalY(0.0) -#ifndef QT_NO_ANIMATION - , scrollTimer(new QScrollTimer(this)) -#endif - , q_ptr(q) -{ - connect(target, SIGNAL(destroyed(QObject*)), this, SLOT(targetDestroyed())); -} - -void QScrollerPrivate::init() -{ - setDpiFromWidget(0); - monotonicTimer.start(); -} - -void QScrollerPrivate::sendEvent(QObject *o, QEvent *e) -{ - qt_sendSpontaneousEvent(o, e); -} - -const char *QScrollerPrivate::stateName(QScroller::State state) -{ - switch (state) { - case QScroller::Inactive: return "inactive"; - case QScroller::Pressed: return "pressed"; - case QScroller::Dragging: return "dragging"; - case QScroller::Scrolling: return "scrolling"; - default: return "(invalid)"; - } -} - -const char *QScrollerPrivate::inputName(QScroller::Input input) -{ - switch (input) { - case QScroller::InputPress: return "press"; - case QScroller::InputMove: return "move"; - case QScroller::InputRelease: return "release"; - default: return "(invalid)"; - } -} - -void QScrollerPrivate::targetDestroyed() -{ -#ifndef QT_NO_ANIMATION - scrollTimer->stop(); -#endif - delete q_ptr; -} - -void QScrollerPrivate::timerTick() -{ - struct timerevent { - QScroller::State state; - typedef void (QScrollerPrivate::*timerhandler_t)(); - timerhandler_t handler; - }; - - timerevent timerevents[] = { - { QScroller::Dragging, &QScrollerPrivate::timerEventWhileDragging }, - { QScroller::Scrolling, &QScrollerPrivate::timerEventWhileScrolling }, - }; - - for (int i = 0; i < int(sizeof(timerevents) / sizeof(*timerevents)); ++i) { - timerevent *te = timerevents + i; - - if (state == te->state) { - (this->*te->handler)(); - return; - } - } - -#ifndef QT_NO_ANIMATION - scrollTimer->stop(); -#endif -} - -/*! - This function is used by gesture recognizers to inform the scroller about a new input event. - The scroller changes its internal state() according to the input event and its attached - scroller properties. The scroller doesn't distinguish between the kind of input device the - event came from. Therefore the event needs to be split into the \a input type, a \a position and a - milli-second \a timestamp. The \a position needs to be in the target's coordinate system. - - The return value is \c true if the event should be consumed by the calling filter or \c false - if the event should be forwarded to the control. - - \note Using grabGesture() should be sufficient for most use cases. -*/ -bool QScroller::handleInput(Input input, const QPointF &position, qint64 timestamp) -{ - Q_D(QScroller); - - qScrollerDebug() << "QScroller::handleInput(" << input << ", " << d->stateName(d->state) << ", " << position << ", " << timestamp << ")"; - struct statechange { - State state; - Input input; - typedef bool (QScrollerPrivate::*inputhandler_t)(const QPointF &position, qint64 timestamp); - inputhandler_t handler; - }; - - statechange statechanges[] = { - { QScroller::Inactive, InputPress, &QScrollerPrivate::pressWhileInactive }, - { QScroller::Pressed, InputMove, &QScrollerPrivate::moveWhilePressed }, - { QScroller::Pressed, InputRelease, &QScrollerPrivate::releaseWhilePressed }, - { QScroller::Dragging, InputMove, &QScrollerPrivate::moveWhileDragging }, - { QScroller::Dragging, InputRelease, &QScrollerPrivate::releaseWhileDragging }, - { QScroller::Scrolling, InputPress, &QScrollerPrivate::pressWhileScrolling } - }; - - for (int i = 0; i < int(sizeof(statechanges) / sizeof(*statechanges)); ++i) { - statechange *sc = statechanges + i; - - if (d->state == sc->state && input == sc->input) - return (d->*sc->handler)(position - d->overshootPosition, timestamp); - } - return false; -} - -#if !defined(Q_WS_MAC) -// the Mac version is implemented in qscroller_mac.mm - -QPointF QScrollerPrivate::realDpi(int screen) -{ -# ifdef Q_WS_MAEMO_5 - Q_UNUSED(screen); - - // The DPI value is hardcoded to 96 on Maemo5: - // https://projects.maemo.org/bugzilla/show_bug.cgi?id=152525 - // This value (260) is only correct for the N900 though, but - // there's no way to get the real DPI at run time. - return QPointF(260, 260); - -# elif defined(Q_WS_X11) && !defined(QT_NO_XRANDR) - if (X11 && X11->use_xrandr && X11->ptrXRRSizes && X11->ptrXRRRootToScreen) { - int nsizes = 0; - // QDesktopWidget is based on Xinerama screens, which do not always - // correspond to RandR screens: NVidia's TwinView e.g. will show up - // as 2 screens in QDesktopWidget, but libXRandR will only see 1 screen. - // (although with the combined size of the Xinerama screens). - // Additionally, libXrandr will simply crash when calling XRRSizes - // for (the non-existent) screen 1 in this scenario. - Window root = RootWindow(X11->display, screen == -1 ? X11->defaultScreen : screen); - int randrscreen = (root != XNone) ? X11->ptrXRRRootToScreen(X11->display, root) : -1; - - XRRScreenSize *sizes = X11->ptrXRRSizes(X11->display, randrscreen == -1 ? 0 : randrscreen, &nsizes); - if (nsizes > 0 && sizes && sizes->width && sizes->height && sizes->mwidth && sizes->mheight) { - qScrollerDebug() << "XRandR DPI:" << QPointF(qreal(25.4) * qreal(sizes->width) / qreal(sizes->mwidth), - qreal(25.4) * qreal(sizes->height) / qreal(sizes->mheight)); - return QPointF(qreal(25.4) * qreal(sizes->width) / qreal(sizes->mwidth), - qreal(25.4) * qreal(sizes->height) / qreal(sizes->mheight)); - } - } -# endif - - QWidget *w = QApplication::desktop()->screen(screen); - return QPointF(w->physicalDpiX(), w->physicalDpiY()); -} - -#endif // !Q_WS_MAC - - -/*! \internal - Returns the resolution of the used screen. -*/ -QPointF QScrollerPrivate::dpi() const -{ - return pixelPerMeter * qreal(0.0254); -} - -/*! \internal - Sets the resolution used for scrolling. - This resolution is only used by the kinetic scroller. If you change this - then the scroller will behave quite different as a lot of the values are - given in physical distances (millimeter). -*/ -void QScrollerPrivate::setDpi(const QPointF &dpi) -{ - pixelPerMeter = dpi / qreal(0.0254); -} - -/*! \internal - Sets the dpi used for scrolling to the value of the widget. -*/ -void QScrollerPrivate::setDpiFromWidget(QWidget *widget) -{ - QDesktopWidget *dw = QApplication::desktop(); - setDpi(realDpi(widget ? dw->screenNumber(widget) : dw->primaryScreen())); -} - -/*! \internal - Updates the velocity during dragging. - Sets releaseVelocity. -*/ -void QScrollerPrivate::updateVelocity(const QPointF &deltaPixelRaw, qint64 deltaTime) -{ - if (deltaTime <= 0) - return; - - Q_Q(QScroller); - QPointF ppm = q->pixelPerMeter(); - const QScrollerPropertiesPrivate *sp = properties.d.data(); - QPointF deltaPixel = deltaPixelRaw; - - qScrollerDebug() << "QScroller::updateVelocity(" << deltaPixelRaw << " [delta pix], " << deltaTime << " [delta ms])"; - - // faster than 2.5mm/ms seems bogus (that would be a screen height in ~20 ms) - if (((deltaPixelRaw / qreal(deltaTime)).manhattanLength() / ((ppm.x() + ppm.y()) / 2) * 1000) > qreal(2.5)) - deltaPixel = deltaPixelRaw * qreal(2.5) * ppm / 1000 / (deltaPixelRaw / qreal(deltaTime)).manhattanLength(); - - QPointF newv = -deltaPixel / qreal(deltaTime) * qreal(1000) / ppm; - // around 95% of all updates are in the [1..50] ms range, so make sure - // to scale the smoothing factor over that range: this way a 50ms update - // will have full impact, while 5ms update will only have a 10% impact. - qreal smoothing = sp->dragVelocitySmoothingFactor * qMin(qreal(deltaTime), qreal(50)) / qreal(50); - - // only smooth if we already have a release velocity and only if the - // user hasn't stopped to move his finger for more than 100ms - if ((releaseVelocity != QPointF(0, 0)) && (deltaTime < 100)) { - qScrollerDebug() << "SMOOTHED from " << newv << " to " << newv * smoothing + releaseVelocity * (qreal(1) - smoothing); - // smooth x or y only if the new velocity is either 0 or at least in - // the same direction of the release velocity - if (!newv.x() || (qSign(releaseVelocity.x()) == qSign(newv.x()))) - newv.setX(newv.x() * smoothing + releaseVelocity.x() * (qreal(1) - smoothing)); - if (!newv.y() || (qSign(releaseVelocity.y()) == qSign(newv.y()))) - newv.setY(newv.y() * smoothing + releaseVelocity.y() * (qreal(1) - smoothing)); - } else - qScrollerDebug() << "NO SMOOTHING to " << newv; - - releaseVelocity.setX(qBound(-sp->maximumVelocity, newv.x(), sp->maximumVelocity)); - releaseVelocity.setY(qBound(-sp->maximumVelocity, newv.y(), sp->maximumVelocity)); - - qScrollerDebug() << " --> new velocity:" << releaseVelocity; -} - -void QScrollerPrivate::pushSegment(ScrollType type, qreal deltaTime, qreal stopProgress, qreal startPos, qreal deltaPos, qreal stopPos, QEasingCurve::Type curve, Qt::Orientation orientation) -{ - if (startPos == stopPos || deltaPos == 0) - return; - - ScrollSegment s; - if (orientation == Qt::Horizontal && !xSegments.isEmpty()) - s.startTime = xSegments.last().startTime + xSegments.last().deltaTime * xSegments.last().stopProgress; - else if (orientation == Qt::Vertical && !ySegments.isEmpty()) - s.startTime = ySegments.last().startTime + ySegments.last().deltaTime * ySegments.last().stopProgress; - else - s.startTime = monotonicTimer.elapsed(); - - s.startPos = startPos; - s.deltaPos = deltaPos; - s.stopPos = stopPos; - s.deltaTime = deltaTime * 1000; - s.stopProgress = stopProgress; - s.curve.setType(curve); - s.type = type; - - if (orientation == Qt::Horizontal) - xSegments.enqueue(s); - else - ySegments.enqueue(s); - - qScrollerDebug() << "+++ Added a new ScrollSegment: " << s; -} - - -/*! \internal - Clears the old segments and recalculates them if the current segments are not longer valid -*/ -void QScrollerPrivate::recalcScrollingSegments(bool forceRecalc) -{ - Q_Q(QScroller); - QPointF ppm = q->pixelPerMeter(); - - releaseVelocity = q->velocity(); - - if (forceRecalc || !scrollingSegmentsValid(Qt::Horizontal)) - createScrollingSegments(releaseVelocity.x(), contentPosition.x() + overshootPosition.x(), ppm.x(), Qt::Horizontal); - - if (forceRecalc || !scrollingSegmentsValid(Qt::Vertical)) - createScrollingSegments(releaseVelocity.y(), contentPosition.y() + overshootPosition.y(), ppm.y(), Qt::Vertical); -} - -/*! \internal - Returns the end position after the current scroll has finished. -*/ -qreal QScrollerPrivate::scrollingSegmentsEndPos(Qt::Orientation orientation) const -{ - if (orientation == Qt::Horizontal) { - if (xSegments.isEmpty()) - return contentPosition.x() + overshootPosition.x(); - else - return xSegments.last().stopPos; - } else { - if (ySegments.isEmpty()) - return contentPosition.y() + overshootPosition.y(); - else - return ySegments.last().stopPos; - } -} - -/*! \internal - Checks if the scroller segment end in a valid position. -*/ -bool QScrollerPrivate::scrollingSegmentsValid(Qt::Orientation orientation) -{ - QQueue<ScrollSegment> *segments; - qreal minPos; - qreal maxPos; - - if (orientation == Qt::Horizontal) { - segments = &xSegments; - minPos = contentPosRange.left(); - maxPos = contentPosRange.right(); - } else { - segments = &ySegments; - minPos = contentPosRange.top(); - maxPos = contentPosRange.bottom(); - } - - if (segments->isEmpty()) - return true; - - const ScrollSegment &last = segments->last(); - qreal stopPos = last.stopPos; - - if (last.type == ScrollTypeScrollTo) - return true; // scrollTo is always valid - - if (last.type == ScrollTypeOvershoot && - (stopPos != minPos && stopPos != maxPos)) - return false; - - if (stopPos < minPos || stopPos > maxPos) - return false; - - if (stopPos == minPos || stopPos == maxPos) // the begin and the end of the list are always ok - return true; - - qreal nextSnap = nextSnapPos(stopPos, 0, orientation); - if (!qIsNaN(nextSnap) && stopPos != nextSnap) - return false; - - return true; -} - -/*! \internal - Creates the sections needed to scroll to the specific \a endPos to the segments queue. -*/ -void QScrollerPrivate::createScrollToSegments(qreal v, qreal deltaTime, qreal endPos, Qt::Orientation orientation, ScrollType type) -{ - Q_UNUSED(v); - - if (orientation == Qt::Horizontal) - xSegments.clear(); - else - ySegments.clear(); - - qScrollerDebug() << "+++ createScrollToSegments: t:" << deltaTime << "ep:" << endPos << "o:" << int(orientation); - - const QScrollerPropertiesPrivate *sp = properties.d.data(); - - qreal startPos = (orientation == Qt::Horizontal) ? contentPosition.x() + overshootPosition.x() - : contentPosition.y() + overshootPosition.y(); - qreal deltaPos = (endPos - startPos) / 2; - - pushSegment(type, deltaTime * qreal(0.3), qreal(1.0), startPos, deltaPos, startPos + deltaPos, QEasingCurve::InQuad, orientation); - pushSegment(type, deltaTime * qreal(0.7), qreal(1.0), startPos + deltaPos, deltaPos, endPos, sp->scrollingCurve.type(), orientation); -} - -/*! \internal -*/ -void QScrollerPrivate::createScrollingSegments(qreal v, qreal startPos, qreal ppm, Qt::Orientation orientation) -{ - const QScrollerPropertiesPrivate *sp = properties.d.data(); - - QScrollerProperties::OvershootPolicy policy; - qreal minPos; - qreal maxPos; - qreal viewSize; - - if (orientation == Qt::Horizontal) { - xSegments.clear(); - policy = sp->hOvershootPolicy; - minPos = contentPosRange.left(); - maxPos = contentPosRange.right(); - viewSize = viewportSize.width(); - } else { - ySegments.clear(); - policy = sp->vOvershootPolicy; - minPos = contentPosRange.top(); - maxPos = contentPosRange.bottom(); - viewSize = viewportSize.height(); - } - - bool alwaysOvershoot = (policy == QScrollerProperties::OvershootAlwaysOn); - bool noOvershoot = (policy == QScrollerProperties::OvershootAlwaysOff) || !sp->overshootScrollDistanceFactor; - bool canOvershoot = !noOvershoot && (alwaysOvershoot || maxPos); - - qScrollerDebug() << "+++ createScrollingSegments: s:" << startPos << "maxPos:" << maxPos << "o:" << int(orientation); - - qScrollerDebug() << "v = " << v << ", decelerationFactor = " << sp->decelerationFactor << ", curveType = " << sp->scrollingCurve.type(); - - // This is only correct for QEasingCurve::OutQuad (linear velocity, - // constant deceleration), but the results look and feel ok for OutExpo - // and OutSine as well - - // v(t) = deltaTime * a * 0.5 * differentialForProgress(t / deltaTime) - // v(0) = vrelease - // v(deltaTime) = 0 - // deltaTime = (2 * vrelease) / (a * differntial(0)) - - // pos(t) = integrate(v(t)dt) - // pos(t) = vrelease * t - 0.5 * a * t * t - // pos(t) = deltaTime * a * 0.5 * progress(t / deltaTime) * deltaTime - // deltaPos = pos(deltaTime) - - qreal deltaTime = (qreal(2) * qAbs(v)) / (sp->decelerationFactor * differentialForProgress(sp->scrollingCurve, 0)); - qreal deltaPos = qSign(v) * deltaTime * deltaTime * qreal(0.5) * sp->decelerationFactor * ppm; - qreal endPos = startPos + deltaPos; - - qScrollerDebug() << " Real Delta:" << deltaPos; - - // -- determine snap points - qreal nextSnap = nextSnapPos(endPos, 0, orientation); - qreal lowerSnapPos = nextSnapPos(startPos, -1, orientation); - qreal higherSnapPos = nextSnapPos(startPos, 1, orientation); - - qScrollerDebug() << " Real Delta:" << lowerSnapPos <<"-"<<nextSnap <<"-"<<higherSnapPos; - - // - check if we can reach another snap point - if (nextSnap > higherSnapPos || qIsNaN(higherSnapPos)) - higherSnapPos = nextSnap; - if (nextSnap < lowerSnapPos || qIsNaN(lowerSnapPos)) - lowerSnapPos = nextSnap; - - // -- check if are in overshoot and end in overshoot - if ((startPos < minPos && endPos < minPos) || - (startPos > maxPos && endPos > maxPos)) { - qreal stopPos = endPos < minPos ? minPos : maxPos; - qreal oDeltaTime = sp->overshootScrollTime; - - pushSegment(ScrollTypeOvershoot, oDeltaTime * qreal(0.7), qreal(1.0), startPos, stopPos - startPos, stopPos, sp->scrollingCurve.type(), orientation); - return; - } - - if (qAbs(v) < sp->minimumVelocity) { - - qScrollerDebug() << "### below minimum Vel" << orientation; - - // - no snap points or already at one - if (qIsNaN(nextSnap) || nextSnap == startPos) - return; // nothing to do, no scrolling needed. - - // - decide which point to use - - qreal snapDistance = higherSnapPos - lowerSnapPos; - - qreal pressDistance = (orientation == Qt::Horizontal) ? - lastPosition.x() - pressPosition.x() : - lastPosition.y() - pressPosition.y(); - - // if not dragged far enough, pick the next snap point. - if (sp->snapPositionRatio == 0.0 || qAbs(pressDistance / sp->snapPositionRatio) > snapDistance) - endPos = nextSnap; - else if (pressDistance < 0.0) - endPos = lowerSnapPos; - else - endPos = higherSnapPos; - - deltaPos = endPos - startPos; - qreal midPos = startPos + deltaPos * qreal(0.3); - pushSegment(ScrollTypeFlick, sp->snapTime * qreal(0.3), qreal(1.0), startPos, midPos - startPos, midPos, QEasingCurve::InQuad, orientation); - pushSegment(ScrollTypeFlick, sp->snapTime * qreal(0.7), qreal(1.0), midPos, endPos - midPos, endPos, sp->scrollingCurve.type(), orientation); - return; - } - - // - go to the next snappoint if there is one - if (v > 0 && !qIsNaN(higherSnapPos)) { - // change the time in relation to the changed end position - if (endPos - startPos) - deltaTime *= qAbs((higherSnapPos - startPos) / (endPos - startPos)); - if (deltaTime > sp->snapTime) - deltaTime = sp->snapTime; - endPos = higherSnapPos; - - } else if (v < 0 && !qIsNaN(lowerSnapPos)) { - // change the time in relation to the changed end position - if (endPos - startPos) - deltaTime *= qAbs((lowerSnapPos - startPos) / (endPos - startPos)); - if (deltaTime > sp->snapTime) - deltaTime = sp->snapTime; - endPos = lowerSnapPos; - - // -- check if we are overshooting - } else if (endPos < minPos || endPos > maxPos) { - qreal stopPos = endPos < minPos ? minPos : maxPos; - - qScrollerDebug() << "Overshoot: delta:" << (stopPos - startPos); - - qreal stopProgress = progressForValue(sp->scrollingCurve, qAbs((stopPos - startPos) / deltaPos)); - - if (!canOvershoot) { - qScrollerDebug() << "Overshoot stopp:" << stopProgress; - - pushSegment(ScrollTypeFlick, deltaTime, stopProgress, startPos, endPos, stopPos, sp->scrollingCurve.type(), orientation); - } else { - qreal oDeltaTime = sp->overshootScrollTime; - qreal oStopProgress = qMin(stopProgress + oDeltaTime * qreal(0.3) / deltaTime, qreal(1)); - qreal oDistance = startPos + deltaPos * sp->scrollingCurve.valueForProgress(oStopProgress) - stopPos; - qreal oMaxDistance = qSign(oDistance) * (viewSize * sp->overshootScrollDistanceFactor); - - qScrollerDebug() << "1 oDistance:" << oDistance << "Max:" << oMaxDistance << "stopP/oStopP" << stopProgress << oStopProgress; - - if (qAbs(oDistance) > qAbs(oMaxDistance)) { - oStopProgress = progressForValue(sp->scrollingCurve, qAbs((stopPos + oMaxDistance - startPos) / deltaPos)); - oDistance = oMaxDistance; - qScrollerDebug() << "2 oDistance:" << oDistance << "Max:" << oMaxDistance << "stopP/oStopP" << stopProgress << oStopProgress; - } - - pushSegment(ScrollTypeFlick, deltaTime, oStopProgress, startPos, deltaPos, stopPos + oDistance, sp->scrollingCurve.type(), orientation); - pushSegment(ScrollTypeOvershoot, oDeltaTime * qreal(0.7), qreal(1.0), stopPos + oDistance, -oDistance, stopPos, sp->scrollingCurve.type(), orientation); - } - return; - } - - pushSegment(ScrollTypeFlick, deltaTime, qreal(1.0), startPos, deltaPos, endPos, sp->scrollingCurve.type(), orientation); -} - - -/*! \internal - Prepares scrolling by sending a QScrollPrepareEvent to the receiver widget. - Returns true if the scrolling was accepted and a target was returned. -*/ -bool QScrollerPrivate::prepareScrolling(const QPointF &position) -{ - QScrollPrepareEvent spe(position); - spe.ignore(); - sendEvent(target, &spe); - - qScrollerDebug() << "QScrollPrepareEvent returned from" << target << "with" << spe.isAccepted() << "mcp:" << spe.contentPosRange() << "cp:" << spe.contentPos(); - if (spe.isAccepted()) { - QPointF oldContentPos = contentPosition + overshootPosition; - QPointF contentDelta = spe.contentPos() - oldContentPos; - - viewportSize = spe.viewportSize(); - contentPosRange = spe.contentPosRange(); - if (contentPosRange.width() < 0) - contentPosRange.setWidth(0); - if (contentPosRange.height() < 0) - contentPosRange.setHeight(0); - contentPosition = clampToRect(spe.contentPos(), contentPosRange); - overshootPosition = spe.contentPos() - contentPosition; - - // - check if the content position was moved - if (contentDelta != QPointF(0, 0)) { - // need to correct all segments - for (int i = 0; i < xSegments.count(); i++) - xSegments[i].startPos -= contentDelta.x(); - - for (int i = 0; i < ySegments.count(); i++) - ySegments[i].startPos -= contentDelta.y(); - } - - if (QWidget *w = qobject_cast<QWidget *>(target)) - setDpiFromWidget(w); -#ifndef QT_NO_GRAPHICSVIEW - if (QGraphicsObject *go = qobject_cast<QGraphicsObject *>(target)) { - //TODO: the first view isn't really correct - maybe use an additional field in the prepare event? - if (go->scene() && !go->scene()->views().isEmpty()) - setDpiFromWidget(go->scene()->views().first()); - } -#endif - - if (state == QScroller::Scrolling) { - recalcScrollingSegments(); - } - return true; - } - - return false; -} - -void QScrollerPrivate::handleDrag(const QPointF &position, qint64 timestamp) -{ - const QScrollerPropertiesPrivate *sp = properties.d.data(); - - QPointF deltaPixel = position - lastPosition; - qint64 deltaTime = timestamp - lastTimestamp; - - if (sp->axisLockThreshold) { - int dx = qAbs(deltaPixel.x()); - int dy = qAbs(deltaPixel.y()); - if (dx || dy) { - bool vertical = (dy > dx); - qreal alpha = qreal(vertical ? dx : dy) / qreal(vertical ? dy : dx); - //qScrollerDebug() << "QScroller::handleDrag() -- axis lock:" << alpha << " / " << axisLockThreshold << "- isvertical:" << vertical << "- dx:" << dx << "- dy:" << dy; - if (alpha <= sp->axisLockThreshold) { - if (vertical) - deltaPixel.setX(0); - else - deltaPixel.setY(0); - } - } - } - - // calculate velocity (if the user would release the mouse NOW) - updateVelocity(deltaPixel, deltaTime); - - // restrict velocity, if content is not scrollable - QRectF max = contentPosRange; - bool canScrollX = (max.width() > 0) || (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn); - bool canScrollY = (max.height() > 0) || (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn); - - if (!canScrollX) { - deltaPixel.setX(0); - releaseVelocity.setX(0); - } - if (!canScrollY) { - deltaPixel.setY(0); - releaseVelocity.setY(0); - } - -// if (firstDrag) { -// // Do not delay the first drag -// setContentPositionHelper(q->contentPosition() - overshootDistance - deltaPixel); -// dragDistance = QPointF(0, 0); -// } else { - dragDistance += deltaPixel; -// } -//qScrollerDebug() << "######################" << deltaPixel << position.y() << lastPosition.y(); - if (canScrollX) - lastPosition.setX(position.x()); - if (canScrollY) - lastPosition.setY(position.y()); - lastTimestamp = timestamp; -} - -bool QScrollerPrivate::pressWhileInactive(const QPointF &position, qint64 timestamp) -{ - if (prepareScrolling(position)) { - const QScrollerPropertiesPrivate *sp = properties.d.data(); - - if (!contentPosRange.isNull() || - (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn) || - (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn)) { - - lastPosition = pressPosition = position; - lastTimestamp = pressTimestamp = timestamp; - setState(QScroller::Pressed); - } - } - return false; -} - -bool QScrollerPrivate::releaseWhilePressed(const QPointF &, qint64) -{ - if (overshootPosition != QPointF(0.0, 0.0)) { - setState(QScroller::Scrolling); - return true; - } else { - setState(QScroller::Inactive); - return false; - } -} - -bool QScrollerPrivate::moveWhilePressed(const QPointF &position, qint64 timestamp) -{ - Q_Q(QScroller); - const QScrollerPropertiesPrivate *sp = properties.d.data(); - QPointF ppm = q->pixelPerMeter(); - - QPointF deltaPixel = position - pressPosition; - - bool moveAborted = false; - bool moveStarted = (((deltaPixel / ppm).manhattanLength()) > sp->dragStartDistance); - - // check the direction of the mouse drag and abort if it's too much in the wrong direction. - if (moveStarted) { - QRectF max = contentPosRange; - bool canScrollX = (max.width() > 0); - bool canScrollY = (max.height() > 0); - - if (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn) - canScrollX = true; - if (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn) - canScrollY = true; - - if (qAbs(deltaPixel.x() / ppm.x()) < qAbs(deltaPixel.y() / ppm.y())) { - if (!canScrollY) - moveAborted = true; - } else { - if (!canScrollX) - moveAborted = true; - } - } - - if (moveAborted) { - setState(QScroller::Inactive); - moveStarted = false; - - } else if (moveStarted) { - setState(QScroller::Dragging); - - // subtract the dragStartDistance - deltaPixel = deltaPixel - deltaPixel * (sp->dragStartDistance / deltaPixel.manhattanLength()); - - if (deltaPixel != QPointF(0, 0)) { - // handleDrag updates lastPosition, lastTimestamp and velocity - handleDrag(pressPosition + deltaPixel, timestamp); - } - } - return moveStarted; -} - -bool QScrollerPrivate::moveWhileDragging(const QPointF &position, qint64 timestamp) -{ - // handleDrag updates lastPosition, lastTimestamp and velocity - handleDrag(position, timestamp); - return true; -} - -void QScrollerPrivate::timerEventWhileDragging() -{ - if (dragDistance != QPointF(0, 0)) { - qScrollerDebug() << "QScroller::timerEventWhileDragging() -- dragDistance:" << dragDistance; - - setContentPositionHelperDragging(-dragDistance); - dragDistance = QPointF(0, 0); - } -} - -bool QScrollerPrivate::releaseWhileDragging(const QPointF &position, qint64 timestamp) -{ - Q_Q(QScroller); - const QScrollerPropertiesPrivate *sp = properties.d.data(); - - // handleDrag updates lastPosition, lastTimestamp and velocity - handleDrag(position, timestamp); - - // check if we moved at all - this can happen if you stop a running - // scroller with a press and release shortly afterwards - QPointF deltaPixel = position - pressPosition; - if (((deltaPixel / q->pixelPerMeter()).manhattanLength()) > sp->dragStartDistance) { - - // handle accelerating flicks - if ((oldVelocity != QPointF(0, 0)) && sp->acceleratingFlickMaximumTime && - ((timestamp - pressTimestamp) < qint64(sp->acceleratingFlickMaximumTime * 1000))) { - - // - determine if the direction was changed - int signX = 0, signY = 0; - if (releaseVelocity.x()) - signX = (releaseVelocity.x() > 0) == (oldVelocity.x() > 0) ? 1 : -1; - if (releaseVelocity.y()) - signY = (releaseVelocity.y() > 0) == (oldVelocity.y() > 0) ? 1 : -1; - - if (signX > 0) - releaseVelocity.setX(qBound(-sp->maximumVelocity, - oldVelocity.x() * sp->acceleratingFlickSpeedupFactor, - sp->maximumVelocity)); - if (signY > 0) - releaseVelocity.setY(qBound(-sp->maximumVelocity, - oldVelocity.y() * sp->acceleratingFlickSpeedupFactor, - sp->maximumVelocity)); - } - } - - QPointF ppm = q->pixelPerMeter(); - createScrollingSegments(releaseVelocity.x(), contentPosition.x() + overshootPosition.x(), ppm.x(), Qt::Horizontal); - createScrollingSegments(releaseVelocity.y(), contentPosition.y() + overshootPosition.y(), ppm.y(), Qt::Vertical); - - qScrollerDebug() << "QScroller::releaseWhileDragging() -- velocity:" << releaseVelocity << "-- minimum velocity:" << sp->minimumVelocity << "overshoot" << overshootPosition; - - if (xSegments.isEmpty() && ySegments.isEmpty()) - setState(QScroller::Inactive); - else - setState(QScroller::Scrolling); - - return true; -} - -void QScrollerPrivate::timerEventWhileScrolling() -{ - qScrollerDebug() << "QScroller::timerEventWhileScrolling()"; - - setContentPositionHelperScrolling(); - if (xSegments.isEmpty() && ySegments.isEmpty()) - setState(QScroller::Inactive); -} - -bool QScrollerPrivate::pressWhileScrolling(const QPointF &position, qint64 timestamp) -{ - Q_Q(QScroller); - - if ((q->velocity() <= properties.d->maximumClickThroughVelocity) && - (overshootPosition == QPointF(0.0, 0.0))) { - setState(QScroller::Inactive); - return false; - } else { - lastPosition = pressPosition = position; - lastTimestamp = pressTimestamp = timestamp; - setState(QScroller::Pressed); - setState(QScroller::Dragging); - return true; - } -} - -/*! \internal - This function handles all state changes of the scroller. -*/ -void QScrollerPrivate::setState(QScroller::State newstate) -{ - Q_Q(QScroller); - bool sendLastScroll = false; - - if (state == newstate) - return; - - qScrollerDebug() << q << "QScroller::setState(" << stateName(newstate) << ")"; - - switch (newstate) { - case QScroller::Inactive: -#ifndef QT_NO_ANIMATION - scrollTimer->stop(); -#endif - - // send the last scroll event (but only after the current state change was finished) - if (!firstScroll) - sendLastScroll = true; - - releaseVelocity = QPointF(0, 0); - break; - - case QScroller::Pressed: -#ifndef QT_NO_ANIMATION - scrollTimer->stop(); -#endif - - oldVelocity = releaseVelocity; - releaseVelocity = QPointF(0, 0); - break; - - case QScroller::Dragging: - dragDistance = QPointF(0, 0); -#ifndef QT_NO_ANIMATION - if (state == QScroller::Pressed) - scrollTimer->start(); -#endif - break; - - case QScroller::Scrolling: -#ifndef QT_NO_ANIMATION - scrollTimer->start(); -#endif - break; - } - - qSwap(state, newstate); - - if (sendLastScroll) { - QScrollEvent se(contentPosition, overshootPosition, QScrollEvent::ScrollFinished); - sendEvent(target, &se); - firstScroll = true; - } - if (state == QScroller::Dragging || state == QScroller::Scrolling) - qt_activeScrollers()->insert(q); - else - qt_activeScrollers()->remove(q); - emit q->stateChanged(state); -} - - -/*! \internal - Helps when setting the content position. - It will try to move the content by the requested delta but stop in case - when we are coming back from an overshoot or a scrollTo. - It will also indicate a new overshooting condition by the overshootX and oversthootY flags. - - In this cases it will reset the velocity variables and other flags. - - Also keeps track of the current over-shooting value in overshootPosition. - - \a deltaPos is the amount of pixels the current content position should be moved -*/ -void QScrollerPrivate::setContentPositionHelperDragging(const QPointF &deltaPos) -{ - Q_Q(QScroller); - QPointF ppm = q->pixelPerMeter(); - const QScrollerPropertiesPrivate *sp = properties.d.data(); - QPointF v = q->velocity(); - - if (sp->overshootDragResistanceFactor) - overshootPosition /= sp->overshootDragResistanceFactor; - - QPointF oldPos = contentPosition + overshootPosition; - QPointF newPos = oldPos + deltaPos; - - qScrollerDebug() << "QScroller::setContentPositionHelperDragging(" << deltaPos << " [pix])"; - qScrollerDebug() << " --> overshoot:" << overshootPosition << "- old pos:" << oldPos << "- new pos:" << newPos; - - QPointF oldClampedPos = clampToRect(oldPos, contentPosRange); - QPointF newClampedPos = clampToRect(newPos, contentPosRange); - - // --- handle overshooting and stop if the coordinate is going back inside the normal area - bool alwaysOvershootX = (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOn); - bool alwaysOvershootY = (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOn); - bool noOvershootX = (sp->hOvershootPolicy == QScrollerProperties::OvershootAlwaysOff) || - ((state == QScroller::Dragging) && !sp->overshootDragResistanceFactor) || - !sp->overshootDragDistanceFactor; - bool noOvershootY = (sp->vOvershootPolicy == QScrollerProperties::OvershootAlwaysOff) || - ((state == QScroller::Dragging) && !sp->overshootDragResistanceFactor) || - !sp->overshootDragDistanceFactor; - bool canOvershootX = !noOvershootX && (alwaysOvershootX || contentPosRange.width()); - bool canOvershootY = !noOvershootY && (alwaysOvershootY || contentPosRange.height()); - - qreal oldOvershootX = (canOvershootX) ? oldPos.x() - oldClampedPos.x() : 0; - qreal oldOvershootY = (canOvershootY) ? oldPos.y() - oldClampedPos.y() : 0; - - qreal newOvershootX = (canOvershootX) ? newPos.x() - newClampedPos.x() : 0; - qreal newOvershootY = (canOvershootY) ? newPos.y() - newClampedPos.y() : 0; - - qreal maxOvershootX = viewportSize.width() * sp->overshootDragDistanceFactor; - qreal maxOvershootY = viewportSize.height() * sp->overshootDragDistanceFactor; - - qScrollerDebug() << " --> noOs:" << noOvershootX << "drf:" << sp->overshootDragResistanceFactor << "mdf:" << sp->overshootScrollDistanceFactor << "ossP:"<<sp->hOvershootPolicy; - qScrollerDebug() << " --> canOS:" << canOvershootX << "newOS:" << newOvershootX << "maxOS:" << maxOvershootX; - - if (sp->overshootDragResistanceFactor) { - oldOvershootX *= sp->overshootDragResistanceFactor; - oldOvershootY *= sp->overshootDragResistanceFactor; - newOvershootX *= sp->overshootDragResistanceFactor; - newOvershootY *= sp->overshootDragResistanceFactor; - } - - // -- stop at the maximum overshoot distance - - newOvershootX = qBound(-maxOvershootX, newOvershootX, maxOvershootX); - newOvershootY = qBound(-maxOvershootY, newOvershootY, maxOvershootY); - - overshootPosition.setX(newOvershootX); - overshootPosition.setY(newOvershootY); - contentPosition = newClampedPos; - - QScrollEvent se(contentPosition, overshootPosition, firstScroll ? QScrollEvent::ScrollStarted : QScrollEvent::ScrollUpdated); - sendEvent(target, &se); - firstScroll = false; - - qScrollerDebug() << " --> new position:" << newClampedPos << "- new overshoot:" << overshootPosition << - "- overshoot x/y?:" << overshootPosition; -} - - -qreal QScrollerPrivate::nextSegmentPosition(QQueue<ScrollSegment> &segments, qint64 now, qreal oldPos) -{ - qreal pos = oldPos; - - // check the X segments for new positions - while (!segments.isEmpty()) { - const ScrollSegment s = segments.head(); - - if ((s.startTime + s.deltaTime * s.stopProgress) <= now) { - segments.dequeue(); - pos = s.stopPos; - } else if (s.startTime <= now) { - qreal progress = qreal(now - s.startTime) / qreal(s.deltaTime); - pos = s.startPos + s.deltaPos * s.curve.valueForProgress(progress); - if (s.deltaPos > 0 ? pos > s.stopPos : pos < s.stopPos) { - segments.dequeue(); - pos = s.stopPos; - } else { - break; - } - } else { - break; - } - } - return pos; -} - -void QScrollerPrivate::setContentPositionHelperScrolling() -{ - qint64 now = monotonicTimer.elapsed(); - QPointF newPos = contentPosition + overshootPosition; - - newPos.setX(nextSegmentPosition(xSegments, now, newPos.x())); - newPos.setY(nextSegmentPosition(ySegments, now, newPos.y())); - - // -- set the position and handle overshoot - qScrollerDebug() << "QScroller::setContentPositionHelperScrolling()"; - qScrollerDebug() << " --> overshoot:" << overshootPosition << "- new pos:" << newPos; - - QPointF newClampedPos = clampToRect(newPos, contentPosRange); - - overshootPosition = newPos - newClampedPos; - contentPosition = newClampedPos; - - QScrollEvent se(contentPosition, overshootPosition, firstScroll ? QScrollEvent::ScrollStarted : QScrollEvent::ScrollUpdated); - sendEvent(target, &se); - firstScroll = false; - - qScrollerDebug() << " --> new position:" << newClampedPos << "- new overshoot:" << overshootPosition; -} - -/*! \internal - Returns the next snap point in direction. - If \a direction >0 it will return the next snap point that is larger than the current position. - If \a direction <0 it will return the next snap point that is smaller than the current position. - If \a direction ==0 it will return the nearest snap point (or the current position if we are already - on a snap point. - Returns the nearest snap position or NaN if no such point could be found. - */ -qreal QScrollerPrivate::nextSnapPos(qreal p, int dir, Qt::Orientation orientation) -{ - qreal bestSnapPos = Q_QNAN; - qreal bestSnapPosDist = Q_INFINITY; - - qreal minPos; - qreal maxPos; - - if (orientation == Qt::Horizontal) { - minPos = contentPosRange.left(); - maxPos = contentPosRange.right(); - } else { - minPos = contentPosRange.top(); - maxPos = contentPosRange.bottom(); - } - - if (orientation == Qt::Horizontal) { - // the snap points in the list - foreach (qreal snapPos, snapPositionsX) { - qreal snapPosDist = snapPos - p; - if ((dir > 0 && snapPosDist < 0) || - (dir < 0 && snapPosDist > 0)) - continue; // wrong direction - if (snapPos < minPos || snapPos > maxPos ) - continue; // invalid - - if (qIsNaN(bestSnapPos) || - qAbs(snapPosDist) < bestSnapPosDist ) { - bestSnapPos = snapPos; - bestSnapPosDist = qAbs(snapPosDist); - } - } - - // the snap point interval - if (snapIntervalX > 0.0) { - qreal first = minPos + snapFirstX; - qreal snapPos; - if (dir > 0) - snapPos = qCeil((p - first) / snapIntervalX) * snapIntervalX + first; - else if (dir < 0) - snapPos = qFloor((p - first) / snapIntervalX) * snapIntervalX + first; - else if (p <= first) - snapPos = first; - else - { - qreal last = qFloor((maxPos - first) / snapIntervalX) * snapIntervalX + first; - if (p >= last) - snapPos = last; - else - snapPos = qRound((p - first) / snapIntervalX) * snapIntervalX + first; - } - - if (snapPos >= first && snapPos <= maxPos ) { - qreal snapPosDist = snapPos - p; - - if (qIsNaN(bestSnapPos) || - qAbs(snapPosDist) < bestSnapPosDist ) { - bestSnapPos = snapPos; - bestSnapPosDist = qAbs(snapPosDist); - } - } - } - - } else { // (orientation == Qt::Vertical) - // the snap points in the list - foreach (qreal snapPos, snapPositionsY) { - qreal snapPosDist = snapPos - p; - if ((dir > 0 && snapPosDist < 0) || - (dir < 0 && snapPosDist > 0)) - continue; // wrong direction - if (snapPos < minPos || snapPos > maxPos ) - continue; // invalid - - if (qIsNaN(bestSnapPos) || - qAbs(snapPosDist) < bestSnapPosDist) { - bestSnapPos = snapPos; - bestSnapPosDist = qAbs(snapPosDist); - } - } - - // the snap point interval - if (snapIntervalY > 0.0) { - qreal first = minPos + snapFirstY; - qreal snapPos; - if (dir > 0) - snapPos = qCeil((p - first) / snapIntervalY) * snapIntervalY + first; - else if (dir < 0) - snapPos = qFloor((p - first) / snapIntervalY) * snapIntervalY + first; - else if (p <= first) - snapPos = first; - else - { - qreal last = qFloor((maxPos - first) / snapIntervalY) * snapIntervalY + first; - if (p >= last) - snapPos = last; - else - snapPos = qRound((p - first) / snapIntervalY) * snapIntervalY + first; - } - - if (snapPos >= first && snapPos <= maxPos ) { - qreal snapPosDist = snapPos - p; - - if (qIsNaN(bestSnapPos) || - qAbs(snapPosDist) < bestSnapPosDist) { - bestSnapPos = snapPos; - bestSnapPosDist = qAbs(snapPosDist); - } - } - } - } - - return bestSnapPos; -} - -/*! - \enum QScroller::State - - This enum contains the different QScroller states. - - \value Inactive The scroller is not scrolling and nothing is pressed. - \value Pressed A touch event was received or the mouse button was pressed but the scroll area is currently not dragged. - \value Dragging The scroll area is currently following the touch point or mouse. - \value Scrolling The scroll area is moving on it's own. -*/ - -/*! - \enum QScroller::ScrollerGestureType - - This enum contains the different gesture types that are supported by the QScroller gesture recognizer. - - \value TouchGesture The gesture recognizer will only trigger on touch - events. Specifically it will react on single touch points when using a - touch screen and dual touch points when using a touchpad. - \value LeftMouseButtonGesture The gesture recognizer will only trigger on left mouse button events. - \value MiddleMouseButtonGesture The gesture recognizer will only trigger on middle mouse button events. - \value RightMouseButtonGesture The gesture recognizer will only trigger on right mouse button events. -*/ - -/*! - \enum QScroller::Input - - This enum contains an input device agnostic view of input events that are relevant for QScroller. - - \value InputPress The user pressed the input device (e.g. QEvent::MouseButtonPress, - QEvent::GraphicsSceneMousePress, QEvent::TouchBegin) - - \value InputMove The user moved the input device (e.g. QEvent::MouseMove, - QEvent::GraphicsSceneMouseMove, QEvent::TouchUpdate) - - \value InputRelease The user released the input device (e.g. QEvent::MouseButtonRelease, - QEvent::GraphicsSceneMouseRelease, QEvent::TouchEnd) - -*/ - -QT_END_NAMESPACE diff --git a/src/gui/util/qscroller.h b/src/gui/util/qscroller.h deleted file mode 100644 index 1599c7d..0000000 --- a/src/gui/util/qscroller.h +++ /dev/null @@ -1,155 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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 QSCROLLER_H -#define QSCROLLER_H - -#include <QtCore/QObject> -#include <QtCore/QPointF> -#include <QtGui/QScrollerProperties> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QWidget; -class QScrollerPrivate; -class QScrollerProperties; -#ifndef QT_NO_GESTURES -class QFlickGestureRecognizer; -class QMouseFlickGestureRecognizer; -#endif - -class Q_GUI_EXPORT QScroller : public QObject -{ - Q_OBJECT - Q_PROPERTY(State state READ state NOTIFY stateChanged) - Q_PROPERTY(QScrollerProperties scrollerProperties READ scrollerProperties WRITE setScrollerProperties NOTIFY scrollerPropertiesChanged) - Q_ENUMS(State) - -public: - enum State - { - Inactive, - Pressed, - Dragging, - Scrolling - }; - - enum ScrollerGestureType - { - TouchGesture, - LeftMouseButtonGesture, - RightMouseButtonGesture, - MiddleMouseButtonGesture - }; - - enum Input - { - InputPress = 1, - InputMove, - InputRelease - }; - - static bool hasScroller(QObject *target); - - static QScroller *scroller(QObject *target); - static const QScroller *scroller(const QObject *target); - -#ifndef QT_NO_GESTURES - static Qt::GestureType grabGesture(QObject *target, ScrollerGestureType gestureType = TouchGesture); - static Qt::GestureType grabbedGesture(QObject *target); - static void ungrabGesture(QObject *target); -#endif - - static QList<QScroller *> activeScrollers(); - - QObject *target() const; - - State state() const; - - bool handleInput(Input input, const QPointF &position, qint64 timestamp = 0); - - void stop(); - QPointF velocity() const; - QPointF finalPosition() const; - QPointF pixelPerMeter() const; - - QScrollerProperties scrollerProperties() const; - - void setSnapPositionsX( const QList<qreal> &positions ); - void setSnapPositionsX( qreal first, qreal interval ); - void setSnapPositionsY( const QList<qreal> &positions ); - void setSnapPositionsY( qreal first, qreal interval ); - -public Q_SLOTS: - void setScrollerProperties(const QScrollerProperties &prop); - void scrollTo(const QPointF &pos); - void scrollTo(const QPointF &pos, int scrollTime); - void ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin); - void ensureVisible(const QRectF &rect, qreal xmargin, qreal ymargin, int scrollTime); - void resendPrepareEvent(); - -Q_SIGNALS: - void stateChanged(QScroller::State newstate); - void scrollerPropertiesChanged(const QScrollerProperties &); - -private: - QScrollerPrivate *d_ptr; - - QScroller(QObject *target); - virtual ~QScroller(); - - Q_DISABLE_COPY(QScroller) - Q_DECLARE_PRIVATE(QScroller) - -#ifndef QT_NO_GESTURES - friend class QFlickGestureRecognizer; -#endif -}; - -QT_END_NAMESPACE - -QT_END_HEADER - -#endif // QSCROLLER_H diff --git a/src/gui/util/qscroller_p.h b/src/gui/util/qscroller_p.h deleted file mode 100644 index c119615..0000000 --- a/src/gui/util/qscroller_p.h +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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 QSCROLLER_P_H -#define QSCROLLER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QObject> -#include <QPointer> -#include <QQueue> -#include <QSet> -#include <QEasingCurve> -#include <QElapsedTimer> -#include <QSizeF> -#include <QPointF> -#include <QRectF> -#include <qscroller.h> -#include <qscrollerproperties.h> -#include <private/qscrollerproperties_p.h> -#include <QAbstractAnimation> - -QT_BEGIN_NAMESPACE - -#ifndef QT_NO_GESTURES -class QFlickGestureRecognizer; -#endif - -#ifndef QT_NO_ANIMATION -class QScrollTimer; -#endif -class QScrollerPrivate : public QObject -{ - Q_OBJECT - Q_DECLARE_PUBLIC(QScroller) - -public: - QScrollerPrivate(QScroller *q, QObject *target); - void init(); - - void sendEvent(QObject *o, QEvent *e); - - void setState(QScroller::State s); - - enum ScrollType { - ScrollTypeFlick = 0, - ScrollTypeScrollTo, - ScrollTypeOvershoot - }; - - struct ScrollSegment { - qint64 startTime; - qint64 deltaTime; - qreal startPos; - qreal deltaPos; - QEasingCurve curve; - qreal stopProgress; // whatever is.. - qreal stopPos; // ..reached first - ScrollType type; - }; - - bool pressWhileInactive(const QPointF &position, qint64 timestamp); - bool moveWhilePressed(const QPointF &position, qint64 timestamp); - bool releaseWhilePressed(const QPointF &position, qint64 timestamp); - bool moveWhileDragging(const QPointF &position, qint64 timestamp); - bool releaseWhileDragging(const QPointF &position, qint64 timestamp); - bool pressWhileScrolling(const QPointF &position, qint64 timestamp); - - void timerTick(); - void timerEventWhileDragging(); - void timerEventWhileScrolling(); - - bool prepareScrolling(const QPointF &position); - void handleDrag(const QPointF &position, qint64 timestamp); - - QPointF realDpi(int screen); - QPointF dpi() const; - void setDpi(const QPointF &dpi); - void setDpiFromWidget(QWidget *widget); - - void updateVelocity(const QPointF &deltaPixelRaw, qint64 deltaTime); - void pushSegment(ScrollType type, qreal deltaTime, qreal stopProgress, qreal startPos, qreal deltaPos, qreal stopPos, QEasingCurve::Type curve, Qt::Orientation orientation); - void recalcScrollingSegments(bool forceRecalc = false); - qreal scrollingSegmentsEndPos(Qt::Orientation orientation) const; - bool scrollingSegmentsValid(Qt::Orientation orientation); - void createScrollToSegments(qreal v, qreal deltaTime, qreal endPos, Qt::Orientation orientation, ScrollType type); - void createScrollingSegments(qreal v, qreal startPos, qreal ppm, Qt::Orientation orientation); - - void setContentPositionHelperDragging(const QPointF &deltaPos); - void setContentPositionHelperScrolling(); - - qreal nextSnapPos(qreal p, int dir, Qt::Orientation orientation); - static qreal nextSegmentPosition(QQueue<ScrollSegment> &segments, qint64 now, qreal oldPos); - - inline int frameRateSkip() const { return properties.d.data()->frameRate; } - - static const char *stateName(QScroller::State state); - static const char *inputName(QScroller::Input input); - -public slots: - void targetDestroyed(); - -public: - // non static - QObject *target; - QScrollerProperties properties; -#ifndef QT_NO_GESTURES - QFlickGestureRecognizer *recognizer; - Qt::GestureType recognizerType; -#endif - - // scroller state: - - // QPointer<QObject> scrollTarget; - QSizeF viewportSize; - QRectF contentPosRange; - QPointF contentPosition; - QPointF overshootPosition; // the number of pixels we are overshooting (before overshootDragResistanceFactor) - - // state - - bool enabled; - QScroller::State state; - bool firstScroll; // true if we haven't already send a scroll event - - QPointF oldVelocity; // the release velocity of the last drag - - QPointF pressPosition; - QPointF lastPosition; - qint64 pressTimestamp; - qint64 lastTimestamp; - - QPointF dragDistance; // the distance we should move during the next drag timer event - - QQueue<ScrollSegment> xSegments; - QQueue<ScrollSegment> ySegments; - - // snap positions - QList<qreal> snapPositionsX; - qreal snapFirstX; - qreal snapIntervalX; - QList<qreal> snapPositionsY; - qreal snapFirstY; - qreal snapIntervalY; - - QPointF pixelPerMeter; - - QElapsedTimer monotonicTimer; - - QPointF releaseVelocity; // the starting velocity of the scrolling state -#ifndef QT_NO_ANIMATION - QScrollTimer *scrollTimer; -#endif - - QScroller *q_ptr; -}; - - -QT_END_NAMESPACE - -#endif // QSCROLLER_P_H - diff --git a/src/gui/util/qscrollerproperties.cpp b/src/gui/util/qscrollerproperties.cpp deleted file mode 100644 index 85e2e82..0000000 --- a/src/gui/util/qscrollerproperties.cpp +++ /dev/null @@ -1,393 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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 <QPointer> -#include <QObject> -#include <QtCore/qmath.h> -#ifdef Q_WS_WIN -# include <QLibrary> -#endif - -#include "qscrollerproperties.h" -#include "private/qscrollerproperties_p.h" - -QT_BEGIN_NAMESPACE - -static QScrollerPropertiesPrivate *userDefaults = 0; -static QScrollerPropertiesPrivate *systemDefaults = 0; - -QScrollerPropertiesPrivate *QScrollerPropertiesPrivate::defaults() -{ - if (!systemDefaults) { - QScrollerPropertiesPrivate spp; - spp.mousePressEventDelay = qreal(0.25); - spp.dragStartDistance = qreal(5.0 / 1000); - spp.dragVelocitySmoothingFactor = qreal(0.8); - spp.axisLockThreshold = qreal(0); - spp.scrollingCurve.setType(QEasingCurve::OutQuad); - spp.decelerationFactor = qreal(0.125); - spp.minimumVelocity = qreal(50.0 / 1000); - spp.maximumVelocity = qreal(500.0 / 1000); - spp.maximumClickThroughVelocity = qreal(66.5 / 1000); - spp.acceleratingFlickMaximumTime = qreal(1.25); - spp.acceleratingFlickSpeedupFactor = qreal(3.0); - spp.snapPositionRatio = qreal(0.5); - spp.snapTime = qreal(0.3); - spp.overshootDragResistanceFactor = qreal(0.5); - spp.overshootDragDistanceFactor = qreal(1); - spp.overshootScrollDistanceFactor = qreal(0.5); - spp.overshootScrollTime = qreal(0.7); -# ifdef Q_WS_WIN - if (QLibrary::resolve(QLatin1String("UxTheme"), "BeginPanningFeedback")) - spp.overshootScrollTime = qreal(0.35); -# endif - spp.hOvershootPolicy = QScrollerProperties::OvershootWhenScrollable; - spp.vOvershootPolicy = QScrollerProperties::OvershootWhenScrollable; - spp.frameRate = QScrollerProperties::Standard; - - systemDefaults = new QScrollerPropertiesPrivate(spp); - } - return new QScrollerPropertiesPrivate(userDefaults ? *userDefaults : *systemDefaults); -} - -/*! - \class QScrollerProperties - \brief The QScrollerProperties class stores the settings for a QScroller. - \since 4.8 - - The QScrollerProperties class stores the parameters used by QScroller. - - The default settings are platform dependent so that Qt emulates the - platform behaviour for kinetic scrolling. - - As a convention the QScrollerProperties are in physical units (meter, - seconds) and are converted by QScroller using the current DPI. - - \sa QScroller -*/ - -/*! - Constructs new scroller properties. -*/ -QScrollerProperties::QScrollerProperties() - : d(QScrollerPropertiesPrivate::defaults()) -{ -} - -/*! - Constructs a copy of \a sp. -*/ -QScrollerProperties::QScrollerProperties(const QScrollerProperties &sp) - : d(new QScrollerPropertiesPrivate(*sp.d)) -{ -} - -/*! - Assigns \a sp to these scroller properties and returns a reference to these scroller properties. -*/ -QScrollerProperties &QScrollerProperties::operator=(const QScrollerProperties &sp) -{ - *d.data() = *sp.d.data(); - return *this; -} - -/*! - Destroys the scroller properties. -*/ -QScrollerProperties::~QScrollerProperties() -{ -} - -/*! - Returns true if these scroller properties are equal to \a sp; otherwise returns false. -*/ -bool QScrollerProperties::operator==(const QScrollerProperties &sp) const -{ - return *d.data() == *sp.d.data(); -} - -/*! - Returns true if these scroller properties are different from \a sp; otherwise returns false. -*/ -bool QScrollerProperties::operator!=(const QScrollerProperties &sp) const -{ - return !(*d.data() == *sp.d.data()); -} - -bool QScrollerPropertiesPrivate::operator==(const QScrollerPropertiesPrivate &p) const -{ - bool same = true; - same &= (mousePressEventDelay == p.mousePressEventDelay); - same &= (dragStartDistance == p.dragStartDistance); - same &= (dragVelocitySmoothingFactor == p.dragVelocitySmoothingFactor); - same &= (axisLockThreshold == p.axisLockThreshold); - same &= (scrollingCurve == p.scrollingCurve); - same &= (decelerationFactor == p.decelerationFactor); - same &= (minimumVelocity == p.minimumVelocity); - same &= (maximumVelocity == p.maximumVelocity); - same &= (maximumClickThroughVelocity == p.maximumClickThroughVelocity); - same &= (acceleratingFlickMaximumTime == p.acceleratingFlickMaximumTime); - same &= (acceleratingFlickSpeedupFactor == p.acceleratingFlickSpeedupFactor); - same &= (snapPositionRatio == p.snapPositionRatio); - same &= (snapTime == p.snapTime); - same &= (overshootDragResistanceFactor == p.overshootDragResistanceFactor); - same &= (overshootDragDistanceFactor == p.overshootDragDistanceFactor); - same &= (overshootScrollDistanceFactor == p.overshootScrollDistanceFactor); - same &= (overshootScrollTime == p.overshootScrollTime); - same &= (hOvershootPolicy == p.hOvershootPolicy); - same &= (vOvershootPolicy == p.vOvershootPolicy); - same &= (frameRate == p.frameRate); - return same; -} - -/*! - Sets the scroller properties for all new QScrollerProperties objects to \a sp. - - Use this function to override the platform default properties returned by the default - constructor. If you only want to change the scroller properties of a single scroller, use - QScroller::setScrollerProperties() - - \note Calling this function will not change the content of already existing - QScrollerProperties objects. - - \sa unsetDefaultScrollerProperties() -*/ -void QScrollerProperties::setDefaultScrollerProperties(const QScrollerProperties &sp) -{ - if (!userDefaults) - userDefaults = new QScrollerPropertiesPrivate(*sp.d); - else - *userDefaults = *sp.d; -} - -/*! - Sets the scroller properties returned by the default constructor back to the platform default - properties. - - \sa setDefaultScrollerProperties() -*/ -void QScrollerProperties::unsetDefaultScrollerProperties() -{ - delete userDefaults; - userDefaults = 0; -} - -/*! - Query the \a metric value of the scroller properties. - - \sa setScrollMetric(), ScrollMetric -*/ -QVariant QScrollerProperties::scrollMetric(ScrollMetric metric) const -{ - switch (metric) { - case MousePressEventDelay: return d->mousePressEventDelay; - case DragStartDistance: return d->dragStartDistance; - case DragVelocitySmoothingFactor: return d->dragVelocitySmoothingFactor; - case AxisLockThreshold: return d->axisLockThreshold; - case ScrollingCurve: return d->scrollingCurve; - case DecelerationFactor: return d->decelerationFactor; - case MinimumVelocity: return d->minimumVelocity; - case MaximumVelocity: return d->maximumVelocity; - case MaximumClickThroughVelocity: return d->maximumClickThroughVelocity; - case AcceleratingFlickMaximumTime: return d->acceleratingFlickMaximumTime; - case AcceleratingFlickSpeedupFactor:return d->acceleratingFlickSpeedupFactor; - case SnapPositionRatio: return d->snapPositionRatio; - case SnapTime: return d->snapTime; - case OvershootDragResistanceFactor: return d->overshootDragResistanceFactor; - case OvershootDragDistanceFactor: return d->overshootDragDistanceFactor; - case OvershootScrollDistanceFactor: return d->overshootScrollDistanceFactor; - case OvershootScrollTime: return d->overshootScrollTime; - case HorizontalOvershootPolicy: return QVariant::fromValue(d->hOvershootPolicy); - case VerticalOvershootPolicy: return QVariant::fromValue(d->vOvershootPolicy); - case FrameRate: return QVariant::fromValue(d->frameRate); - case ScrollMetricCount: break; - } - return QVariant(); -} - -/*! - Set a specific value of the \a metric ScrollerMetric to \a value. - - \sa scrollMetric(), ScrollMetric -*/ -void QScrollerProperties::setScrollMetric(ScrollMetric metric, const QVariant &value) -{ - switch (metric) { - case MousePressEventDelay: d->mousePressEventDelay = value.toReal(); break; - case DragStartDistance: d->dragStartDistance = value.toReal(); break; - case DragVelocitySmoothingFactor: d->dragVelocitySmoothingFactor = qBound(qreal(0), value.toReal(), qreal(1)); break; - case AxisLockThreshold: d->axisLockThreshold = qBound(qreal(0), value.toReal(), qreal(1)); break; - case ScrollingCurve: d->scrollingCurve = value.toEasingCurve(); break; - case DecelerationFactor: d->decelerationFactor = value.toReal(); break; - case MinimumVelocity: d->minimumVelocity = value.toReal(); break; - case MaximumVelocity: d->maximumVelocity = value.toReal(); break; - case MaximumClickThroughVelocity: d->maximumClickThroughVelocity = value.toReal(); break; - case AcceleratingFlickMaximumTime: d->acceleratingFlickMaximumTime = value.toReal(); break; - case AcceleratingFlickSpeedupFactor:d->acceleratingFlickSpeedupFactor = value.toReal(); break; - case SnapPositionRatio: d->snapPositionRatio = qBound(qreal(0), value.toReal(), qreal(1)); break; - case SnapTime: d->snapTime = value.toReal(); break; - case OvershootDragResistanceFactor: d->overshootDragResistanceFactor = value.toReal(); break; - case OvershootDragDistanceFactor: d->overshootDragDistanceFactor = qBound(qreal(0), value.toReal(), qreal(1)); break; - case OvershootScrollDistanceFactor: d->overshootScrollDistanceFactor = qBound(qreal(0), value.toReal(), qreal(1)); break; - case OvershootScrollTime: d->overshootScrollTime = value.toReal(); break; - case HorizontalOvershootPolicy: d->hOvershootPolicy = value.value<QScrollerProperties::OvershootPolicy>(); break; - case VerticalOvershootPolicy: d->vOvershootPolicy = value.value<QScrollerProperties::OvershootPolicy>(); break; - case FrameRate: d->frameRate = value.value<QScrollerProperties::FrameRates>(); break; - case ScrollMetricCount: break; - } -} - -/*! - \enum QScrollerProperties::FrameRates - - This enum describes the available frame rates used while dragging or scrolling. - - \value Fps60 60 frames per second - \value Fps30 30 frames per second - \value Fps20 20 frames per second - \value Standard the default value is 60 frames per second (which corresponds to QAbstractAnimation). -*/ - -/*! - \enum QScrollerProperties::OvershootPolicy - - This enum describes the various modes of overshooting. - - \value OvershootWhenScrollable Overshooting is possible when the content is scrollable. This is the - default. - - \value OvershootAlwaysOff Overshooting is never enabled, even when the content is scrollable. - - \value OvershootAlwaysOn Overshooting is always enabled, even when the content is not - scrollable. -*/ - -/*! - \enum QScrollerProperties::ScrollMetric - - This enum contains the different scroll metric types. When not indicated otherwise the - setScrollMetric function expects a QVariant of type qreal. - - See the QScroller documentation for further details of the concepts behind the different - values. - - \value MousePressEventDelay This is the time a mouse press event is delayed when starting - a flick gesture in \c{[s]}. If the gesture is triggered within that time, no mouse press or - release is sent to the scrolled object. If it triggers after that delay the delayed - mouse press plus a faked release event at global postion \c{QPoint(-QWIDGETSIZE_MAX, - -QWIDGETSIZE_MAX)} is sent. If the gesture is canceled, then both the delayed mouse - press plus the real release event are delivered. - - \value DragStartDistance This is the minimum distance the touch or mouse point needs to be - moved before the flick gesture is triggered in \c m. - - \value DragVelocitySmoothingFactor A value that describes to which extent new drag velocities are - included in the final scrolling velocity. This value should be in the range between \c 0 and - \c 1. The lower the value, the more smoothing is applied to the dragging velocity. - - \value AxisLockThreshold Restricts the movement to one axis if the movement is inside an angle - around the axis. The threshold must be in the range \c 0 to \c 1. - - \value ScrollingCurve The QEasingCurve used when decelerating the scrolling velocity after an - user initiated flick. Please note that this is the easing curve for the positions, \bold{not} - the velocity: the default is QEasingCurve::OutQuad, which results in a linear decrease in - velocity (1st derivative) and a constant deceleration (2nd derivative). - - \value DecelerationFactor This factor influences how long it takes the scroller to decelerate - to 0 velocity. The actual value depends on the chosen ScrollingCurve. For most - types the value should be in the range from \c 0.1 to \c 2.0 - - \value MinimumVelocity The minimum velocity that is needed after ending the touch or releasing - the mouse to start scrolling in \c{m/s}. - - \value MaximumVelocity This is the maximum velocity that can be reached in \c{m/s}. - - \value MaximumClickThroughVelocity This is the maximum allowed scroll speed for a click-through - in \c{m/s}. This means that a click on a currently (slowly) scrolling object will not only stop - the scrolling but the click event will also be delivered to the UI control. This is - useful when using exponential-type scrolling curves. - - \value AcceleratingFlickMaximumTime This is the maximum time in \c seconds that a flick gesture - can take to be recognized as an accelerating flick. If set to zero no such gesture is - detected. An "accelerating flick" is a flick gesture executed on an already scrolling object. - In such cases the scrolling speed is multiplied by AcceleratingFlickSpeedupFactor in order to - accelerate it. - - \value AcceleratingFlickSpeedupFactor The current speed is multiplied by this number if an - accelerating flick is detected. Should be \c{>= 1}. - - \value SnapPositionRatio This is the distance that the user must drag the area beween two snap - points in order to snap it to the next position. \c{0.33} means that the scroll must only - reach one third of the distance between two snap points to snap to the next one. The ratio must - be between \c 0 and \c 1. - - \value SnapTime This is the time factor for the scrolling curve. A lower value means that the - scrolling will take longer. The scrolling distance is independet of this value. - - \value OvershootDragResistanceFactor This value is the factor between the mouse dragging and - the actual scroll area movement (during overshoot). The factor must be between \c 0 and \c 1. - - \value OvershootDragDistanceFactor This is the maximum distance for overshoot movements while - dragging. The actual overshoot distance is calculated by multiplying this value with the - viewport size of the scrolled object. The factor must be between \c 0 and \c 1. - - \value OvershootScrollDistanceFactor This is the maximum distance for overshoot movements while - scrolling. The actual overshoot distance is calculated by multiplying this value with the - viewport size of the scrolled object. The factor must be between \c 0 and \c 1. - - \value OvershootScrollTime This is the time in \c seconds that is used to play the - complete overshoot animation. - - \value HorizontalOvershootPolicy This is the horizontal overshooting policy (see OvershootPolicy). - - \value VerticalOvershootPolicy This is the horizontal overshooting policy (see OvershootPolicy). - - \value FrameRate This is the frame rate which should be used while dragging or scrolling. - QScroller uses a QAbstractAnimation timer internally to sync all scrolling operations to other - animations that might be active at the same time. If the standard value of 60 frames per - second is too fast, it can be lowered with this setting, - while still being in-sync with QAbstractAnimation. Please note that only the values of the - FrameRates enum are allowed here. - - \value ScrollMetricCount This is always the last entry. -*/ - -QT_END_NAMESPACE diff --git a/src/gui/util/qscrollerproperties.h b/src/gui/util/qscrollerproperties.h deleted file mode 100644 index 75d8932..0000000 --- a/src/gui/util/qscrollerproperties.h +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 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 QSCROLLERPROPERTIES_H -#define QSCROLLERPROPERTIES_H - -#include <QtCore/QScopedPointer> -#include <QtCore/QMetaType> -#include <QtCore/QVariant> - -QT_BEGIN_HEADER - -QT_BEGIN_NAMESPACE - -QT_MODULE(Gui) - -class QScroller; -class QScrollerPrivate; -class QScrollerPropertiesPrivate; - -class Q_GUI_EXPORT QScrollerProperties -{ -public: - QScrollerProperties(); - QScrollerProperties(const QScrollerProperties &sp); - QScrollerProperties &operator=(const QScrollerProperties &sp); - virtual ~QScrollerProperties(); - - bool operator==(const QScrollerProperties &sp) const; - bool operator!=(const QScrollerProperties &sp) const; - - static void setDefaultScrollerProperties(const QScrollerProperties &sp); - static void unsetDefaultScrollerProperties(); - - enum OvershootPolicy - { - OvershootWhenScrollable, - OvershootAlwaysOff, - OvershootAlwaysOn - }; - - enum FrameRates { - Standard, - Fps60, - Fps30, - Fps20 - }; - - enum ScrollMetric - { - MousePressEventDelay, // qreal [s] - DragStartDistance, // qreal [m] - DragVelocitySmoothingFactor, // qreal [0..1/s] (complex calculation involving time) v = v_new* DASF + v_old * (1-DASF) - AxisLockThreshold, // qreal [0..1] atan(|min(dx,dy)|/|max(dx,dy)|) - - ScrollingCurve, // QEasingCurve - DecelerationFactor, // slope of the curve - - MinimumVelocity, // qreal [m/s] - MaximumVelocity, // qreal [m/s] - MaximumClickThroughVelocity, // qreal [m/s] - - AcceleratingFlickMaximumTime, // qreal [s] - AcceleratingFlickSpeedupFactor, // qreal [1..] - - SnapPositionRatio, // qreal [0..1] - SnapTime, // qreal [s] - - OvershootDragResistanceFactor, // qreal [0..1] - OvershootDragDistanceFactor, // qreal [0..1] - OvershootScrollDistanceFactor, // qreal [0..1] - OvershootScrollTime, // qreal [s] - - HorizontalOvershootPolicy, // enum OvershootPolicy - VerticalOvershootPolicy, // enum OvershootPolicy - FrameRate, // enum FrameRates - - ScrollMetricCount - }; - - QVariant scrollMetric(ScrollMetric metric) const; - void setScrollMetric(ScrollMetric metric, const QVariant &value); - -protected: - QScopedPointer<QScrollerPropertiesPrivate> d; - -private: - QScrollerProperties(QScrollerPropertiesPrivate &dd); - - friend class QScrollerPropertiesPrivate; - friend class QScroller; - friend class QScrollerPrivate; -}; - -QT_END_NAMESPACE - -Q_DECLARE_METATYPE(QScrollerProperties::OvershootPolicy) -Q_DECLARE_METATYPE(QScrollerProperties::FrameRates) - -QT_END_HEADER - -#endif // QSCROLLERPROPERTIES_H diff --git a/src/gui/util/qundogroup.cpp b/src/gui/util/qundogroup.cpp index 42cda74..a24ce8d 100644 --- a/src/gui/util/qundogroup.cpp +++ b/src/gui/util/qundogroup.cpp @@ -375,15 +375,18 @@ bool QUndoGroup::isClean() const for undo, if the group is empty or if none of the stacks are active, this action will be disabled. - If \a prefix is empty, the default prefix "Undo" is used. + If \a prefix is empty, the default template "Undo %1" is used instead of prefix. + Before Qt 4.8, the prefix "Undo" was used by default. \sa createRedoAction() canUndo() QUndoCommand::text() */ QAction *QUndoGroup::createUndoAction(QObject *parent, const QString &prefix) const { - QString pref = prefix.isEmpty() ? tr("Undo") : prefix; - QUndoAction *result = new QUndoAction(pref, parent); + QUndoAction *result = new QUndoAction(prefix, parent); + if (prefix.isEmpty()) + result->setTextFormat(tr("Undo %1"), tr("Undo", "Default text for undo action")); + result->setEnabled(canUndo()); result->setPrefixedText(undoText()); connect(this, SIGNAL(canUndoChanged(bool)), @@ -403,15 +406,18 @@ QAction *QUndoGroup::createUndoAction(QObject *parent, const QString &prefix) co for redo, if the group is empty or if none of the stacks are active, this action will be disabled. - If \a prefix is empty, the default prefix "Undo" is used. + If \a prefix is empty, the default template "Redo %1" is used instead of prefix. + Before Qt 4.8, the prefix "Redo" was used by default. \sa createUndoAction() canRedo() QUndoCommand::text() */ QAction *QUndoGroup::createRedoAction(QObject *parent, const QString &prefix) const { - QString pref = prefix.isEmpty() ? tr("Redo") : prefix; - QUndoAction *result = new QUndoAction(pref, parent); + QUndoAction *result = new QUndoAction(prefix, parent); + if (prefix.isEmpty()) + result->setTextFormat(tr("Redo %1"), tr("Redo", "Default text for redo action")); + result->setEnabled(canRedo()); result->setPrefixedText(redoText()); connect(this, SIGNAL(canRedoChanged(bool)), diff --git a/src/gui/util/qundostack.cpp b/src/gui/util/qundostack.cpp index 6b038ee..1dfab5d 100644 --- a/src/gui/util/qundostack.cpp +++ b/src/gui/util/qundostack.cpp @@ -114,7 +114,7 @@ QUndoCommand::QUndoCommand(const QString &text, QUndoCommand *parent) d = new QUndoCommandPrivate; if (parent != 0) parent->d->child_list.append(this); - d->text = text; + setText(text); } /*! @@ -230,10 +230,9 @@ void QUndoCommand::undo() Returns a short text string describing what this command does; for example, "insert text". - The text is used when the text properties of the stack's undo and redo - actions are updated. + The text is used for names of items in QUndoView. - \sa setText(), QUndoStack::createUndoAction(), QUndoStack::createRedoAction() + \sa actionText(), setText(), QUndoStack::createUndoAction(), QUndoStack::createRedoAction() */ QString QUndoCommand::text() const @@ -242,17 +241,47 @@ QString QUndoCommand::text() const } /*! + \since 4.8 + + Returns a short text string describing what this command does; for example, + "insert text". + + The text is used when the text properties of the stack's undo and redo + actions are updated. + + \sa text(), setText(), QUndoStack::createUndoAction(), QUndoStack::createRedoAction() +*/ + +QString QUndoCommand::actionText() const +{ + return d->actionText; +} + +/*! Sets the command's text to be the \a text specified. The specified text should be a short user-readable string describing what this command does. - \sa text() QUndoStack::createUndoAction() QUndoStack::createRedoAction() + If you need to have two different strings for text() and actionText(), separate + them with "\n" and pass into this function. Even if you do not use this feature + for English strings during development, you can still let translators use two + different strings in order to match specific languages' needs. + The described feature and the function actionText() are available since Qt 4.8. + + \sa text() actionText() QUndoStack::createUndoAction() QUndoStack::createRedoAction() */ void QUndoCommand::setText(const QString &text) { - d->text = text; + int cdpos = text.indexOf(QLatin1Char('\n')); + if (cdpos > 0) { + d->text = text.left(cdpos); + d->actionText = text.mid(cdpos + 1); + } else { + d->text = text; + d->actionText = text; + } } /*! @@ -374,11 +403,24 @@ QUndoAction::QUndoAction(const QString &prefix, QObject *parent) void QUndoAction::setPrefixedText(const QString &text) { - QString s = m_prefix; - if (!m_prefix.isEmpty() && !text.isEmpty()) - s.append(QLatin1Char(' ')); - s.append(text); - setText(s); + if (m_defaultText.isEmpty()) { + QString s = m_prefix; + if (!m_prefix.isEmpty() && !text.isEmpty()) + s.append(QLatin1Char(' ')); + s.append(text); + setText(s); + } else { + if (text.isEmpty()) + setText(m_defaultText); + else + setText(m_prefix.arg(text)); + } +} + +void QUndoAction::setTextFormat(const QString &textFormat, const QString &defaultText) +{ + m_prefix = textFormat; + m_defaultText = defaultText; } #endif // QT_NO_ACTION @@ -783,7 +825,7 @@ bool QUndoStack::canRedo() const /*! Returns the text of the command which will be undone in the next call to undo(). - \sa QUndoCommand::text() redoText() + \sa QUndoCommand::actionText() redoText() */ QString QUndoStack::undoText() const @@ -792,14 +834,14 @@ QString QUndoStack::undoText() const if (!d->macro_stack.isEmpty()) return QString(); if (d->index > 0) - return d->command_list.at(d->index - 1)->text(); + return d->command_list.at(d->index - 1)->actionText(); return QString(); } /*! Returns the text of the command which will be redone in the next call to redo(). - \sa QUndoCommand::text() undoText() + \sa QUndoCommand::actionText() undoText() */ QString QUndoStack::redoText() const @@ -808,7 +850,7 @@ QString QUndoStack::redoText() const if (!d->macro_stack.isEmpty()) return QString(); if (d->index < d->command_list.size()) - return d->command_list.at(d->index)->text(); + return d->command_list.at(d->index)->actionText(); return QString(); } @@ -822,15 +864,18 @@ QString QUndoStack::redoText() const prefixed by the specified \a prefix. If there is no command available for undo, this action will be disabled. - If \a prefix is empty, the default prefix "Undo" is used. + If \a prefix is empty, the default template "Undo %1" is used instead of prefix. + Before Qt 4.8, the prefix "Undo" was used by default. \sa createRedoAction(), canUndo(), QUndoCommand::text() */ QAction *QUndoStack::createUndoAction(QObject *parent, const QString &prefix) const { - QString pref = prefix.isEmpty() ? tr("Undo") : prefix; - QUndoAction *result = new QUndoAction(pref, parent); + QUndoAction *result = new QUndoAction(prefix, parent); + if (prefix.isEmpty()) + result->setTextFormat(tr("Undo %1"), tr("Undo", "Default text for undo action")); + result->setEnabled(canUndo()); result->setPrefixedText(undoText()); connect(this, SIGNAL(canUndoChanged(bool)), @@ -849,15 +894,18 @@ QAction *QUndoStack::createUndoAction(QObject *parent, const QString &prefix) co prefixed by the specified \a prefix. If there is no command available for redo, this action will be disabled. - If \a prefix is empty, the default prefix "Redo" is used. + If \a prefix is empty, the default template "Redo %1" is used instead of prefix. + Before Qt 4.8, the prefix "Redo" was used by default. \sa createUndoAction(), canRedo(), QUndoCommand::text() */ QAction *QUndoStack::createRedoAction(QObject *parent, const QString &prefix) const { - QString pref = prefix.isEmpty() ? tr("Redo") : prefix; - QUndoAction *result = new QUndoAction(pref, parent); + QUndoAction *result = new QUndoAction(prefix, parent); + if (prefix.isEmpty()) + result->setTextFormat(tr("Redo %1"), tr("Redo", "Default text for redo action")); + result->setEnabled(canRedo()); result->setPrefixedText(redoText()); connect(this, SIGNAL(canRedoChanged(bool)), diff --git a/src/gui/util/qundostack.h b/src/gui/util/qundostack.h index 65941b5..700996f 100644 --- a/src/gui/util/qundostack.h +++ b/src/gui/util/qundostack.h @@ -70,6 +70,7 @@ public: virtual void redo(); QString text() const; + QString actionText() const; void setText(const QString &text); virtual int id() const; diff --git a/src/gui/util/qundostack_p.h b/src/gui/util/qundostack_p.h index 3c7d0e7..a100763 100644 --- a/src/gui/util/qundostack_p.h +++ b/src/gui/util/qundostack_p.h @@ -70,6 +70,7 @@ public: QUndoCommandPrivate() : id(-1) {} QList<QUndoCommand*> child_list; QString text; + QString actionText; int id; }; @@ -98,10 +99,12 @@ class QUndoAction : public QAction Q_OBJECT public: QUndoAction(const QString &prefix, QObject *parent = 0); + void setTextFormat(const QString &textFormat, const QString &defaultText); public Q_SLOTS: void setPrefixedText(const QString &text); private: QString m_prefix; + QString m_defaultText; }; #endif // QT_NO_ACTION diff --git a/src/gui/util/util.pri b/src/gui/util/util.pri index 2814a2d..f125f82 100644 --- a/src/gui/util/util.pri +++ b/src/gui/util/util.pri @@ -6,11 +6,6 @@ HEADERS += \ util/qcompleter_p.h \ util/qdesktopservices.h \ util/qsystemtrayicon_p.h \ - util/qscroller.h \ - util/qscroller_p.h \ - util/qscrollerproperties.h \ - util/qscrollerproperties_p.h \ - util/qflickgesture_p.h \ util/qundogroup.h \ util/qundostack.h \ util/qundostack_p.h \ @@ -20,9 +15,6 @@ SOURCES += \ util/qsystemtrayicon.cpp \ util/qcompleter.cpp \ util/qdesktopservices.cpp \ - util/qscroller.cpp \ - util/qscrollerproperties.cpp \ - util/qflickgesture.cpp \ util/qundogroup.cpp \ util/qundostack.cpp \ util/qundoview.cpp @@ -65,7 +57,3 @@ symbian { DEFINES += USE_SCHEMEHANDLER } } - -macx { - OBJECTIVE_SOURCES += util/qscroller_mac.mm -} diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index dabfec0..2503b99 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -53,8 +53,6 @@ #include "qpainter.h" #include "qmargins.h" -#include <QDebug> - #include "qabstractscrollarea_p.h" #include <qwidget.h> @@ -64,10 +62,6 @@ #include <private/qt_mac_p.h> #include <private/qt_cocoa_helpers_mac_p.h> #endif -#ifdef Q_WS_WIN -# include <qlibrary.h> -# include <windows.h> -#endif QT_BEGIN_NAMESPACE @@ -301,14 +295,9 @@ void QAbstractScrollAreaPrivate::init() q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); layoutChildren(); #ifndef Q_WS_MAC -# ifndef QT_NO_GESTURES +#ifndef QT_NO_GESTURES viewport->grabGesture(Qt::PanGesture); -# endif #endif -#ifdef Q_WS_MAEMO_5 -# ifndef QT_NO_GESTURES - // viewport->grabGesture(Qt::TouchFlickGesture); -# endif #endif } @@ -563,11 +552,6 @@ void QAbstractScrollArea::setViewport(QWidget *widget) d->viewport->grabGesture(Qt::PanGesture); #endif #endif -#ifdef Q_WS_MAEMO_5 -#ifndef QT_NO_GESTURES -// d->viewport->grabGesture(Qt::TouchFlickGesture); -#endif -#endif d->layoutChildren(); if (isVisible()) d->viewport->show(); @@ -1002,66 +986,6 @@ bool QAbstractScrollArea::event(QEvent *e) return false; } #endif // QT_NO_GESTURES - case QEvent::ScrollPrepare: - { - QScrollPrepareEvent *se = static_cast<QScrollPrepareEvent *>(e); - if (d->canStartScrollingAt(se->startPos().toPoint())) { - QScrollBar *hBar = horizontalScrollBar(); - QScrollBar *vBar = verticalScrollBar(); - - se->setViewportSize(QSizeF(viewport()->size())); - se->setContentPosRange(QRectF(0, 0, hBar->maximum(), vBar->maximum())); - se->setContentPos(QPointF(hBar->value(), vBar->value())); - se->accept(); - return true; - } - return false; - } - case QEvent::Scroll: - { - QScrollEvent *se = static_cast<QScrollEvent *>(e); - - QScrollBar *hBar = horizontalScrollBar(); - QScrollBar *vBar = verticalScrollBar(); - hBar->setValue(se->contentPos().x()); - vBar->setValue(se->contentPos().y()); - -#ifdef Q_WS_WIN - typedef BOOL (*PtrBeginPanningFeedback)(HWND); - typedef BOOL (*PtrUpdatePanningFeedback)(HWND, LONG, LONG, BOOL); - typedef BOOL (*PtrEndPanningFeedback)(HWND, BOOL); - - static PtrBeginPanningFeedback ptrBeginPanningFeedback = 0; - static PtrUpdatePanningFeedback ptrUpdatePanningFeedback = 0; - static PtrEndPanningFeedback ptrEndPanningFeedback = 0; - - if (!ptrBeginPanningFeedback) - ptrBeginPanningFeedback = (PtrBeginPanningFeedback) QLibrary::resolve(QLatin1String("UxTheme"), "BeginPanningFeedback"); - if (!ptrUpdatePanningFeedback) - ptrUpdatePanningFeedback = (PtrUpdatePanningFeedback) QLibrary::resolve(QLatin1String("UxTheme"), "UpdatePanningFeedback"); - if (!ptrEndPanningFeedback) - ptrEndPanningFeedback = (PtrEndPanningFeedback) QLibrary::resolve(QLatin1String("UxTheme"), "EndPanningFeedback"); - - if (ptrBeginPanningFeedback && ptrUpdatePanningFeedback && ptrEndPanningFeedback) { - WId wid = window()->winId(); - - if (!se->overshootDistance().isNull() && d->overshoot.isNull()) - ptrBeginPanningFeedback(wid); - if (!se->overshootDistance().isNull()) - ptrUpdatePanningFeedback(wid, -se->overshootDistance().x(), -se->overshootDistance().y(), false); - if (se->overshootDistance().isNull() && !d->overshoot.isNull()) - ptrEndPanningFeedback(wid, true); - } else -#endif - { - QPoint delta = d->overshoot - se->overshootDistance().toPoint(); - if (!delta.isNull()) - viewport()->move(viewport()->pos() + delta); - } - d->overshoot = se->overshootDistance().toPoint(); - - return true; - } case QEvent::StyleChange: case QEvent::LayoutDirectionChange: case QEvent::ApplicationLayoutDirectionChange: @@ -1123,9 +1047,6 @@ bool QAbstractScrollArea::viewportEvent(QEvent *e) case QEvent::GestureOverride: return event(e); #endif - case QEvent::ScrollPrepare: - case QEvent::Scroll: - return event(e); default: break; } @@ -1382,32 +1303,6 @@ void QAbstractScrollArea::scrollContentsBy(int, int) viewport()->update(); } -bool QAbstractScrollAreaPrivate::canStartScrollingAt( const QPoint &startPos ) -{ - Q_Q(QAbstractScrollArea); - -#ifndef QT_NO_GRAPHICSVIEW - // don't start scrolling when a drag mode has been set. - // don't start scrolling on a movable item. - if (QGraphicsView *view = qobject_cast<QGraphicsView *>(q)) { - if (view->dragMode() != QGraphicsView::NoDrag) - return false; - - QGraphicsItem *childItem = view->itemAt(startPos); - - if (childItem && (childItem->flags() & QGraphicsItem::ItemIsMovable)) - return false; - } -#endif - - // don't start scrolling on a QAbstractSlider - if (qobject_cast<QAbstractSlider *>(q->viewport()->childAt(startPos))) { - return false; - } - - return true; -} - void QAbstractScrollAreaPrivate::_q_hslide(int x) { Q_Q(QAbstractScrollArea); diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h index 76e1c34..85536e3 100644 --- a/src/gui/widgets/qabstractscrollarea_p.h +++ b/src/gui/widgets/qabstractscrollarea_p.h @@ -84,13 +84,11 @@ public: int left, top, right, bottom; // viewport margin int xoffset, yoffset; - QPoint overshoot; void init(); void layoutChildren(); // ### Fix for 4.4, talk to Bjoern E or Girish. virtual void scrollBarPolicyChanged(Qt::Orientation, Qt::ScrollBarPolicy) {} - bool canStartScrollingAt( const QPoint &startPos ); void _q_hslide(int); void _q_vslide(int); diff --git a/src/gui/widgets/qdatetimeedit.cpp b/src/gui/widgets/qdatetimeedit.cpp index 6337113..a4739a7 100644 --- a/src/gui/widgets/qdatetimeedit.cpp +++ b/src/gui/widgets/qdatetimeedit.cpp @@ -2538,20 +2538,32 @@ void QDateTimeEditPrivate::syncCalendarWidget() } QCalendarPopup::QCalendarPopup(QWidget * parent, QCalendarWidget *cw) - : QWidget(parent, Qt::Popup), calendar(0) + : QWidget(parent, Qt::Popup) { setAttribute(Qt::WA_WindowPropagation); dateChanged = false; if (!cw) { - cw = new QCalendarWidget(this); + verifyCalendarInstance(); + } else { + setCalendarWidget(cw); + } +} + +QCalendarWidget *QCalendarPopup::verifyCalendarInstance() +{ + if (calendar.isNull()) { + QCalendarWidget *cw = new QCalendarWidget(this); cw->setVerticalHeaderFormat(QCalendarWidget::NoVerticalHeader); #ifdef QT_KEYPAD_NAVIGATION if (QApplication::keypadNavigationEnabled()) cw->setHorizontalHeaderFormat(QCalendarWidget::SingleLetterDayNames); #endif + setCalendarWidget(cw); + return cw; + } else { + return calendar.data(); } - setCalendarWidget(cw); } void QCalendarPopup::setCalendarWidget(QCalendarWidget *cw) @@ -2563,28 +2575,29 @@ void QCalendarPopup::setCalendarWidget(QCalendarWidget *cw) widgetLayout->setMargin(0); widgetLayout->setSpacing(0); } - delete calendar; - calendar = cw; - widgetLayout->addWidget(calendar); + delete calendar.data(); + calendar = QWeakPointer<QCalendarWidget>(cw); + widgetLayout->addWidget(cw); - connect(calendar, SIGNAL(activated(QDate)), this, SLOT(dateSelected(QDate))); - connect(calendar, SIGNAL(clicked(QDate)), this, SLOT(dateSelected(QDate))); - connect(calendar, SIGNAL(selectionChanged()), this, SLOT(dateSelectionChanged())); + connect(cw, SIGNAL(activated(QDate)), this, SLOT(dateSelected(QDate))); + connect(cw, SIGNAL(clicked(QDate)), this, SLOT(dateSelected(QDate))); + connect(cw, SIGNAL(selectionChanged()), this, SLOT(dateSelectionChanged())); - calendar->setFocus(); + cw->setFocus(); } void QCalendarPopup::setDate(const QDate &date) { oldDate = date; - calendar->setSelectedDate(date); + verifyCalendarInstance()->setSelectedDate(date); } void QCalendarPopup::setDateRange(const QDate &min, const QDate &max) { - calendar->setMinimumDate(min); - calendar->setMaximumDate(max); + QCalendarWidget *cw = verifyCalendarInstance(); + cw->setMinimumDate(min); + cw->setMaximumDate(max); } void QCalendarPopup::mousePressEvent(QMouseEvent *event) @@ -2620,7 +2633,7 @@ bool QCalendarPopup::event(QEvent *event) void QCalendarPopup::dateSelectionChanged() { dateChanged = true; - emit newDateSelected(calendar->selectedDate()); + emit newDateSelected(verifyCalendarInstance()->selectedDate()); } void QCalendarPopup::dateSelected(const QDate &date) { diff --git a/src/gui/widgets/qdatetimeedit_p.h b/src/gui/widgets/qdatetimeedit_p.h index acdc878..c85c0fb 100644 --- a/src/gui/widgets/qdatetimeedit_p.h +++ b/src/gui/widgets/qdatetimeedit_p.h @@ -148,11 +148,11 @@ class QCalendarPopup : public QWidget Q_OBJECT public: QCalendarPopup(QWidget *parent = 0, QCalendarWidget *cw = 0); - QDate selectedDate() { return calendar->selectedDate(); } + QDate selectedDate() { return verifyCalendarInstance()->selectedDate(); } void setDate(const QDate &date); void setDateRange(const QDate &min, const QDate &max); - void setFirstDayOfWeek(Qt::DayOfWeek dow) { calendar->setFirstDayOfWeek(dow); } - QCalendarWidget *calendarWidget() const { return calendar; } + void setFirstDayOfWeek(Qt::DayOfWeek dow) { verifyCalendarInstance()->setFirstDayOfWeek(dow); } + QCalendarWidget *calendarWidget() const { return const_cast<QCalendarPopup*>(this)->verifyCalendarInstance(); } void setCalendarWidget(QCalendarWidget *cw); Q_SIGNALS: void activated(const QDate &date); @@ -171,7 +171,9 @@ protected: bool event(QEvent *e); private: - QCalendarWidget *calendar; + QCalendarWidget *verifyCalendarInstance(); + + QWeakPointer<QCalendarWidget> calendar; QDate oldDate; bool dateChanged; }; diff --git a/src/gui/widgets/qdockarealayout.cpp b/src/gui/widgets/qdockarealayout.cpp index 223421d..28c0388 100644 --- a/src/gui/widgets/qdockarealayout.cpp +++ b/src/gui/widgets/qdockarealayout.cpp @@ -2100,7 +2100,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const bool gap = false; int tab_idx = 0; - bool changed = false; for (int i = 0; i < item_list.count(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); if (item.skip()) @@ -2121,7 +2120,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const tabBar->setTabToolTip(tab_idx, title); #endif tabBar->setTabData(tab_idx, id); - changed = true; } else if (qvariant_cast<quintptr>(tabBar->tabData(tab_idx)) != id) { if (tab_idx + 1 < tabBar->count() && qvariant_cast<quintptr>(tabBar->tabData(tab_idx + 1)) == id) @@ -2133,7 +2131,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const #endif tabBar->setTabData(tab_idx, id); } - changed = true; } if (title != tabBar->tabText(tab_idx)) { @@ -2141,7 +2138,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const #ifndef QT_NO_TOOLTIP tabBar->setTabToolTip(tab_idx, title); #endif - changed = true; } ++tab_idx; @@ -2149,7 +2145,6 @@ bool QDockAreaLayoutInfo::updateTabBar() const while (tab_idx < tabBar->count()) { tabBar->removeTab(tab_idx); - changed = true; } tabBar->blockSignals(blocked); diff --git a/src/gui/widgets/qdockwidget.cpp b/src/gui/widgets/qdockwidget.cpp index 9d1a737..16b60c8 100644 --- a/src/gui/widgets/qdockwidget.cpp +++ b/src/gui/widgets/qdockwidget.cpp @@ -161,7 +161,6 @@ void QDockWidgetTitleButton::paintEvent(QPaintEvent *) { QPainter p(this); - QRect r = rect(); QStyleOptionToolButton opt; opt.init(this); opt.state |= QStyle::State_AutoRaise; diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp index ced66e5..c9dae77 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -435,6 +435,8 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event) c += event->commitString().length() - qMin(-event->replacementStart(), event->replacementLength()); m_cursor += event->replacementStart(); + if (m_cursor < 0) + m_cursor = 0; // insert commit string if (event->replacementLength()) { @@ -447,7 +449,7 @@ void QLineControl::processInputMethodEvent(QInputMethodEvent *event) cursorPositionChanged = true; } - m_cursor = qMin(c, m_text.length()); + m_cursor = qBound(0, c, m_text.length()); for (int i = 0; i < event->attributes().size(); ++i) { const QInputMethodEvent::Attribute &a = event->attributes().at(i); @@ -1593,6 +1595,7 @@ void QLineControl::processKeyEvent(QKeyEvent* event) } bool unknown = false; + bool visual = cursorMoveStyle() == Qt::VisualMoveStyle; if (false) { } @@ -1657,11 +1660,11 @@ void QLineControl::processKeyEvent(QKeyEvent* event) #endif moveCursor(selectionEnd(), false); } else { - cursorForward(0, layoutDirection() == Qt::LeftToRight ? 1 : -1); + cursorForward(0, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1)); } } else if (event == QKeySequence::SelectNextChar) { - cursorForward(1, layoutDirection() == Qt::LeftToRight ? 1 : -1); + cursorForward(1, visual ? 1 : (layoutDirection() == Qt::LeftToRight ? 1 : -1)); } else if (event == QKeySequence::MoveToPreviousChar) { #if !defined(Q_WS_WIN) || defined(QT_NO_COMPLETER) @@ -1672,11 +1675,11 @@ void QLineControl::processKeyEvent(QKeyEvent* event) #endif moveCursor(selectionStart(), false); } else { - cursorForward(0, layoutDirection() == Qt::LeftToRight ? -1 : 1); + cursorForward(0, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1)); } } else if (event == QKeySequence::SelectPreviousChar) { - cursorForward(1, layoutDirection() == Qt::LeftToRight ? -1 : 1); + cursorForward(1, visual ? -1 : (layoutDirection() == Qt::LeftToRight ? -1 : 1)); } else if (event == QKeySequence::MoveToNextWord) { if (echoMode() == QLineEdit::Normal) diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 7f3cad6..9764ba9 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -160,6 +160,8 @@ public: int cursorWidth() const { return m_cursorWidth; } void setCursorWidth(int value) { m_cursorWidth = value; } + Qt::CursorMoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); } + void setCursorMoveStyle(Qt::CursorMoveStyle style) { m_textLayout.setCursorMoveStyle(style); } void moveCursor(int pos, bool mark = false); void cursorForward(bool mark, int steps) @@ -167,10 +169,12 @@ public: int c = m_cursor; if (steps > 0) { while (steps--) - c = m_textLayout.nextCursorPosition(c); + c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.rightCursorPosition(c) + : m_textLayout.nextCursorPosition(c); } else if (steps < 0) { while (steps++) - c = m_textLayout.previousCursorPosition(c); + c = cursorMoveStyle() == Qt::VisualMoveStyle ? m_textLayout.leftCursorPosition(c) + : m_textLayout.previousCursorPosition(c); } moveCursor(c, mark); } diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index 07bd273..3c9874e 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1112,6 +1112,34 @@ void QLineEdit::setDragEnabled(bool b) /*! + \property QLineEdit::cursorMoveStyle + \brief the movement style of cursor in this line edit + \since 4.8 + + When this property is set to Qt::VisualMoveStyle, the line edit will use visual + movement style. Pressing the left arrow key will always cause the cursor to move + left, regardless of the text's writing direction. The same behavior applies to + right arrow key. + + When the property is Qt::LogicalMoveStyle (the default), within a LTR text block, + increase cursor position when pressing left arrow key, decrease cursor position + when pressing the right arrow key. If the text block is right to left, the opposite + behavior applies. +*/ + +Qt::CursorMoveStyle QLineEdit::cursorMoveStyle() const +{ + Q_D(const QLineEdit); + return d->control->cursorMoveStyle(); +} + +void QLineEdit::setCursorMoveStyle(Qt::CursorMoveStyle style) +{ + Q_D(QLineEdit); + d->control->setCursorMoveStyle(style); +} + +/*! \property QLineEdit::acceptableInput \brief whether the input satisfies the inputMask and the validator. diff --git a/src/gui/widgets/qlineedit.h b/src/gui/widgets/qlineedit.h index 636cee7..e88273f 100644 --- a/src/gui/widgets/qlineedit.h +++ b/src/gui/widgets/qlineedit.h @@ -43,6 +43,7 @@ #define QLINEEDIT_H #include <QtGui/qframe.h> +#include <QtGui/qtextcursor.h> #include <QtCore/qstring.h> #include <QtCore/qmargins.h> @@ -84,6 +85,7 @@ class Q_GUI_EXPORT QLineEdit : public QWidget Q_PROPERTY(bool redoAvailable READ isRedoAvailable) Q_PROPERTY(bool acceptableInput READ hasAcceptableInput) Q_PROPERTY(QString placeholderText READ placeholderText WRITE setPlaceholderText) + Q_PROPERTY(Qt::CursorMoveStyle cursorMoveStyle READ cursorMoveStyle WRITE setCursorMoveStyle) public: explicit QLineEdit(QWidget* parent=0); @@ -158,6 +160,9 @@ public: void setDragEnabled(bool b); bool dragEnabled() const; + void setCursorMoveStyle(Qt::CursorMoveStyle style); + Qt::CursorMoveStyle cursorMoveStyle() const; + QString inputMask() const; void setInputMask(const QString &inputMask); bool hasAcceptableInput() const; diff --git a/src/gui/widgets/qmainwindow.cpp b/src/gui/widgets/qmainwindow.cpp index 43d6796..e39e595 100644 --- a/src/gui/widgets/qmainwindow.cpp +++ b/src/gui/widgets/qmainwindow.cpp @@ -78,7 +78,6 @@ public: : layout(0), explicitIconSize(false), toolButtonStyle(Qt::ToolButtonIconOnly) #ifdef Q_WS_MAC , useHIToolBar(false) - , activateUnifiedToolbarAfterFullScreen(false) #endif #if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_CURSOR) , hasOldCursor(false) , cursorAdjusted(false) @@ -90,7 +89,6 @@ public: Qt::ToolButtonStyle toolButtonStyle; #ifdef Q_WS_MAC bool useHIToolBar; - bool activateUnifiedToolbarAfterFullScreen; #endif void init(); QList<int> hoverSeparator; diff --git a/src/gui/widgets/qmainwindowlayout.cpp b/src/gui/widgets/qmainwindowlayout.cpp index d4afe07..8880ca9 100644 --- a/src/gui/widgets/qmainwindowlayout.cpp +++ b/src/gui/widgets/qmainwindowlayout.cpp @@ -1699,6 +1699,7 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow, QLayout *parentLay , gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow)) #endif //QT_NO_RUBBERBAND #ifdef Q_WS_MAC + , activateUnifiedToolbarAfterFullScreen(false) , blockVisiblityCheck(false) #endif { diff --git a/src/gui/widgets/qmainwindowlayout_p.h b/src/gui/widgets/qmainwindowlayout_p.h index 20aca61..0442510 100644 --- a/src/gui/widgets/qmainwindowlayout_p.h +++ b/src/gui/widgets/qmainwindowlayout_p.h @@ -338,7 +338,6 @@ public: void removeFromMacToolbar(QToolBar *toolbar); void cleanUpMacToolbarItems(); void fixSizeInUnifiedToolbar(QToolBar *tb) const; - bool useHIToolBar; bool activateUnifiedToolbarAfterFullScreen; void syncUnifiedToolbarVisibility(); bool blockVisiblityCheck; diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index b0ea00f..1dac661 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -82,6 +82,10 @@ # include <private/qt_cocoa_helpers_mac_p.h> #endif +#ifdef Q_WS_S60 +# include "private/qt_s60_p.h" +#endif + QT_BEGIN_NAMESPACE @@ -172,6 +176,14 @@ void QMenuPrivate::init() q->addAction(selectAction); q->addAction(cancelAction); #endif + +#ifdef Q_WS_S60 + if (S60->avkonComponentsSupportTransparency) { + bool noSystemBackground = q->testAttribute(Qt::WA_NoSystemBackground); + q->setAttribute(Qt::WA_TranslucentBackground); // also sets WA_NoSystemBackground + q->setAttribute(Qt::WA_NoSystemBackground, noSystemBackground); // restore system background attribute + } +#endif } int QMenuPrivate::scrollerHeight() const diff --git a/src/gui/widgets/qplaintextedit.cpp b/src/gui/widgets/qplaintextedit.cpp index 7435691..51c4ccb 100644 --- a/src/gui/widgets/qplaintextedit.cpp +++ b/src/gui/widgets/qplaintextedit.cpp @@ -483,6 +483,7 @@ int QPlainTextEditPrivate::verticalOffset(int topBlock, int topLine) const QPlainTextDocumentLayout *documentLayout = qobject_cast<QPlainTextDocumentLayout*>(doc->documentLayout()); Q_ASSERT(documentLayout); QRectF r = documentLayout->blockBoundingRect(currentBlock); + Q_UNUSED(r); QTextLayout *layout = currentBlock.layout(); if (layout && topLine <= layout->lineCount()) { QTextLine line = layout->lineAt(topLine - 1); @@ -648,6 +649,11 @@ void QPlainTextEditPrivate::setTopBlock(int blockNumber, int lineNumber, int dx) } control->topBlock = blockNumber; topLine = lineNumber; + + bool vbarSignalsBlocked = vbar->blockSignals(true); + vbar->setValue(block.firstLineNumber() + lineNumber); + vbar->blockSignals(vbarSignalsBlocked); + if (dx || dy) viewport->scroll(q->isRightToLeft() ? -dx : dx, dy); else diff --git a/src/gui/widgets/qtextedit.cpp b/src/gui/widgets/qtextedit.cpp index ff924bf..8df436f 100644 --- a/src/gui/widgets/qtextedit.cpp +++ b/src/gui/widgets/qtextedit.cpp @@ -2614,7 +2614,6 @@ Qt::TextFormat QTextEdit::textFormat() const void QTextEdit::append(const QString &text) { Q_D(QTextEdit); - QTextBlock lastBlock = d->control->document()->lastBlock(); const bool atBottom = isReadOnly() ? d->verticalOffset() >= d->vbar->maximum() : d->control->textCursor().atEnd(); d->control->append(text); diff --git a/src/gui/widgets/qworkspace.cpp b/src/gui/widgets/qworkspace.cpp index bf50d07..13ef13b 100644 --- a/src/gui/widgets/qworkspace.cpp +++ b/src/gui/widgets/qworkspace.cpp @@ -1239,7 +1239,6 @@ QWidget * QWorkspace::addWindow(QWidget *w, Qt::WindowFlags flags) int x = w->x(); int y = w->y(); bool hasPos = w->testAttribute(Qt::WA_Moved); - QSize s = w->size().expandedTo(qSmartMinSize(w)); if (!hasSize && w->sizeHint().isValid()) w->adjustSize(); diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 07dd729..a471559 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -519,6 +519,15 @@ bool QHttpNetworkConnectionPrivate::dequeueRequest(QAbstractSocket *socket) return false; } +QHttpNetworkRequest QHttpNetworkConnectionPrivate::predictNextRequest() +{ + if (!highPriorityQueue.isEmpty()) + return highPriorityQueue.last().first; + if (!lowPriorityQueue.isEmpty()) + return lowPriorityQueue.last().first; + return QHttpNetworkRequest(); +} + // this is called from _q_startNextRequest and when a request has been sent down a socket from the channel void QHttpNetworkConnectionPrivate::fillPipeline(QAbstractSocket *socket) { diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index adb779f4..329d3626 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -169,6 +169,7 @@ public: void requeueRequest(const HttpMessagePair &pair); // e.g. after pipeline broke bool dequeueRequest(QAbstractSocket *socket); void prepareRequest(HttpMessagePair &request); + QHttpNetworkRequest predictNextRequest(); void fillPipeline(QAbstractSocket *socket); bool fillPipeline(QList<HttpMessagePair> &queue, QHttpNetworkConnectionChannel &channel); diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index 6fbc6f8..f440101 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -579,6 +579,17 @@ bool QHttpNetworkConnectionChannel::ensureConnection() connectHost = connection->d_func()->networkProxy.hostName(); connectPort = connection->d_func()->networkProxy.port(); } + if (socket->proxy().type() == QNetworkProxy::HttpProxy) { + // Make user-agent field available to HTTP proxy socket engine (QTBUG-17223) + QByteArray value; + // ensureConnection is called before any request has been assigned, but can also be called again if reconnecting + if (request.url().isEmpty()) + value = connection->d_func()->predictNextRequest().headerField("user-agent"); + else + value = request.headerField("user-agent"); + if (!value.isEmpty()) + socket->setProperty("_q_user-agent", value); + } #endif if (ssl) { #ifndef QT_NO_OPENSSL diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp index 99f9376..0364dac 100644 --- a/src/network/access/qhttpthreaddelegate.cpp +++ b/src/network/access/qhttpthreaddelegate.cpp @@ -51,6 +51,7 @@ #include "private/qnetworkaccesscache_p.h" #include "private/qnoncontiguousbytedevice_p.h" +#ifndef QT_NO_HTTP QT_BEGIN_NAMESPACE @@ -576,4 +577,6 @@ void QHttpThreadDelegate::synchronousProxyAuthenticationRequiredSlot(const QNet #endif +#endif // QT_NO_HTTP + QT_END_NAMESPACE diff --git a/src/network/access/qhttpthreaddelegate_p.h b/src/network/access/qhttpthreaddelegate_p.h index 752bc09..c0f2077 100644 --- a/src/network/access/qhttpthreaddelegate_p.h +++ b/src/network/access/qhttpthreaddelegate_p.h @@ -68,6 +68,8 @@ #include "private/qnoncontiguousbytedevice_p.h" #include "qnetworkaccessauthenticationmanager_p.h" +#ifndef QT_NO_HTTP + QT_BEGIN_NAMESPACE class QAuthenticator; @@ -285,4 +287,6 @@ signals: QT_END_NAMESPACE +#endif // QT_NO_HTTP + #endif // QHTTPTHREADDELEGATE_H diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp index 6220abe..2aea350 100644 --- a/src/network/access/qnetworkaccessbackend.cpp +++ b/src/network/access/qnetworkaccessbackend.cpp @@ -41,6 +41,7 @@ #include "qnetworkaccessbackend_p.h" #include "qnetworkaccessmanager_p.h" +#include "qnetworkconfigmanager.h" #include "qnetworkrequest.h" #include "qnetworkreply.h" #include "qnetworkreply_p.h" @@ -343,8 +344,6 @@ void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors) #endif } -#ifndef QT_NO_BEARERMANAGEMENT - /*! Starts the backend. Returns true if the backend is started. Returns false if the backend could not be started due to an unopened or roaming session. The caller should recall this @@ -352,31 +351,62 @@ void QNetworkAccessBackend::sslErrors(const QList<QSslError> &errors) */ bool QNetworkAccessBackend::start() { - if (!manager->networkSession) { - open(); - return true; - } - - // This is not ideal. - const QString host = reply->url.host(); - if (host == QLatin1String("localhost") || - QHostAddress(host) == QHostAddress::LocalHost || - QHostAddress(host) == QHostAddress::LocalHostIPv6) { - // Don't need an open session for localhost access. - open(); - return true; +#ifndef QT_NO_BEARERMANAGEMENT + // For bearer, check if session start is required + if (manager->networkSession) { + // session required + if (manager->networkSession->isOpen() && + manager->networkSession->state() == QNetworkSession::Connected) { + // Session is already open and ready to use. + // copy network session down to the backend + setProperty("_q_networksession", QVariant::fromValue(manager->networkSession)); + } else { + // Session not ready, but can skip for loopback connections + + // This is not ideal. + const QString host = reply->url.host(); + + if (host == QLatin1String("localhost") || + QHostAddress(host) == QHostAddress::LocalHost || + QHostAddress(host) == QHostAddress::LocalHostIPv6) { + // Don't need an open session for localhost access. + } else { + // need to wait for session to be opened + return false; + } + } } +#endif - if (manager->networkSession->isOpen() && - manager->networkSession->state() == QNetworkSession::Connected) { - //copy network session down to the backend - setProperty("_q_networksession", QVariant::fromValue(manager->networkSession)); - open(); - return true; +#ifndef QT_NO_NETWORKPROXY +#ifndef QT_NO_BEARERMANAGEMENT + // Get the proxy settings from the network session (in the case of service networks, + // the proxy settings change depending which AP was activated) + QNetworkSession *session = manager->networkSession.data(); + QNetworkConfiguration config; + if (session) { + QNetworkConfigurationManager configManager; + // The active configuration tells us what IAP is in use + QVariant v = session->sessionProperty(QLatin1String("ActiveConfiguration")); + if (v.isValid()) + config = configManager.configurationFromIdentifier(qvariant_cast<QString>(v)); + // Fallback to using the configuration if no active configuration + if (!config.isValid()) + config = session->configuration(); + // or unspecified configuration if that is no good either + if (!config.isValid()) + config = QNetworkConfiguration(); } + reply->proxyList = manager->queryProxy(QNetworkProxyQuery(config, url())); +#else // QT_NO_BEARERMANAGEMENT + // Without bearer management, the proxy depends only on the url + reply->proxyList = manager->queryProxy(QNetworkProxyQuery(url())); +#endif +#endif - return false; + // now start the request + open(); + return true; } -#endif QT_END_NAMESPACE diff --git a/src/network/access/qnetworkaccesscachebackend.cpp b/src/network/access/qnetworkaccesscachebackend.cpp index 13f4cd9..c585848 100644 --- a/src/network/access/qnetworkaccesscachebackend.cpp +++ b/src/network/access/qnetworkaccesscachebackend.cpp @@ -66,6 +66,7 @@ void QNetworkAccessCacheBackend::open() QString msg = QCoreApplication::translate("QNetworkAccessCacheBackend", "Error opening %1") .arg(this->url().toString()); error(QNetworkReply::ContentNotFoundError, msg); + } else { setAttribute(QNetworkRequest::SourceIsFromCacheAttribute, true); } finished(); @@ -85,14 +86,18 @@ bool QNetworkAccessCacheBackend::sendCacheContents() QNetworkCacheMetaData::AttributesMap attributes = item.attributes(); setAttribute(QNetworkRequest::HttpStatusCodeAttribute, attributes.value(QNetworkRequest::HttpStatusCodeAttribute)); setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, attributes.value(QNetworkRequest::HttpReasonPhraseAttribute)); - setAttribute(QNetworkRequest::SourceIsFromCacheAttribute, true); // set the raw headers QNetworkCacheMetaData::RawHeaderList rawHeaders = item.rawHeaders(); QNetworkCacheMetaData::RawHeaderList::ConstIterator it = rawHeaders.constBegin(), end = rawHeaders.constEnd(); - for ( ; it != end; ++it) + for ( ; it != end; ++it) { + if (it->first.toLower() == "cache-control" && + it->second.toLower().contains("must-revalidate")) { + return false; + } setRawHeader(it->first, it->second); + } // handle a possible redirect QVariant redirectionTarget = attributes.value(QNetworkRequest::RedirectionTargetAttribute); diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index c619114..a45c2de 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -262,13 +262,11 @@ bool QNetworkAccessHttpBackend::loadFromCacheIfAllowed(QHttpNetworkRequest &http if (lastModified.isValid()) httpRequest.setHeaderField("If-Modified-Since", QNetworkHeadersPrivate::toHttpDate(lastModified)); - if (CacheLoadControlAttribute == QNetworkRequest::PreferNetwork) { - it = cacheHeaders.findRawHeader("Cache-Control"); - if (it != cacheHeaders.rawHeaders.constEnd()) { - QHash<QByteArray, QByteArray> cacheControl = parseHttpOptionHeader(it->second); - if (cacheControl.contains("must-revalidate")) - return false; - } + it = cacheHeaders.findRawHeader("Cache-Control"); + if (it != cacheHeaders.rawHeaders.constEnd()) { + QHash<QByteArray, QByteArray> cacheControl = parseHttpOptionHeader(it->second); + if (cacheControl.contains("must-revalidate")) + return false; } QDateTime currentDateTime = QDateTime::currentDateTime(); diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 5a7521e..55d6a7c 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -861,7 +861,7 @@ QNetworkAccessManager::NetworkAccessibility QNetworkAccessManager::networkAccess device will be uploaded to the server; in that case, data must be open for reading and must remain valid until the finished() signal is emitted for this reply. - \note This feature is currently available for HTTP only. + \note This feature is currently available for HTTP(S) only. \sa get(), post(), put(), deleteResource() */ @@ -986,10 +986,6 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera // third step: find a backend priv->backend = d->findBackend(op, request); -#ifndef QT_NO_NETWORKPROXY - QList<QNetworkProxy> proxyList = d->queryProxy(QNetworkProxyQuery(request.url())); - priv->proxyList = proxyList; -#endif if (priv->backend) { priv->backend->setParent(reply); priv->backend->reply = priv; diff --git a/src/network/access/qnetworkcookie.cpp b/src/network/access/qnetworkcookie.cpp index 52eb345..eec8507 100644 --- a/src/network/access/qnetworkcookie.cpp +++ b/src/network/access/qnetworkcookie.cpp @@ -395,8 +395,8 @@ static QPair<QByteArray, QByteArray> nextField(const QByteArray &text, int &posi // qdtext = <any TEXT except <">> // quoted-pair = "\" CHAR - // If its NAME=VALUE, retain the value as is - // refer to ttp://bugreports.qt.nokia.com/browse/QTBUG-17746 + // If it is NAME=VALUE, retain the value as is + // refer to http://bugreports.qt.nokia.com/browse/QTBUG-17746 if (isNameValue) second += '"'; ++i; @@ -432,7 +432,9 @@ static QPair<QByteArray, QByteArray> nextField(const QByteArray &text, int &posi position = i; for ( ; i < length; ++i) { register char c = text.at(i); - if (c == ',' || c == ';' || isLWS(c)) + // for name value pairs, we want to parse until reaching the next ';' + // and not break when reaching a space char + if (c == ',' || c == ';' || ((isNameValue && (c == '\n' || c == '\r')) || (!isNameValue && isLWS(c)))) break; } @@ -487,7 +489,6 @@ QByteArray QNetworkCookie::toRawForm(RawForm form) const result += '='; if ((d->value.contains(';') || d->value.contains(',') || - d->value.contains(' ') || d->value.contains('"')) && (!d->value.startsWith('"') && !d->value.endsWith('"'))) { diff --git a/src/network/access/qnetworkreplyimpl.cpp b/src/network/access/qnetworkreplyimpl.cpp index 9eb505d..db57e90 100644 --- a/src/network/access/qnetworkreplyimpl.cpp +++ b/src/network/access/qnetworkreplyimpl.cpp @@ -90,10 +90,10 @@ void QNetworkReplyImplPrivate::_q_startOperation() return; } + if (!backend->start()) { #ifndef QT_NO_BEARERMANAGEMENT - if (!backend->start()) { // ### we should call that method even if bearer is not used // backend failed to start because the session state is not Connected. - // QNetworkAccessManager will call reply->backend->start() again for us when the session + // QNetworkAccessManager will call _q_startOperation again for us when the session // state changes. state = WaitingForSession; @@ -109,11 +109,20 @@ void QNetworkReplyImplPrivate::_q_startOperation() session->open(); } else { qWarning("Backend is waiting for QNetworkSession to connect, but there is none!"); + state = Working; + error(QNetworkReplyImpl::UnknownNetworkError, + QCoreApplication::translate("QNetworkReply", "Network session error.")); + finished(); } - +#else + qWarning("Backend start failed"); + state = Working; + error(QNetworkReplyImpl::UnknownNetworkError, + QCoreApplication::translate("QNetworkReply", "backend start error.")); + finished(); +#endif return; } -#endif if (backend && backend->isSynchronous()) { state = Finished; @@ -851,6 +860,8 @@ void QNetworkReplyImpl::abort() if (d->state != QNetworkReplyImplPrivate::Finished) { // call finished which will emit signals d->error(OperationCanceledError, tr("Operation canceled")); + if (d->state == QNetworkReplyImplPrivate::WaitingForSession) + d->state = QNetworkReplyImplPrivate::Working; d->finished(); } d->state = QNetworkReplyImplPrivate::Aborted; @@ -1010,10 +1021,6 @@ bool QNetworkReplyImplPrivate::migrateBackend() if (state == Finished || state == Aborted) return true; - // Backend does not support resuming download. - if (!backend->canResume()) - return false; - // Request has outgoing data, not migrating. if (outgoingData) return false; @@ -1022,6 +1029,10 @@ bool QNetworkReplyImplPrivate::migrateBackend() if (copyDevice) return true; + // Backend does not support resuming download. + if (!backend->canResume()) + return false; + state = QNetworkReplyImplPrivate::Reconnecting; if (backend) { diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index c108ad3..42fc49d 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -60,7 +60,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, #endif QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate() - : QObject(), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true) + : QObject(), pollTimer(0), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true) { qRegisterMetaType<QNetworkConfiguration>("QNetworkConfiguration"); qRegisterMetaType<QNetworkConfigurationPrivatePointer>("QNetworkConfigurationPrivatePointer"); @@ -385,8 +385,6 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() this, SLOT(configurationRemoved(QNetworkConfigurationPrivatePointer))); connect(engine, SIGNAL(configurationChanged(QNetworkConfigurationPrivatePointer)), this, SLOT(configurationChanged(QNetworkConfigurationPrivatePointer))); - - QMetaObject::invokeMethod(engine, "initialize"); } } @@ -410,8 +408,19 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() startPolling(); } - if (firstUpdate) + if (firstUpdate) { firstUpdate = false; + QList<QBearerEngine*> enginesToInitialize = sessionEngines; //shallow copy the list in case it is modified when we unlock mutex + Qt::ConnectionType connectionType; + if (QCoreApplicationPrivate::mainThread() == QThread::currentThread()) + connectionType = Qt::DirectConnection; + else + connectionType = Qt::BlockingQueuedConnection; + locker.unlock(); + foreach (QBearerEngine* engine, enginesToInitialize) { + QMetaObject::invokeMethod(engine, "initialize", connectionType); + } + } } void QNetworkConfigurationManagerPrivate::performAsyncConfigurationUpdate() @@ -442,9 +451,19 @@ void QNetworkConfigurationManagerPrivate::startPolling() { QMutexLocker locker(&mutex); + if(!pollTimer) { + pollTimer = new QTimer(this); + pollTimer->setInterval(10000); + pollTimer->setSingleShot(true); + connect(pollTimer, SIGNAL(timeout()), this, SLOT(pollEngines())); + } + + if(pollTimer->isActive()) + return; + foreach (QBearerEngine *engine, sessionEngines) { if (engine->requiresPolling() && (forcedPolling || engine->configurationsInUse())) { - QTimer::singleShot(10000, this, SLOT(pollEngines())); + pollTimer->start(); break; } } @@ -469,7 +488,7 @@ void QNetworkConfigurationManagerPrivate::enablePolling() ++forcedPolling; if (forcedPolling == 1) - startPolling(); + QMetaObject::invokeMethod(this, "startPolling"); } void QNetworkConfigurationManagerPrivate::disablePolling() diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h index 81f38c5..45d6a75 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.h +++ b/src/network/bearer/qnetworkconfigmanager_p.h @@ -64,6 +64,7 @@ QT_BEGIN_NAMESPACE class QBearerEngine; +class QTimer; class Q_NETWORK_EXPORT QNetworkConfigurationManagerPrivate : public QObject { @@ -106,7 +107,8 @@ private Q_SLOTS: void pollEngines(); private: - void startPolling(); + Q_INVOKABLE void startPolling(); + QTimer *pollTimer; private: mutable QMutex mutex; diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index ae7d7a1..4e7c286 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -720,7 +720,8 @@ Q_IPV6ADDR QHostAddress::toIPv6Address() const Returns the address as a string. For example, if the address is the IPv4 address 127.0.0.1, the - returned string is "127.0.0.1". + returned string is "127.0.0.1". For IPv6 the string format will + follow the RFC5952 recommendation. \sa toIPv4Address() */ @@ -741,8 +742,32 @@ QString QHostAddress::toString() const ugle[i] = (quint16(d->a6[2*i]) << 8) | quint16(d->a6[2*i+1]); } QString s; - s.sprintf("%X:%X:%X:%X:%X:%X:%X:%X", - ugle[0], ugle[1], ugle[2], ugle[3], ugle[4], ugle[5], ugle[6], ugle[7]); + QString temp; + bool zeroDetected = false; + bool zeroShortened = false; + for (int i = 0; i < 8; i++) { + if ((ugle[i] != 0) || zeroShortened) { + temp.sprintf("%X", ugle[i]); + s.append(temp); + if (zeroDetected) + zeroShortened = true; + } else { + if (!zeroDetected) { + if (i<7 && (ugle[i+1] == 0)) { + s.append(QLatin1Char(':')); + zeroDetected = true; + } else { + temp.sprintf("%X", ugle[i]); + s.append(temp); + if (i<7) + s.append(QLatin1Char(':')); + } + } + } + if (i<7 && ((ugle[i] != 0) || zeroShortened || (i==0 && zeroDetected))) + s.append(QLatin1Char(':')); + } + if (!d->scopeId.isEmpty()) s.append(QLatin1Char('%') + d->scopeId); return s; diff --git a/src/network/kernel/qnetworkinterface_unix.cpp b/src/network/kernel/qnetworkinterface_unix.cpp index 6098bde..7f251a7 100644 --- a/src/network/kernel/qnetworkinterface_unix.cpp +++ b/src/network/kernel/qnetworkinterface_unix.cpp @@ -219,7 +219,7 @@ static QNetworkInterfacePrivate *findInterface(int socket, QList<QNetworkInterfa #ifdef SIOCGIFHWADDR // Get the HW address if (qt_safe_ioctl(socket, SIOCGIFHWADDR, &req) >= 0) { - uchar *addr = (uchar *)&req.ifr_addr; + uchar *addr = (uchar *)req.ifr_addr.sa_data; iface->hardwareAddress = iface->makeHwAddress(6, addr); } #endif diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp index 68ff955..14db913 100644 --- a/src/network/kernel/qnetworkproxy.cpp +++ b/src/network/kernel/qnetworkproxy.cpp @@ -228,6 +228,10 @@ #include "qmutex.h" #include "qurl.h" +#ifndef QT_NO_BEARERMANAGEMENT +#include <QtNetwork/QNetworkConfiguration> +#endif + QT_BEGIN_NAMESPACE class QSocks5SocketEngineHandler; @@ -716,6 +720,9 @@ public: QUrl remote; int localPort; QNetworkProxyQuery::QueryType type; +#ifndef QT_NO_BEARERMANAGEMENT + QNetworkConfiguration config; +#endif }; template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach() @@ -777,6 +784,11 @@ template<> void QSharedDataPointer<QNetworkProxyQueryPrivate>::detach() like choosing an caching HTTP proxy for HTTP-based connections, but a more powerful SOCKSv5 proxy for all others. + The network configuration specifies which configuration to use, + when bearer management is used. For example on a mobile phone + the proxy settings are likely to be different for the cellular + network vs WLAN. + Some of the criteria may not make sense in all of the types of query. The following table lists the criteria that are most commonly used, according to the type of query. @@ -902,6 +914,68 @@ QNetworkProxyQuery::QNetworkProxyQuery(quint16 bindPort, const QString &protocol d->type = queryType; } +#ifndef QT_NO_BEARERMANAGEMENT +/*! + Constructs a QNetworkProxyQuery with the URL \a requestUrl and + sets the query type to \a queryType. The specified \a networkConfiguration + is used to resolve the proxy settings. + + \sa protocolTag(), peerHostName(), peerPort(), networkConfiguration() +*/ +QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, + const QUrl &requestUrl, QueryType queryType) +{ + d->config = networkConfiguration; + d->remote = requestUrl; + d->type = queryType; +} + +/*! + Constructs a QNetworkProxyQuery of type \a queryType and sets the + protocol tag to be \a protocolTag. This constructor is suitable + for QNetworkProxyQuery::TcpSocket queries, because it sets the + peer hostname to \a hostname and the peer's port number to \a + port. The specified \a networkConfiguration + is used to resolve the proxy settings. + + \sa networkConfiguration() +*/ +QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, + const QString &hostname, int port, + const QString &protocolTag, + QueryType queryType) +{ + d->config = networkConfiguration; + d->remote.setScheme(protocolTag); + d->remote.setHost(hostname); + d->remote.setPort(port); + d->type = queryType; +} + +/*! + Constructs a QNetworkProxyQuery of type \a queryType and sets the + protocol tag to be \a protocolTag. This constructor is suitable + for QNetworkProxyQuery::TcpSocket queries because it sets the + local port number to \a bindPort. The specified \a networkConfiguration + is used to resolve the proxy settings. + + Note that \a bindPort is of type quint16 to indicate the exact + port number that is requested. The value of -1 (unknown) is not + allowed in this context. + + \sa localPort(), networkConfiguration() +*/ +QNetworkProxyQuery::QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, + quint16 bindPort, const QString &protocolTag, + QueryType queryType) +{ + d->config = networkConfiguration; + d->remote.setScheme(protocolTag); + d->localPort = bindPort; + d->type = queryType; +} +#endif + /*! Constructs a QNetworkProxyQuery object that is a copy of \a other. */ @@ -1116,6 +1190,30 @@ void QNetworkProxyQuery::setUrl(const QUrl &url) d->remote = url; } +#ifndef QT_NO_BEARERMANAGEMENT +QNetworkConfiguration QNetworkProxyQuery::networkConfiguration() const +{ + return d ? d->config : QNetworkConfiguration(); +} + +/*! + Sets the network configuration component of this QNetworkProxyQuery + object to be \a networkConfiguration. The network configuration can + be used to return different proxy settings based on the network in + use, for example WLAN vs cellular networks on a mobile phone. + + In the case of "user choice" or "service network" configurations, + you should first start the QNetworkSession and obtain the active + configuration from its properties. + + \sa networkConfiguration +*/ +void QNetworkProxyQuery::setNetworkConfiguration(const QNetworkConfiguration &networkConfiguration) +{ + d->config = networkConfiguration; +} +#endif + /*! \class QNetworkProxyFactory \brief The QNetworkProxyFactory class provides fine-grained proxy selection. diff --git a/src/network/kernel/qnetworkproxy.h b/src/network/kernel/qnetworkproxy.h index 26562d5..e16b29e 100644 --- a/src/network/kernel/qnetworkproxy.h +++ b/src/network/kernel/qnetworkproxy.h @@ -54,6 +54,7 @@ QT_BEGIN_NAMESPACE QT_MODULE(Network) class QUrl; +class QNetworkConfiguration; class QNetworkProxyQueryPrivate; class Q_NETWORK_EXPORT QNetworkProxyQuery @@ -73,6 +74,16 @@ public: QNetworkProxyQuery(quint16 bindPort, const QString &protocolTag = QString(), QueryType queryType = TcpServer); QNetworkProxyQuery(const QNetworkProxyQuery &other); +#ifndef QT_NO_BEARERMANAGEMENT + QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, + const QUrl &requestUrl, QueryType queryType = UrlRequest); + QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, + const QString &hostname, int port, const QString &protocolTag = QString(), + QueryType queryType = TcpSocket); + QNetworkProxyQuery(const QNetworkConfiguration &networkConfiguration, + quint16 bindPort, const QString &protocolTag = QString(), + QueryType queryType = TcpServer); +#endif ~QNetworkProxyQuery(); QNetworkProxyQuery &operator=(const QNetworkProxyQuery &other); bool operator==(const QNetworkProxyQuery &other) const; @@ -97,6 +108,11 @@ public: QUrl url() const; void setUrl(const QUrl &url); +#ifndef QT_NO_BEARERMANAGEMENT + QNetworkConfiguration networkConfiguration() const; + void setNetworkConfiguration(const QNetworkConfiguration &networkConfiguration); +#endif + private: QSharedDataPointer<QNetworkProxyQueryPrivate> d; }; diff --git a/src/network/kernel/qnetworkproxy_symbian.cpp b/src/network/kernel/qnetworkproxy_symbian.cpp index 79dfb27..1fb31b5 100644 --- a/src/network/kernel/qnetworkproxy_symbian.cpp +++ b/src/network/kernel/qnetworkproxy_symbian.cpp @@ -58,6 +58,7 @@ #include <commsdattypeinfov1_1.h> // CCDIAPRecord, CCDProxiesRecord #include <commsdattypesv1_1.h> // KCDTIdIAPRecord, KCDTIdProxiesRecord #include <QtNetwork/QNetworkConfigurationManager> +#include <QtNetwork/QNetworkConfiguration> #include <QFlags> using namespace CommsDat; @@ -67,82 +68,96 @@ QT_BEGIN_NAMESPACE class SymbianIapId { public: - enum State{ - NotValid, - Valid - }; - Q_DECLARE_FLAGS(States, State) - SymbianIapId() {} + SymbianIapId() : valid(false), id(0) {} ~SymbianIapId() {} - void setIapId(TUint32 iapId) { iapState |= Valid; id = iapId; } - bool isValid() { return iapState == Valid; } + void setIapId(TUint32 iapId) { valid = true; id = iapId; } + bool isValid() { return valid; } TUint32 iapId() { return id; } private: - QFlags<States> iapState; + bool valid; TUint32 id; }; -Q_DECLARE_OPERATORS_FOR_FLAGS(SymbianIapId::States) - class SymbianProxyQuery { public: static QNetworkConfiguration findCurrentConfiguration(QNetworkConfigurationManager& configurationManager); - static SymbianIapId getIapId(QNetworkConfigurationManager& configurationManager); + static QNetworkConfiguration findCurrentConfigurationFromServiceNetwork(const QNetworkConfiguration& serviceNetwork); + static SymbianIapId getIapId(QNetworkConfigurationManager &configurationManager, const QNetworkProxyQuery &query); static CCDIAPRecord *getIapRecordLC(TUint32 aIAPId, CMDBSession &aDb); static CMDBRecordSet<CCDProxiesRecord> *prepareQueryLC(TUint32 serviceId, TDesC& serviceType); static QList<QNetworkProxy> proxyQueryL(TUint32 aIAPId, const QNetworkProxyQuery &query); }; +QNetworkConfiguration SymbianProxyQuery::findCurrentConfigurationFromServiceNetwork(const QNetworkConfiguration& serviceNetwork) +{ + // Note: This code assumes that the only unambigious way to + // find current proxy config is if there is only one access point + // or if the found access point is immediately usable. + QList<QNetworkConfiguration> childConfigurations = serviceNetwork.children(); + if (childConfigurations.isEmpty()) { + qWarning("QNetworkProxyFactory::systemProxyForQuery called with empty service network"); + return QNetworkConfiguration(); + } else if (childConfigurations.count() == 1) { + //if only one IAP in the service network, it's always going to be used. + return childConfigurations.at(0); + } else { + //use highest priority active config, if available + for (int index = 0; index < childConfigurations.count(); index++) { + QNetworkConfiguration childConfig = childConfigurations.at(index); + if (childConfig.isValid() && childConfig.state() == QNetworkConfiguration::Active) + return childConfig; + } + //otherwise use highest priority discovered config (that's the one which will be activated if start were called now) + for (int index = 0; index < childConfigurations.count(); index++) { + QNetworkConfiguration childConfig = childConfigurations.at(index); + if (childConfig.isValid() && childConfig.state() == QNetworkConfiguration::Discovered) + return childConfig; + } + //otherwise the highest priority defined (most likely to be activated if all were available when start is called) + qWarning("QNetworkProxyFactory::systemProxyForQuery called with service network, but none of its IAPs are available"); + return childConfigurations.at(0); + } +} + QNetworkConfiguration SymbianProxyQuery::findCurrentConfiguration(QNetworkConfigurationManager& configurationManager) { QList<QNetworkConfiguration> activeConfigurations = configurationManager.allConfigurations( QNetworkConfiguration::Active); - QNetworkConfiguration currentConfig; if (activeConfigurations.count() > 0) { - currentConfig = activeConfigurations.at(0); + return activeConfigurations.at(0); } else { // No active configurations, try default one QNetworkConfiguration defaultConfiguration = configurationManager.defaultConfiguration(); if (defaultConfiguration.isValid()) { switch (defaultConfiguration.type()) { case QNetworkConfiguration::InternetAccessPoint: - currentConfig = defaultConfiguration; - break; + return defaultConfiguration; case QNetworkConfiguration::ServiceNetwork: - { - // Note: This code assumes that the only unambigious way to - // find current proxy config is if there is only one access point - // or if the found access point is immediately usable. - QList<QNetworkConfiguration> childConfigurations = defaultConfiguration.children(); - if (childConfigurations.count() == 1) { - currentConfig = childConfigurations.at(0); - } else { - for (int index = 0; index < childConfigurations.count(); index++) { - QNetworkConfiguration childConfig = childConfigurations.at(index); - if (childConfig.isValid() && childConfig.state() == QNetworkConfiguration::Discovered) { - currentConfig = childConfig; - break; - } - } - } - } - break; + return findCurrentConfigurationFromServiceNetwork(defaultConfiguration); case QNetworkConfiguration::UserChoice: - // User choice is not a valid configuration for proxy discovery + qWarning("QNetworkProxyFactory::systemProxyForQuery called with user choice configuration, which is not valid"); break; } } } - return currentConfig; + return QNetworkConfiguration(); } -SymbianIapId SymbianProxyQuery::getIapId(QNetworkConfigurationManager& configurationManager) +SymbianIapId SymbianProxyQuery::getIapId(QNetworkConfigurationManager& configurationManager, const QNetworkProxyQuery &query) { SymbianIapId iapId; - QNetworkConfiguration currentConfig = findCurrentConfiguration(configurationManager); - if (currentConfig.isValid()) { + QNetworkConfiguration currentConfig = query.networkConfiguration(); + if (!currentConfig.isValid()) { + //If config is not specified, then try to find out an active or default one + currentConfig = findCurrentConfiguration(configurationManager); + } + if (currentConfig.isValid() && currentConfig.type() == QNetworkConfiguration::ServiceNetwork) { + //convert service network to the real IAP. + currentConfig = findCurrentConfigurationFromServiceNetwork(currentConfig); + } + if (currentConfig.isValid() && currentConfig.type() == QNetworkConfiguration::InternetAccessPoint) { // Note: the following code assumes that the identifier is in format // I_xxxx where xxxx is the identifier of IAP. This is meant as a // temporary solution until there is a support for returning @@ -231,7 +246,12 @@ QList<QNetworkProxy> SymbianProxyQuery::proxyQueryL(TUint32 aIAPId, const QNetwo CleanupStack::Pop(); // serverName TUint32 port = proxyRecord->iPortNumber; - QNetworkProxy proxy(QNetworkProxy::HttpProxy, serverNameQt, port); + //Symbian config doesn't include proxy type, assume http unless the port matches assigned port of another type + //Mobile operators use a wide variety of port numbers for http proxies. + QNetworkProxy::ProxyType proxyType = QNetworkProxy::HttpProxy; + if (port == 1080) //IANA assigned port for SOCKS + proxyType = QNetworkProxy::Socks5Proxy; + QNetworkProxy proxy(proxyType, serverNameQt, port); foundProxies.append(proxy); } } @@ -249,7 +269,7 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro SymbianIapId iapId; TInt error; QNetworkConfigurationManager manager; - iapId = SymbianProxyQuery::getIapId(manager); + iapId = SymbianProxyQuery::getIapId(manager, query); if (iapId.isValid()) { TRAP(error, proxies = SymbianProxyQuery::proxyQueryL(iapId.iapId(), query)) if (error != KErrNone) { diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 7af71cc..e5af5c6 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -547,15 +547,19 @@ bool QAbstractSocketPrivate::initSocketLayer(QAbstractSocket::NetworkLayerProtoc resetSocketLayer(); socketEngine = QAbstractSocketEngine::createSocketEngine(q->socketType(), proxyInUse, q); -#ifndef QT_NO_BEARERMANAGEMENT - //copy network session down to the socket engine (if it has been set) - socketEngine->setProperty("_q_networksession", q->property("_q_networksession")); -#endif if (!socketEngine) { socketError = QAbstractSocket::UnsupportedSocketOperationError; q->setErrorString(QAbstractSocket::tr("Operation on socket is not supported")); return false; } +#ifndef QT_NO_BEARERMANAGEMENT + //copy network session down to the socket engine (if it has been set) + socketEngine->setProperty("_q_networksession", q->property("_q_networksession")); +#endif +#ifndef QT_NO_NETWORKPROXY + //copy user agent to socket engine (if it has been set) + socketEngine->setProperty("_q_user-agent", q->property("_q_user-agent")); +#endif if (!socketEngine->initialize(q->socketType(), protocol)) { #if defined (QABSTRACTSOCKET_DEBUG) qDebug("QAbstractSocketPrivate::initSocketLayer(%s, %s) failed (%s)", @@ -1605,15 +1609,15 @@ bool QAbstractSocket::setSocketDescriptor(int socketDescriptor, SocketState sock d->resetSocketLayer(); d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, this); -#ifndef QT_NO_BEARERMANAGEMENT - //copy network session down to the socket engine (if it has been set) - d->socketEngine->setProperty("_q_networksession", property("_q_networksession")); -#endif if (!d->socketEngine) { d->socketError = UnsupportedSocketOperationError; setErrorString(tr("Operation on socket is not supported")); return false; } +#ifndef QT_NO_BEARERMANAGEMENT + //copy network session down to the socket engine (if it has been set) + d->socketEngine->setProperty("_q_networksession", property("_q_networksession")); +#endif bool result = d->socketEngine->initialize(socketDescriptor, socketState); if (!result) { d->socketError = d->socketEngine->error(); @@ -1877,7 +1881,7 @@ bool QAbstractSocket::waitForReadyRead(int msecs) } Q_ASSERT(d->socketEngine); - forever { + do { bool readyToRead = false; bool readyToWrite = false; if (!d->socketEngine->waitForReadOrWrite(&readyToRead, &readyToWrite, true, !d->writeBuffer.isEmpty(), @@ -1904,7 +1908,7 @@ bool QAbstractSocket::waitForReadyRead(int msecs) if (state() != ConnectedState) return false; - } + } while (msecs == -1 || qt_timeout_value(msecs, stopWatch.elapsed()) > 0); return false; } diff --git a/src/network/socket/qhttpsocketengine.cpp b/src/network/socket/qhttpsocketengine.cpp index 7846056..a8a11a7 100644 --- a/src/network/socket/qhttpsocketengine.cpp +++ b/src/network/socket/qhttpsocketengine.cpp @@ -501,7 +501,13 @@ void QHttpSocketEngine::slotSocketConnected() data += path; data += " HTTP/1.1\r\n"; data += "Proxy-Connection: keep-alive\r\n" - "User-Agent: Mozilla/5.0\r\n" + "User-Agent: "; + QVariant v = property("_q_user-agent"); + if (v.isValid()) + data += v.toByteArray(); + else + data += "Mozilla/5.0"; + data += "\r\n" "Host: " + peerAddress + "\r\n"; QAuthenticatorPrivate *priv = QAuthenticatorPrivate::getPrivate(d->authenticator); //qDebug() << "slotSocketConnected: priv=" << priv << (priv ? (int)priv->method : -1); diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index c365635..88b5aca 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -1540,8 +1540,13 @@ qint64 QSocks5SocketEngine::write(const char *data, qint64 len) // ### Handle this error. } - d->data->controlSocket->write(sealedBuf); + qint64 written = d->data->controlSocket->write(sealedBuf); + if (written <= 0) { + QSOCKS5_Q_DEBUG << "native write returned" << written; + return written; + } d->data->controlSocket->waitForBytesWritten(0); + //NB: returning len rather than written for the OK case, because the "sealing" may increase the length return len; #ifndef QT_NO_UDPSOCKET } else if (d->mode == QSocks5SocketEnginePrivate::UdpAssociateMode) { diff --git a/src/network/socket/qsymbiansocketengine.cpp b/src/network/socket/qsymbiansocketengine.cpp index f1b2982..b6d12fe 100644 --- a/src/network/socket/qsymbiansocketengine.cpp +++ b/src/network/socket/qsymbiansocketengine.cpp @@ -251,7 +251,8 @@ QSymbianSocketEnginePrivate::QSymbianSocketEnginePrivate() : readNotificationsEnabled(false), writeNotificationsEnabled(false), exceptNotificationsEnabled(false), - asyncSelect(0) + asyncSelect(0), + hasReceivedBufferedDatagram(false) { } @@ -781,21 +782,34 @@ qint64 QSymbianSocketEngine::pendingDatagramSize() const Q_D(const QSymbianSocketEngine); Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::pendingDatagramSize(), false); Q_CHECK_TYPE(QSymbianSocketEngine::hasPendingDatagrams(), QAbstractSocket::UdpSocket, false); - int nbytes; + //can only buffer one datagram at a time + if (d->hasReceivedBufferedDatagram) + return d->receivedDataBuffer.size(); + int nbytes = 0; TInt err = d->nativeSocket.GetOpt(KSOReadBytesPending,KSOLSocket, nbytes); if (nbytes > 0) { //nbytes includes IP header, which is of variable length (IPv4 with or without options, IPv6...) - QByteArray next(nbytes,0); - TPtr8 buffer((TUint8*)next.data(), next.size()); + //therefore read the datagram into a buffer to find its true size + d->receivedDataBuffer.resize(nbytes); + TPtr8 buffer((TUint8*)d->receivedDataBuffer.data(), nbytes); + //nbytes = size including IP header, buffer is a pointer descriptor backed by the receivedDataBuffer TInetAddr addr; TRequestStatus status; - //TODO: rather than peek, should we save this for next call to readDatagram? - //what if calls don't match though? - d->nativeSocket.RecvFrom(buffer, addr, KSockReadPeek, status); + //RecvFrom copies only the payload (we don't want the header so don't specify the option to retrieve it) + d->nativeSocket.RecvFrom(buffer, addr, 0, status); User::WaitForRequest(status); - if (status.Int()) + if (status != KErrNone) { + d->receivedDataBuffer.clear(); return 0; - return buffer.Length(); + } + nbytes = buffer.Length(); + //nbytes = size of payload, resize the receivedDataBuffer to the final size + d->receivedDataBuffer.resize(nbytes); + d->hasReceivedBufferedDatagram = true; + //now receivedDataBuffer contains one datagram, which has been removed from the socket's internal buffer +#if defined (QNATIVESOCKETENGINE_DEBUG) + qDebug() << "QSymbianSocketEngine::pendingDatagramSize buffering" << nbytes << "bytes"; +#endif } return qint64(nbytes); } @@ -807,6 +821,19 @@ qint64 QSymbianSocketEngine::readDatagram(char *data, qint64 maxSize, Q_D(QSymbianSocketEngine); Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::readDatagram(), -1); Q_CHECK_TYPE(QSymbianSocketEngine::readDatagram(), QAbstractSocket::UdpSocket, false); + + // if a datagram was buffered in pendingDatagramSize(), return it now + if (d->hasReceivedBufferedDatagram) { + qint64 size = qMin(maxSize, (qint64)d->receivedDataBuffer.size()); + memcpy(data, d->receivedDataBuffer.constData(), size); + d->receivedDataBuffer.clear(); + d->hasReceivedBufferedDatagram = false; +#if defined (QNATIVESOCKETENGINE_DEBUG) + qDebug() << "QSymbianSocketEngine::readDatagram returning" << size << "bytes from buffer"; +#endif + return size; + } + TPtr8 buffer((TUint8*)data, (int)maxSize); TInetAddr addr; TRequestStatus status; @@ -985,6 +1012,9 @@ void QSymbianSocketEngine::close() d->localAddress.clear(); d->peerPort = 0; d->peerAddress.clear(); + + d->hasReceivedBufferedDatagram = false; + d->receivedDataBuffer.clear(); } qint64 QSymbianSocketEngine::write(const char *data, qint64 len) @@ -1036,6 +1066,18 @@ qint64 QSymbianSocketEngine::read(char *data, qint64 maxSize) Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::read(), -1); Q_CHECK_STATES(QSymbianSocketEngine::read(), QAbstractSocket::ConnectedState, QAbstractSocket::BoundState, -1); + // if a datagram was buffered in pendingDatagramSize(), return it now + if (d->hasReceivedBufferedDatagram) { + qint64 size = qMin(maxSize, (qint64)d->receivedDataBuffer.size()); + memcpy(data, d->receivedDataBuffer.constData(), size); + d->receivedDataBuffer.clear(); + d->hasReceivedBufferedDatagram = false; +#if defined (QNATIVESOCKETENGINE_DEBUG) + qDebug() << "QSymbianSocketEngine::read returning" << size << "bytes from buffer"; +#endif + return size; + } + TPtr8 buffer((TUint8*)data, (int)maxSize); TSockXfrLength received = 0; TRequestStatus status; @@ -1440,6 +1482,7 @@ void QSymbianSocketEngine::startNotifications() qDebug() << "QSymbianSocketEngine::startNotifications" << d->readNotificationsEnabled << d->writeNotificationsEnabled << d->exceptNotificationsEnabled; #endif if (!d->asyncSelect && (d->readNotificationsEnabled || d->writeNotificationsEnabled || d->exceptNotificationsEnabled)) { + Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::startNotifications(), Q_VOID); if (d->threadData->eventDispatcher) { d->asyncSelect = q_check_ptr(new QAsyncSelect( static_cast<QEventDispatcherSymbian*> (d->threadData->eventDispatcher), d->nativeSocket, @@ -1456,14 +1499,12 @@ void QSymbianSocketEngine::startNotifications() bool QSymbianSocketEngine::isReadNotificationEnabled() const { Q_D(const QSymbianSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::isReadNotificationEnabled(), false); return d->readNotificationsEnabled; } void QSymbianSocketEngine::setReadNotificationEnabled(bool enable) { Q_D(QSymbianSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::setReadNotificationEnabled(), Q_VOID); #ifdef QNATIVESOCKETENGINE_DEBUG qDebug() << "QSymbianSocketEngine::setReadNotificationEnabled" << enable << "socket" << d->socketDescriptor; #endif @@ -1474,14 +1515,12 @@ void QSymbianSocketEngine::setReadNotificationEnabled(bool enable) bool QSymbianSocketEngine::isWriteNotificationEnabled() const { Q_D(const QSymbianSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::isWriteNotificationEnabled(), false); return d->writeNotificationsEnabled; } void QSymbianSocketEngine::setWriteNotificationEnabled(bool enable) { Q_D(QSymbianSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::setWriteNotificationEnabled(), Q_VOID); #ifdef QNATIVESOCKETENGINE_DEBUG qDebug() << "QSymbianSocketEngine::setWriteNotificationEnabled" << enable << "socket" << d->socketDescriptor; #endif @@ -1492,7 +1531,6 @@ void QSymbianSocketEngine::setWriteNotificationEnabled(bool enable) bool QSymbianSocketEngine::isExceptionNotificationEnabled() const { Q_D(const QSymbianSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::isExceptionNotificationEnabled(), false); return d->exceptNotificationsEnabled; return false; } @@ -1500,7 +1538,6 @@ bool QSymbianSocketEngine::isExceptionNotificationEnabled() const void QSymbianSocketEngine::setExceptionNotificationEnabled(bool enable) { Q_D(QSymbianSocketEngine); - Q_CHECK_VALID_SOCKETLAYER(QSymbianSocketEngine::setExceptionNotificationEnabled(), Q_VOID); #ifdef QNATIVESOCKETENGINE_DEBUG qDebug() << "QSymbianSocketEngine::setExceptionNotificationEnabled" << enable << "socket" << d->socketDescriptor; #endif @@ -1660,6 +1697,9 @@ void QAsyncSelect::run() //when event loop disabled socket events, defer until later if (maybeDeferSocketEvent()) return; +#if defined (QNATIVESOCKETENGINE_DEBUG) + qDebug() << "QAsyncSelect::run" << m_selectBuf() << m_selectFlags; +#endif m_inSocketEvent = true; m_selectBuf() &= m_selectFlags; //the select ioctl reports everything, so mask to only what we requested //KSockSelectReadContinuation is for reading datagrams in a mode that doesn't discard when the diff --git a/src/network/socket/qsymbiansocketengine_p.h b/src/network/socket/qsymbiansocketengine_p.h index 85ab54a..2e7c155 100644 --- a/src/network/socket/qsymbiansocketengine_p.h +++ b/src/network/socket/qsymbiansocketengine_p.h @@ -196,6 +196,8 @@ public: bool exceptNotificationsEnabled; QAsyncSelect* asyncSelect; + mutable QByteArray receivedDataBuffer; + mutable bool hasReceivedBufferedDatagram; // FIXME this is duplicated from qnativesocketengine_p.h enum ErrorString { NonBlockingInitFailedErrorString, diff --git a/src/network/socket/qtcpserver.cpp b/src/network/socket/qtcpserver.cpp index 5a60764..026ceb4 100644 --- a/src/network/socket/qtcpserver.cpp +++ b/src/network/socket/qtcpserver.cpp @@ -416,6 +416,11 @@ bool QTcpServer::setSocketDescriptor(int socketDescriptor) if (d->socketEngine) delete d->socketEngine; d->socketEngine = QAbstractSocketEngine::createSocketEngine(socketDescriptor, this); + if (!d->socketEngine) { + d->serverSocketError = QAbstractSocket::UnsupportedSocketOperationError; + d->serverSocketErrorString = tr("Operation on socket is not supported"); + return false; + } #ifndef QT_NO_BEARERMANAGEMENT //copy network session down to the socket engine (if it has been set) d->socketEngine->setProperty("_q_networksession", property("_q_networksession")); diff --git a/src/network/ssl/qsslconfiguration.cpp b/src/network/ssl/qsslconfiguration.cpp index 70d7dd8..ab4d7f1 100644 --- a/src/network/ssl/qsslconfiguration.cpp +++ b/src/network/ssl/qsslconfiguration.cpp @@ -233,7 +233,7 @@ void QSslConfiguration::setProtocol(QSsl::SslProtocol protocol) client), and whether it should require that this certificate is valid. The default mode is AutoVerifyPeer, which tells QSslSocket to use - VerifyPeer for clients, QueryPeer for clients. + VerifyPeer for clients, QueryPeer for servers. \sa setPeerVerifyMode() */ @@ -249,7 +249,7 @@ QSslSocket::PeerVerifyMode QSslConfiguration::peerVerifyMode() const client), and whether it should require that this certificate is valid. The default mode is AutoVerifyPeer, which tells QSslSocket to use - VerifyPeer for clients, QueryPeer for clients. + VerifyPeer for clients, QueryPeer for servers. \sa peerVerifyMode() */ diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 0dbf4b5..2695df1 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -1736,6 +1736,8 @@ void QSslSocket::connectToHostImplementation(const QString &hostName, quint16 po } #ifndef QT_NO_NETWORKPROXY d->plainSocket->setProxy(proxy()); + //copy user agent down to the plain socket (if it has been set) + d->plainSocket->setProperty("_q_user-agent", property("_q_user-agent")); #endif QIODevice::open(openMode); d->plainSocket->connectToHost(hostName, port, openMode); diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp index 8068aa8..207ab3d 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager.cpp +++ b/src/opengl/gl2paintengineex/qglengineshadermanager.cpp @@ -495,6 +495,8 @@ GLuint QGLEngineShaderManager::getUniformLocation(Uniform id) "fmp", "fmp2_m_radius2", "inverse_2_fmp2_m_radius2", + "sqrfr", + "bradius", "invertedTextureSize", "brushTransform", "brushTexture", diff --git a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h index 7cc9dc3..bf2fe42 100644 --- a/src/opengl/gl2paintengineex/qglengineshadermanager_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadermanager_p.h @@ -442,6 +442,8 @@ public: Fmp, Fmp2MRadius2, Inverse2Fmp2MRadius2, + SqrFr, + BRadius, InvertedTextureSize, BrushTransform, BrushTexture, diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h index fc8b9ef..9362c58 100644 --- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h +++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h @@ -241,6 +241,7 @@ static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\n\ uniform mediump vec2 halfViewportSize; \n\ uniform highp mat3 brushTransform; \n\ uniform highp vec2 fmp; \n\ + uniform highp vec3 bradius; \n\ varying highp float b; \n\ varying highp vec2 A; \n\ void setPosition(void) \n\ @@ -253,7 +254,7 @@ static const char* const qglslPositionWithRadialGradientBrushVertexShader = "\n\ mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\ gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\ A = hTexCoords.xy * invertedHTexCoordsZ; \n\ - b = 2.0 * dot(A, fmp); \n\ + b = bradius.x + 2.0 * dot(A, fmp); \n\ }\n"; static const char* const qglslAffinePositionWithRadialGradientBrushVertexShader @@ -263,13 +264,22 @@ static const char* const qglslRadialGradientBrushSrcFragmentShader = "\n\ uniform sampler2D brushTexture; \n\ uniform highp float fmp2_m_radius2; \n\ uniform highp float inverse_2_fmp2_m_radius2; \n\ + uniform highp float sqrfr; \n\ varying highp float b; \n\ varying highp vec2 A; \n\ + uniform highp vec3 bradius; \n\ lowp vec4 srcPixel() \n\ { \n\ - highp float c = -dot(A, A); \n\ - highp vec2 val = vec2((-b + sqrt(b*b - 4.0*fmp2_m_radius2*c)) * inverse_2_fmp2_m_radius2, 0.5); \n\ - return texture2D(brushTexture, val); \n\ + highp float c = sqrfr-dot(A, A); \n\ + highp float det = b*b - 4.0*fmp2_m_radius2*c; \n\ + lowp vec4 result = vec4(0.0); \n\ + if (det >= 0.0) { \n\ + highp float detSqrt = sqrt(det); \n\ + highp float w = max((-b - detSqrt) * inverse_2_fmp2_m_radius2, (-b + detSqrt) * inverse_2_fmp2_m_radius2); \n\ + if (bradius.y + w * bradius.z >= 0.0) \n\ + result = texture2D(brushTexture, vec2(w, 0.5)); \n\ + } \n\ + return result; \n\ }\n"; diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp index 18c684f..38bd58d 100644 --- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp +++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp @@ -301,7 +301,7 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() const QRadialGradient *g = static_cast<const QRadialGradient *>(currentBrush.gradient()); QPointF realCenter = g->center(); QPointF realFocal = g->focalPoint(); - qreal realRadius = g->radius(); + qreal realRadius = g->centerRadius() - g->focalRadius(); translationPoint = realFocal; QPointF fmp = realCenter - realFocal; @@ -311,6 +311,12 @@ void QGL2PaintEngineExPrivate::updateBrushUniforms() shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Fmp2MRadius2), fmp2_m_radius2); shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::Inverse2Fmp2MRadius2), GLfloat(1.0 / (2.0*fmp2_m_radius2))); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::SqrFr), + GLfloat(g->focalRadius() * g->focalRadius())); + shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::BRadius), + GLfloat(2 * (g->centerRadius() - g->focalRadius()) * g->focalRadius()), + g->focalRadius(), + g->centerRadius() - g->focalRadius()); QVector2D halfViewportSize(width*0.5, height*0.5); shaderManager->currentProgram()->setUniformValue(location(QGLEngineShaderManager::HalfViewportSize), halfViewportSize); @@ -1548,6 +1554,14 @@ namespace { } +#if defined(Q_WS_WIN) +static bool fontSmoothingApproximately(qreal target) +{ + extern Q_GUI_EXPORT qreal qt_fontsmoothing_gamma; // qapplication_win.cpp + return (qAbs(qt_fontsmoothing_gamma - target) < 0.2); +} +#endif + // #define QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyphType, @@ -1786,7 +1800,6 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp shaderManager->setMaskType(QGLEngineShaderManager::PixelMask); prepareForDraw(false); // Text always causes src pixels to be transparent } - //### TODO: Gamma correction QGLTextureGlyphCache::FilterMode filterMode = (s->matrix.type() > QTransform::TxTranslate)?QGLTextureGlyphCache::Linear:QGLTextureGlyphCache::Nearest; if (lastMaskTextureUsed != cache->texture() || cache->filterMode() != filterMode) { @@ -1809,12 +1822,31 @@ void QGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngineGlyphCache::Type glyp } } + bool srgbFrameBufferEnabled = false; + if (ctx->d_ptr->extension_flags & QGLExtensions::SRGBFrameBuffer) { +#if defined(Q_WS_MAC) + if (glyphType == QFontEngineGlyphCache::Raster_RGBMask) +#elif defined(Q_WS_WIN) + if (glyphType != QFontEngineGlyphCache::Raster_RGBMask || fontSmoothingApproximately(2.1)) +#else + if (false) +#endif + { + glEnable(FRAMEBUFFER_SRGB_EXT); + srgbFrameBufferEnabled = true; + } + } + #if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO) glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); #else glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, elementIndices.data()); #endif + + if (srgbFrameBufferEnabled) + glDisable(FRAMEBUFFER_SRGB_EXT); + } void QGL2PaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap, @@ -1986,7 +2018,8 @@ bool QGL2PaintEngineEx::begin(QPaintDevice *pdev) #if !defined(QT_OPENGL_ES_2) #if defined(Q_WS_WIN) - if (qt_cleartype_enabled) + if (qt_cleartype_enabled + && (fontSmoothingApproximately(1.0) || fontSmoothingApproximately(2.1))) #endif #if defined(Q_WS_MAC) if (qt_applefontsmoothing_enabled) diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 057fb55..099cc00 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -5490,6 +5490,13 @@ QGLExtensions::Extensions QGLExtensions::currentContextExtensions() if (extensions.match("GL_EXT_bgra")) glExtensions |= BGRATextureFormat; + { + GLboolean srgbCapableFramebuffers; + glGetBooleanv(FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgbCapableFramebuffers); + if (srgbCapableFramebuffers) + glExtensions |= SRGBFrameBuffer; + } + return glExtensions; } diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index c57995d..ab88d9c 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -401,7 +401,7 @@ protected: #if defined(Q_WS_WIN) virtual int choosePixelFormat(void* pfd, HDC pdc); #endif -#if defined(Q_WS_X11) && defined(QT_NO_EGL) +#if defined(Q_WS_X11) virtual void* tryVisual(const QGLFormat& f, int bufDepth = 1); virtual void* chooseVisual(); #endif diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 50d13c9..ac54e2f 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -288,7 +288,8 @@ public: PVRTCTextureCompression = 0x00020000, FragmentShader = 0x00040000, ElementIndexUint = 0x00080000, - Depth24 = 0x00100000 + Depth24 = 0x00100000, + SRGBFrameBuffer = 0x00200000 }; Q_DECLARE_FLAGS(Extensions, Extension) diff --git a/src/opengl/qgl_symbian.cpp b/src/opengl/qgl_symbian.cpp index 1b41db4..ab37977 100644 --- a/src/opengl/qgl_symbian.cpp +++ b/src/opengl/qgl_symbian.cpp @@ -49,6 +49,9 @@ #include <private/qpaintengine_opengl_p.h> #include <private/qwidget_p.h> // to access QWExtra #include <private/qnativeimagehandleprovider_p.h> +#include <private/qapplication_p.h> +#include <private/qgraphicssystem_p.h> +#include <private/qgraphicssystemex_symbian_p.h> #include "qgl_egl_p.h" #include "qpixmapdata_gl_p.h" #include "qgltexturepool_p.h" @@ -180,6 +183,15 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // almost same as d->ownsEglContext = true; d->eglContext->setApi(QEgl::OpenGL); + QGraphicsSystemEx *ex = QApplicationPrivate::graphicsSystem()->platformExtension(); + QSymbianGraphicsSystemEx *symex = static_cast<QSymbianGraphicsSystemEx*>(ex); + if (symex && !symex->hasBCM2727()) { + // Most likely we have hw support for multisampling + // so let's enable it. + d->glFormat.setSampleBuffers(1); + d->glFormat.setSamples(4); + } + // If the device is a widget with WA_TranslucentBackground set, make sure the glFormat // has the alpha channel option set: if (devType == QInternal::Widget) { @@ -229,20 +241,20 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) // almost same as d->eglSurface = QEgl::createSurface(device(), d->eglContext->config()); - eglGetError(); // Clear error state first. + eglGetError(); // Clear error state first. #ifdef QGL_NO_PRESERVED_SWAP - eglSurfaceAttrib(QEgl::display(), d->eglSurface, - EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); + eglSurfaceAttrib(QEgl::display(), d->eglSurface, + EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); - if (eglGetError() != EGL_SUCCESS) - qWarning("QGLContext: could not enable destroyed swap behaviour"); + if (eglGetError() != EGL_SUCCESS) + qWarning("QGLContext: could not enable destroyed swap behaviour"); #else - eglSurfaceAttrib(QEgl::display(), d->eglSurface, - EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); + eglSurfaceAttrib(QEgl::display(), d->eglSurface, + EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); - if (eglGetError() != EGL_SUCCESS) - qWarning("QGLContext: could not enable preserved swap behaviour"); + if (eglGetError() != EGL_SUCCESS) + qWarning("QGLContext: could not enable preserved swap behaviour"); #endif setWindowCreated(true); diff --git a/src/opengl/qgl_x11egl.cpp b/src/opengl/qgl_x11egl.cpp index 2ddfd35..34ca97d 100644 --- a/src/opengl/qgl_x11egl.cpp +++ b/src/opengl/qgl_x11egl.cpp @@ -257,6 +257,20 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) return true; } +void *QGLContext::chooseVisual() +{ + qFatal("QGLContext::chooseVisual - this method must not be called as Qt is built with EGL support"); + return 0; +} + +void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) +{ + Q_UNUSED(f); + Q_UNUSED(bufDepth); + qFatal("QGLContext::tryVisual - this method must not be called as Qt is built with EGL support"); + return 0; +} + void QGLWidget::resizeEvent(QResizeEvent *) { Q_D(QGLWidget); diff --git a/src/opengl/qglextensions_p.h b/src/opengl/qglextensions_p.h index 529c7a1..ac80ce8 100644 --- a/src/opengl/qglextensions_p.h +++ b/src/opengl/qglextensions_p.h @@ -477,6 +477,14 @@ struct QGLExtensionFuncs // OpenGL constants +#ifndef FRAMEBUFFER_SRGB_CAPABLE_EXT +#define FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#endif + +#ifndef FRAMEBUFFER_SRGB_EXT +#define FRAMEBUFFER_SRGB_EXT 0x8DB9 +#endif + #ifndef GL_ARRAY_BUFFER #define GL_ARRAY_BUFFER 0x8892 #endif diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp index be8219a..9137e0f 100644 --- a/src/opengl/qglfunctions.cpp +++ b/src/opengl/qglfunctions.cpp @@ -211,19 +211,24 @@ QGLFunctions::QGLFunctions(const QGLContext *context) static int qt_gl_resolve_features() { #if defined(QT_OPENGL_ES_2) - return QGLFunctions::Multitexture | - QGLFunctions::Shaders | - QGLFunctions::Buffers | - QGLFunctions::Framebuffers | - QGLFunctions::BlendColor | - QGLFunctions::BlendEquation | - QGLFunctions::BlendEquationSeparate | - QGLFunctions::BlendFuncSeparate | - QGLFunctions::BlendSubtract | - QGLFunctions::CompressedTextures | - QGLFunctions::Multisample | - QGLFunctions::StencilSeparate | - QGLFunctions::NPOTTextures; + int features = QGLFunctions::Multitexture | + QGLFunctions::Shaders | + QGLFunctions::Buffers | + QGLFunctions::Framebuffers | + QGLFunctions::BlendColor | + QGLFunctions::BlendEquation | + QGLFunctions::BlendEquationSeparate | + QGLFunctions::BlendFuncSeparate | + QGLFunctions::BlendSubtract | + QGLFunctions::CompressedTextures | + QGLFunctions::Multisample | + QGLFunctions::StencilSeparate; + QGLExtensionMatcher extensions; + if (extensions.match("GL_OES_texture_npot")) + features |= QGLFunctions::NPOTTextures; + if (extensions.match("GL_IMG_texture_npot")) + features |= QGLFunctions::NPOTTextures; + return features; #elif defined(QT_OPENGL_ES) int features = QGLFunctions::Multitexture | QGLFunctions::Buffers | @@ -240,6 +245,8 @@ static int qt_gl_resolve_features() features |= QGLFunctions::BlendSubtract; if (extensions.match("GL_OES_texture_npot")) features |= QGLFunctions::NPOTTextures; + if (extensions.match("GL_IMG_texture_npot")) + features |= QGLFunctions::NPOTTextures; return features; #else int features = 0; diff --git a/src/opengl/qgraphicssystem_gl.cpp b/src/opengl/qgraphicssystem_gl.cpp index 0aa3c2e..5a01d8c 100644 --- a/src/opengl/qgraphicssystem_gl.cpp +++ b/src/opengl/qgraphicssystem_gl.cpp @@ -104,11 +104,17 @@ QWindowSurface *QGLGraphicsSystem::createWindowSurface(QWidget *widget) const return new QGLWindowSurface(widget); } -#ifdef QGL_USE_TEXTURE_POOL -void QGLGraphicsSystem::releaseCachedResources() +#ifdef Q_OS_SYMBIAN +void QGLGraphicsSystem::releaseCachedGpuResources() { QGLTexturePool::instance()->hibernate(); } + +QGraphicsSystemEx* QGLGraphicsSystem::platformExtension() +{ + return this; +} #endif + QT_END_NAMESPACE diff --git a/src/opengl/qgraphicssystem_gl_p.h b/src/opengl/qgraphicssystem_gl_p.h index 5829dcc..5372443 100644 --- a/src/opengl/qgraphicssystem_gl_p.h +++ b/src/opengl/qgraphicssystem_gl_p.h @@ -55,11 +55,19 @@ #include "private/qgraphicssystem_p.h" +#ifdef Q_OS_SYMBIAN +#include "private/qgraphicssystemex_symbian_p.h" +#endif + #include <QMap> QT_BEGIN_NAMESPACE class Q_OPENGL_EXPORT QGLGraphicsSystem : public QGraphicsSystem +#ifdef Q_OS_SYMBIAN + , public QSymbianGraphicsSystemEx +#endif + { public: QGLGraphicsSystem(bool useX11GL); @@ -67,8 +75,9 @@ public: QPixmapData *createPixmapData(QPixmapData::PixelType type) const; QWindowSurface *createWindowSurface(QWidget *widget) const; -#ifdef QGL_USE_TEXTURE_POOL - void releaseCachedResources(); +#ifdef Q_OS_SYMBIAN + void releaseCachedGpuResources(); + QGraphicsSystemEx* platformExtension(); #endif private: bool m_useX11GL; diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 9da811a..58ce6f8 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -2119,6 +2119,7 @@ void QOpenGLPaintEnginePrivate::fillPath(const QPainterPath &path) updateGLMatrix(); } +Q_GUI_EXPORT bool qt_isExtendedRadialGradient(const QBrush &brush); static inline bool needsEmulation(Qt::BrushStyle style) { @@ -2129,9 +2130,11 @@ static inline bool needsEmulation(Qt::BrushStyle style) void QOpenGLPaintEnginePrivate::updateUseEmulation() { - use_emulation = !use_fragment_programs - && ((has_pen && needsEmulation(pen_brush_style)) - || (has_brush && needsEmulation(brush_style))); + use_emulation = (!use_fragment_programs + && ((has_pen && needsEmulation(pen_brush_style)) + || (has_brush && needsEmulation(brush_style)))) + || (has_pen && qt_isExtendedRadialGradient(cpen.brush())) + || (has_brush && qt_isExtendedRadialGradient(cbrush)); } void QOpenGLPaintEngine::updatePen(const QPen &pen) @@ -5447,50 +5450,7 @@ void QOpenGLPaintEngine::transformChanged() updateMatrix(state()->matrix); } -static QPainterPath painterPathFromVectorPath(const QVectorPath &path) -{ - const qreal *points = path.points(); - const QPainterPath::ElementType *types = path.elements(); - - QPainterPath p; - if (types) { - int id = 0; - for (int i=0; i<path.elementCount(); ++i) { - switch(types[i]) { - case QPainterPath::MoveToElement: - p.moveTo(QPointF(points[id], points[id+1])); - id+=2; - break; - case QPainterPath::LineToElement: - p.lineTo(QPointF(points[id], points[id+1])); - id+=2; - break; - case QPainterPath::CurveToElement: { - QPointF p1(points[id], points[id+1]); - QPointF p2(points[id+2], points[id+3]); - QPointF p3(points[id+4], points[id+5]); - p.cubicTo(p1, p2, p3); - id+=6; - break; - } - case QPainterPath::CurveToDataElement: - ; - break; - } - } - } else { - p.moveTo(QPointF(points[0], points[1])); - int id = 2; - for (int i=1; i<path.elementCount(); ++i) { - p.lineTo(QPointF(points[id], points[id+1])); - id+=2; - } - } - if (path.hints() & QVectorPath::WindingFill) - p.setFillRule(Qt::WindingFill); - - return p; -} +Q_GUI_EXPORT QPainterPath qt_painterPathFromVectorPath(const QVectorPath &path); void QOpenGLPaintEngine::fill(const QVectorPath &path, const QBrush &brush) { @@ -5499,11 +5459,11 @@ void QOpenGLPaintEngine::fill(const QVectorPath &path, const QBrush &brush) if (brush.style() == Qt::NoBrush) return; - if (!d->use_fragment_programs && needsEmulation(brush.style())) { + if ((!d->use_fragment_programs && needsEmulation(brush.style())) || qt_isExtendedRadialGradient(brush)) { QPainter *p = painter(); QBrush oldBrush = p->brush(); p->setBrush(brush); - qt_draw_helper(p->d_ptr.data(), painterPathFromVectorPath(path), QPainterPrivate::FillDraw); + qt_draw_helper(p->d_ptr.data(), qt_painterPathFromVectorPath(path), QPainterPrivate::FillDraw); p->setBrush(oldBrush); return; } @@ -5520,7 +5480,7 @@ void QOpenGLPaintEngine::fill(const QVectorPath &path, const QBrush &brush) drawRects(&r, 1); updatePen(old_pen); } else { - d->fillPath(painterPathFromVectorPath(path)); + d->fillPath(qt_painterPathFromVectorPath(path)); } updateBrush(old_brush, state()->brushOrigin); diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp index 56e2c3b..49b3dc2 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -184,7 +184,9 @@ QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL) class QGLGlobalShareWidget { public: - QGLGlobalShareWidget() : firstPixmap(0), widgetRefCount(0), widget(0), initializing(false) {} + QGLGlobalShareWidget() : firstPixmap(0), widgetRefCount(0), widget(0), initializing(false) { + created = true; + } QGLWidget *shareWidget() { if (!initializing && !widget && !cleanedUp) { @@ -223,6 +225,7 @@ public: } static bool cleanedUp; + static bool created; QGLPixmapData *firstPixmap; int widgetRefCount; @@ -233,6 +236,7 @@ private: }; bool QGLGlobalShareWidget::cleanedUp = false; +bool QGLGlobalShareWidget::created = false; static void qt_cleanup_gl_share_widget(); Q_GLOBAL_STATIC_WITH_INITIALIZER(QGLGlobalShareWidget, _qt_gl_share_widget, @@ -242,7 +246,8 @@ Q_GLOBAL_STATIC_WITH_INITIALIZER(QGLGlobalShareWidget, _qt_gl_share_widget, static void qt_cleanup_gl_share_widget() { - _qt_gl_share_widget()->cleanup(); + if (QGLGlobalShareWidget::created) + _qt_gl_share_widget()->cleanup(); } QGLWidget* qt_gl_share_widget() @@ -254,7 +259,8 @@ QGLWidget* qt_gl_share_widget() void qt_destroy_gl_share_widget() { - _qt_gl_share_widget()->destroy(); + if (QGLGlobalShareWidget::created) + _qt_gl_share_widget()->destroy(); } const QGLContext *qt_gl_share_context() @@ -610,6 +616,17 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & if (!d_ptr->destructive_swap_buffers && !d_ptr->did_paint) return; +#ifdef Q_OS_SYMBIAN + if (window() != widget) { + // For performance reasons we don't support + // flushing native child widgets on Symbian. + // It breaks overlapping native child widget + // rendering in some cases but we prefer performance. + return; + } +#endif + + QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); Q_ASSERT(parent); diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 588c35a..70e26fb 100644 --- a/src/openvg/qpaintengine_vg.cpp +++ b/src/openvg/qpaintengine_vg.cpp @@ -173,6 +173,9 @@ public: bool forcePenChange; // Force a pen change, even if the same. bool forceBrushChange; // Force a brush change, even if the same. + bool hasExtendedRadialGradientPen; // Current pen's brush is extended radial gradient. + bool hasExtendedRadialGradientBrush; // Current brush is extended radial gradient. + VGPaintType penType; // Type of the last pen that was set. VGPaintType brushType; // Type of the last brush that was set. @@ -275,6 +278,27 @@ public: } } + inline bool needsEmulation(const QBrush &brush) const + { + Q_GUI_EXPORT bool qt_isExtendedRadialGradient(const QBrush &brush); + return qt_isExtendedRadialGradient(brush); + } + + inline bool needsEmulation() const + { + return hasExtendedRadialGradientPen || hasExtendedRadialGradientBrush; + } + + inline bool needsPenEmulation() const + { + return hasExtendedRadialGradientPen; + } + + inline bool needsBrushEmulation() const + { + return hasExtendedRadialGradientBrush; + } + // Set various modes, but only if different. inline void setImageMode(VGImageMode mode); inline void setRenderingQuality(VGRenderingQuality mode); @@ -355,6 +379,10 @@ void QVGPaintEnginePrivate::init() forcePenChange = true; forceBrushChange = true; + + hasExtendedRadialGradientPen = false; + hasExtendedRadialGradientBrush = false; + penType = (VGPaintType)0; brushType = (VGPaintType)0; @@ -1530,12 +1558,18 @@ bool QVGPaintEngine::begin(QPaintDevice *pdev) bool QVGPaintEngine::end() { + vgSeti(VG_SCISSORING, VG_FALSE); + vgSeti(VG_MASKING, VG_FALSE); return true; } void QVGPaintEngine::draw(const QVectorPath &path) { Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::draw(path); + return; + } QVGPainterState *s = state(); VGPath vgpath = d->vectorPathToVGPath(path); if (!path.hasWindingFill()) @@ -1545,9 +1579,19 @@ void QVGPaintEngine::draw(const QVectorPath &path) vgDestroyPath(vgpath); } +Q_GUI_EXPORT QPainterPath qt_painterPathFromVectorPath(const QVectorPath &path); + void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush) { Q_D(QVGPaintEngine); + if (d->needsEmulation(brush)) { + QPainter *p = painter(); + QBrush oldBrush = p->brush(); + p->setBrush(brush); + qt_draw_helper(p->d_ptr.data(), qt_painterPathFromVectorPath(path), QPainterPrivate::FillDraw); + p->setBrush(oldBrush); + return; + } VGPath vgpath = d->vectorPathToVGPath(path); if (!path.hasWindingFill()) d->fill(vgpath, brush, VG_EVEN_ODD); @@ -1559,6 +1603,10 @@ void QVGPaintEngine::fill(const QVectorPath &path, const QBrush &brush) void QVGPaintEngine::stroke(const QVectorPath &path, const QPen &pen) { Q_D(QVGPaintEngine); + if (d->needsEmulation(pen.brush())) { + QPaintEngineEx::stroke(path, pen); + return; + } VGPath vgpath = d->vectorPathToVGPath(path); d->stroke(vgpath, pen); vgDestroyPath(vgpath); @@ -2362,12 +2410,17 @@ void QVGPaintEngine::penChanged() { Q_D(QVGPaintEngine); d->dirty |= QPaintEngine::DirtyPen; + + d->hasExtendedRadialGradientPen = + state()->pen.style() != Qt::NoPen && d->needsEmulation(state()->pen.brush()); } void QVGPaintEngine::brushChanged() { Q_D(QVGPaintEngine); d->dirty |= QPaintEngine::DirtyBrush; + + d->hasExtendedRadialGradientPen = d->needsEmulation(state()->brush); } void QVGPaintEngine::brushOriginChanged() @@ -2546,6 +2599,11 @@ void QVGPaintEngine::fillRect(const QRectF &rect, const QBrush &brush) return; } + if (d->needsEmulation(brush)) { + QPaintEngineEx::fillRect(rect, brush); + return; + } + #if !defined(QVG_NO_MODIFY_PATH) VGfloat coords[8]; if (d->simpleTransform) { @@ -2623,6 +2681,10 @@ void QVGPaintEngine::fillRect(const QRectF &rect, const QColor &color) void QVGPaintEngine::drawRoundedRect(const QRectF &rect, qreal xrad, qreal yrad, Qt::SizeMode mode) { Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawRoundedRect(rect, xrad, yrad, mode); + return; + } if (d->simpleTransform) { QVGPainterState *s = state(); VGPath vgpath = d->roundedRectPath(rect, xrad, yrad, mode); @@ -2639,6 +2701,10 @@ void QVGPaintEngine::drawRects(const QRect *rects, int rectCount) { #if !defined(QVG_NO_MODIFY_PATH) Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawRects(rects, rectCount); + return; + } QVGPainterState *s = state(); for (int i = 0; i < rectCount; ++i, ++rects) { VGfloat coords[8]; @@ -2680,6 +2746,10 @@ void QVGPaintEngine::drawRects(const QRectF *rects, int rectCount) { #if !defined(QVG_NO_MODIFY_PATH) Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawRects(rects, rectCount); + return; + } QVGPainterState *s = state(); for (int i = 0; i < rectCount; ++i, ++rects) { VGfloat coords[8]; @@ -2718,6 +2788,10 @@ void QVGPaintEngine::drawLines(const QLine *lines, int lineCount) { #if !defined(QVG_NO_MODIFY_PATH) Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawLines(lines, lineCount); + return; + } QVGPainterState *s = state(); for (int i = 0; i < lineCount; ++i, ++lines) { VGfloat coords[4]; @@ -2746,6 +2820,10 @@ void QVGPaintEngine::drawLines(const QLineF *lines, int lineCount) { #if !defined(QVG_NO_MODIFY_PATH) Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawLines(lines, lineCount); + return; + } QVGPainterState *s = state(); for (int i = 0; i < lineCount; ++i, ++lines) { VGfloat coords[4]; @@ -2775,6 +2853,10 @@ void QVGPaintEngine::drawEllipse(const QRectF &r) // Based on the description of vguEllipse() in the OpenVG specification. // We don't use vguEllipse(), to avoid unnecessary library dependencies. Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawEllipse(r); + return; + } if (d->simpleTransform) { QVGPainterState *s = state(); VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, @@ -2825,6 +2907,10 @@ void QVGPaintEngine::drawPath(const QPainterPath &path) // Shortcut past the QPainterPath -> QVectorPath conversion, // converting the QPainterPath directly into a VGPath. Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawPath(path); + return; + } QVGPainterState *s = state(); VGPath vgpath = d->painterPathToVGPath(path); if (path.fillRule() == Qt::OddEvenFill) @@ -2839,6 +2925,11 @@ void QVGPaintEngine::drawPoints(const QPointF *points, int pointCount) #if !defined(QVG_NO_MODIFY_PATH) Q_D(QVGPaintEngine); + if (d->needsPenEmulation()) { + QPaintEngineEx::drawPoints(points, pointCount); + return; + } + // Set up a new pen if necessary. QPen pen = state()->pen; if (pen.style() == Qt::NoPen) @@ -2873,6 +2964,11 @@ void QVGPaintEngine::drawPoints(const QPoint *points, int pointCount) #if !defined(QVG_NO_MODIFY_PATH) Q_D(QVGPaintEngine); + if (d->needsEmulation()) { + QPaintEngineEx::drawPoints(points, pointCount); + return; + } + // Set up a new pen if necessary. QPen pen = state()->pen; if (pen.style() == Qt::NoPen) @@ -2905,6 +3001,12 @@ void QVGPaintEngine::drawPoints(const QPoint *points, int pointCount) void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode) { Q_D(QVGPaintEngine); + + if (d->needsEmulation()) { + QPaintEngineEx::drawPolygon(points, pointCount, mode); + return; + } + QVGPainterState *s = state(); VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, @@ -2952,6 +3054,12 @@ void QVGPaintEngine::drawPolygon(const QPointF *points, int pointCount, PolygonD void QVGPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode) { Q_D(QVGPaintEngine); + + if (d->needsEmulation()) { + QPaintEngineEx::drawPolygon(points, pointCount, mode); + return; + } + QVGPainterState *s = state(); VGPath path = vgCreatePath(VG_PATH_FORMAT_STANDARD, VG_PATH_DATATYPE_F, @@ -3611,6 +3719,11 @@ void QVGPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem) return; } + if (d->needsPenEmulation()) { + QPaintEngineEx::drawTextItem(p, textItem); + return; + } + // Get the glyphs and positions associated with the text item. QVarLengthArray<QFixedPoint> positions; QVarLengthArray<glyph_t> glyphs; @@ -3756,6 +3869,8 @@ void QVGPaintEngine::beginNativePainting() #if !defined(QVG_NO_DRAW_GLYPHS) d->setTransform(VG_MATRIX_GLYPH_USER_TO_SURFACE, d->pathTransform); #endif + vgSeti(VG_SCISSORING, VG_FALSE); + vgSeti(VG_MASKING, VG_FALSE); d->rawVG = true; } @@ -3816,6 +3931,7 @@ void QVGPaintEngine::restoreState(QPaintEngine::DirtyFlags dirty) if ((dirty & QPaintEngine::DirtyBrushOrigin) != 0) brushOriginChanged(); d->fillRule = 0; + d->clearColor = QColor(); if ((dirty & QPaintEngine::DirtyOpacity) != 0) opacityChanged(); if ((dirty & QPaintEngine::DirtyTransform) != 0) diff --git a/src/openvg/qpixmapdata_vg.cpp b/src/openvg/qpixmapdata_vg.cpp index ea93748..e52722d 100644 --- a/src/openvg/qpixmapdata_vg.cpp +++ b/src/openvg/qpixmapdata_vg.cpp @@ -378,7 +378,7 @@ VGImage QVGPixmapData::toVGImage() QVGImagePool::instance()->useImage(this); } - if (!source.isNull() && recreate) { + if (!source.isNull() && (recreate || source.paintingActive())) { source.beginDataAccess(); vgImageSubData (vgImage, diff --git a/src/openvg/qwindowsurface_vg.cpp b/src/openvg/qwindowsurface_vg.cpp index eedfea5..dcc5d6a 100644 --- a/src/openvg/qwindowsurface_vg.cpp +++ b/src/openvg/qwindowsurface_vg.cpp @@ -78,6 +78,17 @@ QPaintDevice *QVGWindowSurface::paintDevice() void QVGWindowSurface::flush(QWidget *widget, const QRegion ®ion, const QPoint &offset) { Q_UNUSED(offset); + +#ifdef Q_OS_SYMBIAN + if (window() != widget) { + // For performance reasons we don't support + // flushing native child widgets on Symbian. + // It breaks overlapping native child widget + // rendering in some cases but we prefer performance. + return; + } +#endif + QWidget *parent = widget->internalWinId() ? widget : widget->nativeParentWidget(); d_ptr->endPaint(parent, region); } diff --git a/src/plugins/codecs/jp/qsjiscodec.cpp b/src/plugins/codecs/jp/qsjiscodec.cpp index 49190d3..3ea5300 100644 --- a/src/plugins/codecs/jp/qsjiscodec.cpp +++ b/src/plugins/codecs/jp/qsjiscodec.cpp @@ -155,7 +155,9 @@ QString QSjisCodec::convertToUnicode(const char* chars, int len, ConverterState uchar ch = chars[i]; switch (nbuf) { case 0: - if (ch < 0x80 || IsKana(ch)) { + if (ch < 0x80) { + result += QValidChar(ch); + } else if (IsKana(ch)) { // JIS X 0201 Latin or JIS X 0201 Kana u = conv->jisx0201ToUnicode(ch); result += QValidChar(u); diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp index 4b4f677..bf29dd4 100644 --- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp +++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg.cpp @@ -80,9 +80,15 @@ QWindowSurface *QVGGraphicsSystem::createWindowSurface(QWidget *widget) const return new QVGWindowSurface(widget); } -void QVGGraphicsSystem::releaseCachedResources() +#ifdef Q_OS_SYMBIAN +void QVGGraphicsSystem::releaseCachedGpuResources() { QVGImagePool::instance()->hibernate(); } +QGraphicsSystemEx *QVGGraphicsSystem::platformExtension() +{ + return this; +} +#endif QT_END_NAMESPACE diff --git a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h index 9c9b3e2..feff451 100644 --- a/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h +++ b/src/plugins/graphicssystems/openvg/qgraphicssystem_vg_p.h @@ -55,9 +55,16 @@ #include <QtGui/private/qgraphicssystem_p.h> +#ifdef Q_OS_SYMBIAN +#include <QtGui/private/qgraphicssystemex_symbian_p.h> +#endif + QT_BEGIN_NAMESPACE class QVGGraphicsSystem : public QGraphicsSystem +#ifdef Q_OS_SYMBIAN + , public QSymbianGraphicsSystemEx +#endif { public: QVGGraphicsSystem(); @@ -65,7 +72,10 @@ public: QPixmapData *createPixmapData(QPixmapData::PixelType type) const; QWindowSurface *createWindowSurface(QWidget *widget) const; - void releaseCachedResources(); +#ifdef Q_OS_SYMBIAN + void releaseCachedGpuResources(); + QGraphicsSystemEx* platformExtension(); +#endif }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/uikit/quikiteventloop.mm b/src/plugins/platforms/uikit/quikiteventloop.mm index 8d2603c..2b9728c 100644 --- a/src/plugins/platforms/uikit/quikiteventloop.mm +++ b/src/plugins/platforms/uikit/quikiteventloop.mm @@ -69,13 +69,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { Q_UNUSED(launchOptions) + Q_UNUSED(application) foreach (QWidget *widget, qApp->topLevelWidgets()) { - QRect geom = widget->geometry(); - CGRect bar = application.statusBarFrame; - if (geom.y() <= bar.size.height) { - geom.setY(bar.size.height); - widget->setGeometry(geom); - } QUIKitWindow *platformWindow = static_cast<QUIKitWindow *>(widget->platformWindow()); platformWindow->ensureNativeWindow(); } diff --git a/src/plugins/platforms/uikit/quikitintegration.mm b/src/plugins/platforms/uikit/quikitintegration.mm index d4b4192..3a432d1 100644 --- a/src/plugins/platforms/uikit/quikitintegration.mm +++ b/src/plugins/platforms/uikit/quikitintegration.mm @@ -66,7 +66,7 @@ QUIKitIntegration::~QUIKitIntegration() QPixmapData *QUIKitIntegration::createPixmapData(QPixmapData::PixelType type) const { - return new QRasterPixmapData(type); + return new QRasterPixmapData(type); } QPlatformWindow *QUIKitIntegration::createPlatformWindow(QWidget *widget, WId winId) const diff --git a/src/plugins/platforms/uikit/quikitscreen.mm b/src/plugins/platforms/uikit/quikitscreen.mm index 21494c9..78389f2 100644 --- a/src/plugins/platforms/uikit/quikitscreen.mm +++ b/src/plugins/platforms/uikit/quikitscreen.mm @@ -54,7 +54,7 @@ QUIKitScreen::QUIKitScreen(int screenIndex) NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; UIScreen *screen = [[UIScreen screens] objectAtIndex:screenIndex]; CGRect bounds = [screen bounds]; - m_geometry = QRect(0, 0, bounds.size.width, bounds.size.height); + m_geometry = QRect(bounds.origin.x, bounds.origin.y, bounds.size.width, bounds.size.height); m_format = QImage::Format_ARGB32; @@ -62,7 +62,7 @@ QUIKitScreen::QUIKitScreen(int screenIndex) const qreal inch = 25.4; qreal dpi = 160.; - int dragDistance = 14; + int dragDistance = 12; if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) { dpi = 132.; dragDistance = 10; diff --git a/src/plugins/platforms/uikit/quikitwindow.h b/src/plugins/platforms/uikit/quikitwindow.h index 9e73754..5c6496a 100644 --- a/src/plugins/platforms/uikit/quikitwindow.h +++ b/src/plugins/platforms/uikit/quikitwindow.h @@ -47,6 +47,8 @@ #import <UIKit/UIKit.h> #import <OpenGLES/ES1/gl.h> #import <OpenGLES/ES1/glext.h> +#import <OpenGLES/ES2/gl.h> +#import <OpenGLES/ES2/glext.h> #import <OpenGLES/EAGL.h> @interface EAGLView : UIView <UIKeyInput> @@ -59,6 +61,7 @@ GLuint mFramebuffer, mColorRenderbuffer, mDepthRenderbuffer; + id delegate; // ------- Text Input ---------- UITextAutocapitalizationType autocapitalizationType; UITextAutocorrectionType autocorrectionType; @@ -77,6 +80,8 @@ - (void)setWindow:(QPlatformWindow *)window; - (void)sendMouseEventForTouches:(NSSet *)touches withEvent:(UIEvent *)event fakeButtons:(Qt::MouseButtons)buttons; +@property (readonly,getter=fbo) GLint fbo; +@property (nonatomic, assign) id delegate; // ------- Text Input ---------- @@ -90,6 +95,10 @@ @end +@protocol EAGLViewDelegate +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; +@end + class EAGLPlatformContext; QT_BEGIN_NAMESPACE @@ -103,7 +112,7 @@ public: ~QUIKitWindow(); UIWindow *nativeWindow() const { return mWindow; } - UIView *nativeView() const { return mView; } + EAGLView *nativeView() const { return mView; } void setGeometry(const QRect &rect); UIWindow *ensureNativeWindow(); diff --git a/src/plugins/platforms/uikit/quikitwindow.mm b/src/plugins/platforms/uikit/quikitwindow.mm index 52d1846..1f57baa 100644 --- a/src/plugins/platforms/uikit/quikitwindow.mm +++ b/src/plugins/platforms/uikit/quikitwindow.mm @@ -79,7 +79,11 @@ public: mFormat.setStereo(false); mFormat.setDirectRendering(false); +#if defined(QT_OPENGL_ES_2) + EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; +#else EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; +#endif [mView setContext:aContext]; } @@ -116,6 +120,8 @@ private: @implementation EAGLView +@synthesize delegate; + + (Class)layerClass { return [CAEAGLLayer class]; @@ -156,8 +162,8 @@ private: { if (mContext) { [EAGLContext setCurrentContext:mContext]; - glBindRenderbufferOES(GL_RENDERBUFFER_OES, mColorRenderbuffer); - [mContext presentRenderbuffer:GL_RENDERBUFFER_OES]; + glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + [mContext presentRenderbuffer:GL_RENDERBUFFER]; } } @@ -167,15 +173,15 @@ private: { [EAGLContext setCurrentContext:mContext]; if (mFramebuffer) { - glDeleteFramebuffersOES(1, &mFramebuffer); + glDeleteFramebuffers(1, &mFramebuffer); mFramebuffer = 0; } if (mColorRenderbuffer) { - glDeleteRenderbuffersOES(1, &mColorRenderbuffer); + glDeleteRenderbuffers(1, &mColorRenderbuffer); mColorRenderbuffer = 0; } if (mDepthRenderbuffer) { - glDeleteRenderbuffersOES(1, &mDepthRenderbuffer); + glDeleteRenderbuffers(1, &mDepthRenderbuffer); mDepthRenderbuffer = 0; } } @@ -186,24 +192,27 @@ private: if (mContext && !mFramebuffer) { [EAGLContext setCurrentContext:mContext]; - glGenFramebuffersOES(1, &mFramebuffer); - glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFramebuffer); - - glGenRenderbuffersOES(1, &mColorRenderbuffer); - glBindRenderbufferOES(GL_RENDERBUFFER_OES, mColorRenderbuffer); - [mContext renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(CAEAGLLayer *)self.layer]; - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &mFramebufferWidth); - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &mFramebufferHeight); - glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, mColorRenderbuffer); - - glGenRenderbuffersOES(1, &mDepthRenderbuffer); - glBindRenderbufferOES(GL_RENDERBUFFER_OES, mDepthRenderbuffer); - glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight); - glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer); - glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_STENCIL_ATTACHMENT_OES, GL_RENDERBUFFER_OES, mDepthRenderbuffer); - - if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) - NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); + glGenFramebuffers(1, &mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); + + glGenRenderbuffers(1, &mColorRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mColorRenderbuffer); + [mContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &mFramebufferWidth); + glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &mFramebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, mColorRenderbuffer); + + glGenRenderbuffers(1, &mDepthRenderbuffer); + glBindRenderbuffer(GL_RENDERBUFFER, mDepthRenderbuffer); + glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, mFramebufferWidth, mFramebufferHeight); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, mDepthRenderbuffer); + + if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) + NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); + if (delegate && [delegate respondsToSelector:@selector(eaglView:usesFramebuffer:)]) { + [delegate eaglView:self usesFramebuffer:mFramebuffer]; + } } } @@ -214,11 +223,16 @@ private: [EAGLContext setCurrentContext:mContext]; if (!mFramebuffer) [self createFramebuffer]; - glBindFramebufferOES(GL_FRAMEBUFFER_OES, mFramebuffer); + glBindFramebuffer(GL_FRAMEBUFFER, mFramebuffer); glViewport(0, 0, mFramebufferWidth, mFramebufferHeight); } } +- (GLint)fbo +{ + return mFramebuffer; +} + - (void)setWindow:(QPlatformWindow *)window { mWindow = window; @@ -322,6 +336,7 @@ QUIKitWindow::QUIKitWindow(QWidget *tlw) : CGRect screenBounds = [mScreen->uiScreen() bounds]; QRect geom(screenBounds.origin.x, screenBounds.origin.y, screenBounds.size.width, screenBounds.size.height); setGeometry(geom); + mView = [[EAGLView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; // TODO ensure the native window if the application is already running } @@ -334,7 +349,7 @@ QUIKitWindow::~QUIKitWindow() void QUIKitWindow::setGeometry(const QRect &rect) { - if (mWindow) { + if (mWindow && rect != geometry()) { mWindow.frame = CGRectMake(rect.x(), rect.y(), rect.width(), rect.height()); mView.frame = CGRectMake(0, 0, rect.width(), rect.height()); [mView deleteFramebuffer]; @@ -347,14 +362,16 @@ UIWindow *QUIKitWindow::ensureNativeWindow() { if (!mWindow) { // window - QRect geom = geometry(); - CGRect frame = CGRectMake(geom.x(), geom.y(), geom.width(), geom.height()); - mWindow = [[UIWindow alloc] initWithFrame:frame]; + CGRect frame = [mScreen->uiScreen() applicationFrame]; + QRect geom = QRect(frame.origin.x, frame.origin.y, frame.size.width, frame.size.height); + widget()->setGeometry(geom); + mWindow = [[UIWindow alloc] init]; mWindow.screen = mScreen->uiScreen(); - mWindow.frame = frame; // for some reason setting the screen resets frame.origin + mWindow.frame = frame; // for some reason setting the screen resets frame.origin, so we need to set the frame afterwards // view - mView = [[EAGLView alloc] initWithFrame:CGRectMake(0, 0, geom.width(), geom.height())]; + [mView deleteFramebuffer]; + mView.frame = CGRectMake(0, 0, frame.size.width, frame.size.height); // fill [mView setMultipleTouchEnabled:YES]; [mView setWindow:this]; [mWindow addSubview:mView]; diff --git a/src/plugins/platforms/uikit/quikitwindowsurface.mm b/src/plugins/platforms/uikit/quikitwindowsurface.mm index bb7dcd7..8caa15f 100644 --- a/src/plugins/platforms/uikit/quikitwindowsurface.mm +++ b/src/plugins/platforms/uikit/quikitwindowsurface.mm @@ -47,27 +47,64 @@ #include <QtDebug> +class EAGLPaintDevice; + +@interface PaintDeviceHelper : NSObject { + EAGLPaintDevice *device; +} + +@property (nonatomic, assign) EAGLPaintDevice *device; + +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer; + +@end + class EAGLPaintDevice : public QGLPaintDevice { public: EAGLPaintDevice(QPlatformWindow *window) :QGLPaintDevice(), mWindow(window) { +#if defined(QT_OPENGL_ES_2) + helper = [[PaintDeviceHelper alloc] init]; + helper.device = this; + EAGLView *view = static_cast<QUIKitWindow *>(window)->nativeView(); + view.delegate = helper; + m_thisFBO = view.fbo; +#endif } + ~EAGLPaintDevice() + { +#if defined(QT_OPENGL_ES_2) + [helper release]; +#endif + } + + void setFramebuffer(GLuint buffer) { m_thisFBO = buffer; } int devType() const { return QInternal::OpenGL; } QSize size() const { return mWindow->geometry().size(); } QGLContext* context() const { return QGLContext::fromPlatformGLContext(mWindow->glContext()); } QPaintEngine *paintEngine() const { return qt_qgl_paint_engine(); } - void beginPaint(){ - QGLPaintDevice::beginPaint(); - } private: QPlatformWindow *mWindow; + PaintDeviceHelper *helper; }; +@implementation PaintDeviceHelper +@synthesize device; + +- (void)eaglView:(EAGLView *)view usesFramebuffer:(GLuint)buffer +{ + Q_UNUSED(view) + if (device) + device->setFramebuffer(buffer); +} + +@end + QT_BEGIN_NAMESPACE QUIKitWindowSurface::QUIKitWindowSurface(QWidget *window) diff --git a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp index ebe4c7b..7929ccb 100644 --- a/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp +++ b/src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp @@ -178,7 +178,7 @@ void QWaylandGLWindowSurface::resize(const QSize &size) QWindowSurface::resize(size); window()->platformWindow()->glContext()->makeCurrent(); delete mPaintDevice; - mPaintDevice = new QGLFramebufferObject(size); + mPaintDevice = new QGLFramebufferObject(size,QGLFramebufferObject::CombinedDepthStencil); } QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp index 39e7be5..ddd1763 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.cpp @@ -49,7 +49,6 @@ QWaylandEglIntegration::QWaylandEglIntegration(struct wl_display *waylandDisplay) : mWaylandDisplay(waylandDisplay) - , mNativeEglDisplay(wl_egl_display_create(mWaylandDisplay)) { qDebug() << "Using Wayland-EGL"; } @@ -63,7 +62,7 @@ QWaylandEglIntegration::~QWaylandEglIntegration() void QWaylandEglIntegration::initialize() { EGLint major,minor; - mEglDisplay = eglGetDisplay((EGLNativeDisplayType)mNativeEglDisplay); + mEglDisplay = eglGetDisplay(mWaylandDisplay); if (mEglDisplay == NULL) { qWarning("EGL not available"); } else { @@ -84,11 +83,6 @@ EGLDisplay QWaylandEglIntegration::eglDisplay() const return mEglDisplay; } -wl_egl_display * QWaylandEglIntegration::nativeDisplay() const -{ - return mNativeEglDisplay; -} - QWaylandGLIntegration *QWaylandGLIntegration::createGLIntegration(QWaylandDisplay *waylandDisplay) { return new QWaylandEglIntegration(waylandDisplay->wl_display()); diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h index bf4c3fe..3a26f97 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglintegration.h @@ -65,9 +65,6 @@ private: struct wl_display *mWaylandDisplay; EGLDisplay mEglDisplay; - struct wl_egl_display *mNativeEglDisplay; - - }; #endif // QWAYLANDEGLINTEGRATION_H diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp index d7cf0a5..cf52f39 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.cpp @@ -103,7 +103,7 @@ void QWaylandEglWindow::newSurfaceCreated() if (!size.isValid()) size = QSize(0,0); - mWaylandEglWindow = wl_egl_window_create(mEglIntegration->nativeDisplay(),mSurface,size.width(),size.height(),visual); + mWaylandEglWindow = wl_egl_window_create(mSurface,size.width(),size.height(),visual); if (mGLContext) { EGLNativeWindowType window(reinterpret_cast<EGLNativeWindowType>(mWaylandEglWindow)); EGLSurface surface = eglCreateWindowSurface(mEglIntegration->eglDisplay(),mGLContext->eglConfig(),window,NULL); diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h index 549d039..856321d 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandeglwindow.h @@ -63,7 +63,6 @@ private: QWaylandEglIntegration *mEglIntegration; QWaylandGLContext *mGLContext; struct wl_egl_window *mWaylandEglWindow; - EGLConfig mConfig; const QWaylandWindow *mParentWindow; }; diff --git a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri index bc97864..cd07011 100644 --- a/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri +++ b/src/plugins/platforms/wayland/gl_integration/wayland_egl/wayland_egl.pri @@ -1,12 +1,11 @@ +include (../../../eglconvenience/eglconvenience.pri) + LIBS += -lwayland-egl -lEGL INCLUDEPATH += $$PWD SOURCES += $$PWD/qwaylandeglintegration.cpp \ $$PWD/qwaylandglcontext.cpp \ - $$PWD/qwaylandeglwindow.cpp \ - $$PWD/../../../eglconvenience/qeglconvenience.cpp + $$PWD/qwaylandeglwindow.cpp HEADERS += $$PWD/qwaylandeglintegration.h \ $$PWD/qwaylandglcontext.h \ - $$PWD/qwaylandeglwindow.h \ - $$PWD/../../../eglconvenience/qeglconvenience.h \ - gl_integration/wayland_egl/qwaylandeglinclude.h + $$PWD/qwaylandeglwindow.h diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp index 95b4112..7537b52 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglintegration.cpp @@ -111,9 +111,9 @@ const struct wl_xcomposite_listener QWaylandXCompositeEGLIntegration::xcomposite void QWaylandXCompositeEGLIntegration::wlDisplayHandleGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data) { Q_UNUSED(version); - if (strcmp(interface, "xcomposite") == 0) { + if (strcmp(interface, "wl_xcomposite") == 0) { QWaylandXCompositeEGLIntegration *integration = static_cast<QWaylandXCompositeEGLIntegration *>(data); - integration->mWaylandComposite = wl_xcomposite_create(display,id); + integration->mWaylandComposite = wl_xcomposite_create(display,id,1); wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); } diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp index 43c0135..5cb6ef3 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_glx/qwaylandxcompositeglxintegration.cpp @@ -106,9 +106,9 @@ const struct wl_xcomposite_listener QWaylandXCompositeGLXIntegration::xcomposite void QWaylandXCompositeGLXIntegration::wlDisplayHandleGlobal(wl_display *display, uint32_t id, const char *interface, uint32_t version, void *data) { Q_UNUSED(version); - if (strcmp(interface, "xcomposite") == 0) { + if (strcmp(interface, "wl_xcomposite") == 0) { QWaylandXCompositeGLXIntegration *integration = static_cast<QWaylandXCompositeGLXIntegration *>(data); - integration->mWaylandComposite = wl_xcomposite_create(display,id); + integration->mWaylandComposite = wl_xcomposite_create(display,id,1); wl_xcomposite_add_listener(integration->mWaylandComposite,&xcomposite_listener,integration); } diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h index 72376e1..85da7a9 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-client-protocol.h @@ -39,7 +39,6 @@ ** ****************************************************************************/ - #ifndef XCOMPOSITE_CLIENT_PROTOCOL_H #define XCOMPOSITE_CLIENT_PROTOCOL_H @@ -55,84 +54,63 @@ struct wl_client; struct wl_xcomposite; -struct wl_proxy; - -extern void -wl_proxy_marshal(struct wl_proxy *p, uint32_t opcode, ...); -extern struct wl_proxy * -wl_proxy_create(struct wl_proxy *factory, - const struct wl_interface *interface); -extern struct wl_proxy * -wl_proxy_create_for_id(struct wl_display *display, - const struct wl_interface *interface, uint32_t id); -extern void -wl_proxy_destroy(struct wl_proxy *proxy); - -extern int -wl_proxy_add_listener(struct wl_proxy *proxy, - void (**implementation)(void), void *data); - -extern void -wl_proxy_set_user_data(struct wl_proxy *proxy, void *user_data); - -extern void * -wl_proxy_get_user_data(struct wl_proxy *proxy); - extern const struct wl_interface wl_xcomposite_interface; struct wl_xcomposite_listener { void (*root)(void *data, - struct wl_xcomposite *xcomposite, + struct wl_xcomposite *wl_xcomposite, const char *display_name, uint32_t root_window); }; static inline int -wl_xcomposite_add_listener(struct wl_xcomposite *xcomposite, - const struct wl_xcomposite_listener *listener, void *data) +wl_xcomposite_add_listener(struct wl_xcomposite *wl_xcomposite, + const struct wl_xcomposite_listener *listener, void *data) { - return wl_proxy_add_listener((struct wl_proxy *) xcomposite, + return wl_proxy_add_listener((struct wl_proxy *) wl_xcomposite, (void (**)(void)) listener, data); } #define WL_XCOMPOSITE_CREATE_BUFFER 0 static inline struct wl_xcomposite * -wl_xcomposite_create(struct wl_display *display, uint32_t id) +wl_xcomposite_create(struct wl_display *display, uint32_t id, uint32_t version) { + wl_display_bind(display, id, "wl_xcomposite", version); + return (struct wl_xcomposite *) wl_proxy_create_for_id(display, &wl_xcomposite_interface, id); } static inline void -wl_xcomposite_set_user_data(struct wl_xcomposite *xcomposite, void *user_data) +wl_xcomposite_set_user_data(struct wl_xcomposite *wl_xcomposite, void *user_data) { - wl_proxy_set_user_data((struct wl_proxy *) xcomposite, user_data); + wl_proxy_set_user_data((struct wl_proxy *) wl_xcomposite, user_data); } static inline void * -wl_xcomposite_get_user_data(struct wl_xcomposite *xcomposite) +wl_xcomposite_get_user_data(struct wl_xcomposite *wl_xcomposite) { - return wl_proxy_get_user_data((struct wl_proxy *) xcomposite); + return wl_proxy_get_user_data((struct wl_proxy *) wl_xcomposite); } static inline void -wl_xcomposite_destroy(struct wl_xcomposite *xcomposite) +wl_xcomposite_destroy(struct wl_xcomposite *wl_xcomposite) { - wl_proxy_destroy((struct wl_proxy *) xcomposite); + wl_proxy_destroy((struct wl_proxy *) wl_xcomposite); } static inline struct wl_buffer * -wl_xcomposite_create_buffer(struct wl_xcomposite *xcomposite, uint32_t x_window, int width, int height, struct wl_visual *visual) +wl_xcomposite_create_buffer(struct wl_xcomposite *wl_xcomposite, uint32_t x_window, int width, int height, struct wl_visual *visual) { struct wl_proxy *id; - id = wl_proxy_create((struct wl_proxy *) xcomposite, + id = wl_proxy_create((struct wl_proxy *) wl_xcomposite, &wl_buffer_interface); if (!id) return NULL; - wl_proxy_marshal((struct wl_proxy *) xcomposite, + wl_proxy_marshal((struct wl_proxy *) wl_xcomposite, WL_XCOMPOSITE_CREATE_BUFFER, id, x_window, width, height, visual); return (struct wl_buffer *) id; diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c index 5c966fd..a1b6325 100644 --- a/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c +++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_share/wayland-xcomposite-protocol.c @@ -43,17 +43,17 @@ #include <stdint.h> #include "wayland-util.h" -static const struct wl_message xcomposite_requests[] = { +static const struct wl_message wl_xcomposite_requests[] = { { "create_buffer", "nuiio" }, }; -static const struct wl_message xcomposite_events[] = { +static const struct wl_message wl_xcomposite_events[] = { { "root", "su" }, }; WL_EXPORT const struct wl_interface wl_xcomposite_interface = { - "xcomposite", 1, - ARRAY_LENGTH(xcomposite_requests), xcomposite_requests, - ARRAY_LENGTH(xcomposite_events), xcomposite_events, + "wl_xcomposite", 1, + ARRAY_LENGTH(wl_xcomposite_requests), wl_xcomposite_requests, + ARRAY_LENGTH(wl_xcomposite_events), wl_xcomposite_events, }; diff --git a/src/plugins/platforms/wayland/qwaylandbuffer.h b/src/plugins/platforms/wayland/qwaylandbuffer.h index 8779d5f..faeb3e8 100644 --- a/src/plugins/platforms/wayland/qwaylandbuffer.h +++ b/src/plugins/platforms/wayland/qwaylandbuffer.h @@ -44,6 +44,7 @@ #include <QtCore/QSize> +#include <wayland-client.h> #include <wayland-client-protocol.h> class QWaylandBuffer { diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.cpp b/src/plugins/platforms/wayland/qwaylandclipboard.cpp new file mode 100644 index 0000000..9c533aa --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandclipboard.cpp @@ -0,0 +1,242 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins 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 "qwaylandclipboard.h" +#include "qwaylanddisplay.h" +#include "qwaylandinputdevice.h" +#include <QtGui/QPlatformNativeInterface> +#include <QtGui/QApplication> +#include <QtCore/QMimeData> +#include <QtCore/QStringList> +#include <QtCore/QFile> +#include <QtCore/QtDebug> + +static QWaylandClipboard *clipboard; + +class QWaylandSelection +{ +public: + QWaylandSelection(QWaylandDisplay *display, QMimeData *data); + ~QWaylandSelection(); + +private: + static uint32_t getTime(); + static void send(void *data, struct wl_selection *selection, const char *mime_type, int fd); + static void cancelled(void *data, struct wl_selection *selection); + static const struct wl_selection_listener selectionListener; + + QMimeData *mMimeData; + struct wl_selection *mSelection; +}; + +const struct wl_selection_listener QWaylandSelection::selectionListener = { + QWaylandSelection::send, + QWaylandSelection::cancelled +}; + +uint32_t QWaylandSelection::getTime() +{ + struct timeval tv; + gettimeofday(&tv, 0); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} + +QWaylandSelection::QWaylandSelection(QWaylandDisplay *display, QMimeData *data) + : mMimeData(data), mSelection(0) +{ + struct wl_shell *shell = display->wl_shell(); + mSelection = wl_shell_create_selection(shell); + wl_selection_add_listener(mSelection, &selectionListener, this); + foreach (const QString &format, data->formats()) + wl_selection_offer(mSelection, format.toLatin1().constData()); + wl_selection_activate(mSelection, + display->inputDevices().at(0)->wl_input_device(), + getTime()); +} + +QWaylandSelection::~QWaylandSelection() +{ + if (mSelection) { + clipboard->unregisterSelection(this); + wl_selection_destroy(mSelection); + } + delete mMimeData; +} + +void QWaylandSelection::send(void *data, + struct wl_selection *selection, + const char *mime_type, + int fd) +{ + Q_UNUSED(selection); + QWaylandSelection *self = static_cast<QWaylandSelection *>(data); + QString mimeType = QString::fromLatin1(mime_type); + QByteArray content = self->mMimeData->data(mimeType); + if (!content.isEmpty()) { + QFile f; + if (f.open(fd, QIODevice::WriteOnly)) + f.write(content); + } + close(fd); +} + +void QWaylandSelection::cancelled(void *data, struct wl_selection *selection) +{ + Q_UNUSED(selection); + delete static_cast<QWaylandSelection *>(data); +} + +QWaylandClipboard::QWaylandClipboard(QWaylandDisplay *display) + : mDisplay(display), mSelection(0), mMimeDataIn(0), mOffer(0) +{ + clipboard = this; +} + +QWaylandClipboard::~QWaylandClipboard() +{ + if (mOffer) + wl_selection_offer_destroy(mOffer); + delete mMimeDataIn; + qDeleteAll(mSelections); +} + +void QWaylandClipboard::unregisterSelection(QWaylandSelection *selection) +{ + mSelections.removeOne(selection); +} + +void QWaylandClipboard::syncCallback(void *data) +{ + *static_cast<bool *>(data) = true; +} + +void QWaylandClipboard::forceRoundtrip(struct wl_display *display) +{ + bool done = false; + wl_display_sync_callback(display, syncCallback, &done); + wl_display_iterate(display, WL_DISPLAY_WRITABLE); + while (!done) + wl_display_iterate(display, WL_DISPLAY_READABLE); +} + +const QMimeData *QWaylandClipboard::mimeData(QClipboard::Mode mode) const +{ + Q_ASSERT(mode == QClipboard::Clipboard); + if (!mMimeDataIn) + mMimeDataIn = new QMimeData; + mMimeDataIn->clear(); + if (!mOfferedMimeTypes.isEmpty() && mOffer) { + foreach (const QString &mimeType, mOfferedMimeTypes) { + int pipefd[2]; + if (pipe(pipefd) == -1) { + qWarning("QWaylandClipboard::mimedata: pipe() failed"); + break; + } + QByteArray mimeTypeBa = mimeType.toLatin1(); + wl_selection_offer_receive(mOffer, mimeTypeBa.constData(), pipefd[1]); + QByteArray content; + forceRoundtrip(mDisplay->wl_display()); + char buf[256]; + int n; + close(pipefd[1]); + while ((n = read(pipefd[0], &buf, sizeof buf)) > 0) + content.append(buf, n); + close(pipefd[0]); + mMimeDataIn->setData(mimeType, content); + } + } + return mMimeDataIn; +} + +void QWaylandClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode) +{ + Q_ASSERT(mode == QClipboard::Clipboard); + if (!mDisplay->inputDevices().isEmpty()) { + if (!data) + data = new QMimeData; + mSelection = new QWaylandSelection(mDisplay, data); + } else { + qWarning("QWaylandClipboard::setMimeData: No input devices"); + } +} + +bool QWaylandClipboard::supportsMode(QClipboard::Mode mode) const +{ + return mode == QClipboard::Clipboard; +} + +const struct wl_selection_offer_listener QWaylandClipboard::selectionOfferListener = { + QWaylandClipboard::offer, + QWaylandClipboard::keyboardFocus +}; + +void QWaylandClipboard::createSelectionOffer(uint32_t id) +{ + mOfferedMimeTypes.clear(); + if (mOffer) + wl_selection_offer_destroy(mOffer); + mOffer = 0; + struct wl_selection_offer *offer = wl_selection_offer_create(mDisplay->wl_display(), id, 1); + wl_selection_offer_add_listener(offer, &selectionOfferListener, this); +} + +void QWaylandClipboard::offer(void *data, + struct wl_selection_offer *selection_offer, + const char *type) +{ + Q_UNUSED(selection_offer); + QWaylandClipboard *self = static_cast<QWaylandClipboard *>(data); + self->mOfferedMimeTypes.append(QString::fromLatin1(type)); +} + +void QWaylandClipboard::keyboardFocus(void *data, + struct wl_selection_offer *selection_offer, + wl_input_device *input_device) +{ + QWaylandClipboard *self = static_cast<QWaylandClipboard *>(data); + if (!input_device) { + wl_selection_offer_destroy(selection_offer); + self->mOffer = 0; + return; + } + self->mOffer = selection_offer; + self->emitChanged(QClipboard::Clipboard); +} diff --git a/src/plugins/platforms/wayland/qwaylandclipboard.h b/src/plugins/platforms/wayland/qwaylandclipboard.h new file mode 100644 index 0000000..606a1f6 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandclipboard.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins 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 QWAYLANDCLIPBOARD_H +#define QWAYLANDCLIPBOARD_H + +#include <QtGui/QPlatformClipboard> +#include <QtCore/QStringList> + +class QWaylandDisplay; +class QWaylandSelection; +struct wl_selection_offer; + +class QWaylandClipboard : public QPlatformClipboard +{ +public: + QWaylandClipboard(QWaylandDisplay *display); + ~QWaylandClipboard(); + + const QMimeData *mimeData(QClipboard::Mode mode = QClipboard::Clipboard) const; + void setMimeData(QMimeData *data, QClipboard::Mode mode = QClipboard::Clipboard); + bool supportsMode(QClipboard::Mode mode) const; + + void unregisterSelection(QWaylandSelection *selection); + + void createSelectionOffer(uint32_t id); + +private: + static void offer(void *data, + struct wl_selection_offer *selection_offer, + const char *type); + static void keyboardFocus(void *data, + struct wl_selection_offer *selection_offer, + struct wl_input_device *input_device); + static const struct wl_selection_offer_listener selectionOfferListener; + + static void syncCallback(void *data); + static void forceRoundtrip(struct wl_display *display); + + QWaylandDisplay *mDisplay; + QWaylandSelection *mSelection; + mutable QMimeData *mMimeDataIn; + QList<QWaylandSelection *> mSelections; + QStringList mOfferedMimeTypes; + struct wl_selection_offer *mOffer; +}; + +#endif // QWAYLANDCLIPBOARD_H diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index 1c56561..974453d 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -45,6 +45,7 @@ #include "qwaylandscreen.h" #include "qwaylandcursor.h" #include "qwaylandinputdevice.h" +#include "qwaylandclipboard.h" #ifdef QT_WAYLAND_GL_SUPPORT #include "gl_integration/qwaylandglintegration.h" @@ -52,6 +53,7 @@ #include <QtCore/QAbstractEventDispatcher> #include <QtGui/QApplication> +#include <QtGui/private/qapplication_p.h> #include <unistd.h> #include <fcntl.h> @@ -126,6 +128,7 @@ QWaylandDisplay::QWaylandDisplay(void) #ifdef QT_WAYLAND_GL_SUPPORT mEglIntegration = QWaylandGLIntegration::createGLIntegration(this); #endif + blockingReadEvents(); qRegisterMetaType<uint32_t>("uint32_t"); @@ -216,9 +219,6 @@ void QWaylandDisplay::outputHandleGeometry(void *data, int32_t x, int32_t y, int32_t width, int32_t height) { - //call back function called from another thread; - //but its safe to call createScreen from another thread since - //QWaylandScreen does a moveToThread QWaylandDisplay *waylandDisplay = static_cast<QWaylandDisplay *>(data); QRect outputRect = QRect(x, y, width, height); waylandDisplay->createNewScreen(output,outputRect); @@ -251,20 +251,23 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id, uint32_t version) { Q_UNUSED(version); - - if (interface == "output") { - struct wl_output *output = wl_output_create(mDisplay, id); + if (interface == "wl_output") { + struct wl_output *output = wl_output_create(mDisplay, id, 1); wl_output_add_listener(output, &outputListener, this); - } else if (interface == "compositor") { - mCompositor = wl_compositor_create(mDisplay, id); - } else if (interface == "shm") { - mShm = wl_shm_create(mDisplay, id); - } else if (interface == "shell"){ - mShell = wl_shell_create(mDisplay, id); + } else if (interface == "wl_compositor") { + mCompositor = wl_compositor_create(mDisplay, id, 1); + } else if (interface == "wl_shm") { + mShm = wl_shm_create(mDisplay, id, 1); + } else if (interface == "wl_shell"){ + mShell = wl_shell_create(mDisplay, id, 1); wl_shell_add_listener(mShell, &shellListener, this); - } else if (interface == "input_device") { + } else if (interface == "wl_input_device") { QWaylandInputDevice *inputDevice = new QWaylandInputDevice(mDisplay, id); mInputDevices.append(inputDevice); + } else if (interface == "wl_selection_offer") { + QPlatformIntegration *plat = QApplicationPrivate::platformIntegration(); + QWaylandClipboard *clipboard = static_cast<QWaylandClipboard *>(plat->clipboard()); + clipboard->createSelectionOffer(id); } } diff --git a/src/plugins/platforms/wayland/qwaylanddisplay.h b/src/plugins/platforms/wayland/qwaylanddisplay.h index a2cb1b2..0658956 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.h +++ b/src/plugins/platforms/wayland/qwaylanddisplay.h @@ -80,6 +80,7 @@ public: void frameCallback(wl_display_frame_func_t func, struct wl_surface *surface, void *data); struct wl_display *wl_display() const { return mDisplay; } + struct wl_shell *wl_shell() const { return mShell; } QList<QWaylandInputDevice *> inputDevices() const { return mInputDevices; } diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp index 6c2f341..f9e7c95 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.cpp +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.cpp @@ -61,7 +61,7 @@ QWaylandInputDevice::QWaylandInputDevice(struct wl_display *display, uint32_t id) : mDisplay(display) - , mInputDevice(wl_input_device_create(display, id)) + , mInputDevice(wl_input_device_create(display, id, 1)) , mPointerFocus(NULL) , mKeyboardFocus(NULL) , mButtons(0) @@ -101,6 +101,12 @@ void QWaylandInputDevice::inputHandleMotion(void *data, QWaylandInputDevice *inputDevice = (QWaylandInputDevice *) data; QWaylandWindow *window = inputDevice->mPointerFocus; + if (window == NULL) { + /* We destroyed the pointer focus surface, but the server + * didn't get the message yet. */ + return; + } + inputDevice->mSurfacePos = QPoint(surface_x, surface_y); inputDevice->mGlobalPos = QPoint(x, y); inputDevice->mTime = time; @@ -120,6 +126,12 @@ void QWaylandInputDevice::inputHandleButton(void *data, QWaylandWindow *window = inputDevice->mPointerFocus; Qt::MouseButton qt_button; + if (window == NULL) { + /* We destroyed the pointer focus surface, but the server + * didn't get the message yet. */ + return; + } + switch (button) { case 272: qt_button = Qt::LeftButton; @@ -229,6 +241,12 @@ void QWaylandInputDevice::inputHandleKey(void *data, QEvent::Type type; char s[2]; + if (window == NULL) { + /* We destroyed the keyboard focus surface, but the server + * didn't get the message yet. */ + return; + } + code = key + inputDevice->mXkb->min_key_code; level = 0; @@ -250,9 +268,6 @@ void QWaylandInputDevice::inputHandleKey(void *data, sym = translateKey(sym, s, sizeof s); - qWarning("keycode %d, sym %d, string %d, modifiers 0x%x", - code, sym, s[0], (int) inputDevice->mModifiers); - if (window) { QWindowSystemInterface::handleKeyEvent(window->widget(), time, type, sym, diff --git a/src/plugins/platforms/wayland/qwaylandinputdevice.h b/src/plugins/platforms/wayland/qwaylandinputdevice.h index 3c83252..251259b 100644 --- a/src/plugins/platforms/wayland/qwaylandinputdevice.h +++ b/src/plugins/platforms/wayland/qwaylandinputdevice.h @@ -60,6 +60,7 @@ public: QWaylandInputDevice(struct wl_display *display, uint32_t id); void attach(QWaylandBuffer *buffer, int x, int y); void handleWindowDestroyed(QWaylandWindow *window); + struct wl_input_device *wl_input_device() const { return mInputDevice; } private: struct wl_display *mDisplay; diff --git a/src/plugins/platforms/wayland/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index 3f3ee5e..6166c14 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -44,6 +44,8 @@ #include "qwaylanddisplay.h" #include "qwaylandshmsurface.h" #include "qwaylandshmwindow.h" +#include "qwaylandnativeinterface.h" +#include "qwaylandclipboard.h" #include "qgenericunixfontdatabase.h" @@ -62,9 +64,16 @@ QWaylandIntegration::QWaylandIntegration(bool useOpenGL) : mFontDb(new QGenericUnixFontDatabase()) , mDisplay(new QWaylandDisplay()) , mUseOpenGL(useOpenGL) + , mNativeInterface(new QWaylandNativeInterface) + , mClipboard(0) { } +QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const +{ + return mNativeInterface; +} + QList<QPlatformScreen *> QWaylandIntegration::screens() const { @@ -125,3 +134,10 @@ bool QWaylandIntegration::hasOpenGL() const return false; #endif } + +QPlatformClipboard *QWaylandIntegration::clipboard() const +{ + if (!mClipboard) + mClipboard = new QWaylandClipboard(mDisplay); + return mClipboard; +} diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h index fc9b8d6..fc748b0 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.h +++ b/src/plugins/platforms/wayland/qwaylandintegration.h @@ -63,12 +63,18 @@ public: QPlatformFontDatabase *fontDatabase() const; + QPlatformNativeInterface *nativeInterface() const; + + QPlatformClipboard *clipboard() const; + private: bool hasOpenGL() const; QPlatformFontDatabase *mFontDb; QWaylandDisplay *mDisplay; bool mUseOpenGL; + QPlatformNativeInterface *mNativeInterface; + mutable QPlatformClipboard *mClipboard; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp new file mode 100644 index 0000000..c3bfba0 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.cpp @@ -0,0 +1,72 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins 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 "qwaylandnativeinterface.h" + +#include "qwaylanddisplay.h" +#include "qwaylandwindow.h" +#include <QtGui/private/qapplication_p.h> + +void *QWaylandNativeInterface::nativeResourceForWidget(const QByteArray &resourceString, QWidget *widget) +{ + QByteArray lowerCaseResource = resourceString.toLower(); + + if (lowerCaseResource == "display") + return qPlatformScreenForWidget(widget)->display()->wl_display(); + if (lowerCaseResource == "surface") { + return ((QWaylandWindow *) widget->platformWindow())->wl_surface(); + } + + return NULL; +} + + +QWaylandScreen * QWaylandNativeInterface::qPlatformScreenForWidget(QWidget *widget) +{ + QWaylandScreen *screen; + + if (widget) { + screen = static_cast<QWaylandScreen *>(QPlatformScreen::platformScreenForWidget(widget)); + } else { + screen = static_cast<QWaylandScreen *>(QApplicationPrivate::platformIntegration()->screens()[0]); + } + return screen; +} diff --git a/src/plugins/platforms/wayland/qwaylandnativeinterface.h b/src/plugins/platforms/wayland/qwaylandnativeinterface.h new file mode 100644 index 0000000..ac4cdb9 --- /dev/null +++ b/src/plugins/platforms/wayland/qwaylandnativeinterface.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the plugins 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 QWAYLANDNATIVEINTERFACE_H +#define QWAYLANDNATIVEINTERFACE_H + +#include "qwaylandscreen.h" + +#include <QtGui/QPlatformNativeInterface> + +class QWaylandNativeInterface : public QPlatformNativeInterface +{ +public: + void *nativeResourceForWidget(const QByteArray &resourceString, + QWidget *widget); + +private: + static QWaylandScreen *qPlatformScreenForWidget(QWidget *widget); +}; + + +#endif // QWAYLANDNATIVEINTERFACE_H diff --git a/src/plugins/platforms/wayland/qwaylandwindow.cpp b/src/plugins/platforms/wayland/qwaylandwindow.cpp index 6f52291..53f2f48 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.cpp +++ b/src/plugins/platforms/wayland/qwaylandwindow.cpp @@ -146,6 +146,7 @@ void QWaylandWindow::newSurfaceCreated() void QWaylandWindow::frameCallback(struct wl_surface *surface, void *data, uint32_t time) { Q_UNUSED(time); + Q_UNUSED(surface); QWaylandWindow *self = static_cast<QWaylandWindow*>(data); self->mWaitingForFrameSync = false; } diff --git a/src/plugins/platforms/wayland/qwaylandwindow.h b/src/plugins/platforms/wayland/qwaylandwindow.h index 1e60508..47d49a7 100644 --- a/src/plugins/platforms/wayland/qwaylandwindow.h +++ b/src/plugins/platforms/wayland/qwaylandwindow.h @@ -74,6 +74,9 @@ public: void damage(const QRegion ®ion); void waitForFrameSync(); + + struct wl_surface *wl_surface() const { return mSurface; } + protected: struct wl_surface *mSurface; virtual void newSurfaceCreated(); diff --git a/src/plugins/platforms/wayland/wayland.pro b/src/plugins/platforms/wayland/wayland.pro index 5945438..76f8be5 100644 --- a/src/plugins/platforms/wayland/wayland.pro +++ b/src/plugins/platforms/wayland/wayland.pro @@ -8,27 +8,35 @@ DEFINES += $$QMAKE_DEFINES_WAYLAND SOURCES = main.cpp \ qwaylandintegration.cpp \ + qwaylandnativeinterface.cpp \ qwaylandshmsurface.cpp \ qwaylandinputdevice.cpp \ qwaylandcursor.cpp \ qwaylanddisplay.cpp \ qwaylandwindow.cpp \ qwaylandscreen.cpp \ - qwaylandshmwindow.cpp + qwaylandshmwindow.cpp \ + qwaylandclipboard.cpp HEADERS = qwaylandintegration.h \ + qwaylandnativeinterface.h \ qwaylandcursor.h \ qwaylanddisplay.h \ qwaylandwindow.h \ qwaylandscreen.h \ qwaylandshmsurface.h \ qwaylandbuffer.h \ - qwaylandshmwindow.h + qwaylandshmwindow.h \ + qwaylandclipboard.h INCLUDEPATH += $$QMAKE_INCDIR_WAYLAND LIBS += $$QMAKE_LIBS_WAYLAND QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_WAYLAND +!isEmpty(QMAKE_LFLAGS_RPATH) { + !isEmpty(QMAKE_LIBDIR_WAYLAND):QMAKE_LFLAGS += $${QMAKE_LFLAGS_RPATH}$${QMAKE_LIBDIR_WAYLAND} +} + INCLUDEPATH += $$PWD include ($$PWD/gl_integration/gl_integration.pri) diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index 190221c..1417157 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -110,7 +110,6 @@ void QGLXContext::swapBuffers() { Q_XCB_NOOP(m_screen->connection()); glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), m_drawable); - doneCurrent(); Q_XCB_NOOP(m_screen->connection()); } diff --git a/src/plugins/platforms/xlib/qglxintegration.cpp b/src/plugins/platforms/xlib/qglxintegration.cpp index 7a0f36d..a43851c 100644 --- a/src/plugins/platforms/xlib/qglxintegration.cpp +++ b/src/plugins/platforms/xlib/qglxintegration.cpp @@ -46,15 +46,13 @@ #include "qxlibwindow.h" #include "qxlibscreen.h" #include "qxlibdisplay.h" +#include "qxlibstatic.h" #if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2) -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <GL/glx.h> -#include "qglxconvenience.h" - #include "qglxintegration.h" +#include "qglxconvenience.h" + #if defined(Q_OS_LINUX) || defined(Q_OS_BSD4) #include <dlfcn.h> #endif diff --git a/src/plugins/platforms/xlib/qglxintegration.h b/src/plugins/platforms/xlib/qglxintegration.h index 57c716b..d0527c3 100644 --- a/src/plugins/platforms/xlib/qglxintegration.h +++ b/src/plugins/platforms/xlib/qglxintegration.h @@ -47,10 +47,10 @@ #include <QtGui/QPlatformGLContext> #include <QtGui/QPlatformWindowFormat> -#include <QtCore/QMutex> - #if !defined(QT_NO_OPENGL) && !defined(QT_OPENGL_ES_2) +#define Status int #include <GL/glx.h> +#undef Status QT_BEGIN_NAMESPACE diff --git a/src/plugins/platforms/xlib/qxlibscreen.cpp b/src/plugins/platforms/xlib/qxlibscreen.cpp index 7c8a367..c4c8126 100644 --- a/src/plugins/platforms/xlib/qxlibscreen.cpp +++ b/src/plugins/platforms/xlib/qxlibscreen.cpp @@ -54,8 +54,6 @@ #include <private/qapplication_p.h> -#include <X11/extensions/Xfixes.h> - QT_BEGIN_NAMESPACE static int (*original_x_errhandler)(Display *dpy, XErrorEvent *); @@ -201,7 +199,7 @@ QXlibScreen::QXlibScreen() #ifndef DONT_USE_MIT_SHM - Status MIT_SHM_extension_supported = XShmQueryExtension (mDisplay->nativeDisplay()); + int MIT_SHM_extension_supported = XShmQueryExtension (mDisplay->nativeDisplay()); Q_ASSERT(MIT_SHM_extension_supported == True); #endif original_x_errhandler = XSetErrorHandler(qt_x_errhandler); diff --git a/src/plugins/platforms/xlib/qxlibstatic.cpp b/src/plugins/platforms/xlib/qxlibstatic.cpp index 6117781..7b562ea 100644 --- a/src/plugins/platforms/xlib/qxlibstatic.cpp +++ b/src/plugins/platforms/xlib/qxlibstatic.cpp @@ -51,10 +51,6 @@ #include <QDebug> -#ifndef QT_NO_XFIXES -#include <X11/extensions/Xfixes.h> -#endif // QT_NO_XFIXES - static const char * x11_atomnames = { // window-manager <-> client protocols "WM_PROTOCOLS\0" diff --git a/src/plugins/platforms/xlib/qxlibstatic.h b/src/plugins/platforms/xlib/qxlibstatic.h index 72cfaec..ebc8085 100644 --- a/src/plugins/platforms/xlib/qxlibstatic.h +++ b/src/plugins/platforms/xlib/qxlibstatic.h @@ -118,6 +118,10 @@ extern "C" { } #endif +#ifndef QT_NO_XFIXES +#include <X11/extensions/Xfixes.h> +#endif // QT_NO_XFIXES + // #define QT_NO_XKB #ifndef QT_NO_XKB # include <X11/XKBlib.h> diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 7479d2f..2d0c201 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -7,9 +7,9 @@ unix:!symbian { SUBDIRS *= codecs } !contains(QT_CONFIG, no-gui): SUBDIRS *= imageformats iconengines -!embedded:!qpa:SUBDIRS *= graphicssystems +!embedded:!qpa:!contains(QT_CONFIG, no-gui):SUBDIRS *= graphicssystems embedded:SUBDIRS *= gfxdrivers decorations mousedrivers kbddrivers -!win32:!embedded:!mac:!symbian:SUBDIRS *= inputmethods +!win32:!embedded:!mac:!symbian:!contains(QT_CONFIG, no-gui):SUBDIRS *= inputmethods !symbian:!contains(QT_CONFIG, no-gui):SUBDIRS += accessible symbian:SUBDIRS += s60 contains(QT_CONFIG, phonon): SUBDIRS *= phonon diff --git a/src/plugins/qmltooling/declarativeobserver/declarativeobserver.pro b/src/plugins/qmltooling/declarativeobserver/declarativeobserver.pro new file mode 100644 index 0000000..bccabcb --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/declarativeobserver.pro @@ -0,0 +1,53 @@ +TARGET = declarativeobserver +QT += declarative + +include(../../qpluginbase.pri) + +QTDIR_build:DESTDIR = $$QT_BUILD_TREE/plugins/qmltooling +QTDIR_build:REQUIRES += "contains(QT_CONFIG, declarative)" + +SOURCES += \ + qdeclarativeobserverplugin.cpp \ + qdeclarativeviewobserver.cpp \ + editor/abstractliveedittool.cpp \ + editor/liveselectiontool.cpp \ + editor/livelayeritem.cpp \ + editor/livesingleselectionmanipulator.cpp \ + editor/liverubberbandselectionmanipulator.cpp \ + editor/liveselectionrectangle.cpp \ + editor/liveselectionindicator.cpp \ + editor/boundingrecthighlighter.cpp \ + editor/subcomponenteditortool.cpp \ + editor/subcomponentmasklayeritem.cpp \ + editor/zoomtool.cpp \ + editor/colorpickertool.cpp \ + editor/qmltoolbar.cpp \ + editor/toolbarcolorbox.cpp + +HEADERS += \ + qdeclarativeobserverplugin.h \ + qdeclarativeobserverprotocol.h \ + qdeclarativeviewobserver_p.h \ + qdeclarativeviewobserver_p_p.h \ + qmlobserverconstants_p.h \ + editor/abstractliveedittool_p.h \ + editor/liveselectiontool_p.h \ + editor/livelayeritem_p.h \ + editor/livesingleselectionmanipulator_p.h \ + editor/liverubberbandselectionmanipulator_p.h \ + editor/liveselectionrectangle_p.h \ + editor/liveselectionindicator_p.h \ + editor/boundingrecthighlighter_p.h \ + editor/subcomponenteditortool_p.h \ + editor/subcomponentmasklayeritem_p.h \ + editor/zoomtool_p.h \ + editor/colorpickertool_p.h \ + editor/qmltoolbar_p.h \ + editor/toolbarcolorbox_p.h + +RESOURCES += editor/editor.qrc + +target.path += $$[QT_INSTALL_PLUGINS]/qmltooling +INSTALLS += target + +symbian:TARGET.UID3=0x20031E90 diff --git a/src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool.cpp b/src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool.cpp new file mode 100644 index 0000000..b3ed22e --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool.cpp @@ -0,0 +1,200 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "abstractliveedittool_p.h" +#include "../qdeclarativeviewobserver_p_p.h" + +#include <QDeclarativeEngine> + +#include <QtDebug> +#include <QGraphicsItem> +#include <QDeclarativeItem> + +QT_BEGIN_NAMESPACE + +AbstractLiveEditTool::AbstractLiveEditTool(QDeclarativeViewObserver *editorView) + : QObject(editorView), m_observer(editorView) +{ +} + + +AbstractLiveEditTool::~AbstractLiveEditTool() +{ +} + +QDeclarativeViewObserver *AbstractLiveEditTool::observer() const +{ + return m_observer; +} + +QDeclarativeView *AbstractLiveEditTool::view() const +{ + return m_observer->declarativeView(); +} + +QGraphicsScene* AbstractLiveEditTool::scene() const +{ + return view()->scene(); +} + +void AbstractLiveEditTool::updateSelectedItems() +{ + selectedItemsChanged(items()); +} + +QList<QGraphicsItem*> AbstractLiveEditTool::items() const +{ + return observer()->selectedItems(); +} + +void AbstractLiveEditTool::enterContext(QGraphicsItem *itemToEnter) +{ + observer()->data->enterContext(itemToEnter); +} + +bool AbstractLiveEditTool::topItemIsMovable(const QList<QGraphicsItem*> & itemList) +{ + QGraphicsItem *firstSelectableItem = topMovableGraphicsItem(itemList); + if (firstSelectableItem == 0) + return false; + if (toQDeclarativeItem(firstSelectableItem) != 0) + return true; + + return false; + +} + +bool AbstractLiveEditTool::topSelectedItemIsMovable(const QList<QGraphicsItem*> &itemList) +{ + QList<QGraphicsItem*> selectedItems = observer()->selectedItems(); + + foreach (QGraphicsItem *item, itemList) { + QDeclarativeItem *declarativeItem = toQDeclarativeItem(item); + if (declarativeItem + && selectedItems.contains(declarativeItem) + /*&& (declarativeItem->qmlItemNode().hasShowContent() || selectNonContentItems)*/) + return true; + } + + return false; + +} + +bool AbstractLiveEditTool::topItemIsResizeHandle(const QList<QGraphicsItem*> &/*itemList*/) +{ + return false; +} + +QDeclarativeItem *AbstractLiveEditTool::toQDeclarativeItem(QGraphicsItem *item) +{ + return qobject_cast<QDeclarativeItem*>(item->toGraphicsObject()); +} + +QGraphicsItem *AbstractLiveEditTool::topMovableGraphicsItem(const QList<QGraphicsItem*> &itemList) +{ + foreach (QGraphicsItem *item, itemList) { + if (item->flags().testFlag(QGraphicsItem::ItemIsMovable)) + return item; + } + return 0; +} + +QDeclarativeItem *AbstractLiveEditTool::topMovableDeclarativeItem(const QList<QGraphicsItem*> + &itemList) +{ + foreach (QGraphicsItem *item, itemList) { + QDeclarativeItem *declarativeItem = toQDeclarativeItem(item); + if (declarativeItem /*&& (declarativeItem->qmlItemNode().hasShowContent())*/) + return declarativeItem; + } + + return 0; +} + +QList<QGraphicsObject*> AbstractLiveEditTool::toGraphicsObjectList(const QList<QGraphicsItem*> + &itemList) +{ + QList<QGraphicsObject*> gfxObjects; + foreach (QGraphicsItem *item, itemList) { + QGraphicsObject *obj = item->toGraphicsObject(); + if (obj) + gfxObjects << obj; + } + + return gfxObjects; +} + +QString AbstractLiveEditTool::titleForItem(QGraphicsItem *item) +{ + QString className(QLatin1String("QGraphicsItem")); + QString objectStringId; + + QString constructedName; + + QGraphicsObject *gfxObject = item->toGraphicsObject(); + if (gfxObject) { + className = QLatin1String(gfxObject->metaObject()->className()); + + className.remove(QRegExp(QLatin1String("_QMLTYPE_\\d+"))); + className.remove(QRegExp(QLatin1String("_QML_\\d+"))); + if (className.startsWith(QLatin1String("QDeclarative"))) + className = className.remove(QLatin1String("QDeclarative")); + + QDeclarativeItem *declarativeItem = qobject_cast<QDeclarativeItem*>(gfxObject); + if (declarativeItem) { + objectStringId = m_observer->idStringForObject(declarativeItem); + } + + if (!objectStringId.isEmpty()) { + constructedName = objectStringId + QLatin1String(" (") + className + QLatin1Char(')'); + } else { + if (!gfxObject->objectName().isEmpty()) { + constructedName = gfxObject->objectName() + QLatin1String(" (") + className + QLatin1Char(')'); + } else { + constructedName = className; + } + } + } + + return constructedName; +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool_p.h b/src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool_p.h new file mode 100644 index 0000000..1dbc323 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/abstractliveedittool_p.h @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 ABSTRACTLIVEEDITTOOL_H +#define ABSTRACTLIVEEDITTOOL_H + +#include <QtCore/QList> +#include <QtCore/QObject> + +QT_BEGIN_NAMESPACE +class QMouseEvent; +class QGraphicsItem; +class QDeclarativeItem; +class QKeyEvent; +class QGraphicsScene; +class QGraphicsObject; +class QWheelEvent; +class QDeclarativeView; +QT_END_NAMESPACE + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeViewObserver; + +class AbstractLiveEditTool : public QObject +{ + Q_OBJECT +public: + AbstractLiveEditTool(QDeclarativeViewObserver *observer); + + virtual ~AbstractLiveEditTool(); + + virtual void mousePressEvent(QMouseEvent *event) = 0; + virtual void mouseMoveEvent(QMouseEvent *event) = 0; + virtual void mouseReleaseEvent(QMouseEvent *event) = 0; + virtual void mouseDoubleClickEvent(QMouseEvent *event) = 0; + + virtual void hoverMoveEvent(QMouseEvent *event) = 0; + virtual void wheelEvent(QWheelEvent *event) = 0; + + virtual void keyPressEvent(QKeyEvent *event) = 0; + virtual void keyReleaseEvent(QKeyEvent *keyEvent) = 0; + virtual void itemsAboutToRemoved(const QList<QGraphicsItem*> &itemList) = 0; + + virtual void clear() = 0; + + void updateSelectedItems(); + QList<QGraphicsItem*> items() const; + + void enterContext(QGraphicsItem *itemToEnter); + + bool topItemIsMovable(const QList<QGraphicsItem*> &itemList); + bool topItemIsResizeHandle(const QList<QGraphicsItem*> &itemList); + bool topSelectedItemIsMovable(const QList<QGraphicsItem*> &itemList); + + QString titleForItem(QGraphicsItem *item); + + static QList<QGraphicsObject*> toGraphicsObjectList(const QList<QGraphicsItem*> &itemList); + static QGraphicsItem* topMovableGraphicsItem(const QList<QGraphicsItem*> &itemList); + static QDeclarativeItem* topMovableDeclarativeItem(const QList<QGraphicsItem*> &itemList); + static QDeclarativeItem *toQDeclarativeItem(QGraphicsItem *item); + +protected: + virtual void selectedItemsChanged(const QList<QGraphicsItem*> &objectList) = 0; + + QDeclarativeViewObserver *observer() const; + QDeclarativeView *view() const; + QGraphicsScene *scene() const; + +private: + QDeclarativeViewObserver *m_observer; + QList<QGraphicsItem*> m_itemList; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // ABSTRACTLIVEEDITTOOL_H diff --git a/src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter.cpp b/src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter.cpp new file mode 100644 index 0000000..98dbc4f --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter.cpp @@ -0,0 +1,284 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "boundingrecthighlighter_p.h" + +#include "../qdeclarativeviewobserver_p.h" +#include "../qmlobserverconstants_p.h" + +#include <QtGui/QGraphicsPolygonItem> + +#include <QtCore/QTimer> +#include <QtCore/QObject> +#include <QtCore/QDebug> + +QT_BEGIN_NAMESPACE + +const qreal AnimDelta = 0.025f; +const int AnimInterval = 30; +const int AnimFrames = 10; + +BoundingBox::BoundingBox(QGraphicsObject *itemToHighlight, QGraphicsItem *parentItem, + QObject *parent) + : QObject(parent), + highlightedObject(itemToHighlight), + highlightPolygon(0), + highlightPolygonEdge(0) +{ + highlightPolygon = new BoundingBoxPolygonItem(parentItem); + highlightPolygonEdge = new BoundingBoxPolygonItem(parentItem); + + highlightPolygon->setPen(QPen(QColor(0, 22, 159))); + highlightPolygonEdge->setPen(QPen(QColor(158, 199, 255))); + + highlightPolygon->setFlag(QGraphicsItem::ItemIsSelectable, false); + highlightPolygonEdge->setFlag(QGraphicsItem::ItemIsSelectable, false); +} + +BoundingBox::~BoundingBox() +{ + highlightedObject.clear(); +} + +BoundingBoxPolygonItem::BoundingBoxPolygonItem(QGraphicsItem *item) : QGraphicsPolygonItem(item) +{ + QPen pen; + pen.setColor(QColor(108, 141, 221)); + pen.setWidth(1); + setPen(pen); +} + +int BoundingBoxPolygonItem::type() const +{ + return Constants::EditorItemType; +} + +BoundingRectHighlighter::BoundingRectHighlighter(QDeclarativeViewObserver *view) : + LiveLayerItem(view->declarativeView()->scene()), + m_view(view), + m_animFrame(0) +{ + m_animTimer = new QTimer(this); + m_animTimer->setInterval(AnimInterval); + connect(m_animTimer, SIGNAL(timeout()), SLOT(animTimeout())); +} + +BoundingRectHighlighter::~BoundingRectHighlighter() +{ + +} + +void BoundingRectHighlighter::animTimeout() +{ + ++m_animFrame; + if (m_animFrame == AnimFrames) { + m_animTimer->stop(); + } + + qreal alpha = m_animFrame / float(AnimFrames); + + foreach (BoundingBox *box, m_boxes) { + box->highlightPolygonEdge->setOpacity(alpha); + } +} + +void BoundingRectHighlighter::clear() +{ + if (m_boxes.length()) { + m_animTimer->stop(); + + foreach (BoundingBox *box, m_boxes) { + freeBoundingBox(box); + } + } +} + +BoundingBox *BoundingRectHighlighter::boxFor(QGraphicsObject *item) const +{ + foreach (BoundingBox *box, m_boxes) { + if (box->highlightedObject.data() == item) { + return box; + } + } + return 0; +} + +void BoundingRectHighlighter::highlight(QList<QGraphicsObject*> items) +{ + if (items.isEmpty()) + return; + + bool animate = false; + + QList<BoundingBox *> newBoxes; + foreach (QGraphicsObject *itemToHighlight, items) { + BoundingBox *box = boxFor(itemToHighlight); + if (!box) { + box = createBoundingBox(itemToHighlight); + animate = true; + } + + newBoxes << box; + } + qSort(newBoxes); + + if (newBoxes != m_boxes) { + clear(); + m_boxes << newBoxes; + } + + highlightAll(animate); +} + +void BoundingRectHighlighter::highlight(QGraphicsObject* itemToHighlight) +{ + if (!itemToHighlight) + return; + + bool animate = false; + + BoundingBox *box = boxFor(itemToHighlight); + if (!box) { + box = createBoundingBox(itemToHighlight); + m_boxes << box; + animate = true; + qSort(m_boxes); + } + + highlightAll(animate); +} + +BoundingBox *BoundingRectHighlighter::createBoundingBox(QGraphicsObject *itemToHighlight) +{ + if (!m_freeBoxes.isEmpty()) { + BoundingBox *box = m_freeBoxes.last(); + if (box->highlightedObject.isNull()) { + box->highlightedObject = itemToHighlight; + box->highlightPolygon->show(); + box->highlightPolygonEdge->show(); + m_freeBoxes.removeLast(); + return box; + } + } + + BoundingBox *box = new BoundingBox(itemToHighlight, this, this); + + connect(itemToHighlight, SIGNAL(xChanged()), this, SLOT(refresh())); + connect(itemToHighlight, SIGNAL(yChanged()), this, SLOT(refresh())); + connect(itemToHighlight, SIGNAL(widthChanged()), this, SLOT(refresh())); + connect(itemToHighlight, SIGNAL(heightChanged()), this, SLOT(refresh())); + connect(itemToHighlight, SIGNAL(rotationChanged()), this, SLOT(refresh())); + connect(itemToHighlight, SIGNAL(destroyed(QObject*)), this, SLOT(itemDestroyed(QObject*))); + + return box; +} + +void BoundingRectHighlighter::removeBoundingBox(BoundingBox *box) +{ + delete box; + box = 0; +} + +void BoundingRectHighlighter::freeBoundingBox(BoundingBox *box) +{ + if (!box->highlightedObject.isNull()) { + disconnect(box->highlightedObject.data(), SIGNAL(xChanged()), this, SLOT(refresh())); + disconnect(box->highlightedObject.data(), SIGNAL(yChanged()), this, SLOT(refresh())); + disconnect(box->highlightedObject.data(), SIGNAL(widthChanged()), this, SLOT(refresh())); + disconnect(box->highlightedObject.data(), SIGNAL(heightChanged()), this, SLOT(refresh())); + disconnect(box->highlightedObject.data(), SIGNAL(rotationChanged()), this, SLOT(refresh())); + } + + box->highlightedObject.clear(); + box->highlightPolygon->hide(); + box->highlightPolygonEdge->hide(); + m_boxes.removeOne(box); + m_freeBoxes << box; +} + +void BoundingRectHighlighter::itemDestroyed(QObject *obj) +{ + foreach (BoundingBox *box, m_boxes) { + if (box->highlightedObject.data() == obj) { + freeBoundingBox(box); + break; + } + } +} + +void BoundingRectHighlighter::highlightAll(bool animate) +{ + foreach (BoundingBox *box, m_boxes) { + if (box && box->highlightedObject.isNull()) { + // clear all highlights + clear(); + return; + } + QGraphicsObject *item = box->highlightedObject.data(); + QRectF itemAndChildRect = item->boundingRect() | item->childrenBoundingRect(); + + QPolygonF boundingRectInSceneSpace(item->mapToScene(itemAndChildRect)); + QPolygonF boundingRectInLayerItemSpace = mapFromScene(boundingRectInSceneSpace); + QRectF bboxRect + = m_view->adjustToScreenBoundaries(boundingRectInLayerItemSpace.boundingRect()); + QRectF edgeRect = bboxRect; + edgeRect.adjust(-1, -1, 1, 1); + + box->highlightPolygon->setPolygon(QPolygonF(bboxRect)); + box->highlightPolygonEdge->setPolygon(QPolygonF(edgeRect)); + + if (animate) + box->highlightPolygonEdge->setOpacity(0); + } + + if (animate) { + m_animFrame = 0; + m_animTimer->start(); + } +} + +void BoundingRectHighlighter::refresh() +{ + if (!m_boxes.isEmpty()) + highlightAll(true); +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter_p.h b/src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter_p.h new file mode 100644 index 0000000..c1beed8 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/boundingrecthighlighter_p.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 BOUNDINGRECTHIGHLIGHTER_H +#define BOUNDINGRECTHIGHLIGHTER_H + +#include "livelayeritem_p.h" + +#include <QtCore/QObject> +#include <QtCore/QWeakPointer> + +QT_FORWARD_DECLARE_CLASS(QGraphicsItem) +QT_FORWARD_DECLARE_CLASS(QPainter) +QT_FORWARD_DECLARE_CLASS(QWidget) +QT_FORWARD_DECLARE_CLASS(QStyleOptionGraphicsItem) +QT_FORWARD_DECLARE_CLASS(QTimer) + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeViewObserver; +class BoundingBox; + +class BoundingRectHighlighter : public LiveLayerItem +{ + Q_OBJECT +public: + explicit BoundingRectHighlighter(QDeclarativeViewObserver *view); + ~BoundingRectHighlighter(); + void clear(); + void highlight(QList<QGraphicsObject*> items); + void highlight(QGraphicsObject* item); + +private slots: + void refresh(); + void animTimeout(); + void itemDestroyed(QObject *); + +private: + BoundingBox *boxFor(QGraphicsObject *item) const; + void highlightAll(bool animate); + BoundingBox *createBoundingBox(QGraphicsObject *itemToHighlight); + void removeBoundingBox(BoundingBox *box); + void freeBoundingBox(BoundingBox *box); + +private: + Q_DISABLE_COPY(BoundingRectHighlighter) + + QDeclarativeViewObserver *m_view; + QList<BoundingBox* > m_boxes; + QList<BoundingBox* > m_freeBoxes; + QTimer *m_animTimer; + qreal m_animScale; + int m_animFrame; + +}; + +class BoundingBox : public QObject +{ + Q_OBJECT +public: + explicit BoundingBox(QGraphicsObject *itemToHighlight, QGraphicsItem *parentItem, + QObject *parent = 0); + ~BoundingBox(); + QWeakPointer<QGraphicsObject> highlightedObject; + QGraphicsPolygonItem *highlightPolygon; + QGraphicsPolygonItem *highlightPolygonEdge; + +private: + Q_DISABLE_COPY(BoundingBox) + +}; + +class BoundingBoxPolygonItem : public QGraphicsPolygonItem +{ +public: + explicit BoundingBoxPolygonItem(QGraphicsItem *item); + int type() const; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // BOUNDINGRECTHIGHLIGHTER_H diff --git a/src/plugins/qmltooling/declarativeobserver/editor/colorpickertool.cpp b/src/plugins/qmltooling/declarativeobserver/editor/colorpickertool.cpp new file mode 100644 index 0000000..a71e408 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/colorpickertool.cpp @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "colorpickertool_p.h" + +#include "../qdeclarativeviewobserver_p.h" + +#include <QtGui/QMouseEvent> +#include <QtGui/QKeyEvent> +#include <QtCore/QRectF> +#include <QtGui/QRgb> +#include <QtGui/QImage> +#include <QtGui/QApplication> +#include <QtGui/QPalette> + +QT_BEGIN_NAMESPACE + +ColorPickerTool::ColorPickerTool(QDeclarativeViewObserver *view) : + AbstractLiveEditTool(view) +{ + m_selectedColor.setRgb(0,0,0); +} + +ColorPickerTool::~ColorPickerTool() +{ + +} + +void ColorPickerTool::mousePressEvent(QMouseEvent * /*event*/) +{ +} + +void ColorPickerTool::mouseMoveEvent(QMouseEvent *event) +{ + pickColor(event->pos()); +} + +void ColorPickerTool::mouseReleaseEvent(QMouseEvent *event) +{ + pickColor(event->pos()); +} + +void ColorPickerTool::mouseDoubleClickEvent(QMouseEvent * /*event*/) +{ +} + + +void ColorPickerTool::hoverMoveEvent(QMouseEvent * /*event*/) +{ +} + +void ColorPickerTool::keyPressEvent(QKeyEvent * /*event*/) +{ +} + +void ColorPickerTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/) +{ +} +void ColorPickerTool::wheelEvent(QWheelEvent * /*event*/) +{ +} + +void ColorPickerTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/) +{ +} + +void ColorPickerTool::clear() +{ + view()->setCursor(Qt::CrossCursor); +} + +void ColorPickerTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*itemList*/) +{ +} + +void ColorPickerTool::pickColor(const QPoint &pos) +{ + QRgb fillColor = view()->backgroundBrush().color().rgb(); + if (view()->backgroundBrush().style() == Qt::NoBrush) + fillColor = view()->palette().color(QPalette::Base).rgb(); + + QRectF target(0,0, 1, 1); + QRect source(pos.x(), pos.y(), 1, 1); + QImage img(1, 1, QImage::Format_ARGB32); + img.fill(fillColor); + QPainter painter(&img); + view()->render(&painter, target, source); + m_selectedColor = QColor::fromRgb(img.pixel(0, 0)); + + emit selectedColorChanged(m_selectedColor); +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/declarativeobserver/editor/colorpickertool_p.h b/src/plugins/qmltooling/declarativeobserver/editor/colorpickertool_p.h new file mode 100644 index 0000000..86a8893 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/colorpickertool_p.h @@ -0,0 +1,99 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 COLORPICKERTOOL_H +#define COLORPICKERTOOL_H + +#include "abstractliveedittool_p.h" + +#include <QtGui/QColor> + +QT_FORWARD_DECLARE_CLASS(QPoint) + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class ColorPickerTool : public AbstractLiveEditTool +{ + Q_OBJECT +public: + explicit ColorPickerTool(QDeclarativeViewObserver *view); + + virtual ~ColorPickerTool(); + + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + + void hoverMoveEvent(QMouseEvent *event); + + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *keyEvent); + + void wheelEvent(QWheelEvent *event); + + void itemsAboutToRemoved(const QList<QGraphicsItem*> &itemList); + + void clear(); + +signals: + void selectedColorChanged(const QColor &color); + +protected: + + void selectedItemsChanged(const QList<QGraphicsItem*> &itemList); + +private: + void pickColor(const QPoint &pos); + +private: + QColor m_selectedColor; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // COLORPICKERTOOL_H diff --git a/src/plugins/qmltooling/declarativeobserver/editor/editor.qrc b/src/plugins/qmltooling/declarativeobserver/editor/editor.qrc new file mode 100644 index 0000000..77744d5 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/editor.qrc @@ -0,0 +1,24 @@ +<RCC> + <qresource prefix="/qml"> + <file>images/resize_handle.png</file> + <file>images/select.png</file> + <file>images/select-marquee.png</file> + <file>images/color-picker.png</file> + <file>images/play.png</file> + <file>images/pause.png</file> + <file>images/from-qml.png</file> + <file>images/to-qml.png</file> + <file>images/color-picker-hicontrast.png</file> + <file>images/zoom.png</file> + <file>images/color-picker-24.png</file> + <file>images/from-qml-24.png</file> + <file>images/pause-24.png</file> + <file>images/play-24.png</file> + <file>images/to-qml-24.png</file> + <file>images/zoom-24.png</file> + <file>images/select-24.png</file> + <file>images/select-marquee-24.png</file> + <file>images/observermode.png</file> + <file>images/observermode-24.png</file> + </qresource> +</RCC> diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-24.png Binary files differnew file mode 100644 index 0000000..cff4721 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-24.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-hicontrast.png b/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-hicontrast.png Binary files differnew file mode 100644 index 0000000..b953d08 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker-hicontrast.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker.png b/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker.png Binary files differnew file mode 100644 index 0000000..026c31b --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/color-picker.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/from-qml-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/from-qml-24.png Binary files differnew file mode 100644 index 0000000..0ad21f3 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/from-qml-24.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/from-qml.png b/src/plugins/qmltooling/declarativeobserver/editor/images/from-qml.png Binary files differnew file mode 100644 index 0000000..666382c --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/from-qml.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/observermode-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/observermode-24.png Binary files differnew file mode 100644 index 0000000..5e74d86 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/observermode-24.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/observermode.png b/src/plugins/qmltooling/declarativeobserver/editor/images/observermode.png Binary files differnew file mode 100644 index 0000000..daed21c --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/observermode.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/pause-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/pause-24.png Binary files differnew file mode 100644 index 0000000..d9a2f6f --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/pause-24.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/pause.png b/src/plugins/qmltooling/declarativeobserver/editor/images/pause.png Binary files differnew file mode 100644 index 0000000..114d89b --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/pause.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/play-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/play-24.png Binary files differnew file mode 100644 index 0000000..e2b9fbc --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/play-24.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/play.png b/src/plugins/qmltooling/declarativeobserver/editor/images/play.png Binary files differnew file mode 100644 index 0000000..011598a --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/play.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/reload.png b/src/plugins/qmltooling/declarativeobserver/editor/images/reload.png Binary files differnew file mode 100644 index 0000000..7042bec --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/reload.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/resize_handle.png b/src/plugins/qmltooling/declarativeobserver/editor/images/resize_handle.png Binary files differnew file mode 100644 index 0000000..2934f25 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/resize_handle.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/select-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/select-24.png Binary files differnew file mode 100644 index 0000000..5388a9d --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/select-24.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee-24.png Binary files differnew file mode 100644 index 0000000..0111dda --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee-24.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee.png b/src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee.png Binary files differnew file mode 100644 index 0000000..92fe40d --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/select-marquee.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/select.png b/src/plugins/qmltooling/declarativeobserver/editor/images/select.png Binary files differnew file mode 100644 index 0000000..6722855 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/select.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/to-qml-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/to-qml-24.png Binary files differnew file mode 100644 index 0000000..b72450d --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/to-qml-24.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/to-qml.png b/src/plugins/qmltooling/declarativeobserver/editor/images/to-qml.png Binary files differnew file mode 100644 index 0000000..2ab951f --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/to-qml.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/zoom-24.png b/src/plugins/qmltooling/declarativeobserver/editor/images/zoom-24.png Binary files differnew file mode 100644 index 0000000..0346200 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/zoom-24.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/images/zoom.png b/src/plugins/qmltooling/declarativeobserver/editor/images/zoom.png Binary files differnew file mode 100644 index 0000000..17f0da6 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/images/zoom.png diff --git a/src/plugins/qmltooling/declarativeobserver/editor/livelayeritem.cpp b/src/plugins/qmltooling/declarativeobserver/editor/livelayeritem.cpp new file mode 100644 index 0000000..7b508a4 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/livelayeritem.cpp @@ -0,0 +1,92 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "livelayeritem_p.h" + +#include "../qmlobserverconstants_p.h" + +#include <QGraphicsScene> + +QT_BEGIN_NAMESPACE + +LiveLayerItem::LiveLayerItem(QGraphicsScene* scene) + : QGraphicsObject() +{ + scene->addItem(this); + setZValue(1); + setFlag(QGraphicsItem::ItemIsMovable, false); +} + +LiveLayerItem::~LiveLayerItem() +{ +} + +void LiveLayerItem::paint(QPainter * /*painter*/, const QStyleOptionGraphicsItem * /*option*/, + QWidget * /*widget*/) +{ +} + +int LiveLayerItem::type() const +{ + return Constants::EditorItemType; +} + +QRectF LiveLayerItem::boundingRect() const +{ + return childrenBoundingRect(); +} + +QList<QGraphicsItem*> LiveLayerItem::findAllChildItems() const +{ + return findAllChildItems(this); +} + +QList<QGraphicsItem*> LiveLayerItem::findAllChildItems(const QGraphicsItem *item) const +{ + QList<QGraphicsItem*> itemList(item->childItems()); + + foreach (QGraphicsItem *childItem, item->childItems()) + itemList += findAllChildItems(childItem); + + return itemList; +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/declarativeobserver/editor/livelayeritem_p.h b/src/plugins/qmltooling/declarativeobserver/editor/livelayeritem_p.h new file mode 100644 index 0000000..242e365 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/livelayeritem_p.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 LIVELAYERITEM_H +#define LIVELAYERITEM_H + +#include <QtGui/QGraphicsObject> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class LiveLayerItem : public QGraphicsObject +{ +public: + LiveLayerItem(QGraphicsScene *scene); + ~LiveLayerItem(); + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget = 0); + QRectF boundingRect() const; + int type() const; + + QList<QGraphicsItem*> findAllChildItems() const; + +protected: + QList<QGraphicsItem*> findAllChildItems(const QGraphicsItem *item) const; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // LIVELAYERITEM_H diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator.cpp b/src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator.cpp new file mode 100644 index 0000000..6c37ba5 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator.cpp @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "liverubberbandselectionmanipulator_p.h" + +#include "../qdeclarativeviewobserver_p_p.h" + +#include <QtGui/QGraphicsItem> + +#include <QtCore/QDebug> + +QT_BEGIN_NAMESPACE + +LiveRubberBandSelectionManipulator::LiveRubberBandSelectionManipulator(QGraphicsObject *layerItem, + QDeclarativeViewObserver *editorView) + : m_selectionRectangleElement(layerItem), + m_editorView(editorView), + m_beginFormEditorItem(0), + m_isActive(false) +{ + m_selectionRectangleElement.hide(); +} + +void LiveRubberBandSelectionManipulator::clear() +{ + m_selectionRectangleElement.clear(); + m_isActive = false; + m_beginPoint = QPointF(); + m_itemList.clear(); + m_oldSelectionList.clear(); +} + +QGraphicsItem *LiveRubberBandSelectionManipulator::topFormEditorItem(const QList<QGraphicsItem*> + &itemList) +{ + if (itemList.isEmpty()) + return 0; + + return itemList.first(); +} + +void LiveRubberBandSelectionManipulator::begin(const QPointF &beginPoint) +{ + m_beginPoint = beginPoint; + m_selectionRectangleElement.setRect(m_beginPoint, m_beginPoint); + m_selectionRectangleElement.show(); + m_isActive = true; + QDeclarativeViewObserverPrivate *observerPrivate + = QDeclarativeViewObserverPrivate::get(m_editorView); + m_beginFormEditorItem = topFormEditorItem(observerPrivate->selectableItems(beginPoint)); + m_oldSelectionList = m_editorView->selectedItems(); +} + +void LiveRubberBandSelectionManipulator::update(const QPointF &updatePoint) +{ + m_selectionRectangleElement.setRect(m_beginPoint, updatePoint); +} + +void LiveRubberBandSelectionManipulator::end() +{ + m_oldSelectionList.clear(); + m_selectionRectangleElement.hide(); + m_isActive = false; +} + +void LiveRubberBandSelectionManipulator::select(SelectionType selectionType) +{ + QDeclarativeViewObserverPrivate *observerPrivate + = QDeclarativeViewObserverPrivate::get(m_editorView); + QList<QGraphicsItem*> itemList + = observerPrivate->selectableItems(m_selectionRectangleElement.rect(), + Qt::IntersectsItemShape); + QList<QGraphicsItem*> newSelectionList; + + foreach (QGraphicsItem* item, itemList) { + if (item + && item->parentItem() + && !newSelectionList.contains(item) + //&& m_beginFormEditorItem->childItems().contains(item) // TODO activate this test + ) + { + newSelectionList.append(item); + } + } + + if (newSelectionList.isEmpty() && m_beginFormEditorItem) + newSelectionList.append(m_beginFormEditorItem); + + QList<QGraphicsItem*> resultList; + + switch (selectionType) { + case AddToSelection: { + resultList.append(m_oldSelectionList); + resultList.append(newSelectionList); + } + break; + case ReplaceSelection: { + resultList.append(newSelectionList); + } + break; + case RemoveFromSelection: { + QSet<QGraphicsItem*> oldSelectionSet(m_oldSelectionList.toSet()); + QSet<QGraphicsItem*> newSelectionSet(newSelectionList.toSet()); + resultList.append(oldSelectionSet.subtract(newSelectionSet).toList()); + } + } + + m_editorView->setSelectedItems(resultList); +} + + +void LiveRubberBandSelectionManipulator::setItems(const QList<QGraphicsItem*> &itemList) +{ + m_itemList = itemList; +} + +QPointF LiveRubberBandSelectionManipulator::beginPoint() const +{ + return m_beginPoint; +} + +bool LiveRubberBandSelectionManipulator::isActive() const +{ + return m_isActive; +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator_p.h b/src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator_p.h new file mode 100644 index 0000000..8d15288 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/liverubberbandselectionmanipulator_p.h @@ -0,0 +1,102 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 RUBBERBANDSELECTIONMANIPULATOR_H +#define RUBBERBANDSELECTIONMANIPULATOR_H + +#include "liveselectionrectangle_p.h" + +#include <QtCore/QPointF> + +QT_FORWARD_DECLARE_CLASS(QGraphicsItem) + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeViewObserver; + +class LiveRubberBandSelectionManipulator +{ +public: + enum SelectionType { + ReplaceSelection, + AddToSelection, + RemoveFromSelection + }; + + LiveRubberBandSelectionManipulator(QGraphicsObject *layerItem, + QDeclarativeViewObserver *editorView); + + void setItems(const QList<QGraphicsItem*> &itemList); + + void begin(const QPointF& beginPoint); + void update(const QPointF& updatePoint); + void end(); + + void clear(); + + void select(SelectionType selectionType); + + QPointF beginPoint() const; + + bool isActive() const; + +protected: + QGraphicsItem *topFormEditorItem(const QList<QGraphicsItem*> &itemList); + +private: + QList<QGraphicsItem*> m_itemList; + QList<QGraphicsItem*> m_oldSelectionList; + LiveSelectionRectangle m_selectionRectangleElement; + QPointF m_beginPoint; + QDeclarativeViewObserver *m_editorView; + QGraphicsItem *m_beginFormEditorItem; + bool m_isActive; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // RUBBERBANDSELECTIONMANIPULATOR_H diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator.cpp b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator.cpp new file mode 100644 index 0000000..96e9dbf --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator.cpp @@ -0,0 +1,148 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "liveselectionindicator_p.h" + +#include "../qdeclarativeviewobserver_p_p.h" +#include "../qmlobserverconstants_p.h" + +#include <QtCore/QDebug> + +#include <QtGui/QGraphicsPolygonItem> +#include <QtGui/QGraphicsObject> +#include <QtGui/QGraphicsScene> +#include <QtGui/QPen> + +#include <cmath> + +QT_BEGIN_NAMESPACE + +LiveSelectionIndicator::LiveSelectionIndicator(QDeclarativeViewObserver *editorView, + QGraphicsObject *layerItem) + : m_layerItem(layerItem), m_view(editorView) +{ +} + +LiveSelectionIndicator::~LiveSelectionIndicator() +{ + clear(); +} + +void LiveSelectionIndicator::show() +{ + foreach (QGraphicsPolygonItem *item, m_indicatorShapeHash.values()) + item->show(); +} + +void LiveSelectionIndicator::hide() +{ + foreach (QGraphicsPolygonItem *item, m_indicatorShapeHash.values()) + item->hide(); +} + +void LiveSelectionIndicator::clear() +{ + if (!m_layerItem.isNull()) { + QHashIterator<QGraphicsItem*, QGraphicsPolygonItem *> iter(m_indicatorShapeHash); + while (iter.hasNext()) { + iter.next(); + m_layerItem.data()->scene()->removeItem(iter.value()); + delete iter.value(); + } + } + + m_indicatorShapeHash.clear(); + +} + +QPolygonF LiveSelectionIndicator::addBoundingRectToPolygon(QGraphicsItem *item, QPolygonF &polygon) +{ + // ### remove this if statement when QTBUG-12172 gets fixed + if (item->boundingRect() != QRectF(0,0,0,0)) { + QPolygonF bounding = item->mapToScene(item->boundingRect()); + if (bounding.isClosed()) //avoid crashes if there is an infinite scale. + polygon = polygon.united(bounding); + } + + foreach (QGraphicsItem *child, item->childItems()) { + if (!QDeclarativeViewObserverPrivate::get(m_view)->isEditorItem(child)) + addBoundingRectToPolygon(child, polygon); + } + return polygon; +} + +void LiveSelectionIndicator::setItems(const QList<QWeakPointer<QGraphicsObject> > &itemList) +{ + clear(); + + // set selections to also all children if they are not editor items + + foreach (const QWeakPointer<QGraphicsObject> &object, itemList) { + if (object.isNull()) + continue; + + QGraphicsItem *item = object.data(); + + QGraphicsPolygonItem *newSelectionIndicatorGraphicsItem + = new QGraphicsPolygonItem(m_layerItem.data()); + if (!m_indicatorShapeHash.contains(item)) { + m_indicatorShapeHash.insert(item, newSelectionIndicatorGraphicsItem); + + QPolygonF boundingShapeInSceneSpace; + addBoundingRectToPolygon(item, boundingShapeInSceneSpace); + + QRectF boundingRect + = m_view->adjustToScreenBoundaries(boundingShapeInSceneSpace.boundingRect()); + QPolygonF boundingRectInLayerItemSpace = m_layerItem.data()->mapFromScene(boundingRect); + + QPen pen; + pen.setColor(QColor(108, 141, 221)); + newSelectionIndicatorGraphicsItem->setData(Constants::EditorItemDataKey, + QVariant(true)); + newSelectionIndicatorGraphicsItem->setFlag(QGraphicsItem::ItemIsSelectable, false); + newSelectionIndicatorGraphicsItem->setPolygon(boundingRectInLayerItemSpace); + newSelectionIndicatorGraphicsItem->setPen(pen); + } + } +} + +QT_END_NAMESPACE + diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator_p.h b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator_p.h new file mode 100644 index 0000000..da95955 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionindicator_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 LIVESELECTIONINDICATOR_H +#define LIVESELECTIONINDICATOR_H + +#include <QtCore/QWeakPointer> +#include <QtCore/QHash> + +QT_BEGIN_NAMESPACE +class QGraphicsObject; +class QGraphicsPolygonItem; +class QGraphicsItem; +class QPolygonF; +QT_END_NAMESPACE + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeViewObserver; + +class LiveSelectionIndicator +{ +public: + LiveSelectionIndicator(QDeclarativeViewObserver* editorView, QGraphicsObject *layerItem); + ~LiveSelectionIndicator(); + + void show(); + void hide(); + + void clear(); + + void setItems(const QList<QWeakPointer<QGraphicsObject> > &itemList); + +private: + QPolygonF addBoundingRectToPolygon(QGraphicsItem *item, QPolygonF &polygon); + +private: + QHash<QGraphicsItem*, QGraphicsPolygonItem *> m_indicatorShapeHash; + QWeakPointer<QGraphicsObject> m_layerItem; + QDeclarativeViewObserver *m_view; + +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // LIVESELECTIONINDICATOR_H diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle.cpp b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle.cpp new file mode 100644 index 0000000..2a1d393 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle.cpp @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "liveselectionrectangle_p.h" + +#include "../qmlobserverconstants_p.h" + +#include <QtGui/QPen> +#include <QtGui/QGraphicsRectItem> +#include <QtGui/QGraphicsObject> +#include <QtGui/QGraphicsScene> + +#include <QtCore/QtDebug> + +#include <cmath> + +QT_BEGIN_NAMESPACE + +class SelectionRectShape : public QGraphicsRectItem +{ +public: + SelectionRectShape(QGraphicsItem *parent = 0) : QGraphicsRectItem(parent) {} + int type() const { return Constants::EditorItemType; } +}; + +LiveSelectionRectangle::LiveSelectionRectangle(QGraphicsObject *layerItem) + : m_controlShape(new SelectionRectShape(layerItem)), + m_layerItem(layerItem) +{ + m_controlShape->setPen(QPen(Qt::black)); + m_controlShape->setBrush(QColor(128, 128, 128, 50)); +} + +LiveSelectionRectangle::~LiveSelectionRectangle() +{ + if (m_layerItem) + m_layerItem.data()->scene()->removeItem(m_controlShape); +} + +void LiveSelectionRectangle::clear() +{ + hide(); +} +void LiveSelectionRectangle::show() +{ + m_controlShape->show(); +} + +void LiveSelectionRectangle::hide() +{ + m_controlShape->hide(); +} + +QRectF LiveSelectionRectangle::rect() const +{ + return m_controlShape->mapFromScene(m_controlShape->rect()).boundingRect(); +} + +void LiveSelectionRectangle::setRect(const QPointF &firstPoint, + const QPointF &secondPoint) +{ + double firstX = std::floor(firstPoint.x()) + 0.5; + double firstY = std::floor(firstPoint.y()) + 0.5; + double secondX = std::floor(secondPoint.x()) + 0.5; + double secondY = std::floor(secondPoint.y()) + 0.5; + QPointF topLeftPoint(firstX < secondX ? firstX : secondX, + firstY < secondY ? firstY : secondY); + QPointF bottomRightPoint(firstX > secondX ? firstX : secondX, + firstY > secondY ? firstY : secondY); + + QRectF rect(topLeftPoint, bottomRightPoint); + m_controlShape->setRect(rect); +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle_p.h b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle_p.h new file mode 100644 index 0000000..d1bed72 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/liveselectionrectangle_p.h @@ -0,0 +1,83 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 LIVESELECTIONRECTANGLE_H +#define LIVESELECTIONRECTANGLE_H + +#include <QtCore/QWeakPointer> + +QT_FORWARD_DECLARE_CLASS(QGraphicsObject) +QT_FORWARD_DECLARE_CLASS(QGraphicsRectItem) +QT_FORWARD_DECLARE_CLASS(QPointF) +QT_FORWARD_DECLARE_CLASS(QRectF) + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class LiveSelectionRectangle +{ +public: + LiveSelectionRectangle(QGraphicsObject *layerItem); + ~LiveSelectionRectangle(); + + void show(); + void hide(); + + void clear(); + + void setRect(const QPointF &firstPoint, + const QPointF &secondPoint); + + QRectF rect() const; + +private: + QGraphicsRectItem *m_controlShape; + QWeakPointer<QGraphicsObject> m_layerItem; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // LIVESELECTIONRECTANGLE_H diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool.cpp b/src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool.cpp new file mode 100644 index 0000000..d85926e --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool.cpp @@ -0,0 +1,442 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "liveselectiontool_p.h" +#include "livelayeritem_p.h" + +#include "../qdeclarativeviewobserver_p_p.h" + +#include <QtGui/QApplication> +#include <QtGui/QWheelEvent> +#include <QtGui/QMouseEvent> +#include <QtGui/QClipboard> +#include <QtGui/QMenu> +#include <QtGui/QAction> +#include <QtGui/QGraphicsObject> + +#include <QtDeclarative/QDeclarativeItem> +#include <QtDeclarative/QDeclarativeEngine> + +#include <QtCore/QDebug> + +QT_BEGIN_NAMESPACE + +LiveSelectionTool::LiveSelectionTool(QDeclarativeViewObserver *editorView) : + AbstractLiveEditTool(editorView), + m_rubberbandSelectionMode(false), + m_rubberbandSelectionManipulator( + QDeclarativeViewObserverPrivate::get(editorView)->manipulatorLayer, editorView), + m_singleSelectionManipulator(editorView), + m_selectionIndicator(editorView, + QDeclarativeViewObserverPrivate::get(editorView)->manipulatorLayer), + //m_resizeIndicator(editorView->manipulatorLayer()), + m_selectOnlyContentItems(true) +{ + +} + +LiveSelectionTool::~LiveSelectionTool() +{ +} + +void LiveSelectionTool::setRubberbandSelectionMode(bool value) +{ + m_rubberbandSelectionMode = value; +} + +LiveSingleSelectionManipulator::SelectionType LiveSelectionTool::getSelectionType(Qt::KeyboardModifiers + modifiers) +{ + LiveSingleSelectionManipulator::SelectionType selectionType + = LiveSingleSelectionManipulator::ReplaceSelection; + if (modifiers.testFlag(Qt::ControlModifier)) { + selectionType = LiveSingleSelectionManipulator::RemoveFromSelection; + } else if (modifiers.testFlag(Qt::ShiftModifier)) { + selectionType = LiveSingleSelectionManipulator::AddToSelection; + } + return selectionType; +} + +bool LiveSelectionTool::alreadySelected(const QList<QGraphicsItem*> &itemList) const +{ + QDeclarativeViewObserverPrivate *observerPrivate + = QDeclarativeViewObserverPrivate::get(observer()); + const QList<QGraphicsItem*> selectedItems = observerPrivate->selectedItems(); + + if (selectedItems.isEmpty()) + return false; + + foreach (QGraphicsItem *item, itemList) + if (selectedItems.contains(item)) + return true; + + return false; +} + +void LiveSelectionTool::mousePressEvent(QMouseEvent *event) +{ + QDeclarativeViewObserverPrivate *observerPrivate + = QDeclarativeViewObserverPrivate::get(observer()); + QList<QGraphicsItem*> itemList = observerPrivate->selectableItems(event->pos()); + LiveSingleSelectionManipulator::SelectionType selectionType = getSelectionType(event->modifiers()); + + if (event->buttons() & Qt::LeftButton) { + m_mousePressTimer.start(); + + if (m_rubberbandSelectionMode) { + m_rubberbandSelectionManipulator.begin(event->pos()); + } else { + m_singleSelectionManipulator.begin(event->pos()); + m_singleSelectionManipulator.select(selectionType, m_selectOnlyContentItems); + } + } else if (event->buttons() & Qt::RightButton) { + createContextMenu(itemList, event->globalPos()); + } +} + +void LiveSelectionTool::createContextMenu(QList<QGraphicsItem*> itemList, QPoint globalPos) +{ + if (!QDeclarativeViewObserverPrivate::get(observer())->mouseInsideContextItem()) + return; + + QMenu contextMenu; + connect(&contextMenu, SIGNAL(hovered(QAction*)), + this, SLOT(contextMenuElementHovered(QAction*))); + + m_contextMenuItemList = itemList; + + contextMenu.addAction(tr("Items")); + contextMenu.addSeparator(); + int shortcutKey = Qt::Key_1; + bool addKeySequence = true; + int i = 0; + + foreach (QGraphicsItem * const item, itemList) { + QString itemTitle = titleForItem(item); + QAction *elementAction = contextMenu.addAction(itemTitle, this, + SLOT(contextMenuElementSelected())); + + if (observer()->selectedItems().contains(item)) { + QFont boldFont = elementAction->font(); + boldFont.setBold(true); + elementAction->setFont(boldFont); + } + + elementAction->setData(i); + if (addKeySequence) + elementAction->setShortcut(QKeySequence(shortcutKey)); + + shortcutKey++; + if (shortcutKey > Qt::Key_9) + addKeySequence = false; + + ++i; + } + // add root item separately + // QString itemTitle = QString(tr("%1")).arg(titleForItem(view()->currentRootItem())); + // contextMenu.addAction(itemTitle, this, SLOT(contextMenuElementSelected())); + // m_contextMenuItemList.append(view()->currentRootItem()); + + contextMenu.exec(globalPos); + m_contextMenuItemList.clear(); +} + +void LiveSelectionTool::contextMenuElementSelected() +{ + QAction *senderAction = static_cast<QAction*>(sender()); + int itemListIndex = senderAction->data().toInt(); + if (itemListIndex >= 0 && itemListIndex < m_contextMenuItemList.length()) { + + QPointF updatePt(0, 0); + QGraphicsItem *item = m_contextMenuItemList.at(itemListIndex); + m_singleSelectionManipulator.begin(updatePt); + m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::InvertSelection, + QList<QGraphicsItem*>() << item, + false); + m_singleSelectionManipulator.end(updatePt); + enterContext(item); + } +} + +void LiveSelectionTool::contextMenuElementHovered(QAction *action) +{ + int itemListIndex = action->data().toInt(); + if (itemListIndex >= 0 && itemListIndex < m_contextMenuItemList.length()) { + QGraphicsObject *item = m_contextMenuItemList.at(itemListIndex)->toGraphicsObject(); + QDeclarativeViewObserverPrivate::get(observer())->highlight(item); + } +} + +void LiveSelectionTool::mouseMoveEvent(QMouseEvent *event) +{ + if (m_singleSelectionManipulator.isActive()) { + QPointF mouseMovementVector = m_singleSelectionManipulator.beginPoint() - event->pos(); + + if ((mouseMovementVector.toPoint().manhattanLength() > Constants::DragStartDistance) + && (m_mousePressTimer.elapsed() > Constants::DragStartTime)) + { + m_singleSelectionManipulator.end(event->pos()); + //view()->changeToMoveTool(m_singleSelectionManipulator.beginPoint()); + return; + } + } else if (m_rubberbandSelectionManipulator.isActive()) { + QPointF mouseMovementVector = m_rubberbandSelectionManipulator.beginPoint() - event->pos(); + + if ((mouseMovementVector.toPoint().manhattanLength() > Constants::DragStartDistance) + && (m_mousePressTimer.elapsed() > Constants::DragStartTime)) { + m_rubberbandSelectionManipulator.update(event->pos()); + + if (event->modifiers().testFlag(Qt::ControlModifier)) + m_rubberbandSelectionManipulator.select( + LiveRubberBandSelectionManipulator::RemoveFromSelection); + else if (event->modifiers().testFlag(Qt::ShiftModifier)) + m_rubberbandSelectionManipulator.select( + LiveRubberBandSelectionManipulator::AddToSelection); + else + m_rubberbandSelectionManipulator.select( + LiveRubberBandSelectionManipulator::ReplaceSelection); + } + } +} + +void LiveSelectionTool::hoverMoveEvent(QMouseEvent * event) +{ +// ### commented out until move tool is re-enabled +// QList<QGraphicsItem*> itemList = view()->items(event->pos()); +// if (!itemList.isEmpty() && !m_rubberbandSelectionMode) { +// +// foreach (QGraphicsItem *item, itemList) { +// if (item->type() == Constants::ResizeHandleItemType) { +// ResizeHandleItem* resizeHandle = ResizeHandleItem::fromGraphicsItem(item); +// if (resizeHandle) +// view()->changeTool(Constants::ResizeToolMode); +// return; +// } +// } +// if (topSelectedItemIsMovable(itemList)) +// view()->changeTool(Constants::MoveToolMode); +// } + QDeclarativeViewObserverPrivate *observerPrivate + = QDeclarativeViewObserverPrivate::get(observer()); + + QList<QGraphicsItem*> selectableItemList = observerPrivate->selectableItems(event->pos()); + if (!selectableItemList.isEmpty()) { + QGraphicsObject *item = selectableItemList.first()->toGraphicsObject(); + if (item) + QDeclarativeViewObserverPrivate::get(observer())->highlight(item); + + return; + } + + QDeclarativeViewObserverPrivate::get(observer())->clearHighlight(); +} + +void LiveSelectionTool::mouseReleaseEvent(QMouseEvent *event) +{ + if (m_singleSelectionManipulator.isActive()) { + m_singleSelectionManipulator.end(event->pos()); + } + else if (m_rubberbandSelectionManipulator.isActive()) { + + QPointF mouseMovementVector = m_rubberbandSelectionManipulator.beginPoint() - event->pos(); + if (mouseMovementVector.toPoint().manhattanLength() < Constants::DragStartDistance) { + m_singleSelectionManipulator.begin(event->pos()); + + if (event->modifiers().testFlag(Qt::ControlModifier)) + m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::RemoveFromSelection, + m_selectOnlyContentItems); + else if (event->modifiers().testFlag(Qt::ShiftModifier)) + m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::AddToSelection, + m_selectOnlyContentItems); + else + m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::InvertSelection, + m_selectOnlyContentItems); + + m_singleSelectionManipulator.end(event->pos()); + } else { + m_rubberbandSelectionManipulator.update(event->pos()); + + if (event->modifiers().testFlag(Qt::ControlModifier)) + m_rubberbandSelectionManipulator.select( + LiveRubberBandSelectionManipulator::RemoveFromSelection); + else if (event->modifiers().testFlag(Qt::ShiftModifier)) + m_rubberbandSelectionManipulator.select( + LiveRubberBandSelectionManipulator::AddToSelection); + else + m_rubberbandSelectionManipulator.select( + LiveRubberBandSelectionManipulator::ReplaceSelection); + + m_rubberbandSelectionManipulator.end(); + } + } +} + +void LiveSelectionTool::mouseDoubleClickEvent(QMouseEvent * /*event*/) +{ +} + +void LiveSelectionTool::keyPressEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Left: + case Qt::Key_Right: + case Qt::Key_Up: + case Qt::Key_Down: + // disabled for now, cannot move stuff yet. + //view()->changeTool(Constants::MoveToolMode); + //view()->currentTool()->keyPressEvent(event); + break; + } +} + +void LiveSelectionTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/) +{ + +} + +void LiveSelectionTool::wheelEvent(QWheelEvent *event) +{ + if (event->orientation() == Qt::Horizontal || m_rubberbandSelectionMode) + return; + + QDeclarativeViewObserverPrivate *observerPrivate + = QDeclarativeViewObserverPrivate::get(observer()); + QList<QGraphicsItem*> itemList = observerPrivate->selectableItems(event->pos()); + + if (itemList.isEmpty()) + return; + + int selectedIdx = 0; + if (!observer()->selectedItems().isEmpty()) { + selectedIdx = itemList.indexOf(observer()->selectedItems().first()); + if (selectedIdx >= 0) { + if (event->delta() > 0) { + selectedIdx++; + if (selectedIdx == itemList.length()) + selectedIdx = 0; + } else if (event->delta() < 0) { + selectedIdx--; + if (selectedIdx == -1) + selectedIdx = itemList.length() - 1; + } + } else { + selectedIdx = 0; + } + } + + QPointF updatePt(0, 0); + m_singleSelectionManipulator.begin(updatePt); + m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::ReplaceSelection, + QList<QGraphicsItem*>() << itemList.at(selectedIdx), + false); + m_singleSelectionManipulator.end(updatePt); + +} + +void LiveSelectionTool::setSelectOnlyContentItems(bool selectOnlyContentItems) +{ + m_selectOnlyContentItems = selectOnlyContentItems; +} + +void LiveSelectionTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/) +{ +} + +void LiveSelectionTool::clear() +{ + view()->setCursor(Qt::ArrowCursor); + m_rubberbandSelectionManipulator.clear(), + m_singleSelectionManipulator.clear(); + m_selectionIndicator.clear(); + //m_resizeIndicator.clear(); +} + +void LiveSelectionTool::selectedItemsChanged(const QList<QGraphicsItem*> &itemList) +{ + foreach (const QWeakPointer<QGraphicsObject> &obj, m_selectedItemList) { + if (!obj.isNull()) { + disconnect(obj.data(), SIGNAL(xChanged()), this, SLOT(repaintBoundingRects())); + disconnect(obj.data(), SIGNAL(yChanged()), this, SLOT(repaintBoundingRects())); + disconnect(obj.data(), SIGNAL(widthChanged()), this, SLOT(repaintBoundingRects())); + disconnect(obj.data(), SIGNAL(heightChanged()), this, SLOT(repaintBoundingRects())); + disconnect(obj.data(), SIGNAL(rotationChanged()), this, SLOT(repaintBoundingRects())); + } + } + + QList<QGraphicsObject*> objects = toGraphicsObjectList(itemList); + m_selectedItemList.clear(); + + foreach (QGraphicsObject *obj, objects) { + m_selectedItemList.append(obj); + connect(obj, SIGNAL(xChanged()), this, SLOT(repaintBoundingRects())); + connect(obj, SIGNAL(yChanged()), this, SLOT(repaintBoundingRects())); + connect(obj, SIGNAL(widthChanged()), this, SLOT(repaintBoundingRects())); + connect(obj, SIGNAL(heightChanged()), this, SLOT(repaintBoundingRects())); + connect(obj, SIGNAL(rotationChanged()), this, SLOT(repaintBoundingRects())); + } + + m_selectionIndicator.setItems(m_selectedItemList); + //m_resizeIndicator.setItems(toGraphicsObjectList(itemList)); +} + +void LiveSelectionTool::repaintBoundingRects() +{ + m_selectionIndicator.setItems(m_selectedItemList); +} + +void LiveSelectionTool::selectUnderPoint(QMouseEvent *event) +{ + m_singleSelectionManipulator.begin(event->pos()); + + if (event->modifiers().testFlag(Qt::ControlModifier)) + m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::RemoveFromSelection, + m_selectOnlyContentItems); + else if (event->modifiers().testFlag(Qt::ShiftModifier)) + m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::AddToSelection, + m_selectOnlyContentItems); + else + m_singleSelectionManipulator.select(LiveSingleSelectionManipulator::InvertSelection, + m_selectOnlyContentItems); + + m_singleSelectionManipulator.end(event->pos()); +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool_p.h b/src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool_p.h new file mode 100644 index 0000000..3daac3d --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/liveselectiontool_p.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 LIVESELECTIONTOOL_H +#define LIVESELECTIONTOOL_H + +#include "abstractliveedittool_p.h" +#include "liverubberbandselectionmanipulator_p.h" +#include "livesingleselectionmanipulator_p.h" +#include "liveselectionindicator_p.h" + +#include <QtCore/QList> +#include <QtCore/QTime> + +QT_FORWARD_DECLARE_CLASS(QGraphicsItem) +QT_FORWARD_DECLARE_CLASS(QMouseEvent) +QT_FORWARD_DECLARE_CLASS(QKeyEvent) +QT_FORWARD_DECLARE_CLASS(QAction) + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class LiveSelectionTool : public AbstractLiveEditTool +{ + Q_OBJECT + +public: + LiveSelectionTool(QDeclarativeViewObserver* editorView); + ~LiveSelectionTool(); + + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + void hoverMoveEvent(QMouseEvent *event); + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *keyEvent); + void wheelEvent(QWheelEvent *event); + + void itemsAboutToRemoved(const QList<QGraphicsItem*> &itemList); +// QVariant itemChange(const QList<QGraphicsItem*> &itemList, +// QGraphicsItem::GraphicsItemChange change, +// const QVariant &value ); + +// void update(); + + void clear(); + + void selectedItemsChanged(const QList<QGraphicsItem*> &itemList); + + void selectUnderPoint(QMouseEvent *event); + + void setSelectOnlyContentItems(bool selectOnlyContentItems); + + void setRubberbandSelectionMode(bool value); + +private slots: + void contextMenuElementSelected(); + void contextMenuElementHovered(QAction *action); + void repaintBoundingRects(); + +private: + void createContextMenu(QList<QGraphicsItem*> itemList, QPoint globalPos); + LiveSingleSelectionManipulator::SelectionType getSelectionType(Qt::KeyboardModifiers modifiers); + bool alreadySelected(const QList<QGraphicsItem*> &itemList) const; + +private: + bool m_rubberbandSelectionMode; + LiveRubberBandSelectionManipulator m_rubberbandSelectionManipulator; + LiveSingleSelectionManipulator m_singleSelectionManipulator; + LiveSelectionIndicator m_selectionIndicator; + //ResizeIndicator m_resizeIndicator; + QTime m_mousePressTimer; + bool m_selectOnlyContentItems; + + QList<QWeakPointer<QGraphicsObject> > m_selectedItemList; + + QList<QGraphicsItem*> m_contextMenuItemList; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // LIVESELECTIONTOOL_H diff --git a/src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator.cpp b/src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator.cpp new file mode 100644 index 0000000..e753b64 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator.cpp @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "livesingleselectionmanipulator_p.h" + +#include "../qdeclarativeviewobserver_p_p.h" + +#include <QtDebug> + +QT_BEGIN_NAMESPACE + +LiveSingleSelectionManipulator::LiveSingleSelectionManipulator(QDeclarativeViewObserver *editorView) + : m_editorView(editorView), + m_isActive(false) +{ +} + + +void LiveSingleSelectionManipulator::begin(const QPointF &beginPoint) +{ + m_beginPoint = beginPoint; + m_isActive = true; + m_oldSelectionList = QDeclarativeViewObserverPrivate::get(m_editorView)->selectedItems(); +} + +void LiveSingleSelectionManipulator::update(const QPointF &/*updatePoint*/) +{ + m_oldSelectionList.clear(); +} + +void LiveSingleSelectionManipulator::clear() +{ + m_beginPoint = QPointF(); + m_oldSelectionList.clear(); +} + + +void LiveSingleSelectionManipulator::end(const QPointF &/*updatePoint*/) +{ + m_oldSelectionList.clear(); + m_isActive = false; +} + +void LiveSingleSelectionManipulator::select(SelectionType selectionType, + const QList<QGraphicsItem*> &items, + bool /*selectOnlyContentItems*/) +{ + QGraphicsItem *selectedItem = 0; + + foreach (QGraphicsItem* item, items) + { + //FormEditorItem *formEditorItem = FormEditorItem::fromQGraphicsItem(item); + if (item + /*&& !formEditorItem->qmlItemNode().isRootNode() + && (formEditorItem->qmlItemNode().hasShowContent() || !selectOnlyContentItems)*/) + { + selectedItem = item; + break; + } + } + + QList<QGraphicsItem*> resultList; + + switch (selectionType) { + case AddToSelection: { + resultList.append(m_oldSelectionList); + if (selectedItem && !m_oldSelectionList.contains(selectedItem)) + resultList.append(selectedItem); + } + break; + case ReplaceSelection: { + if (selectedItem) + resultList.append(selectedItem); + } + break; + case RemoveFromSelection: { + resultList.append(m_oldSelectionList); + if (selectedItem) + resultList.removeAll(selectedItem); + } + break; + case InvertSelection: { + if (selectedItem + && !m_oldSelectionList.contains(selectedItem)) + { + resultList.append(selectedItem); + } + } + } + + m_editorView->setSelectedItems(resultList); +} + +void LiveSingleSelectionManipulator::select(SelectionType selectionType, bool selectOnlyContentItems) +{ + QDeclarativeViewObserverPrivate *observerPrivate = + QDeclarativeViewObserverPrivate::get(m_editorView); + QList<QGraphicsItem*> itemList = observerPrivate->selectableItems(m_beginPoint); + select(selectionType, itemList, selectOnlyContentItems); +} + + +bool LiveSingleSelectionManipulator::isActive() const +{ + return m_isActive; +} + +QPointF LiveSingleSelectionManipulator::beginPoint() const +{ + return m_beginPoint; +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator_p.h b/src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator_p.h new file mode 100644 index 0000000..68329e5 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/livesingleselectionmanipulator_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 LIVESINGLESELECTIONMANIPULATOR_H +#define LIVESINGLESELECTIONMANIPULATOR_H + +#include <QtCore/QPointF> +#include <QtCore/QList> + +QT_FORWARD_DECLARE_CLASS(QGraphicsItem) + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeViewObserver; + +class LiveSingleSelectionManipulator +{ +public: + LiveSingleSelectionManipulator(QDeclarativeViewObserver *editorView); + + enum SelectionType { + ReplaceSelection, + AddToSelection, + RemoveFromSelection, + InvertSelection + }; + + void begin(const QPointF& beginPoint); + void update(const QPointF& updatePoint); + void end(const QPointF& updatePoint); + + void select(SelectionType selectionType, const QList<QGraphicsItem*> &items, + bool selectOnlyContentItems); + void select(SelectionType selectionType, bool selectOnlyContentItems); + + void clear(); + + QPointF beginPoint() const; + + bool isActive() const; + +private: + QList<QGraphicsItem*> m_oldSelectionList; + QPointF m_beginPoint; + QDeclarativeViewObserver *m_editorView; + bool m_isActive; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // LIVESINGLESELECTIONMANIPULATOR_H diff --git a/src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar.cpp b/src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar.cpp new file mode 100644 index 0000000..359e9ef --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar.cpp @@ -0,0 +1,328 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "qmltoolbar_p.h" +#include "toolbarcolorbox_p.h" + +#include <QtGui/QLabel> +#include <QtGui/QIcon> +#include <QtGui/QAction> +#include <QtGui/QMenu> + +#include <QtCore/QDebug> + +QT_BEGIN_NAMESPACE + +QmlToolBar::QmlToolBar(QWidget *parent) + : QToolBar(parent) + , m_emitSignals(true) + , m_paused(false) + , m_animationSpeed(1.0f) + , ui(new Ui) +{ + ui->playIcon = QIcon(QLatin1String(":/qml/images/play-24.png")); + ui->pauseIcon = QIcon(QLatin1String(":/qml/images/pause-24.png")); + + ui->designmode = new QAction(QIcon(QLatin1String(":/qml/images/observermode-24.png")), + tr("Observer Mode"), this); + ui->play = new QAction(ui->pauseIcon, tr("Play/Pause Animations"), this); + ui->select = new QAction(QIcon(QLatin1String(":/qml/images/select-24.png")), tr("Select"), this); + ui->selectMarquee = new QAction(QIcon(QLatin1String(":/qml/images/select-marquee-24.png")), + tr("Select (Marquee)"), this); + ui->zoom = new QAction(QIcon(QLatin1String(":/qml/images/zoom-24.png")), tr("Zoom"), this); + ui->colorPicker = new QAction(QIcon(QLatin1String(":/qml/images/color-picker-24.png")), + tr("Color Picker"), this); + ui->toQml = new QAction(QIcon(QLatin1String(":/qml/images/to-qml-24.png")), + tr("Apply Changes to QML Viewer"), this); + ui->fromQml = new QAction(QIcon(QLatin1String(":/qml/images/from-qml-24.png")), + tr("Apply Changes to Document"), this); + ui->designmode->setCheckable(true); + ui->designmode->setChecked(false); + + ui->play->setCheckable(false); + ui->select->setCheckable(true); + ui->selectMarquee->setCheckable(true); + ui->zoom->setCheckable(true); + ui->colorPicker->setCheckable(true); + + setWindowTitle(tr("Tools")); + + addAction(ui->designmode); + addAction(ui->play); + addSeparator(); + + addAction(ui->select); + // disabled because multi selection does not do anything useful without design mode + //addAction(ui->selectMarquee); + addSeparator(); + addAction(ui->zoom); + addAction(ui->colorPicker); + //addAction(ui->fromQml); + + ui->colorBox = new ToolBarColorBox(this); + ui->colorBox->setMinimumSize(24, 24); + ui->colorBox->setMaximumSize(28, 28); + ui->colorBox->setColor(Qt::black); + addWidget(ui->colorBox); + + setWindowFlags(Qt::Tool); + + QMenu *playSpeedMenu = new QMenu(this); + ui->playSpeedMenuActions = new QActionGroup(this); + ui->playSpeedMenuActions->setExclusive(true); + + QAction *speedAction = playSpeedMenu->addAction(tr("1x"), this, SLOT(changeAnimationSpeed())); + speedAction->setCheckable(true); + speedAction->setChecked(true); + speedAction->setData(1.0f); + ui->playSpeedMenuActions->addAction(speedAction); + + speedAction = playSpeedMenu->addAction(tr("0.5x"), this, SLOT(changeAnimationSpeed())); + speedAction->setCheckable(true); + speedAction->setData(2.0f); + ui->playSpeedMenuActions->addAction(speedAction); + + speedAction = playSpeedMenu->addAction(tr("0.25x"), this, SLOT(changeAnimationSpeed())); + speedAction->setCheckable(true); + speedAction->setData(4.0f); + ui->playSpeedMenuActions->addAction(speedAction); + + speedAction = playSpeedMenu->addAction(tr("0.125x"), this, SLOT(changeAnimationSpeed())); + speedAction->setCheckable(true); + speedAction->setData(8.0f); + ui->playSpeedMenuActions->addAction(speedAction); + + speedAction = playSpeedMenu->addAction(tr("0.1x"), this, SLOT(changeAnimationSpeed())); + speedAction->setCheckable(true); + speedAction->setData(10.0f); + ui->playSpeedMenuActions->addAction(speedAction); + + ui->play->setMenu(playSpeedMenu); + + connect(ui->designmode, SIGNAL(toggled(bool)), SLOT(setDesignModeBehaviorOnClick(bool))); + + connect(ui->colorPicker, SIGNAL(triggered()), SLOT(activateColorPickerOnClick())); + + connect(ui->play, SIGNAL(triggered()), SLOT(activatePlayOnClick())); + + connect(ui->zoom, SIGNAL(triggered()), SLOT(activateZoomOnClick())); + connect(ui->colorPicker, SIGNAL(triggered()), SLOT(activateColorPickerOnClick())); + connect(ui->select, SIGNAL(triggered()), SLOT(activateSelectToolOnClick())); + connect(ui->selectMarquee, SIGNAL(triggered()), SLOT(activateMarqueeSelectToolOnClick())); + + connect(ui->toQml, SIGNAL(triggered()), SLOT(activateToQml())); + connect(ui->fromQml, SIGNAL(triggered()), SLOT(activateFromQml())); +} + +QmlToolBar::~QmlToolBar() +{ + delete ui; +} + +void QmlToolBar::activateColorPicker() +{ + m_emitSignals = false; + activateColorPickerOnClick(); + m_emitSignals = true; +} + +void QmlToolBar::activateSelectTool() +{ + m_emitSignals = false; + activateSelectToolOnClick(); + m_emitSignals = true; +} + +void QmlToolBar::activateMarqueeSelectTool() +{ + m_emitSignals = false; + activateMarqueeSelectToolOnClick(); + m_emitSignals = true; +} + +void QmlToolBar::activateZoom() +{ + m_emitSignals = false; + activateZoomOnClick(); + m_emitSignals = true; +} + +void QmlToolBar::setAnimationSpeed(qreal slowDownFactor) +{ + if (m_animationSpeed == slowDownFactor) + return; + + m_emitSignals = false; + m_animationSpeed = slowDownFactor; + + foreach (QAction *action, ui->playSpeedMenuActions->actions()) { + if (action->data().toReal() == slowDownFactor) { + action->setChecked(true); + break; + } + } + + m_emitSignals = true; +} + +void QmlToolBar::setAnimationPaused(bool paused) +{ + if (m_paused == paused) + return; + + m_paused = paused; + updatePlayAction(); +} + +void QmlToolBar::changeAnimationSpeed() +{ + QAction *action = qobject_cast<QAction*>(sender()); + m_animationSpeed = action->data().toReal(); + emit animationSpeedChanged(m_animationSpeed); +} + +void QmlToolBar::setDesignModeBehavior(bool inDesignMode) +{ + m_emitSignals = false; + ui->designmode->setChecked(inDesignMode); + setDesignModeBehaviorOnClick(inDesignMode); + m_emitSignals = true; +} + +void QmlToolBar::setDesignModeBehaviorOnClick(bool checked) +{ + ui->select->setEnabled(checked); + ui->selectMarquee->setEnabled(checked); + ui->zoom->setEnabled(checked); + ui->colorPicker->setEnabled(checked); + ui->toQml->setEnabled(checked); + ui->fromQml->setEnabled(checked); + + if (m_emitSignals) + emit designModeBehaviorChanged(checked); +} + +void QmlToolBar::setColorBoxColor(const QColor &color) +{ + ui->colorBox->setColor(color); +} + +void QmlToolBar::activatePlayOnClick() +{ + m_paused = !m_paused; + emit animationPausedChanged(m_paused); + updatePlayAction(); +} + +void QmlToolBar::updatePlayAction() +{ + ui->play->setIcon(m_paused ? ui->playIcon : ui->pauseIcon); +} + +void QmlToolBar::activateColorPickerOnClick() +{ + ui->zoom->setChecked(false); + ui->select->setChecked(false); + ui->selectMarquee->setChecked(false); + + ui->colorPicker->setChecked(true); + if (m_activeTool != Constants::ColorPickerMode) { + m_activeTool = Constants::ColorPickerMode; + if (m_emitSignals) + emit colorPickerSelected(); + } +} + +void QmlToolBar::activateSelectToolOnClick() +{ + ui->zoom->setChecked(false); + ui->selectMarquee->setChecked(false); + ui->colorPicker->setChecked(false); + + ui->select->setChecked(true); + if (m_activeTool != Constants::SelectionToolMode) { + m_activeTool = Constants::SelectionToolMode; + if (m_emitSignals) + emit selectToolSelected(); + } +} + +void QmlToolBar::activateMarqueeSelectToolOnClick() +{ + ui->zoom->setChecked(false); + ui->select->setChecked(false); + ui->colorPicker->setChecked(false); + + ui->selectMarquee->setChecked(true); + if (m_activeTool != Constants::MarqueeSelectionToolMode) { + m_activeTool = Constants::MarqueeSelectionToolMode; + if (m_emitSignals) + emit marqueeSelectToolSelected(); + } +} + +void QmlToolBar::activateZoomOnClick() +{ + ui->select->setChecked(false); + ui->selectMarquee->setChecked(false); + ui->colorPicker->setChecked(false); + + ui->zoom->setChecked(true); + if (m_activeTool != Constants::ZoomMode) { + m_activeTool = Constants::ZoomMode; + if (m_emitSignals) + emit zoomToolSelected(); + } +} + +void QmlToolBar::activateFromQml() +{ + if (m_emitSignals) + emit applyChangesFromQmlFileSelected(); +} + +void QmlToolBar::activateToQml() +{ + if (m_emitSignals) + emit applyChangesToQmlFileSelected(); +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar_p.h b/src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar_p.h new file mode 100644 index 0000000..459eafd --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/qmltoolbar_p.h @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 QMLTOOLBAR_H +#define QMLTOOLBAR_H + +#include <QtGui/QToolBar> +#include <QtGui/QIcon> + +#include "../qmlobserverconstants_p.h" + +QT_FORWARD_DECLARE_CLASS(QActionGroup) + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class ToolBarColorBox; + +class QmlToolBar : public QToolBar +{ + Q_OBJECT + +public: + explicit QmlToolBar(QWidget *parent = 0); + ~QmlToolBar(); + +public slots: + void setDesignModeBehavior(bool inDesignMode); + void setColorBoxColor(const QColor &color); + void activateColorPicker(); + void activateSelectTool(); + void activateMarqueeSelectTool(); + void activateZoom(); + + void setAnimationSpeed(qreal slowDownFactor); + void setAnimationPaused(bool paused); + +signals: + void animationSpeedChanged(qreal factor); + void animationPausedChanged(bool paused); + + void designModeBehaviorChanged(bool inDesignMode); + void colorPickerSelected(); + void selectToolSelected(); + void marqueeSelectToolSelected(); + void zoomToolSelected(); + + void applyChangesToQmlFileSelected(); + void applyChangesFromQmlFileSelected(); + +private slots: + void setDesignModeBehaviorOnClick(bool inDesignMode); + void activatePlayOnClick(); + void activateColorPickerOnClick(); + void activateSelectToolOnClick(); + void activateMarqueeSelectToolOnClick(); + void activateZoomOnClick(); + + void activateFromQml(); + void activateToQml(); + + void changeAnimationSpeed(); + + void updatePlayAction(); + +private: + class Ui { + public: + QAction *designmode; + QAction *play; + QAction *select; + QAction *selectMarquee; + QAction *zoom; + QAction *colorPicker; + QAction *toQml; + QAction *fromQml; + QIcon playIcon; + QIcon pauseIcon; + ToolBarColorBox *colorBox; + + QActionGroup *playSpeedMenuActions; + }; + + bool m_emitSignals; + bool m_paused; + qreal m_animationSpeed; + + Constants::DesignTool m_activeTool; + + Ui *ui; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMLTOOLBAR_H diff --git a/src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool.cpp b/src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool.cpp new file mode 100644 index 0000000..ab77296 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool.cpp @@ -0,0 +1,364 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "subcomponenteditortool_p.h" +#include "subcomponentmasklayeritem_p.h" +#include "livelayeritem_p.h" + +#include "../qdeclarativeviewobserver_p_p.h" + +#include <QtGui/QGraphicsItem> +#include <QtGui/QGraphicsObject> +#include <QtGui/QMouseEvent> +#include <QtGui/QKeyEvent> + +#include <QtCore/QTimer> +#include <QtCore/QDebug> + +QT_BEGIN_NAMESPACE + +const qreal MaxOpacity = 0.5f; + +SubcomponentEditorTool::SubcomponentEditorTool(QDeclarativeViewObserver *view) + : AbstractLiveEditTool(view), + m_animIncrement(0.05f), + m_animTimer(new QTimer(this)) +{ + QDeclarativeViewObserverPrivate *observerPrivate = + QDeclarativeViewObserverPrivate::get(view); + m_mask = new SubcomponentMaskLayerItem(view, observerPrivate->manipulatorLayer); + connect(m_animTimer, SIGNAL(timeout()), SLOT(animate())); + m_animTimer->setInterval(20); +} + +SubcomponentEditorTool::~SubcomponentEditorTool() +{ + +} + +void SubcomponentEditorTool::mousePressEvent(QMouseEvent * /*event*/) +{ + +} + +void SubcomponentEditorTool::mouseMoveEvent(QMouseEvent * /*event*/) +{ + +} + +bool SubcomponentEditorTool::containsCursor(const QPoint &mousePos) const +{ + if (!m_currentContext.size()) + return false; + + QPointF scenePos = view()->mapToScene(mousePos); + QRectF itemRect = m_currentContext.top()->boundingRect() + | m_currentContext.top()->childrenBoundingRect(); + QRectF polyRect = m_currentContext.top()->mapToScene(itemRect).boundingRect(); + + return polyRect.contains(scenePos); +} + +void SubcomponentEditorTool::mouseReleaseEvent(QMouseEvent * /*event*/) +{ + +} + +void SubcomponentEditorTool::mouseDoubleClickEvent(QMouseEvent *event) +{ + if (event->buttons() & Qt::LeftButton + && !containsCursor(event->pos()) + && m_currentContext.size() > 1) + { + aboutToPopContext(); + } +} + +void SubcomponentEditorTool::hoverMoveEvent(QMouseEvent *event) +{ + if (!containsCursor(event->pos()) && m_currentContext.size() > 1) { + QDeclarativeViewObserverPrivate::get(observer())->clearHighlight(); + } +} + +void SubcomponentEditorTool::wheelEvent(QWheelEvent * /*event*/) +{ + +} + +void SubcomponentEditorTool::keyPressEvent(QKeyEvent * /*event*/) +{ + +} + +void SubcomponentEditorTool::keyReleaseEvent(QKeyEvent * /*keyEvent*/) +{ + +} + +void SubcomponentEditorTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/) +{ + +} + +void SubcomponentEditorTool::animate() +{ + if (m_animIncrement > 0) { + if (m_mask->opacity() + m_animIncrement < MaxOpacity) { + m_mask->setOpacity(m_mask->opacity() + m_animIncrement); + } else { + m_animTimer->stop(); + m_mask->setOpacity(MaxOpacity); + } + } else { + if (m_mask->opacity() + m_animIncrement > 0) { + m_mask->setOpacity(m_mask->opacity() + m_animIncrement); + } else { + m_animTimer->stop(); + m_mask->setOpacity(0); + popContext(); + emit contextPathChanged(m_path); + } + } + +} + +void SubcomponentEditorTool::clear() +{ + m_currentContext.clear(); + m_mask->setCurrentItem(0); + m_animTimer->stop(); + m_mask->hide(); + m_path.clear(); + + emit contextPathChanged(m_path); + emit cleared(); +} + +void SubcomponentEditorTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*itemList*/) +{ + +} + +void SubcomponentEditorTool::setCurrentItem(QGraphicsItem* contextItem) +{ + if (!contextItem) + return; + + QGraphicsObject *gfxObject = contextItem->toGraphicsObject(); + if (!gfxObject) + return; + + //QString parentClassName = gfxObject->metaObject()->className(); + //if (parentClassName.contains(QRegExp("_QMLTYPE_\\d+"))) + + bool containsSelectableItems = false; + foreach (QGraphicsItem *item, gfxObject->childItems()) { + if (item->type() == Constants::EditorItemType + || item->type() == Constants::ResizeHandleItemType) + { + continue; + } + containsSelectableItems = true; + break; + } + + if (containsSelectableItems) { + m_mask->setCurrentItem(gfxObject); + m_mask->setOpacity(0); + m_mask->show(); + m_animIncrement = 0.05f; + m_animTimer->start(); + + QDeclarativeViewObserverPrivate::get(observer())->clearHighlight(); + observer()->setSelectedItems(QList<QGraphicsItem*>()); + + pushContext(gfxObject); + } +} + +QGraphicsItem *SubcomponentEditorTool::firstChildOfContext(QGraphicsItem *item) const +{ + if (!item) + return 0; + + if (isDirectChildOfContext(item)) + return item; + + QGraphicsItem *parent = item->parentItem(); + while (parent) { + if (isDirectChildOfContext(parent)) + return parent; + parent = parent->parentItem(); + } + + return 0; +} + +bool SubcomponentEditorTool::isChildOfContext(QGraphicsItem *item) const +{ + return (firstChildOfContext(item) != 0); +} + +bool SubcomponentEditorTool::isDirectChildOfContext(QGraphicsItem *item) const +{ + return (item->parentItem() == m_currentContext.top()); +} + +bool SubcomponentEditorTool::itemIsChildOfQmlSubComponent(QGraphicsItem *item) const +{ + if (item->parentItem() && item->parentItem() != m_currentContext.top()) { + QGraphicsObject *parent = item->parentItem()->toGraphicsObject(); + QString parentClassName = QLatin1String(parent->metaObject()->className()); + + if (parentClassName.contains(QRegExp(QLatin1String("_QMLTYPE_\\d+")))) { + return true; + } else { + return itemIsChildOfQmlSubComponent(parent); + } + } + + return false; +} + +void SubcomponentEditorTool::pushContext(QGraphicsObject *contextItem) +{ + connect(contextItem, SIGNAL(destroyed(QObject*)), this, SLOT(contextDestroyed(QObject*))); + connect(contextItem, SIGNAL(xChanged()), this, SLOT(resizeMask())); + connect(contextItem, SIGNAL(yChanged()), this, SLOT(resizeMask())); + connect(contextItem, SIGNAL(widthChanged()), this, SLOT(resizeMask())); + connect(contextItem, SIGNAL(heightChanged()), this, SLOT(resizeMask())); + connect(contextItem, SIGNAL(rotationChanged()), this, SLOT(resizeMask())); + + m_currentContext.push(contextItem); + QString title = titleForItem(contextItem); + emit contextPushed(title); + + m_path << title; + emit contextPathChanged(m_path); +} + +void SubcomponentEditorTool::aboutToPopContext() +{ + if (m_currentContext.size() > 2) { + popContext(); + emit contextPathChanged(m_path); + } else { + m_animIncrement = -0.05f; + m_animTimer->start(); + } +} + +QGraphicsObject *SubcomponentEditorTool::popContext() +{ + QGraphicsObject *popped = m_currentContext.pop(); + m_path.removeLast(); + + emit contextPopped(); + + disconnect(popped, SIGNAL(xChanged()), this, SLOT(resizeMask())); + disconnect(popped, SIGNAL(yChanged()), this, SLOT(resizeMask())); + disconnect(popped, SIGNAL(scaleChanged()), this, SLOT(resizeMask())); + disconnect(popped, SIGNAL(widthChanged()), this, SLOT(resizeMask())); + disconnect(popped, SIGNAL(heightChanged()), this, SLOT(resizeMask())); + + if (m_currentContext.size() > 1) { + QGraphicsObject *item = m_currentContext.top(); + m_mask->setCurrentItem(item); + m_mask->setOpacity(MaxOpacity); + m_mask->setVisible(true); + } else { + m_mask->setVisible(false); + } + + return popped; +} + +void SubcomponentEditorTool::resizeMask() +{ + QGraphicsObject *item = m_currentContext.top(); + m_mask->setCurrentItem(item); +} + +QGraphicsObject *SubcomponentEditorTool::currentRootItem() const +{ + return m_currentContext.top(); +} + +void SubcomponentEditorTool::contextDestroyed(QObject *contextToDestroy) +{ + disconnect(contextToDestroy, SIGNAL(destroyed(QObject*)), + this, SLOT(contextDestroyed(QObject*))); + + // pop out the whole context - it might not be safe anymore. + while (m_currentContext.size() > 1) { + m_currentContext.pop(); + m_path.removeLast(); + emit contextPopped(); + } + m_mask->setVisible(false); + + emit contextPathChanged(m_path); +} + +QGraphicsObject *SubcomponentEditorTool::setContext(int contextIndex) +{ + Q_ASSERT(contextIndex >= 0); + + // sometimes we have to delete the context while user was still clicking around, + // so just bail out. + if (contextIndex >= m_currentContext.size() -1) + return 0; + + while (m_currentContext.size() - 1 > contextIndex) { + popContext(); + } + emit contextPathChanged(m_path); + + return m_currentContext.top(); +} + +int SubcomponentEditorTool::contextIndex() const +{ + return m_currentContext.size() - 1; +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool_p.h b/src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool_p.h new file mode 100644 index 0000000..15217eb --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/subcomponenteditortool_p.h @@ -0,0 +1,131 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 SUBCOMPONENTEDITORTOOL_H +#define SUBCOMPONENTEDITORTOOL_H + +#include "abstractliveedittool_p.h" + +#include <QtCore/QStack> +#include <QtCore/QStringList> + +QT_FORWARD_DECLARE_CLASS(QGraphicsObject) +QT_FORWARD_DECLARE_CLASS(QPoint) +QT_FORWARD_DECLARE_CLASS(QTimer) + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class SubcomponentMaskLayerItem; + +class SubcomponentEditorTool : public AbstractLiveEditTool +{ + Q_OBJECT + +public: + SubcomponentEditorTool(QDeclarativeViewObserver *view); + ~SubcomponentEditorTool(); + + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + + void hoverMoveEvent(QMouseEvent *event); + void wheelEvent(QWheelEvent *event); + + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *keyEvent); + void itemsAboutToRemoved(const QList<QGraphicsItem*> &itemList); + + void clear(); + + bool containsCursor(const QPoint &mousePos) const; + bool itemIsChildOfQmlSubComponent(QGraphicsItem *item) const; + + bool isChildOfContext(QGraphicsItem *item) const; + bool isDirectChildOfContext(QGraphicsItem *item) const; + QGraphicsItem *firstChildOfContext(QGraphicsItem *item) const; + + void setCurrentItem(QGraphicsItem *contextObject); + + void pushContext(QGraphicsObject *contextItem); + + QGraphicsObject *currentRootItem() const; + QGraphicsObject *setContext(int contextIndex); + int contextIndex() const; + +signals: + void exitContextRequested(); + void cleared(); + void contextPushed(const QString &contextTitle); + void contextPopped(); + void contextPathChanged(const QStringList &path); + +protected: + void selectedItemsChanged(const QList<QGraphicsItem*> &itemList); + +private slots: + void animate(); + void contextDestroyed(QObject *context); + void resizeMask(); + +private: + QGraphicsObject *popContext(); + void aboutToPopContext(); + +private: + QStack<QGraphicsObject *> m_currentContext; + QStringList m_path; + + qreal m_animIncrement; + SubcomponentMaskLayerItem *m_mask; + QTimer *m_animTimer; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // SUBCOMPONENTEDITORTOOL_H diff --git a/src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem.cpp b/src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem.cpp new file mode 100644 index 0000000..15d2a2c --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem.cpp @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "subcomponentmasklayeritem_p.h" + +#include "../qmlobserverconstants_p.h" +#include "../qdeclarativeviewobserver_p.h" + +#include <QtGui/QPolygonF> + +QT_BEGIN_NAMESPACE + +SubcomponentMaskLayerItem::SubcomponentMaskLayerItem(QDeclarativeViewObserver *observer, + QGraphicsItem *parentItem) : + QGraphicsPolygonItem(parentItem), + m_observer(observer), + m_currentItem(0), + m_borderRect(new QGraphicsRectItem(this)) +{ + m_borderRect->setRect(0,0,0,0); + m_borderRect->setPen(QPen(QColor(60, 60, 60), 1)); + m_borderRect->setData(Constants::EditorItemDataKey, QVariant(true)); + + setBrush(QBrush(QColor(160,160,160))); + setPen(Qt::NoPen); +} + +int SubcomponentMaskLayerItem::type() const +{ + return Constants::EditorItemType; +} + +static QRectF resizeRect(const QRectF &newRect, const QRectF &oldRect) +{ + QRectF result = newRect; + if (oldRect.left() < newRect.left()) + result.setLeft(oldRect.left()); + + if (oldRect.top() < newRect.top()) + result.setTop(oldRect.top()); + + if (oldRect.right() > newRect.right()) + result.setRight(oldRect.right()); + + if (oldRect.bottom() > newRect.bottom()) + result.setBottom(oldRect.bottom()); + + return result; +} + + +void SubcomponentMaskLayerItem::setCurrentItem(QGraphicsItem *item) +{ + QGraphicsItem *prevItem = m_currentItem; + m_currentItem = item; + + if (!m_currentItem) + return; + + QPolygonF viewPoly(QRectF(m_observer->declarativeView()->rect())); + viewPoly = m_observer->declarativeView()->mapToScene(viewPoly.toPolygon()); + + QRectF itemRect = item->boundingRect() | item->childrenBoundingRect(); + QPolygonF itemPoly(itemRect); + itemPoly = item->mapToScene(itemPoly); + + // if updating the same item as before, resize the rectangle only bigger, not smaller. + if (prevItem == item && prevItem != 0) { + m_itemPolyRect = resizeRect(itemPoly.boundingRect(), m_itemPolyRect); + } else { + m_itemPolyRect = itemPoly.boundingRect(); + } + QRectF borderRect = m_itemPolyRect; + borderRect.adjust(-1, -1, 1, 1); + m_borderRect->setRect(borderRect); + + itemPoly = viewPoly.subtracted(QPolygonF(m_itemPolyRect)); + setPolygon(itemPoly); +} + +QGraphicsItem *SubcomponentMaskLayerItem::currentItem() const +{ + return m_currentItem; +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem_p.h b/src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem_p.h new file mode 100644 index 0000000..e0b892d --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/subcomponentmasklayeritem_p.h @@ -0,0 +1,77 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 SUBCOMPONENTMASKLAYERITEM_H +#define SUBCOMPONENTMASKLAYERITEM_H + +#include <QtGui/QGraphicsPolygonItem> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeViewObserver; + +class SubcomponentMaskLayerItem : public QGraphicsPolygonItem +{ +public: + explicit SubcomponentMaskLayerItem(QDeclarativeViewObserver *observer, + QGraphicsItem *parentItem = 0); + int type() const; + void setCurrentItem(QGraphicsItem *item); + void setBoundingBox(const QRectF &boundingBox); + QGraphicsItem *currentItem() const; + QRectF itemRect() const; + +private: + QDeclarativeViewObserver *m_observer; + QGraphicsItem *m_currentItem; + QGraphicsRectItem *m_borderRect; + QRectF m_itemPolyRect; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // SUBCOMPONENTMASKLAYERITEM_H diff --git a/src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox.cpp b/src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox.cpp new file mode 100644 index 0000000..35582fb --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox.cpp @@ -0,0 +1,134 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "toolbarcolorbox_p.h" + +#include "../qmlobserverconstants_p.h" + +#include <QtGui/QPixmap> +#include <QtGui/QPainter> +#include <QtGui/QMenu> +#include <QtGui/QAction> +#include <QtGui/QContextMenuEvent> +#include <QtGui/QClipboard> +#include <QtGui/QApplication> +#include <QtGui/QColorDialog> +#include <QtGui/QDrag> + +#include <QtCore/QMimeData> +#include <QtCore/QDebug> + +QT_BEGIN_NAMESPACE + +ToolBarColorBox::ToolBarColorBox(QWidget *parent) : + QLabel(parent) +{ + m_copyHexColor = new QAction(QIcon(QLatin1String(":/qml/images/color-picker-hicontrast.png")), + tr("Copy Color"), this); + connect(m_copyHexColor, SIGNAL(triggered()), SLOT(copyColorToClipboard())); + setScaledContents(false); +} + +void ToolBarColorBox::setColor(const QColor &color) +{ + m_color = color; + + QPixmap pix = createDragPixmap(width()); + setPixmap(pix); + update(); +} + +void ToolBarColorBox::mousePressEvent(QMouseEvent *event) +{ + m_dragBeginPoint = event->pos(); + m_dragStarted = false; +} + +void ToolBarColorBox::mouseMoveEvent(QMouseEvent *event) +{ + + if (event->buttons() & Qt::LeftButton + && (QPoint(event->pos() - m_dragBeginPoint).manhattanLength() + > Constants::DragStartDistance) + && !m_dragStarted) + { + m_dragStarted = true; + QDrag *drag = new QDrag(this); + QMimeData *mimeData = new QMimeData; + + mimeData->setText(m_color.name()); + drag->setMimeData(mimeData); + drag->setPixmap(createDragPixmap()); + + drag->exec(); + } +} + +QPixmap ToolBarColorBox::createDragPixmap(int size) const +{ + QPixmap pix(size, size); + QPainter p(&pix); + + QColor borderColor1 = QColor(143, 143 ,143); + QColor borderColor2 = QColor(43, 43, 43); + + p.setBrush(QBrush(m_color)); + p.setPen(QPen(QBrush(borderColor2),1)); + + p.fillRect(0, 0, size, size, borderColor1); + p.drawRect(1,1, size - 3, size - 3); + return pix; +} + +void ToolBarColorBox::contextMenuEvent(QContextMenuEvent *ev) +{ + QMenu contextMenu; + contextMenu.addAction(m_copyHexColor); + contextMenu.exec(ev->globalPos()); +} + +void ToolBarColorBox::copyColorToClipboard() +{ + QClipboard *clipboard = QApplication::clipboard(); + clipboard->setText(m_color.name()); +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox_p.h b/src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox_p.h new file mode 100644 index 0000000..d4914fa --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/toolbarcolorbox_p.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 TOOLBARCOLORBOX_H +#define TOOLBARCOLORBOX_H + +#include <QtGui/QLabel> +#include <QtGui/QColor> +#include <QtCore/QPoint> + +QT_FORWARD_DECLARE_CLASS(QContextMenuEvent) +QT_FORWARD_DECLARE_CLASS(QAction) + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class ToolBarColorBox : public QLabel +{ + Q_OBJECT + +public: + explicit ToolBarColorBox(QWidget *parent = 0); + void setColor(const QColor &color); + +protected: + void contextMenuEvent(QContextMenuEvent *ev); + void mousePressEvent(QMouseEvent *ev); + void mouseMoveEvent(QMouseEvent *ev); +private slots: + void copyColorToClipboard(); + +private: + QPixmap createDragPixmap(int size = 24) const; + +private: + bool m_dragStarted; + QPoint m_dragBeginPoint; + QAction *m_copyHexColor; + QColor m_color; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // TOOLBARCOLORBOX_H diff --git a/src/plugins/qmltooling/declarativeobserver/editor/zoomtool.cpp b/src/plugins/qmltooling/declarativeobserver/editor/zoomtool.cpp new file mode 100644 index 0000000..b70cda5 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/zoomtool.cpp @@ -0,0 +1,336 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "zoomtool_p.h" + +#include "../qdeclarativeviewobserver_p_p.h" + +#include <QtGui/QMouseEvent> +#include <QtGui/QWheelEvent> +#include <QtGui/QKeyEvent> +#include <QtGui/QMenu> +#include <QtGui/QAction> + +#include <QtCore/QRectF> +#include <QtCore/QDebug> + +QT_BEGIN_NAMESPACE + +ZoomTool::ZoomTool(QDeclarativeViewObserver *view) : + AbstractLiveEditTool(view), + m_rubberbandManipulator(), + m_smoothZoomMultiplier(0.05f), + m_currentScale(1.0f) +{ + m_zoomTo100Action = new QAction(tr("Zoom to &100%"), this); + m_zoomInAction = new QAction(tr("Zoom In"), this); + m_zoomOutAction = new QAction(tr("Zoom Out"), this); + m_zoomInAction->setShortcut(QKeySequence(Qt::Key_Plus)); + m_zoomOutAction->setShortcut(QKeySequence(Qt::Key_Minus)); + + + LiveLayerItem *layerItem = QDeclarativeViewObserverPrivate::get(view)->manipulatorLayer; + QGraphicsObject *layerObject = reinterpret_cast<QGraphicsObject *>(layerItem); + m_rubberbandManipulator = new LiveRubberBandSelectionManipulator(layerObject, view); + + + connect(m_zoomTo100Action, SIGNAL(triggered()), SLOT(zoomTo100())); + connect(m_zoomInAction, SIGNAL(triggered()), SLOT(zoomIn())); + connect(m_zoomOutAction, SIGNAL(triggered()), SLOT(zoomOut())); +} + +ZoomTool::~ZoomTool() +{ + delete m_rubberbandManipulator; +} + +void ZoomTool::mousePressEvent(QMouseEvent *event) +{ + m_mousePos = event->pos(); + + QPointF scenePos = view()->mapToScene(event->pos()); + + if (event->buttons() & Qt::RightButton) { + QMenu contextMenu; + contextMenu.addAction(m_zoomTo100Action); + contextMenu.addSeparator(); + contextMenu.addAction(m_zoomInAction); + contextMenu.addAction(m_zoomOutAction); + contextMenu.exec(event->globalPos()); + } else if (event->buttons() & Qt::LeftButton) { + m_dragBeginPos = scenePos; + m_dragStarted = false; + } +} + +void ZoomTool::mouseMoveEvent(QMouseEvent *event) +{ + m_mousePos = event->pos(); + + QPointF scenePos = view()->mapToScene(event->pos()); + + if (event->buttons() & Qt::LeftButton + && (QPointF(scenePos - m_dragBeginPos).manhattanLength() + > Constants::DragStartDistance / 3) + && !m_dragStarted) + { + m_dragStarted = true; + m_rubberbandManipulator->begin(m_dragBeginPos); + return; + } + + if (m_dragStarted) + m_rubberbandManipulator->update(scenePos); + +} + +void ZoomTool::mouseReleaseEvent(QMouseEvent *event) +{ + m_mousePos = event->pos(); + QPointF scenePos = view()->mapToScene(event->pos()); + + if (m_dragStarted) { + m_rubberbandManipulator->end(); + + int x1 = qMin(scenePos.x(), m_rubberbandManipulator->beginPoint().x()); + int x2 = qMax(scenePos.x(), m_rubberbandManipulator->beginPoint().x()); + int y1 = qMin(scenePos.y(), m_rubberbandManipulator->beginPoint().y()); + int y2 = qMax(scenePos.y(), m_rubberbandManipulator->beginPoint().y()); + + QPointF scenePosTopLeft = QPoint(x1, y1); + QPointF scenePosBottomRight = QPoint(x2, y2); + + QRectF sceneArea(scenePosTopLeft, scenePosBottomRight); + + m_currentScale = qMin(view()->rect().width() / sceneArea.width(), + view()->rect().height() / sceneArea.height()); + + + QTransform transform; + transform.scale(m_currentScale, m_currentScale); + + view()->setTransform(transform); + view()->setSceneRect(sceneArea); + } else { + Qt::KeyboardModifier modifierKey = Qt::ControlModifier; +#ifdef Q_WS_MAC + modifierKey = Qt::AltModifier; +#endif + if (event->modifiers() & modifierKey) { + zoomOut(); + } else { + zoomIn(); + } + } +} + +void ZoomTool::zoomIn() +{ + m_currentScale = nextZoomScale(ZoomIn); + scaleView(view()->mapToScene(m_mousePos)); +} + +void ZoomTool::zoomOut() +{ + m_currentScale = nextZoomScale(ZoomOut); + scaleView(view()->mapToScene(m_mousePos)); +} + +void ZoomTool::mouseDoubleClickEvent(QMouseEvent *event) +{ + m_mousePos = event->pos(); +} + + +void ZoomTool::hoverMoveEvent(QMouseEvent *event) +{ + m_mousePos = event->pos(); +} + + +void ZoomTool::keyPressEvent(QKeyEvent * /*event*/) +{ +} + +void ZoomTool::wheelEvent(QWheelEvent *event) +{ + if (event->orientation() != Qt::Vertical) + return; + + Qt::KeyboardModifier smoothZoomModifier = Qt::ControlModifier; + if (event->modifiers() & smoothZoomModifier) { + int numDegrees = event->delta() / 8; + m_currentScale += m_smoothZoomMultiplier * (numDegrees / 15.0f); + + scaleView(view()->mapToScene(m_mousePos)); + + } else if (!event->modifiers()) { + if (event->delta() > 0) { + m_currentScale = nextZoomScale(ZoomIn); + } else if (event->delta() < 0) { + m_currentScale = nextZoomScale(ZoomOut); + } + scaleView(view()->mapToScene(m_mousePos)); + } +} + +void ZoomTool::keyReleaseEvent(QKeyEvent *event) +{ + switch (event->key()) { + case Qt::Key_Plus: + zoomIn(); + break; + case Qt::Key_Minus: + zoomOut(); + break; + case Qt::Key_1: + case Qt::Key_2: + case Qt::Key_3: + case Qt::Key_4: + case Qt::Key_5: + case Qt::Key_6: + case Qt::Key_7: + case Qt::Key_8: + case Qt::Key_9: + { + m_currentScale = ((event->key() - Qt::Key_0) * 1.0f); + scaleView(view()->mapToScene(m_mousePos)); // view()->mapToScene(view()->rect().center()) + break; + } + + default: + break; + } + +} + +void ZoomTool::itemsAboutToRemoved(const QList<QGraphicsItem*> &/*itemList*/) +{ +} + +void ZoomTool::clear() +{ + view()->setCursor(Qt::ArrowCursor); +} + +void ZoomTool::selectedItemsChanged(const QList<QGraphicsItem*> &/*itemList*/) +{ +} + +void ZoomTool::scaleView(const QPointF ¢erPos) +{ + + QTransform transform; + transform.scale(m_currentScale, m_currentScale); + view()->setTransform(transform); + + QPointF adjustedCenterPos = centerPos; + QSize rectSize(view()->rect().width() / m_currentScale, + view()->rect().height() / m_currentScale); + + QRectF sceneRect; + if (qAbs(m_currentScale - 1.0f) < Constants::ZoomSnapDelta) { + adjustedCenterPos.rx() = rectSize.width() / 2; + adjustedCenterPos.ry() = rectSize.height() / 2; + } + + if (m_currentScale < 1.0f) { + adjustedCenterPos.rx() = rectSize.width() / 2; + adjustedCenterPos.ry() = rectSize.height() / 2; + sceneRect.setRect(view()->rect().width() / 2 -rectSize.width() / 2, + view()->rect().height() / 2 -rectSize.height() / 2, + rectSize.width(), + rectSize.height()); + } else { + sceneRect.setRect(adjustedCenterPos.x() - rectSize.width() / 2, + adjustedCenterPos.y() - rectSize.height() / 2, + rectSize.width(), + rectSize.height()); + } + + view()->setSceneRect(sceneRect); +} + +void ZoomTool::zoomTo100() +{ + m_currentScale = 1.0f; + scaleView(view()->mapToScene(view()->rect().center())); +} + +qreal ZoomTool::nextZoomScale(ZoomDirection direction) const +{ + static QList<qreal> zoomScales = + QList<qreal>() + << 0.125f + << 1.0f / 6.0f + << 0.25f + << 1.0f / 3.0f + << 0.5f + << 2.0f / 3.0f + << 1.0f + << 2.0f + << 3.0f + << 4.0f + << 5.0f + << 6.0f + << 7.0f + << 8.0f + << 12.0f + << 16.0f + << 32.0f + << 48.0f; + + if (direction == ZoomIn) { + for (int i = 0; i < zoomScales.length(); ++i) { + if (zoomScales[i] > m_currentScale || i == zoomScales.length() - 1) + return zoomScales[i]; + } + } else { + for (int i = zoomScales.length() - 1; i >= 0; --i) { + if (zoomScales[i] < m_currentScale || i == 0) + return zoomScales[i]; + } + } + + return 1.0f; +} + +QT_END_NAMESPACE diff --git a/src/plugins/qmltooling/declarativeobserver/editor/zoomtool_p.h b/src/plugins/qmltooling/declarativeobserver/editor/zoomtool_p.h new file mode 100644 index 0000000..6734cf9 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/editor/zoomtool_p.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 ZOOMTOOL_H +#define ZOOMTOOL_H + +#include "abstractliveedittool_p.h" +#include "liverubberbandselectionmanipulator_p.h" + +QT_FORWARD_DECLARE_CLASS(QAction) + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class ZoomTool : public AbstractLiveEditTool +{ + Q_OBJECT + +public: + enum ZoomDirection { + ZoomIn, + ZoomOut + }; + + explicit ZoomTool(QDeclarativeViewObserver *view); + + virtual ~ZoomTool(); + + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void mouseDoubleClickEvent(QMouseEvent *event); + + void hoverMoveEvent(QMouseEvent *event); + void wheelEvent(QWheelEvent *event); + + void keyPressEvent(QKeyEvent *event); + void keyReleaseEvent(QKeyEvent *keyEvent); + void itemsAboutToRemoved(const QList<QGraphicsItem*> &itemList); + + void clear(); + +protected: + void selectedItemsChanged(const QList<QGraphicsItem*> &itemList); + +private slots: + void zoomTo100(); + void zoomIn(); + void zoomOut(); + +private: + qreal nextZoomScale(ZoomDirection direction) const; + void scaleView(const QPointF ¢erPos); + +private: + bool m_dragStarted; + QPoint m_mousePos; // in view coords + QPointF m_dragBeginPos; + QAction *m_zoomTo100Action; + QAction *m_zoomInAction; + QAction *m_zoomOutAction; + LiveRubberBandSelectionManipulator *m_rubberbandManipulator; + + qreal m_smoothZoomMultiplier; + qreal m_currentScale; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // ZOOMTOOL_H diff --git a/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.cpp b/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.cpp new file mode 100644 index 0000000..458b7ef --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "qdeclarativeobserverplugin.h" + +#include "qdeclarativeviewobserver_p.h" + +#include <QtCore/qplugin.h> +#include <QtDeclarative/private/qdeclarativeobserverservice_p.h> + +QT_BEGIN_NAMESPACE + +QDeclarativeObserverPlugin::QDeclarativeObserverPlugin() : + m_observer(0) +{ +} + +QDeclarativeObserverPlugin::~QDeclarativeObserverPlugin() +{ + delete m_observer; +} + +void QDeclarativeObserverPlugin::activate() +{ + QDeclarativeObserverService *service = QDeclarativeObserverService::instance(); + QList<QDeclarativeView*> views = service->views(); + if (views.isEmpty()) + return; + + // TODO: Support multiple views + QDeclarativeView *view = service->views().at(0); + m_observer = new QDeclarativeViewObserver(view, view); +} + +void QDeclarativeObserverPlugin::deactivate() +{ + delete m_observer; +} + +Q_EXPORT_PLUGIN2(declarativeobserver, QDeclarativeObserverPlugin) + +QT_END_NAMESPACE + diff --git a/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.h b/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.h new file mode 100644 index 0000000..82d3dbc --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverplugin.h @@ -0,0 +1,71 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 QDECLARATIVEOBSERVERPLUGIN_H +#define QDECLARATIVEOBSERVERPLUGIN_H + +#include <QtCore/QPointer> +#include <QtDeclarative/private/qdeclarativeobserverinterface_p.h> + +QT_BEGIN_NAMESPACE + +class QDeclarativeViewObserver; + +class QDeclarativeObserverPlugin : public QObject, public QDeclarativeObserverInterface +{ + Q_OBJECT + Q_DISABLE_COPY(QDeclarativeObserverPlugin) + Q_INTERFACES(QDeclarativeObserverInterface) + +public: + QDeclarativeObserverPlugin(); + ~QDeclarativeObserverPlugin(); + + void activate(); + void deactivate(); + +private: + QPointer<QDeclarativeViewObserver> m_observer; +}; + +QT_END_NAMESPACE + +#endif // QDECLARATIVEOBSERVERPLUGIN_H diff --git a/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverprotocol.h b/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverprotocol.h new file mode 100644 index 0000000..eb46693 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/qdeclarativeobserverprotocol.h @@ -0,0 +1,145 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 QDECLARATIVEOBSERVERPROTOCOL_H +#define QDECLARATIVEOBSERVERPROTOCOL_H + +#include <QtCore/QDebug> +#include <QtCore/QMetaType> +#include <QtCore/QMetaEnum> +#include <QtCore/QObject> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class ObserverProtocol : public QObject +{ + Q_OBJECT + Q_ENUMS(Message Tool) + +public: + enum Message { + AnimationSpeedChanged = 0, + AnimationPausedChanged = 19, // highest value + ChangeTool = 1, + ClearComponentCache = 2, + ColorChanged = 3, + ContextPathUpdated = 4, + CreateObject = 5, + CurrentObjectsChanged = 6, + DestroyObject = 7, + MoveObject = 8, + ObjectIdList = 9, + Reload = 10, + Reloaded = 11, + SetAnimationSpeed = 12, + SetAnimationPaused = 18, + SetContextPathIdx = 13, + SetCurrentObjects = 14, + SetDesignMode = 15, + ShowAppOnTop = 16, + ToolChanged = 17 + }; + + enum Tool { + ColorPickerTool, + SelectMarqueeTool, + SelectTool, + ZoomTool + }; + + static inline QString toString(Message message) + { + return QLatin1String(staticMetaObject.enumerator(0).valueToKey(message)); + } + + static inline QString toString(Tool tool) + { + return QLatin1String(staticMetaObject.enumerator(1).valueToKey(tool)); + } +}; + +inline QDataStream & operator<< (QDataStream &stream, ObserverProtocol::Message message) +{ + return stream << static_cast<quint32>(message); +} + +inline QDataStream & operator>> (QDataStream &stream, ObserverProtocol::Message &message) +{ + quint32 i; + stream >> i; + message = static_cast<ObserverProtocol::Message>(i); + return stream; +} + +inline QDebug operator<< (QDebug dbg, ObserverProtocol::Message message) +{ + dbg << ObserverProtocol::toString(message); + return dbg; +} + +inline QDataStream & operator<< (QDataStream &stream, ObserverProtocol::Tool tool) +{ + return stream << static_cast<quint32>(tool); +} + +inline QDataStream & operator>> (QDataStream &stream, ObserverProtocol::Tool &tool) +{ + quint32 i; + stream >> i; + tool = static_cast<ObserverProtocol::Tool>(i); + return stream; +} + +inline QDebug operator<< (QDebug dbg, ObserverProtocol::Tool tool) +{ + dbg << ObserverProtocol::toString(tool); + return dbg; +} + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QDECLARATIVEOBSERVERPROTOCOL_H diff --git a/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver.cpp b/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver.cpp new file mode 100644 index 0000000..2286990 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver.cpp @@ -0,0 +1,1167 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 "QtDeclarative/private/qdeclarativeobserverservice_p.h" +#include "QtDeclarative/private/qdeclarativedebughelper_p.h" + +#include "qdeclarativeviewobserver_p.h" +#include "qdeclarativeviewobserver_p_p.h" +#include "qdeclarativeobserverprotocol.h" + +#include "editor/liveselectiontool_p.h" +#include "editor/zoomtool_p.h" +#include "editor/colorpickertool_p.h" +#include "editor/livelayeritem_p.h" +#include "editor/boundingrecthighlighter_p.h" +#include "editor/subcomponenteditortool_p.h" +#include "editor/qmltoolbar_p.h" + +#include <QtDeclarative/QDeclarativeItem> +#include <QtDeclarative/QDeclarativeEngine> +#include <QtDeclarative/QDeclarativeContext> +#include <QtDeclarative/QDeclarativeExpression> +#include <QtGui/QWidget> +#include <QtGui/QVBoxLayout> +#include <QtGui/QMouseEvent> +#include <QtGui/QGraphicsObject> +#include <QtGui/QApplication> +#include <QtCore/QSettings> + +static inline void initEditorResource() { Q_INIT_RESOURCE(editor); } + +QT_BEGIN_NAMESPACE + +const char * const KEY_TOOLBOX_GEOMETRY = "toolBox/geometry"; + +const int SceneChangeUpdateInterval = 5000; + + +class ToolBox : public QWidget +{ + Q_OBJECT + +public: + ToolBox(QWidget *parent = 0); + ~ToolBox(); + + QmlToolBar *toolBar() const { return m_toolBar; } + +private: + QSettings m_settings; + QmlToolBar *m_toolBar; +}; + +ToolBox::ToolBox(QWidget *parent) + : QWidget(parent, Qt::Tool) + , m_settings(QLatin1String("Nokia"), QLatin1String("QmlObserver"), this) + , m_toolBar(new QmlToolBar) +{ + setWindowFlags((windowFlags() & ~Qt::WindowCloseButtonHint) | Qt::CustomizeWindowHint); + setWindowTitle(tr("Qt Quick Toolbox")); + + QVBoxLayout *verticalLayout = new QVBoxLayout; + verticalLayout->setMargin(0); + verticalLayout->addWidget(m_toolBar); + setLayout(verticalLayout); + + restoreGeometry(m_settings.value(QLatin1String(KEY_TOOLBOX_GEOMETRY)).toByteArray()); +} + +ToolBox::~ToolBox() +{ + m_settings.setValue(QLatin1String(KEY_TOOLBOX_GEOMETRY), saveGeometry()); +} + + +QDeclarativeViewObserverPrivate::QDeclarativeViewObserverPrivate(QDeclarativeViewObserver *q) : + q(q), + designModeBehavior(false), + showAppOnTop(false), + animationPaused(false), + slowDownFactor(1.0f), + toolBox(0) +{ +} + +QDeclarativeViewObserverPrivate::~QDeclarativeViewObserverPrivate() +{ +} + +QDeclarativeViewObserver::QDeclarativeViewObserver(QDeclarativeView *view, + QObject *parent) : + QObject(parent), + data(new QDeclarativeViewObserverPrivate(this)) +{ + initEditorResource(); + + data->view = view; + data->manipulatorLayer = new LiveLayerItem(view->scene()); + data->selectionTool = new LiveSelectionTool(this); + data->zoomTool = new ZoomTool(this); + data->colorPickerTool = new ColorPickerTool(this); + data->boundingRectHighlighter = new BoundingRectHighlighter(this); + data->subcomponentEditorTool = new SubcomponentEditorTool(this); + data->currentTool = data->selectionTool; + + // to capture ChildRemoved event when viewport changes + data->view->installEventFilter(this); + + data->setViewport(data->view->viewport()); + + data->debugService = QDeclarativeObserverService::instance(); + connect(data->debugService, SIGNAL(gotMessage(QByteArray)), + this, SLOT(handleMessage(QByteArray))); + + connect(data->view, SIGNAL(statusChanged(QDeclarativeView::Status)), + data.data(), SLOT(_q_onStatusChanged(QDeclarativeView::Status))); + + connect(data->colorPickerTool, SIGNAL(selectedColorChanged(QColor)), + SIGNAL(selectedColorChanged(QColor))); + connect(data->colorPickerTool, SIGNAL(selectedColorChanged(QColor)), + this, SLOT(sendColorChanged(QColor))); + + connect(data->subcomponentEditorTool, SIGNAL(cleared()), SIGNAL(inspectorContextCleared())); + connect(data->subcomponentEditorTool, SIGNAL(contextPushed(QString)), + SIGNAL(inspectorContextPushed(QString))); + connect(data->subcomponentEditorTool, SIGNAL(contextPopped()), + SIGNAL(inspectorContextPopped())); + connect(data->subcomponentEditorTool, SIGNAL(contextPathChanged(QStringList)), + this, SLOT(sendContextPathUpdated(QStringList))); + + data->_q_changeToSingleSelectTool(); +} + +QDeclarativeViewObserver::~QDeclarativeViewObserver() +{ +} + +void QDeclarativeViewObserver::setObserverContext(int contextIndex) +{ + if (data->subcomponentEditorTool->contextIndex() != contextIndex) { + QGraphicsObject *object = data->subcomponentEditorTool->setContext(contextIndex); + if (object) + setSelectedItems(QList<QGraphicsItem*>() << object); + } +} + +void QDeclarativeViewObserverPrivate::_q_setToolBoxVisible(bool visible) +{ +#if !defined(Q_OS_SYMBIAN) && !defined(Q_WS_MAEMO_5) && !defined(Q_WS_SIMULATOR) + if (!toolBox && visible) + createToolBox(); + if (toolBox) + toolBox->setVisible(visible); +#else + Q_UNUSED(visible) +#endif +} + +void QDeclarativeViewObserverPrivate::_q_reloadView() +{ + subcomponentEditorTool->clear(); + clearHighlight(); + emit q->reloadRequested(); +} + +void QDeclarativeViewObserverPrivate::setViewport(QWidget *widget) +{ + if (viewport.data() == widget) + return; + + if (viewport) + viewport.data()->removeEventFilter(q); + + viewport = widget; + if (viewport) { + // make sure we get mouse move events + viewport.data()->setMouseTracking(true); + viewport.data()->installEventFilter(q); + } +} + +void QDeclarativeViewObserverPrivate::clearEditorItems() +{ + clearHighlight(); + setSelectedItems(QList<QGraphicsItem*>()); +} + +bool QDeclarativeViewObserver::eventFilter(QObject *obj, QEvent *event) +{ + if (obj == data->view) { + // Event from view + if (event->type() == QEvent::ChildRemoved) { + // Might mean that viewport has changed + if (data->view->viewport() != data->viewport.data()) + data->setViewport(data->view->viewport()); + } + return QObject::eventFilter(obj, event); + } + + // Event from viewport + switch (event->type()) { + case QEvent::Leave: { + if (leaveEvent(event)) + return true; + break; + } + case QEvent::MouseButtonPress: { + if (mousePressEvent(static_cast<QMouseEvent*>(event))) + return true; + break; + } + case QEvent::MouseMove: { + if (mouseMoveEvent(static_cast<QMouseEvent*>(event))) + return true; + break; + } + case QEvent::MouseButtonRelease: { + if (mouseReleaseEvent(static_cast<QMouseEvent*>(event))) + return true; + break; + } + case QEvent::KeyPress: { + if (keyPressEvent(static_cast<QKeyEvent*>(event))) + return true; + break; + } + case QEvent::KeyRelease: { + if (keyReleaseEvent(static_cast<QKeyEvent*>(event))) + return true; + break; + } + case QEvent::MouseButtonDblClick: { + if (mouseDoubleClickEvent(static_cast<QMouseEvent*>(event))) + return true; + break; + } + case QEvent::Wheel: { + if (wheelEvent(static_cast<QWheelEvent*>(event))) + return true; + break; + } + default: { + break; + } + } //switch + + // standard event processing + return QObject::eventFilter(obj, event); +} + +bool QDeclarativeViewObserver::leaveEvent(QEvent * /*event*/) +{ + if (!data->designModeBehavior) + return false; + data->clearHighlight(); + return true; +} + +bool QDeclarativeViewObserver::mousePressEvent(QMouseEvent *event) +{ + if (!data->designModeBehavior) + return false; + data->cursorPos = event->pos(); + data->currentTool->mousePressEvent(event); + return true; +} + +bool QDeclarativeViewObserver::mouseMoveEvent(QMouseEvent *event) +{ + if (!data->designModeBehavior) { + data->clearEditorItems(); + return false; + } + data->cursorPos = event->pos(); + + QList<QGraphicsItem*> selItems = data->selectableItems(event->pos()); + if (!selItems.isEmpty()) { + declarativeView()->setToolTip(data->currentTool->titleForItem(selItems.first())); + } else { + declarativeView()->setToolTip(QString()); + } + if (event->buttons()) { + data->subcomponentEditorTool->mouseMoveEvent(event); + data->currentTool->mouseMoveEvent(event); + } else { + data->subcomponentEditorTool->hoverMoveEvent(event); + data->currentTool->hoverMoveEvent(event); + } + return true; +} + +bool QDeclarativeViewObserver::mouseReleaseEvent(QMouseEvent *event) +{ + if (!data->designModeBehavior) + return false; + data->subcomponentEditorTool->mouseReleaseEvent(event); + + data->cursorPos = event->pos(); + data->currentTool->mouseReleaseEvent(event); + return true; +} + +bool QDeclarativeViewObserver::keyPressEvent(QKeyEvent *event) +{ + if (!data->designModeBehavior) + return false; + + data->currentTool->keyPressEvent(event); + return true; +} + +bool QDeclarativeViewObserver::keyReleaseEvent(QKeyEvent *event) +{ + if (!data->designModeBehavior) + return false; + + switch (event->key()) { + case Qt::Key_V: + data->_q_changeToSingleSelectTool(); + break; +// disabled because multiselection does not do anything useful without design mode +// case Qt::Key_M: +// data->_q_changeToMarqueeSelectTool(); +// break; + case Qt::Key_I: + data->_q_changeToColorPickerTool(); + break; + case Qt::Key_Z: + data->_q_changeToZoomTool(); + break; + case Qt::Key_Enter: + case Qt::Key_Return: + if (!data->selectedItems().isEmpty()) + data->subcomponentEditorTool->setCurrentItem(data->selectedItems().first()); + break; + case Qt::Key_Space: + setAnimationPaused(!data->animationPaused); + break; + default: + break; + } + + data->currentTool->keyReleaseEvent(event); + return true; +} + +void QDeclarativeViewObserverPrivate::_q_createQmlObject(const QString &qml, QObject *parent, + const QStringList &importList, + const QString &filename) +{ + if (!parent) + return; + + QString imports; + foreach (const QString &s, importList) { + imports += s; + imports += QLatin1Char('\n'); + } + + QDeclarativeContext *parentContext = view->engine()->contextForObject(parent); + QDeclarativeComponent component(view->engine(), q); + QByteArray constructedQml = QString(imports + qml).toLatin1(); + + component.setData(constructedQml, QUrl::fromLocalFile(filename)); + QObject *newObject = component.create(parentContext); + if (newObject) { + newObject->setParent(parent); + QDeclarativeItem *parentItem = qobject_cast<QDeclarativeItem*>(parent); + QDeclarativeItem *newItem = qobject_cast<QDeclarativeItem*>(newObject); + if (parentItem && newItem) + newItem->setParentItem(parentItem); + } +} + +void QDeclarativeViewObserverPrivate::_q_reparentQmlObject(QObject *object, QObject *newParent) +{ + if (!newParent) + return; + + object->setParent(newParent); + QDeclarativeItem *newParentItem = qobject_cast<QDeclarativeItem*>(newParent); + QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(object); + if (newParentItem && item) + item->setParentItem(newParentItem); +} + +void QDeclarativeViewObserverPrivate::_q_clearComponentCache() +{ + view->engine()->clearComponentCache(); +} + +void QDeclarativeViewObserverPrivate::_q_removeFromSelection(QObject *obj) +{ + QList<QGraphicsItem*> items = selectedItems(); + if (QGraphicsItem *item = qobject_cast<QGraphicsObject*>(obj)) + items.removeOne(item); + setSelectedItems(items); +} + +QGraphicsItem *QDeclarativeViewObserverPrivate::currentRootItem() const +{ + return subcomponentEditorTool->currentRootItem(); +} + +bool QDeclarativeViewObserver::mouseDoubleClickEvent(QMouseEvent *event) +{ + if (!data->designModeBehavior) + return false; + + if (data->currentToolMode != Constants::SelectionToolMode + && data->currentToolMode != Constants::MarqueeSelectionToolMode) + return true; + + QGraphicsItem *itemToEnter = 0; + QList<QGraphicsItem*> itemList = data->view->items(event->pos()); + data->filterForSelection(itemList); + + if (data->selectedItems().isEmpty() && !itemList.isEmpty()) { + itemToEnter = itemList.first(); + } else if (!data->selectedItems().isEmpty() && !itemList.isEmpty()) { + itemToEnter = itemList.first(); + } + + if (itemToEnter) + itemToEnter = data->subcomponentEditorTool->firstChildOfContext(itemToEnter); + + data->subcomponentEditorTool->setCurrentItem(itemToEnter); + data->subcomponentEditorTool->mouseDoubleClickEvent(event); + + if ((event->buttons() & Qt::LeftButton) && itemToEnter) { + if (QGraphicsObject *objectToEnter = itemToEnter->toGraphicsObject()) + setSelectedItems(QList<QGraphicsItem*>() << objectToEnter); + } + + return true; +} + +bool QDeclarativeViewObserver::wheelEvent(QWheelEvent *event) +{ + if (!data->designModeBehavior) + return false; + data->currentTool->wheelEvent(event); + return true; +} + +void QDeclarativeViewObserverPrivate::enterContext(QGraphicsItem *itemToEnter) +{ + QGraphicsItem *itemUnderCurrentContext = itemToEnter; + if (itemUnderCurrentContext) + itemUnderCurrentContext = subcomponentEditorTool->firstChildOfContext(itemToEnter); + + if (itemUnderCurrentContext) + subcomponentEditorTool->setCurrentItem(itemToEnter); +} + +void QDeclarativeViewObserver::setDesignModeBehavior(bool value) +{ + emit designModeBehaviorChanged(value); + + if (data->toolBox) + data->toolBox->toolBar()->setDesignModeBehavior(value); + sendDesignModeBehavior(value); + + data->designModeBehavior = value; + if (data->subcomponentEditorTool) { + data->subcomponentEditorTool->clear(); + data->clearHighlight(); + data->setSelectedItems(QList<QGraphicsItem*>()); + + if (data->view->rootObject()) + data->subcomponentEditorTool->pushContext(data->view->rootObject()); + } + + if (!data->designModeBehavior) + data->clearEditorItems(); +} + +bool QDeclarativeViewObserver::designModeBehavior() +{ + return data->designModeBehavior; +} + +bool QDeclarativeViewObserver::showAppOnTop() const +{ + return data->showAppOnTop; +} + +void QDeclarativeViewObserver::setShowAppOnTop(bool appOnTop) +{ + if (data->view) { + QWidget *window = data->view->window(); + Qt::WindowFlags flags = window->windowFlags(); + if (appOnTop) + flags |= Qt::WindowStaysOnTopHint; + else + flags &= ~Qt::WindowStaysOnTopHint; + + window->setWindowFlags(flags); + window->show(); + } + + data->showAppOnTop = appOnTop; + sendShowAppOnTop(appOnTop); + + emit showAppOnTopChanged(appOnTop); +} + +void QDeclarativeViewObserverPrivate::changeTool(Constants::DesignTool tool, + Constants::ToolFlags /*flags*/) +{ + switch (tool) { + case Constants::SelectionToolMode: + _q_changeToSingleSelectTool(); + break; + case Constants::NoTool: + default: + currentTool = 0; + break; + } +} + +void QDeclarativeViewObserverPrivate::setSelectedItemsForTools(QList<QGraphicsItem *> items) +{ + foreach (const QWeakPointer<QGraphicsObject> &obj, currentSelection) { + if (QGraphicsItem *item = obj.data()) { + if (!items.contains(item)) { + QObject::disconnect(obj.data(), SIGNAL(destroyed(QObject*)), + this, SLOT(_q_removeFromSelection(QObject*))); + currentSelection.removeOne(obj); + } + } + } + + foreach (QGraphicsItem *item, items) { + if (item) { + if (QGraphicsObject *obj = item->toGraphicsObject()) { + QObject::connect(obj, SIGNAL(destroyed(QObject*)), + this, SLOT(_q_removeFromSelection(QObject*))); + currentSelection.append(obj); + } + } + } + + currentTool->updateSelectedItems(); +} + +void QDeclarativeViewObserverPrivate::setSelectedItems(QList<QGraphicsItem *> items) +{ + QList<QWeakPointer<QGraphicsObject> > oldList = currentSelection; + setSelectedItemsForTools(items); + if (oldList != currentSelection) { + QList<QObject*> objectList; + foreach (const QWeakPointer<QGraphicsObject> &graphicsObject, currentSelection) { + if (graphicsObject) + objectList << graphicsObject.data(); + } + + q->sendCurrentObjects(objectList); + } +} + +QList<QGraphicsItem *> QDeclarativeViewObserverPrivate::selectedItems() const +{ + QList<QGraphicsItem *> selection; + foreach (const QWeakPointer<QGraphicsObject> &selectedObject, currentSelection) { + if (selectedObject.data()) + selection << selectedObject.data(); + } + + return selection; +} + +void QDeclarativeViewObserver::setSelectedItems(QList<QGraphicsItem *> items) +{ + data->setSelectedItems(items); +} + +QList<QGraphicsItem *> QDeclarativeViewObserver::selectedItems() const +{ + return data->selectedItems(); +} + +QDeclarativeView *QDeclarativeViewObserver::declarativeView() +{ + return data->view; +} + +void QDeclarativeViewObserverPrivate::clearHighlight() +{ + boundingRectHighlighter->clear(); +} + +void QDeclarativeViewObserverPrivate::highlight(QGraphicsObject * item, ContextFlags flags) +{ + highlight(QList<QGraphicsObject*>() << item, flags); +} + +void QDeclarativeViewObserverPrivate::highlight(QList<QGraphicsObject *> items, ContextFlags flags) +{ + if (items.isEmpty()) + return; + + QList<QGraphicsObject*> objectList; + foreach (QGraphicsItem *item, items) { + QGraphicsItem *child = item; + if (flags & ContextSensitive) + child = subcomponentEditorTool->firstChildOfContext(item); + + if (child) { + QGraphicsObject *childObject = child->toGraphicsObject(); + if (childObject) + objectList << childObject; + } + } + + boundingRectHighlighter->highlight(objectList); +} + +bool QDeclarativeViewObserverPrivate::mouseInsideContextItem() const +{ + return subcomponentEditorTool->containsCursor(cursorPos.toPoint()); +} + +QList<QGraphicsItem*> QDeclarativeViewObserverPrivate::selectableItems( + const QPointF &scenePos) const +{ + QList<QGraphicsItem*> itemlist = view->scene()->items(scenePos); + return filterForCurrentContext(itemlist); +} + +QList<QGraphicsItem*> QDeclarativeViewObserverPrivate::selectableItems(const QPoint &pos) const +{ + QList<QGraphicsItem*> itemlist = view->items(pos); + return filterForCurrentContext(itemlist); +} + +QList<QGraphicsItem*> QDeclarativeViewObserverPrivate::selectableItems( + const QRectF &sceneRect, Qt::ItemSelectionMode selectionMode) const +{ + QList<QGraphicsItem*> itemlist = view->scene()->items(sceneRect, selectionMode); + + return filterForCurrentContext(itemlist); +} + +void QDeclarativeViewObserverPrivate::_q_changeToSingleSelectTool() +{ + currentToolMode = Constants::SelectionToolMode; + selectionTool->setRubberbandSelectionMode(false); + + changeToSelectTool(); + + emit q->selectToolActivated(); + q->sendCurrentTool(Constants::SelectionToolMode); +} + +void QDeclarativeViewObserverPrivate::changeToSelectTool() +{ + if (currentTool == selectionTool) + return; + + currentTool->clear(); + currentTool = selectionTool; + currentTool->clear(); + currentTool->updateSelectedItems(); +} + +void QDeclarativeViewObserverPrivate::_q_changeToMarqueeSelectTool() +{ + changeToSelectTool(); + currentToolMode = Constants::MarqueeSelectionToolMode; + selectionTool->setRubberbandSelectionMode(true); + + emit q->marqueeSelectToolActivated(); + q->sendCurrentTool(Constants::MarqueeSelectionToolMode); +} + +void QDeclarativeViewObserverPrivate::_q_changeToZoomTool() +{ + currentToolMode = Constants::ZoomMode; + currentTool->clear(); + currentTool = zoomTool; + currentTool->clear(); + + emit q->zoomToolActivated(); + q->sendCurrentTool(Constants::ZoomMode); +} + +void QDeclarativeViewObserverPrivate::_q_changeToColorPickerTool() +{ + if (currentTool == colorPickerTool) + return; + + currentToolMode = Constants::ColorPickerMode; + currentTool->clear(); + currentTool = colorPickerTool; + currentTool->clear(); + + emit q->colorPickerActivated(); + q->sendCurrentTool(Constants::ColorPickerMode); +} + +void QDeclarativeViewObserverPrivate::_q_changeContextPathIndex(int index) +{ + subcomponentEditorTool->setContext(index); +} + +void QDeclarativeViewObserver::setAnimationSpeed(qreal slowDownFactor) +{ + Q_ASSERT(slowDownFactor > 0); + if (data->slowDownFactor == slowDownFactor) + return; + + animationSpeedChangeRequested(slowDownFactor); + sendAnimationSpeed(slowDownFactor); +} + +void QDeclarativeViewObserver::setAnimationPaused(bool paused) +{ + if (data->animationPaused == paused) + return; + + animationPausedChangeRequested(paused); + sendAnimationPaused(paused); +} + +void QDeclarativeViewObserver::animationSpeedChangeRequested(qreal factor) +{ + if (data->slowDownFactor != factor) { + data->slowDownFactor = factor; + emit animationSpeedChanged(factor); + } + + const float effectiveFactor = data->animationPaused ? 0 : factor; + QDeclarativeDebugHelper::setAnimationSlowDownFactor(effectiveFactor); +} + +void QDeclarativeViewObserver::animationPausedChangeRequested(bool paused) +{ + if (data->animationPaused != paused) { + data->animationPaused = paused; + emit animationPausedChanged(paused); + } + + const float effectiveFactor = paused ? 0 : data->slowDownFactor; + QDeclarativeDebugHelper::setAnimationSlowDownFactor(effectiveFactor); +} + + +void QDeclarativeViewObserverPrivate::_q_applyChangesFromClient() +{ +} + + +QList<QGraphicsItem*> QDeclarativeViewObserverPrivate::filterForSelection( + QList<QGraphicsItem*> &itemlist) const +{ + foreach (QGraphicsItem *item, itemlist) { + if (isEditorItem(item) || !subcomponentEditorTool->isChildOfContext(item)) + itemlist.removeOne(item); + } + + return itemlist; +} + +QList<QGraphicsItem*> QDeclarativeViewObserverPrivate::filterForCurrentContext( + QList<QGraphicsItem*> &itemlist) const +{ + foreach (QGraphicsItem *item, itemlist) { + + if (isEditorItem(item) || !subcomponentEditorTool->isDirectChildOfContext(item)) { + + // if we're a child, but not directly, replace with the parent that is directly in context. + if (QGraphicsItem *contextParent = subcomponentEditorTool->firstChildOfContext(item)) { + if (contextParent != item) { + if (itemlist.contains(contextParent)) { + itemlist.removeOne(item); + } else { + itemlist.replace(itemlist.indexOf(item), contextParent); + } + } + } else { + itemlist.removeOne(item); + } + } + } + + return itemlist; +} + +bool QDeclarativeViewObserverPrivate::isEditorItem(QGraphicsItem *item) const +{ + return (item->type() == Constants::EditorItemType + || item->type() == Constants::ResizeHandleItemType + || item->data(Constants::EditorItemDataKey).toBool()); +} + +void QDeclarativeViewObserverPrivate::_q_onStatusChanged(QDeclarativeView::Status status) +{ + if (status == QDeclarativeView::Ready) { + if (view->rootObject()) { + if (subcomponentEditorTool->contextIndex() != -1) + subcomponentEditorTool->clear(); + subcomponentEditorTool->pushContext(view->rootObject()); + } + q->sendReloaded(); + } +} + +void QDeclarativeViewObserverPrivate::_q_onCurrentObjectsChanged(QList<QObject*> objects) +{ + QList<QGraphicsItem*> items; + QList<QGraphicsObject*> gfxObjects; + foreach (QObject *obj, objects) { + QDeclarativeItem* declarativeItem = qobject_cast<QDeclarativeItem*>(obj); + if (declarativeItem) { + items << declarativeItem; + if (QGraphicsObject *gfxObj = declarativeItem->toGraphicsObject()) + gfxObjects << gfxObj; + } + } + if (designModeBehavior) { + setSelectedItemsForTools(items); + clearHighlight(); + highlight(gfxObjects, QDeclarativeViewObserverPrivate::IgnoreContext); + } +} + +// adjusts bounding boxes on edges of screen to be visible +QRectF QDeclarativeViewObserver::adjustToScreenBoundaries(const QRectF &boundingRectInSceneSpace) +{ + int marginFromEdge = 1; + QRectF boundingRect(boundingRectInSceneSpace); + if (qAbs(boundingRect.left()) - 1 < 2) + boundingRect.setLeft(marginFromEdge); + + QRect rect = data->view->rect(); + + if (boundingRect.right() >= rect.right()) + boundingRect.setRight(rect.right() - marginFromEdge); + + if (qAbs(boundingRect.top()) - 1 < 2) + boundingRect.setTop(marginFromEdge); + + if (boundingRect.bottom() >= rect.bottom()) + boundingRect.setBottom(rect.bottom() - marginFromEdge); + + return boundingRect; +} + +void QDeclarativeViewObserverPrivate::createToolBox() +{ + toolBox = new ToolBox(q->declarativeView()); + + QmlToolBar *toolBar = toolBox->toolBar(); + + QObject::connect(q, SIGNAL(selectedColorChanged(QColor)), + toolBar, SLOT(setColorBoxColor(QColor))); + + QObject::connect(q, SIGNAL(designModeBehaviorChanged(bool)), + toolBar, SLOT(setDesignModeBehavior(bool))); + + QObject::connect(toolBar, SIGNAL(designModeBehaviorChanged(bool)), + q, SLOT(setDesignModeBehavior(bool))); + QObject::connect(toolBar, SIGNAL(animationSpeedChanged(qreal)), q, SLOT(setAnimationSpeed(qreal))); + QObject::connect(toolBar, SIGNAL(animationPausedChanged(bool)), q, SLOT(setAnimationPaused(bool))); + QObject::connect(toolBar, SIGNAL(colorPickerSelected()), this, SLOT(_q_changeToColorPickerTool())); + QObject::connect(toolBar, SIGNAL(zoomToolSelected()), this, SLOT(_q_changeToZoomTool())); + QObject::connect(toolBar, SIGNAL(selectToolSelected()), this, SLOT(_q_changeToSingleSelectTool())); + QObject::connect(toolBar, SIGNAL(marqueeSelectToolSelected()), + this, SLOT(_q_changeToMarqueeSelectTool())); + + QObject::connect(toolBar, SIGNAL(applyChangesFromQmlFileSelected()), + this, SLOT(_q_applyChangesFromClient())); + + QObject::connect(q, SIGNAL(animationSpeedChanged(qreal)), toolBar, SLOT(setAnimationSpeed(qreal))); + QObject::connect(q, SIGNAL(animationPausedChanged(bool)), toolBar, SLOT(setAnimationPaused(bool))); + + QObject::connect(q, SIGNAL(selectToolActivated()), toolBar, SLOT(activateSelectTool())); + + // disabled features + //connect(d->m_toolBar, SIGNAL(applyChangesToQmlFileSelected()), SLOT(applyChangesToClient())); + //connect(q, SIGNAL(resizeToolActivated()), d->m_toolBar, SLOT(activateSelectTool())); + //connect(q, SIGNAL(moveToolActivated()), d->m_toolBar, SLOT(activateSelectTool())); + + QObject::connect(q, SIGNAL(colorPickerActivated()), toolBar, SLOT(activateColorPicker())); + QObject::connect(q, SIGNAL(zoomToolActivated()), toolBar, SLOT(activateZoom())); + QObject::connect(q, SIGNAL(marqueeSelectToolActivated()), + toolBar, SLOT(activateMarqueeSelectTool())); +} + +void QDeclarativeViewObserver::handleMessage(const QByteArray &message) +{ + QDataStream ds(message); + + ObserverProtocol::Message type; + ds >> type; + + switch (type) { + case ObserverProtocol::SetCurrentObjects: { + int itemCount = 0; + ds >> itemCount; + + QList<QObject*> selectedObjects; + for (int i = 0; i < itemCount; ++i) { + int debugId = -1; + ds >> debugId; + QObject *obj = QDeclarativeDebugService::objectForId(debugId); + + if (obj) + selectedObjects << obj; + } + + data->_q_onCurrentObjectsChanged(selectedObjects); + break; + } + case ObserverProtocol::Reload: { + data->_q_reloadView(); + break; + } + case ObserverProtocol::SetAnimationSpeed: { + qreal speed; + ds >> speed; + animationSpeedChangeRequested(speed); + break; + } + case ObserverProtocol::SetAnimationPaused: { + bool paused; + ds >> paused; + animationPausedChangeRequested(paused); + break; + } + case ObserverProtocol::ChangeTool: { + ObserverProtocol::Tool tool; + ds >> tool; + switch (tool) { + case ObserverProtocol::ColorPickerTool: + data->_q_changeToColorPickerTool(); + break; + case ObserverProtocol::SelectTool: + data->_q_changeToSingleSelectTool(); + break; + case ObserverProtocol::SelectMarqueeTool: + data->_q_changeToMarqueeSelectTool(); + break; + case ObserverProtocol::ZoomTool: + data->_q_changeToZoomTool(); + break; + default: + qWarning() << "Warning: Unhandled tool:" << tool; + } + break; + } + case ObserverProtocol::SetDesignMode: { + bool inDesignMode; + ds >> inDesignMode; + setDesignModeBehavior(inDesignMode); + break; + } + case ObserverProtocol::ShowAppOnTop: { + bool showOnTop; + ds >> showOnTop; + setShowAppOnTop(showOnTop); + break; + } + case ObserverProtocol::CreateObject: { + QString qml; + int parentId; + QString filename; + QStringList imports; + ds >> qml >> parentId >> imports >> filename; + data->_q_createQmlObject(qml, QDeclarativeDebugService::objectForId(parentId), + imports, filename); + break; + } + case ObserverProtocol::DestroyObject: { + int debugId; + ds >> debugId; + if (QObject* obj = QDeclarativeDebugService::objectForId(debugId)) + obj->deleteLater(); + break; + } + case ObserverProtocol::MoveObject: { + int debugId, newParent; + ds >> debugId >> newParent; + data->_q_reparentQmlObject(QDeclarativeDebugService::objectForId(debugId), + QDeclarativeDebugService::objectForId(newParent)); + break; + } + case ObserverProtocol::ObjectIdList: { + int itemCount; + ds >> itemCount; + data->stringIdForObjectId.clear(); + for (int i = 0; i < itemCount; ++i) { + int itemDebugId; + QString itemIdString; + ds >> itemDebugId + >> itemIdString; + + data->stringIdForObjectId.insert(itemDebugId, itemIdString); + } + break; + } + case ObserverProtocol::SetContextPathIdx: { + int contextPathIndex; + ds >> contextPathIndex; + data->_q_changeContextPathIndex(contextPathIndex); + break; + } + case ObserverProtocol::ClearComponentCache: { + data->_q_clearComponentCache(); + break; + } + default: + qWarning() << "Warning: Not handling message:" << type; + } +} + +void QDeclarativeViewObserver::sendDesignModeBehavior(bool inDesignMode) +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << ObserverProtocol::SetDesignMode + << inDesignMode; + + data->debugService->sendMessage(message); +} + +void QDeclarativeViewObserver::sendCurrentObjects(QList<QObject*> objects) +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << ObserverProtocol::CurrentObjectsChanged + << objects.length(); + + foreach (QObject *object, objects) { + int id = QDeclarativeDebugService::idForObject(object); + ds << id; + } + + data->debugService->sendMessage(message); +} + +void QDeclarativeViewObserver::sendCurrentTool(Constants::DesignTool toolId) +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << ObserverProtocol::ToolChanged + << toolId; + + data->debugService->sendMessage(message); +} + +void QDeclarativeViewObserver::sendAnimationSpeed(qreal slowDownFactor) +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << ObserverProtocol::AnimationSpeedChanged + << slowDownFactor; + + data->debugService->sendMessage(message); +} + +void QDeclarativeViewObserver::sendAnimationPaused(bool paused) +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << ObserverProtocol::AnimationPausedChanged + << paused; + + data->debugService->sendMessage(message); +} + +void QDeclarativeViewObserver::sendReloaded() +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << ObserverProtocol::Reloaded; + + data->debugService->sendMessage(message); +} + +void QDeclarativeViewObserver::sendShowAppOnTop(bool showAppOnTop) +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << ObserverProtocol::ShowAppOnTop << showAppOnTop; + + data->debugService->sendMessage(message); +} + +void QDeclarativeViewObserver::sendColorChanged(const QColor &color) +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << ObserverProtocol::ColorChanged + << color; + + data->debugService->sendMessage(message); +} + +void QDeclarativeViewObserver::sendContextPathUpdated(const QStringList &contextPath) +{ + QByteArray message; + QDataStream ds(&message, QIODevice::WriteOnly); + + ds << ObserverProtocol::ContextPathUpdated + << contextPath; + + data->debugService->sendMessage(message); +} + +QString QDeclarativeViewObserver::idStringForObject(QObject *obj) const +{ + int id = QDeclarativeDebugService::idForObject(obj); + QString idString = data->stringIdForObjectId.value(id, QString()); + return idString; +} + +QT_END_NAMESPACE + +#include "qdeclarativeviewobserver.moc" diff --git a/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p.h b/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p.h new file mode 100644 index 0000000..6e986c2 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p.h @@ -0,0 +1,154 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 QDECLARATIVEVIEWOBSERVER_P_H +#define QDECLARATIVEVIEWOBSERVER_P_H + +#include <private/qdeclarativeglobal_p.h> +#include "qmlobserverconstants_p.h" + +#include <QtCore/QScopedPointer> +#include <QtDeclarative/QDeclarativeView> + +QT_FORWARD_DECLARE_CLASS(QDeclarativeItem) +QT_FORWARD_DECLARE_CLASS(QMouseEvent) +QT_FORWARD_DECLARE_CLASS(QToolBar) + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeViewObserverPrivate; + +class QDeclarativeViewObserver : public QObject +{ + Q_OBJECT + +public: + explicit QDeclarativeViewObserver(QDeclarativeView *view, QObject *parent = 0); + ~QDeclarativeViewObserver(); + + void setSelectedItems(QList<QGraphicsItem *> items); + QList<QGraphicsItem *> selectedItems() const; + + QDeclarativeView *declarativeView(); + + QRectF adjustToScreenBoundaries(const QRectF &boundingRectInSceneSpace); + + bool showAppOnTop() const; + + void sendDesignModeBehavior(bool inDesignMode); + void sendCurrentObjects(QList<QObject*> items); + void sendAnimationSpeed(qreal slowDownFactor); + void sendAnimationPaused(bool paused); + void sendCurrentTool(Constants::DesignTool toolId); + void sendReloaded(); + void sendShowAppOnTop(bool showAppOnTop); + + QString idStringForObject(QObject *obj) const; + +public Q_SLOTS: + void sendColorChanged(const QColor &color); + void sendContextPathUpdated(const QStringList &contextPath); + + void setDesignModeBehavior(bool value); + bool designModeBehavior(); + + void setShowAppOnTop(bool appOnTop); + + void setAnimationSpeed(qreal factor); + void setAnimationPaused(bool paused); + + void setObserverContext(int contextIndex); + +Q_SIGNALS: + void designModeBehaviorChanged(bool inDesignMode); + void showAppOnTopChanged(bool showAppOnTop); + void reloadRequested(); + void marqueeSelectToolActivated(); + void selectToolActivated(); + void zoomToolActivated(); + void colorPickerActivated(); + void selectedColorChanged(const QColor &color); + + void animationSpeedChanged(qreal factor); + void animationPausedChanged(bool paused); + + void inspectorContextCleared(); + void inspectorContextPushed(const QString &contextTitle); + void inspectorContextPopped(); + +protected: + bool eventFilter(QObject *obj, QEvent *event); + + bool leaveEvent(QEvent *); + bool mousePressEvent(QMouseEvent *event); + bool mouseMoveEvent(QMouseEvent *event); + bool mouseReleaseEvent(QMouseEvent *event); + bool keyPressEvent(QKeyEvent *event); + bool keyReleaseEvent(QKeyEvent *keyEvent); + bool mouseDoubleClickEvent(QMouseEvent *event); + bool wheelEvent(QWheelEvent *event); + + void setSelectedItemsForTools(QList<QGraphicsItem *> items); + +private slots: + void handleMessage(const QByteArray &message); + + void animationSpeedChangeRequested(qreal factor); + void animationPausedChangeRequested(bool paused); + +private: + Q_DISABLE_COPY(QDeclarativeViewObserver) + + inline QDeclarativeViewObserverPrivate *d_func() { return data.data(); } + QScopedPointer<QDeclarativeViewObserverPrivate> data; + friend class QDeclarativeViewObserverPrivate; + friend class AbstractLiveEditTool; +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QDECLARATIVEVIEWOBSERVER_P_H diff --git a/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p_p.h b/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p_p.h new file mode 100644 index 0000000..6022555 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/qdeclarativeviewobserver_p_p.h @@ -0,0 +1,165 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 QDECLARATIVEVIEWOBSERVER_P_P_H +#define QDECLARATIVEVIEWOBSERVER_P_P_H + +#include "qdeclarativeviewobserver_p.h" + +#include <QtCore/QWeakPointer> +#include <QtCore/QPointF> + +#include "QtDeclarative/private/qdeclarativeobserverservice_p.h" + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +class QDeclarativeViewObserver; +class LiveSelectionTool; +class ZoomTool; +class ColorPickerTool; +class LiveLayerItem; +class BoundingRectHighlighter; +class SubcomponentEditorTool; +class ToolBox; +class AbstractLiveEditTool; + +class QDeclarativeViewObserverPrivate : public QObject +{ + Q_OBJECT +public: + enum ContextFlags { + IgnoreContext, + ContextSensitive + }; + + QDeclarativeViewObserverPrivate(QDeclarativeViewObserver *); + ~QDeclarativeViewObserverPrivate(); + + QDeclarativeView *view; + QDeclarativeViewObserver *q; + QDeclarativeObserverService *debugService; + QWeakPointer<QWidget> viewport; + QHash<int, QString> stringIdForObjectId; + + QPointF cursorPos; + QList<QWeakPointer<QGraphicsObject> > currentSelection; + + Constants::DesignTool currentToolMode; + AbstractLiveEditTool *currentTool; + + LiveSelectionTool *selectionTool; + ZoomTool *zoomTool; + ColorPickerTool *colorPickerTool; + SubcomponentEditorTool *subcomponentEditorTool; + LiveLayerItem *manipulatorLayer; + + BoundingRectHighlighter *boundingRectHighlighter; + + bool designModeBehavior; + bool showAppOnTop; + + bool animationPaused; + qreal slowDownFactor; + + ToolBox *toolBox; + + void setViewport(QWidget *widget); + + void clearEditorItems(); + void createToolBox(); + void changeToSelectTool(); + QList<QGraphicsItem*> filterForCurrentContext(QList<QGraphicsItem*> &itemlist) const; + QList<QGraphicsItem*> filterForSelection(QList<QGraphicsItem*> &itemlist) const; + + QList<QGraphicsItem*> selectableItems(const QPoint &pos) const; + QList<QGraphicsItem*> selectableItems(const QPointF &scenePos) const; + QList<QGraphicsItem*> selectableItems(const QRectF &sceneRect, Qt::ItemSelectionMode selectionMode) const; + + void setSelectedItemsForTools(QList<QGraphicsItem *> items); + void setSelectedItems(QList<QGraphicsItem *> items); + QList<QGraphicsItem *> selectedItems() const; + + void changeTool(Constants::DesignTool tool, + Constants::ToolFlags flags = Constants::NoToolFlags); + + void clearHighlight(); + void highlight(QList<QGraphicsObject *> item, ContextFlags flags = ContextSensitive); + void highlight(QGraphicsObject *item, ContextFlags flags = ContextSensitive); + + bool mouseInsideContextItem() const; + bool isEditorItem(QGraphicsItem *item) const; + + QGraphicsItem *currentRootItem() const; + + void enterContext(QGraphicsItem *itemToEnter); + +public slots: + void _q_setToolBoxVisible(bool visible); + + void _q_reloadView(); + void _q_onStatusChanged(QDeclarativeView::Status status); + void _q_onCurrentObjectsChanged(QList<QObject*> objects); + void _q_applyChangesFromClient(); + void _q_createQmlObject(const QString &qml, QObject *parent, + const QStringList &imports, const QString &filename = QString()); + void _q_reparentQmlObject(QObject *, QObject *); + + void _q_changeToSingleSelectTool(); + void _q_changeToMarqueeSelectTool(); + void _q_changeToZoomTool(); + void _q_changeToColorPickerTool(); + void _q_changeContextPathIndex(int index); + void _q_clearComponentCache(); + void _q_removeFromSelection(QObject *); + +public: + static QDeclarativeViewObserverPrivate *get(QDeclarativeViewObserver *v) { return v->d_func(); } +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QDECLARATIVEVIEWOBSERVER_P_P_H diff --git a/src/plugins/qmltooling/declarativeobserver/qmlobserverconstants_p.h b/src/plugins/qmltooling/declarativeobserver/qmlobserverconstants_p.h new file mode 100644 index 0000000..353e235 --- /dev/null +++ b/src/plugins/qmltooling/declarativeobserver/qmlobserverconstants_p.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtDeclarative 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 QMLOBSERVERCONSTANTS_H +#define QMLOBSERVERCONSTANTS_H + +#include <QtDeclarative/private/qdeclarativeglobal_p.h> + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Declarative) + +namespace Constants { + +enum DesignTool { + NoTool = 0, + SelectionToolMode = 1, + MarqueeSelectionToolMode = 2, + MoveToolMode = 3, + ResizeToolMode = 4, + ColorPickerMode = 5, + ZoomMode = 6 +}; + +enum ToolFlags { + NoToolFlags = 0, + UseCursorPos = 1 +}; + +static const int DragStartTime = 50; + +static const int DragStartDistance = 20; + +static const double ZoomSnapDelta = 0.04; + +static const int EditorItemDataKey = 1000; + +enum GraphicsItemTypes { + EditorItemType = 0xEAAA, + ResizeHandleItemType = 0xEAEA +}; + + +} // namespace Constants + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QMLOBSERVERCONSTANTS_H diff --git a/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.cpp b/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.cpp index 1c91c34..ac32081 100644 --- a/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.cpp +++ b/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.cpp @@ -109,6 +109,12 @@ void QmlOstPlugin::disconnect() d->protocol = 0; } +bool QmlOstPlugin::waitForMessage() +{ + Q_D(QmlOstPlugin); + return d->protocol->waitForReadyRead(-1); +} + void QmlOstPlugin::setPort(int port, bool block) { Q_UNUSED(port); diff --git a/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.h b/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.h index eee6ee1..b4ff377 100644 --- a/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.h +++ b/src/plugins/qmltooling/qmldbg_ost/qmlostplugin.h @@ -68,6 +68,7 @@ public: bool isConnected() const; void send(const QByteArray &message); void disconnect(); + bool waitForMessage(); private Q_SLOTS: void readyRead(); diff --git a/src/plugins/qmltooling/qmldbg_ost/qostdevice.cpp b/src/plugins/qmltooling/qmldbg_ost/qostdevice.cpp index 21b0169..d3b2661 100644 --- a/src/plugins/qmltooling/qmldbg_ost/qostdevice.cpp +++ b/src/plugins/qmltooling/qmldbg_ost/qostdevice.cpp @@ -57,6 +57,8 @@ public: Cancel(); } + TInt& AoFlags() { return ((TInt*)&iStatus)[1]; } + private: void RunL(); void DoCancel(); @@ -65,6 +67,7 @@ private: RUsbOstComm ost; TBuf8<4096> readBuf; QByteArray dataBuf; + TBool inReadyRead; }; QOstDevice::QOstDevice(QObject *parent) : @@ -116,7 +119,11 @@ void QOstDevicePrivate::RunL() ost.ReadMessage(iStatus, readBuf); SetActive(); - emit q->readyRead(); + if (!inReadyRead) { + inReadyRead = true; + emit q->readyRead(); + inReadyRead = false; + } } else { q->setErrorString(QString("Error %1 from RUsbOstComm::ReadMessage()").arg(iStatus.Int())); } @@ -178,3 +185,36 @@ qint64 QOstDevice::bytesAvailable() const Q_D(const QOstDevice); return d->dataBuf.length(); } + +bool QOstDevice::waitForReadyRead(int msecs) +{ + Q_D(QOstDevice); + if (msecs >= 0) { + RTimer timer; + TInt err = timer.CreateLocal(); + if (err) return false; + TRequestStatus timeoutStat; + timer.After(timeoutStat, msecs*1000); + User::WaitForRequest(timeoutStat, d->iStatus); + if (timeoutStat != KRequestPending) { + // Timed out + timer.Close(); + return false; + } else { + // We got data, so cancel timer + timer.Cancel(); + User::WaitForRequest(timeoutStat); + timer.Close(); + // And drop through + } + } else { + // Just wait forever for data + User::WaitForRequest(d->iStatus); + } + + // If we get here we have data + TInt err = d->iStatus.Int(); + d->AoFlags() &= ~3; // This is necessary to clean up the scheduler as you're not supposed to bypass it like this + TRAP_IGNORE(d->RunL()); + return err == KErrNone; +} diff --git a/src/plugins/qmltooling/qmldbg_ost/qostdevice.h b/src/plugins/qmltooling/qmldbg_ost/qostdevice.h index 2c26ff7..200e607 100644 --- a/src/plugins/qmltooling/qmldbg_ost/qostdevice.h +++ b/src/plugins/qmltooling/qmldbg_ost/qostdevice.h @@ -61,10 +61,12 @@ public: bool open(int ostProtocolId); void close(); + bool waitForReadyRead(int msecs); + qint64 bytesAvailable() const; + protected: qint64 readData(char *data, qint64 maxSize); qint64 writeData(const char *data, qint64 maxSize); - qint64 bytesAvailable() const; private: QOstDevicePrivate* d_ptr; diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp index 85c43e3..7cd3d73 100644 --- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp +++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.cpp @@ -41,6 +41,7 @@ #include "qtcpserverconnection.h" +#include <QtCore/qplugin.h> #include <QtNetwork/qtcpserver.h> #include <QtNetwork/qtcpsocket.h> @@ -54,6 +55,7 @@ public: QTcpServerConnectionPrivate(); int port; + bool block; QTcpSocket *socket; QPacketProtocol *protocol; QTcpServer *tcpServer; @@ -63,6 +65,7 @@ public: QTcpServerConnectionPrivate::QTcpServerConnectionPrivate() : port(0), + block(false), socket(0), protocol(0), tcpServer(0), @@ -119,10 +122,17 @@ void QTcpServerConnection::disconnect() d->socket = 0; } +bool QTcpServerConnection::waitForMessage() +{ + Q_D(QTcpServerConnection); + return d->protocol->waitForReadyRead(-1); +} + void QTcpServerConnection::setPort(int port, bool block) { Q_D(QTcpServerConnection); d->port = port; + d->block = block; listen(); if (block) @@ -169,8 +179,11 @@ void QTcpServerConnection::newConnection() d->socket->setParent(this); d->protocol = new QPacketProtocol(d->socket, this); QObject::connect(d->protocol, SIGNAL(readyRead()), this, SLOT(readyRead())); -} + if (d->block) { + d->protocol->waitForReadyRead(-1); + } +} Q_EXPORT_PLUGIN2(tcpserver, QTcpServerConnection) diff --git a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h index 66a10e1..dd5a5ec 100644 --- a/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h +++ b/src/plugins/qmltooling/qmldbg_tcp/qtcpserverconnection.h @@ -42,7 +42,6 @@ #ifndef QTCPSERVERCONNECTION_H #define QTCPSERVERCONNECTION_H -#include <QtGui/QStylePlugin> #include <QtDeclarative/private/qdeclarativedebugserverconnection_p.h> QT_BEGIN_NAMESPACE @@ -67,6 +66,7 @@ public: bool isConnected() const; void send(const QByteArray &message); void disconnect(); + bool waitForMessage(); void listen(); void waitForConnection(); diff --git a/src/plugins/qmltooling/qmltooling.pro b/src/plugins/qmltooling/qmltooling.pro index 9b3346f..0d60eb1 100644 --- a/src/plugins/qmltooling/qmltooling.pro +++ b/src/plugins/qmltooling/qmltooling.pro @@ -1,4 +1,4 @@ TEMPLATE = subdirs -SUBDIRS = qmldbg_tcp +SUBDIRS = qmldbg_tcp declarativeobserver symbian:SUBDIRS += qmldbg_ost diff --git a/src/qbase.pri b/src/qbase.pri index ce69757..c4d081f 100644 --- a/src/qbase.pri +++ b/src/qbase.pri @@ -163,7 +163,7 @@ contains(QT_PRODUCT, OpenSource.*):DEFINES *= QT_OPENSOURCE DEFINES *= QT_NO_CAST_TO_ASCII QT_ASCII_CAST_WARNINGS contains(QT_CONFIG, qt3support):DEFINES *= QT3_SUPPORT DEFINES *= QT_MOC_COMPAT #we don't need warnings from calling moc code in our generated code -DEFINES *= QT_USE_FAST_OPERATOR_PLUS QT_USE_FAST_CONCATENATION +DEFINES *= QT_USE_QSTRINGBUILDER TARGET = $$qtLibraryTarget($$TARGET$$QT_LIBINFIX) #do this towards the end diff --git a/src/qt3support/text/q3richtext.cpp b/src/qt3support/text/q3richtext.cpp index 668a322..6c77405 100644 --- a/src/qt3support/text/q3richtext.cpp +++ b/src/qt3support/text/q3richtext.cpp @@ -63,6 +63,7 @@ #include "qstyleoption.h" #include "q3stylesheet.h" #include "qtextstream.h" +#include <private/qtextdocument_p.h> #include <private/qtextengine_p.h> #include <stdlib.h> diff --git a/src/s60installs/bwins/QtCoreu.def b/src/s60installs/bwins/QtCoreu.def index 0e6021a..f26b4d0 100644 --- a/src/s60installs/bwins/QtCoreu.def +++ b/src/s60installs/bwins/QtCoreu.def @@ -4844,4 +4844,172 @@ EXPORTS ?staticMetaObjectExtraData@QEventTransition@@0UQMetaObjectExtraData@@B @ 4843 NONAME ; struct QMetaObjectExtraData const QEventTransition::staticMetaObjectExtraData ?qt_static_metacall@QEventLoop@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 4844 NONAME ; void QEventLoop::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) ?keys@QProcessEnvironment@@QBE?AVQStringList@@XZ @ 4845 NONAME ; class QStringList QProcessEnvironment::keys(void) const + ?progressTextChanged@QFutureWatcherBase@@IAEXABVQString@@@Z @ 4846 NONAME ; void QFutureWatcherBase::progressTextChanged(class QString const &) + ?timeAfterUser@BlockSizeManager@QtConcurrent@@QAEXXZ @ 4847 NONAME ; void QtConcurrent::BlockSizeManager::timeAfterUser(void) + ?hasThrown@ExceptionStore@internal@QtConcurrent@@QBE_NXZ @ 4848 NONAME ; bool QtConcurrent::internal::ExceptionStore::hasThrown(void) const + ??1ExceptionStore@internal@QtConcurrent@@QAE@XZ @ 4849 NONAME ; QtConcurrent::internal::ExceptionStore::~ExceptionStore(void) + ?isVector@ResultIteratorBase@QtConcurrent@@QBE_NXZ @ 4850 NONAME ; bool QtConcurrent::ResultIteratorBase::isVector(void) const + ?queryState@QFutureInterfaceBase@@QBE_NW4State@1@@Z @ 4851 NONAME ; bool QFutureInterfaceBase::queryState(enum QFutureInterfaceBase::State) const + ?end@ResultStoreBase@QtConcurrent@@QBE?AVResultIteratorBase@2@XZ @ 4852 NONAME ; class QtConcurrent::ResultIteratorBase QtConcurrent::ResultStoreBase::end(void) const + ?run@ThreadEngineBase@QtConcurrent@@EAEXXZ @ 4853 NONAME ; void QtConcurrent::ThreadEngineBase::run(void) + ?exception@ExceptionStore@internal@QtConcurrent@@QAE?AVExceptionHolder@23@XZ @ 4854 NONAME ; class QtConcurrent::internal::ExceptionHolder QtConcurrent::internal::ExceptionStore::exception(void) + ?isStarted@QFutureWatcherBase@@QBE_NXZ @ 4855 NONAME ; bool QFutureWatcherBase::isStarted(void) const + ?resultIndex@ResultIteratorBase@QtConcurrent@@QBEHXZ @ 4856 NONAME ; int QtConcurrent::ResultIteratorBase::resultIndex(void) const + ?qt_metacast@QFutureWatcherBase@@UAEPAXPBD@Z @ 4857 NONAME ; void * QFutureWatcherBase::qt_metacast(char const *) + ??9QFutureInterfaceBase@@QBE_NABV0@@Z @ 4858 NONAME ; bool QFutureInterfaceBase::operator!=(class QFutureInterfaceBase const &) const + ??0QFutureInterfaceBase@@QAE@W4State@0@@Z @ 4859 NONAME ; QFutureInterfaceBase::QFutureInterfaceBase(enum QFutureInterfaceBase::State) + ?staticMetaObjectExtraData@QFutureWatcherBase@@0UQMetaObjectExtraData@@B @ 4860 NONAME ; struct QMetaObjectExtraData const QFutureWatcherBase::staticMetaObjectExtraData + ??0QFutureWatcherBase@@QAE@PAVQObject@@@Z @ 4861 NONAME ; QFutureWatcherBase::QFutureWatcherBase(class QObject *) + ??1QFutureInterfaceBase@@UAE@XZ @ 4862 NONAME ; QFutureInterfaceBase::~QFutureInterfaceBase(void) + ?resume@QFutureWatcherBase@@QAEXXZ @ 4863 NONAME ; void QFutureWatcherBase::resume(void) + ?startSingleThreaded@ThreadEngineBase@QtConcurrent@@QAEXXZ @ 4864 NONAME ; void QtConcurrent::ThreadEngineBase::startSingleThreaded(void) + ?setPaused@QFutureWatcherBase@@QAEX_N@Z @ 4865 NONAME ; void QFutureWatcherBase::setPaused(bool) + ?waitForResume@QFutureInterfaceBase@@QAEXXZ @ 4866 NONAME ; void QFutureInterfaceBase::waitForResume(void) + ?progressMinimum@QFutureInterfaceBase@@QBEHXZ @ 4867 NONAME ; int QFutureInterfaceBase::progressMinimum(void) const + ?hasException@ExceptionStore@internal@QtConcurrent@@QBE_NXZ @ 4868 NONAME ; bool QtConcurrent::internal::ExceptionStore::hasException(void) const + ?tr@QFutureWatcherBase@@SA?AVQString@@PBD0H@Z @ 4869 NONAME ; class QString QFutureWatcherBase::tr(char const *, char const *, int) + ?resultAt@ResultStoreBase@QtConcurrent@@QBE?AVResultIteratorBase@2@H@Z @ 4870 NONAME ; class QtConcurrent::ResultIteratorBase QtConcurrent::ResultStoreBase::resultAt(int) const + ?connectOutputInterface@QFutureWatcherBase@@IAEXXZ @ 4871 NONAME ; void QFutureWatcherBase::connectOutputInterface(void) + ?insertResultItem@ResultStoreBase@QtConcurrent@@IAEHHAAVResultItem@2@@Z @ 4872 NONAME ; int QtConcurrent::ResultStoreBase::insertResultItem(int, class QtConcurrent::ResultItem &) + ?syncResultCount@ResultStoreBase@QtConcurrent@@IAEXXZ @ 4873 NONAME ; void QtConcurrent::ResultStoreBase::syncResultCount(void) + ?setProgressRange@ThreadEngineBase@QtConcurrent@@QAEXHH@Z @ 4874 NONAME ; void QtConcurrent::ThreadEngineBase::setProgressRange(int, int) + ??_EQFutureWatcherBase@@UAE@I@Z @ 4875 NONAME ; QFutureWatcherBase::~QFutureWatcherBase(unsigned int) + ?progressValueChanged@QFutureWatcherBase@@IAEXH@Z @ 4876 NONAME ; void QFutureWatcherBase::progressValueChanged(int) + ?threadExit@ThreadEngineBase@QtConcurrent@@AAEXXZ @ 4877 NONAME ; void QtConcurrent::ThreadEngineBase::threadExit(void) + ?mutex@QFutureInterfaceBase@@QBEPAVQMutex@@XZ @ 4878 NONAME ; class QMutex * QFutureInterfaceBase::mutex(void) const + ?staticMetaObject@QFutureWatcherBase@@2UQMetaObject@@B @ 4879 NONAME ; struct QMetaObject const QFutureWatcherBase::staticMetaObject + ?setException@ExceptionStore@internal@QtConcurrent@@QAEXABVException@3@@Z @ 4880 NONAME ; void QtConcurrent::internal::ExceptionStore::setException(class QtConcurrent::Exception const &) + ??0ResultIteratorBase@QtConcurrent@@QAE@XZ @ 4881 NONAME ; QtConcurrent::ResultIteratorBase::ResultIteratorBase(void) + ?hasNextResult@ResultStoreBase@QtConcurrent@@QBE_NXZ @ 4882 NONAME ; bool QtConcurrent::ResultStoreBase::hasNextResult(void) const + ??_EResultStoreBase@QtConcurrent@@UAE@I@Z @ 4883 NONAME ; QtConcurrent::ResultStoreBase::~ResultStoreBase(unsigned int) + ?contains@ResultStoreBase@QtConcurrent@@QBE_NH@Z @ 4884 NONAME ; bool QtConcurrent::ResultStoreBase::contains(int) const + ?updateInsertIndex@ResultStoreBase@QtConcurrent@@IAEHHH@Z @ 4885 NONAME ; int QtConcurrent::ResultStoreBase::updateInsertIndex(int, int) + ??_EException@QtConcurrent@@UAE@I@Z @ 4886 NONAME ; QtConcurrent::Exception::~Exception(unsigned int) + ?qt_metacall@QFutureWatcherBase@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 4887 NONAME ; int QFutureWatcherBase::qt_metacall(enum QMetaObject::Call, int, void * *) + ?isStarted@QFutureInterfaceBase@@QBE_NXZ @ 4888 NONAME ; bool QFutureInterfaceBase::isStarted(void) const + ??0QFutureInterfaceBase@@QAE@ABV0@@Z @ 4889 NONAME ; QFutureInterfaceBase::QFutureInterfaceBase(class QFutureInterfaceBase const &) + ??_EUnhandledException@QtConcurrent@@UAE@I@Z @ 4890 NONAME ; QtConcurrent::UnhandledException::~UnhandledException(unsigned int) + ?progressValue@QFutureWatcherBase@@QBEHXZ @ 4891 NONAME ; int QFutureWatcherBase::progressValue(void) const + ??8ResultIteratorBase@QtConcurrent@@QBE_NABV01@@Z @ 4892 NONAME ; bool QtConcurrent::ResultIteratorBase::operator==(class QtConcurrent::ResultIteratorBase const &) const + ?tr@QFutureWatcherBase@@SA?AVQString@@PBD0@Z @ 4893 NONAME ; class QString QFutureWatcherBase::tr(char const *, char const *) + ?startBlocking@ThreadEngineBase@QtConcurrent@@QAEXXZ @ 4894 NONAME ; void QtConcurrent::ThreadEngineBase::startBlocking(void) + ?threadThrottleExit@ThreadEngineBase@QtConcurrent@@AAE_NXZ @ 4895 NONAME ; bool QtConcurrent::ThreadEngineBase::threadThrottleExit(void) + ?isFinished@QFutureWatcherBase@@QBE_NXZ @ 4896 NONAME ; bool QFutureWatcherBase::isFinished(void) const + ?resultsReadyAt@QFutureWatcherBase@@IAEXHH@Z @ 4897 NONAME ; void QFutureWatcherBase::resultsReadyAt(int, int) + ?start@ThreadEngineBase@QtConcurrent@@MAEXXZ @ 4898 NONAME ; void QtConcurrent::ThreadEngineBase::start(void) + ?runningAnimationCount@QUnifiedTimer@@QAEHXZ @ 4899 NONAME ; int QUnifiedTimer::runningAnimationCount(void) + ??9ResultIteratorBase@QtConcurrent@@QBE_NABV01@@Z @ 4900 NONAME ; bool QtConcurrent::ResultIteratorBase::operator!=(class QtConcurrent::ResultIteratorBase const &) const + ??1UnhandledException@QtConcurrent@@UAE@XZ @ 4901 NONAME ; QtConcurrent::UnhandledException::~UnhandledException(void) + ?shouldStartThread@ThreadEngineBase@QtConcurrent@@MAE_NXZ @ 4902 NONAME ; bool QtConcurrent::ThreadEngineBase::shouldStartThread(void) + ?d_func@QFutureWatcherBase@@AAEPAVQFutureWatcherBasePrivate@@XZ @ 4903 NONAME ; class QFutureWatcherBasePrivate * QFutureWatcherBase::d_func(void) + ?startThread@ThreadEngineBase@QtConcurrent@@QAEXXZ @ 4904 NONAME ; void QtConcurrent::ThreadEngineBase::startThread(void) + ?threadFunction@ThreadEngineBase@QtConcurrent@@MAE?AW4ThreadFunctionResult@2@XZ @ 4905 NONAME ; enum QtConcurrent::ThreadFunctionResult QtConcurrent::ThreadEngineBase::threadFunction(void) + ?count@ResultStoreBase@QtConcurrent@@QBEHXZ @ 4906 NONAME ; int QtConcurrent::ResultStoreBase::count(void) const + ?isThrottled@QFutureInterfaceBase@@QBE_NXZ @ 4907 NONAME ; bool QFutureInterfaceBase::isThrottled(void) const + ?waitForResume@ThreadEngineBase@QtConcurrent@@QAEXXZ @ 4908 NONAME ; void QtConcurrent::ThreadEngineBase::waitForResume(void) + ?progressMinimum@QFutureWatcherBase@@QBEHXZ @ 4909 NONAME ; int QFutureWatcherBase::progressMinimum(void) const + ??1ThreadEngineBase@QtConcurrent@@UAE@XZ @ 4910 NONAME ; QtConcurrent::ThreadEngineBase::~ThreadEngineBase(void) + ?finished@QFutureWatcherBase@@IAEXXZ @ 4911 NONAME ; void QFutureWatcherBase::finished(void) + ?progressMaximum@QFutureInterfaceBase@@QBEHXZ @ 4912 NONAME ; int QFutureInterfaceBase::progressMaximum(void) const + ?pause@QFutureWatcherBase@@QAEXXZ @ 4913 NONAME ; void QFutureWatcherBase::pause(void) + ?isProgressReportingEnabled@ThreadEngineBase@QtConcurrent@@QAE_NXZ @ 4914 NONAME ; bool QtConcurrent::ThreadEngineBase::isProgressReportingEnabled(void) + ?blockSizeMaxed@BlockSizeManager@QtConcurrent@@AAE_NXZ @ 4915 NONAME ; bool QtConcurrent::BlockSizeManager::blockSizeMaxed(void) + ?isCanceled@QFutureInterfaceBase@@QBE_NXZ @ 4916 NONAME ; bool QFutureInterfaceBase::isCanceled(void) const + ?cancel@QFutureInterfaceBase@@QAEXXZ @ 4917 NONAME ; void QFutureInterfaceBase::cancel(void) + ?setFilterMode@QFutureInterfaceBase@@QAEX_N@Z @ 4918 NONAME ; void QFutureInterfaceBase::setFilterMode(bool) + ?setProgressValueAndText@QFutureInterfaceBase@@QAEXHABVQString@@@Z @ 4919 NONAME ; void QFutureInterfaceBase::setProgressValueAndText(int, class QString const &) + ?setRunnable@QFutureInterfaceBase@@QAEXPAVQRunnable@@@Z @ 4920 NONAME ; void QFutureInterfaceBase::setRunnable(class QRunnable *) + ?trUtf8@QFutureWatcherBase@@SA?AVQString@@PBD0H@Z @ 4921 NONAME ; class QString QFutureWatcherBase::trUtf8(char const *, char const *, int) + ?paused@QFutureWatcherBase@@IAEXXZ @ 4922 NONAME ; void QFutureWatcherBase::paused(void) + ?disconnectOutputInterface@QFutureWatcherBase@@IAEX_N@Z @ 4923 NONAME ; void QFutureWatcherBase::disconnectOutputInterface(bool) + ?isCanceled@QFutureWatcherBase@@QBE_NXZ @ 4924 NONAME ; bool QFutureWatcherBase::isCanceled(void) const + ?expectedResultCount@QFutureInterfaceBase@@QAEHXZ @ 4925 NONAME ; int QFutureInterfaceBase::expectedResultCount(void) + ??_EQFutureInterfaceBase@@UAE@I@Z @ 4926 NONAME ; QFutureInterfaceBase::~QFutureInterfaceBase(unsigned int) + ?waitForResult@QFutureInterfaceBase@@QAEXH@Z @ 4927 NONAME ; void QFutureInterfaceBase::waitForResult(int) + ?d_func@QFutureWatcherBase@@ABEPBVQFutureWatcherBasePrivate@@XZ @ 4928 NONAME ; class QFutureWatcherBasePrivate const * QFutureWatcherBase::d_func(void) const + ?setPaused@QFutureInterfaceBase@@QAEX_N@Z @ 4929 NONAME ; void QFutureInterfaceBase::setPaused(bool) + ??_EThreadEngineBase@QtConcurrent@@UAE@I@Z @ 4930 NONAME ; QtConcurrent::ThreadEngineBase::~ThreadEngineBase(unsigned int) + ??0Exception@QtConcurrent@@QAE@ABV01@@Z @ 4931 NONAME ; QtConcurrent::Exception::Exception(class QtConcurrent::Exception const &) + ?referenceCountIsOne@QFutureInterfaceBase@@IBE_NXZ @ 4932 NONAME ; bool QFutureInterfaceBase::referenceCountIsOne(void) const + ?progressText@QFutureInterfaceBase@@QBE?AVQString@@XZ @ 4933 NONAME ; class QString QFutureInterfaceBase::progressText(void) const + ?startThreadInternal@ThreadEngineBase@QtConcurrent@@AAE_NXZ @ 4934 NONAME ; bool QtConcurrent::ThreadEngineBase::startThreadInternal(void) + ?addResult@ResultStoreBase@QtConcurrent@@QAEHHPBX@Z @ 4935 NONAME ; int QtConcurrent::ResultStoreBase::addResult(int, void const *) + ?waitForFinished@QFutureWatcherBase@@QAEXXZ @ 4936 NONAME ; void QFutureWatcherBase::waitForFinished(void) + ?togglePaused@QFutureInterfaceBase@@QAEXXZ @ 4937 NONAME ; void QFutureInterfaceBase::togglePaused(void) + ?isProgressUpdateNeeded@QFutureInterfaceBase@@QBE_NXZ @ 4938 NONAME ; bool QFutureInterfaceBase::isProgressUpdateNeeded(void) const + ?resultReadyAt@QFutureWatcherBase@@IAEXH@Z @ 4939 NONAME ; void QFutureWatcherBase::resultReadyAt(int) + ?waitForNextResult@QFutureInterfaceBase@@QAE_NXZ @ 4940 NONAME ; bool QFutureInterfaceBase::waitForNextResult(void) + ?raise@UnhandledException@QtConcurrent@@UBEXXZ @ 4941 NONAME ; void QtConcurrent::UnhandledException::raise(void) const + ?setProgressValue@QFutureInterfaceBase@@QAEXH@Z @ 4942 NONAME ; void QFutureInterfaceBase::setProgressValue(int) + ?startThreads@ThreadEngineBase@QtConcurrent@@AAEXXZ @ 4943 NONAME ; void QtConcurrent::ThreadEngineBase::startThreads(void) + ?isPaused@QFutureInterfaceBase@@QBE_NXZ @ 4944 NONAME ; bool QFutureInterfaceBase::isPaused(void) const + ?resultStoreBase@QFutureInterfaceBase@@QAEAAVResultStoreBase@QtConcurrent@@XZ @ 4945 NONAME ; class QtConcurrent::ResultStoreBase & QFutureInterfaceBase::resultStoreBase(void) + ?isRunning@QFutureInterfaceBase@@QBE_NXZ @ 4946 NONAME ; bool QFutureInterfaceBase::isRunning(void) const + ?begin@ResultStoreBase@QtConcurrent@@QBE?AVResultIteratorBase@2@XZ @ 4947 NONAME ; class QtConcurrent::ResultIteratorBase QtConcurrent::ResultStoreBase::begin(void) const + ?resultStoreBase@QFutureInterfaceBase@@QBEABVResultStoreBase@QtConcurrent@@XZ @ 4948 NONAME ; class QtConcurrent::ResultStoreBase const & QFutureInterfaceBase::resultStoreBase(void) const + ?setExpectedResultCount@QFutureInterfaceBase@@QAEXH@Z @ 4949 NONAME ; void QFutureInterfaceBase::setExpectedResultCount(int) + ?progressMaximum@QFutureWatcherBase@@QBEHXZ @ 4950 NONAME ; int QFutureWatcherBase::progressMaximum(void) const + ??0ResultStoreBase@QtConcurrent@@QAE@XZ @ 4951 NONAME ; QtConcurrent::ResultStoreBase::ResultStoreBase(void) + ?setProgressRange@QFutureInterfaceBase@@QAEXHH@Z @ 4952 NONAME ; void QFutureInterfaceBase::setProgressRange(int, int) + ?canIncrementVectorIndex@ResultIteratorBase@QtConcurrent@@QBE_NXZ @ 4953 NONAME ; bool QtConcurrent::ResultIteratorBase::canIncrementVectorIndex(void) const + ?progressValue@QFutureInterfaceBase@@QBEHXZ @ 4954 NONAME ; int QFutureInterfaceBase::progressValue(void) const + ?cancel@QFutureWatcherBase@@QAEXXZ @ 4955 NONAME ; void QFutureWatcherBase::cancel(void) + ?trolltechConf@QCoreApplicationPrivate@@SAPAVQSettings@@XZ @ 4956 NONAME ; class QSettings * QCoreApplicationPrivate::trolltechConf(void) + ?trUtf8@QFutureWatcherBase@@SA?AVQString@@PBD0@Z @ 4957 NONAME ; class QString QFutureWatcherBase::trUtf8(char const *, char const *) + ?getStaticMetaObject@QFutureWatcherBase@@SAABUQMetaObject@@XZ @ 4958 NONAME ; struct QMetaObject const & QFutureWatcherBase::getStaticMetaObject(void) + ?vectorIndex@ResultIteratorBase@QtConcurrent@@QBEHXZ @ 4959 NONAME ; int QtConcurrent::ResultIteratorBase::vectorIndex(void) const + ?syncPendingResults@ResultStoreBase@QtConcurrent@@IAEXXZ @ 4960 NONAME ; void QtConcurrent::ResultStoreBase::syncPendingResults(void) + ?progressText@QFutureWatcherBase@@QBE?AVQString@@XZ @ 4961 NONAME ; class QString QFutureWatcherBase::progressText(void) const + ??1QFutureWatcherBase@@UAE@XZ @ 4962 NONAME ; QFutureWatcherBase::~QFutureWatcherBase(void) + ?togglePaused@QFutureWatcherBase@@QAEXXZ @ 4963 NONAME ; void QFutureWatcherBase::togglePaused(void) + ?acquireBarrierSemaphore@ThreadEngineBase@QtConcurrent@@QAEXXZ @ 4964 NONAME ; void QtConcurrent::ThreadEngineBase::acquireBarrierSemaphore(void) + ?setFilterMode@ResultStoreBase@QtConcurrent@@QAEX_N@Z @ 4965 NONAME ; void QtConcurrent::ResultStoreBase::setFilterMode(bool) + ?disconnectNotify@QFutureWatcherBase@@MAEXPBD@Z @ 4966 NONAME ; void QFutureWatcherBase::disconnectNotify(char const *) + ?handleException@ThreadEngineBase@QtConcurrent@@AAEXABVException@2@@Z @ 4967 NONAME ; void QtConcurrent::ThreadEngineBase::handleException(class QtConcurrent::Exception const &) + ?setThrottled@QFutureInterfaceBase@@QAEX_N@Z @ 4968 NONAME ; void QFutureInterfaceBase::setThrottled(bool) + ?setProgressValue@ThreadEngineBase@QtConcurrent@@QAEXH@Z @ 4969 NONAME ; void QtConcurrent::ThreadEngineBase::setProgressValue(int) + ??4QFutureInterfaceBase@@QAEAAV0@ABV0@@Z @ 4970 NONAME ; class QFutureInterfaceBase & QFutureInterfaceBase::operator=(class QFutureInterfaceBase const &) + ?isFinished@QFutureInterfaceBase@@QBE_NXZ @ 4971 NONAME ; bool QFutureInterfaceBase::isFinished(void) const + ?progressRangeChanged@QFutureWatcherBase@@IAEXHH@Z @ 4972 NONAME ; void QFutureWatcherBase::progressRangeChanged(int, int) + ?finish@ThreadEngineBase@QtConcurrent@@MAEXXZ @ 4973 NONAME ; void QtConcurrent::ThreadEngineBase::finish(void) + ?isRunning@QFutureWatcherBase@@QBE_NXZ @ 4974 NONAME ; bool QFutureWatcherBase::isRunning(void) const + ?reportResultsReady@QFutureInterfaceBase@@QAEXHH@Z @ 4975 NONAME ; void QFutureInterfaceBase::reportResultsReady(int, int) + ?qt_static_metacall@QFutureWatcherBase@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 4976 NONAME ; void QFutureWatcherBase::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) + ?blockSize@BlockSizeManager@QtConcurrent@@QAEHXZ @ 4977 NONAME ; int QtConcurrent::BlockSizeManager::blockSize(void) + ??0BlockSizeManager@QtConcurrent@@QAE@H@Z @ 4978 NONAME ; QtConcurrent::BlockSizeManager::BlockSizeManager(int) + ?batchSize@ResultIteratorBase@QtConcurrent@@QBEHXZ @ 4979 NONAME ; int QtConcurrent::ResultIteratorBase::batchSize(void) const + ?started@QFutureWatcherBase@@IAEXXZ @ 4980 NONAME ; void QFutureWatcherBase::started(void) + ?metaObject@QFutureWatcherBase@@UBEPBUQMetaObject@@XZ @ 4981 NONAME ; struct QMetaObject const * QFutureWatcherBase::metaObject(void) const + ?resumed@QFutureWatcherBase@@IAEXXZ @ 4982 NONAME ; void QFutureWatcherBase::resumed(void) + ??0UnhandledException@QtConcurrent@@QAE@ABV01@@Z @ 4983 NONAME ; QtConcurrent::UnhandledException::UnhandledException(class QtConcurrent::UnhandledException const &) + ?timeBeforeUser@BlockSizeManager@QtConcurrent@@QAEXXZ @ 4984 NONAME ; void QtConcurrent::BlockSizeManager::timeBeforeUser(void) + ??EResultIteratorBase@QtConcurrent@@QAE?AV01@XZ @ 4985 NONAME ; class QtConcurrent::ResultIteratorBase QtConcurrent::ResultIteratorBase::operator++(void) + ?isResultReadyAt@QFutureInterfaceBase@@QBE_NH@Z @ 4986 NONAME ; bool QFutureInterfaceBase::isResultReadyAt(int) const + ?throwPossibleException@ExceptionStore@internal@QtConcurrent@@QAEXXZ @ 4987 NONAME ; void QtConcurrent::internal::ExceptionStore::throwPossibleException(void) + ?setPendingResultsLimit@QFutureWatcherBase@@QAEXH@Z @ 4988 NONAME ; void QFutureWatcherBase::setPendingResultsLimit(int) + ?resultCount@QFutureInterfaceBase@@QBEHXZ @ 4989 NONAME ; int QFutureInterfaceBase::resultCount(void) const + ?event@QFutureWatcherBase@@UAE_NPAVQEvent@@@Z @ 4990 NONAME ; bool QFutureWatcherBase::event(class QEvent *) + ?isPaused@QFutureWatcherBase@@QBE_NXZ @ 4991 NONAME ; bool QFutureWatcherBase::isPaused(void) const + ?clone@Exception@QtConcurrent@@UBEPAV12@XZ @ 4992 NONAME ; class QtConcurrent::Exception * QtConcurrent::Exception::clone(void) const + ?insertResultItemIfValid@ResultStoreBase@QtConcurrent@@IAEXHAAVResultItem@2@@Z @ 4993 NONAME ; void QtConcurrent::ResultStoreBase::insertResultItemIfValid(int, class QtConcurrent::ResultItem &) + ?reportException@QFutureInterfaceBase@@QAEXABVException@QtConcurrent@@@Z @ 4994 NONAME ; void QFutureInterfaceBase::reportException(class QtConcurrent::Exception const &) + ?waitForFinished@QFutureInterfaceBase@@QAEXXZ @ 4995 NONAME ; void QFutureInterfaceBase::waitForFinished(void) + ??0ResultIteratorBase@QtConcurrent@@QAE@Vconst_iterator@?$QMap@HVResultItem@QtConcurrent@@@@H@Z @ 4996 NONAME ; QtConcurrent::ResultIteratorBase::ResultIteratorBase(class QMap<int, class QtConcurrent::ResultItem>::const_iterator, int) + ?reportStarted@QFutureInterfaceBase@@QAEXXZ @ 4997 NONAME ; void QFutureInterfaceBase::reportStarted(void) + ??8QFutureInterfaceBase@@QBE_NABV0@@Z @ 4998 NONAME ; bool QFutureInterfaceBase::operator==(class QFutureInterfaceBase const &) const + ?addResults@ResultStoreBase@QtConcurrent@@QAEHHPBXHH@Z @ 4999 NONAME ; int QtConcurrent::ResultStoreBase::addResults(int, void const *, int, int) + ?shouldThrottleThread@ThreadEngineBase@QtConcurrent@@MAE_NXZ @ 5000 NONAME ; bool QtConcurrent::ThreadEngineBase::shouldThrottleThread(void) + ?reportFinished@QFutureInterfaceBase@@QAEXXZ @ 5001 NONAME ; void QFutureInterfaceBase::reportFinished(void) + ??0ThreadEngineBase@QtConcurrent@@QAE@XZ @ 5002 NONAME ; QtConcurrent::ThreadEngineBase::ThreadEngineBase(void) + ??1Exception@QtConcurrent@@UAE@XZ @ 5003 NONAME ; QtConcurrent::Exception::~Exception(void) + ?filterMode@ResultStoreBase@QtConcurrent@@QBE_NXZ @ 5004 NONAME ; bool QtConcurrent::ResultStoreBase::filterMode(void) const + ?raise@Exception@QtConcurrent@@UBEXXZ @ 5005 NONAME ; void QtConcurrent::Exception::raise(void) const + ?batchedAdvance@ResultIteratorBase@QtConcurrent@@QAEXXZ @ 5006 NONAME ; void QtConcurrent::ResultIteratorBase::batchedAdvance(void) + ?exceptionStore@QFutureInterfaceBase@@QAEAAVExceptionStore@internal@QtConcurrent@@XZ @ 5007 NONAME ; class QtConcurrent::internal::ExceptionStore & QFutureInterfaceBase::exceptionStore(void) + ?reportCanceled@QFutureInterfaceBase@@QAEXXZ @ 5008 NONAME ; void QFutureInterfaceBase::reportCanceled(void) + ?connectNotify@QFutureWatcherBase@@MAEXPBD@Z @ 5009 NONAME ; void QFutureWatcherBase::connectNotify(char const *) + ??1ResultStoreBase@QtConcurrent@@UAE@XZ @ 5010 NONAME ; QtConcurrent::ResultStoreBase::~ResultStoreBase(void) + ?isCanceled@ThreadEngineBase@QtConcurrent@@QAE_NXZ @ 5011 NONAME ; bool QtConcurrent::ThreadEngineBase::isCanceled(void) + ?canceled@QFutureWatcherBase@@IAEXXZ @ 5012 NONAME ; void QFutureWatcherBase::canceled(void) + ?clone@UnhandledException@QtConcurrent@@UBEPAVException@2@XZ @ 5013 NONAME ; class QtConcurrent::Exception * QtConcurrent::UnhandledException::clone(void) const diff --git a/src/s60installs/bwins/QtGuiu.def b/src/s60installs/bwins/QtGuiu.def index 813bbf8..88973f9 100644 --- a/src/s60installs/bwins/QtGuiu.def +++ b/src/s60installs/bwins/QtGuiu.def @@ -12855,7 +12855,7 @@ EXPORTS ?populate@QTextureGlyphCache@@QAEXPAVQFontEngine@@HPBIPBUQFixedPoint@@@Z @ 12854 NONAME ABSENT ; void QTextureGlyphCache::populate(class QFontEngine *, int, unsigned int const *, struct QFixedPoint const *) ?hasPartialUpdateSupport@QWindowSurface@@UBE_NXZ @ 12855 NONAME ABSENT ; bool QWindowSurface::hasPartialUpdateSupport(void) const ?scroll@QRuntimePixmapData@@UAE_NHHABVQRect@@@Z @ 12856 NONAME ; bool QRuntimePixmapData::scroll(int, int, class QRect const &) - ?qt_draw_glyphs@@YAXPAVQPainter@@PBIPBVQPointF@@H@Z @ 12857 NONAME ; void qt_draw_glyphs(class QPainter *, unsigned int const *, class QPointF const *, int) + ?qt_draw_glyphs@@YAXPAVQPainter@@PBIPBVQPointF@@H@Z @ 12857 NONAME ABSENT ; void qt_draw_glyphs(class QPainter *, unsigned int const *, class QPointF const *, int) ?nativeDisplay@QEgl@@YAHXZ @ 12858 NONAME ; int QEgl::nativeDisplay(void) ?PreDocConstructL@QS60MainApplication@@UAEXXZ @ 12859 NONAME ; void QS60MainApplication::PreDocConstructL(void) ?detach@QStaticText@@AAEXXZ @ 12860 NONAME ; void QStaticText::detach(void) @@ -13213,7 +13213,7 @@ EXPORTS ??0QRasterWindowSurface@@QAE@PAVQWidget@@_N@Z @ 13212 NONAME ; QRasterWindowSurface::QRasterWindowSurface(class QWidget *, bool) ?brushChanged@QBlitterPaintEngine@@UAEXXZ @ 13213 NONAME ; void QBlitterPaintEngine::brushChanged(void) ?clip@QBlitterPaintEngine@@UAEXABVQRect@@W4ClipOperation@Qt@@@Z @ 13214 NONAME ; void QBlitterPaintEngine::clip(class QRect const &, enum Qt::ClipOperation) - ?detach@QGlyphs@@AAEXXZ @ 13215 NONAME ; void QGlyphs::detach(void) + ?detach@QGlyphs@@AAEXXZ @ 13215 NONAME ABSENT ; void QGlyphs::detach(void) ?trUtf8@QInternalMimeData@@SA?AVQString@@PBD0@Z @ 13216 NONAME ; class QString QInternalMimeData::trUtf8(char const *, char const *) ??0QShowEvent@@QAE@ABV0@@Z @ 13217 NONAME ABSENT ; QShowEvent::QShowEvent(class QShowEvent const &) ??0QMouseEvent@@QAE@ABV0@@Z @ 13218 NONAME ABSENT ; QMouseEvent::QMouseEvent(class QMouseEvent const &) @@ -13260,7 +13260,7 @@ EXPORTS ?trUtf8@QFlickGesture@@SA?AVQString@@PBD0@Z @ 13259 NONAME ; class QString QFlickGesture::trUtf8(char const *, char const *) ?stop@QScroller@@QAEXXZ @ 13260 NONAME ; void QScroller::stop(void) ?retrieveData@QInternalMimeData@@MBE?AVQVariant@@ABVQString@@W4Type@2@@Z @ 13261 NONAME ; class QVariant QInternalMimeData::retrieveData(class QString const &, enum QVariant::Type) const - ??8QGlyphs@@QBE_NABV0@@Z @ 13262 NONAME ; bool QGlyphs::operator==(class QGlyphs const &) const + ??8QGlyphs@@QBE_NABV0@@Z @ 13262 NONAME ABSENT ; bool QGlyphs::operator==(class QGlyphs const &) const ?drawImage@QBlitterPaintEngine@@UAEXABVQRectF@@ABVQImage@@0V?$QFlags@W4ImageConversionFlag@Qt@@@@@Z @ 13263 NONAME ; void QBlitterPaintEngine::drawImage(class QRectF const &, class QImage const &, class QRectF const &, class QFlags<enum Qt::ImageConversionFlag>) ?contentPos@QScrollEvent@@QBE?AVQPointF@@XZ @ 13264 NONAME ; class QPointF QScrollEvent::contentPos(void) const ?mimeTypes@QAbstractProxyModel@@UBE?AVQStringList@@XZ @ 13265 NONAME ; class QStringList QAbstractProxyModel::mimeTypes(void) const @@ -13286,7 +13286,7 @@ EXPORTS ?canFetchMore@QAbstractProxyModel@@UBE_NABVQModelIndex@@@Z @ 13285 NONAME ; bool QAbstractProxyModel::canFetchMore(class QModelIndex const &) const ??4QStyleOptionProgressBarV2@@QAEAAV0@ABV0@@Z @ 13286 NONAME ABSENT ; class QStyleOptionProgressBarV2 & QStyleOptionProgressBarV2::operator=(class QStyleOptionProgressBarV2 const &) ??1QScroller@@EAE@XZ @ 13287 NONAME ; QScroller::~QScroller(void) - ?setFont@QGlyphs@@QAEXABVQFont@@@Z @ 13288 NONAME ; void QGlyphs::setFont(class QFont const &) + ?setFont@QGlyphs@@QAEXABVQFont@@@Z @ 13288 NONAME ABSENT ; void QGlyphs::setFont(class QFont const &) ?startPos@QScrollPrepareEvent@@QBE?AVQPointF@@XZ @ 13289 NONAME ; class QPointF QScrollPrepareEvent::startPos(void) const ?resize@QBlittablePixmapData@@UAEXHH@Z @ 13290 NONAME ; void QBlittablePixmapData::resize(int, int) ?setTabsClosable@QMdiArea@@QAEX_N@Z @ 13291 NONAME ; void QMdiArea::setTabsClosable(bool) @@ -13304,14 +13304,14 @@ EXPORTS ?opacityChanged@QBlitterPaintEngine@@UAEXXZ @ 13303 NONAME ; void QBlitterPaintEngine::opacityChanged(void) ?tr@QFlickGesture@@SA?AVQString@@PBD0H@Z @ 13304 NONAME ; class QString QFlickGesture::tr(char const *, char const *, int) ??_EQTextCursor@@QAE@I@Z @ 13305 NONAME ABSENT ; QTextCursor::~QTextCursor(unsigned int) - ?createExplicitFontWithName@QFontEngine@@IBE?AVQFont@@ABVQString@@@Z @ 13306 NONAME ; class QFont QFontEngine::createExplicitFontWithName(class QString const &) const + ?createExplicitFontWithName@QFontEngine@@IBE?AVQFont@@ABVQString@@@Z @ 13306 NONAME ABSENT ; class QFont QFontEngine::createExplicitFontWithName(class QString const &) const ?setState@QBlitterPaintEngine@@UAEXPAVQPainterState@@@Z @ 13307 NONAME ; void QBlitterPaintEngine::setState(class QPainterState *) ?clip@QBlitterPaintEngine@@UAEXABVQRegion@@W4ClipOperation@Qt@@@Z @ 13308 NONAME ; void QBlitterPaintEngine::clip(class QRegion const &, enum Qt::ClipOperation) ?subPixelPositionForX@QTextureGlyphCache@@QBE?AUQFixed@@U2@@Z @ 13309 NONAME ; struct QFixed QTextureGlyphCache::subPixelPositionForX(struct QFixed) const ?hasAlphaChannel@QBlittablePixmapData@@UBE_NXZ @ 13310 NONAME ; bool QBlittablePixmapData::hasAlphaChannel(void) const ?setSnapPositionsX@QScroller@@QAEXABV?$QList@M@@@Z @ 13311 NONAME ; void QScroller::setSnapPositionsX(class QList<float> const &) ?numberSuffix@QTextListFormat@@QBE?AVQString@@XZ @ 13312 NONAME ; class QString QTextListFormat::numberSuffix(void) const - ??HQGlyphs@@ABE?AV0@ABV0@@Z @ 13313 NONAME ; class QGlyphs QGlyphs::operator+(class QGlyphs const &) const + ??HQGlyphs@@ABE?AV0@ABV0@@Z @ 13313 NONAME ABSENT ; class QGlyphs QGlyphs::operator+(class QGlyphs const &) const ??0QGradient@@QAE@ABV0@@Z @ 13314 NONAME ABSENT ; QGradient::QGradient(class QGradient const &) ?tabsMovable@QMdiArea@@QBE_NXZ @ 13315 NONAME ; bool QMdiArea::tabsMovable(void) const ??4QInputMethodEvent@@QAEAAV0@ABV0@@Z @ 13316 NONAME ABSENT ; class QInputMethodEvent & QInputMethodEvent::operator=(class QInputMethodEvent const &) @@ -13329,7 +13329,7 @@ EXPORTS ??_EQKeySequence@@QAE@I@Z @ 13328 NONAME ABSENT ; QKeySequence::~QKeySequence(unsigned int) ?tr@QInternalMimeData@@SA?AVQString@@PBD0H@Z @ 13329 NONAME ; class QString QInternalMimeData::tr(char const *, char const *, int) ?velocity@QScroller@@QBE?AVQPointF@@XZ @ 13330 NONAME ; class QPointF QScroller::velocity(void) const - ?glyphIndexes@QGlyphs@@QBE?AV?$QVector@I@@XZ @ 13331 NONAME ; class QVector<unsigned int> QGlyphs::glyphIndexes(void) const + ?glyphIndexes@QGlyphs@@QBE?AV?$QVector@I@@XZ @ 13331 NONAME ABSENT ; class QVector<unsigned int> QGlyphs::glyphIndexes(void) const ?get@QFontPrivate@@SAPAV1@ABVQFont@@@Z @ 13332 NONAME ; class QFontPrivate * QFontPrivate::get(class QFont const &) ?setScrollMetric@QScrollerProperties@@QAEXW4ScrollMetric@1@ABVQVariant@@@Z @ 13333 NONAME ; void QScrollerProperties::setScrollMetric(enum QScrollerProperties::ScrollMetric, class QVariant const &) ??4QGradient@@QAEAAV0@ABV0@@Z @ 13334 NONAME ABSENT ; class QGradient & QGradient::operator=(class QGradient const &) @@ -13339,7 +13339,7 @@ EXPORTS ??0QTextTableFormat@@QAE@ABV0@@Z @ 13338 NONAME ABSENT ; QTextTableFormat::QTextTableFormat(class QTextTableFormat const &) ??_EQImagePixmapCleanupHooks@@QAE@I@Z @ 13339 NONAME ABSENT ; QImagePixmapCleanupHooks::~QImagePixmapCleanupHooks(unsigned int) ?fetchMore@QAbstractProxyModel@@UAEXABVQModelIndex@@@Z @ 13340 NONAME ; void QAbstractProxyModel::fetchMore(class QModelIndex const &) - ?glyphs@QTextLine@@ABE?AV?$QList@VQGlyphs@@@@HH@Z @ 13341 NONAME ; class QList<class QGlyphs> QTextLine::glyphs(int, int) const + ?glyphs@QTextLine@@ABE?AV?$QList@VQGlyphs@@@@HH@Z @ 13341 NONAME ABSENT ; class QList<class QGlyphs> QTextLine::glyphs(int, int) const ?getStaticMetaObject@QFlickGesture@@SAABUQMetaObject@@XZ @ 13342 NONAME ; struct QMetaObject const & QFlickGesture::getStaticMetaObject(void) ?setViewportSize@QScrollPrepareEvent@@QAEXABVQSizeF@@@Z @ 13343 NONAME ; void QScrollPrepareEvent::setViewportSize(class QSizeF const &) ??0QStatusTipEvent@@QAE@ABV0@@Z @ 13344 NONAME ABSENT ; QStatusTipEvent::QStatusTipEvent(class QStatusTipEvent const &) @@ -13374,7 +13374,7 @@ EXPORTS ??4QStyleOptionQ3DockWindow@@QAEAAV0@ABV0@@Z @ 13373 NONAME ABSENT ; class QStyleOptionQ3DockWindow & QStyleOptionQ3DockWindow::operator=(class QStyleOptionQ3DockWindow const &) ?qt_metacast@QFlickGesture@@UAEPAXPBD@Z @ 13374 NONAME ; void * QFlickGesture::qt_metacast(char const *) ??_EQFont@@QAE@I@Z @ 13375 NONAME ABSENT ; QFont::~QFont(unsigned int) - ?setPositions@QGlyphs@@QAEXABV?$QVector@VQPointF@@@@@Z @ 13376 NONAME ; void QGlyphs::setPositions(class QVector<class QPointF> const &) + ?setPositions@QGlyphs@@QAEXABV?$QVector@VQPointF@@@@@Z @ 13376 NONAME ABSENT ; void QGlyphs::setPositions(class QVector<class QPointF> const &) ??4QStyleOptionDockWidget@@QAEAAV0@ABV0@@Z @ 13377 NONAME ABSENT ; class QStyleOptionDockWidget & QStyleOptionDockWidget::operator=(class QStyleOptionDockWidget const &) ??0QPainterState@@QAE@ABV0@@Z @ 13378 NONAME ABSENT ; QPainterState::QPainterState(class QPainterState const &) ??4QStyleOptionFrame@@QAEAAV0@ABV0@@Z @ 13379 NONAME ABSENT ; class QStyleOptionFrame & QStyleOptionFrame::operator=(class QStyleOptionFrame const &) @@ -13384,7 +13384,7 @@ EXPORTS ?renderHintsChanged@QBlitterPaintEngine@@UAEXXZ @ 13383 NONAME ; void QBlitterPaintEngine::renderHintsChanged(void) ?supportedDropActions@QAbstractProxyModel@@UBE?AV?$QFlags@W4DropAction@Qt@@@@XZ @ 13384 NONAME ; class QFlags<enum Qt::DropAction> QAbstractProxyModel::supportedDropActions(void) const ?fillRect@QBlitterPaintEngine@@UAEXABVQRectF@@ABVQBrush@@@Z @ 13385 NONAME ; void QBlitterPaintEngine::fillRect(class QRectF const &, class QBrush const &) - ?setGlyphIndexes@QGlyphs@@QAEXABV?$QVector@I@@@Z @ 13386 NONAME ; void QGlyphs::setGlyphIndexes(class QVector<unsigned int> const &) + ?setGlyphIndexes@QGlyphs@@QAEXABV?$QVector@I@@@Z @ 13386 NONAME ABSENT ; void QGlyphs::setGlyphIndexes(class QVector<unsigned int> const &) ?alphaMapBoundingBox@QFontEngine@@UAE?AUglyph_metrics_t@@IABVQTransform@@W4GlyphFormat@1@@Z @ 13387 NONAME ABSENT ; struct glyph_metrics_t QFontEngine::alphaMapBoundingBox(unsigned int, class QTransform const &, enum QFontEngine::GlyphFormat) ?resendPrepareEvent@QScroller@@QAEXXZ @ 13388 NONAME ; void QScroller::resendPrepareEvent(void) ??4QTextLength@@QAEAAV0@ABV0@@Z @ 13389 NONAME ABSENT ; class QTextLength & QTextLength::operator=(class QTextLength const &) @@ -13399,12 +13399,12 @@ EXPORTS ?scrollTo@QScroller@@QAEXABVQPointF@@H@Z @ 13398 NONAME ; void QScroller::scrollTo(class QPointF const &, int) ?ungrabGesture@QScroller@@SAXPAVQObject@@@Z @ 13399 NONAME ; void QScroller::ungrabGesture(class QObject *) ??4QItemSelectionRange@@QAEAAV0@ABV0@@Z @ 13400 NONAME ABSENT ; class QItemSelectionRange & QItemSelectionRange::operator=(class QItemSelectionRange const &) - ?clear@QGlyphs@@QAEXXZ @ 13401 NONAME ; void QGlyphs::clear(void) + ?clear@QGlyphs@@QAEXXZ @ 13401 NONAME ABSENT ; void QGlyphs::clear(void) ??_EQStyleOptionViewItemV4@@QAE@I@Z @ 13402 NONAME ABSENT ; QStyleOptionViewItemV4::~QStyleOptionViewItemV4(unsigned int) ??1QBlittablePixmapData@@UAE@XZ @ 13403 NONAME ; QBlittablePixmapData::~QBlittablePixmapData(void) ?formatsHelper@QInternalMimeData@@SA?AVQStringList@@PBVQMimeData@@@Z @ 13404 NONAME ; class QStringList QInternalMimeData::formatsHelper(class QMimeData const *) ?qt_metacast@QInternalMimeData@@UAEPAXPBD@Z @ 13405 NONAME ; void * QInternalMimeData::qt_metacast(char const *) - ?font@QGlyphs@@QBE?AVQFont@@XZ @ 13406 NONAME ; class QFont QGlyphs::font(void) const + ?font@QGlyphs@@QBE?AVQFont@@XZ @ 13406 NONAME ABSENT ; class QFont QGlyphs::font(void) const ?paintEngine@QBlittablePixmapData@@UBEPAVQPaintEngine@@XZ @ 13407 NONAME ; class QPaintEngine * QBlittablePixmapData::paintEngine(void) const ?unsetDefaultScrollerProperties@QScrollerProperties@@SAXXZ @ 13408 NONAME ; void QScrollerProperties::unsetDefaultScrollerProperties(void) ?hasChildren@QAbstractProxyModel@@UBE_NABVQModelIndex@@@Z @ 13409 NONAME ; bool QAbstractProxyModel::hasChildren(class QModelIndex const &) const @@ -13422,7 +13422,7 @@ EXPORTS ?qt_metacall@QInternalMimeData@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 13421 NONAME ; int QInternalMimeData::qt_metacall(enum QMetaObject::Call, int, void * *) ?lineHeightType@QTextBlockFormat@@QBEHXZ @ 13422 NONAME ; int QTextBlockFormat::lineHeightType(void) const ?hintingPreference@QFont@@QBE?AW4HintingPreference@1@XZ @ 13423 NONAME ; enum QFont::HintingPreference QFont::hintingPreference(void) const - ??0QGlyphs@@QAE@XZ @ 13424 NONAME ; QGlyphs::QGlyphs(void) + ??0QGlyphs@@QAE@XZ @ 13424 NONAME ABSENT ; QGlyphs::QGlyphs(void) ?trUtf8@QInternalMimeData@@SA?AVQString@@PBD0H@Z @ 13425 NONAME ; class QString QInternalMimeData::trUtf8(char const *, char const *, int) ??0QImageIOHandlerFactoryInterface@@QAE@XZ @ 13426 NONAME ABSENT ; QImageIOHandlerFactoryInterface::QImageIOHandlerFactoryInterface(void) ??_EQRegion@@QAE@I@Z @ 13427 NONAME ABSENT ; QRegion::~QRegion(unsigned int) @@ -13442,10 +13442,10 @@ EXPORTS ?clip@QBlitterPaintEngine@@UAEXABVQVectorPath@@W4ClipOperation@Qt@@@Z @ 13441 NONAME ; void QBlitterPaintEngine::clip(class QVectorPath const &, enum Qt::ClipOperation) ??1QScrollEvent@@UAE@XZ @ 13442 NONAME ; QScrollEvent::~QScrollEvent(void) ?state@QScroller@@QBE?AW4State@1@XZ @ 13443 NONAME ; enum QScroller::State QScroller::state(void) const - ?positions@QGlyphs@@QBE?AV?$QVector@VQPointF@@@@XZ @ 13444 NONAME ; class QVector<class QPointF> QGlyphs::positions(void) const + ?positions@QGlyphs@@QBE?AV?$QVector@VQPointF@@@@XZ @ 13444 NONAME ABSENT ; class QVector<class QPointF> QGlyphs::positions(void) const ?tr@QScroller@@SA?AVQString@@PBD0@Z @ 13445 NONAME ; class QString QScroller::tr(char const *, char const *) ?canReadData@QInternalMimeData@@SA_NABVQString@@@Z @ 13446 NONAME ; bool QInternalMimeData::canReadData(class QString const &) - ?glyphs@QTextLayout@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 13447 NONAME ; class QList<class QGlyphs> QTextLayout::glyphs(void) const + ?glyphs@QTextLayout@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 13447 NONAME ABSENT ; class QList<class QGlyphs> QTextLayout::glyphs(void) const ?leadingSpaceWidth@QTextEngine@@QAE?AUQFixed@@ABUQScriptLine@@@Z @ 13448 NONAME ; struct QFixed QTextEngine::leadingSpaceWidth(struct QScriptLine const &) ??_EQTextFormat@@QAE@I@Z @ 13449 NONAME ABSENT ; QTextFormat::~QTextFormat(unsigned int) ??4QStyleOptionTabWidgetFrame@@QAEAAV0@ABV0@@Z @ 13450 NONAME ABSENT ; class QStyleOptionTabWidgetFrame & QStyleOptionTabWidgetFrame::operator=(class QStyleOptionTabWidgetFrame const &) @@ -13463,7 +13463,7 @@ EXPORTS ??0QInternalMimeData@@QAE@XZ @ 13462 NONAME ; QInternalMimeData::QInternalMimeData(void) ??_EQScrollEvent@@UAE@I@Z @ 13463 NONAME ; QScrollEvent::~QScrollEvent(unsigned int) ?features@QRasterWindowSurface@@UBE?AV?$QFlags@W4WindowSurfaceFeature@QWindowSurface@@@@XZ @ 13464 NONAME ; class QFlags<enum QWindowSurface::WindowSurfaceFeature> QRasterWindowSurface::features(void) const - ??4QGlyphs@@QAEAAV0@ABV0@@Z @ 13465 NONAME ; class QGlyphs & QGlyphs::operator=(class QGlyphs const &) + ??4QGlyphs@@QAEAAV0@ABV0@@Z @ 13465 NONAME ABSENT ; class QGlyphs & QGlyphs::operator=(class QGlyphs const &) ??4QQuaternion@@QAEAAV0@ABV0@@Z @ 13466 NONAME ABSENT ; class QQuaternion & QQuaternion::operator=(class QQuaternion const &) ??4Symbol@QCss@@QAEAAU01@ABU01@@Z @ 13467 NONAME ABSENT ; struct QCss::Symbol & QCss::Symbol::operator=(struct QCss::Symbol const &) ??0QBlittable@@QAE@ABVQSize@@V?$QFlags@W4Capability@QBlittable@@@@@Z @ 13468 NONAME ; QBlittable::QBlittable(class QSize const &, class QFlags<enum QBlittable::Capability>) @@ -13480,10 +13480,10 @@ EXPORTS ?calculateSubPixelPositionCount@QTextureGlyphCache@@IBEHI@Z @ 13479 NONAME ; int QTextureGlyphCache::calculateSubPixelPositionCount(unsigned int) const ??0QTextImageFormat@@QAE@ABV0@@Z @ 13480 NONAME ABSENT ; QTextImageFormat::QTextImageFormat(class QTextImageFormat const &) ??0QMoveEvent@@QAE@ABV0@@Z @ 13481 NONAME ABSENT ; QMoveEvent::QMoveEvent(class QMoveEvent const &) - ?glyphs@QTextFragment@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 13482 NONAME ; class QList<class QGlyphs> QTextFragment::glyphs(void) const + ?glyphs@QTextFragment@@QBE?AV?$QList@VQGlyphs@@@@XZ @ 13482 NONAME ABSENT ; class QList<class QGlyphs> QTextFragment::glyphs(void) const ??0QInputContextFactoryInterface@@QAE@XZ @ 13483 NONAME ABSENT ; QInputContextFactoryInterface::QInputContextFactoryInterface(void) ??0QTextFrameFormat@@QAE@ABV0@@Z @ 13484 NONAME ABSENT ; QTextFrameFormat::QTextFrameFormat(class QTextFrameFormat const &) - ?resetInternalData@QAbstractProxyModel@@IAEXXZ @ 13485 NONAME ; void QAbstractProxyModel::resetInternalData(void) + ?resetInternalData@QAbstractProxyModel@@IAEXXZ @ 13485 NONAME ABSENT ; void QAbstractProxyModel::resetInternalData(void) ??0Symbol@QCss@@QAE@ABU01@@Z @ 13486 NONAME ABSENT ; QCss::Symbol::Symbol(struct QCss::Symbol const &) ?features@QWindowSurface@@UBE?AV?$QFlags@W4WindowSurfaceFeature@QWindowSurface@@@@XZ @ 13487 NONAME ; class QFlags<enum QWindowSurface::WindowSurfaceFeature> QWindowSurface::features(void) const ?markRasterOverlay@QBlittablePixmapData@@QAEXABVQVectorPath@@@Z @ 13488 NONAME ; void QBlittablePixmapData::markRasterOverlay(class QVectorPath const &) @@ -13499,7 +13499,7 @@ EXPORTS ?swap@QPainterPath@@QAEXAAV1@@Z @ 13498 NONAME ; void QPainterPath::swap(class QPainterPath &) ??4QStyleOptionRubberBand@@QAEAAV0@ABV0@@Z @ 13499 NONAME ABSENT ; class QStyleOptionRubberBand & QStyleOptionRubberBand::operator=(class QStyleOptionRubberBand const &) ?minimumSizeHint@QCheckBox@@UBE?AVQSize@@XZ @ 13500 NONAME ; class QSize QCheckBox::minimumSizeHint(void) const - ?createExplicitFont@QFontEngine@@UBE?AVQFont@@XZ @ 13501 NONAME ; class QFont QFontEngine::createExplicitFont(void) const + ?createExplicitFont@QFontEngine@@UBE?AVQFont@@XZ @ 13501 NONAME ABSENT ; class QFont QFontEngine::createExplicitFont(void) const ?alphaMapForGlyph@QFontEngine@@UAE?AVQImage@@IUQFixed@@@Z @ 13502 NONAME ; class QImage QFontEngine::alphaMapForGlyph(unsigned int, struct QFixed) ?fillTexture@QImageTextureGlyphCache@@UAEXABUCoord@QTextureGlyphCache@@IUQFixed@@@Z @ 13503 NONAME ; void QImageTextureGlyphCache::fillTexture(struct QTextureGlyphCache::Coord const &, unsigned int, struct QFixed) ?swap@QIcon@@QAEXAAV1@@Z @ 13504 NONAME ; void QIcon::swap(class QIcon &) @@ -13532,11 +13532,11 @@ EXPORTS ?pixelPerMeter@QScroller@@QBE?AVQPointF@@XZ @ 13531 NONAME ; class QPointF QScroller::pixelPerMeter(void) const ?target@QScroller@@QBEPAVQObject@@XZ @ 13532 NONAME ; class QObject * QScroller::target(void) const ?swap@QKeySequence@@QAEXAAV1@@Z @ 13533 NONAME ; void QKeySequence::swap(class QKeySequence &) - ??1QGlyphs@@QAE@XZ @ 13534 NONAME ; QGlyphs::~QGlyphs(void) + ??1QGlyphs@@QAE@XZ @ 13534 NONAME ABSENT ; QGlyphs::~QGlyphs(void) ?lineHeight@QTextBlockFormat@@QBEMXZ @ 13535 NONAME ; float QTextBlockFormat::lineHeight(void) const ?stroke@QBlitterPaintEngine@@UAEXABVQVectorPath@@ABVQPen@@@Z @ 13536 NONAME ; void QBlitterPaintEngine::stroke(class QVectorPath const &, class QPen const &) ?tr@QInternalMimeData@@SA?AVQString@@PBD0@Z @ 13537 NONAME ; class QString QInternalMimeData::tr(char const *, char const *) - ??9QGlyphs@@QBE_NABV0@@Z @ 13538 NONAME ; bool QGlyphs::operator!=(class QGlyphs const &) const + ??9QGlyphs@@QBE_NABV0@@Z @ 13538 NONAME ABSENT ; bool QGlyphs::operator!=(class QGlyphs const &) const ??1QBlittable@@UAE@XZ @ 13539 NONAME ; QBlittable::~QBlittable(void) ??_EQBlitterPaintEngine@@UAE@I@Z @ 13540 NONAME ; QBlitterPaintEngine::~QBlitterPaintEngine(unsigned int) ??0QCloseEvent@@QAE@ABV0@@Z @ 13541 NONAME ABSENT ; QCloseEvent::QCloseEvent(class QCloseEvent const &) @@ -13547,7 +13547,7 @@ EXPORTS ?finalPosition@QScroller@@QBE?AVQPointF@@XZ @ 13546 NONAME ; class QPointF QScroller::finalPosition(void) const ??4QStyleOptionTabWidgetFrameV2@@QAEAAV0@ABV0@@Z @ 13547 NONAME ABSENT ; class QStyleOptionTabWidgetFrameV2 & QStyleOptionTabWidgetFrameV2::operator=(class QStyleOptionTabWidgetFrameV2 const &) ?drawStaticTextItem@QBlitterPaintEngine@@UAEXPAVQStaticTextItem@@@Z @ 13548 NONAME ; void QBlitterPaintEngine::drawStaticTextItem(class QStaticTextItem *) - ??0QGlyphs@@QAE@ABV0@@Z @ 13549 NONAME ; QGlyphs::QGlyphs(class QGlyphs const &) + ??0QGlyphs@@QAE@ABV0@@Z @ 13549 NONAME ABSENT ; QGlyphs::QGlyphs(class QGlyphs const &) ?lock@QBlittable@@QAEPAVQImage@@XZ @ 13550 NONAME ; class QImage * QBlittable::lock(void) ?setFontHintingPreference@QTextCharFormat@@QAEXW4HintingPreference@QFont@@@Z @ 13551 NONAME ; void QTextCharFormat::setFontHintingPreference(enum QFont::HintingPreference) ??4QStyleOptionTabV2@@QAEAAV0@ABV0@@Z @ 13552 NONAME ABSENT ; class QStyleOptionTabV2 & QStyleOptionTabV2::operator=(class QStyleOptionTabV2 const &) @@ -13559,7 +13559,7 @@ EXPORTS ?markRasterOverlay@QBlittablePixmapData@@QAEXABVQPointF@@ABVQTextItem@@@Z @ 13558 NONAME ; void QBlittablePixmapData::markRasterOverlay(class QPointF const &, class QTextItem const &) ?trUtf8@QScroller@@SA?AVQString@@PBD0@Z @ 13559 NONAME ; class QString QScroller::trUtf8(char const *, char const *) ??_EQIcon@@QAE@I@Z @ 13560 NONAME ABSENT ; QIcon::~QIcon(unsigned int) - ??YQGlyphs@@AAEAAV0@ABV0@@Z @ 13561 NONAME ; class QGlyphs & QGlyphs::operator+=(class QGlyphs const &) + ??YQGlyphs@@AAEAAV0@ABV0@@Z @ 13561 NONAME ABSENT ; class QGlyphs & QGlyphs::operator+=(class QGlyphs const &) ??9QScrollerProperties@@QBE_NABV0@@Z @ 13562 NONAME ; bool QScrollerProperties::operator!=(class QScrollerProperties const &) const ??0QTextListFormat@@QAE@ABV0@@Z @ 13563 NONAME ABSENT ; QTextListFormat::QTextListFormat(class QTextListFormat const &) ?drawEllipse@QBlitterPaintEngine@@UAEXABVQRectF@@@Z @ 13564 NONAME ; void QBlitterPaintEngine::drawEllipse(class QRectF const &) @@ -13590,7 +13590,7 @@ EXPORTS ?qt_addBitmapToPath@@YAXMMPBEHHHPAVQPainterPath@@@Z @ 13589 NONAME ; void qt_addBitmapToPath(float, float, unsigned char const *, int, int, int, class QPainterPath *) ?staticMetaObject@QInternalMimeData@@2UQMetaObject@@B @ 13590 NONAME ; struct QMetaObject const QInternalMimeData::staticMetaObject ?activeScrollers@QScroller@@SA?AV?$QList@PAVQScroller@@@@XZ @ 13591 NONAME ; class QList<class QScroller *> QScroller::activeScrollers(void) - ?drawGlyphs@QPainter@@QAEXABVQPointF@@ABVQGlyphs@@@Z @ 13592 NONAME ; void QPainter::drawGlyphs(class QPointF const &, class QGlyphs const &) + ?drawGlyphs@QPainter@@QAEXABVQPointF@@ABVQGlyphs@@@Z @ 13592 NONAME ABSENT ; void QPainter::drawGlyphs(class QPointF const &, class QGlyphs const &) ??4QTextFrameFormat@@QAEAAV0@ABV0@@Z @ 13593 NONAME ABSENT ; class QTextFrameFormat & QTextFrameFormat::operator=(class QTextFrameFormat const &) ?staticMetaObjectExtraData@QStylePlugin@@0UQMetaObjectExtraData@@B @ 13594 NONAME ; struct QMetaObjectExtraData const QStylePlugin::staticMetaObjectExtraData ?staticMetaObjectExtraData@QToolBar@@0UQMetaObjectExtraData@@B @ 13595 NONAME ; struct QMetaObjectExtraData const QToolBar::staticMetaObjectExtraData @@ -13953,4 +13953,71 @@ EXPORTS ?staticMetaObjectExtraData@QWorkspace@@0UQMetaObjectExtraData@@B @ 13952 NONAME ; struct QMetaObjectExtraData const QWorkspace::staticMetaObjectExtraData ?staticMetaObjectExtraData@QSessionManager@@0UQMetaObjectExtraData@@B @ 13953 NONAME ; struct QMetaObjectExtraData const QSessionManager::staticMetaObjectExtraData ?qt_static_metacall@QGraphicsItemAnimation@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 13954 NONAME ; void QGraphicsItemAnimation::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) - + ?cursorMoveStyle@QLineEdit@@QBE?AW4MoveStyle@QTextCursor@@XZ @ 13955 NONAME ; enum QTextCursor::MoveStyle QLineEdit::cursorMoveStyle(void) const + ?focalRadius@QRadialGradient@@QBEMXZ @ 13956 NONAME ; float QRadialGradient::focalRadius(void) const + ?alignLine@QTextEngine@@QAE?AUQFixed@@ABUQScriptLine@@@Z @ 13957 NONAME ; struct QFixed QTextEngine::alignLine(struct QScriptLine const &) + ?match@QIdentityProxyModel@@UBE?AV?$QList@VQModelIndex@@@@ABVQModelIndex@@HABVQVariant@@HV?$QFlags@W4MatchFlag@Qt@@@@@Z @ 13958 NONAME ; class QList<class QModelIndex> QIdentityProxyModel::match(class QModelIndex const &, int, class QVariant const &, int, class QFlags<enum Qt::MatchFlag>) const + ?positionAfterVisualMovement@QTextEngine@@QAEHHW4MoveOperation@QTextCursor@@@Z @ 13959 NONAME ; int QTextEngine::positionAfterVisualMovement(int, enum QTextCursor::MoveOperation) + ?qt_painterPathFromVectorPath@@YA?AVQPainterPath@@ABVQVectorPath@@@Z @ 13960 NONAME ; class QPainterPath qt_painterPathFromVectorPath(class QVectorPath const &) + ?metaObject@QIdentityProxyModel@@UBEPBUQMetaObject@@XZ @ 13961 NONAME ; struct QMetaObject const * QIdentityProxyModel::metaObject(void) const + ?qt_static_metacall@QIdentityProxyModel@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 13962 NONAME ; void QIdentityProxyModel::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) + ?setCursorMoveStyle@QLineControl@@QAEXW4MoveStyle@QTextCursor@@@Z @ 13963 NONAME ; void QLineControl::setCursorMoveStyle(enum QTextCursor::MoveStyle) + ?visualCursorMovement@QTextEngine@@QBE_NXZ @ 13964 NONAME ; bool QTextEngine::visualCursorMovement(void) const + ?setFocalRadius@QRadialGradient@@QAEXM@Z @ 13965 NONAME ; void QRadialGradient::setFocalRadius(float) + ??_EQIdentityProxyModel@@UAE@I@Z @ 13966 NONAME ; QIdentityProxyModel::~QIdentityProxyModel(unsigned int) + ??1QIdentityProxyModel@@UAE@XZ @ 13967 NONAME ; QIdentityProxyModel::~QIdentityProxyModel(void) + ?d_func@QIdentityProxyModel@@AAEPAVQIdentityProxyModelPrivate@@XZ @ 13968 NONAME ; class QIdentityProxyModelPrivate * QIdentityProxyModel::d_func(void) + ?rowCount@QIdentityProxyModel@@UBEHABVQModelIndex@@@Z @ 13969 NONAME ; int QIdentityProxyModel::rowCount(class QModelIndex const &) const + ?previousLogicalPosition@QTextEngine@@QBEHH@Z @ 13970 NONAME ; int QTextEngine::previousLogicalPosition(int) const + ?endOfLine@QTextEngine@@AAEHH@Z @ 13971 NONAME ; int QTextEngine::endOfLine(int) + ?lineNumberForTextPosition@QTextEngine@@QAEHH@Z @ 13972 NONAME ; int QTextEngine::lineNumberForTextPosition(int) + ?mapToSource@QIdentityProxyModel@@UBE?AVQModelIndex@@ABV2@@Z @ 13973 NONAME ; class QModelIndex QIdentityProxyModel::mapToSource(class QModelIndex const &) const + ?setCursorMoveStyle@QTextLayout@@QAEXW4MoveStyle@QTextCursor@@@Z @ 13974 NONAME ; void QTextLayout::setCursorMoveStyle(enum QTextCursor::MoveStyle) + ?dropMimeData@QIdentityProxyModel@@UAE_NPBVQMimeData@@W4DropAction@Qt@@HHABVQModelIndex@@@Z @ 13975 NONAME ; bool QIdentityProxyModel::dropMimeData(class QMimeData const *, enum Qt::DropAction, int, int, class QModelIndex const &) + ?mapSelectionFromSource@QIdentityProxyModel@@UBE?AVQItemSelection@@ABV2@@Z @ 13976 NONAME ; class QItemSelection QIdentityProxyModel::mapSelectionFromSource(class QItemSelection const &) const + ?setInstantInvalidatePropagation@QGraphicsLayout@@SAX_N@Z @ 13977 NONAME ; void QGraphicsLayout::setInstantInvalidatePropagation(bool) + ?mapFromSource@QIdentityProxyModel@@UBE?AVQModelIndex@@ABV2@@Z @ 13978 NONAME ; class QModelIndex QIdentityProxyModel::mapFromSource(class QModelIndex const &) const + ?centerRadius@QRadialGradient@@QBEMXZ @ 13979 NONAME ; float QRadialGradient::centerRadius(void) const + ?mapSelectionToSource@QIdentityProxyModel@@UBE?AVQItemSelection@@ABV2@@Z @ 13980 NONAME ; class QItemSelection QIdentityProxyModel::mapSelectionToSource(class QItemSelection const &) const + ?tr@QIdentityProxyModel@@SA?AVQString@@PBD0H@Z @ 13981 NONAME ; class QString QIdentityProxyModel::tr(char const *, char const *, int) + ?cursorMoveStyle@QTextLayout@@QBE?AW4MoveStyle@QTextCursor@@XZ @ 13982 NONAME ; enum QTextCursor::MoveStyle QTextLayout::cursorMoveStyle(void) const + ?index@QIdentityProxyModel@@UBE?AVQModelIndex@@HHABV2@@Z @ 13983 NONAME ; class QModelIndex QIdentityProxyModel::index(int, int, class QModelIndex const &) const + ?qt_draw_decoration_for_glyphs@@YAXPAVQPainter@@PBIPBUQFixedPoint@@HPAVQFontEngine@@ABVQFont@@ABVQTextCharFormat@@@Z @ 13984 NONAME ; void qt_draw_decoration_for_glyphs(class QPainter *, unsigned int const *, struct QFixedPoint const *, int, class QFontEngine *, class QFont const &, class QTextCharFormat const &) + ?defaultCursorMoveStyle@QTextDocument@@QBE?AW4MoveStyle@QTextCursor@@XZ @ 13985 NONAME ; enum QTextCursor::MoveStyle QTextDocument::defaultCursorMoveStyle(void) const + ?insertRows@QIdentityProxyModel@@UAE_NHHABVQModelIndex@@@Z @ 13986 NONAME ; bool QIdentityProxyModel::insertRows(int, int, class QModelIndex const &) + ?qt_isExtendedRadialGradient@@YA_NABVQBrush@@@Z @ 13987 NONAME ; bool qt_isExtendedRadialGradient(class QBrush const &) + ?trUtf8@QIdentityProxyModel@@SA?AVQString@@PBD0H@Z @ 13988 NONAME ; class QString QIdentityProxyModel::trUtf8(char const *, char const *, int) + ?instantInvalidatePropagation@QGraphicsLayout@@SA_NXZ @ 13989 NONAME ; bool QGraphicsLayout::instantInvalidatePropagation(void) + ?trUtf8@QIdentityProxyModel@@SA?AVQString@@PBD0@Z @ 13990 NONAME ; class QString QIdentityProxyModel::trUtf8(char const *, char const *) + ??0QIdentityProxyModel@@QAE@PAVQObject@@@Z @ 13991 NONAME ; QIdentityProxyModel::QIdentityProxyModel(class QObject *) + ?removeColumns@QIdentityProxyModel@@UAE_NHHABVQModelIndex@@@Z @ 13992 NONAME ; bool QIdentityProxyModel::removeColumns(int, int, class QModelIndex const &) + ??0QIdentityProxyModel@@IAE@AAVQIdentityProxyModelPrivate@@PAVQObject@@@Z @ 13993 NONAME ; QIdentityProxyModel::QIdentityProxyModel(class QIdentityProxyModelPrivate &, class QObject *) + ?tr@QIdentityProxyModel@@SA?AVQString@@PBD0@Z @ 13994 NONAME ; class QString QIdentityProxyModel::tr(char const *, char const *) + ?columnCount@QIdentityProxyModel@@UBEHABVQModelIndex@@@Z @ 13995 NONAME ; int QIdentityProxyModel::columnCount(class QModelIndex const &) const + ??0QRadialGradient@@QAE@MMMMMM@Z @ 13996 NONAME ; QRadialGradient::QRadialGradient(float, float, float, float, float, float) + ?offsetInLigature@QTextEngine@@QAE?AUQFixed@@PBUQScriptItem@@HHH@Z @ 13997 NONAME ; struct QFixed QTextEngine::offsetInLigature(struct QScriptItem const *, int, int, int) + ?cursorMoveStyle@QLineControl@@QBE?AW4MoveStyle@QTextCursor@@XZ @ 13998 NONAME ; enum QTextCursor::MoveStyle QLineControl::cursorMoveStyle(void) const + ?beginningOfLine@QTextEngine@@AAEHH@Z @ 13999 NONAME ; int QTextEngine::beginningOfLine(int) + ?setCenterRadius@QRadialGradient@@QAEXM@Z @ 14000 NONAME ; void QRadialGradient::setCenterRadius(float) + ?setCursorMoveStyle@QLineEdit@@QAEXW4MoveStyle@QTextCursor@@@Z @ 14001 NONAME ; void QLineEdit::setCursorMoveStyle(enum QTextCursor::MoveStyle) + ??0QRadialGradient@@QAE@ABVQPointF@@M0M@Z @ 14002 NONAME ; QRadialGradient::QRadialGradient(class QPointF const &, float, class QPointF const &, float) + ?actionText@QUndoCommand@@QBE?AVQString@@XZ @ 14003 NONAME ; class QString QUndoCommand::actionText(void) const + ?insertionPointsForLine@QTextEngine@@QAEXHAAV?$QVector@H@@@Z @ 14004 NONAME ; void QTextEngine::insertionPointsForLine(int, class QVector<int> &) + ?rightCursorPosition@QTextLayout@@QBEHH@Z @ 14005 NONAME ; int QTextLayout::rightCursorPosition(int) const + ?insertColumns@QIdentityProxyModel@@UAE_NHHABVQModelIndex@@@Z @ 14006 NONAME ; bool QIdentityProxyModel::insertColumns(int, int, class QModelIndex const &) + ?setDefaultCursorMoveStyle@QTextDocument@@QAEXW4MoveStyle@QTextCursor@@@Z @ 14007 NONAME ; void QTextDocument::setDefaultCursorMoveStyle(enum QTextCursor::MoveStyle) + ?doItemsLayout@QTableView@@UAEXXZ @ 14008 NONAME ; void QTableView::doItemsLayout(void) + ?qt_metacast@QIdentityProxyModel@@UAEPAXPBD@Z @ 14009 NONAME ; void * QIdentityProxyModel::qt_metacast(char const *) + ?setSourceModel@QIdentityProxyModel@@UAEXPAVQAbstractItemModel@@@Z @ 14010 NONAME ; void QIdentityProxyModel::setSourceModel(class QAbstractItemModel *) + ?d_func@QIdentityProxyModel@@ABEPBVQIdentityProxyModelPrivate@@XZ @ 14011 NONAME ; class QIdentityProxyModelPrivate const * QIdentityProxyModel::d_func(void) const + ?cloneWithSize@QFontEngine@@UBEPAV1@M@Z @ 14012 NONAME ; class QFontEngine * QFontEngine::cloneWithSize(float) const + ?leftCursorPosition@QTextLayout@@QBEHH@Z @ 14013 NONAME ; int QTextLayout::leftCursorPosition(int) const + ?paintingActive@QVolatileImage@@QBE_NXZ @ 14014 NONAME ; bool QVolatileImage::paintingActive(void) const + ?parent@QIdentityProxyModel@@UBE?AVQModelIndex@@ABV2@@Z @ 14015 NONAME ; class QModelIndex QIdentityProxyModel::parent(class QModelIndex const &) const + ?nextLogicalPosition@QTextEngine@@QBEHH@Z @ 14016 NONAME ; int QTextEngine::nextLogicalPosition(int) const + ?qt_metacall@QIdentityProxyModel@@UAEHW4Call@QMetaObject@@HPAPAX@Z @ 14017 NONAME ; int QIdentityProxyModel::qt_metacall(enum QMetaObject::Call, int, void * *) + ?staticMetaObject@QIdentityProxyModel@@2UQMetaObject@@B @ 14018 NONAME ; struct QMetaObject const QIdentityProxyModel::staticMetaObject + ?staticMetaObjectExtraData@QIdentityProxyModel@@0UQMetaObjectExtraData@@B @ 14019 NONAME ; struct QMetaObjectExtraData const QIdentityProxyModel::staticMetaObjectExtraData + ?getStaticMetaObject@QIdentityProxyModel@@SAABUQMetaObject@@XZ @ 14020 NONAME ; struct QMetaObject const & QIdentityProxyModel::getStaticMetaObject(void) + ?removeRows@QIdentityProxyModel@@UAE_NHHABVQModelIndex@@@Z @ 14021 NONAME ; bool QIdentityProxyModel::removeRows(int, int, class QModelIndex const &) + ?qt_s60_setPartialScreenAutomaticTranslation@@YAX_N@Z @ 14022 NONAME ; void qt_s60_setPartialScreenAutomaticTranslation(bool) diff --git a/src/s60installs/bwins/QtNetworku.def b/src/s60installs/bwins/QtNetworku.def index 49538ef..dd9dfae 100644 --- a/src/s60installs/bwins/QtNetworku.def +++ b/src/s60installs/bwins/QtNetworku.def @@ -1237,4 +1237,9 @@ EXPORTS ?qt_static_metacall@QBearerEnginePlugin@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 1236 NONAME ; void QBearerEnginePlugin::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) ?staticMetaObjectExtraData@QNetworkConfigurationManager@@0UQMetaObjectExtraData@@B @ 1237 NONAME ; struct QMetaObjectExtraData const QNetworkConfigurationManager::staticMetaObjectExtraData ?qt_static_metacall@QTcpSocket@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z @ 1238 NONAME ; void QTcpSocket::qt_static_metacall(class QObject *, enum QMetaObject::Call, int, void * *) + ??0QNetworkProxyQuery@@QAE@ABVQNetworkConfiguration@@GABVQString@@W4QueryType@0@@Z @ 1239 NONAME ; QNetworkProxyQuery::QNetworkProxyQuery(class QNetworkConfiguration const &, unsigned short, class QString const &, enum QNetworkProxyQuery::QueryType) + ??0QNetworkProxyQuery@@QAE@ABVQNetworkConfiguration@@ABVQString@@H1W4QueryType@0@@Z @ 1240 NONAME ; QNetworkProxyQuery::QNetworkProxyQuery(class QNetworkConfiguration const &, class QString const &, int, class QString const &, enum QNetworkProxyQuery::QueryType) + ?networkConfiguration@QNetworkProxyQuery@@QBE?AVQNetworkConfiguration@@XZ @ 1241 NONAME ; class QNetworkConfiguration QNetworkProxyQuery::networkConfiguration(void) const + ?setNetworkConfiguration@QNetworkProxyQuery@@QAEXABVQNetworkConfiguration@@@Z @ 1242 NONAME ; void QNetworkProxyQuery::setNetworkConfiguration(class QNetworkConfiguration const &) + ??0QNetworkProxyQuery@@QAE@ABVQNetworkConfiguration@@ABVQUrl@@W4QueryType@0@@Z @ 1243 NONAME ; QNetworkProxyQuery::QNetworkProxyQuery(class QNetworkConfiguration const &, class QUrl const &, enum QNetworkProxyQuery::QueryType) diff --git a/src/s60installs/eabi/QtCoreu.def b/src/s60installs/eabi/QtCoreu.def index 81b5267..6c4e837 100644 --- a/src/s60installs/eabi/QtCoreu.def +++ b/src/s60installs/eabi/QtCoreu.def @@ -3992,4 +3992,166 @@ EXPORTS _ZNK7QLocale9bcp47NameEv @ 3991 NONAME _ZTI13QActiveObject @ 3992 NONAME _ZTV13QActiveObject @ 3993 NONAME + _ZN23QCoreApplicationPrivate13trolltechConfEv @ 3994 NONAME + _ZN12QtConcurrent15ResultStoreBase10addResultsEiPKvii @ 3995 NONAME + _ZN12QtConcurrent15ResultStoreBase13setFilterModeEb @ 3996 NONAME + _ZN12QtConcurrent15ResultStoreBase15syncResultCountEv @ 3997 NONAME + _ZN12QtConcurrent15ResultStoreBase16insertResultItemEiRNS_10ResultItemE @ 3998 NONAME + _ZN12QtConcurrent15ResultStoreBase17updateInsertIndexEii @ 3999 NONAME + _ZN12QtConcurrent15ResultStoreBase18syncPendingResultsEv @ 4000 NONAME + _ZN12QtConcurrent15ResultStoreBase23insertResultItemIfValidEiRNS_10ResultItemE @ 4001 NONAME + _ZN12QtConcurrent15ResultStoreBase9addResultEiPKv @ 4002 NONAME + _ZN12QtConcurrent15ResultStoreBaseC1Ev @ 4003 NONAME + _ZN12QtConcurrent15ResultStoreBaseC2Ev @ 4004 NONAME + _ZN12QtConcurrent16BlockSizeManager13timeAfterUserEv @ 4005 NONAME + _ZN12QtConcurrent16BlockSizeManager14timeBeforeUserEv @ 4006 NONAME + _ZN12QtConcurrent16BlockSizeManager9blockSizeEv @ 4007 NONAME + _ZN12QtConcurrent16BlockSizeManagerC1Ei @ 4008 NONAME + _ZN12QtConcurrent16BlockSizeManagerC2Ei @ 4009 NONAME + _ZN12QtConcurrent16ThreadEngineBase10isCanceledEv @ 4010 NONAME + _ZN12QtConcurrent16ThreadEngineBase10threadExitEv @ 4011 NONAME + _ZN12QtConcurrent16ThreadEngineBase11startThreadEv @ 4012 NONAME + _ZN12QtConcurrent16ThreadEngineBase12startThreadsEv @ 4013 NONAME + _ZN12QtConcurrent16ThreadEngineBase13startBlockingEv @ 4014 NONAME + _ZN12QtConcurrent16ThreadEngineBase13waitForResumeEv @ 4015 NONAME + _ZN12QtConcurrent16ThreadEngineBase15handleExceptionERKNS_9ExceptionE @ 4016 NONAME + _ZN12QtConcurrent16ThreadEngineBase16setProgressRangeEii @ 4017 NONAME + _ZN12QtConcurrent16ThreadEngineBase16setProgressValueEi @ 4018 NONAME + _ZN12QtConcurrent16ThreadEngineBase18threadThrottleExitEv @ 4019 NONAME + _ZN12QtConcurrent16ThreadEngineBase19startSingleThreadedEv @ 4020 NONAME + _ZN12QtConcurrent16ThreadEngineBase19startThreadInternalEv @ 4021 NONAME + _ZN12QtConcurrent16ThreadEngineBase23acquireBarrierSemaphoreEv @ 4022 NONAME + _ZN12QtConcurrent16ThreadEngineBase26isProgressReportingEnabledEv @ 4023 NONAME + _ZN12QtConcurrent16ThreadEngineBase3runEv @ 4024 NONAME + _ZN12QtConcurrent16ThreadEngineBaseC2Ev @ 4025 NONAME + _ZN12QtConcurrent16ThreadEngineBaseD0Ev @ 4026 NONAME + _ZN12QtConcurrent16ThreadEngineBaseD1Ev @ 4027 NONAME + _ZN12QtConcurrent16ThreadEngineBaseD2Ev @ 4028 NONAME + _ZN12QtConcurrent18ResultIteratorBase14batchedAdvanceEv @ 4029 NONAME + _ZN12QtConcurrent18ResultIteratorBaseC1EN4QMapIiNS_10ResultItemEE14const_iteratorEi @ 4030 NONAME + _ZN12QtConcurrent18ResultIteratorBaseC1Ev @ 4031 NONAME + _ZN12QtConcurrent18ResultIteratorBaseC2EN4QMapIiNS_10ResultItemEE14const_iteratorEi @ 4032 NONAME + _ZN12QtConcurrent18ResultIteratorBaseC2Ev @ 4033 NONAME + _ZN12QtConcurrent18ResultIteratorBaseppEv @ 4034 NONAME + _ZN12QtConcurrent8internal14ExceptionStore12setExceptionERKNS_9ExceptionE @ 4035 NONAME + _ZN12QtConcurrent8internal14ExceptionStore22throwPossibleExceptionEv @ 4036 NONAME + _ZN12QtConcurrent8internal14ExceptionStore9exceptionEv @ 4037 NONAME + _ZN18QFutureWatcherBase11qt_metacallEN11QMetaObject4CallEiPPv @ 4038 NONAME + _ZN18QFutureWatcherBase11qt_metacastEPKc @ 4039 NONAME + _ZN18QFutureWatcherBase12togglePausedEv @ 4040 NONAME + _ZN18QFutureWatcherBase13connectNotifyEPKc @ 4041 NONAME + _ZN18QFutureWatcherBase13resultReadyAtEi @ 4042 NONAME + _ZN18QFutureWatcherBase14resultsReadyAtEii @ 4043 NONAME + _ZN18QFutureWatcherBase15waitForFinishedEv @ 4044 NONAME + _ZN18QFutureWatcherBase16disconnectNotifyEPKc @ 4045 NONAME + _ZN18QFutureWatcherBase16staticMetaObjectE @ 4046 NONAME DATA 16 + _ZN18QFutureWatcherBase18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 4047 NONAME + _ZN18QFutureWatcherBase19getStaticMetaObjectEv @ 4048 NONAME + _ZN18QFutureWatcherBase19progressTextChangedERK7QString @ 4049 NONAME + _ZN18QFutureWatcherBase20progressRangeChangedEii @ 4050 NONAME + _ZN18QFutureWatcherBase20progressValueChangedEi @ 4051 NONAME + _ZN18QFutureWatcherBase22connectOutputInterfaceEv @ 4052 NONAME + _ZN18QFutureWatcherBase22setPendingResultsLimitEi @ 4053 NONAME + _ZN18QFutureWatcherBase25disconnectOutputInterfaceEb @ 4054 NONAME + _ZN18QFutureWatcherBase25staticMetaObjectExtraDataE @ 4055 NONAME DATA 8 + _ZN18QFutureWatcherBase5eventEP6QEvent @ 4056 NONAME + _ZN18QFutureWatcherBase5pauseEv @ 4057 NONAME + _ZN18QFutureWatcherBase6cancelEv @ 4058 NONAME + _ZN18QFutureWatcherBase6pausedEv @ 4059 NONAME + _ZN18QFutureWatcherBase6resumeEv @ 4060 NONAME + _ZN18QFutureWatcherBase7resumedEv @ 4061 NONAME + _ZN18QFutureWatcherBase7startedEv @ 4062 NONAME + _ZN18QFutureWatcherBase8canceledEv @ 4063 NONAME + _ZN18QFutureWatcherBase8finishedEv @ 4064 NONAME + _ZN18QFutureWatcherBase9setPausedEb @ 4065 NONAME + _ZN18QFutureWatcherBaseC2EP7QObject @ 4066 NONAME + _ZN20QFutureInterfaceBase11setRunnableEP9QRunnable @ 4067 NONAME + _ZN20QFutureInterfaceBase12setThrottledEb @ 4068 NONAME + _ZN20QFutureInterfaceBase12togglePausedEv @ 4069 NONAME + _ZN20QFutureInterfaceBase13reportStartedEv @ 4070 NONAME + _ZN20QFutureInterfaceBase13setFilterModeEb @ 4071 NONAME + _ZN20QFutureInterfaceBase13waitForResultEi @ 4072 NONAME + _ZN20QFutureInterfaceBase13waitForResumeEv @ 4073 NONAME + _ZN20QFutureInterfaceBase14exceptionStoreEv @ 4074 NONAME + _ZN20QFutureInterfaceBase14reportCanceledEv @ 4075 NONAME + _ZN20QFutureInterfaceBase14reportFinishedEv @ 4076 NONAME + _ZN20QFutureInterfaceBase15reportExceptionERKN12QtConcurrent9ExceptionE @ 4077 NONAME + _ZN20QFutureInterfaceBase15resultStoreBaseEv @ 4078 NONAME + _ZN20QFutureInterfaceBase15waitForFinishedEv @ 4079 NONAME + _ZN20QFutureInterfaceBase16setProgressRangeEii @ 4080 NONAME + _ZN20QFutureInterfaceBase16setProgressValueEi @ 4081 NONAME + _ZN20QFutureInterfaceBase17waitForNextResultEv @ 4082 NONAME + _ZN20QFutureInterfaceBase18reportResultsReadyEii @ 4083 NONAME + _ZN20QFutureInterfaceBase19expectedResultCountEv @ 4084 NONAME + _ZN20QFutureInterfaceBase22setExpectedResultCountEi @ 4085 NONAME + _ZN20QFutureInterfaceBase23setProgressValueAndTextEiRK7QString @ 4086 NONAME + _ZN20QFutureInterfaceBase6cancelEv @ 4087 NONAME + _ZN20QFutureInterfaceBase9setPausedEb @ 4088 NONAME + _ZN20QFutureInterfaceBaseC1ENS_5StateE @ 4089 NONAME + _ZN20QFutureInterfaceBaseC1ERKS_ @ 4090 NONAME + _ZN20QFutureInterfaceBaseC2ENS_5StateE @ 4091 NONAME + _ZN20QFutureInterfaceBaseC2ERKS_ @ 4092 NONAME + _ZN20QFutureInterfaceBaseD0Ev @ 4093 NONAME + _ZN20QFutureInterfaceBaseD1Ev @ 4094 NONAME + _ZN20QFutureInterfaceBaseD2Ev @ 4095 NONAME + _ZN20QFutureInterfaceBaseaSERKS_ @ 4096 NONAME + _ZNK12QtConcurrent15ResultStoreBase10filterModeEv @ 4097 NONAME + _ZNK12QtConcurrent15ResultStoreBase13hasNextResultEv @ 4098 NONAME + _ZNK12QtConcurrent15ResultStoreBase3endEv @ 4099 NONAME + _ZNK12QtConcurrent15ResultStoreBase5beginEv @ 4100 NONAME + _ZNK12QtConcurrent15ResultStoreBase5countEv @ 4101 NONAME + _ZNK12QtConcurrent15ResultStoreBase8containsEi @ 4102 NONAME + _ZNK12QtConcurrent15ResultStoreBase8resultAtEi @ 4103 NONAME + _ZNK12QtConcurrent18ResultIteratorBase11resultIndexEv @ 4104 NONAME + _ZNK12QtConcurrent18ResultIteratorBase11vectorIndexEv @ 4105 NONAME + _ZNK12QtConcurrent18ResultIteratorBase23canIncrementVectorIndexEv @ 4106 NONAME + _ZNK12QtConcurrent18ResultIteratorBase8isVectorEv @ 4107 NONAME + _ZNK12QtConcurrent18ResultIteratorBase9batchSizeEv @ 4108 NONAME + _ZNK12QtConcurrent18ResultIteratorBaseeqERKS0_ @ 4109 NONAME + _ZNK12QtConcurrent18ResultIteratorBaseneERKS0_ @ 4110 NONAME + _ZNK12QtConcurrent18UnhandledException5cloneEv @ 4111 NONAME + _ZNK12QtConcurrent18UnhandledException5raiseEv @ 4112 NONAME + _ZNK12QtConcurrent8internal14ExceptionStore12hasExceptionEv @ 4113 NONAME + _ZNK12QtConcurrent8internal14ExceptionStore9hasThrownEv @ 4114 NONAME + _ZNK12QtConcurrent9Exception5cloneEv @ 4115 NONAME + _ZNK12QtConcurrent9Exception5raiseEv @ 4116 NONAME + _ZNK18QFutureWatcherBase10isCanceledEv @ 4117 NONAME + _ZNK18QFutureWatcherBase10isFinishedEv @ 4118 NONAME + _ZNK18QFutureWatcherBase10metaObjectEv @ 4119 NONAME + _ZNK18QFutureWatcherBase12progressTextEv @ 4120 NONAME + _ZNK18QFutureWatcherBase13progressValueEv @ 4121 NONAME + _ZNK18QFutureWatcherBase15progressMaximumEv @ 4122 NONAME + _ZNK18QFutureWatcherBase15progressMinimumEv @ 4123 NONAME + _ZNK18QFutureWatcherBase8isPausedEv @ 4124 NONAME + _ZNK18QFutureWatcherBase9isRunningEv @ 4125 NONAME + _ZNK18QFutureWatcherBase9isStartedEv @ 4126 NONAME + _ZNK20QFutureInterfaceBase10isCanceledEv @ 4127 NONAME + _ZNK20QFutureInterfaceBase10isFinishedEv @ 4128 NONAME + _ZNK20QFutureInterfaceBase10queryStateENS_5StateE @ 4129 NONAME + _ZNK20QFutureInterfaceBase11isThrottledEv @ 4130 NONAME + _ZNK20QFutureInterfaceBase11resultCountEv @ 4131 NONAME + _ZNK20QFutureInterfaceBase12progressTextEv @ 4132 NONAME + _ZNK20QFutureInterfaceBase13progressValueEv @ 4133 NONAME + _ZNK20QFutureInterfaceBase15isResultReadyAtEi @ 4134 NONAME + _ZNK20QFutureInterfaceBase15progressMaximumEv @ 4135 NONAME + _ZNK20QFutureInterfaceBase15progressMinimumEv @ 4136 NONAME + _ZNK20QFutureInterfaceBase15resultStoreBaseEv @ 4137 NONAME + _ZNK20QFutureInterfaceBase19referenceCountIsOneEv @ 4138 NONAME + _ZNK20QFutureInterfaceBase22isProgressUpdateNeededEv @ 4139 NONAME + _ZNK20QFutureInterfaceBase5mutexEv @ 4140 NONAME + _ZNK20QFutureInterfaceBase8isPausedEv @ 4141 NONAME + _ZNK20QFutureInterfaceBase9isRunningEv @ 4142 NONAME + _ZNK20QFutureInterfaceBase9isStartedEv @ 4143 NONAME + _ZTI18QFutureWatcherBase @ 4144 NONAME + _ZTI20QFutureInterfaceBase @ 4145 NONAME + _ZTIN12QtConcurrent15ResultStoreBaseE @ 4146 NONAME + _ZTIN12QtConcurrent16ThreadEngineBaseE @ 4147 NONAME + _ZTIN12QtConcurrent18UnhandledExceptionE @ 4148 NONAME + _ZTIN12QtConcurrent9ExceptionE @ 4149 NONAME + _ZTV18QFutureWatcherBase @ 4150 NONAME + _ZTV20QFutureInterfaceBase @ 4151 NONAME + _ZTVN12QtConcurrent15ResultStoreBaseE @ 4152 NONAME + _ZTVN12QtConcurrent16ThreadEngineBaseE @ 4153 NONAME + _ZTVN12QtConcurrent18UnhandledExceptionE @ 4154 NONAME + _ZTVN12QtConcurrent9ExceptionE @ 4155 NONAME diff --git a/src/s60installs/eabi/QtGuiu.def b/src/s60installs/eabi/QtGuiu.def index 6646401..2a0cf21 100644 --- a/src/s60installs/eabi/QtGuiu.def +++ b/src/s60installs/eabi/QtGuiu.def @@ -11820,7 +11820,7 @@ EXPORTS _ZN20QGraphicsItemPrivate16clearFocusHelperEb @ 11819 NONAME _ZN24QImagePixmapCleanupHooks13isImageCachedERK6QImage @ 11820 NONAME _ZN24QImagePixmapCleanupHooks14isPixmapCachedERK7QPixmap @ 11821 NONAME - _Z14qt_draw_glyphsP8QPainterPKjPK7QPointFi @ 11822 NONAME + _Z14qt_draw_glyphsP8QPainterPKjPK7QPointFi @ 11822 NONAME ABSENT _ZN10QImageData14convertInPlaceEN6QImage6FormatE6QFlagsIN2Qt19ImageConversionFlagEE @ 11823 NONAME _ZN10QZipReader5closeEv @ 11824 NONAME _ZN10QZipReader8FileInfoC1ERKS0_ @ 11825 NONAME @@ -12230,7 +12230,7 @@ EXPORTS _ZN17QInternalMimeDataD2Ev @ 12229 NONAME _ZN18QTextureGlyphCache19fillInPendingGlyphsEv @ 12230 NONAME _ZN19QAbstractProxyModel11setItemDataERK11QModelIndexRK4QMapIi8QVariantE @ 12231 NONAME - _ZN19QAbstractProxyModel17resetInternalDataEv @ 12232 NONAME + _ZN19QAbstractProxyModel17resetInternalDataEv @ 12232 NONAME ABSENT _ZN19QAbstractProxyModel4sortEiN2Qt9SortOrderE @ 12233 NONAME _ZN19QAbstractProxyModel9fetchMoreERK11QModelIndex @ 12234 NONAME _ZN19QApplicationPrivateC1ERiPPcN12QApplication4TypeEi @ 12235 NONAME @@ -12302,22 +12302,22 @@ EXPORTS _ZN5QFont20setHintingPreferenceENS_17HintingPreferenceE @ 12301 NONAME _ZN6QImage4fillEN2Qt11GlobalColorE @ 12302 NONAME _ZN6QImage4fillERK6QColor @ 12303 NONAME - _ZN7QGlyphs12setPositionsERK7QVectorI7QPointFE @ 12304 NONAME - _ZN7QGlyphs15setGlyphIndexesERK7QVectorIjE @ 12305 NONAME - _ZN7QGlyphs5clearEv @ 12306 NONAME - _ZN7QGlyphs6detachEv @ 12307 NONAME - _ZN7QGlyphs7setFontERK5QFont @ 12308 NONAME - _ZN7QGlyphsC1ERKS_ @ 12309 NONAME - _ZN7QGlyphsC1Ev @ 12310 NONAME - _ZN7QGlyphsC2ERKS_ @ 12311 NONAME - _ZN7QGlyphsC2Ev @ 12312 NONAME - _ZN7QGlyphsD1Ev @ 12313 NONAME - _ZN7QGlyphsD2Ev @ 12314 NONAME - _ZN7QGlyphsaSERKS_ @ 12315 NONAME - _ZN7QGlyphspLERKS_ @ 12316 NONAME + _ZN7QGlyphs12setPositionsERK7QVectorI7QPointFE @ 12304 NONAME ABSENT + _ZN7QGlyphs15setGlyphIndexesERK7QVectorIjE @ 12305 NONAME ABSENT + _ZN7QGlyphs5clearEv @ 12306 NONAME ABSENT + _ZN7QGlyphs6detachEv @ 12307 NONAME ABSENT + _ZN7QGlyphs7setFontERK5QFont @ 12308 NONAME ABSENT + _ZN7QGlyphsC1ERKS_ @ 12309 NONAME ABSENT + _ZN7QGlyphsC1Ev @ 12310 NONAME ABSENT + _ZN7QGlyphsC2ERKS_ @ 12311 NONAME ABSENT + _ZN7QGlyphsC2Ev @ 12312 NONAME ABSENT + _ZN7QGlyphsD1Ev @ 12313 NONAME ABSENT + _ZN7QGlyphsD2Ev @ 12314 NONAME ABSENT + _ZN7QGlyphsaSERKS_ @ 12315 NONAME ABSENT + _ZN7QGlyphspLERKS_ @ 12316 NONAME ABSENT _ZN8QMdiArea14setTabsMovableEb @ 12317 NONAME _ZN8QMdiArea15setTabsClosableEb @ 12318 NONAME - _ZN8QPainter10drawGlyphsERK7QPointFRK7QGlyphs @ 12319 NONAME + _ZN8QPainter10drawGlyphsERK7QPointFRK7QGlyphs @ 12319 NONAME ABSENT _ZN9QScroller11grabGestureEP7QObjectNS_19ScrollerGestureTypeE @ 12320 NONAME _ZN9QScroller11handleInputENS_5InputERK7QPointFx @ 12321 NONAME _ZN9QScroller11hasScrollerEP7QObject @ 12322 NONAME @@ -12351,9 +12351,9 @@ EXPORTS _ZNK10QBlittable12capabilitiesEv @ 12350 NONAME _ZNK10QBlittable4sizeEv @ 12351 NONAME _ZNK10QTabWidget14heightForWidthEi @ 12352 NONAME - _ZNK11QFontEngine18createExplicitFontEv @ 12353 NONAME - _ZNK11QFontEngine26createExplicitFontWithNameERK7QString @ 12354 NONAME - _ZNK11QTextLayout6glyphsEv @ 12355 NONAME + _ZNK11QFontEngine18createExplicitFontEv @ 12353 NONAME ABSENT + _ZNK11QFontEngine26createExplicitFontWithNameERK7QString @ 12354 NONAME ABSENT + _ZNK11QTextLayout6glyphsEv @ 12355 NONAME ABSENT _ZNK12QFontMetrics10inFontUcs4Ej @ 12356 NONAME _ZNK12QRadioButton15minimumSizeHintEv @ 12357 NONAME _ZNK12QScrollEvent10contentPosEv @ 12358 NONAME @@ -12362,7 +12362,7 @@ EXPORTS _ZNK12QScrollEvent6d_funcEv @ 12361 NONAME _ZNK13QFlickGesture10metaObjectEv @ 12362 NONAME _ZNK13QFontMetricsF10inFontUcs4Ej @ 12363 NONAME - _ZNK13QTextFragment6glyphsEv @ 12364 NONAME + _ZNK13QTextFragment6glyphsEv @ 12364 NONAME ABSENT _ZNK14QFileOpenEvent8openFileER5QFile6QFlagsIN9QIODevice12OpenModeFlagEE @ 12365 NONAME _ZNK14QWidgetPrivate17hasHeightForWidthEv @ 12366 NONAME _ZNK16QFileSystemModel5rmdirERK11QModelIndex @ 12367 NONAME @@ -12396,12 +12396,12 @@ EXPORTS _ZNK20QBlittablePixmapData9blittableEv @ 12395 NONAME _ZNK20QRasterWindowSurface24hasStaticContentsSupportEv @ 12396 NONAME ABSENT _ZNK5QFont17hintingPreferenceEv @ 12397 NONAME - _ZNK7QGlyphs12glyphIndexesEv @ 12398 NONAME - _ZNK7QGlyphs4fontEv @ 12399 NONAME - _ZNK7QGlyphs9positionsEv @ 12400 NONAME - _ZNK7QGlyphseqERKS_ @ 12401 NONAME - _ZNK7QGlyphsneERKS_ @ 12402 NONAME - _ZNK7QGlyphsplERKS_ @ 12403 NONAME + _ZNK7QGlyphs12glyphIndexesEv @ 12398 NONAME ABSENT + _ZNK7QGlyphs4fontEv @ 12399 NONAME ABSENT + _ZNK7QGlyphs9positionsEv @ 12400 NONAME ABSENT + _ZNK7QGlyphseqERKS_ @ 12401 NONAME ABSENT + _ZNK7QGlyphsneERKS_ @ 12402 NONAME ABSENT + _ZNK7QGlyphsplERKS_ @ 12403 NONAME ABSENT _ZNK8QMdiArea11tabsMovableEv @ 12404 NONAME _ZNK8QMdiArea12tabsClosableEv @ 12405 NONAME _ZNK8QPainter16clipBoundingRectEv @ 12406 NONAME @@ -12413,7 +12413,7 @@ EXPORTS _ZNK9QScroller5stateEv @ 12412 NONAME _ZNK9QScroller6targetEv @ 12413 NONAME _ZNK9QScroller8velocityEv @ 12414 NONAME - _ZNK9QTextLine6glyphsEii @ 12415 NONAME + _ZNK9QTextLine6glyphsEii @ 12415 NONAME ABSENT _ZTI10QBlittable @ 12416 NONAME _ZTI12QScrollEvent @ 12417 NONAME _ZTI13QFlickGesture @ 12418 NONAME @@ -12799,4 +12799,69 @@ EXPORTS _ZNK10QZipWriter6deviceEv @ 12798 NONAME _ZNK10QZipWriter6existsEv @ 12799 NONAME _ZNK10QZipWriter6statusEv @ 12800 NONAME - + _Z27qt_isExtendedRadialGradientRK6QBrush @ 12801 NONAME + _Z28qt_painterPathFromVectorPathRK11QVectorPath @ 12802 NONAME + _Z29qt_draw_decoration_for_glyphsP8QPainterPKjPK11QFixedPointiP11QFontEngineRK5QFontRK15QTextCharFormat @ 12803 NONAME + _ZN10QTableView13doItemsLayoutEv @ 12804 NONAME + _ZN11QTextEngine15beginningOfLineEi @ 12805 NONAME + _ZN11QTextEngine16offsetInLigatureEPK11QScriptItemiii @ 12806 NONAME + _ZN11QTextEngine22insertionPointsForLineEiR7QVectorIiE @ 12807 NONAME + _ZN11QTextEngine25lineNumberForTextPositionEi @ 12808 NONAME + _ZN11QTextEngine27positionAfterVisualMovementEiN11QTextCursor13MoveOperationE @ 12809 NONAME + _ZN11QTextEngine9alignLineERK11QScriptLine @ 12810 NONAME + _ZN11QTextEngine9endOfLineEi @ 12811 NONAME + _ZN11QTextLayout18setCursorMoveStyleEN11QTextCursor9MoveStyleE @ 12812 NONAME + _ZN13QTextDocument25setDefaultCursorMoveStyleEN11QTextCursor9MoveStyleE @ 12813 NONAME + _ZN15QGraphicsLayout28instantInvalidatePropagationEv @ 12814 NONAME + _ZN15QGraphicsLayout31setInstantInvalidatePropagationEb @ 12815 NONAME + _ZN15QRadialGradient14setFocalRadiusEf @ 12816 NONAME + _ZN15QRadialGradient15setCenterRadiusEf @ 12817 NONAME + _ZN15QRadialGradientC1ERK7QPointFfS2_f @ 12818 NONAME + _ZN15QRadialGradientC1Effffff @ 12819 NONAME + _ZN15QRadialGradientC2ERK7QPointFfS2_f @ 12820 NONAME + _ZN15QRadialGradientC2Effffff @ 12821 NONAME + _ZN19QIdentityProxyModel10insertRowsEiiRK11QModelIndex @ 12822 NONAME + _ZN19QIdentityProxyModel10removeRowsEiiRK11QModelIndex @ 12823 NONAME + _ZN19QIdentityProxyModel11qt_metacallEN11QMetaObject4CallEiPPv @ 12824 NONAME + _ZN19QIdentityProxyModel11qt_metacastEPKc @ 12825 NONAME + _ZN19QIdentityProxyModel12dropMimeDataEPK9QMimeDataN2Qt10DropActionEiiRK11QModelIndex @ 12826 NONAME + _ZN19QIdentityProxyModel13insertColumnsEiiRK11QModelIndex @ 12827 NONAME + _ZN19QIdentityProxyModel13removeColumnsEiiRK11QModelIndex @ 12828 NONAME + _ZN19QIdentityProxyModel14setSourceModelEP18QAbstractItemModel @ 12829 NONAME + _ZN19QIdentityProxyModel16staticMetaObjectE @ 12830 NONAME DATA 16 + _ZN19QIdentityProxyModel18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 12831 NONAME + _ZN19QIdentityProxyModel19getStaticMetaObjectEv @ 12832 NONAME + _ZN19QIdentityProxyModel25staticMetaObjectExtraDataE @ 12833 NONAME DATA 8 + _ZN19QIdentityProxyModelC1EP7QObject @ 12834 NONAME + _ZN19QIdentityProxyModelC1ER26QIdentityProxyModelPrivateP7QObject @ 12835 NONAME + _ZN19QIdentityProxyModelC2EP7QObject @ 12836 NONAME + _ZN19QIdentityProxyModelC2ER26QIdentityProxyModelPrivateP7QObject @ 12837 NONAME + _ZN19QIdentityProxyModelD0Ev @ 12838 NONAME + _ZN19QIdentityProxyModelD1Ev @ 12839 NONAME + _ZN19QIdentityProxyModelD2Ev @ 12840 NONAME + _ZN9QLineEdit18setCursorMoveStyleEN11QTextCursor9MoveStyleE @ 12841 NONAME + _ZNK10QTextBlock7isValidEv @ 12842 NONAME + _ZNK11QTextEngine19nextLogicalPositionEi @ 12843 NONAME + _ZNK11QTextEngine23previousLogicalPositionEi @ 12844 NONAME + _ZNK11QTextLayout15cursorMoveStyleEv @ 12845 NONAME + _ZNK11QTextLayout18leftCursorPositionEi @ 12846 NONAME + _ZNK11QTextLayout19rightCursorPositionEi @ 12847 NONAME + _ZNK12QUndoCommand10actionTextEv @ 12848 NONAME + _ZNK13QTextDocument22defaultCursorMoveStyleEv @ 12849 NONAME + _ZNK14QVolatileImage14paintingActiveEv @ 12850 NONAME + _ZNK15QRadialGradient11focalRadiusEv @ 12851 NONAME + _ZNK15QRadialGradient12centerRadiusEv @ 12852 NONAME + _ZNK19QIdentityProxyModel10metaObjectEv @ 12853 NONAME + _ZNK19QIdentityProxyModel11columnCountERK11QModelIndex @ 12854 NONAME + _ZNK19QIdentityProxyModel11mapToSourceERK11QModelIndex @ 12855 NONAME + _ZNK19QIdentityProxyModel13mapFromSourceERK11QModelIndex @ 12856 NONAME + _ZNK19QIdentityProxyModel20mapSelectionToSourceERK14QItemSelection @ 12857 NONAME + _ZNK19QIdentityProxyModel22mapSelectionFromSourceERK14QItemSelection @ 12858 NONAME + _ZNK19QIdentityProxyModel5indexEiiRK11QModelIndex @ 12859 NONAME + _ZNK19QIdentityProxyModel5matchERK11QModelIndexiRK8QVarianti6QFlagsIN2Qt9MatchFlagEE @ 12860 NONAME + _ZNK19QIdentityProxyModel6parentERK11QModelIndex @ 12861 NONAME + _ZNK19QIdentityProxyModel8rowCountERK11QModelIndex @ 12862 NONAME + _ZNK9QLineEdit15cursorMoveStyleEv @ 12863 NONAME + _ZTI19QIdentityProxyModel @ 12864 NONAME + _ZTV19QIdentityProxyModel @ 12865 NONAME + _Z43qt_s60_setPartialScreenAutomaticTranslationb @ 12866 NONAME diff --git a/src/s60installs/eabi/QtNetworku.def b/src/s60installs/eabi/QtNetworku.def index b0cbb38..8e29c2d 100644 --- a/src/s60installs/eabi/QtNetworku.def +++ b/src/s60installs/eabi/QtNetworku.def @@ -1260,4 +1260,12 @@ EXPORTS _ZN4QFtp25staticMetaObjectExtraDataE @ 1259 NONAME DATA 8 _ZN5QHttp18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 1260 NONAME _ZN5QHttp25staticMetaObjectExtraDataE @ 1261 NONAME DATA 8 + _ZN18QNetworkProxyQuery23setNetworkConfigurationERK21QNetworkConfiguration @ 1262 NONAME + _ZN18QNetworkProxyQueryC1ERK21QNetworkConfigurationRK4QUrlNS_9QueryTypeE @ 1263 NONAME + _ZN18QNetworkProxyQueryC1ERK21QNetworkConfigurationRK7QStringiS5_NS_9QueryTypeE @ 1264 NONAME + _ZN18QNetworkProxyQueryC1ERK21QNetworkConfigurationtRK7QStringNS_9QueryTypeE @ 1265 NONAME + _ZN18QNetworkProxyQueryC2ERK21QNetworkConfigurationRK4QUrlNS_9QueryTypeE @ 1266 NONAME + _ZN18QNetworkProxyQueryC2ERK21QNetworkConfigurationRK7QStringiS5_NS_9QueryTypeE @ 1267 NONAME + _ZN18QNetworkProxyQueryC2ERK21QNetworkConfigurationtRK7QStringNS_9QueryTypeE @ 1268 NONAME + _ZNK18QNetworkProxyQuery20networkConfigurationEv @ 1269 NONAME diff --git a/src/s60installs/eabi/QtOpenGLu.def b/src/s60installs/eabi/QtOpenGLu.def index 44f7306..c252484 100644 --- a/src/s60installs/eabi/QtOpenGLu.def +++ b/src/s60installs/eabi/QtOpenGLu.def @@ -759,11 +759,25 @@ EXPORTS _ZNK14QGLPaintDevice9isFlippedEv @ 758 NONAME _ZNK16QGLWindowSurface8featuresEv @ 759 NONAME _ZNK26QGLFramebufferObjectFormat6mipmapEv @ 760 NONAME - _ZTI22QGLContextResourceBase @ 761 NONAME - _ZTI27QGLContextGroupResourceBase @ 762 NONAME - _ZTV22QGLContextResourceBase @ 763 NONAME - _ZTV27QGLContextGroupResourceBase @ 764 NONAME - _ZThn104_N20QGLTextureGlyphCacheD0Ev @ 765 NONAME - _ZThn104_N20QGLTextureGlyphCacheD1Ev @ 766 NONAME - _ZThn8_NK16QGLWindowSurface8featuresEv @ 767 NONAME + _ZTI22QGLContextResourceBase @ 761 NONAME ABSENT + _ZTI27QGLContextGroupResourceBase @ 762 NONAME ABSENT + _ZTV22QGLContextResourceBase @ 763 NONAME ABSENT + _ZTV27QGLContextGroupResourceBase @ 764 NONAME ABSENT + _ZThn104_N20QGLTextureGlyphCacheD0Ev @ 765 NONAME ABSENT + _ZThn104_N20QGLTextureGlyphCacheD1Ev @ 766 NONAME ABSENT + _ZThn8_NK16QGLWindowSurface8featuresEv @ 767 NONAME ABSENT + _ZN14QGLSignalProxy18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 768 NONAME + _ZN14QGLSignalProxy25staticMetaObjectExtraDataE @ 769 NONAME DATA 8 + _ZN16QGLShaderProgram18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 770 NONAME + _ZN16QGLShaderProgram25staticMetaObjectExtraDataE @ 771 NONAME DATA 8 + _ZN16QGLWindowSurface18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 772 NONAME + _ZN16QGLWindowSurface25staticMetaObjectExtraDataE @ 773 NONAME DATA 8 + _ZN21QGraphicsShaderEffect18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 774 NONAME + _ZN21QGraphicsShaderEffect25staticMetaObjectExtraDataE @ 775 NONAME DATA 8 + _ZN22QGLEngineShaderManager18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 776 NONAME + _ZN22QGLEngineShaderManager25staticMetaObjectExtraDataE @ 777 NONAME DATA 8 + _ZN9QGLShader18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 778 NONAME + _ZN9QGLShader25staticMetaObjectExtraDataE @ 779 NONAME DATA 8 + _ZN9QGLWidget18qt_static_metacallEP7QObjectN11QMetaObject4CallEiPPv @ 780 NONAME + _ZN9QGLWidget25staticMetaObjectExtraDataE @ 781 NONAME DATA 8 diff --git a/src/script/api/qscriptengineagent_p.h b/src/script/api/qscriptengineagent_p.h index abe4e9e..b96d19d 100644 --- a/src/script/api/qscriptengineagent_p.h +++ b/src/script/api/qscriptengineagent_p.h @@ -57,22 +57,22 @@ public: static QScriptEngineAgentPrivate* get(QScriptEngineAgent* p) {return p->d_func();} QScriptEngineAgentPrivate(){} - virtual ~QScriptEngineAgentPrivate(){}; + virtual ~QScriptEngineAgentPrivate(){} void attach(); void detach(); //scripts - virtual void sourceParsed(JSC::ExecState*, const JSC::SourceCode&, int /*errorLine*/, const JSC::UString& /*errorMsg*/) {}; + virtual void sourceParsed(JSC::ExecState*, const JSC::SourceCode&, int /*errorLine*/, const JSC::UString& /*errorMsg*/) {} virtual void scriptUnload(qint64 id) { q_ptr->scriptUnload(id); - }; + } virtual void scriptLoad(qint64 id, const JSC::UString &program, const JSC::UString &fileName, int baseLineNumber) { q_ptr->scriptLoad(id,program, fileName, baseLineNumber); - }; + } //exceptions virtual void exception(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno, bool hasHandler) @@ -81,7 +81,7 @@ public: Q_UNUSED(sourceID); Q_UNUSED(lineno); Q_UNUSED(hasHandler); - }; + } virtual void exceptionThrow(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, bool hasHandler); virtual void exceptionCatch(const JSC::DebuggerCallFrame& frame, intptr_t sourceID); @@ -92,20 +92,20 @@ public: Q_UNUSED(lineno); q_ptr->contextPush(); q_ptr->functionEntry(sourceID); - }; + } virtual void returnEvent(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno); virtual void willExecuteProgram(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno) { Q_UNUSED(frame); Q_UNUSED(sourceID); Q_UNUSED(lineno); - }; + } virtual void didExecuteProgram(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno) { Q_UNUSED(frame); - Q_UNUSED(sourceID); + Q_UNUSED(sourceID); Q_UNUSED(lineno); - }; + } virtual void functionExit(const JSC::JSValue& returnValue, intptr_t sourceID); //others virtual void didReachBreakpoint(const JSC::DebuggerCallFrame& frame, intptr_t sourceID, int lineno/*, int column*/); diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 49e7f13..4250b61 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -1374,12 +1374,16 @@ QStringList QMYSQLDriver::tables(QSql::TableType type) const } else { QSqlQuery q(createResult()); if(type & QSql::Tables) { - q.exec(QLatin1String("select table_name from information_schema.tables where table_type = 'BASE TABLE'")); + QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'BASE TABLE'"); + q.exec(sql); + while(q.next()) tl.append(q.value(0).toString()); } if(type & QSql::Views) { - q.exec(QLatin1String("select table_name from information_schema.tables where table_type = 'VIEW'")); + QString sql = QLatin1String("select table_name from information_schema.tables where table_schema = '") + QLatin1String(d->mysql->db) + QLatin1String("' and table_type = 'VIEW'"); + q.exec(sql); + while(q.next()) tl.append(q.value(0).toString()); } diff --git a/src/tools/uic3/uic3.pro b/src/tools/uic3/uic3.pro index 5ad3c4d..54f7dc8 100644 --- a/src/tools/uic3/uic3.pro +++ b/src/tools/uic3/uic3.pro @@ -1,5 +1,6 @@ TEMPLATE = app CONFIG += console qt_no_compat_warning +win32-msvc*:CONFIG += no_batch # otherwise the wrong main.cpp may be picked up CONFIG -= app_bundle build_all:!build_pass { CONFIG -= build_all diff --git a/src/xmlpatterns/data/qitem_p.h b/src/xmlpatterns/data/qitem_p.h index 8184b25..fb3866e 100644 --- a/src/xmlpatterns/data/qitem_p.h +++ b/src/xmlpatterns/data/qitem_p.h @@ -408,6 +408,10 @@ namespace QPatternist inline void reset() { + /* Delete the atomicValue if necessary*/ + if(isAtomicValue() && !atomicValue->ref.deref()) + delete atomicValue; + /* Note that this function should be equal to the default * constructor. */ node.model = 0; diff --git a/src/xmlpatterns/expr/qdynamiccontextstore.cpp b/src/xmlpatterns/expr/qdynamiccontextstore.cpp index 762b7d6..7e7ead7 100644 --- a/src/xmlpatterns/expr/qdynamiccontextstore.cpp +++ b/src/xmlpatterns/expr/qdynamiccontextstore.cpp @@ -51,24 +51,24 @@ using namespace QPatternist; DynamicContextStore::DynamicContextStore(const Expression::Ptr &operand, const DynamicContext::Ptr &context) : SingleContainer(operand), - m_context(context) + m_context(context.data()) { Q_ASSERT(context); } bool DynamicContextStore::evaluateEBV(const DynamicContext::Ptr &) const { - return m_operand->evaluateEBV(m_context); + return m_operand->evaluateEBV(DynamicContext::Ptr(m_context)); } Item::Iterator::Ptr DynamicContextStore::evaluateSequence(const DynamicContext::Ptr &) const { - return m_operand->evaluateSequence(m_context); + return m_operand->evaluateSequence(DynamicContext::Ptr(m_context)); } Item DynamicContextStore::evaluateSingleton(const DynamicContext::Ptr &) const { - return m_operand->evaluateSingleton(m_context); + return m_operand->evaluateSingleton(DynamicContext::Ptr(m_context)); } SequenceType::Ptr DynamicContextStore::staticType() const diff --git a/src/xmlpatterns/expr/qdynamiccontextstore_p.h b/src/xmlpatterns/expr/qdynamiccontextstore_p.h index 1d5d035..40bfcd1 100644 --- a/src/xmlpatterns/expr/qdynamiccontextstore_p.h +++ b/src/xmlpatterns/expr/qdynamiccontextstore_p.h @@ -86,7 +86,7 @@ namespace QPatternist virtual const SourceLocationReflection *actualReflection() const; private: - const DynamicContext::Ptr m_context; + DynamicContext *m_context; }; } diff --git a/src/xmlpatterns/expr/qevaluationcache.cpp b/src/xmlpatterns/expr/qevaluationcache.cpp index 2d1bb56..cb95af6 100644 --- a/src/xmlpatterns/expr/qevaluationcache.cpp +++ b/src/xmlpatterns/expr/qevaluationcache.cpp @@ -49,7 +49,7 @@ template<bool IsForGlobal> EvaluationCache<IsForGlobal>::EvaluationCache(const Expression::Ptr &op, const VariableDeclaration::Ptr &varDecl, const VariableSlotID aSlot) : SingleContainer(op) - , m_declaration(varDecl) + , m_declaration(varDecl.constData()) , m_varSlot(aSlot) { Q_ASSERT(m_declaration); diff --git a/src/xmlpatterns/expr/qevaluationcache_p.h b/src/xmlpatterns/expr/qevaluationcache_p.h index 86aeaf8..af4cfa0 100644 --- a/src/xmlpatterns/expr/qevaluationcache_p.h +++ b/src/xmlpatterns/expr/qevaluationcache_p.h @@ -124,7 +124,7 @@ namespace QPatternist private: static DynamicContext::Ptr topFocusContext(const DynamicContext::Ptr &context); - const VariableDeclaration::Ptr m_declaration; + const VariableDeclaration* m_declaration; /** * This variable must not be called m_slot. If it so, a compiler bug on * HP-UX-aCC-64 is triggered in the constructor initializor. See the diff --git a/src/xmlpatterns/expr/qletclause.cpp b/src/xmlpatterns/expr/qletclause.cpp index d3e939b..b789b48 100644 --- a/src/xmlpatterns/expr/qletclause.cpp +++ b/src/xmlpatterns/expr/qletclause.cpp @@ -60,7 +60,7 @@ LetClause::LetClause(const Expression::Ptr &operand1, DynamicContext::Ptr LetClause::bindVariable(const DynamicContext::Ptr &context) const { - context->setExpressionVariable(m_varDecl->slot, Expression::Ptr(new DynamicContextStore(m_operand1, context))); + context->setExpressionVariable(m_varDecl->slot, m_operand1); return context; } diff --git a/src/xmlpatterns/schema/qxsdattribute.cpp b/src/xmlpatterns/schema/qxsdattribute.cpp index 68f9e3d..fb768d4 100644 --- a/src/xmlpatterns/schema/qxsdattribute.cpp +++ b/src/xmlpatterns/schema/qxsdattribute.cpp @@ -59,12 +59,12 @@ XsdAttribute::Scope::Variety XsdAttribute::Scope::variety() const void XsdAttribute::Scope::setParent(const NamedSchemaComponent::Ptr &parent) { - m_parent = parent; + m_parent = parent.data(); } NamedSchemaComponent::Ptr XsdAttribute::Scope::parent() const { - return m_parent; + return NamedSchemaComponent::Ptr(m_parent); } void XsdAttribute::ValueConstraint::setVariety(Variety variety) diff --git a/src/xmlpatterns/schema/qxsdattribute_p.h b/src/xmlpatterns/schema/qxsdattribute_p.h index d64d335..a21fe70 100644 --- a/src/xmlpatterns/schema/qxsdattribute_p.h +++ b/src/xmlpatterns/schema/qxsdattribute_p.h @@ -131,7 +131,7 @@ namespace QPatternist private: Variety m_variety; - NamedSchemaComponent::Ptr m_parent; + NamedSchemaComponent *m_parent; }; diff --git a/src/xmlpatterns/schema/qxsdcomplextype.cpp b/src/xmlpatterns/schema/qxsdcomplextype.cpp index 42aeb60..0932060 100644 --- a/src/xmlpatterns/schema/qxsdcomplextype.cpp +++ b/src/xmlpatterns/schema/qxsdcomplextype.cpp @@ -140,12 +140,12 @@ SchemaType::Ptr XsdComplexType::wxsSuperType() const void XsdComplexType::setContext(const NamedSchemaComponent::Ptr &component) { - m_context = component; + m_context = component.data(); } NamedSchemaComponent::Ptr XsdComplexType::context() const { - return m_context; + return NamedSchemaComponent::Ptr(m_context); } void XsdComplexType::setContentType(const ContentType::Ptr &type) diff --git a/src/xmlpatterns/schema/qxsdcomplextype_p.h b/src/xmlpatterns/schema/qxsdcomplextype_p.h index d28d2fc..d02583c 100644 --- a/src/xmlpatterns/schema/qxsdcomplextype_p.h +++ b/src/xmlpatterns/schema/qxsdcomplextype_p.h @@ -386,7 +386,7 @@ namespace QPatternist private: SchemaType::Ptr m_superType; - NamedSchemaComponent::Ptr m_context; + NamedSchemaComponent *m_context; DerivationMethod m_derivationMethod; bool m_isAbstract; XsdAttributeUse::List m_attributeUses; diff --git a/src/xmlpatterns/schema/qxsdelement.cpp b/src/xmlpatterns/schema/qxsdelement.cpp index 1ebec06..b0c5661 100644 --- a/src/xmlpatterns/schema/qxsdelement.cpp +++ b/src/xmlpatterns/schema/qxsdelement.cpp @@ -57,12 +57,12 @@ XsdElement::Scope::Variety XsdElement::Scope::variety() const void XsdElement::Scope::setParent(const NamedSchemaComponent::Ptr &parent) { - m_parent = parent; + m_parent = parent.data(); } NamedSchemaComponent::Ptr XsdElement::Scope::parent() const { - return m_parent; + return NamedSchemaComponent::Ptr(m_parent); } void XsdElement::ValueConstraint::setVariety(Variety variety) @@ -233,10 +233,10 @@ XsdElement::List XsdElement::substitutionGroupAffiliations() const void XsdElement::addSubstitutionGroup(const XsdElement::Ptr &element) { - m_substitutionGroups.insert(element); + m_substitutionGroups.insert(element.data()); } -XsdElement::List XsdElement::substitutionGroups() const +XsdElement::WeakList XsdElement::substitutionGroups() const { return m_substitutionGroups.toList(); } diff --git a/src/xmlpatterns/schema/qxsdelement_p.h b/src/xmlpatterns/schema/qxsdelement_p.h index 93c5983..3794c96 100644 --- a/src/xmlpatterns/schema/qxsdelement_p.h +++ b/src/xmlpatterns/schema/qxsdelement_p.h @@ -85,7 +85,7 @@ namespace QPatternist public: typedef QExplicitlySharedDataPointer<XsdElement> Ptr; typedef QList<XsdElement::Ptr> List; - + typedef QList<XsdElement *> WeakList; /** * Describes the <a href="http://www.w3.org/TR/xmlschema11-1/#ed-value_constraint">constraint type</a> of the element. @@ -138,7 +138,7 @@ namespace QPatternist private: Variety m_variety; - NamedSchemaComponent::Ptr m_parent; + NamedSchemaComponent *m_parent; }; /** @@ -379,7 +379,7 @@ namespace QPatternist /** * Returns the substitution groups of the element. */ - XsdElement::List substitutionGroups() const; + XsdElement::WeakList substitutionGroups() const; private: SchemaType::Ptr m_type; @@ -392,7 +392,7 @@ namespace QPatternist SchemaType::DerivationConstraints m_substitutionGroupExclusions; XsdIdentityConstraint::List m_identityConstraints; XsdElement::List m_substitutionGroupAffiliations; - QSet<XsdElement::Ptr> m_substitutionGroups; + QSet<XsdElement *> m_substitutionGroups; }; } diff --git a/src/xmlpatterns/schema/qxsdparticlechecker.cpp b/src/xmlpatterns/schema/qxsdparticlechecker.cpp index 15c2afe..d4beae7 100644 --- a/src/xmlpatterns/schema/qxsdparticlechecker.cpp +++ b/src/xmlpatterns/schema/qxsdparticlechecker.cpp @@ -309,12 +309,12 @@ static bool hasDuplicatedElementsInternal(const XsdParticle::Ptr &particle, cons const XsdTerm::Ptr term = particle->term(); if (term->isElement()) { const XsdElement::Ptr mainElement(term); - XsdElement::List substGroups = mainElement->substitutionGroups(); + XsdElement::WeakList substGroups = mainElement->substitutionGroups(); if (substGroups.isEmpty()) - substGroups << mainElement; + substGroups << mainElement.data(); for (int i = 0; i < substGroups.count(); ++i) { - const XsdElement::Ptr element = substGroups.at(i); + const XsdElement::Ptr element(substGroups.at(i)); if (hash.contains(element->name(namePool))) { if (element->type()->name(namePool) != hash.value(element->name(namePool))->type()->name(namePool)) { conflictingElement = element; diff --git a/src/xmlpatterns/schema/qxsdsimpletype.cpp b/src/xmlpatterns/schema/qxsdsimpletype.cpp index 6fd5658..3e77aca 100644 --- a/src/xmlpatterns/schema/qxsdsimpletype.cpp +++ b/src/xmlpatterns/schema/qxsdsimpletype.cpp @@ -72,12 +72,12 @@ SchemaType::Ptr XsdSimpleType::wxsSuperType() const void XsdSimpleType::setContext(const NamedSchemaComponent::Ptr &component) { - m_context = component; + m_context = component.data(); } NamedSchemaComponent::Ptr XsdSimpleType::context() const { - return m_context; + return NamedSchemaComponent::Ptr(m_context); } void XsdSimpleType::setPrimitiveType(const AnySimpleType::Ptr &type) diff --git a/src/xmlpatterns/schema/qxsdsimpletype_p.h b/src/xmlpatterns/schema/qxsdsimpletype_p.h index 6305fc7..a5b72a7 100644 --- a/src/xmlpatterns/schema/qxsdsimpletype_p.h +++ b/src/xmlpatterns/schema/qxsdsimpletype_p.h @@ -202,7 +202,7 @@ namespace QPatternist private: SchemaType::Ptr m_superType; - NamedSchemaComponent::Ptr m_context; + NamedSchemaComponent* m_context; AnySimpleType::Ptr m_primitiveType; AnySimpleType::Ptr m_itemType; AnySimpleType::List m_memberTypes; diff --git a/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp index fed8a41..b6c8704 100644 --- a/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp +++ b/src/xmlpatterns/schema/qxsdstatemachinebuilder.cpp @@ -166,14 +166,14 @@ XsdStateMachine<XsdTerm::Ptr>::StateId XsdStateMachineBuilder::buildTerm(const X const XsdElement::Ptr element(term); if (m_mode == CheckingMode) { - const XsdElement::List substGroups = element->substitutionGroups(); + const XsdElement::WeakList substGroups = element->substitutionGroups(); for (int i = 0; i < substGroups.count(); ++i) - m_stateMachine->addTransition(b, substGroups.at(i), endState); + m_stateMachine->addTransition(b, XsdElement::Ptr(substGroups.at(i)), endState); } else if (m_mode == ValidatingMode) { - const XsdElement::List substGroups = element->substitutionGroups(); + const XsdElement::WeakList substGroups = element->substitutionGroups(); for (int i = 0; i < substGroups.count(); ++i) { - if (XsdSchemaHelper::substitutionGroupOkTransitive(element, substGroups.at(i), m_namePool)) - m_stateMachine->addTransition(b, substGroups.at(i), endState); + if (XsdSchemaHelper::substitutionGroupOkTransitive(element, XsdElement::Ptr(substGroups.at(i)), m_namePool)) + m_stateMachine->addTransition(b, XsdElement::Ptr(substGroups.at(i)), endState); } } diff --git a/tests/arthur/baselineserver/src/baselineserver.cpp b/tests/arthur/baselineserver/src/baselineserver.cpp index 0c0871a..97ee80c 100644 --- a/tests/arthur/baselineserver/src/baselineserver.cpp +++ b/tests/arthur/baselineserver/src/baselineserver.cpp @@ -60,6 +60,7 @@ const QString PI_CreationDate(QLS("CreationDate")); QString BaselineServer::storage; QString BaselineServer::url; +QString BaselineServer::settingsFile; BaselineServer::BaselineServer(QObject *parent) : QTcpServer(parent), lastRunIdIdx(0) @@ -91,6 +92,15 @@ QString BaselineServer::baseUrl() return url; } +QString BaselineServer::settingsFilePath() +{ + if (settingsFile.isEmpty()) { + QString exeName = QCoreApplication::applicationFilePath().section(QLC('/'), -1); + settingsFile = storagePath() + QLC('/') + exeName + QLS(".ini"); + } + return settingsFile; +} + void BaselineServer::incomingConnection(int socketDescriptor) { QString runId = QDateTime::currentDateTime().toString(QLS("MMMdd-hhmmss")); @@ -144,6 +154,8 @@ void BaselineThread::run() BaselineHandler::BaselineHandler(const QString &runId, int socketDescriptor) : QObject(), runId(runId), connectionEstablished(false) { + settings = new QSettings(BaselineServer::settingsFilePath(), QSettings::IniFormat, this); + if (socketDescriptor == -1) return; @@ -162,6 +174,7 @@ bool BaselineHandler::establishConnection() { if (!proto.acceptConnection(&plat)) { qWarning() << runId << logtime() << "Accepting new connection from" << proto.socket.peerAddress().toString() << "failed." << proto.errorMessage(); + proto.sendBlock(BaselineProtocol::Abort, proto.errorMessage().toLatin1()); // In case the client can hear us, tell it what's wrong. proto.socket.disconnectFromHost(); return false; } @@ -173,17 +186,23 @@ bool BaselineHandler::establishConnection() qDebug() << runId << logtime() << "Connection established with" << plat.value(PI_HostName) << "[" << qPrintable(plat.value(PI_HostAddress)) << "]" << logMsg; - // Filter on branch - QString branch = plat.value(PI_PulseGitBranch); - if (branch.isEmpty()) { - // Not run by Pulse, i.e. ad hoc run: Ok. - } - else if (branch != QLS("master-integration") || !plat.value(PI_GitCommit).contains(QLS("Merge branch 'master' of scm.dev.nokia.troll.no:qt/qt-fire-staging into master-integration"))) { - qDebug() << runId << logtime() << "Did not pass branch/staging repo filter, disconnecting."; - proto.sendBlock(BaselineProtocol::Abort, QByteArray("This branch/staging repo is not assigned to be tested.")); - proto.socket.disconnectFromHost(); - return false; + settings->beginGroup("ClientFilters"); + if (!settings->childKeys().isEmpty() && !plat.value(PI_PulseGitBranch).isEmpty()) { // i.e. not adhoc client + // Abort if client does not match the filters + foreach (QString filterKey, settings->childKeys()) { + QString filter = settings->value(filterKey).toString(); + QString platVal = plat.value(filterKey); + if (filter.isEmpty() || platVal.isEmpty()) + continue; // tbd: add a syntax for specifying a "value-must-be-present" filter + if (!platVal.contains(filter)) { + qDebug() << runId << logtime() << "Did not pass client filter on" << filterKey << "; disconnecting."; + proto.sendBlock(BaselineProtocol::Abort, QByteArray("Configured to not do testing for this client or repo, ref. ") + BaselineServer::settingsFilePath().toLatin1()); + proto.socket.disconnectFromHost(); + return false; + } + } } + settings->endGroup(); proto.sendBlock(BaselineProtocol::Ack, QByteArray()); diff --git a/tests/arthur/baselineserver/src/baselineserver.h b/tests/arthur/baselineserver/src/baselineserver.h index cae490f..0dcd4ea 100644 --- a/tests/arthur/baselineserver/src/baselineserver.h +++ b/tests/arthur/baselineserver/src/baselineserver.h @@ -48,6 +48,7 @@ #include <QScopedPointer> #include <QTimer> #include <QDateTime> +#include <QSettings> #include "baselineprotocol.h" #include "report.h" @@ -65,6 +66,7 @@ public: static QString storagePath(); static QString baseUrl(); + static QString settingsFilePath(); protected: void incomingConnection(int socketDescriptor); @@ -79,6 +81,7 @@ private: int lastRunIdIdx; static QString storage; static QString url; + static QString settingsFile; }; @@ -132,6 +135,7 @@ private: QString runId; bool connectionEstablished; Report report; + QSettings *settings; }; #endif // BASELINESERVER_H diff --git a/tests/arthur/common/baselineprotocol.cpp b/tests/arthur/common/baselineprotocol.cpp index 88cea36..8879b78 100644 --- a/tests/arthur/common/baselineprotocol.cpp +++ b/tests/arthur/common/baselineprotocol.cpp @@ -374,7 +374,7 @@ bool BaselineProtocol::connect(const QString &testCase, bool *dryrun) Command cmd = UnknownError; if (!receiveBlock(&cmd, &block)) { - errMsg += QLS("Failed to get response from server."); + errMsg.prepend(QLS("Failed to get response from server. ")); return false; } @@ -424,15 +424,17 @@ bool BaselineProtocol::requestBaselineChecksums(const QString &testFunction, Ima it->testFunction = testFunction; QByteArray block; - QDataStream ds(&block, QIODevice::ReadWrite); + QDataStream ds(&block, QIODevice::WriteOnly); ds << *itemList; if (!sendBlock(RequestBaselineChecksums, block)) return false; + Command cmd; - if (!receiveBlock(&cmd, &block)) + QByteArray rcvBlock; + if (!receiveBlock(&cmd, &rcvBlock) || cmd != BaselineProtocol::Ack) return false; - ds.device()->seek(0); - ds >> *itemList; + QDataStream rds(&rcvBlock, QIODevice::ReadOnly); + rds >> *itemList; return true; } diff --git a/tests/arthur/common/baselineprotocol.h b/tests/arthur/common/baselineprotocol.h index 8a99ace..bc1a3eb 100644 --- a/tests/arthur/common/baselineprotocol.h +++ b/tests/arthur/common/baselineprotocol.h @@ -146,7 +146,7 @@ public: enum Constant { ProtocolVersion = 5, ServerPort = 54129, - Timeout = 5000 + Timeout = 15000 }; enum Command { diff --git a/tests/arthur/common/paintcommands.cpp b/tests/arthur/common/paintcommands.cpp index 7a018e3..9273142 100644 --- a/tests/arthur/common/paintcommands.cpp +++ b/tests/arthur/common/paintcommands.cpp @@ -346,8 +346,12 @@ void PaintCommands::staticInit() "gradient_setLinear 1.0 1.0 2.0 2.0"); DECL_PAINTCOMMAND("gradient_setRadial", command_gradient_setRadial, "^gradient_setRadial\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s?([\\w.]*)\\s?([\\w.]*)$", - "gradient_setRadial <cx> <cy> <rad> <fx> <fy>\n - C is the center\n - rad is the angle in degrees\n - F is the focal point", + "gradient_setRadial <cx> <cy> <rad> <fx> <fy>\n - C is the center\n - rad is the radius\n - F is the focal point", "gradient_setRadial 1.0 1.0 45.0 2.0 2.0"); + DECL_PAINTCOMMAND("gradient_setRadialExtended", command_gradient_setRadialExtended, + "^gradient_setRadialExtended\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s?([\\w.]*)\\s?([\\w.]*)\\s?([\\w.]*)$", + "gradient_setRadialExtended <cx> <cy> <rad> <fx> <fy> <frad>\n - C is the center\n - rad is the center radius\n - F is the focal point\n - frad is the focal radius", + "gradient_setRadialExtended 1.0 1.0 45.0 2.0 2.0 45.0"); DECL_PAINTCOMMAND("gradient_setLinearPen", command_gradient_setLinearPen, "^gradient_setLinearPen\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)\\s+([\\w.]*)$", "gradient_setLinearPen <x1> <y1> <x2> <y2>", @@ -2400,7 +2404,7 @@ void PaintCommands::command_gradient_setRadial(QRegExp re) double fy = convertToDouble(caps.at(5)); if (m_verboseMode) - printf(" -(lance) gradient_setRadial center=(%.2f, %.2f), radius=%.2f focal=(%.2f, %.2f), " + printf(" -(lance) gradient_setRadial center=(%.2f, %.2f), radius=%.2f, focal=(%.2f, %.2f), " "spread=%d\n", cx, cy, rad, fx, fy, m_gradientSpread); @@ -2415,6 +2419,32 @@ void PaintCommands::command_gradient_setRadial(QRegExp re) } /***************************************************************************************************/ +void PaintCommands::command_gradient_setRadialExtended(QRegExp re) +{ + QStringList caps = re.capturedTexts(); + double cx = convertToDouble(caps.at(1)); + double cy = convertToDouble(caps.at(2)); + double rad = convertToDouble(caps.at(3)); + double fx = convertToDouble(caps.at(4)); + double fy = convertToDouble(caps.at(5)); + double frad = convertToDouble(caps.at(6)); + + if (m_verboseMode) + printf(" -(lance) gradient_setRadialExtended center=(%.2f, %.2f), radius=%.2f, focal=(%.2f, %.2f), " + "focal radius=%.2f, spread=%d\n", + cx, cy, rad, fx, fy, frad, m_gradientSpread); + + QRadialGradient rg(QPointF(cx, cy), rad, QPointF(fx, fy), frad); + rg.setStops(m_gradientStops); + rg.setSpread(m_gradientSpread); + rg.setCoordinateMode(m_gradientCoordinate); + QBrush brush(rg); + QTransform brush_matrix = m_painter->brush().transform(); + brush.setTransform(brush_matrix); + m_painter->setBrush(brush); +} + +/***************************************************************************************************/ void PaintCommands::command_gradient_setConical(QRegExp re) { QStringList caps = re.capturedTexts(); diff --git a/tests/arthur/common/paintcommands.h b/tests/arthur/common/paintcommands.h index 2740412..08c0e25 100644 --- a/tests/arthur/common/paintcommands.h +++ b/tests/arthur/common/paintcommands.h @@ -179,6 +179,7 @@ private: void command_gradient_setConical(QRegExp re); void command_gradient_setLinear(QRegExp re); void command_gradient_setRadial(QRegExp re); + void command_gradient_setRadialExtended(QRegExp re); void command_gradient_setLinearPen(QRegExp re); void command_gradient_setSpread(QRegExp re); void command_gradient_setCoordinateMode(QRegExp re); diff --git a/tests/arthur/data/qps/radial_gradients_extended.qps b/tests/arthur/data/qps/radial_gradients_extended.qps new file mode 100644 index 0000000..d80a149 --- /dev/null +++ b/tests/arthur/data/qps/radial_gradients_extended.qps @@ -0,0 +1,95 @@ +path_addRect path 400 0 80 80 +path_addEllipse path 440 40 60 60 + +setRenderHint Antialiasing + +setPen black + +begin_block gradients +gradient_clearStops +gradient_appendStop 0 red +gradient_appendStop 0.25 orange +gradient_appendStop 0.5 yellow +gradient_appendStop 0.8 green +gradient_appendStop 1 cyan + +gradient_setSpread PadSpread +gradient_setRadialExtended 0 0 20 40 40 10 +drawRect 0 0 100 100 + +gradient_setSpread ReflectSpread +gradient_setRadialExtended 120 20 20 140 40 10 +drawEllipse 100 0 100 100 + +gradient_setSpread RepeatSpread +gradient_setRadialExtended 240 20 20 260 40 10 +drawRoundRect 200 0 100 100 + +gradient_clearStops +gradient_appendStop 0 3f7f7fff +gradient_appendStop 0.5 dfdfffff +gradient_appendStop 1 7f00007f + +gradient_setSpread PadSpread +gradient_setRadialExtended 320 20 20 340 40 10 +drawPolygon [300 0 390 0 350 99] + +gradient_setSpread ReflectSpread +gradient_setRadialExtended 420 20 20 440 40 10 +drawPath path + +gradient_setSpread RepeatSpread +gradient_setRadialExtended 520 20 20 540 40 10 +drawPie 500 0 100 100 720 4320 +end_block + +translate 0 100 +scale 1 2 +repeat_block gradients + +resetMatrix +translate 0 300 +brushTranslate 30 0 +brushScale 0.9 0.9 +repeat_block gradients + +# Some helpful info perhaps? +resetMatrix +setPen black + +drawText 610 50 "No XForm" +drawText 610 200 "scale 1x2" +drawText 610 300 "brush transform" +drawText 10 450 "Pad" +drawText 110 450 "Reflect" +drawText 210 450 "Repeat" +drawText 310 450 "Pad w/alpha" +drawText 410 450 "Reflect w/alpha" +drawText 510 450 "Repeat w/alpha" + +# Radius and focal indicators +setPen 3f000000 +setBrush nobrush + +begin_block ellipse_draw +setClipRect 0 0 100 100 +drawEllipse -30 -30 100 100 +drawEllipse 35 35 11 11 +translate 100 0 +end_block + +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw + +resetMatrix +translate 0 100 +scale 1 2 +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw +repeat_block ellipse_draw diff --git a/tests/arthur/data/qps/radial_gradients_extended_qps.png b/tests/arthur/data/qps/radial_gradients_extended_qps.png Binary files differnew file mode 100644 index 0000000..45a3e60 --- /dev/null +++ b/tests/arthur/data/qps/radial_gradients_extended_qps.png diff --git a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp index de4ddcc..dba2007 100644 --- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp +++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp @@ -80,7 +80,7 @@ private: void recursiveCompareObjects(const QDeclarativeDebugObjectReference &a, const QDeclarativeDebugObjectReference &b) const; void recursiveCompareContexts(const QDeclarativeDebugContextReference &a, const QDeclarativeDebugContextReference &b) const; void compareProperties(const QDeclarativeDebugPropertyReference &a, const QDeclarativeDebugPropertyReference &b) const; - + QDeclarativeDebugConnection *m_conn; QDeclarativeEngineDebug *m_dbg; QDeclarativeEngine *m_engine; @@ -134,7 +134,7 @@ QDeclarativeDebugObjectReference tst_QDeclarativeDebug::findRootObject(int conte { QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); - + if (q_engines->engines().count() == 0) return QDeclarativeDebugObjectReference(); QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); @@ -368,7 +368,7 @@ void tst_QDeclarativeDebug::initTestCase() for (int i=0; i<qml.count(); i++) { QDeclarativeComponent component(m_engine); component.setData(qml[i], QUrl::fromLocalFile("")); - Q_ASSERT(component.isReady()); // fails if bad syntax + QVERIFY(component.isReady()); // fails if bad syntax m_components << qobject_cast<QDeclarativeItem*>(component.create()); } m_rootItem = qobject_cast<QDeclarativeItem*>(m_components.first()); @@ -382,7 +382,7 @@ void tst_QDeclarativeDebug::initTestCase() QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Connection established"); bool ok = m_conn->waitForConnected(); - Q_ASSERT(ok); + QVERIFY(ok); QTRY_VERIFY(QDeclarativeDebugService::hasDebuggingClient()); m_dbg = new QDeclarativeEngineDebug(m_conn, this); QTRY_VERIFY(m_dbg->status() == QDeclarativeEngineDebug::Enabled); @@ -439,7 +439,7 @@ void tst_QDeclarativeDebug::watch_property() QDeclarativeDebugPropertyReference prop = findProperty(obj.properties(), "width"); QDeclarativeDebugPropertyWatch *watch; - + QDeclarativeEngineDebug *unconnected = new QDeclarativeEngineDebug(0); watch = unconnected->addWatch(prop, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Dead); @@ -450,7 +450,7 @@ void tst_QDeclarativeDebug::watch_property() QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Inactive); delete watch; - + watch = m_dbg->addWatch(prop, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Waiting); QCOMPARE(watch->objectDebugId(), obj.debugId()); @@ -482,12 +482,12 @@ void tst_QDeclarativeDebug::watch_object() { QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); - - Q_ASSERT(q_engines->engines().count() > 0); + + QVERIFY(q_engines->engines().count() > 0); QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); - Q_ASSERT(q_context->rootContext().objects().count() > 0); + QVERIFY(q_context->rootContext().objects().count() > 0); QDeclarativeDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().objects()[0], this); waitForQuery(q_obj); @@ -504,7 +504,7 @@ void tst_QDeclarativeDebug::watch_object() QCOMPARE(watch->state(), QDeclarativeDebugWatch::Dead); delete watch; delete unconnected; - + watch = m_dbg->addWatch(QDeclarativeDebugObjectReference(), this); QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Inactive); @@ -558,7 +558,7 @@ void tst_QDeclarativeDebug::watch_expression() QFETCH(int, incrementCount); int origWidth = m_rootItem->property("width").toInt(); - + QDeclarativeDebugObjectReference obj = findRootObject(); QDeclarativeDebugObjectExpressionWatch *watch; @@ -568,12 +568,12 @@ void tst_QDeclarativeDebug::watch_expression() QCOMPARE(watch->state(), QDeclarativeDebugWatch::Dead); delete watch; delete unconnected; - + watch = m_dbg->addWatch(QDeclarativeDebugObjectReference(), expr, this); QVERIFY(QDeclarativeDebugTest::waitForSignal(watch, SIGNAL(stateChanged(QDeclarativeDebugWatch::State)))); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Inactive); delete watch; - + watch = m_dbg->addWatch(obj, expr, this); QCOMPARE(watch->state(), QDeclarativeDebugWatch::Waiting); QCOMPARE(watch->objectDebugId(), obj.debugId()); @@ -603,7 +603,7 @@ void tst_QDeclarativeDebug::watch_expression() delete watch; // restore original value and verify spy doesn't get a signal since watch has been removed - m_rootItem->setProperty("width", origWidth); + m_rootItem->setProperty("width", origWidth); QTest::qWait(100); QCOMPARE(spy.count(), expectedSpyCount); @@ -664,7 +664,13 @@ void tst_QDeclarativeDebug::queryAvailableEngines() QCOMPARE(e.name(), m_engine->objectName()); } + // Make query invalid by deleting client + q_engines = m_dbg->queryAvailableEngines(this); + QCOMPARE(q_engines->state(), QDeclarativeDebugQuery::Waiting); + delete m_dbg; + QCOMPARE(q_engines->state(), QDeclarativeDebugQuery::Error); delete q_engines; + m_dbg = new QDeclarativeEngineDebug(m_conn, this); } void tst_QDeclarativeDebug::queryRootContexts() @@ -672,9 +678,10 @@ void tst_QDeclarativeDebug::queryRootContexts() QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); int engineId = q_engines->engines()[0].debugId(); + delete q_engines; QDeclarativeDebugRootContextQuery *q_context; - + QDeclarativeEngineDebug *unconnected = new QDeclarativeEngineDebug(0); q_context = unconnected->queryRootContexts(engineId, this); QCOMPARE(q_context->state(), QDeclarativeDebugQuery::Error); @@ -703,8 +710,13 @@ void tst_QDeclarativeDebug::queryRootContexts() QVERIFY(context.contexts()[0].debugId() >= 0); QCOMPARE(context.contexts()[0].name(), QString("tst_QDeclarativeDebug_childContext")); - delete q_engines; + // Make query invalid by deleting client + q_context = m_dbg->queryRootContexts(engineId, this); + QCOMPARE(q_context->state(), QDeclarativeDebugQuery::Waiting); + delete m_dbg; + QCOMPARE(q_context->state(), QDeclarativeDebugQuery::Error); delete q_context; + m_dbg = new QDeclarativeEngineDebug(m_conn, this); } void tst_QDeclarativeDebug::queryObject() @@ -713,7 +725,7 @@ void tst_QDeclarativeDebug::queryObject() QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); - + QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); QDeclarativeDebugObjectReference rootObject = q_context->rootContext().objects()[0]; @@ -736,7 +748,14 @@ void tst_QDeclarativeDebug::queryObject() delete q_engines; delete q_context; + + // Make query invalid by deleting client + q_obj = recursive ? m_dbg->queryObjectRecursive(rootObject, this) : m_dbg->queryObject(rootObject, this); + QCOMPARE(q_obj->state(), QDeclarativeDebugQuery::Waiting); + delete m_dbg; + QCOMPARE(q_obj->state(), QDeclarativeDebugQuery::Error); delete q_obj; + m_dbg = new QDeclarativeEngineDebug(m_conn, this); // check source as defined in main() QDeclarativeDebugFileReference source = obj.source(); @@ -787,7 +806,7 @@ void tst_QDeclarativeDebug::queryExpressionResult() QDeclarativeDebugEnginesQuery *q_engines = m_dbg->queryAvailableEngines(this); waitForQuery(q_engines); // check immediate deletion is ok - + QDeclarativeDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this); waitForQuery(q_context); int objectId = q_context->rootContext().objects()[0].debugId(); @@ -799,7 +818,7 @@ void tst_QDeclarativeDebug::queryExpressionResult() QCOMPARE(q_expr->state(), QDeclarativeDebugQuery::Error); delete q_expr; delete unconnected; - + q_expr = m_dbg->queryExpressionResult(objectId, expr, this); delete q_expr; @@ -811,7 +830,14 @@ void tst_QDeclarativeDebug::queryExpressionResult() delete q_engines; delete q_context; + + // Make query invalid by deleting client + q_expr = m_dbg->queryExpressionResult(objectId, expr, this); + QCOMPARE(q_expr->state(), QDeclarativeDebugQuery::Waiting); + delete m_dbg; + QCOMPARE(q_expr->state(), QDeclarativeDebugQuery::Error); delete q_expr; + m_dbg = new QDeclarativeEngineDebug(m_conn, this); } void tst_QDeclarativeDebug::queryExpressionResult_data() @@ -938,7 +964,7 @@ void tst_QDeclarativeDebug::tst_QDeclarativeDebugPropertyReference() QDeclarativeDebugObjectQuery *query = m_dbg->queryObject(rootObject, this); waitForQuery(query); QDeclarativeDebugObjectReference obj = query->object(); - delete query; + delete query; QDeclarativeDebugPropertyReference ref = findProperty(obj.properties(), "scale"); QVERIFY(ref.objectDebugId() > 0); @@ -947,7 +973,7 @@ void tst_QDeclarativeDebug::tst_QDeclarativeDebugPropertyReference() QVERIFY(!ref.valueTypeName().isEmpty()); QVERIFY(!ref.binding().isEmpty()); QVERIFY(ref.hasNotifySignal()); - + QDeclarativeDebugPropertyReference copy(ref); QDeclarativeDebugPropertyReference copyAssign; copyAssign = ref; @@ -1001,7 +1027,7 @@ void tst_QDeclarativeDebug::setBindingForObject() // set handler // rootObject = findRootObject(); - QCOMPARE(rootObject.children().size(), 3); + QCOMPARE(rootObject.children().size(), 4); // Rectangle, Text, MouseArea, QDeclarativeComponentAttached QDeclarativeDebugObjectReference mouseAreaObject = rootObject.children().at(2); QDeclarativeDebugObjectQuery *q_obj = m_dbg->queryObjectRecursive(mouseAreaObject, this); waitForQuery(q_obj); diff --git a/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp b/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp index c182893..59214d1 100644 --- a/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp +++ b/tests/auto/declarative/qdeclarativedebugclient/tst_qdeclarativedebugclient.cpp @@ -88,7 +88,7 @@ void tst_QDeclarativeDebugClient::initTestCase() QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Connection established"); bool ok = m_conn->waitForConnected(); - Q_ASSERT(ok); + QVERIFY(ok); QTRY_VERIFY(QDeclarativeDebugService::hasDebuggingClient()); QTRY_COMPARE(client.status(), QDeclarativeDebugClient::Enabled); diff --git a/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp b/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp index 0911a83..a61f4a8 100644 --- a/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp +++ b/tests/auto/declarative/qdeclarativedebugservice/tst_qdeclarativedebugservice.cpp @@ -87,7 +87,7 @@ void tst_QDeclarativeDebugService::initTestCase() QTest::ignoreMessage(QtWarningMsg, "QDeclarativeDebugServer: Connection established"); bool ok = m_conn->waitForConnected(); - Q_ASSERT(ok); + QVERIFY(ok); QTRY_VERIFY(QDeclarativeDebugService::hasDebuggingClient()); } diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml b/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml new file mode 100644 index 0000000..cbbbbf9 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/realToInt.qml @@ -0,0 +1,11 @@ +import QtQuick 1.0 +import Qt.test 1.0 + +MyQmlObject { + function test1() { + value = 4.2 + } + function test2() { + value = 7.9 + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 1ec12fe..c7926b0 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -176,6 +176,7 @@ private slots: void aliasBindingsOverrideTarget(); void aliasWritesOverrideBindings(); void pushCleanContext(); + void realToInt(); void include(); @@ -2161,16 +2162,12 @@ public: ~CppOwnershipReturnValue() { delete value; } Q_INVOKABLE QObject *create() { - Q_ASSERT(value == 0); - value = new QObject; QDeclarativeEngine::setObjectOwnership(value, QDeclarativeEngine::CppOwnership); return value; } Q_INVOKABLE MyQmlObject *createQmlObject() { - Q_ASSERT(value == 0); - MyQmlObject *rv = new MyQmlObject; value = rv; return rv; @@ -3081,6 +3078,18 @@ void tst_qdeclarativeecmascript::pushCleanContext() QCOMPARE(func2.call().toInt32(), 6); } +void tst_qdeclarativeecmascript::realToInt() +{ + QDeclarativeComponent component(&engine, TEST_FILE("realToInt.qml")); + MyQmlObject *object = qobject_cast<MyQmlObject*>(component.create()); + QVERIFY(object != 0); + + QMetaObject::invokeMethod(object, "test1"); + QCOMPARE(object->value(), int(4)); + QMetaObject::invokeMethod(object, "test2"); + QCOMPARE(object->value(), int(8)); +} + QTEST_MAIN(tst_qdeclarativeecmascript) #include "tst_qdeclarativeecmascript.moc" diff --git a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp index e684bbe..2f0992c 100644 --- a/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp +++ b/tests/auto/declarative/qdeclarativefontloader/tst_qdeclarativefontloader.cpp @@ -55,13 +55,13 @@ #endif class tst_qdeclarativefontloader : public QObject - { Q_OBJECT public: tst_qdeclarativefontloader(); private slots: + void init(); void noFont(); void namedFont(); void localFont(); @@ -71,8 +71,6 @@ private slots: void failWebFont(); void changeFont(); -private slots: - private: QDeclarativeEngine engine; TestHTTPServer server; @@ -82,7 +80,11 @@ tst_qdeclarativefontloader::tst_qdeclarativefontloader() : server(SERVER_PORT) { server.serveDirectory(SRCDIR "/data"); - Q_ASSERT(server.isValid()); +} + +void tst_qdeclarativefontloader::init() +{ + QVERIFY(server.isValid()); } void tst_qdeclarativefontloader::noFont() diff --git a/tests/auto/declarative/qdeclarativegridview/data/gridview1.qml b/tests/auto/declarative/qdeclarativegridview/data/gridview1.qml index caa28d6..a2b0a91 100644 --- a/tests/auto/declarative/qdeclarativegridview/data/gridview1.qml +++ b/tests/auto/declarative/qdeclarativegridview/data/gridview1.qml @@ -2,6 +2,7 @@ import QtQuick 1.1 Rectangle { id: root + property int count: grid.count property bool showHeader: false property bool showFooter: false property int added: -1 diff --git a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp index c8e7817..dc79370 100644 --- a/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp +++ b/tests/auto/declarative/qdeclarativegridview/tst_qdeclarativegridview.cpp @@ -222,6 +222,7 @@ void tst_QDeclarativeGridView::items() QTRY_VERIFY(contentItem != 0); QTRY_COMPARE(gridview->count(), model.count()); + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item for (int i = 0; i < model.count(); ++i) { @@ -305,6 +306,7 @@ void tst_QDeclarativeGridView::inserted() QTRY_VERIFY(contentItem != 0); model.insertItem(1, "Will", "9876"); + QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count()); QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item @@ -382,6 +384,7 @@ void tst_QDeclarativeGridView::removed() QTRY_VERIFY(contentItem != 0); model.removeItem(1); + QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count()); QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 1); QTRY_VERIFY(name != 0); diff --git a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp index 2f7513f..7ca2b79 100644 --- a/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp +++ b/tests/auto/declarative/qdeclarativelistmodel/tst_qdeclarativelistmodel.cpp @@ -115,7 +115,6 @@ int tst_qdeclarativelistmodel::roleFromName(const QDeclarativeListModel *model, if (model->toString(roles[i]) == roleName) return roles[i]; } - Q_ASSERT(false); return -1; } @@ -741,6 +740,7 @@ void tst_qdeclarativelistmodel::get() "}", QUrl()); QDeclarativeListModel *model = qobject_cast<QDeclarativeListModel*>(component.create()); int role = roleFromName(model, roleName); + QVERIFY(role >= 0); QSignalSpy spy(model, SIGNAL(itemsChanged(int, int, QList<int>))); QDeclarativeExpression expr(eng.rootContext(), model, expression); @@ -802,6 +802,7 @@ void tst_qdeclarativelistmodel::get_worker() model.append(sv); model.append(sv); int role = roleFromName(&model, roleName); + QVERIFY(role >= 0); const char *warning = "<Unknown File>: QML ListModel: Cannot add list-type data when modifying or after modification from a worker script"; if (roleValue.type() == QVariant::List || roleValue.type() == QVariant::Map) @@ -893,6 +894,7 @@ void tst_qdeclarativelistmodel::get_nested() int outerListIndex = testData[i].first; QString outerListRoleName = testData[i].second; int outerListRole = roleFromName(model, outerListRoleName); + QVERIFY(outerListRole >= 0); childModel = qobject_cast<QDeclarativeListModel*>(model->data(outerListIndex, outerListRole).value<QObject*>()); QVERIFY(childModel); @@ -905,6 +907,7 @@ void tst_qdeclarativelistmodel::get_nested() QVERIFY(!expr.hasError()); int role = roleFromName(childModel, roleName); + QVERIFY(role >= 0); QCOMPARE(childModel->data(index, role), roleValue); QCOMPARE(spy.count(), 1); diff --git a/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml index 3cd6f42..75ddabb 100644 --- a/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml +++ b/tests/auto/declarative/qdeclarativelistview/data/listviewtest.qml @@ -6,6 +6,7 @@ Rectangle { height: 320 color: "#ffffff" + property int count: list.count property bool showHeader: false property bool showFooter: false property real hr: list.visibleArea.heightRatio diff --git a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp index 0c96587..23ac523 100644 --- a/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp +++ b/tests/auto/declarative/qdeclarativelistview/tst_qdeclarativelistview.cpp @@ -389,6 +389,7 @@ void tst_QDeclarativeListView::items() QTRY_VERIFY(listview->highlightItem() != 0); QTRY_COMPARE(listview->count(), model.count()); + QTRY_COMPARE(canvas->rootObject()->property("count").toInt(), model.count()); QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item // current item should be first item @@ -517,6 +518,7 @@ void tst_QDeclarativeListView::inserted() model.insertItem(0, "Foo", "1111"); // zero index, and current item + QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count()); QTRY_COMPARE(contentItem->childItems().count(), model.count()+1); // assumes all are visible, +1 for the (default) highlight item name = findItem<QDeclarativeText>(contentItem, "textName", 0); @@ -583,6 +585,7 @@ void tst_QDeclarativeListView::removed(bool animated) QTRY_VERIFY(contentItem != 0); model.removeItem(1); + QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count()); QDeclarativeText *name = findItem<QDeclarativeText>(contentItem, "textName", 1); QTRY_VERIFY(name != 0); @@ -711,6 +714,16 @@ void tst_QDeclarativeListView::removed(bool animated) QTRY_VERIFY(name = findItem<QDeclarativeText>(contentItem, "textName", model.count()-1)); QCOMPARE(name->text(), QString("New")); + // Add some more items so that we don't run out + for (int i = 50; i < 100; i++) + model.addItem("Item" + QString::number(i), ""); + + // QTBUG-19198 move to end and remove all visible items one at a time. + listview->positionViewAtEnd(); + for (int i = 0; i < 18; ++i) + model.removeItems(model.count() - 1, 1); + QTRY_VERIFY(findItems<QDeclarativeItem>(contentItem, "wrapper").count() > 16); + delete canvas; } diff --git a/tests/auto/declarative/qdeclarativemousearea/data/preventContextMenu.qml b/tests/auto/declarative/qdeclarativemousearea/data/preventContextMenu.qml new file mode 100644 index 0000000..dcbb5d7 --- /dev/null +++ b/tests/auto/declarative/qdeclarativemousearea/data/preventContextMenu.qml @@ -0,0 +1,22 @@ +import QtQuick 1.1 +import Test 1.0 + +Item { + width: 200 + height: 200 + + property alias mouseAreaEnabled: mouseArea.enabled + property alias eventsReceived: receiver.eventCount + + ContextMenuEventReceiver { + id: receiver + anchors.fill: parent + } + + MouseArea { + id: mouseArea + anchors.fill: parent + acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton + enabled: true + } +} diff --git a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp index e1c34fc..fea7865 100644 --- a/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp +++ b/tests/auto/declarative/qdeclarativemousearea/tst_qdeclarativemousearea.cpp @@ -47,6 +47,7 @@ #include <QtDeclarative/qdeclarativeview.h> #include <QtDeclarative/qdeclarativecontext.h> #include <QtDeclarative/qdeclarativeengine.h> +#include <QtDeclarative/qdeclarativeproperty.h> #ifdef Q_OS_SYMBIAN // In Symbian OS test data is located in applications private dir @@ -70,6 +71,9 @@ private slots: void preventStealing(); void testQtQuick11Attributes(); void testQtQuick11Attributes_data(); +#ifndef QT_NO_CONTEXTMENU + void preventContextMenu(); +#endif // QT_NO_CONTEXTMENU private: QDeclarativeView *createView(); @@ -637,6 +641,65 @@ void tst_QDeclarativeMouseArea::testQtQuick11Attributes_data() << ":1 \"MouseArea.preventStealing\" is not available in QtQuick 1.0.\n"; } +#ifndef QT_NO_CONTEXTMENU +class ContextMenuEventReceiver : public QDeclarativeItem +{ + Q_OBJECT + Q_PROPERTY(int eventCount READ eventCount NOTIFY eventCountChanged); +public: + ContextMenuEventReceiver(QDeclarativeItem *parent = 0) : QDeclarativeItem(parent), m_eventCount(0) { } + int eventCount() const { return m_eventCount; } +signals: + void eventCountChanged(int); +protected: + void contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { + if (event->reason() == QGraphicsSceneContextMenuEvent::Mouse) { + m_eventCount++; + emit eventCountChanged(m_eventCount); + } + } +private: + int m_eventCount; +}; + +void tst_QDeclarativeMouseArea::preventContextMenu() +{ + // A MouseArea accepting Left, Middle and Right buttons should prevent context menu + // events with "Mouse" reason to hit the Item below. + + qmlRegisterType<ContextMenuEventReceiver>("Test", 1, 0, "ContextMenuEventReceiver"); + + QDeclarativeView *view = createView(); + view->setSource(QUrl::fromLocalFile(SRCDIR "/data/preventContextMenu.qml")); + view->show(); + QVERIFY(view->rootObject() != 0); + + QDeclarativeProperty mouseAreaEnabled(view->rootObject(), "mouseAreaEnabled"); + QVERIFY(mouseAreaEnabled.read().toBool()); + + QDeclarativeProperty eventsReceived(view->rootObject(), "eventsReceived"); + QCOMPARE(eventsReceived.read().toInt(), 0); + + QPoint targetPoint = view->mapFromScene(QPoint(80, 80)); + + QContextMenuEvent fakeEvent1(QContextMenuEvent::Mouse, targetPoint); + QApplication::sendEvent(view->viewport(), &fakeEvent1); + QCOMPARE(eventsReceived.read().toInt(), 0); + + mouseAreaEnabled.write(false); + QVERIFY(!mouseAreaEnabled.read().toBool()); + QContextMenuEvent fakeEvent2(QContextMenuEvent::Mouse, targetPoint); + QApplication::sendEvent(view->viewport(), &fakeEvent2); + QCOMPARE(eventsReceived.read().toInt(), 1); + + mouseAreaEnabled.write(true); + QVERIFY(mouseAreaEnabled.read().toBool()); + QContextMenuEvent fakeEvent3(QContextMenuEvent::Mouse, targetPoint); + QApplication::sendEvent(view->viewport(), &fakeEvent3); + QCOMPARE(eventsReceived.read().toInt(), 1); +} +#endif // QT_NO_CONTEXTMENU + QTEST_MAIN(tst_QDeclarativeMouseArea) #include "tst_qdeclarativemousearea.moc" diff --git a/tests/auto/declarative/qdeclarativepathview/data/datamodel.qml b/tests/auto/declarative/qdeclarativepathview/data/datamodel.qml index 1322025..e2c4e3d 100644 --- a/tests/auto/declarative/qdeclarativepathview/data/datamodel.qml +++ b/tests/auto/declarative/qdeclarativepathview/data/datamodel.qml @@ -2,6 +2,7 @@ import QtQuick 1.0 PathView { id: pathview + property int viewCount: count objectName: "pathview" width: 240; height: 320 pathItemCount: testObject.pathItemCount diff --git a/tests/auto/declarative/qdeclarativepathview/data/pathview0.qml b/tests/auto/declarative/qdeclarativepathview/data/pathview0.qml index 04c7717..28b6fb9 100644 --- a/tests/auto/declarative/qdeclarativepathview/data/pathview0.qml +++ b/tests/auto/declarative/qdeclarativepathview/data/pathview0.qml @@ -2,6 +2,7 @@ import QtQuick 1.0 Rectangle { id: root + property int count: view.count property int currentA: -1 property int currentB: -1 property real delegateWidth: 60 diff --git a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp index 46c3519..24b1115 100644 --- a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp +++ b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp @@ -253,6 +253,8 @@ void tst_QDeclarativePathView::items() QDeclarativePathView *pathview = findItem<QDeclarativePathView>(canvas->rootObject(), "view"); QVERIFY(pathview != 0); + QCOMPARE(pathview->count(), model.count()); + QCOMPARE(canvas->rootObject()->property("count").toInt(), model.count()); QCOMPARE(pathview->childItems().count(), model.count()+1); // assumes all are visible, including highlight for (int i = 0; i < model.count(); ++i) { @@ -400,6 +402,7 @@ void tst_QDeclarativePathView::dataModel() model.insertItem(4, "orange", "10"); QTest::qWait(100); + QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count()); QTRY_COMPARE(findItems<QDeclarativeItem>(pathview, "wrapper").count(), 14); QVERIFY(pathview->currentIndex() == 0); @@ -409,6 +412,7 @@ void tst_QDeclarativePathView::dataModel() QCOMPARE(text->text(), model.name(4)); model.removeItem(2); + QCOMPARE(canvas->rootObject()->property("viewCount").toInt(), model.count()); text = findItem<QDeclarativeText>(pathview, "myText", 2); QVERIFY(text); QCOMPARE(text->text(), model.name(2)); diff --git a/tests/auto/declarative/qdeclarativetextedit/data/mouseselection_multiline.qml b/tests/auto/declarative/qdeclarativetextedit/data/mouseselection_multiline.qml new file mode 100644 index 0000000..af23f6d --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextedit/data/mouseselection_multiline.qml @@ -0,0 +1,8 @@ +import QtQuick 1.1 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRS\nTUVWXYZ" + selectByMouse: true + mouseSelectionMode: TextInput.SelectWords +} diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index 2fad88d..f8af433 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -119,6 +119,7 @@ private slots: void moveCursorSelectionSequence(); void mouseSelection_data(); void mouseSelection(); + void multilineMouseSelection(); void deferEnableSelectByMouse_data(); void deferEnableSelectByMouse(); void deferDisableSelectByMouse_data(); @@ -1364,6 +1365,41 @@ void tst_qdeclarativetextedit::mouseSelection() delete canvas; } +void tst_qdeclarativetextedit::multilineMouseSelection() +{ + QDeclarativeView *canvas = createView(SRCDIR "/data/mouseselection_multiline.qml"); + + canvas->show(); + QApplication::setActiveWindow(canvas); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas)); + + QVERIFY(canvas->rootObject() != 0); + QDeclarativeTextEdit *textEditObject = qobject_cast<QDeclarativeTextEdit *>(canvas->rootObject()); + QVERIFY(textEditObject != 0); + + // press-and-drag from x1,y1 to x2,y1 + int x1 = 10; + int x2 = textEditObject->width() - 10; + int y1 = textEditObject->height() / 4; + int y2 = textEditObject->height() * 3 / 4; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y1))); + QMouseEvent mv1(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y1)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv1); + QString str1 = textEditObject->selectedText(); + QVERIFY(str1.length() > 3); // don't reallly care *what* was selected (and it's too sensitive to platform) + + // drag-and-release from x2,y1 to x2,y2 + QMouseEvent mv2(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y2)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv2); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y2))); + QString str2 = textEditObject->selectedText(); + QVERIFY(str1 != str2); + QVERIFY(str2.length() > 3); + + delete canvas; +} + void tst_qdeclarativetextedit::deferEnableSelectByMouse_data() { QTest::addColumn<QString>("qmlfile"); @@ -1639,6 +1675,26 @@ void tst_qdeclarativetextedit::cursorDelegate() QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); } + // Clear preedit text; + QInputMethodEvent event; + QApplication::sendEvent(view, &event); + + // Test delegate gets moved on mouse press. + textEditObject->setSelectByMouse(true); + textEditObject->setCursorPosition(0); + qDebug() << textEditObject->boundingRect() << textEditObject->positionToRectangle(5).center() << view->mapFromScene(textEditObject->positionToRectangle(5).center()); + QTest::mouseClick(view->viewport(), Qt::LeftButton, 0, view->mapFromScene(textEditObject->positionToRectangle(5).center())); + QVERIFY(textEditObject->cursorPosition() != 0); + QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); + QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + + textEditObject->setReadOnly(true); + textEditObject->setCursorPosition(0); + QTest::mouseClick(view->viewport(), Qt::LeftButton, 0, view->mapFromScene(textEditObject->positionToRectangle(5).center())); + QVERIFY(textEditObject->cursorPosition() != 0); + QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); + QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + textEditObject->setCursorPosition(0); QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); diff --git a/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp b/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp index 85d7876..7b384f8 100644 --- a/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp +++ b/tests/auto/declarative/qdeclarativevisualdatamodel/tst_qdeclarativevisualdatamodel.cpp @@ -190,6 +190,11 @@ void tst_qdeclarativevisualdatamodel::rootIndex() QMetaObject::invokeMethod(obj, "setRootToParent"); QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex()); + QMetaObject::invokeMethod(obj, "setRoot"); + QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == model.index(0,0)); + model.clear(); // will emit modelReset() + QVERIFY(qvariant_cast<QModelIndex>(obj->rootIndex()) == QModelIndex()); + delete obj; } diff --git a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp index a0e2547..c4f4058 100644 --- a/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp +++ b/tests/auto/declarative/qdeclarativexmllistmodel/tst_qdeclarativexmllistmodel.cpp @@ -126,7 +126,10 @@ private: QStringList fields = item.split(","); foreach(const QString &field, fields) { QStringList values = field.split("="); - Q_ASSERT(values.count() == 2); + if (values.count() != 2) { + qWarning() << "makeItemXmlAndData: invalid field:" << field; + continue; + } xml += QString("<%1>%2</%1>").arg(values[0], values[1]); if (!modelData) continue; diff --git a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp index 1b9831c..f12bcc3 100644 --- a/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp +++ b/tests/auto/declarative/qmetaobjectbuilder/tst_qmetaobjectbuilder.cpp @@ -546,6 +546,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!nullProp.isUser()); QVERIFY(!nullProp.hasStdCppSet()); QVERIFY(!nullProp.isEnumOrFlag()); + QVERIFY(!nullProp.isConstant()); + QVERIFY(!nullProp.isFinal()); QCOMPARE(nullProp.index(), 0); // Add a property and check its attributes. @@ -563,6 +565,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop1.isUser()); QVERIFY(!prop1.hasStdCppSet()); QVERIFY(!prop1.isEnumOrFlag()); + QVERIFY(!prop1.isConstant()); + QVERIFY(!prop1.isFinal()); QCOMPARE(prop1.index(), 0); QCOMPARE(builder.propertyCount(), 1); @@ -581,6 +585,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); + QVERIFY(!prop2.isConstant()); + QVERIFY(!prop2.isFinal()); QCOMPARE(prop2.index(), 1); QCOMPARE(builder.propertyCount(), 2); @@ -602,6 +608,8 @@ void tst_QMetaObjectBuilder::property() prop1.setUser(true); prop1.setStdCppSet(true); prop1.setEnumOrFlag(true); + prop1.setConstant(true); + prop1.setFinal(true); // Check that prop1 is changed, but prop2 is not. QCOMPARE(prop1.name(), QByteArray("foo")); @@ -616,6 +624,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(prop1.isUser()); QVERIFY(prop1.hasStdCppSet()); QVERIFY(prop1.isEnumOrFlag()); + QVERIFY(prop1.isConstant()); + QVERIFY(prop1.isFinal()); QVERIFY(prop2.isReadable()); QVERIFY(prop2.isWritable()); QCOMPARE(prop2.name(), QByteArray("bar")); @@ -628,6 +638,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); + QVERIFY(!prop2.isConstant()); + QVERIFY(!prop2.isFinal()); // Remove prop1 and check that prop2 becomes index 0. builder.removeProperty(0); @@ -643,6 +655,8 @@ void tst_QMetaObjectBuilder::property() QVERIFY(!prop2.isUser()); QVERIFY(!prop2.hasStdCppSet()); QVERIFY(!prop2.isEnumOrFlag()); + QVERIFY(!prop2.isConstant()); + QVERIFY(!prop2.isFinal()); QCOMPARE(prop2.index(), 0); // Perform index-based lookup again. @@ -666,6 +680,8 @@ void tst_QMetaObjectBuilder::property() prop2.setUser(false); \ prop2.setStdCppSet(false); \ prop2.setEnumOrFlag(false); \ + prop2.setConstant(false); \ + prop2.setFinal(false); \ } while (0) #define COUNT_FLAGS() \ ((prop2.isReadable() ? 1 : 0) + \ @@ -677,7 +693,9 @@ void tst_QMetaObjectBuilder::property() (prop2.isEditable() ? 1 : 0) + \ (prop2.isUser() ? 1 : 0) + \ (prop2.hasStdCppSet() ? 1 : 0) + \ - (prop2.isEnumOrFlag() ? 1 : 0)) + (prop2.isEnumOrFlag() ? 1 : 0) + \ + (prop2.isConstant() ? 1 : 0) + \ + (prop2.isFinal() ? 1 : 0)) #define CHECK_FLAG(setFunc,isFunc) \ do { \ CLEAR_FLAGS(); \ @@ -696,6 +714,8 @@ void tst_QMetaObjectBuilder::property() CHECK_FLAG(setUser, isUser); CHECK_FLAG(setStdCppSet, hasStdCppSet); CHECK_FLAG(setEnumOrFlag, isEnumOrFlag); + CHECK_FLAG(setConstant, isConstant); + CHECK_FLAG(setFinal, isFinal); // Check that nothing else changed. QVERIFY(checkForSideEffects(builder, QMetaObjectBuilder::Properties)); diff --git a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp index 2dbed3b..61e1883 100644 --- a/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp +++ b/tests/auto/declarative/qmlvisual/tst_qmlvisual.cpp @@ -185,16 +185,22 @@ QString tst_qmlvisual::toTestScript(const QString &file, Mode mode) if (platformsuffix && (mode == UpdatePlatformVisuals || QFile::exists(testdata+QLatin1String(platformsuffix)+QDir::separator()+testname+".qml"))) { QString platformdir = testdata + QLatin1String(platformsuffix); if (mode == UpdatePlatformVisuals) { - Q_ASSERT(QDir().mkpath(platformdir)); + if (!QDir().mkpath(platformdir)) { + qFatal("Cannot make path %s", qPrintable(platformdir)); + } // Copy from base QDir dir(testdata,testname+".*"); dir.setFilter(QDir::Files); QFileInfoList list = dir.entryInfoList(); for (int i = 0; i < list.size(); ++i) { QFile in(list.at(i).filePath()); - Q_ASSERT(in.open(QIODevice::ReadOnly)); + if (!in.open(QIODevice::ReadOnly)) { + qFatal("Cannot open file %s: %s", qPrintable(in.fileName()), qPrintable(in.errorString())); + } QFile out(platformdir + QDir::separator() + list.at(i).fileName()); - Q_ASSERT(out.open(QIODevice::WriteOnly)); + if (!out.open(QIODevice::WriteOnly)) { + qFatal("Cannot open file %s: %s", qPrintable(out.fileName()), qPrintable(out.errorString())); + } out.write(in.readAll()); } } @@ -234,8 +240,6 @@ QStringList tst_qmlvisual::findQmlFiles(const QDir &d) void action(Mode mode, const QString &file) { - Q_ASSERT(mode != Test); - QString testdata = tst_qmlvisual::toTestScript(file,mode); QStringList arguments; diff --git a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp index e7e516e..d167228 100644 --- a/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp +++ b/tests/auto/exceptionsafety_objects/tst_exceptionsafety_objects.cpp @@ -60,7 +60,7 @@ QT_USE_NAMESPACE #include "3rdparty/memcheck.h" #endif -class tst_ExceptionSafetyObjects: public QObject +class tst_ExceptionSafety_Objects: public QObject { Q_OBJECT @@ -156,7 +156,7 @@ struct DirCreator : public AbstractTester } }; -void tst_ExceptionSafetyObjects::objects_data() +void tst_ExceptionSafety_Objects::objects_data() { QTest::addColumn<AbstractTester *>("objectCreator"); @@ -164,12 +164,12 @@ void tst_ExceptionSafetyObjects::objects_data() NEWROW(QObject); NEWROW(QBuffer); NEWROW(QFile); + NEWROW(QFSFileEngine); NEWROW(QProcess); NEWROW(QSettings); NEWROW(QThread); NEWROW(QThreadPool); NEWROW(QTranslator); - NEWROW(QFSFileEngine); #define NEWROW2(T, CREATOR) QTest::newRow(#T) << static_cast<AbstractTester *>(new CREATOR) NEWROW2(QBitArray, BitArrayCreator); @@ -177,7 +177,6 @@ void tst_ExceptionSafetyObjects::objects_data() NEWROW2(QCryptographicHash, CryptographicHashCreator); NEWROW2(QDataStream, DataStreamCreator); NEWROW2(QDir, DirCreator); - } // create and destructs an object, and lets each and every allocation @@ -274,9 +273,9 @@ public: } }; -QtMsgHandler tst_ExceptionSafetyObjects::testMessageHandler; +QtMsgHandler tst_ExceptionSafety_Objects::testMessageHandler; -void tst_ExceptionSafetyObjects::safeMessageHandler(QtMsgType type, const char *msg) +void tst_ExceptionSafety_Objects::safeMessageHandler(QtMsgType type, const char *msg) { // this temporarily suspends OOM testing while handling a message int currentIndex = mallocFailIndex; @@ -301,7 +300,7 @@ void debugUnexpected() (*defaultUnexpected)(); } -void tst_ExceptionSafetyObjects::initTestCase() +void tst_ExceptionSafety_Objects::initTestCase() { // set handlers for bad exception cases, you might want to step in and breakpoint the default handlers too defaultTerminate = std::set_terminate(&debugTerminate); @@ -345,17 +344,25 @@ void tst_ExceptionSafetyObjects::initTestCase() QCOMPARE(malloc2Failed, 1); } -void tst_ExceptionSafetyObjects::cleanupTestCase() +void tst_ExceptionSafety_Objects::cleanupTestCase() { qInstallMsgHandler(testMessageHandler); } -void tst_ExceptionSafetyObjects::objects() +void tst_ExceptionSafety_Objects::objects() { + QLatin1String tag = QLatin1String(QTest::currentDataTag()); + if (tag == QLatin1String("QFile") + || tag == QLatin1String("QProcess") + || tag == QLatin1String("QSettings") + || tag == QLatin1String("QThread") + || tag == QLatin1String("QThreadPool")) + QSKIP("This type of object is not currently strongly exception safe", SkipSingle); + QFETCH(AbstractTester *, objectCreator); doOOMTest(*objectCreator, 0); - + delete objectCreator; } @@ -364,7 +371,8 @@ struct WidgetCreator : public AbstractTester { void operator()(QObject *parent) { - Q_ASSERT(!parent || parent->isWidgetType()); + if (parent && !parent->isWidgetType()) + qFatal("%s: parent must be either null or a widget type", Q_FUNC_INFO); QScopedPointer<T> ptr(parent ? new T(static_cast<QWidget *>(parent)) : new T); } }; @@ -374,7 +382,8 @@ template <> struct WidgetCreator<QSizeGrip> : public AbstractTester { void operator()(QObject *parent) { - Q_ASSERT(!parent || parent->isWidgetType()); + if (parent && !parent->isWidgetType()) + qFatal("%s: parent must be either null or a widget type", Q_FUNC_INFO); QScopedPointer<QSizeGrip> ptr(new QSizeGrip(static_cast<QWidget *>(parent))); } }; @@ -384,17 +393,18 @@ template <> struct WidgetCreator<QDesktopWidget> : public AbstractTester { void operator()(QObject *parent) { - Q_ASSERT(!parent || parent->isWidgetType()); + if (parent && !parent->isWidgetType()) + qFatal("%s: parent must be either null or a widget type", Q_FUNC_INFO); QScopedPointer<QDesktopWidget> ptr(new QDesktopWidget()); } }; -void tst_ExceptionSafetyObjects::widgets_data() +void tst_ExceptionSafety_Objects::widgets_data() { #ifdef Q_OS_SYMBIAN // Initialise the S60 rasteriser, which crashes if started while out of memory - QImage image(20, 20, QImage::Format_RGB32); - QPainter p(&image); - p.drawText(0, 15, "foo"); + QImage image(20, 20, QImage::Format_RGB32); + QPainter p(&image); + p.drawText(0, 15, "foo"); #endif QTest::addColumn<AbstractTester *>("widgetCreator"); @@ -405,23 +415,27 @@ void tst_ExceptionSafetyObjects::widgets_data() NEWROW(QWidget); NEWROW(QButtonGroup); - NEWROW(QDesktopWidget); NEWROW(QCheckBox); + NEWROW(QColumnView); NEWROW(QComboBox); NEWROW(QCommandLinkButton); NEWROW(QDateEdit); NEWROW(QDateTimeEdit); + NEWROW(QDesktopWidget); NEWROW(QDial); NEWROW(QDoubleSpinBox); NEWROW(QFocusFrame); NEWROW(QFontComboBox); NEWROW(QFrame); NEWROW(QGroupBox); - NEWROW(QLCDNumber); NEWROW(QLabel); NEWROW(QLCDNumber); NEWROW(QLineEdit); + NEWROW(QListView); + NEWROW(QListWidget); + NEWROW(QMainWindow); NEWROW(QMenu); + NEWROW(QMenuBar); NEWROW(QPlainTextEdit); NEWROW(QProgressBar); NEWROW(QPushButton); @@ -435,28 +449,58 @@ void tst_ExceptionSafetyObjects::widgets_data() NEWROW(QStackedWidget); NEWROW(QStatusBar); NEWROW(QTabBar); + NEWROW(QTableView); + NEWROW(QTableWidget); NEWROW(QTabWidget); NEWROW(QTextBrowser); NEWROW(QTextEdit); NEWROW(QTimeEdit); + NEWROW(QToolBar); NEWROW(QToolBox); NEWROW(QToolButton); - NEWROW(QStatusBar); - NEWROW(QToolBar); - NEWROW(QMenuBar); - NEWROW(QMainWindow); - NEWROW(QWorkspace); - NEWROW(QColumnView); - NEWROW(QListView); - NEWROW(QListWidget); - NEWROW(QTableView); - NEWROW(QTableWidget); NEWROW(QTreeView); NEWROW(QTreeWidget); + NEWROW(QWorkspace); } -void tst_ExceptionSafetyObjects::widgets() -{ +void tst_ExceptionSafety_Objects::widgets() +{ + QLatin1String tag = QLatin1String(QTest::currentDataTag()); + if (tag == QLatin1String("QColumnView") + || tag == QLatin1String("QComboBox") + || tag == QLatin1String("QCommandLinkButton") + || tag == QLatin1String("QDateEdit") + || tag == QLatin1String("QDateTimeEdit") + || tag == QLatin1String("QDesktopWidget") + || tag == QLatin1String("QDoubleSpinBox") + || tag == QLatin1String("QFontComboBox") + || tag == QLatin1String("QGroupBox") + || tag == QLatin1String("QLineEdit") + || tag == QLatin1String("QListView") + || tag == QLatin1String("QListWidget") + || tag == QLatin1String("QMainWindow") + || tag == QLatin1String("QMenu") + || tag == QLatin1String("QMenuBar") + || tag == QLatin1String("QPlainTextEdit") + || tag == QLatin1String("QProgressBar") + || tag == QLatin1String("QPushButton") + || tag == QLatin1String("QScrollArea") + || tag == QLatin1String("QSpinBox") + || tag == QLatin1String("QStackedWidget") + || tag == QLatin1String("QStatusBar") + || tag == QLatin1String("QTableView") + || tag == QLatin1String("QTableWidget") + || tag == QLatin1String("QTabWidget") + || tag == QLatin1String("QTextBrowser") + || tag == QLatin1String("QTextEdit") + || tag == QLatin1String("QTimeEdit") + || tag == QLatin1String("QToolBar") + || tag == QLatin1String("QToolBox") + || tag == QLatin1String("QTreeView") + || tag == QLatin1String("QTreeWidget") + || tag == QLatin1String("QWorkspace")) + QSKIP("This type of widget is not currently strongly exception safe", SkipSingle); + QFETCH(AbstractTester *, widgetCreator); doOOMTest(*widgetCreator, 0, 00000); @@ -547,7 +591,9 @@ struct IntegerMoveable }; int IntegerMoveable::instanceCount = 0; +QT_BEGIN_NAMESPACE Q_DECLARE_TYPEINFO(IntegerMoveable, Q_MOVABLE_TYPE); +QT_END_NAMESPACE template <typename T, template<typename> class Container> void containerInsertTest(QObject*) @@ -720,12 +766,12 @@ static void containerData() QTest::newRow("erase moveable") << static_cast<TestFunction>(containerEraseTest<IntegerMoveable, Container>); } -void tst_ExceptionSafetyObjects::vector_data() +void tst_ExceptionSafety_Objects::vector_data() { containerData<QVector>(); } -void tst_ExceptionSafetyObjects::vector() +void tst_ExceptionSafety_Objects::vector() { QFETCH(TestFunction, testFunction); @@ -736,30 +782,30 @@ void tst_ExceptionSafetyObjects::vector() doOOMTest(testFunction, 0); } -void tst_ExceptionSafetyObjects::list_data() +void tst_ExceptionSafety_Objects::list_data() { containerData<QList>(); } -void tst_ExceptionSafetyObjects::list() +void tst_ExceptionSafety_Objects::list() { QFETCH(TestFunction, testFunction); doOOMTest(testFunction, 0); } -void tst_ExceptionSafetyObjects::linkedList_data() +void tst_ExceptionSafety_Objects::linkedList_data() { containerData<QLinkedList>(); } -void tst_ExceptionSafetyObjects::linkedList() +void tst_ExceptionSafety_Objects::linkedList() { QFETCH(TestFunction, testFunction); doOOMTest(testFunction, 0); } -QTEST_MAIN(tst_ExceptionSafetyObjects) +QTEST_MAIN(tst_ExceptionSafety_Objects) #include "tst_exceptionsafety_objects.moc" #endif // QT_NO_EXCEPTIONS diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp index 7327a49..d580c8b 100644 --- a/tests/auto/gestures/tst_gestures.cpp +++ b/tests/auto/gestures/tst_gestures.cpp @@ -280,7 +280,7 @@ protected: eventsPtr->canceled << g->gestureType(); break; default: - Q_ASSERT(false); + qWarning() << "Unknown GestureState enum value:" << static_cast<int>(g->state()); } } } else if (event->type() == CustomEvent::EventType) { @@ -823,7 +823,7 @@ public: emit gestureCanceled(e->type(), g); break; default: - Q_ASSERT(false); + qWarning() << "Unknown GestureState enum value:" << static_cast<int>(g->state()); } } } else if (event->type() == CustomEvent::EventType) { @@ -1518,17 +1518,20 @@ void tst_Gestures::autoCancelGestures() { class MockWidget : public GestureWidget { public: - MockWidget(const char *name) : GestureWidget(name) { } + MockWidget(const char *name) : GestureWidget(name), badGestureEvents(0) { } bool event(QEvent *event) { if (event->type() == QEvent::Gesture) { QGestureEvent *ge = static_cast<QGestureEvent*>(event); - Q_ASSERT(ge->gestures().count() == 1); // can't use QCOMPARE here... + if (ge->gestures().count() != 1) + ++badGestureEvents; // event should contain exactly one gesture ge->gestures().first()->setGestureCancelPolicy(QGesture::CancelAllInContext); } return GestureWidget::event(event); } + + int badGestureEvents; }; const Qt::GestureType secondGesture = QGestureRecognizer::registerRecognizer(new CustomGestureRecognizer); @@ -1563,22 +1566,26 @@ void tst_Gestures::autoCancelGestures() event.serial = CustomGesture::SerialFinishedThreshold; QApplication::sendEvent(child, &event); QCOMPARE(parent.events.all.count(), 2); + QCOMPARE(parent.badGestureEvents, 0); } void tst_Gestures::autoCancelGestures2() { class MockItem : public GestureItem { public: - MockItem(const char *name) : GestureItem(name) { } + MockItem(const char *name) : GestureItem(name), badGestureEvents(0) { } bool event(QEvent *event) { if (event->type() == QEvent::Gesture) { QGestureEvent *ge = static_cast<QGestureEvent*>(event); - Q_ASSERT(ge->gestures().count() == 1); // can't use QCOMPARE here... + if (ge->gestures().count() != 1) + ++badGestureEvents; // event should contain exactly one gesture ge->gestures().first()->setGestureCancelPolicy(QGesture::CancelAllInContext); } return GestureItem::event(event); } + + int badGestureEvents; }; const Qt::GestureType secondGesture = QGestureRecognizer ::registerRecognizer(new CustomGestureRecognizer); @@ -1614,6 +1621,7 @@ void tst_Gestures::autoCancelGestures2() event.serial = CustomGesture::SerialFinishedThreshold; scene.sendEvent(child, &event); QCOMPARE(parent->events.all.count(), 2); + QCOMPARE(parent->badGestureEvents, 0); } void tst_Gestures::graphicsViewParentPropagation() diff --git a/tests/auto/gui.pro b/tests/auto/gui.pro index 22c5e51..17f56f2 100644 --- a/tests/auto/gui.pro +++ b/tests/auto/gui.pro @@ -58,7 +58,7 @@ SUBDIRS=\ qfontdialog \ qfontmetrics \ qformlayout \ - qglyphs \ + qglyphrun \ qgraphicsanchorlayout \ qgraphicsanchorlayout1 \ qgraphicseffect \ @@ -142,7 +142,6 @@ SUBDIRS=\ qregion \ qscrollarea \ qscrollbar \ - qscroller \ qsharedpointer_and_qwidget \ qshortcut \ qsidebar \ diff --git a/tests/auto/lancelot/tst_lancelot.cpp b/tests/auto/lancelot/tst_lancelot.cpp index 9721665..2eb3f20 100644 --- a/tests/auto/lancelot/tst_lancelot.cpp +++ b/tests/auto/lancelot/tst_lancelot.cpp @@ -254,7 +254,8 @@ void tst_Lancelot::runTestSuite(GraphicsEngine engine, QImage::Format format) if (baseline.status == ImageItem::BaselineNotFound) { - proto.submitNewBaseline(rendered, 0); + if (!proto.submitNewBaseline(rendered, 0)) + QWARN("Failed to submit new baseline: " + proto.errorMessage().toLatin1()); QSKIP("Baseline not found; new baseline created.", SkipSingle); } diff --git a/tests/auto/modeltest/dynamictreemodel.cpp b/tests/auto/modeltest/dynamictreemodel.cpp index fa634b6..80708d4 100644 --- a/tests/auto/modeltest/dynamictreemodel.cpp +++ b/tests/auto/modeltest/dynamictreemodel.cpp @@ -44,6 +44,7 @@ #include <QtCore/QHash> #include <QtCore/QList> #include <QtCore/QTimer> +#include <QtCore/QDebug> DynamicTreeModel::DynamicTreeModel(QObject *parent) @@ -66,9 +67,11 @@ QModelIndex DynamicTreeModel::index(int row, int column, const QModelIndex &pare const qint64 grandParent = findParentId(parent.internalId()); if (grandParent >= 0) { QList<QList<qint64> > parentTable = m_childItems.value(grandParent); - Q_ASSERT(parent.column() < parentTable.size()); + if (parent.column() >= parentTable.size()) + qFatal("%s: parent.column() must be less than parentTable.size()", Q_FUNC_INFO); QList<qint64> parentSiblings = parentTable.at(parent.column()); - Q_ASSERT(parent.row() < parentSiblings.size()); + if (parent.row() >= parentSiblings.size()) + qFatal("%s: parent.row() must be less than parentSiblings.size()", Q_FUNC_INFO); } if (childIdColumns.size() == 0) @@ -189,7 +192,8 @@ QModelIndex ModelChangeCommand::findIndex(QList<int> rows) while (i.hasNext()) { parent = m_model->index(i.next(), col, parent); - Q_ASSERT(parent.isValid()); + if (!parent.isValid()) + qFatal("%s: parent must be valid", Q_FUNC_INFO); } return parent; } diff --git a/tests/auto/modeltest/modeltest.cpp b/tests/auto/modeltest/modeltest.cpp index 98d707c..ec1091a 100644 --- a/tests/auto/modeltest/modeltest.cpp +++ b/tests/auto/modeltest/modeltest.cpp @@ -45,8 +45,6 @@ #include "modeltest.h" #include <QtTest/QtTest> -#undef Q_ASSERT -#define Q_ASSERT QVERIFY Q_DECLARE_METATYPE ( QModelIndex ) @@ -55,7 +53,8 @@ Q_DECLARE_METATYPE ( QModelIndex ) */ ModelTest::ModelTest ( QAbstractItemModel *_model, QObject *parent ) : QObject ( parent ), model ( _model ), fetchingMore ( false ) { - Q_ASSERT ( model ); + if (!model) + qFatal("%s: model must not be null", Q_FUNC_INFO); connect ( model, SIGNAL ( columnsAboutToBeInserted ( const QModelIndex &, int, int ) ), this, SLOT ( runAllTests() ) ); @@ -118,15 +117,15 @@ void ModelTest::runAllTests() */ void ModelTest::nonDestructiveBasicTest() { - Q_ASSERT ( model->buddy ( QModelIndex() ) == QModelIndex() ); + QVERIFY( model->buddy ( QModelIndex() ) == QModelIndex() ); model->canFetchMore ( QModelIndex() ); - Q_ASSERT ( model->columnCount ( QModelIndex() ) >= 0 ); - Q_ASSERT ( model->data ( QModelIndex() ) == QVariant() ); + QVERIFY( model->columnCount ( QModelIndex() ) >= 0 ); + QVERIFY( model->data ( QModelIndex() ) == QVariant() ); fetchingMore = true; model->fetchMore ( QModelIndex() ); fetchingMore = false; Qt::ItemFlags flags = model->flags ( QModelIndex() ); - Q_ASSERT ( flags == Qt::ItemIsDropEnabled || flags == 0 ); + QVERIFY( flags == Qt::ItemIsDropEnabled || flags == 0 ); model->hasChildren ( QModelIndex() ); model->hasIndex ( 0, 0 ); model->headerData ( 0, Qt::Horizontal ); @@ -135,8 +134,8 @@ void ModelTest::nonDestructiveBasicTest() QVariant cache; model->match ( QModelIndex(), -1, cache ); model->mimeTypes(); - Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() ); - Q_ASSERT ( model->rowCount() >= 0 ); + QVERIFY( model->parent ( QModelIndex() ) == QModelIndex() ); + QVERIFY( model->rowCount() >= 0 ); QVariant variant; model->setData ( QModelIndex(), variant, -1 ); model->setHeaderData ( -1, Qt::Horizontal, QVariant() ); @@ -158,17 +157,17 @@ void ModelTest::rowCount() // check top row QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); int rows = model->rowCount ( topIndex ); - Q_ASSERT ( rows >= 0 ); + QVERIFY( rows >= 0 ); if ( rows > 0 ) - Q_ASSERT ( model->hasChildren ( topIndex ) == true ); + QVERIFY( model->hasChildren ( topIndex ) ); QModelIndex secondLevelIndex = model->index ( 0, 0, topIndex ); if ( secondLevelIndex.isValid() ) { // not the top level // check a row count where parent is valid rows = model->rowCount ( secondLevelIndex ); - Q_ASSERT ( rows >= 0 ); + QVERIFY( rows >= 0 ); if ( rows > 0 ) - Q_ASSERT ( model->hasChildren ( secondLevelIndex ) == true ); + QVERIFY( model->hasChildren ( secondLevelIndex ) ); } // The models rowCount() is tested more extensively in checkChildren(), @@ -182,12 +181,12 @@ void ModelTest::columnCount() { // check top row QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); - Q_ASSERT ( model->columnCount ( topIndex ) >= 0 ); + QVERIFY( model->columnCount ( topIndex ) >= 0 ); // check a column count where parent is valid QModelIndex childIndex = model->index ( 0, 0, topIndex ); if ( childIndex.isValid() ) - Q_ASSERT ( model->columnCount ( childIndex ) >= 0 ); + QVERIFY( model->columnCount ( childIndex ) >= 0 ); // columnCount() is tested more extensively in checkChildren(), // but this catches the big mistakes @@ -200,19 +199,19 @@ void ModelTest::hasIndex() { // qDebug() << "hi"; // Make sure that invalid values returns an invalid index - Q_ASSERT ( model->hasIndex ( -2, -2 ) == false ); - Q_ASSERT ( model->hasIndex ( -2, 0 ) == false ); - Q_ASSERT ( model->hasIndex ( 0, -2 ) == false ); + QVERIFY( !model->hasIndex ( -2, -2 ) ); + QVERIFY( !model->hasIndex ( -2, 0 ) ); + QVERIFY( !model->hasIndex ( 0, -2 ) ); int rows = model->rowCount(); int columns = model->columnCount(); // check out of bounds - Q_ASSERT ( model->hasIndex ( rows, columns ) == false ); - Q_ASSERT ( model->hasIndex ( rows + 1, columns + 1 ) == false ); + QVERIFY( !model->hasIndex ( rows, columns ) ); + QVERIFY( !model->hasIndex ( rows + 1, columns + 1 ) ); if ( rows > 0 ) - Q_ASSERT ( model->hasIndex ( 0, 0 ) == true ); + QVERIFY( model->hasIndex ( 0, 0 ) ); // hasIndex() is tested more extensively in checkChildren(), // but this catches the big mistakes @@ -225,9 +224,9 @@ void ModelTest::index() { // qDebug() << "i"; // Make sure that invalid values returns an invalid index - Q_ASSERT ( model->index ( -2, -2 ) == QModelIndex() ); - Q_ASSERT ( model->index ( -2, 0 ) == QModelIndex() ); - Q_ASSERT ( model->index ( 0, -2 ) == QModelIndex() ); + QVERIFY( model->index ( -2, -2 ) == QModelIndex() ); + QVERIFY( model->index ( -2, 0 ) == QModelIndex() ); + QVERIFY( model->index ( 0, -2 ) == QModelIndex() ); int rows = model->rowCount(); int columns = model->columnCount(); @@ -236,13 +235,13 @@ void ModelTest::index() return; // Catch off by one errors - Q_ASSERT ( model->index ( rows, columns ) == QModelIndex() ); - Q_ASSERT ( model->index ( 0, 0 ).isValid() == true ); + QVERIFY( model->index ( rows, columns ) == QModelIndex() ); + QVERIFY( model->index ( 0, 0 ).isValid() ); // Make sure that the same index is *always* returned QModelIndex a = model->index ( 0, 0 ); QModelIndex b = model->index ( 0, 0 ); - Q_ASSERT ( a == b ); + QVERIFY( a == b ); // index() is tested more extensively in checkChildren(), // but this catches the big mistakes @@ -256,7 +255,7 @@ void ModelTest::parent() // qDebug() << "p"; // Make sure the model wont crash and will return an invalid QModelIndex // when asked for the parent of an invalid index. - Q_ASSERT ( model->parent ( QModelIndex() ) == QModelIndex() ); + QVERIFY( model->parent ( QModelIndex() ) == QModelIndex() ); if ( model->rowCount() == 0 ) return; @@ -269,13 +268,13 @@ void ModelTest::parent() // Common error test #1, make sure that a top level index has a parent // that is a invalid QModelIndex. QModelIndex topIndex = model->index ( 0, 0, QModelIndex() ); - Q_ASSERT ( model->parent ( topIndex ) == QModelIndex() ); + QVERIFY( model->parent ( topIndex ) == QModelIndex() ); // Common error test #2, make sure that a second level index has a parent // that is the first level index. if ( model->rowCount ( topIndex ) > 0 ) { QModelIndex childIndex = model->index ( 0, 0, topIndex ); - Q_ASSERT ( model->parent ( childIndex ) == topIndex ); + QVERIFY( model->parent ( childIndex ) == topIndex ); } // Common error test #3, the second column should NOT have the same children @@ -285,7 +284,7 @@ void ModelTest::parent() if ( model->rowCount ( topIndex1 ) > 0 ) { QModelIndex childIndex = model->index ( 0, 0, topIndex ); QModelIndex childIndex1 = model->index ( 0, 0, topIndex1 ); - Q_ASSERT ( childIndex != childIndex1 ); + QVERIFY( childIndex != childIndex1 ); } // Full test, walk n levels deep through the model making sure that all @@ -325,47 +324,47 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) int columns = model->columnCount ( parent ); if ( rows > 0 ) - Q_ASSERT ( model->hasChildren ( parent ) ); + QVERIFY( model->hasChildren ( parent ) ); // Some further testing against rows(), columns(), and hasChildren() - Q_ASSERT ( rows >= 0 ); - Q_ASSERT ( columns >= 0 ); + QVERIFY( rows >= 0 ); + QVERIFY( columns >= 0 ); if ( rows > 0 ) - Q_ASSERT ( model->hasChildren ( parent ) == true ); + QVERIFY( model->hasChildren ( parent ) ); //qDebug() << "parent:" << model->data(parent).toString() << "rows:" << rows // << "columns:" << columns << "parent column:" << parent.column(); - Q_ASSERT ( model->hasIndex ( rows + 1, 0, parent ) == false ); + QVERIFY( !model->hasIndex ( rows + 1, 0, parent ) ); for ( int r = 0; r < rows; ++r ) { if ( model->canFetchMore ( parent ) ) { fetchingMore = true; model->fetchMore ( parent ); fetchingMore = false; } - Q_ASSERT ( model->hasIndex ( r, columns + 1, parent ) == false ); + QVERIFY( !model->hasIndex ( r, columns + 1, parent ) ); for ( int c = 0; c < columns; ++c ) { - Q_ASSERT ( model->hasIndex ( r, c, parent ) == true ); + QVERIFY( model->hasIndex ( r, c, parent ) ); QModelIndex index = model->index ( r, c, parent ); // rowCount() and columnCount() said that it existed... - Q_ASSERT ( index.isValid() == true ); + QVERIFY( index.isValid() ); // index() should always return the same index when called twice in a row QModelIndex modifiedIndex = model->index ( r, c, parent ); - Q_ASSERT ( index == modifiedIndex ); + QVERIFY( index == modifiedIndex ); // Make sure we get the same index if we request it twice in a row QModelIndex a = model->index ( r, c, parent ); QModelIndex b = model->index ( r, c, parent ); - Q_ASSERT ( a == b ); + QVERIFY( a == b ); // Some basic checking on the index that is returned - Q_ASSERT ( index.model() == model ); - Q_ASSERT ( index.row() == r ); - Q_ASSERT ( index.column() == c ); + QVERIFY( index.model() == model ); + QCOMPARE( index.row(), r ); + QCOMPARE( index.column(), c ); // While you can technically return a QVariant usually this is a sign - // of an bug in data() Disable if this really is ok in your model. -// Q_ASSERT ( model->data ( index, Qt::DisplayRole ).isValid() == true ); + // of a bug in data(). Disable if this really is ok in your model. +// QVERIFY( model->data ( index, Qt::DisplayRole ).isValid() ); // If the next test fails here is some somewhat useful debug you play with. @@ -380,8 +379,7 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) } // Check that we can get back our real parent. -// qDebug() << model->parent ( index ) << parent ; - Q_ASSERT ( model->parent ( index ) == parent ); + QCOMPARE( model->parent ( index ), parent ); // recursively go down the children if ( model->hasChildren ( index ) && currentDepth < 10 ) { @@ -391,7 +389,7 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) // make sure that after testing the children that the index doesn't change. QModelIndex newerIndex = model->index ( r, c, parent ); - Q_ASSERT ( index == newerIndex ); + QVERIFY( index == newerIndex ); } } } @@ -402,68 +400,68 @@ void ModelTest::checkChildren ( const QModelIndex &parent, int currentDepth ) void ModelTest::data() { // Invalid index should return an invalid qvariant - Q_ASSERT ( !model->data ( QModelIndex() ).isValid() ); + QVERIFY( !model->data ( QModelIndex() ).isValid() ); if ( model->rowCount() == 0 ) return; // A valid index should have a valid QVariant data - Q_ASSERT ( model->index ( 0, 0 ).isValid() ); + QVERIFY( model->index ( 0, 0 ).isValid() ); // shouldn't be able to set data on an invalid index - Q_ASSERT ( model->setData ( QModelIndex(), QLatin1String ( "foo" ), Qt::DisplayRole ) == false ); + QVERIFY( !model->setData ( QModelIndex(), QLatin1String ( "foo" ), Qt::DisplayRole ) ); // General Purpose roles that should return a QString QVariant variant = model->data ( model->index ( 0, 0 ), Qt::ToolTipRole ); if ( variant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QString> ( variant ) ); + QVERIFY( qVariantCanConvert<QString> ( variant ) ); } variant = model->data ( model->index ( 0, 0 ), Qt::StatusTipRole ); if ( variant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QString> ( variant ) ); + QVERIFY( qVariantCanConvert<QString> ( variant ) ); } variant = model->data ( model->index ( 0, 0 ), Qt::WhatsThisRole ); if ( variant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QString> ( variant ) ); + QVERIFY( qVariantCanConvert<QString> ( variant ) ); } // General Purpose roles that should return a QSize variant = model->data ( model->index ( 0, 0 ), Qt::SizeHintRole ); if ( variant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QSize> ( variant ) ); + QVERIFY( qVariantCanConvert<QSize> ( variant ) ); } // General Purpose roles that should return a QFont QVariant fontVariant = model->data ( model->index ( 0, 0 ), Qt::FontRole ); if ( fontVariant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QFont> ( fontVariant ) ); + QVERIFY( qVariantCanConvert<QFont> ( fontVariant ) ); } // Check that the alignment is one we know about QVariant textAlignmentVariant = model->data ( model->index ( 0, 0 ), Qt::TextAlignmentRole ); if ( textAlignmentVariant.isValid() ) { int alignment = textAlignmentVariant.toInt(); - Q_ASSERT ( alignment == ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) ); + QCOMPARE( alignment, ( alignment & ( Qt::AlignHorizontal_Mask | Qt::AlignVertical_Mask ) ) ); } // General Purpose roles that should return a QColor QVariant colorVariant = model->data ( model->index ( 0, 0 ), Qt::BackgroundColorRole ); if ( colorVariant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QColor> ( colorVariant ) ); + QVERIFY( qVariantCanConvert<QColor> ( colorVariant ) ); } colorVariant = model->data ( model->index ( 0, 0 ), Qt::TextColorRole ); if ( colorVariant.isValid() ) { - Q_ASSERT ( qVariantCanConvert<QColor> ( colorVariant ) ); + QVERIFY( qVariantCanConvert<QColor> ( colorVariant ) ); } // Check that the "check state" is one we know about. QVariant checkStateVariant = model->data ( model->index ( 0, 0 ), Qt::CheckStateRole ); if ( checkStateVariant.isValid() ) { int state = checkStateVariant.toInt(); - Q_ASSERT ( state == Qt::Unchecked || - state == Qt::PartiallyChecked || - state == Qt::Checked ); + QVERIFY( state == Qt::Unchecked || + state == Qt::PartiallyChecked || + state == Qt::Checked ); } } @@ -494,7 +492,7 @@ void ModelTest::rowsAboutToBeInserted ( const QModelIndex &parent, int start, in void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end ) { Changing c = insert.pop(); - Q_ASSERT ( c.parent == parent ); + QVERIFY( c.parent == parent ); // qDebug() << "rowsInserted" << "start=" << start << "end=" << end << "oldsize=" << c.oldSize // << "parent=" << model->data ( parent ).toString() << "current rowcount of parent=" << model->rowCount ( parent ); @@ -504,8 +502,8 @@ void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end ) // } // qDebug(); - Q_ASSERT ( c.oldSize + ( end - start + 1 ) == model->rowCount ( parent ) ); - Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); + QVERIFY( c.oldSize + ( end - start + 1 ) == model->rowCount ( parent ) ); + QVERIFY( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); if (c.next != model->data(model->index(end + 1, 0, c.parent))) { qDebug() << start << end; @@ -514,7 +512,7 @@ void ModelTest::rowsInserted ( const QModelIndex & parent, int start, int end ) qDebug() << c.next << model->data(model->index(end + 1, 0, c.parent)); } - Q_ASSERT ( c.next == model->data ( model->index ( end + 1, 0, c.parent ) ) ); + QVERIFY( c.next == model->data ( model->index ( end + 1, 0, c.parent ) ) ); } void ModelTest::layoutAboutToBeChanged() @@ -527,7 +525,7 @@ void ModelTest::layoutChanged() { for ( int i = 0; i < changing.count(); ++i ) { QPersistentModelIndex p = changing[i]; - Q_ASSERT ( p == model->index ( p.row(), p.column(), p.parent() ) ); + QVERIFY( p == model->index ( p.row(), p.column(), p.parent() ) ); } changing.clear(); } @@ -557,10 +555,10 @@ void ModelTest::rowsRemoved ( const QModelIndex & parent, int start, int end ) { qDebug() << "rr" << parent << start << end; Changing c = remove.pop(); - Q_ASSERT ( c.parent == parent ); - Q_ASSERT ( c.oldSize - ( end - start + 1 ) == model->rowCount ( parent ) ); - Q_ASSERT ( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); - Q_ASSERT ( c.next == model->data ( model->index ( start, 0, c.parent ) ) ); + QVERIFY( c.parent == parent ); + QVERIFY( c.oldSize - ( end - start + 1 ) == model->rowCount ( parent ) ); + QVERIFY( c.last == model->data ( model->index ( start - 1, 0, c.parent ) ) ); + QVERIFY( c.next == model->data ( model->index ( start, 0, c.parent ) ) ); } diff --git a/tests/auto/modeltest/tst_modeltest.cpp b/tests/auto/modeltest/tst_modeltest.cpp index a75fe5b..aedaffe 100644 --- a/tests/auto/modeltest/tst_modeltest.cpp +++ b/tests/auto/modeltest/tst_modeltest.cpp @@ -201,8 +201,10 @@ class ObservingObject : public QObject Q_OBJECT public: ObservingObject(AccessibleProxyModel *proxy, QObject *parent = 0) - : QObject(parent), - m_proxy(proxy) + : QObject(parent) + , m_proxy(proxy) + , storePersistentFailureCount(0) + , checkPersistentFailureCount(0) { connect(m_proxy, SIGNAL(layoutAboutToBeChanged()), SLOT(storePersistent())); connect(m_proxy, SIGNAL(layoutChanged()), SLOT(checkPersistent())); @@ -215,8 +217,14 @@ public slots: for (int row = 0; row < m_proxy->rowCount(parent); ++row) { QModelIndex proxyIndex = m_proxy->index(row, 0, parent); QModelIndex sourceIndex = m_proxy->mapToSource(proxyIndex); - Q_ASSERT(proxyIndex.isValid()); - Q_ASSERT(sourceIndex.isValid()); + if (!proxyIndex.isValid()) { + qWarning("%s: Invalid proxy index", Q_FUNC_INFO); + ++storePersistentFailureCount; + } + if (!sourceIndex.isValid()) { + qWarning("%s: invalid source index", Q_FUNC_INFO); + ++storePersistentFailureCount; + } m_persistentSourceIndexes.append(sourceIndex); m_persistentProxyIndexes.append(proxyIndex); if (m_proxy->hasChildren(proxyIndex)) @@ -226,12 +234,24 @@ public slots: void storePersistent() { - foreach(const QModelIndex &idx, m_persistentProxyIndexes) - Q_ASSERT(idx.isValid()); // This is called from layoutAboutToBeChanged. Persistent indexes should be valid - - Q_ASSERT(m_proxy->persistent().isEmpty()); + // This method is called from layoutAboutToBeChanged. Persistent indexes should be valid + foreach(const QModelIndex &idx, m_persistentProxyIndexes) + if (!idx.isValid()) { + qWarning("%s: persistentProxyIndexes contains invalid index", Q_FUNC_INFO); + ++storePersistentFailureCount; + } + + if (!m_proxy->persistent().isEmpty()) { + qWarning("%s: proxy should have no persistent indexes when storePersistent called", + Q_FUNC_INFO); + ++storePersistentFailureCount; + } storePersistent(QModelIndex()); - Q_ASSERT(!m_proxy->persistent().isEmpty()); + if (m_proxy->persistent().isEmpty()) { + qWarning("%s: proxy should have persistent index after storePersistent called", + Q_FUNC_INFO); + ++storePersistentFailureCount; + } } void checkPersistent() @@ -243,7 +263,10 @@ public slots: for (int row = 0; row < m_persistentProxyIndexes.size(); ++row) { QModelIndex updatedProxy = m_persistentProxyIndexes.at(row); QModelIndex updatedSource = m_persistentSourceIndexes.at(row); - QCOMPARE(m_proxy->mapToSource(updatedProxy), updatedSource); + if (m_proxy->mapToSource(updatedProxy) != updatedSource) { + qWarning("%s: check failed at row %d", Q_FUNC_INFO, row); + ++checkPersistentFailureCount; + } } m_persistentSourceIndexes.clear(); m_persistentProxyIndexes.clear(); @@ -253,6 +276,9 @@ private: AccessibleProxyModel *m_proxy; QList<QPersistentModelIndex> m_persistentSourceIndexes; QList<QPersistentModelIndex> m_persistentProxyIndexes; +public: + int storePersistentFailureCount; + int checkPersistentFailureCount; }; void tst_ModelTest::moveSourceItems() @@ -280,6 +306,9 @@ void tst_ModelTest::moveSourceItems() moveCommand->setDestAncestors(QList<int>() << 1); moveCommand->setDestRow(0); moveCommand->doCommand(); + + QCOMPARE(observer.storePersistentFailureCount, 0); + QCOMPARE(observer.checkPersistentFailureCount, 0); } void tst_ModelTest::testResetThroughProxy() @@ -302,6 +331,9 @@ void tst_ModelTest::testResetThroughProxy() ModelResetCommand *resetCommand = new ModelResetCommand(model, this); resetCommand->setNumCols(0); resetCommand->doCommand(); + + QCOMPARE(observer.storePersistentFailureCount, 0); + QCOMPARE(observer.checkPersistentFailureCount, 0); } diff --git a/tests/auto/other.pro b/tests/auto/other.pro index 8819879..655d666 100644 --- a/tests/auto/other.pro +++ b/tests/auto/other.pro @@ -3,10 +3,8 @@ TEMPLATE=subdirs SUBDIRS=\ -# exceptionsafety_objects \ shouldn't enable it # baselineexample \ Just an example demonstrating qbaselinetest usage lancelot \ - qaccessibility \ qalgorithms \ qcombobox \ qcssparser \ @@ -37,6 +35,8 @@ SUBDIRS=\ windowsmobile \ nativeimagehandleprovider +contains(QT_CONFIG, accessibility):SUBDIRS += qaccessibility + contains(QT_CONFIG, OdfWriter):SUBDIRS += qzip qtextodfwriter mac: { SUBDIRS += macgui \ @@ -56,6 +56,8 @@ symbian { qs60mainapplication } +!win32-msvc*:!wince*:SUBDIRS += exceptionsafety_objects + # Following tests depends on private API !contains(QT_CONFIG, private_tests): SUBDIRS -= \ qcssparser \ diff --git a/tests/auto/q3combobox/tst_q3combobox.cpp b/tests/auto/q3combobox/tst_q3combobox.cpp index 17bd861..825acb2 100644 --- a/tests/auto/q3combobox/tst_q3combobox.cpp +++ b/tests/auto/q3combobox/tst_q3combobox.cpp @@ -1004,6 +1004,10 @@ void tst_Q3ComboBox::wheelEvent() void tst_Q3ComboBox::task231724_clear() { +#ifdef Q_WS_MACX + return; // On Mac, we don't use a ListBox for the popup +#endif + Q3ComboBox box; for ( int i = 0; i <50; i++ ) { diff --git a/tests/auto/q3dns/tst_q3dns.cpp b/tests/auto/q3dns/tst_q3dns.cpp index b97a604..7d633ef 100644 --- a/tests/auto/q3dns/tst_q3dns.cpp +++ b/tests/auto/q3dns/tst_q3dns.cpp @@ -144,7 +144,7 @@ void tst_Q3Dns::literals() QCOMPARE((int) ip6literal1.addresses().count(), 0); Q3Dns ip6literal2("::1", Q3Dns::Aaaa); - QCOMPARE(ip6literal2.addresses().first().toString(), QString("0:0:0:0:0:0:0:1")); + QCOMPARE(ip6literal2.addresses().first().toString(), QString("::1")); QCOMPARE((int) ip6literal2.addresses().count(), 1); } diff --git a/tests/auto/q3listview/tst_q3listview.cpp b/tests/auto/q3listview/tst_q3listview.cpp index 601d74f..c1b3950 100644 --- a/tests/auto/q3listview/tst_q3listview.cpp +++ b/tests/auto/q3listview/tst_q3listview.cpp @@ -678,7 +678,7 @@ void tst_Q3ListView::selections_mouseClick() for (i = 0; i < items.count(); ++i) { Q3ListViewItem *item = items.at(i); - Q_ASSERT(item); + QVERIFY(item); if ( item->isSelected() ) { QVERIFY( selectedItems.contains( i ) ); } else { diff --git a/tests/auto/q3progressbar/tst_q3progressbar.cpp b/tests/auto/q3progressbar/tst_q3progressbar.cpp index 745e2d5..3a0c3e2 100644 --- a/tests/auto/q3progressbar/tst_q3progressbar.cpp +++ b/tests/auto/q3progressbar/tst_q3progressbar.cpp @@ -45,6 +45,7 @@ #include <qapplication.h> #include <qdebug.h> #include <q3progressbar.h> +#include "../../shared/util.h" //TESTED_CLASS= //TESTED_FILES= @@ -106,7 +107,7 @@ void tst_Q3ProgressBar::setProgress() { MyCustomProgressBar * m_progressBar = new MyCustomProgressBar(); m_progressBar->show(); - QApplication::processEvents(); + QTest::qWaitForWindowShown(m_progressBar); //case with total steps = 0 m_progressBar->setTotalSteps(0); @@ -114,10 +115,9 @@ void tst_Q3ProgressBar::setProgress() m_progressBar->paintNumber = 0; m_progressBar->setProgress(m_progressBar->progress() + 1); QCOMPARE(oldValue + 1,m_progressBar->progress()); - QApplication::processEvents(); // It might be > 1 because it is animated. - QVERIFY(m_progressBar->paintNumber >= 1); + QTRY_VERIFY(m_progressBar->paintNumber >= 1); qDebug() << "Animation test: paintNumber =" << m_progressBar->paintNumber; //standard case @@ -125,10 +125,9 @@ void tst_Q3ProgressBar::setProgress() m_progressBar->setProgress(0); m_progressBar->paintNumber = 0; m_progressBar->setProgress(m_progressBar->progress() + 1); - QApplication::processEvents(); // It might be > 1 because other events might cause painting. - QVERIFY(m_progressBar->paintNumber >= 1); + QTRY_VERIFY(m_progressBar->paintNumber >= 1); qDebug() << "Standard test: paintNumber =" << m_progressBar->paintNumber; } diff --git a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp index 6f3722d..838fd22 100644 --- a/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp +++ b/tests/auto/q3sqlcursor/tst_q3sqlcursor.cpp @@ -251,7 +251,7 @@ void tst_Q3SqlCursor::copyConstructor() } QSqlRecord* rec = cur2.primeUpdate(); - Q_ASSERT( rec ); + QVERIFY( rec ); QCOMPARE( (int)rec->count(), 4 ); int i = 0; @@ -398,7 +398,7 @@ void tst_Q3SqlCursor::batchInsert() int i = 0; for ( ; i < 100; ++i ) { QSqlRecord* irec = cur.primeInsert(); - Q_ASSERT( irec ); + QVERIFY( irec ); irec->setValue( "id", i ); irec->setValue( "t_varchar", "blah" ); irec->setValue( "t_char", "blah" ); @@ -412,7 +412,7 @@ void tst_Q3SqlCursor::batchInsert() for ( ; i < 200; ++i ) { QSqlRecord* irec = cur.primeInsert(); - Q_ASSERT( irec ); + QVERIFY( irec ); irec->setValue( "id", i ); irec->setValue( "t_varchar", "blah" ); irec->setValue( "t_char", "blah" ); @@ -699,7 +699,7 @@ void tst_Q3SqlCursor::updateNoPK() Q3SqlCursor cur(qTableName("qtestPK", __FILE__), true, db); QSqlRecord* rec = cur.primeInsert(); - Q_ASSERT(rec); + QVERIFY(rec); rec->setNull(0); rec->setNull(1); rec->setNull(2); @@ -724,7 +724,7 @@ void tst_Q3SqlCursor::updateNoPK() } rec = cur.primeUpdate(); - Q_ASSERT(rec); + QVERIFY(rec); rec->setValue(0, 1); rec->setNull(1); rec->setNull(2); diff --git a/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp b/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp index 1178169..e77b7bb 100644 --- a/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp +++ b/tests/auto/qabstractfileengine/tst_qabstractfileengine.cpp @@ -83,8 +83,12 @@ public: bool open(QIODevice::OpenMode openMode) { - Q_ASSERT(!openForRead_); - Q_ASSERT(!openForWrite_); + if (openForRead_ || openForWrite_) { + qWarning("%s: file is already open for %s", + Q_FUNC_INFO, + (openForRead_ ? "reading" : "writing")); + return false; + } openFile_ = resolveFile(openMode & QIODevice::WriteOnly); if (!openFile_) @@ -132,13 +136,19 @@ public: qint64 pos() const { - Q_ASSERT(openForRead_ || openForWrite_); + if (!openForRead_ && !openForWrite_) { + qWarning("%s: file is not open", Q_FUNC_INFO); + return -1; + } return position_; } bool seek(qint64 pos) { - Q_ASSERT(openForRead_ || openForWrite_); + if (!openForRead_ && !openForWrite_) { + qWarning("%s: file is not open", Q_FUNC_INFO); + return false; + } if (pos >= 0) { position_ = pos; @@ -150,7 +160,11 @@ public: bool flush() { - Q_ASSERT(openForRead_ || openForWrite_); + if (!openForRead_ && !openForWrite_) { + qWarning("%s: file is not open", Q_FUNC_INFO); + return false; + } + return true; } @@ -346,10 +360,10 @@ public: void setFileName(const QString &file) { - Q_ASSERT(!openForRead_); - Q_ASSERT(!openForWrite_); - - fileName_ = file; + if (openForRead_ || openForWrite_) + qWarning("%s: Can't set file name while file is open", Q_FUNC_INFO); + else + fileName_ = file; } // typedef QAbstractFileEngineIterator Iterator; @@ -368,9 +382,16 @@ public: qint64 read(char *data, qint64 maxLen) { - Q_ASSERT(openForRead_); + if (!openForRead_) { + qWarning("%s: file must be open for reading", Q_FUNC_INFO); + return -1; + } + + if (openFile_.isNull()) { + qWarning("%s: file must not be null", Q_FUNC_INFO); + return -1; + } - Q_ASSERT(!openFile_.isNull()); QMutexLocker lock(&openFile_->mutex); qint64 readSize = qMin(openFile_->content.size() - position_, maxLen); if (readSize < 0) @@ -384,12 +405,19 @@ public: qint64 write(const char *data, qint64 length) { - Q_ASSERT(openForWrite_); + if (!openForWrite_) { + qWarning("%s: file must be open for writing", Q_FUNC_INFO); + return -1; + } + + if (openFile_.isNull()) { + qWarning("%s: file must not be null", Q_FUNC_INFO); + return -1; + } if (length < 0) return -1; - Q_ASSERT(!openFile_.isNull()); QMutexLocker lock(&openFile_->mutex); if (openFile_->content.size() == position_) openFile_->content.append(data, length); @@ -434,7 +462,8 @@ protected: QSharedPointer<File> resolveFile(bool create) const { if (openForRead_ || openForWrite_) { - Q_ASSERT(openFile_); + if (!openFile_) + qWarning("%s: file should not be null", Q_FUNC_INFO); return openFile_; } diff --git a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp index 76e6711..e2842c1 100644 --- a/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp +++ b/tests/auto/qabstractnetworkcache/tst_qabstractnetworkcache.cpp @@ -261,14 +261,14 @@ void tst_QAbstractNetworkCache::cacheControl_data() QTest::newRow("200-2") << QNetworkRequest::AlwaysNetwork << "httpcachetest_cachecontrol.cgi?no-cache" << AlwaysFalse; QTest::newRow("200-3") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?no-cache" << false; - QTest::newRow("200-4") << QNetworkRequest::AlwaysCache << "httpcachetest_cachecontrol.cgi?no-cache" << false;//AlwaysTrue; + QTest::newRow("200-4") << QNetworkRequest::AlwaysCache << "httpcachetest_cachecontrol.cgi?no-cache" << false; QTest::newRow("200-5") << QNetworkRequest::PreferCache << "httpcachetest_cachecontrol.cgi?no-cache" << false; QTest::newRow("304-0") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?max-age=1000" << true; QTest::newRow("304-1") << QNetworkRequest::AlwaysNetwork << "httpcachetest_cachecontrol.cgi?max-age=1000, must-revalidate" << AlwaysFalse; QTest::newRow("304-2") << QNetworkRequest::PreferNetwork << "httpcachetest_cachecontrol.cgi?max-age=1000, must-revalidate" << true; - QTest::newRow("304-3") << QNetworkRequest::AlwaysCache << "httpcachetest_cachecontrol.cgi?max-age=1000, must-revalidate" << AlwaysTrue; + QTest::newRow("304-3") << QNetworkRequest::AlwaysCache << "httpcachetest_cachecontrol.cgi?max-age=1000, must-revalidate" << false; QTest::newRow("304-4") << QNetworkRequest::PreferCache << "httpcachetest_cachecontrol.cgi?max-age=1000, must-revalidate" << true; // see QTBUG-7060 diff --git a/tests/auto/qabstractxmlnodemodel/LoadingModel.cpp b/tests/auto/qabstractxmlnodemodel/LoadingModel.cpp index fbc28d6..bb8538c 100644 --- a/tests/auto/qabstractxmlnodemodel/LoadingModel.cpp +++ b/tests/auto/qabstractxmlnodemodel/LoadingModel.cpp @@ -39,7 +39,6 @@ ** ****************************************************************************/ - #include <QFile> #include <QStack> @@ -54,7 +53,6 @@ LoadingModel::LoadingModel(const Node::Vector &content, const QXmlNamePool &np) : QSimpleXmlNodeModel(np) , m_nodes(content) { - Q_ASSERT(!content.isEmpty()); /* foreach(const Node *n, content) qDebug() << "this:" << n @@ -79,20 +77,21 @@ const LoadingModel::Node *LoadingModel::toInternal(const QXmlNodeModelIndex &ni) QXmlNodeModelIndex LoadingModel::createIndex(const Node *const internal) const { - Q_ASSERT_X(internal, Q_FUNC_INFO, - "We shouldn't construct from null pointers."); + if (!internal) + qFatal("%s: cannot construct a model index from a null pointer", Q_FUNC_INFO); return QAbstractXmlNodeModel::createIndex(const_cast<Node *>(internal)); } QUrl LoadingModel::documentUri(const QXmlNodeModelIndex &) const { - Q_ASSERT(false); + qFatal("%s: This method should not be called during the test", Q_FUNC_INFO); return QUrl(); } QXmlNodeModelIndex::NodeKind LoadingModel::kind(const QXmlNodeModelIndex &ni) const { - Q_ASSERT(!ni.isNull()); + if (ni.isNull()) + qFatal("%s: node model index should not be null", Q_FUNC_INFO); return toInternal(ni)->kind; } @@ -100,8 +99,10 @@ QXmlNodeModelIndex::DocumentOrder LoadingModel::compareOrder(const QXmlNodeModel { const Node *const in1 = toInternal(n1); const Node *const in2 = toInternal(n2); - Q_ASSERT(m_nodes.indexOf(in1) != -1); - Q_ASSERT(m_nodes.indexOf(in2) != -1); + if (m_nodes.indexOf(in1) == -1) + qFatal("%s: node n1 is not in internal node list", Q_FUNC_INFO); + if (m_nodes.indexOf(in2) == -1) + qFatal("%s: node n2 is not in internal node list", Q_FUNC_INFO); if(in1 == in2) return QXmlNodeModelIndex::Is; @@ -113,7 +114,10 @@ QXmlNodeModelIndex::DocumentOrder LoadingModel::compareOrder(const QXmlNodeModel QXmlNodeModelIndex LoadingModel::root(const QXmlNodeModelIndex &) const { - Q_ASSERT(kind(createIndex(m_nodes.first())) == QXmlNodeModelIndex::Document); + if (kind(createIndex(m_nodes.first())) != QXmlNodeModelIndex::Document) { + qWarning("%s: first node must be a Document node", Q_FUNC_INFO); + return QXmlNodeModelIndex(); + } return createIndex(m_nodes.first()); } @@ -126,8 +130,11 @@ QVariant LoadingModel::typedValue(const QXmlNodeModelIndex &ni) const { const Node *const internal = toInternal(ni); - Q_ASSERT(internal->kind == QXmlNodeModelIndex::Attribute - || internal->kind == QXmlNodeModelIndex::Element); + if (internal->kind != QXmlNodeModelIndex::Attribute + && internal->kind != QXmlNodeModelIndex::Element) { + qWarning("%s: node must be an attribute or element", Q_FUNC_INFO); + return QVariant(); + } return internal->value; } @@ -167,10 +174,10 @@ QXmlNodeModelIndex LoadingModel::nextFromSimpleAxis(QAbstractXmlNodeModel::Simpl return internal->precedingSibling ? createIndex(internal->precedingSibling) : QXmlNodeModelIndex(); case NextSibling: return internal->followingSibling ? createIndex(internal->followingSibling) : QXmlNodeModelIndex(); + default: + qWarning("%s: unknown axis enum value %d", Q_FUNC_INFO, static_cast<int>(axis)); + return QXmlNodeModelIndex(); } - - Q_ASSERT(false); - return QXmlNodeModelIndex(); } QVector<QXmlNodeModelIndex> LoadingModel::attributes(const QXmlNodeModelIndex &ni) const @@ -326,18 +333,16 @@ void Loader::load() break; } case QXmlStreamReader::DTD: - /* Fallthrough. */ + qFatal("%s: QXmlStreamReader::DTD token is not supported", Q_FUNC_INFO); + break; case QXmlStreamReader::EntityReference: - { - Q_ASSERT_X(false, Q_FUNC_INFO, - "We don't support this."); - /* Fallthrough. */ - } + qFatal("%s: QXmlStreamReader::EntityReference token is not supported", Q_FUNC_INFO); + break; case QXmlStreamReader::NoToken: /* Fallthrough. */ case QXmlStreamReader::Invalid: { - qWarning(qPrintable(reader.errorString())); + qWarning("%s", qPrintable(reader.errorString())); m_result.clear(); return; } @@ -346,7 +351,7 @@ void Loader::load() if(reader.hasError()) { - qWarning(qPrintable(reader.errorString())); + qWarning("%s", qPrintable(reader.errorString())); m_result.clear(); } } @@ -355,6 +360,11 @@ QAbstractXmlNodeModel::Ptr LoadingModel::create(const QXmlNamePool &np) { Loader loader(np); loader.load(); + if (loader.m_result.isEmpty()) { + qWarning("%s: attempt to create model with no content", Q_FUNC_INFO); + return Ptr(0); + } + return Ptr(new LoadingModel(loader.m_result, np)); } #endif //QTEST_XMLPATTERNS diff --git a/tests/auto/qaccessibility/qaccessibility.pro b/tests/auto/qaccessibility/qaccessibility.pro index a4f606c..71d6f95 100644 --- a/tests/auto/qaccessibility/qaccessibility.pro +++ b/tests/auto/qaccessibility/qaccessibility.pro @@ -1,4 +1,5 @@ load(qttest_p4) +requires(contains(QT_CONFIG,accessibility)) SOURCES += tst_qaccessibility.cpp unix:!mac:LIBS+=-lm @@ -8,4 +9,4 @@ wince*: { accessneeded.files = $$QT_BUILD_TREE\\plugins\\accessible\\*.dll accessneeded.path = accessible DEPLOYMENT += accessneeded -}
\ No newline at end of file +} diff --git a/tests/auto/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index 7ff1a08..f4cd93f 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -326,69 +326,16 @@ QString eventName(const int ev) } } -static QString stateNames(int state) -{ - QString stateString; - if (state == 0x00000000) stateString += " Normal"; - if (state & 0x00000001) stateString += " Unavailable"; - if (state & 0x00000002) stateString += " Selected"; - if (state & 0x00000004) stateString += " Focused"; - if (state & 0x00000008) stateString += " Pressed"; - if (state & 0x00000010) stateString += " Checked"; - if (state & 0x00000020) stateString += " Mixed"; - if (state & 0x00000040) stateString += " ReadOnly"; - if (state & 0x00000080) stateString += " HotTracked"; - if (state & 0x00000100) stateString += " DefaultButton"; - if (state & 0x00000200) stateString += " Expanded"; - if (state & 0x00000400) stateString += " Collapsed"; - if (state & 0x00000800) stateString += " Busy"; - if (state & 0x00001000) stateString += " Floating"; - if (state & 0x00002000) stateString += " Marqueed"; - if (state & 0x00004000) stateString += " Animated"; - if (state & 0x00008000) stateString += " Invisible"; - if (state & 0x00010000) stateString += " Offscreen"; - if (state & 0x00020000) stateString += " Sizeable"; - if (state & 0x00040000) stateString += " Moveable"; - if (state & 0x00080000) stateString += " SelfVoicing"; - if (state & 0x00100000) stateString += " Focusable"; - if (state & 0x00200000) stateString += " Selectable"; - if (state & 0x00400000) stateString += " Linked"; - if (state & 0x00800000) stateString += " Traversed"; - if (state & 0x01000000) stateString += " MultiSelectable"; - if (state & 0x02000000) stateString += " ExtSelectable"; - if (state & 0x04000000) stateString += " AlertLow"; - if (state & 0x08000000) stateString += " AlertMedium"; - if (state & 0x10000000) stateString += " AlertHigh"; - if (state & 0x20000000) stateString += " Protected"; - if (state & 0x3fffffff) stateString += " Valid"; - - if (stateString.isEmpty()) - stateString = "Unknown state " + QString::number(state); - - return stateString; -} - QAccessible::State state(QWidget * const widget) { QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget); - Q_ASSERT(iface); - QAccessible::State state = iface->state(0); + if (!iface) + qWarning() << "Cannot get QAccessibleInterface for widget"; + QAccessible::State state = (iface ? iface->state(0) : static_cast<QAccessible::State>(0)); delete iface; return state; } -void printState(QWidget * const widget) -{ - qDebug() << "State for" << widget->metaObject()->className() << stateNames(state(widget)); -} - -void printState(QAccessibleInterface * const iface, const int child = 0) -{ - qDebug() << "State for" << iface->object()->metaObject()->className() << "child" << child - << iface->text(QAccessible::Name, child) << stateNames(iface->state(child)); -} - - class QtTestAccessibleWidget: public QWidget { Q_OBJECT @@ -403,7 +350,6 @@ public: } }; -#ifdef QTEST_ACCESSIBILITY class QtTestAccessibleWidgetIface: public QAccessibleWidget { public: @@ -421,7 +367,6 @@ public: return 0; } }; -#endif tst_QAccessibility::tst_QAccessibility() { @@ -433,17 +378,13 @@ tst_QAccessibility::~tst_QAccessibility() void tst_QAccessibility::initTestCase() { -#ifdef QTEST_ACCESSIBILITY QTestAccessibility::initialize(); QAccessible::installFactory(QtTestAccessibleWidgetIface::ifaceFactory); -#endif } void tst_QAccessibility::cleanupTestCase() { -#ifdef QTEST_ACCESSIBILITY QTestAccessibility::cleanup(); -#endif } void tst_QAccessibility::init() @@ -453,7 +394,6 @@ void tst_QAccessibility::init() void tst_QAccessibility::cleanup() { -#ifdef QTEST_ACCESSIBILITY const EventList list = QTestAccessibility::events(); if (!list.isEmpty()) { qWarning("%d accessibility event(s) were not handled in testfunction '%s':", list.count(), @@ -463,14 +403,10 @@ void tst_QAccessibility::cleanup() eventName(list.at(i).event).toAscii().constData(), list.at(i).event, list.at(i).child); } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::eventTest() { -#ifdef QTEST_ACCESSIBILITY QPushButton* button = new QPushButton(0); button->setObjectName(QString("Olaf")); @@ -491,14 +427,10 @@ void tst_QAccessibility::eventTest() QVERIFY_EVENT(button, 0, QAccessible::ObjectHide); delete button; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::customWidget() { -#ifdef QTEST_ACCESSIBILITY QtTestAccessibleWidget* widget = new QtTestAccessibleWidget(0, "Heinz"); QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget); @@ -510,14 +442,10 @@ void tst_QAccessibility::customWidget() delete iface; delete widget; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::deletedWidget() { -#ifdef QTEST_ACCESSIBILITY QtTestAccessibleWidget *widget = new QtTestAccessibleWidget(0, "Ralf"); QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(widget); QVERIFY(iface != 0); @@ -528,9 +456,6 @@ void tst_QAccessibility::deletedWidget() widget = 0; QVERIFY(!iface->isValid()); delete iface; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } QWidget *tst_QAccessibility::createGUI() @@ -539,7 +464,6 @@ QWidget *tst_QAccessibility::createGUI() qWarning( "Should never get here without Qt3Support"); return 0; #else -# ifdef QTEST_ACCESSIBILITY QWidget *toplevel = new QWidget(0, Qt::X11BypassWindowManagerHint); QGridLayout *grid = new QGridLayout(toplevel, 2, 2); @@ -611,10 +535,6 @@ QWidget *tst_QAccessibility::createGUI() radioAM->setFocus(); QTestAccessibility::clearEvents(); return toplevel; -# else - Q_ASSERT(0); // this function cannot be called without accessibility support - return 0; -# endif #endif // !QT3_SUPPORT } @@ -623,7 +543,6 @@ void tst_QAccessibility::childAt() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); QAccessibleInterface *acc_toplevel = QAccessible::queryAccessibleInterface(toplevel); QVERIFY(acc_toplevel); @@ -655,9 +574,6 @@ void tst_QAccessibility::childAt() delete acc_toplevel; delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -666,7 +582,6 @@ void tst_QAccessibility::childCount() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); QObject *topLeft = toplevel->child("topLeft"); QObject *topRight = toplevel->child("topRight"); @@ -699,9 +614,6 @@ void tst_QAccessibility::childCount() delete acc_bottomRight; delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -710,7 +622,6 @@ void tst_QAccessibility::relationTo() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); toplevel->resize(400,300); QObject *topLeft = toplevel->child("topLeft"); @@ -916,15 +827,11 @@ void tst_QAccessibility::relationTo() delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } void tst_QAccessibility::navigateGeometric() { -#ifdef QTEST_ACCESSIBILITY { static const int skip = 20; //speed the test up significantly static const double step = Q_PI / 180; @@ -1020,14 +927,10 @@ void tst_QAccessibility::navigateGeometric() delete w; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::navigateSlider() { -#ifdef QTEST_ACCESSIBILITY { QSlider *slider = new QSlider(0); slider->setObjectName(QString("Slidy")); @@ -1054,14 +957,10 @@ void tst_QAccessibility::navigateSlider() delete slider; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::navigateCovered() { -#ifdef QTEST_ACCESSIBILITY { QWidget *w = new QWidget(0); w->setObjectName(QString("Harry")); @@ -1164,14 +1063,10 @@ void tst_QAccessibility::navigateCovered() delete w; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::navigateHierarchy() { -#ifdef QTEST_ACCESSIBILITY { QWidget *w = new QWidget(0); w->setObjectName(QString("Hans")); @@ -1267,9 +1162,6 @@ void tst_QAccessibility::navigateHierarchy() delete w; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } #define QSETCOMPARE(thetypename, elements, otherelements) \ @@ -1280,7 +1172,6 @@ void tst_QAccessibility::navigateControllers() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY { Q3VBox vbox; QSlider slider(&vbox); @@ -1363,9 +1254,6 @@ void tst_QAccessibility::navigateControllers() delete acc_slider; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -1374,7 +1262,6 @@ void tst_QAccessibility::navigateLabels() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY { Q3VBox vbox; Q3HBox hbox(&vbox); @@ -1496,9 +1383,6 @@ void tst_QAccessibility::navigateLabels() delete acc_lineedit3; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -1550,7 +1434,6 @@ static QWidget *createWidgets() void tst_QAccessibility::accessibleName() { -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createWidgets(); toplevel->show(); #if defined(Q_WS_X11) @@ -1575,9 +1458,6 @@ void tst_QAccessibility::accessibleName() delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::text() @@ -1585,7 +1465,6 @@ void tst_QAccessibility::text() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); toplevel->show(); #if defined(Q_WS_X11) @@ -1681,10 +1560,6 @@ void tst_QAccessibility::text() delete toplevel; QTestAccessibility::clearEvents(); - -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // !QT3_SUPPORT } @@ -1693,7 +1568,6 @@ void tst_QAccessibility::setText() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QWidget *toplevel = createGUI(); toplevel->show(); QObject *bottomLeft = toplevel->findChild<QObject *>("bottomLeft"); @@ -1717,16 +1591,11 @@ void tst_QAccessibility::setText() delete acc_lineedit; delete toplevel; QTestAccessibility::clearEvents(); - -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif //QT3_SUPPORT } void tst_QAccessibility::hideShowTest() { -#ifdef QTEST_ACCESSIBILITY QWidget * const window = new QWidget(); QWidget * const child = new QWidget(window); @@ -1753,14 +1622,10 @@ void tst_QAccessibility::hideShowTest() delete window; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::userActionCount() { -#ifdef QTEST_ACCESSIBILITY QWidget widget; QAccessibleInterface *test = QAccessible::queryAccessibleInterface(&widget); @@ -1790,18 +1655,14 @@ void tst_QAccessibility::userActionCount() QCOMPARE(test->userActionCount(1), 0); QCOMPARE(test->userActionCount(-1), 0); delete test; test = 0; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::actionText() { -#ifdef QTEST_ACCESSIBILITY - QWidget widget; - widget.show(); + QWidget *widget = new QWidget; + widget->show(); - QAccessibleInterface *test = QAccessible::queryAccessibleInterface(&widget); + QAccessibleInterface *test = QAccessible::queryAccessibleInterface(widget); QVERIFY(test); QVERIFY(test->isValid()); @@ -1813,39 +1674,29 @@ void tst_QAccessibility::actionText() QCOMPARE(test->actionText(QAccessible::DefaultAction, QAccessible::Name, 0), QString("SetFocus")); QCOMPARE(test->actionText(QAccessible::SetFocus, QAccessible::Name, 0), QString("SetFocus")); - delete test; test = 0; + delete test; + delete widget; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif + QTestAccessibility::clearEvents(); } void tst_QAccessibility::doAction() { -#ifdef QTEST_ACCESSIBILITY QSKIP("TODO: Implement me", SkipAll); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::applicationTest() { -#ifdef QTEST_ACCESSIBILITY QLatin1String name = QLatin1String("My Name"); qApp->setApplicationName(name); QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(qApp); QCOMPARE(interface->text(QAccessible::Name, 0), name); QCOMPARE(interface->role(0), QAccessible::Application); delete interface; -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::mainWindowTest() { -#ifdef QTEST_ACCESSIBILITY QMainWindow mw; mw.resize(300, 200); mw.show(); // triggers layout @@ -1858,10 +1709,6 @@ void tst_QAccessibility::mainWindowTest() QCOMPARE(interface->text(QAccessible::Name, 0), name); QCOMPARE(interface->role(0), QAccessible::Window); delete interface; - -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } class CounterButton : public QPushButton { @@ -1881,7 +1728,6 @@ public Q_SLOTS: void tst_QAccessibility::buttonTest() { -#ifdef QTEST_ACCESSIBILITY QWidget window; window.setLayout(new QVBoxLayout); @@ -2070,10 +1916,6 @@ void tst_QAccessibility::buttonTest() // test->release(); QTestAccessibility::clearEvents(); - -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::sliderTest() @@ -2081,20 +1923,19 @@ void tst_QAccessibility::sliderTest() #if !defined(QT3_SUPPORT) QSKIP("This test needs Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY QAccessibleInterface *test = 0; - Q3VBox vbox; - QLabel labelHorizontal("Horizontal", &vbox); - QSlider sliderHorizontal(Qt::Horizontal, &vbox); - labelHorizontal.setBuddy(&sliderHorizontal); + Q3VBox *vbox = new Q3VBox; + QLabel *labelHorizontal = new QLabel("Horizontal", vbox); + QSlider *sliderHorizontal = new QSlider(Qt::Horizontal, vbox); + labelHorizontal->setBuddy(sliderHorizontal); - QLabel labelVertical("Vertical", &vbox); - QSlider sliderVertical(Qt::Vertical, &vbox); - labelVertical.setBuddy(&sliderVertical); - vbox.show(); + QLabel *labelVertical = new QLabel("Vertical", vbox); + QSlider *sliderVertical = new QSlider(Qt::Vertical, vbox); + labelVertical->setBuddy(sliderVertical); + vbox->show(); // test horizontal slider - test = QAccessible::queryAccessibleInterface(&sliderHorizontal); + test = QAccessible::queryAccessibleInterface(sliderHorizontal); QVERIFY(test); QCOMPARE(test->childCount(), 3); QCOMPARE(test->role(0), QAccessible::Slider); @@ -2102,15 +1943,15 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->role(2), QAccessible::Indicator); QCOMPARE(test->role(3), QAccessible::PushButton); - QCOMPARE(test->text(QAccessible::Name, 0), labelHorizontal.text()); + QCOMPARE(test->text(QAccessible::Name, 0), labelHorizontal->text()); QCOMPARE(test->text(QAccessible::Name, 1), QSlider::tr("Page left")); QCOMPARE(test->text(QAccessible::Name, 2), QSlider::tr("Position")); QCOMPARE(test->text(QAccessible::Name, 3), QSlider::tr("Page right")); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.value())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->value())); QCOMPARE(test->text(QAccessible::Value, 1), QString()); - QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderHorizontal.value())); + QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderHorizontal->value())); QCOMPARE(test->text(QAccessible::Value, 3), QString()); -// Skip acton tests. +// Skip action tests. #if 0 QCOMPARE(test->defaultAction(0), QAccessible::SetFocus); QCOMPARE(test->defaultAction(1), QAccessible::Press); @@ -2122,26 +1963,26 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->actionText(QAccessible::Decrease, QAccessible::Name, 2), QSlider::tr("Decrease")); QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 3), QSlider::tr("Press")); QVERIFY(test->doAction(QAccessible::Press, 3)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 3)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 1)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 1)); QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); QVERIFY(test->doAction(QAccessible::Increase, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->lineStep())); QVERIFY(test->doAction(QAccessible::Increase, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderHorizontal->lineStep())); QVERIFY(test->doAction(QAccessible::Decrease, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderHorizontal->lineStep())); QVERIFY(test->doAction(QAccessible::Decrease, 2)); QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); #endif delete test; // test vertical slider - test = QAccessible::queryAccessibleInterface(&sliderVertical); + test = QAccessible::queryAccessibleInterface(sliderVertical); QVERIFY(test); QCOMPARE(test->childCount(), 3); QCOMPARE(test->role(0), QAccessible::Slider); @@ -2149,15 +1990,15 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->role(2), QAccessible::Indicator); QCOMPARE(test->role(3), QAccessible::PushButton); - QCOMPARE(test->text(QAccessible::Name, 0), labelVertical.text()); + QCOMPARE(test->text(QAccessible::Name, 0), labelVertical->text()); QCOMPARE(test->text(QAccessible::Name, 1), QSlider::tr("Page up")); QCOMPARE(test->text(QAccessible::Name, 2), QSlider::tr("Position")); QCOMPARE(test->text(QAccessible::Name, 3), QSlider::tr("Page down")); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.value())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->value())); QCOMPARE(test->text(QAccessible::Value, 1), QString()); - QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderVertical.value())); + QCOMPARE(test->text(QAccessible::Value, 2), QString::number(sliderVertical->value())); QCOMPARE(test->text(QAccessible::Value, 3), QString()); -// Skip acton tests. +// Skip action tests. #if 0 QCOMPARE(test->defaultAction(0), QAccessible::SetFocus); QCOMPARE(test->defaultAction(1), QAccessible::Press); @@ -2169,23 +2010,28 @@ void tst_QAccessibility::sliderTest() QCOMPARE(test->actionText(QAccessible::Decrease, QAccessible::Name, 2), QSlider::tr("Decrease")); QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 3), QSlider::tr("Press")); QVERIFY(test->doAction(QAccessible::Press, 3)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 3)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 1)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.pageStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->pageStep())); QVERIFY(test->doAction(QAccessible::Press, 1)); QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); QVERIFY(test->doAction(QAccessible::Increase, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->lineStep())); QVERIFY(test->doAction(QAccessible::Increase, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(2*sliderVertical->lineStep())); QVERIFY(test->doAction(QAccessible::Decrease, 2)); - QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical.lineStep())); + QCOMPARE(test->text(QAccessible::Value, 0), QString::number(sliderVertical->lineStep())); QVERIFY(test->doAction(QAccessible::Decrease, 2)); QCOMPARE(test->text(QAccessible::Value, 0), QString::number(0)); #endif delete test; + delete sliderHorizontal; + delete sliderVertical; + delete labelHorizontal; + delete labelVertical; + delete vbox; // Test that when we hide() a slider, the PageLeft, Indicator, and PageRight also gets the // Invisible state bit set. @@ -2268,17 +2114,12 @@ void tst_QAccessibility::sliderTest() delete sliderInterface; } - QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif //!QT3_SUPPORT } void tst_QAccessibility::scrollBarTest() { -#ifdef QTEST_ACCESSIBILITY // Test that when we hide() a slider, the PageLeft, Indicator, and PageRight also gets the // Invisible state bit set. enum SubControls { LineUp = 1, @@ -2286,7 +2127,7 @@ void tst_QAccessibility::scrollBarTest() Position = 3, PageDown = 4, LineDown = 5 - }; + }; QScrollBar *scrollBar = new QScrollBar(); QAccessibleInterface * const scrollBarInterface = QAccessible::queryAccessibleInterface(scrollBar); @@ -2368,15 +2209,10 @@ void tst_QAccessibility::scrollBarTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif - } void tst_QAccessibility::tabTest() { -#ifdef QTEST_ACCESSIBILITY QTabBar *tabBar = new QTabBar(); tabBar->show(); @@ -2412,14 +2248,10 @@ void tst_QAccessibility::tabTest() delete tabBar; delete interface; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::tabWidgetTest() { -#ifdef QTEST_ACCESSIBILITY QTabWidget *tabWidget = new QTabWidget(); tabWidget->show(); @@ -2505,14 +2337,10 @@ void tst_QAccessibility::tabWidgetTest() delete interface; delete tabWidget; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::menuTest() { -#ifdef QTEST_ACCESSIBILITY { QMainWindow mw; mw.resize(300, 200); @@ -2758,14 +2586,10 @@ void tst_QAccessibility::menuTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); -#endif } void tst_QAccessibility::spinBoxTest() { -#ifdef QTEST_ACCESSIBILITY QSpinBox * const spinBox = new QSpinBox(); spinBox->show(); @@ -2792,14 +2616,10 @@ void tst_QAccessibility::spinBoxTest() QVERIFY(events.contains(expectedEvent)); delete spinBox; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::doubleSpinBoxTest() { -#ifdef QTEST_ACCESSIBILITY QDoubleSpinBox *doubleSpinBox = new QDoubleSpinBox; doubleSpinBox->show(); @@ -2819,14 +2639,10 @@ void tst_QAccessibility::doubleSpinBoxTest() delete doubleSpinBox; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::textEditTest() { -#ifdef QTEST_ACCESSIBILITY { QTextEdit edit; QString text = "hello world\nhow are you today?\n"; @@ -2846,14 +2662,10 @@ void tst_QAccessibility::textEditTest() QCOMPARE(iface->textInterface()->characterRect(6, QAccessible2::RelativeToParent).size(), QSize(fm.width("w"), fm.height())); } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::textBrowserTest() { -#ifdef QTEST_ACCESSIBILITY { QTextBrowser textBrowser; QString text = QLatin1String("Hello world\nhow are you today?\n"); @@ -2870,14 +2682,10 @@ void tst_QAccessibility::textBrowserTest() QCOMPARE(interface->text(QAccessible::Value, 6), QString()); } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::listViewTest() { -#if 1 //def QTEST_ACCESSIBILITY { QListView listView; QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&listView); @@ -2943,15 +2751,11 @@ void tst_QAccessibility::listViewTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::mdiAreaTest() { -#ifdef QTEST_ACCESSIBILITY { QMdiArea mdiArea; mdiArea.resize(400,300); @@ -3000,14 +2804,10 @@ void tst_QAccessibility::mdiAreaTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::mdiSubWindowTest() { -#ifdef QTEST_ACCESSIBILITY { QMdiArea mdiArea; mdiArea.show(); @@ -3130,14 +2930,10 @@ void tst_QAccessibility::mdiSubWindowTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::lineEditTest() { -#ifdef QTEST_ACCESSIBILITY QLineEdit *le = new QLineEdit; QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(le); QVERIFY(iface); @@ -3195,14 +2991,10 @@ void tst_QAccessibility::lineEditTest() delete le2; delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::workspaceTest() { -#ifdef QTEST_ACCESSIBILITY { QWorkspace workspace; workspace.resize(400,300); @@ -3256,14 +3048,10 @@ void tst_QAccessibility::workspaceTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::dialogButtonBoxTest() { -#ifdef QTEST_ACCESSIBILITY { QDialogButtonBox box(QDialogButtonBox::Reset | QDialogButtonBox::Help | @@ -3376,14 +3164,10 @@ void tst_QAccessibility::dialogButtonBoxTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::dialTest() { -#ifdef QTEST_ACCESSIBILITY { QDial dial; dial.setValue(20); @@ -3425,28 +3209,20 @@ void tst_QAccessibility::dialTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::rubberBandTest() { -#ifdef QTEST_ACCESSIBILITY QRubberBand rubberBand(QRubberBand::Rectangle); QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&rubberBand); QVERIFY(interface); QCOMPARE(interface->role(0), QAccessible::Border); delete interface; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::abstractScrollAreaTest() { -#ifdef QTEST_ACCESSIBILITY { QAbstractScrollArea abstractScrollArea; @@ -3604,14 +3380,10 @@ void tst_QAccessibility::abstractScrollAreaTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::scrollAreaTest() { -#ifdef QTEST_ACCESSIBILITY { QScrollArea scrollArea; scrollArea.show(); @@ -3625,14 +3397,10 @@ void tst_QAccessibility::scrollAreaTest() delete interface; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::tableWidgetTest() { -#ifdef QTEST_ACCESSIBILITY { QWidget *topLevel = new QWidget; QTableWidget *w = new QTableWidget(8,4,topLevel); @@ -3672,10 +3440,6 @@ void tst_QAccessibility::tableWidgetTest() delete topLevel; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif - } class QtTestTableModel: public QAbstractTableModel @@ -3758,7 +3522,6 @@ public: void tst_QAccessibility::tableViewTest() { -#ifdef QTEST_ACCESSIBILITY { QtTestTableModel *model = new QtTestTableModel(3, 4); QTableView *w = new QTableView(); @@ -3838,15 +3601,11 @@ void tst_QAccessibility::tableViewTest() delete model; } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::calendarWidgetTest() { #ifndef QT_NO_CALENDARWIDGET -#ifdef QTEST_ACCESSIBILITY { QCalendarWidget calendarWidget; @@ -3939,17 +3698,12 @@ void tst_QAccessibility::calendarWidgetTest() } QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // QT_NO_CALENDARWIDGET } void tst_QAccessibility::dockWidgetTest() { #ifndef QT_NO_DOCKWIDGET - -#ifdef QTEST_ACCESSIBILITY // Set up a proper main window with two dock widgets QMainWindow *mw = new QMainWindow(); QFrame *central = new QFrame(mw); @@ -4017,19 +3771,14 @@ void tst_QAccessibility::dockWidgetTest() delete dock2; delete mw; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif // QT_NO_DOCKWIDGET } void tst_QAccessibility::pushButtonTest() { #if !defined(QT3_SUPPORT) - qWarning( "Should never get here without Qt3Support"); - return ; + QSKIP( "Should never get here without Qt3Support", SkipAll); #else -#ifdef QTEST_ACCESSIBILITY // Set up a proper main window with two dock widgets QWidget *toplevel = createGUI(); QObject *topRight = toplevel->findChild<QObject *>("topRight"); @@ -4063,15 +3812,11 @@ void tst_QAccessibility::pushButtonTest() delete accToplevel; delete toplevel; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif #endif //QT3_SUPPORT } void tst_QAccessibility::comboBoxTest() { -#ifdef QTEST_ACCESSIBILITY #if defined(Q_OS_WINCE) if (!IsValidCEPlatform()) { QSKIP("Test skipped on Windows Mobile test hardware", SkipAll); @@ -4109,15 +3854,10 @@ void tst_QAccessibility::comboBoxTest() delete w; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif - } void tst_QAccessibility::treeWidgetTest() { -#ifdef QTEST_ACCESSIBILITY QWidget *w = new QWidget; QTreeWidget *tree = new QTreeWidget(w); QHBoxLayout *l = new QHBoxLayout(w); @@ -4175,14 +3915,10 @@ void tst_QAccessibility::treeWidgetTest() delete w; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::labelTest() { -#ifdef QTEST_ACCESSIBILITY QString text = "Hello World"; QLabel *label = new QLabel(text); label->show(); @@ -4221,14 +3957,10 @@ void tst_QAccessibility::labelTest() delete acc_label; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs accessibility support.", SkipAll); -#endif } void tst_QAccessibility::accelerators() { -#ifdef QTEST_ACCESSIBILITY QWidget *window = new QWidget; QHBoxLayout *lay = new QHBoxLayout(window); QLabel *label = new QLabel(tr("&Line edit"), window); @@ -4252,6 +3984,10 @@ void tst_QAccessibility::accelerators() QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("A")); label->setText(tr("Q &&A")); QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QString()); + +#if !defined(QT_NO_DEBUG) && !defined(Q_WS_MAC) + QTest::ignoreMessage(QtWarningMsg, "QKeySequence::mnemonic: \"Q &A&B\" contains multiple occurrences of '&'"); +#endif label->setText(tr("Q &A&B")); QCOMPARE(accLineEdit->text(QAccessible::Accelerator, 0), QKeySequence(Qt::ALT).toString(QKeySequence::NativeText) + QLatin1String("A")); @@ -4261,9 +3997,6 @@ void tst_QAccessibility::accelerators() QTest::qWait(100); delete window; QTestAccessibility::clearEvents(); -#else - QSKIP("Test needs Qt >= 0x040000 and accessibility support.", SkipAll); -#endif } diff --git a/tests/auto/qalgorithms/tst_qalgorithms.cpp b/tests/auto/qalgorithms/tst_qalgorithms.cpp index 8dd7cbc..f0ae08c 100644 --- a/tests/auto/qalgorithms/tst_qalgorithms.cpp +++ b/tests/auto/qalgorithms/tst_qalgorithms.cpp @@ -241,7 +241,8 @@ QList<ResultSet> testAlgorithm(Algorithm &algorithm, QStringList dataSetTypes, foreach(QString dataSetType, dataSetTypes) { QVector<DataType> container = generateData<DataType>(dataSetType, size); results.append(testRun(container, algorithm, time)); - Q_ASSERT(isSorted(container)); + if (!isSorted(container)) + qWarning("%s: container is not sorted after test", Q_FUNC_INFO); } return results; } diff --git a/tests/auto/qatomicint/tst_qatomicint.cpp b/tests/auto/qatomicint/tst_qatomicint.cpp index 717187a..5ccb997 100644 --- a/tests/auto/qatomicint/tst_qatomicint.cpp +++ b/tests/auto/qatomicint/tst_qatomicint.cpp @@ -116,8 +116,7 @@ tst_QAtomicInt::~tst_QAtomicInt() void tst_QAtomicInt::warningFreeHelper() { - Q_ASSERT(false); - // The code below is bogus, and shouldn't be run. We're looking for warnings, only. + qFatal("This code is bogus, and shouldn't be run. We're looking for compiler warnings only."); QBasicAtomicInt i = Q_BASIC_ATOMIC_INITIALIZER(0); diff --git a/tests/auto/qatomicpointer/tst_qatomicpointer.cpp b/tests/auto/qatomicpointer/tst_qatomicpointer.cpp index af8fabc..05f8294 100644 --- a/tests/auto/qatomicpointer/tst_qatomicpointer.cpp +++ b/tests/auto/qatomicpointer/tst_qatomicpointer.cpp @@ -98,8 +98,7 @@ struct WFHC void tst_QAtomicPointer::warningFreeHelper() { - Q_ASSERT(false); - // The code below is bogus, and shouldn't be run. We're looking for warnings, only. + qFatal("This code is bogus, and shouldn't be run. We're looking for compiler warnings only."); QBasicAtomicPointer<WFHC> p = Q_BASIC_ATOMIC_INITIALIZER(0); diff --git a/tests/auto/qbuffer/tst_qbuffer.cpp b/tests/auto/qbuffer/tst_qbuffer.cpp index 3e3cc73..5d6b84f 100644 --- a/tests/auto/qbuffer/tst_qbuffer.cpp +++ b/tests/auto/qbuffer/tst_qbuffer.cpp @@ -309,8 +309,7 @@ void tst_QBuffer::seekTest() // (see Task 184730) { char c; - const int offset = 1; - Q_ASSERT(offset > 0); // any positive integer will do + const int offset = 1; // any positive integer will do const qint64 pos = buf.size() + offset; QVERIFY(buf.seek(pos)); QCOMPARE(buf.pos(), pos); diff --git a/tests/auto/qchar/tst_qchar.cpp b/tests/auto/qchar/tst_qchar.cpp index 45dd7eb..911a30c 100644 --- a/tests/auto/qchar/tst_qchar.cpp +++ b/tests/auto/qchar/tst_qchar.cpp @@ -548,14 +548,14 @@ void tst_QChar::normalization_data() QList<QByteArray> l = line.split(';'); - Q_ASSERT(l.size() == 5); + QCOMPARE(l.size(), 5); QStringList columns; for (int i = 0; i < 5; ++i) { columns.append(QString()); QList<QByteArray> c = l.at(i).split(' '); - Q_ASSERT(!c.isEmpty()); + QVERIFY(!c.isEmpty()); for (int j = 0; j < c.size(); ++j) { bool ok; diff --git a/tests/auto/qcolor/tst_qcolor.cpp b/tests/auto/qcolor/tst_qcolor.cpp index d42c26c..b02537e 100644 --- a/tests/auto/qcolor/tst_qcolor.cpp +++ b/tests/auto/qcolor/tst_qcolor.cpp @@ -1506,7 +1506,6 @@ void tst_QColor::setallowX11ColorNames() for (int i = 0; i < x11RgbTblSize; ++i) { QString colorName = QLatin1String(x11RgbTbl[i].name); QColor color; - QTest::ignoreMessage(QtWarningMsg, QString("QColor::setNamedColor: Unknown color name '%1'").arg(colorName).toLatin1()); color.setNamedColor(colorName); QVERIFY(!color.isValid()); } @@ -1528,7 +1527,6 @@ void tst_QColor::setallowX11ColorNames() for (int i = 0; i < x11RgbTblSize; ++i) { QString colorName = QLatin1String(x11RgbTbl[i].name); QColor color; - QTest::ignoreMessage(QtWarningMsg, QString("QColor::setNamedColor: Unknown color name '%1'").arg(colorName).toLatin1()); color.setNamedColor(colorName); QVERIFY(!color.isValid()); } diff --git a/tests/auto/qcompleter/tst_qcompleter.cpp b/tests/auto/qcompleter/tst_qcompleter.cpp index 932c19e..b0d40d0 100644 --- a/tests/auto/qcompleter/tst_qcompleter.cpp +++ b/tests/auto/qcompleter/tst_qcompleter.cpp @@ -277,7 +277,9 @@ retry: case 'L': row = completer->completionCount() - 1; break; case 'F': row = 0; break; default: - Q_ASSERT(false); + QFAIL(qPrintable(QString( + "Problem with 'step' value in test data: %1 (only P, N, L and F are allowed)." + ).arg(step[i]))); } completer->setCurrentRow(row); } @@ -1248,9 +1250,7 @@ public: void tst_QCompleter::task189564_omitNonSelectableItems() { const QString prefix("a"); - Q_ASSERT(!prefix.isEmpty()); const int n = 5; - Q_ASSERT(n > 0); QStringList strings; for (int i = 0; i < n; ++i) @@ -1278,10 +1278,11 @@ public: { setEditable(true); setInsertPolicy(NoInsert); - Q_ASSERT(completer()); - completer()->setCompletionMode(QCompleter::PopupCompletion); - completer()->setCompletionRole(Qt::DisplayRole); - connect(lineEdit(), SIGNAL(editingFinished()), SLOT(setCompletionPrefix())); + if (completer()) { + completer()->setCompletionMode(QCompleter::PopupCompletion); + completer()->setCompletionRole(Qt::DisplayRole); + connect(lineEdit(), SIGNAL(editingFinished()), SLOT(setCompletionPrefix())); + } } private slots: void setCompletionPrefix() { completer()->setCompletionPrefix(lineEdit()->text()); } @@ -1290,6 +1291,7 @@ private slots: void tst_QCompleter::task246056_setCompletionPrefix() { task246056_ComboBox *comboBox = new task246056_ComboBox; + QVERIFY(comboBox->completer()); comboBox->addItem(""); comboBox->addItem("a1"); comboBox->addItem("a2"); diff --git a/tests/auto/qcomplextext/tst_qcomplextext.cpp b/tests/auto/qcomplextext/tst_qcomplextext.cpp index 3d8e290..ae63bac 100644 --- a/tests/auto/qcomplextext/tst_qcomplextext.cpp +++ b/tests/auto/qcomplextext/tst_qcomplextext.cpp @@ -71,6 +71,10 @@ private slots: void bidiReorderString(); void bidiCursor_qtbug2795(); void bidiCursor_PDF(); + void bidiCursorMovement_data(); + void bidiCursorMovement(); + void bidiCursorLogicalMovement_data(); + void bidiCursorLogicalMovement(); }; tst_QComplexText::tst_QComplexText() @@ -185,6 +189,90 @@ void tst_QComplexText::bidiCursor_qtbug2795() QVERIFY(x1 == x2); } +void tst_QComplexText::bidiCursorMovement_data() +{ + QTest::addColumn<QString>("logical"); + QTest::addColumn<int>("basicDir"); + + const LV *data = logical_visual; + while ( data->name ) { + //next we fill it with data + QTest::newRow( data->name ) + << QString::fromUtf8( data->logical ) + << (int) data->basicDir; + data++; + } +} + +void tst_QComplexText::bidiCursorMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + + QTextLayout layout(logical); + + QTextOption option = layout.textOption(); + option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); + layout.setTextOption(option); + layout.setCursorMoveStyle(Qt::VisualMoveStyle); + bool moved; + int oldPos, newPos = 0; + qreal x, newX; + + layout.beginLayout(); + QTextLine line = layout.createLine(); + layout.endLayout(); + + newX = line.cursorToX(0); + do { + oldPos = newPos; + x = newX; + newX = line.cursorToX(oldPos); + if (basicDir == QChar::DirL) { + QVERIFY(newX >= x); + newPos = layout.rightCursorPosition(oldPos); + } else + { + QVERIFY(newX <= x); + newPos = layout.leftCursorPosition(oldPos); + } + moved = (oldPos != newPos); + } while (moved); +} + +void tst_QComplexText::bidiCursorLogicalMovement_data() +{ + bidiCursorMovement_data(); +} + +void tst_QComplexText::bidiCursorLogicalMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + + QTextLayout layout(logical); + + QTextOption option = layout.textOption(); + option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); + layout.setTextOption(option); + bool moved; + int oldPos, newPos = 0; + + do { + oldPos = newPos; + newPos = layout.nextCursorPosition(oldPos); + QVERIFY(newPos >= oldPos); + moved = (oldPos != newPos); + } while (moved); + + do { + oldPos = newPos; + newPos = layout.previousCursorPosition(oldPos); + QVERIFY(newPos <= oldPos); + moved = (oldPos != newPos); + } while (moved); +} + void tst_QComplexText::bidiCursor_PDF() { QString str = QString::fromUtf8("\342\200\252hello\342\200\254"); diff --git a/tests/auto/qcopchannel/testSend/main.cpp b/tests/auto/qcopchannel/testSend/main.cpp index 91628e5..a56883b 100644 --- a/tests/auto/qcopchannel/testSend/main.cpp +++ b/tests/auto/qcopchannel/testSend/main.cpp @@ -49,7 +49,11 @@ int main(int argc, char** argv) #ifdef Q_WS_QWS QApplication app(argc, argv); QStringList args = app.arguments(); - Q_ASSERT(args.count() == 3 || args.count() == 4); + if (args.count() != 3 && args.count() != 4) { + fprintf(stdout,qPrintable(QString("Usage: %1 channel message [data]").arg(args.at(0)))); + fflush(stdout); + return 1; + } QString channelName = args.at(1); QString msg = args.at(2); QByteArray data; diff --git a/tests/auto/qdatetime/tst_qdatetime.cpp b/tests/auto/qdatetime/tst_qdatetime.cpp index f8836a6..d612911 100644 --- a/tests/auto/qdatetime/tst_qdatetime.cpp +++ b/tests/auto/qdatetime/tst_qdatetime.cpp @@ -85,6 +85,8 @@ private slots: void setTime_t(); void setMSecsSinceEpoch_data(); void setMSecsSinceEpoch(); + void toString_isoDate_data(); + void toString_isoDate(); void toString_enumformat(); void toString_strformat_data(); void toString_strformat(); @@ -506,6 +508,36 @@ void tst_QDateTime::setMSecsSinceEpoch() QCOMPARE(dt, reference.addMSecs(msecs)); } +void tst_QDateTime::toString_isoDate_data() +{ + QTest::addColumn<QDateTime>("dt"); + QTest::addColumn<QString>("formatted"); + + QTest::newRow("localtime") + << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34)) + << QString("1978-11-09T13:28:34"); + QTest::newRow("UTC") + << QDateTime(QDate(1978, 11, 9), QTime(13, 28, 34), Qt::UTC) + << QString("1978-11-09T13:28:34Z"); + QDateTime dt(QDate(1978, 11, 9), QTime(13, 28, 34)); + dt.setUtcOffset(19800); + QTest::newRow("positive OffsetFromUTC") + << dt + << QString("1978-11-09T13:28:34+05:30"); + dt.setUtcOffset(-7200); + QTest::newRow("negative OffsetFromUTC") + << dt + << QString("1978-11-09T13:28:34-02:00"); +} + +void tst_QDateTime::toString_isoDate() +{ + QFETCH(QDateTime, dt); + QFETCH(QString, formatted); + + QCOMPARE(dt.toString(Qt::ISODate), formatted); +} + void tst_QDateTime::toString_enumformat() { QDateTime dt1(QDate(1995, 5, 20), QTime(12, 34, 56)); diff --git a/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp index c8c3b90..f5dbea4 100644 --- a/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp +++ b/tests/auto/qdatetimeedit/tst_qdatetimeedit.cpp @@ -275,6 +275,8 @@ private slots: void focusNextPrevChild(); void taskQTBUG_12384_timeSpecShowTimeOnly(); + + void deleteCalendarWidget(); private: EditorDateEdit* testWidget; @@ -2699,17 +2701,10 @@ void tst_QDateTimeEdit::task98554() QCOMPARE(testWidget->time(), QTime(0, 0, 10, 0)); } -static QList<int> makeList(int val1, int val2 = -1, int val3 = -1, int val4 = -1, int val5 = -1, int val6 = -1, int val7 = -1) +static QList<int> makeList(int val1, int val2, int val3) { QList<int> ret; - Q_ASSERT(val1 >= 0); - ret << val1; - if (val2 < 0) {return ret;} else {ret << val2;} - if (val3 < 0) {return ret;} else {ret << val3;} - if (val4 < 0) {return ret;} else {ret << val4;} - if (val5 < 0) {return ret;} else {ret << val5;} - if (val6 < 0) {return ret;} else {ret << val6;} - if (val7 >= 0) {ret << val2;} + ret << val1 << val2 << val3; return ret; } @@ -2751,7 +2746,7 @@ void tst_QDateTimeEdit::setCurrentSection() QFETCH(QList<int>, setCurrentSections); QFETCH(QList<int>, expectedCursorPositions); - Q_ASSERT(setCurrentSections.size() == expectedCursorPositions.size()); + QCOMPARE(setCurrentSections.size(), expectedCursorPositions.size()); testWidget->setDisplayFormat(format); testWidget->setDateTime(dateTime); #ifdef Q_WS_MAC @@ -3438,5 +3433,26 @@ void tst_QDateTimeEdit::taskQTBUG_12384_timeSpecShowTimeOnly() QCOMPARE(edit.time(), time.time()); } +void tst_QDateTimeEdit::deleteCalendarWidget() +{ + { + // setup + QCalendarWidget *cw = 0; + QDateEdit edit; + QVERIFY(!edit.calendarWidget()); + edit.setCalendarPopup(true); + QVERIFY(edit.calendarWidget()); + edit.calendarWidget()->setObjectName("cw1");; + + // delete + cw = edit.calendarWidget(); + delete cw; + + // it should create a new widget + QVERIFY(edit.calendarWidget()); + QVERIFY(edit.calendarWidget()->objectName() != "cw1"); + } +} + QTEST_MAIN(tst_QDateTimeEdit) #include "tst_qdatetimeedit.moc" diff --git a/tests/auto/qdbusthreading/tst_qdbusthreading.cpp b/tests/auto/qdbusthreading/tst_qdbusthreading.cpp index bfb806b..142b6c2 100644 --- a/tests/auto/qdbusthreading/tst_qdbusthreading.cpp +++ b/tests/auto/qdbusthreading/tst_qdbusthreading.cpp @@ -592,7 +592,7 @@ void tst_QDBusThreading::callbackInAnotherAuxThread() // wait for the event loop sem1.release(); sem2.acquire(); - Q_ASSERT(loop); + QVERIFY(loop); // create the second thread new Thread; diff --git a/tests/auto/qdirmodel/tst_qdirmodel.cpp b/tests/auto/qdirmodel/tst_qdirmodel.cpp index 38a6b8a..a6985a4 100644 --- a/tests/auto/qdirmodel/tst_qdirmodel.cpp +++ b/tests/auto/qdirmodel/tst_qdirmodel.cpp @@ -641,10 +641,10 @@ void tst_QDirModel::filter() QDirModel model; model.setNameFilters(QStringList() << "*.nada"); QModelIndex index = model.index(SRCDIR "test"); - Q_ASSERT(model.rowCount(index) == 0); + QCOMPARE(model.rowCount(index), 0); QModelIndex index2 = model.index(SRCDIR "test/file01.tst"); - Q_ASSERT(!index2.isValid()); - Q_ASSERT(model.rowCount(index) == 0); + QVERIFY(!index2.isValid()); + QCOMPARE(model.rowCount(index), 0); } void tst_QDirModel::task244669_remove() diff --git a/tests/auto/qdom/tst_qdom.cpp b/tests/auto/qdom/tst_qdom.cpp index 18aa84a..f3b3e00 100644 --- a/tests/auto/qdom/tst_qdom.cpp +++ b/tests/auto/qdom/tst_qdom.cpp @@ -137,7 +137,6 @@ private slots: private: static QDomDocument generateRequest(); - static QDomDocument doc(const QString &title, const QByteArray &ba); static int hasAttributesHelper( const QDomNode& node ); static bool compareDocuments( const QDomDocument &doc1, const QDomDocument &doc2 ); static bool compareNodes( const QDomNode &node1, const QDomNode &node2, bool deep ); @@ -1591,14 +1590,6 @@ void tst_QDom::reportDuplicateAttributes() const QVERIFY2(!isSuccess, "Duplicate attributes are well-formedness errors, and should be reported as such."); } -QDomDocument tst_QDom::doc(const QString &title, const QByteArray &ba) -{ - QDomDocument doc(title); - const bool ret = doc.setContent(ba, true); - Q_ASSERT(ret); - return doc; -} - void tst_QDom::namespacedAttributes() const { static const char *const xml = @@ -1611,8 +1602,13 @@ void tst_QDom::namespacedAttributes() const " <Title displayLabel='Title' >>>> SIMPLE BASIC OP - SEND - DUT AS SINK</Title>\n" "</xan:td>\n"; - QDomDocument one = doc("document", xml); - QDomDocument two = doc("document2", one.toByteArray(2)); + QDomDocument one("document"); + QString error; + bool docParsed = one.setContent(QByteArray(xml), true, &error); + QVERIFY2(docParsed, qPrintable(error)); + QDomDocument two("document2"); + docParsed = two.setContent(one.toByteArray(2), true, &error); + QVERIFY2(docParsed, qPrintable(error)); QVERIFY(isDeepEqual(one, two)); } diff --git a/tests/auto/qfile/largefile/tst_largefile.cpp b/tests/auto/qfile/largefile/tst_largefile.cpp index a9ad017..8070ad2 100644 --- a/tests/auto/qfile/largefile/tst_largefile.cpp +++ b/tests/auto/qfile/largefile/tst_largefile.cpp @@ -160,13 +160,10 @@ static inline void appendRaw(QByteArray &array, T data) */ static inline void topUpWith(QByteArray &array, QByteArray filler, int size) { - Q_ASSERT(filler.size() > 0); - for (int i = (size - array.size()) / filler.size(); i > 0; --i) array.append(filler); if (array.size() < size) { - Q_ASSERT(size - array.size() < filler.size()); array.append(filler.left(size - array.size())); } } @@ -206,15 +203,12 @@ static inline QByteArray generateDataBlock(int blockSize, QString text, qint64 u QByteArray filler("0123456789"); block.append(filler.right(10 - block.size() % 10)); - topUpWith(block, filler, blockSize - 2 * sizeof(qint64)); + topUpWith(block, filler, blockSize - 3 * sizeof(qint64)); appendRaw(block, counter); appendRaw(block, userBits); appendRaw(block, randomBits); - Q_ASSERT( block.size() >= blockSize ); - block.resize(blockSize); - ++counter; return block; } diff --git a/tests/auto/qfiledialog2/tst_qfiledialog2.cpp b/tests/auto/qfiledialog2/tst_qfiledialog2.cpp index 5e9f130..dc3ca52 100644 --- a/tests/auto/qfiledialog2/tst_qfiledialog2.cpp +++ b/tests/auto/qfiledialog2/tst_qfiledialog2.cpp @@ -812,7 +812,7 @@ void tst_QFileDialog2::task239706_editableFilterCombo() break; } } - Q_ASSERT(filterCombo); + QVERIFY(filterCombo); filterCombo->setEditable(true); QTest::mouseClick(filterCombo, Qt::LeftButton); QTest::keyPress(filterCombo, Qt::Key_X); diff --git a/tests/auto/qfuture/versioncheck.h b/tests/auto/qfuture/versioncheck.h index 0cf7b76..32a33c8 100644 --- a/tests/auto/qfuture/versioncheck.h +++ b/tests/auto/qfuture/versioncheck.h @@ -47,3 +47,7 @@ #if defined(Q_CC_MSVC) && _MSC_VER < 1400 #define QT_NO_CONCURRENT_TEST #endif + +#if defined(Q_CC_NOKIAX86) +#define QT_NO_CONCURRENT_TEST +#endif diff --git a/tests/auto/qglyphs/qglyphs.pro b/tests/auto/qglyphrun/qglyphrun.pro index 5084cf9..480ad5b 100644 --- a/tests/auto/qglyphs/qglyphs.pro +++ b/tests/auto/qglyphrun/qglyphrun.pro @@ -2,10 +2,10 @@ load(qttest_p4) QT = core gui SOURCES += \ - tst_qglyphs.cpp + tst_qglyphrun.cpp wince*|symbian*: { DEFINES += SRCDIR=\\\"\\\" } else { DEFINES += SRCDIR=\\\"$$PWD/\\\" -}
\ No newline at end of file +} diff --git a/tests/auto/qglyphs/test.ttf b/tests/auto/qglyphrun/test.ttf Binary files differindex 9043a57..9043a57 100644 --- a/tests/auto/qglyphs/test.ttf +++ b/tests/auto/qglyphrun/test.ttf diff --git a/tests/auto/qglyphs/tst_qglyphs.cpp b/tests/auto/qglyphrun/tst_qglyphrun.cpp index ffa0d00..aefc228 100644 --- a/tests/auto/qglyphs/tst_qglyphs.cpp +++ b/tests/auto/qglyphrun/tst_qglyphrun.cpp @@ -41,14 +41,14 @@ #include <QtTest/QtTest> -#include <qglyphs.h> +#include <qglyphrun.h> #include <qpainter.h> #include <qtextlayout.h> #include <qfontdatabase.h> // #define DEBUG_SAVE_IMAGE -class tst_QGlyphs: public QObject +class tst_QGlyphRun: public QObject { Q_OBJECT @@ -82,9 +82,9 @@ private: #if !defined(QT_NO_RAWFONT) -Q_DECLARE_METATYPE(QGlyphs); +Q_DECLARE_METATYPE(QGlyphRun); -void tst_QGlyphs::initTestCase() +void tst_QGlyphRun::initTestCase() { m_testFontId = QFontDatabase::addApplicationFont(SRCDIR "test.ttf"); QVERIFY(m_testFontId >= 0); @@ -94,19 +94,19 @@ void tst_QGlyphs::initTestCase() QCOMPARE(QFontInfo(m_testFont).family(), QString::fromLatin1("QtsSpecialTestFont")); } -void tst_QGlyphs::cleanupTestCase() +void tst_QGlyphRun::cleanupTestCase() { QFontDatabase::removeApplicationFont(m_testFontId); } -void tst_QGlyphs::constructionAndDestruction() +void tst_QGlyphRun::constructionAndDestruction() { - QGlyphs glyphIndexes; + QGlyphRun glyphIndexes; } -static QGlyphs make_dummy_indexes() +static QGlyphRun make_dummy_indexes() { - QGlyphs glyphs; + QGlyphRun glyphs; QVector<quint32> glyphIndexes; QVector<QPointF> positions; @@ -121,16 +121,16 @@ static QGlyphs make_dummy_indexes() positions.append(QPointF(3, 4)); positions.append(QPointF(5, 6)); - glyphs.setFont(QRawFont::fromFont(font)); + glyphs.setRawFont(QRawFont::fromFont(font)); glyphs.setGlyphIndexes(glyphIndexes); glyphs.setPositions(positions); return glyphs; } -void tst_QGlyphs::copyConstructor() +void tst_QGlyphRun::copyConstructor() { - QGlyphs glyphs; + QGlyphRun glyphs; { QVector<quint32> glyphIndexes; @@ -146,40 +146,40 @@ void tst_QGlyphs::copyConstructor() positions.append(QPointF(3, 4)); positions.append(QPointF(5, 6)); - glyphs.setFont(QRawFont::fromFont(font)); + glyphs.setRawFont(QRawFont::fromFont(font)); glyphs.setGlyphIndexes(glyphIndexes); glyphs.setPositions(positions); } - QGlyphs otherGlyphs(glyphs); - QCOMPARE(otherGlyphs.font(), glyphs.font()); + QGlyphRun otherGlyphs(glyphs); + QCOMPARE(otherGlyphs.rawFont(), glyphs.rawFont()); QCOMPARE(glyphs.glyphIndexes(), otherGlyphs.glyphIndexes()); QCOMPARE(glyphs.positions(), otherGlyphs.positions()); } -void tst_QGlyphs::assignment() +void tst_QGlyphRun::assignment() { - QGlyphs glyphs(make_dummy_indexes()); + QGlyphRun glyphs(make_dummy_indexes()); - QGlyphs otherGlyphs = glyphs; - QCOMPARE(otherGlyphs.font(), glyphs.font()); + QGlyphRun otherGlyphs = glyphs; + QCOMPARE(otherGlyphs.rawFont(), glyphs.rawFont()); QCOMPARE(glyphs.glyphIndexes(), otherGlyphs.glyphIndexes()); QCOMPARE(glyphs.positions(), otherGlyphs.positions()); } -void tst_QGlyphs::equalsOperator_data() +void tst_QGlyphRun::equalsOperator_data() { - QTest::addColumn<QGlyphs>("one"); - QTest::addColumn<QGlyphs>("two"); + QTest::addColumn<QGlyphRun>("one"); + QTest::addColumn<QGlyphRun>("two"); QTest::addColumn<bool>("equals"); - QGlyphs one(make_dummy_indexes()); - QGlyphs two(make_dummy_indexes()); + QGlyphRun one(make_dummy_indexes()); + QGlyphRun two(make_dummy_indexes()); QTest::newRow("Identical") << one << two << true; { - QGlyphs busted(two); + QGlyphRun busted(two); QVector<QPointF> positions = busted.positions(); positions[2] += QPointF(1, 1); @@ -190,17 +190,17 @@ void tst_QGlyphs::equalsOperator_data() } { - QGlyphs busted(two); + QGlyphRun busted(two); QFont font; - font.setPixelSize(busted.font().pixelSize() * 2); - busted.setFont(QRawFont::fromFont(font)); + font.setPixelSize(busted.rawFont().pixelSize() * 2); + busted.setRawFont(QRawFont::fromFont(font)); QTest::newRow("Different fonts") << one << busted << false; } { - QGlyphs busted(two); + QGlyphRun busted(two); QVector<quint32> glyphIndexes = busted.glyphIndexes(); glyphIndexes[2] += 1; @@ -211,10 +211,10 @@ void tst_QGlyphs::equalsOperator_data() } -void tst_QGlyphs::equalsOperator() +void tst_QGlyphRun::equalsOperator() { - QFETCH(QGlyphs, one); - QFETCH(QGlyphs, two); + QFETCH(QGlyphRun, one); + QFETCH(QGlyphRun, two); QFETCH(bool, equals); QCOMPARE(one == two, equals); @@ -222,7 +222,7 @@ void tst_QGlyphs::equalsOperator() } -void tst_QGlyphs::textLayoutGlyphIndexes() +void tst_QGlyphRun::textLayoutGlyphIndexes() { QString s; s.append(QLatin1Char('A')); @@ -234,17 +234,17 @@ void tst_QGlyphs::textLayoutGlyphIndexes() layout.createLine(); layout.endLayout(); - QList<QGlyphs> listOfGlyphs = layout.glyphs(); + QList<QGlyphRun> listOfGlyphs = layout.glyphRuns(); QCOMPARE(listOfGlyphs.size(), 1); - QGlyphs glyphs = listOfGlyphs.at(0); + QGlyphRun glyphs = listOfGlyphs.at(0); QCOMPARE(glyphs.glyphIndexes().size(), 2); QCOMPARE(glyphs.glyphIndexes().at(0), quint32(2)); QCOMPARE(glyphs.glyphIndexes().at(1), quint32(1)); } -void tst_QGlyphs::drawExistingGlyphs() +void tst_QGlyphRun::drawExistingGlyphs() { QPixmap textLayoutDraw(1000, 1000); QPixmap drawGlyphs(1000, 1000); @@ -267,13 +267,13 @@ void tst_QGlyphs::drawExistingGlyphs() layout.draw(&p, QPointF(50, 50)); } - QGlyphs glyphs = layout.glyphs().size() > 0 - ? layout.glyphs().at(0) - : QGlyphs(); + QGlyphRun glyphs = layout.glyphRuns().size() > 0 + ? layout.glyphRuns().at(0) + : QGlyphRun(); { QPainter p(&drawGlyphs); - p.drawGlyphs(QPointF(50, 50), glyphs); + p.drawGlyphRun(QPointF(50, 50), glyphs); } #if defined(DEBUG_SAVE_IMAGE) @@ -284,7 +284,7 @@ void tst_QGlyphs::drawExistingGlyphs() QCOMPARE(textLayoutDraw, drawGlyphs); } -void tst_QGlyphs::drawNonExistentGlyphs() +void tst_QGlyphRun::drawNonExistentGlyphs() { QVector<quint32> glyphIndexes; glyphIndexes.append(3); @@ -292,10 +292,10 @@ void tst_QGlyphs::drawNonExistentGlyphs() QVector<QPointF> glyphPositions; glyphPositions.append(QPointF(0, 0)); - QGlyphs glyphs; + QGlyphRun glyphs; glyphs.setGlyphIndexes(glyphIndexes); glyphs.setPositions(glyphPositions); - glyphs.setFont(QRawFont::fromFont(m_testFont)); + glyphs.setRawFont(QRawFont::fromFont(m_testFont)); QPixmap image(1000, 1000); image.fill(Qt::white); @@ -303,7 +303,7 @@ void tst_QGlyphs::drawNonExistentGlyphs() QPixmap imageBefore = image; { QPainter p(&image); - p.drawGlyphs(QPointF(50, 50), glyphs); + p.drawGlyphRun(QPointF(50, 50), glyphs); } #if defined(DEBUG_SAVE_IMAGE) @@ -313,7 +313,7 @@ void tst_QGlyphs::drawNonExistentGlyphs() QCOMPARE(image, imageBefore); // Should be unchanged } -void tst_QGlyphs::drawMultiScriptText1() +void tst_QGlyphRun::drawMultiScriptText1() { QString text; text += QChar(0x03D0); // Greek, beta @@ -329,7 +329,7 @@ void tst_QGlyphs::drawMultiScriptText1() QPixmap drawGlyphs(1000, 1000); drawGlyphs.fill(Qt::white); - QList<QGlyphs> glyphsList = textLayout.glyphs(); + QList<QGlyphRun> glyphsList = textLayout.glyphRuns(); QCOMPARE(glyphsList.size(), 1); { @@ -339,8 +339,8 @@ void tst_QGlyphs::drawMultiScriptText1() { QPainter p(&drawGlyphs); - foreach (QGlyphs glyphs, glyphsList) - p.drawGlyphs(QPointF(50, 50), glyphs); + foreach (QGlyphRun glyphs, glyphsList) + p.drawGlyphRun(QPointF(50, 50), glyphs); } #if defined(DEBUG_SAVE_IMAGE) @@ -352,7 +352,7 @@ void tst_QGlyphs::drawMultiScriptText1() } -void tst_QGlyphs::drawMultiScriptText2() +void tst_QGlyphRun::drawMultiScriptText2() { QString text; text += QChar(0x0621); // Arabic, Hamza @@ -369,7 +369,7 @@ void tst_QGlyphs::drawMultiScriptText2() QPixmap drawGlyphs(1000, 1000); drawGlyphs.fill(Qt::white); - QList<QGlyphs> glyphsList = textLayout.glyphs(); + QList<QGlyphRun> glyphsList = textLayout.glyphRuns(); QCOMPARE(glyphsList.size(), 2); { @@ -379,8 +379,8 @@ void tst_QGlyphs::drawMultiScriptText2() { QPainter p(&drawGlyphs); - foreach (QGlyphs glyphs, glyphsList) - p.drawGlyphs(QPointF(50, 50), glyphs); + foreach (QGlyphRun glyphs, glyphsList) + p.drawGlyphRun(QPointF(50, 50), glyphs); } #if defined(DEBUG_SAVE_IMAGE) @@ -391,13 +391,13 @@ void tst_QGlyphs::drawMultiScriptText2() QCOMPARE(drawGlyphs, textLayoutDraw); } -void tst_QGlyphs::detach() +void tst_QGlyphRun::detach() { - QGlyphs glyphs; + QGlyphRun glyphs; glyphs.setGlyphIndexes(QVector<quint32>() << 1 << 2 << 3); - QGlyphs otherGlyphs; + QGlyphRun otherGlyphs; otherGlyphs = glyphs; QCOMPARE(otherGlyphs.glyphIndexes(), glyphs.glyphIndexes()); @@ -408,7 +408,7 @@ void tst_QGlyphs::detach() QCOMPARE(glyphs.glyphIndexes(), QVector<quint32>() << 1 << 2 << 3); } -void tst_QGlyphs::drawStruckOutText() +void tst_QGlyphRun::drawStruckOutText() { QPixmap textLayoutDraw(1000, 1000); QPixmap drawGlyphs(1000, 1000); @@ -432,13 +432,13 @@ void tst_QGlyphs::drawStruckOutText() layout.draw(&p, QPointF(50, 50)); } - QGlyphs glyphs = layout.glyphs().size() > 0 - ? layout.glyphs().at(0) - : QGlyphs(); + QGlyphRun glyphs = layout.glyphRuns().size() > 0 + ? layout.glyphRuns().at(0) + : QGlyphRun(); { QPainter p(&drawGlyphs); - p.drawGlyphs(QPointF(50, 50), glyphs); + p.drawGlyphRun(QPointF(50, 50), glyphs); } #if defined(DEBUG_SAVE_IMAGE) @@ -449,7 +449,7 @@ void tst_QGlyphs::drawStruckOutText() QCOMPARE(textLayoutDraw, drawGlyphs); } -void tst_QGlyphs::drawOverlinedText() +void tst_QGlyphRun::drawOverlinedText() { QPixmap textLayoutDraw(1000, 1000); QPixmap drawGlyphs(1000, 1000); @@ -473,13 +473,13 @@ void tst_QGlyphs::drawOverlinedText() layout.draw(&p, QPointF(50, 50)); } - QGlyphs glyphs = layout.glyphs().size() > 0 - ? layout.glyphs().at(0) - : QGlyphs(); + QGlyphRun glyphs = layout.glyphRuns().size() > 0 + ? layout.glyphRuns().at(0) + : QGlyphRun(); { QPainter p(&drawGlyphs); - p.drawGlyphs(QPointF(50, 50), glyphs); + p.drawGlyphRun(QPointF(50, 50), glyphs); } #if defined(DEBUG_SAVE_IMAGE) @@ -490,7 +490,7 @@ void tst_QGlyphs::drawOverlinedText() QCOMPARE(textLayoutDraw, drawGlyphs); } -void tst_QGlyphs::drawUnderlinedText() +void tst_QGlyphRun::drawUnderlinedText() { QPixmap textLayoutDraw(1000, 1000); QPixmap drawGlyphs(1000, 1000); @@ -514,13 +514,13 @@ void tst_QGlyphs::drawUnderlinedText() layout.draw(&p, QPointF(50, 50)); } - QGlyphs glyphs = layout.glyphs().size() > 0 - ? layout.glyphs().at(0) - : QGlyphs(); + QGlyphRun glyphs = layout.glyphRuns().size() > 0 + ? layout.glyphRuns().at(0) + : QGlyphRun(); { QPainter p(&drawGlyphs); - p.drawGlyphs(QPointF(50, 50), glyphs); + p.drawGlyphRun(QPointF(50, 50), glyphs); } #if defined(DEBUG_SAVE_IMAGE) @@ -531,7 +531,7 @@ void tst_QGlyphs::drawUnderlinedText() QCOMPARE(textLayoutDraw, drawGlyphs); } -void tst_QGlyphs::drawRightToLeft() +void tst_QGlyphRun::drawRightToLeft() { QString s; s.append(QChar(1575)); @@ -557,13 +557,13 @@ void tst_QGlyphs::drawRightToLeft() layout.draw(&p, QPointF(50, 50)); } - QGlyphs glyphs = layout.glyphs().size() > 0 - ? layout.glyphs().at(0) - : QGlyphs(); + QGlyphRun glyphs = layout.glyphRuns().size() > 0 + ? layout.glyphRuns().at(0) + : QGlyphRun(); { QPainter p(&drawGlyphs); - p.drawGlyphs(QPointF(50, 50), glyphs); + p.drawGlyphRun(QPointF(50, 50), glyphs); } #if defined(DEBUG_SAVE_IMAGE) @@ -577,6 +577,6 @@ void tst_QGlyphs::drawRightToLeft() #endif // QT_NO_RAWFONT -QTEST_MAIN(tst_QGlyphs) -#include "tst_qglyphs.moc" +QTEST_MAIN(tst_QGlyphRun) +#include "tst_qglyphrun.moc" diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index e7c63d5..55d6fc9 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -132,33 +132,32 @@ static void setAnchor(QGraphicsAnchorLayout *l, anchor->setSpacing(spacing); } -static bool checkReverseDirection(QGraphicsWidget *w) +static bool checkReverseDirection(QGraphicsWidget *widget) { - QGraphicsLayout *l = w->layout(); - Q_ASSERT(l); + QGraphicsLayout *layout = widget->layout(); qreal left, top, right, bottom; - l->getContentsMargins(&left, &top, &right, &bottom); - w->setLayoutDirection(Qt::LeftToRight); + layout->getContentsMargins(&left, &top, &right, &bottom); + widget->setLayoutDirection(Qt::LeftToRight); QApplication::processEvents(); - const QRectF lg = l->geometry(); + const QRectF layoutGeometry = layout->geometry(); QMap<QGraphicsLayoutItem *, QRectF> geometries; - for (int i = 0; i < l->count(); ++i) { - QGraphicsLayoutItem *w = l->itemAt(i); - geometries.insert(w, w->geometry()); + for (int i = 0; i < layout->count(); ++i) { + QGraphicsLayoutItem *item = layout->itemAt(i); + geometries.insert(item, item->geometry()); } - w->setLayoutDirection(Qt::RightToLeft); + widget->setLayoutDirection(Qt::RightToLeft); QApplication::processEvents(); - lg.adjusted(+right, +top, -left, -bottom); - for (int i = 0; i < l->count(); ++i) { - QGraphicsLayoutItem *w = l->itemAt(i); - const QRectF rtlGeom = w->geometry(); - const QRectF ltrGeom = geometries.value(w); - QRectF expectedGeom = ltrGeom; - expectedGeom.moveRight(lg.right() - (0 + ltrGeom.left())); - if (expectedGeom != rtlGeom) { - qDebug() << "layout->geometry():" << lg - << "expected:" << expectedGeom - << "actual:" << rtlGeom; + layoutGeometry.adjusted(+right, +top, -left, -bottom); + for (int i = 0; i < layout->count(); ++i) { + QGraphicsLayoutItem *item = layout->itemAt(i); + const QRectF rightToLeftGeometry = item->geometry(); + const QRectF leftToRightGeometry = geometries.value(item); + QRectF expectedGeometry = leftToRightGeometry; + expectedGeometry.moveRight(layoutGeometry.right() - leftToRightGeometry.left()); + if (expectedGeometry != rightToLeftGeometry) { + qDebug() << "layout->geometry():" << layoutGeometry + << "expected:" << expectedGeometry + << "actual:" << rightToLeftGeometry; return false; } } @@ -345,6 +344,7 @@ void tst_QGraphicsAnchorLayout::layoutDirection() p->show(); view->show(); + QVERIFY(p->layout()); QCOMPARE(checkReverseDirection(p), true); if (hasSimplification) { @@ -445,6 +445,7 @@ void tst_QGraphicsAnchorLayout::diagonal() QVERIFY(!usedSimplex(l, Qt::Vertical)); } + QVERIFY(p.layout()); QCOMPARE(checkReverseDirection(&p), true); c->setMinimumWidth(300); @@ -735,6 +736,7 @@ void tst_QGraphicsAnchorLayout::snakeOppositeDirections() QCOMPARE(c->geometry(), QRectF(90.0, 200.0, 100.0, 100.0)); QCOMPARE(p.size(), layoutMaximumSize); + QVERIFY(p.layout()); QCOMPARE(checkReverseDirection(&p), true); } @@ -1091,6 +1093,9 @@ void tst_QGraphicsAnchorLayout::setSpacing() #ifdef Q_WS_MAC QTest::qWait(200); #endif + + // 21x21 + QCOMPARE(p->size(), QSizeF(41, 41)); QCOMPARE(a->geometry(), QRectF(0, 0, 20, 20)); QCOMPARE(b->geometry(), QRectF(21, 0, 20, 20)); QCOMPARE(c->geometry(), QRectF(0, 21, 41, 20)); diff --git a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp index a03f7bc..ee25291 100644 --- a/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp +++ b/tests/auto/qgraphicsanchorlayout1/tst_qgraphicsanchorlayout1.cpp @@ -2585,15 +2585,11 @@ void tst_QGraphicsAnchorLayout1::testSizeDistribution_data() sizeHints1.insert( Qt::MinimumSize, 30 ); sizeHints1.insert( Qt::PreferredSize, 35 ); sizeHints1.insert( Qt::MaximumSize, 40 ); - Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); SizeHintArray sizeHints2; sizeHints2.insert( Qt::MinimumSize, 5 ); sizeHints2.insert( Qt::PreferredSize, 35 ); sizeHints2.insert( Qt::MaximumSize, 300 ); - Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); const qreal width1 = 35; const qreal width2 = 100-10-10-10-width1; @@ -2605,15 +2601,11 @@ void tst_QGraphicsAnchorLayout1::testSizeDistribution_data() sizeHints1.insert( Qt::MinimumSize, 0 ); sizeHints1.insert( Qt::PreferredSize, 20 ); sizeHints1.insert( Qt::MaximumSize, 100 ); - Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); SizeHintArray sizeHints2; sizeHints2.insert( Qt::MinimumSize, 0 ); sizeHints2.insert( Qt::PreferredSize, 50 ); sizeHints2.insert( Qt::MaximumSize, 100 ); - Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); const qreal width1 = 20; const qreal width2 = 100-10-10-10-width1; @@ -2625,15 +2617,11 @@ void tst_QGraphicsAnchorLayout1::testSizeDistribution_data() sizeHints1.insert( Qt::MinimumSize, 0 ); sizeHints1.insert( Qt::PreferredSize, 40 ); sizeHints1.insert( Qt::MaximumSize, 100 ); - Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); SizeHintArray sizeHints2; sizeHints2.insert( Qt::MinimumSize, 0 ); sizeHints2.insert( Qt::PreferredSize, 60 ); sizeHints2.insert( Qt::MaximumSize, 100 ); - Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); const qreal width1 = 28; // got from manual calculation const qreal width2 = 100-10-10-10-width1; @@ -2645,15 +2633,11 @@ void tst_QGraphicsAnchorLayout1::testSizeDistribution_data() sizeHints1.insert( Qt::MinimumSize, 0 ); sizeHints1.insert( Qt::PreferredSize, 10 ); sizeHints1.insert( Qt::MaximumSize, 100 ); - Q_ASSERT( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); SizeHintArray sizeHints2; sizeHints2.insert( Qt::MinimumSize, 0 ); sizeHints2.insert( Qt::PreferredSize, 40 ); sizeHints2.insert( Qt::MaximumSize, 100 ); - Q_ASSERT( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); - Q_ASSERT( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); const qreal width1 = 22; // got from manual calculation const qreal width2 = 100-10-10-10-width1; @@ -2669,6 +2653,12 @@ void tst_QGraphicsAnchorLayout1::testSizeDistribution() QFETCH(qreal, width1); QFETCH(qreal, width2); + // sanity-check the test data - MinimumSize <= PreferredSize <= MaximumSize + QVERIFY( sizeHints1.value( Qt::MinimumSize ) <= sizeHints1.value( Qt::PreferredSize ) ); + QVERIFY( sizeHints1.value( Qt::PreferredSize ) <= sizeHints1.value( Qt::MaximumSize ) ); + QVERIFY( sizeHints2.value( Qt::MinimumSize ) <= sizeHints2.value( Qt::PreferredSize ) ); + QVERIFY( sizeHints2.value( Qt::PreferredSize ) <= sizeHints2.value( Qt::MaximumSize ) ); + // create objects QGraphicsWidget widget; TheAnchorLayout *layout = new TheAnchorLayout; diff --git a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp index 837df78..78010e6 100644 --- a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp +++ b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp @@ -3018,39 +3018,6 @@ static QSizeF wfh(Qt::SizeHint /*which*/, const QSizeF &constraint) return result; } -static qreal growthFactorBelowPreferredSize(qreal desired, qreal sumAvailable, qreal sumDesired) -{ - Q_ASSERT(sumDesired != 0.0); - return desired * qPow(sumAvailable / sumDesired, desired / sumDesired); -} - -static void expectedWidth(qreal minSize1, qreal prefSize1, - qreal minSize2, qreal prefSize2, - qreal targetSize, qreal *width1, qreal *width2) -{ - qreal sumAvail,factor1,factor2; - // stretch behaviour is different below and above preferred size... - if (targetSize < prefSize1 + prefSize2) { - sumAvail = targetSize - minSize1 - minSize2; - const qreal desired1 = prefSize1 - minSize1; - const qreal desired2 = prefSize2 - minSize2; - const qreal sumDesired = desired1 + desired2; - factor1 = growthFactorBelowPreferredSize(desired1, sumAvail, sumDesired); - factor2 = growthFactorBelowPreferredSize(desired2, sumAvail, sumDesired); - const qreal sumFactors = factor1 + factor2; - *width1 = sumAvail*factor1/sumFactors + minSize1; - *width2 = sumAvail*factor2/sumFactors + minSize2; - } else { - sumAvail = targetSize - prefSize1 - prefSize2; - factor1 = prefSize1; - factor2 = prefSize2; - const qreal sumFactors = factor1 + factor2; - *width1 = sumAvail*factor1/sumFactors + prefSize1; - *width2 = sumAvail*factor2/sumFactors + prefSize2; - } -} - - bool qFuzzyCompare(const QSizeF &a, const QSizeF &b) { return qFuzzyCompare(a.width(), b.width()) && qFuzzyCompare(a.height(), b.height()); diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp index 73e5656..f8bf7a1 100644 --- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp +++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp @@ -10732,7 +10732,7 @@ void tst_QGraphicsItem::deviceCoordinateCache_simpleRotations() QTRY_VERIFY(view.repaints > 0); QGraphicsItemCache *itemCache = QGraphicsItemPrivate::get(item)->extraItemCache(); - Q_ASSERT(itemCache); + QVERIFY(itemCache); QPixmapCache::Key currentKey = itemCache->deviceData.value(view.viewport()).key; // Trigger an update and verify that the cache is unchanged. diff --git a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp index 979f03d..29ea074 100644 --- a/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp +++ b/tests/auto/qgraphicslayout/tst_qgraphicslayout.cpp @@ -62,6 +62,7 @@ private slots: void compressLayoutRequest(); void automaticReparenting(); void verifyActivate(); + void invalidate(); void constructors(); void alternativeLayoutItems(); void ownership(); @@ -95,6 +96,14 @@ void tst_QGraphicsLayout::sizeHints() } +enum FunctionType { + SetGeometry = 0, + Invalidate, + NumFunctionTypes +}; + + + class TestGraphicsWidget : public QGraphicsWidget { public: TestGraphicsWidget(QGraphicsWidget *parent = 0) : QGraphicsWidget(parent) @@ -108,9 +117,28 @@ public: int eventCount(QEvent::Type type) { return m_eventCount.value(int(type)); } + void clearEventCount() { m_eventCount.clear(); } + + void clearCounters() { + m_eventCount.clear(); + functionCount.clear(); + } + + void setGeometry(const QRectF &rect) + { + QGraphicsWidget::setGeometry(rect); + ++(functionCount[SetGeometry]); + } + + void callUpdateGeometry() + { + // updateGeometry() is protected + QGraphicsWidget::updateGeometry(); + } + QMap<FunctionType, int> functionCount; private: QMap<int, int> m_eventCount; }; @@ -122,6 +150,8 @@ void tst_QGraphicsLayout::compressLayoutRequest() TestGraphicsWidget *tw = new TestGraphicsWidget(); scene.addItem(tw); view.show(); + + QTest::qWaitForWindowShown(&view); QGraphicsLinearLayout *lout = new QGraphicsLinearLayout(tw); for (int i = 0; i < 4; ++i) { QGraphicsWidget *gw = new QGraphicsWidget(tw); @@ -217,17 +247,27 @@ class TestLayout : public QGraphicsLinearLayout TestLayout(QGraphicsLayoutItem *parent = 0) : QGraphicsLinearLayout(parent) { - m_count = 0; + setContentsMargins(0,0,0,0); + setSpacing(0); } - void setGeometry(const QRectF &rect) { - - ++m_count; + void setGeometry(const QRectF &rect) + { + ++(functionCount[SetGeometry]); QGraphicsLinearLayout::setGeometry(rect); } + void invalidate() + { + ++(functionCount[Invalidate]); + QGraphicsLinearLayout::invalidate(); + } + + void clearCounters() { + functionCount.clear(); + } - int m_count; + QMap<FunctionType, int> functionCount; }; void tst_QGraphicsLayout::verifyActivate() @@ -242,13 +282,278 @@ void tst_QGraphicsLayout::verifyActivate() lout->addItem(w); window->setLayout(lout); - QCOMPARE(lout->m_count, 0); + QCOMPARE(lout->functionCount[SetGeometry], 0); window->setVisible(false); - QCOMPARE(lout->m_count, 0); + QCOMPARE(lout->functionCount[SetGeometry], 0); window->setVisible(true); // on polish or the first time a widget is shown, the widget is resized. - QCOMPARE(lout->m_count, 1); + QCOMPARE(lout->functionCount[SetGeometry], 1); + +} + +static void clearAllCounters(TestGraphicsWidget *widget) +{ + if (!widget) + return; + widget->clearCounters(); + TestLayout *layout = static_cast<TestLayout *>(widget->layout()); + if (layout) { + layout->clearCounters(); + for (int i = layout->count() - 1; i >=0; --i) { + QGraphicsLayoutItem *item = layout->itemAt(i); + if (item->isLayout()) { + // ### Not used ATM + //TestLayout *lay = static_cast<TestLayout*>(static_cast<QGraphicsLayout*>(item)); + //clearAllCounters(lay); + } else { + TestGraphicsWidget *wid = static_cast<TestGraphicsWidget *>(item); + clearAllCounters(wid); + } + } + } +} + +static void activateAndReset(TestGraphicsWidget *widget) +{ + QApplication::sendPostedEvents(); + QApplication::processEvents(); + if (widget->layout()) + widget->layout()->activate(); + clearAllCounters(widget); +} + + +void tst_QGraphicsLayout::invalidate() +{ + QGraphicsLayout::setInstantInvalidatePropagation(true); + QGraphicsScene scene; + QGraphicsView view(&scene); + + TestGraphicsWidget *a = new TestGraphicsWidget; + a->setData(0, QString("a")); + scene.addItem(a); + TestLayout *alay = new TestLayout(a); + TestGraphicsWidget *b = new TestGraphicsWidget; + b->setData(0, QString("b")); + alay->addItem(b); + TestLayout *blay = new TestLayout(b); + TestGraphicsWidget *e = new TestGraphicsWidget; + e->setData(0, QString("e")); + blay->addItem(e); + + + TestGraphicsWidget *c = new TestGraphicsWidget; + c->setData(0, QString("c")); + alay->addItem(c); + TestLayout *clay = new TestLayout(c); + TestGraphicsWidget *f = new TestGraphicsWidget; + f->setData(0, QString("f")); + clay->addItem(f); + + TestGraphicsWidget *d = new TestGraphicsWidget; + d->setData(0, QString("d")); + alay->addItem(d); + TestLayout *dlay = new TestLayout(d); + TestGraphicsWidget *g = new TestGraphicsWidget; + g->setData(0, QString("g")); + dlay->addItem(g); + + view.show(); + + { + clearAllCounters(a); + + QCoreApplication::sendPostedEvents(); + QCoreApplication::processEvents(); + + alay->activate(); + QCOMPARE(alay->isActivated(), true); + QCOMPARE(blay->isActivated(), true); + QCOMPARE(clay->isActivated(), true); + QCOMPARE(dlay->isActivated(), true); + } + + { + clearAllCounters(a); + e->callUpdateGeometry(); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), false); + QCOMPARE(clay->isActivated(), true); + QCOMPARE(dlay->isActivated(), true); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + + // should only invalidate ascendants of e + QCOMPARE(blay->functionCount[Invalidate], 1); + QCOMPARE(alay->functionCount[Invalidate], 1); + // not siblings + QCOMPARE(clay->functionCount[Invalidate], 0); + QCOMPARE(dlay->functionCount[Invalidate], 0); + + QApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + } + + { + activateAndReset(a); + f->callUpdateGeometry(); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), true); + QCOMPARE(clay->isActivated(), false); + QCOMPARE(dlay->isActivated(), true); + + QCoreApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + + QCOMPARE(a->functionCount[SetGeometry], 1); + QCOMPARE(alay->functionCount[SetGeometry], 1); + + QCOMPARE(b->functionCount[SetGeometry], 1); + QCOMPARE(c->functionCount[SetGeometry], 1); + QCOMPARE(d->functionCount[SetGeometry], 1); + // Since nothing really changed, blay and dlay don't need + // to be resized. + QCOMPARE(blay->functionCount[SetGeometry], 0); + QCOMPARE(clay->functionCount[SetGeometry], 1); + QCOMPARE(dlay->functionCount[SetGeometry], 0); + + QCOMPARE(f->functionCount[SetGeometry], 1); + + QCOMPARE(a->size(), QSizeF(150, 50)); + } + + { + activateAndReset(a); + f->setPreferredSize(QSizeF(60,50)); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), true); + QCOMPARE(clay->isActivated(), false); + QCOMPARE(dlay->isActivated(), true); + + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCoreApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + + QCOMPARE(a->functionCount[SetGeometry], 1); + QCOMPARE(alay->functionCount[SetGeometry], 1); + + QCOMPARE(b->functionCount[SetGeometry], 1); + QCOMPARE(c->functionCount[SetGeometry], 1); + QCOMPARE(d->functionCount[SetGeometry], 1); + // f actually got wider, need to rearrange its siblings + QCOMPARE(blay->functionCount[SetGeometry], 1); + QCOMPARE(clay->functionCount[SetGeometry], 1); + QCOMPARE(dlay->functionCount[SetGeometry], 1); + + QCOMPARE(e->functionCount[SetGeometry], 1); + QCOMPARE(f->functionCount[SetGeometry], 1); + QCOMPARE(g->functionCount[SetGeometry], 1); + + QVERIFY(e->size().width() < f->size().width()); + QVERIFY(g->size().width() < f->size().width()); + } + + { + // resize f so much that it'll force a resize of the top widget + // this will currently generate two setGeometry() calls on the child layout + // of the top widget. + activateAndReset(a); + f->setPreferredSize(QSizeF()); + f->setMinimumSize(QSizeF(200,50)); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), true); + QCOMPARE(clay->isActivated(), false); + QCOMPARE(dlay->isActivated(), true); + + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCoreApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 0); + + QCOMPARE(a->functionCount[SetGeometry], 1); + + /* well, ideally one call to setGeometry(), but it will currently + * get two calls to setGeometry(): + * 1. The first LayoutRequest will call activate() - that will call + * setGeometry() on the layout. This geometry will be based on + * the widget geometry which is not correct at this moment. + * (it is still 150 wide) + * 2. Next, we check if the widget is top level, and then we call + * parentWidget->resize(parentWidget->size()); + * This will be adjusted to be minimum 200 pixels wide. + * The new size will then be propagated down to the layout + * + */ + QCOMPARE(alay->functionCount[SetGeometry], 2); + + QCOMPARE(b->functionCount[SetGeometry], 2); + QCOMPARE(c->functionCount[SetGeometry], 2); + QCOMPARE(d->functionCount[SetGeometry], 2); + // f actually got wider, need to rearrange its siblings + QCOMPARE(blay->functionCount[SetGeometry], 1); + QCOMPARE(clay->functionCount[SetGeometry], 1); + QCOMPARE(dlay->functionCount[SetGeometry], 1); + + QCOMPARE(e->functionCount[SetGeometry], 1); + QCOMPARE(f->functionCount[SetGeometry], 1); + QCOMPARE(g->functionCount[SetGeometry], 1); + + QVERIFY(e->size().width() < f->size().width()); + QVERIFY(g->size().width() < f->size().width()); + } + + { + f->setPreferredSize(QSizeF()); + f->setMinimumSize(QSizeF()); + a->adjustSize(); + activateAndReset(a); + // update two different leaf widgets, + // eventCount and functionCount should never be >= 2 + e->callUpdateGeometry(); + g->callUpdateGeometry(); + QCOMPARE(alay->isActivated(), false); + QCOMPARE(blay->isActivated(), false); + QCOMPARE(clay->isActivated(), true); + QCOMPARE(dlay->isActivated(), false); + + QCoreApplication::sendPostedEvents(); + QCOMPARE(a->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(b->eventCount(QEvent::LayoutRequest), 1); + QCOMPARE(c->eventCount(QEvent::LayoutRequest), 0); + QCOMPARE(d->eventCount(QEvent::LayoutRequest), 1); + + QCOMPARE(a->functionCount[SetGeometry], 1); + QCOMPARE(alay->functionCount[SetGeometry], 1); + + QCOMPARE(b->functionCount[SetGeometry], 1); + QCOMPARE(c->functionCount[SetGeometry], 1); + QCOMPARE(d->functionCount[SetGeometry], 1); + // f actually got wider, need to rearrange its siblings + QCOMPARE(blay->functionCount[SetGeometry], 1); + QCOMPARE(clay->functionCount[SetGeometry], 0); + QCOMPARE(dlay->functionCount[SetGeometry], 1); + + QCOMPARE(e->functionCount[SetGeometry], 1); + QCOMPARE(f->functionCount[SetGeometry], 0); + QCOMPARE(g->functionCount[SetGeometry], 1); + + } + + QGraphicsLayout::setInstantInvalidatePropagation(false); } class Layout : public QGraphicsLayout diff --git a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp index 62ba1b4..8f8ac67 100644 --- a/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp +++ b/tests/auto/qgraphicslinearlayout/tst_qgraphicslinearlayout.cpp @@ -94,6 +94,7 @@ private slots: void itemSpacing(); void setStretchFactor_data(); void setStretchFactor(); + void testStretch(); void defaultStretchFactors_data(); void defaultStretchFactors(); void sizeHint_data(); @@ -667,6 +668,10 @@ void tst_QGraphicsLinearLayout::invalidate() layout.setContentsMargins(0, 0, 0, 0); view.show(); widget->show(); + //QTest::qWait(1000); + QTest::qWaitForWindowShown(&view); + qApp->processEvents(); + layout.layoutRequest = 0; layout.setContentsMargins(1, 2, 3, 4); QApplication::sendPostedEvents(0, 0); @@ -1130,6 +1135,41 @@ void tst_QGraphicsLinearLayout::setStretchFactor() delete widget; } +void tst_QGraphicsLinearLayout::testStretch() +{ + QGraphicsScene scene; + QGraphicsView *view = new QGraphicsView(&scene); + QGraphicsWidget *form = new QGraphicsWidget(0, Qt::Window); + + scene.addItem(form); + form->setMinimumSize(600, 600); + form->setMaximumSize(600, 600); + QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Horizontal, form); + QGraphicsWidget *w1 = new RectWidget; + w1->setPreferredSize(100,100); + w1->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + QGraphicsWidget *w2 = new RectWidget; + w2->setPreferredSize(200,200); + w2->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + layout->setSpacing(0); + layout->setContentsMargins(0, 0, 0, 0); + layout->addItem(w1); + layout->addStretch(2); + layout->addItem(w2); + QCOMPARE(layout->count(), 2); + QVERIFY(layout->itemAt(0) == w1); + QVERIFY(layout->itemAt(1) == w2); + layout->activate(); + + //view->setSceneRect(-50, -50, 800, 800); + //view->show(); + //QTest::qWaitForWindowShown(view); + //QTest::qWait(5000); + QCOMPARE(form->geometry().size(), QSizeF(600,600)); + QCOMPARE(w1->geometry(), QRectF(0, 0, 100, 100)); + QCOMPARE(w2->geometry(), QRectF(400, 0, 200, 200)); +} + void tst_QGraphicsLinearLayout::defaultStretchFactors_data() { QTest::addColumn<Qt::Orientation>("orientation"); diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index 9ff086c..0927577 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -3594,7 +3594,7 @@ void tst_QGraphicsScene::task160653_selectionChanged() item->flags() | QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable); item->setSelected(true); } - Q_ASSERT(scene.items().size() > 1); + QVERIFY(scene.items().size() > 1); QCOMPARE(scene.items().size(), scene.selectedItems().size()); QSignalSpy spy(&scene, SIGNAL(selectionChanged())); diff --git a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp index e8e2e23..887026c 100644 --- a/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp +++ b/tests/auto/qgraphicswidget/tst_qgraphicswidget.cpp @@ -186,7 +186,6 @@ private slots: void task250119_shortcutContext(); void QT_BUG_6544_tabFocusFirstUnsetWhenRemovingItems(); void QT_BUG_12056_tabFocusFirstUnsetWhenRemovingItems(); - void QT_BUG_13865_doublePaintWhenAddingASubItem(); }; @@ -3367,46 +3366,6 @@ void tst_QGraphicsWidget::QT_BUG_12056_tabFocusFirstUnsetWhenRemovingItems() //This should not crash } - -struct GreenWidget : public QGraphicsWidget -{ - GreenWidget() : count(0) - { - } - - void paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * ) - { - count++; - painter->setPen(Qt::green); - painter->drawRect(option->rect.adjusted(0,0,-1,-1)); - } - - int count; -}; - -void tst_QGraphicsWidget::QT_BUG_13865_doublePaintWhenAddingASubItem() -{ - QGraphicsScene scene; - QGraphicsView view(&scene); - QGraphicsWidget *widget = new QGraphicsWidget; - widget->resize(100, 100); - scene.addItem(widget); - QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(widget); - - view.show(); - QTest::qWaitForWindowShown(&view); - QApplication::processEvents(); - - - GreenWidget *sub = new GreenWidget; - layout->addItem(sub); - - QTest::qWait(100); - QCOMPARE(sub->count, 1); //it should only be painted once - -} - - QTEST_MAIN(tst_QGraphicsWidget) #include "tst_qgraphicswidget.moc" diff --git a/tests/auto/qheaderview/tst_qheaderview.cpp b/tests/auto/qheaderview/tst_qheaderview.cpp index 9a25fb6..d877d2f 100644 --- a/tests/auto/qheaderview/tst_qheaderview.cpp +++ b/tests/auto/qheaderview/tst_qheaderview.cpp @@ -1106,7 +1106,7 @@ void tst_QHeaderView::moveAndInsertSection() void tst_QHeaderView::resizeMode() { - // Q_ASSERT's when resizeMode is called with an invalid index + // resizeMode must not be called with an invalid index int last = view->count() - 1; view->setResizeMode(QHeaderView::Interactive); QCOMPARE(view->resizeMode(last), QHeaderView::Interactive); diff --git a/tests/auto/qhostaddress/tst_qhostaddress.cpp b/tests/auto/qhostaddress/tst_qhostaddress.cpp index bd020aa..e2043a5 100644 --- a/tests/auto/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/qhostaddress/tst_qhostaddress.cpp @@ -164,21 +164,27 @@ void tst_QHostAddress::setAddress_QString_data() QTest::newRow("ip4_04") << QString("255.3.2.1\r ") << (bool)TRUE << QString("255.3.2.1") << 4; QTest::newRow("ip4_05") << QString("0.0.0.0") << (bool)TRUE << QString("0.0.0.0") << 4; - // for the format of IPv6 addresses see also RFC 1884 + // for the format of IPv6 addresses see also RFC 5952 QTest::newRow("ip6_00") << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << (bool)TRUE << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << 6; - QTest::newRow("ip6_01") << QString("1080:0000:0000:0000:0008:0800:200C:417A") << (bool)TRUE << QString("1080:0:0:0:8:800:200C:417A") << 6; - QTest::newRow("ip6_02") << QString("1080:0:0:0:8:800:200C:417A") << (bool)TRUE << QString("1080:0:0:0:8:800:200C:417A") << 6; - QTest::newRow("ip6_03") << QString("1080::8:800:200C:417A") << (bool)TRUE << QString("1080:0:0:0:8:800:200C:417A") << 6; - QTest::newRow("ip6_04") << QString("FF01::43") << (bool)TRUE << QString("FF01:0:0:0:0:0:0:43") << 6; - QTest::newRow("ip6_05") << QString("::1") << (bool)TRUE << QString("0:0:0:0:0:0:0:1") << 6; - QTest::newRow("ip6_06") << QString("1::") << (bool)TRUE << QString("1:0:0:0:0:0:0:0") << 6; - QTest::newRow("ip6_07") << QString("::") << (bool)TRUE << QString("0:0:0:0:0:0:0:0") << 6; - QTest::newRow("ip6_08") << QString("0:0:0:0:0:0:13.1.68.3") << (bool)TRUE << QString("0:0:0:0:0:0:D01:4403") << 6; - QTest::newRow("ip6_09") << QString("::13.1.68.3") << (bool)TRUE << QString("0:0:0:0:0:0:D01:4403") << 6; - QTest::newRow("ip6_10") << QString("0:0:0:0:0:FFFF:129.144.52.38") << (bool)TRUE << QString("0:0:0:0:0:FFFF:8190:3426") << 6; - QTest::newRow("ip6_11") << QString("::FFFF:129.144.52.38") << (bool)TRUE << QString("0:0:0:0:0:FFFF:8190:3426") << 6; - QTest::newRow("ip6_12") << QString("1::FFFF:129.144.52.38") << (bool)TRUE << QString("1:0:0:0:0:FFFF:8190:3426") << 6; - QTest::newRow("ip6_13") << QString("A:B::D:E") << (bool)TRUE << QString("A:B:0:0:0:0:D:E") << 6; + QTest::newRow("ip6_01") << QString("1080:0000:0000:0000:0008:0800:200C:417A") << (bool)TRUE << QString("1080::8:800:200C:417A") << 6; + QTest::newRow("ip6_02") << QString("1080:0:0:0:8:800:200C:417A") << (bool)TRUE << QString("1080::8:800:200C:417A") << 6; + QTest::newRow("ip6_03") << QString("1080::8:800:200C:417A") << (bool)TRUE << QString("1080::8:800:200C:417A") << 6; + QTest::newRow("ip6_04") << QString("FF01::43") << (bool)TRUE << QString("FF01::43") << 6; + QTest::newRow("ip6_05") << QString("::1") << (bool)TRUE << QString("::1") << 6; + QTest::newRow("ip6_06") << QString("1::") << (bool)TRUE << QString("1::") << 6; + QTest::newRow("ip6_07") << QString("::") << (bool)TRUE << QString("::") << 6; + QTest::newRow("ip6_08") << QString("0:0:0:0:0:0:13.1.68.3") << (bool)TRUE << QString("::D01:4403") << 6; + QTest::newRow("ip6_09") << QString("::13.1.68.3") << (bool)TRUE << QString("::D01:4403") << 6; + QTest::newRow("ip6_10") << QString("0:0:0:0:0:FFFF:129.144.52.38") << (bool)TRUE << QString("::FFFF:8190:3426") << 6; + QTest::newRow("ip6_11") << QString("::FFFF:129.144.52.38") << (bool)TRUE << QString("::FFFF:8190:3426") << 6; + QTest::newRow("ip6_12") << QString("1::FFFF:129.144.52.38") << (bool)TRUE << QString("1::FFFF:8190:3426") << 6; + QTest::newRow("ip6_13") << QString("A:B::D:E") << (bool)TRUE << QString("A:B::D:E") << 6; + QTest::newRow("ip6_14") << QString("1080:0:1:0:8:800:200C:417A") << (bool)TRUE << QString("1080:0:1:0:8:800:200C:417A") << 6; + QTest::newRow("ip6_15") << QString("1080:0:1:0:8:800:200C:0") << (bool)TRUE << QString("1080:0:1:0:8:800:200C:0") << 6; + QTest::newRow("ip6_16") << QString("1080:0:1:0:8:800:0:0") << (bool)TRUE << QString("1080:0:1:0:8:800::") << 6; + QTest::newRow("ip6_17") << QString("1080:0:0:0:8:800:0:0") << (bool)TRUE << QString("1080::8:800:0:0") << 6; + QTest::newRow("ip6_18") << QString("0:1:1:1:8:800:0:0") << (bool)TRUE << QString("0:1:1:1:8:800::") << 6; + QTest::newRow("ip6_19") << QString("0:1:1:1:8:800:0:1") << (bool)TRUE << QString("0:1:1:1:8:800:0:1") << 6; QTest::newRow("error_00") << QString("foobarcom") << (bool)FALSE << QString() << 0; QTest::newRow("error_01") << QString("foo.bar.com") << (bool)FALSE << QString() << 0; @@ -329,16 +335,16 @@ void tst_QHostAddress::scopeId() { QHostAddress address("fe80::2e0:4cff:fefb:662a%eth0"); QCOMPARE(address.scopeId(), QString("eth0")); - QCOMPARE(address.toString().toLower(), QString("fe80:0:0:0:2e0:4cff:fefb:662a%eth0")); + QCOMPARE(address.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%eth0")); QHostAddress address2("fe80::2e0:4cff:fefb:662a"); QCOMPARE(address2.scopeId(), QString()); address2.setScopeId(QString("en0")); - QCOMPARE(address2.toString().toLower(), QString("fe80:0:0:0:2e0:4cff:fefb:662a%en0")); + QCOMPARE(address2.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%en0")); address2 = address; QCOMPARE(address2.scopeId(), QString("eth0")); - QCOMPARE(address2.toString().toLower(), QString("fe80:0:0:0:2e0:4cff:fefb:662a%eth0")); + QCOMPARE(address2.toString().toLower(), QString("fe80::2e0:4cff:fefb:662a%eth0")); } void tst_QHostAddress::hashKey() diff --git a/tests/auto/qimage/tst_qimage.cpp b/tests/auto/qimage/tst_qimage.cpp index c5ded0d..ad85bf5 100644 --- a/tests/auto/qimage/tst_qimage.cpp +++ b/tests/auto/qimage/tst_qimage.cpp @@ -151,6 +151,7 @@ private slots: void rgbSwapped(); void deepCopyWhenPaintingActive(); + void scaled_QTBUG19157(); }; tst_QImage::tst_QImage() @@ -2029,5 +2030,12 @@ void tst_QImage::deepCopyWhenPaintingActive() QVERIFY(copy != image); } +void tst_QImage::scaled_QTBUG19157() +{ + QImage foo(5000, 1, QImage::Format_RGB32); + foo = foo.scaled(1024, 1024, Qt::KeepAspectRatio); + QVERIFY(!foo.isNull()); +} + QTEST_MAIN(tst_QImage) #include "tst_qimage.moc" diff --git a/tests/auto/qinputdialog/tst_qinputdialog.cpp b/tests/auto/qinputdialog/tst_qinputdialog.cpp index 1d13eb6..e0317df 100644 --- a/tests/auto/qinputdialog/tst_qinputdialog.cpp +++ b/tests/auto/qinputdialog/tst_qinputdialog.cpp @@ -193,12 +193,12 @@ void testGetNumeric(QInputDialog *dialog, SpinBoxType * = 0, ValueType * = 0) void testGetText(QInputDialog *dialog) { QLineEdit *ledit = qFindChild<QLineEdit *>(dialog); - Q_ASSERT(ledit); + QVERIFY(ledit); QDialogButtonBox *bbox = qFindChild<QDialogButtonBox *>(dialog); - Q_ASSERT(bbox); + QVERIFY(bbox); QPushButton *okButton = bbox->button(QDialogButtonBox::Ok); - Q_ASSERT(okButton); + QVERIFY(okButton); QVERIFY(ledit->hasAcceptableInput()); QCOMPARE(ledit->selectedText(), ledit->text()); @@ -211,12 +211,12 @@ void testGetText(QInputDialog *dialog) void testGetItem(QInputDialog *dialog) { QComboBox *cbox = qFindChild<QComboBox *>(dialog); - Q_ASSERT(cbox); + QVERIFY(cbox); QDialogButtonBox *bbox = qFindChild<QDialogButtonBox *>(dialog); - Q_ASSERT(bbox); + QVERIFY(bbox); QPushButton *okButton = bbox->button(QDialogButtonBox::Ok); - Q_ASSERT(okButton); + QVERIFY(okButton); QVERIFY(okButton->isEnabled()); const int origIndex = cbox->currentIndex(); @@ -249,7 +249,7 @@ void tst_QInputDialog::timerEvent(QTimerEvent *event) { killTimer(event->timerId()); QInputDialog *dialog = qFindChild<QInputDialog *>(parent); - Q_ASSERT(dialog); + QVERIFY(dialog); if (testFunc) testFunc(dialog); dialog->done(doneCode); // cause static function call to return @@ -270,7 +270,7 @@ void tst_QInputDialog::getInteger() { QFETCH(int, min); QFETCH(int, max); - Q_ASSERT(min < max); + QVERIFY(min < max); parent = new QWidget; doneCode = QDialog::Accepted; testFunc = &tst_QInputDialog::testFuncGetInteger; @@ -310,7 +310,7 @@ void tst_QInputDialog::getDouble() QFETCH(double, min); QFETCH(double, max); QFETCH(int, decimals); - Q_ASSERT(min < max && decimals >= 0 && decimals <= 13); + QVERIFY(min < max && decimals >= 0 && decimals <= 13); parent = new QWidget; doneCode = QDialog::Accepted; testFunc = &tst_QInputDialog::testFuncGetDouble; diff --git a/tests/auto/qitemmodel/modelstotest.cpp b/tests/auto/qitemmodel/modelstotest.cpp index c4c2cbb..df06c95 100644 --- a/tests/auto/qitemmodel/modelstotest.cpp +++ b/tests/auto/qitemmodel/modelstotest.cpp @@ -227,7 +227,6 @@ QAbstractItemModel *ModelsToTest::createModel(const QString &modelType) return widget->model(); } - Q_ASSERT(false); return 0; } @@ -309,15 +308,23 @@ QModelIndex ModelsToTest::populateTestArea(QAbstractItemModel *model) */ } QModelIndex returnIndex = model->index(0,0); - Q_ASSERT(returnIndex.isValid()); + if (!returnIndex.isValid()) + qFatal("%s: model index to be returned is invalid", Q_FUNC_INFO); return returnIndex; } if (QDirModel *dirModel = qobject_cast<QDirModel *>(model)) { - // Don't risk somthing bad happening, assert if this fails - Q_ASSERT(QDir(QDir::currentPath()).mkdir("test")); - for (int i = 0; i < 26; ++i) - Q_ASSERT(QDir(QDir::currentPath()).mkdir(QString("test/foo_%1").arg(i))); + if (!QDir::current().mkdir("test")) + qFatal("%s: cannot create directory %s", + Q_FUNC_INFO, + qPrintable(QDir::toNativeSeparators(QDir::currentPath()+"/test"))); + for (int i = 0; i < 26; ++i) { + QString subdir = QString("test/foo_%1").arg(i); + if (!QDir::current().mkdir(subdir)) + qFatal("%s: cannot create directory %s", + Q_FUNC_INFO, + qPrintable(QDir::toNativeSeparators(QDir::currentPath()+"/"+subdir))); + } return dirModel->index(QDir::currentPath()+"/test"); } @@ -373,7 +380,7 @@ QModelIndex ModelsToTest::populateTestArea(QAbstractItemModel *model) return QModelIndex(); } - Q_ASSERT(false); + qFatal("%s: unknown type of model", Q_FUNC_INFO); return QModelIndex(); } @@ -387,9 +394,17 @@ void ModelsToTest::cleanupTestArea(QAbstractItemModel *model) { if (QDir(QDir::currentPath()+"/test").exists()) { - for (int i = 0; i < 26; ++i) - QDir::current().rmdir(QString("test/foo_%1").arg(i)); - Q_ASSERT(QDir::current().rmdir("test")); + for (int i = 0; i < 26; ++i) { + QString subdir(QString("test/foo_%1").arg(i)); + if (!QDir::current().rmdir(subdir)) + qFatal("%s: cannot remove directory %s", + Q_FUNC_INFO, + qPrintable(QDir::toNativeSeparators(QDir::currentPath()+"/"+subdir))); + } + if (!QDir::current().rmdir("test")) + qFatal("%s: cannot remove directory %s", + Q_FUNC_INFO, + qPrintable(QDir::toNativeSeparators(QDir::currentPath()+"/test"))); } } else if (qobject_cast<QSqlQueryModel *>(model)) { QSqlQuery q("DROP TABLE test"); diff --git a/tests/auto/qitemmodel/tst_qitemmodel.cpp b/tests/auto/qitemmodel/tst_qitemmodel.cpp index 7e177ba..9482853 100644 --- a/tests/auto/qitemmodel/tst_qitemmodel.cpp +++ b/tests/auto/qitemmodel/tst_qitemmodel.cpp @@ -199,6 +199,7 @@ void tst_QItemModel::nonDestructiveBasicTest() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QCOMPARE(currentModel->buddy(QModelIndex()), QModelIndex()); currentModel->canFetchMore(QModelIndex()); @@ -244,6 +245,7 @@ void tst_QItemModel::rowCount() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QFETCH(bool, isEmpty); if (isEmpty) { @@ -291,6 +293,7 @@ void tst_QItemModel::columnCount() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QFETCH(bool, isEmpty); if (isEmpty) { @@ -325,6 +328,7 @@ void tst_QItemModel::hasIndex() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); // Make sure that invalid values returns an invalid index QCOMPARE(currentModel->hasIndex(-2, -2), false); @@ -359,6 +363,7 @@ void tst_QItemModel::index() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); // Make sure that invalid values returns an invalid index QCOMPARE(currentModel->index(-2, -2), QModelIndex()); @@ -489,6 +494,7 @@ void tst_QItemModel::parent() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); // Make sure the model wont crash and will return an invalid QModelIndex // when asked for the parent of an invalid index. @@ -538,6 +544,7 @@ void tst_QItemModel::data() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); // Invalid index should return an invalid qvariant QVERIFY(!currentModel->data(QModelIndex()).isValid()); @@ -618,6 +625,7 @@ void tst_QItemModel::setData() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); qRegisterMetaType<QModelIndex>("QModelIndex"); QSignalSpy spy(currentModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &))); QCOMPARE(currentModel->setData(QModelIndex(), QVariant()), false); @@ -660,6 +668,7 @@ void tst_QItemModel::setHeaderData() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QCOMPARE(currentModel->setHeaderData(-1, Qt::Horizontal, QVariant()), false); QCOMPARE(currentModel->setHeaderData(-1, Qt::Vertical, QVariant()), false); @@ -708,6 +717,7 @@ void tst_QItemModel::sort() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QFETCH(bool, isEmpty); if (isEmpty) @@ -819,6 +829,7 @@ void tst_QItemModel::remove() QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QFETCH(bool, readOnly); if (readOnly) @@ -1160,6 +1171,7 @@ void tst_QItemModel::insert() { QFETCH(QString, modelType); currentModel = testModels->createModel(modelType); + QVERIFY(currentModel); QFETCH(bool, readOnly); if (readOnly) diff --git a/tests/auto/qitemview/tst_qitemview.cpp b/tests/auto/qitemview/tst_qitemview.cpp index 220a174..fa8367e 100644 --- a/tests/auto/qitemview/tst_qitemview.cpp +++ b/tests/auto/qitemview/tst_qitemview.cpp @@ -148,12 +148,18 @@ public: CheckerModel() : QStandardItemModel() {}; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole ) const { - Q_ASSERT(index.isValid()); + if (!index.isValid()) { + qWarning("%s: index is not valid", Q_FUNC_INFO); + return QVariant(); + } return QStandardItemModel::data(index, role); }; Qt::ItemFlags flags(const QModelIndex & index) const { - Q_ASSERT(index.isValid()); + if (!index.isValid()) { + qWarning("%s: index is not valid", Q_FUNC_INFO); + return Qt::ItemFlags(); + } if (index.row() == 2 || index.row() == rowCount() - 3 || index.column() == 2 || index.column() == columnCount() - 3) { Qt::ItemFlags f = QStandardItemModel::flags(index); @@ -164,14 +170,26 @@ public: }; QModelIndex parent ( const QModelIndex & child ) const { - Q_ASSERT(child.isValid()); + if (!child.isValid()) { + qWarning("%s: child index is not valid", Q_FUNC_INFO); + return QModelIndex(); + } return QStandardItemModel::parent(child); }; QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const { - Q_ASSERT(section >= 0); - if (orientation == Qt::Horizontal) { Q_ASSERT(section <= columnCount());}; - if (orientation == Qt::Vertical) { Q_ASSERT(section <= rowCount());}; + if (orientation == Qt::Horizontal + && (section < 0 || section > columnCount())) { + qWarning("%s: invalid section %d, must be in range 0..%d", + Q_FUNC_INFO, section, columnCount()); + return QVariant(); + } + if (orientation == Qt::Vertical + && (section < 0 || section > rowCount())) { + qWarning("%s: invalid section %d, must be in range 0..%d", + Q_FUNC_INFO, section, rowCount()); + return QVariant(); + } return QStandardItemModel::headerData(section, orientation, role); } @@ -180,23 +198,46 @@ public: }; bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole ) { - Q_ASSERT(index.isValid()); + if (!index.isValid()) { + qWarning("%s: index is not valid", Q_FUNC_INFO); + return false; + } return QStandardItemModel::setData(index, value, role); } void sort( int column, Qt::SortOrder order = Qt::AscendingOrder ) { - Q_ASSERT(column >= 0 && column <= columnCount()); - QStandardItemModel::sort(column, order); + if (column < 0 || column > columnCount()) + qWarning("%s: invalid column %d, must be in range 0..%d", + Q_FUNC_INFO, column, columnCount()); + else + QStandardItemModel::sort(column, order); }; QModelIndexList match ( const QModelIndex & start, int role, const QVariant & value, int hits = 1, Qt::MatchFlags flags = Qt::MatchFlags( Qt::MatchStartsWith | Qt::MatchWrap ) ) const { - Q_ASSERT(hits > 0); - Q_ASSERT(value.isValid()); + if (hits <= 0) { + qWarning("%s: hits must be greater than zero", Q_FUNC_INFO); + return QModelIndexList(); + } + if (!value.isValid()) { + qWarning("%s: value is not valid", Q_FUNC_INFO); + return QModelIndexList(); + } return QAbstractItemModel::match(start, role, value, hits, flags); }; bool setHeaderData ( int section, Qt::Orientation orientation, const QVariant & value, int role = Qt::EditRole ) { - Q_ASSERT(section >= 0); + if (orientation == Qt::Horizontal + && (section < 0 || section > columnCount())) { + qWarning("%s: invalid section %d, must be in range 0..%d", + Q_FUNC_INFO, section, columnCount()); + return false; + } + if (orientation == Qt::Vertical + && (section < 0 || section > rowCount())) { + qWarning("%s: invalid section %d, must be in range 0..%d", + Q_FUNC_INFO, section, rowCount()); + return false; + } return QAbstractItemModel::setHeaderData(section, orientation, value, role); }; }; @@ -297,9 +338,11 @@ void tst_QItemView::nonDestructiveBasicTest() #endif QFETCH(QString, viewType); - view = testViews->createView(viewType); QFETCH(int, vscroll); QFETCH(int, hscroll); + + view = testViews->createView(viewType); + QVERIFY(view); view->setVerticalScrollMode((QAbstractItemView::ScrollMode)vscroll); view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll); @@ -454,9 +497,11 @@ void tst_QItemView::spider() QSKIP("This test takes too long to execute on IRIX", SkipAll); #endif QFETCH(QString, viewType); - view = testViews->createView(viewType); QFETCH(int, vscroll); QFETCH(int, hscroll); + + view = testViews->createView(viewType); + QVERIFY(view); view->setVerticalScrollMode((QAbstractItemView::ScrollMode)vscroll); view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll); view->setModel(treeModel); @@ -489,9 +534,11 @@ void tst_QItemView::resize() // This test needs to be re-thought out, it takes too long and // doesn't really catch theproblem. QFETCH(QString, viewType); - view = testViews->createView(viewType); QFETCH(int, vscroll); QFETCH(int, hscroll); + + view = testViews->createView(viewType); + QVERIFY(view); view->setVerticalScrollMode((QAbstractItemView::ScrollMode)vscroll); view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll); view->setModel(treeModel); @@ -517,9 +564,11 @@ void tst_QItemView::visualRect() QSKIP("This test takes too long to execute on IRIX", SkipAll); #endif QFETCH(QString, viewType); - view = testViews->createView(viewType); QFETCH(int, vscroll); QFETCH(int, hscroll); + + view = testViews->createView(viewType); + QVERIFY(view); view->setVerticalScrollMode((QAbstractItemView::ScrollMode)vscroll); view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll); QCOMPARE(view->visualRect(QModelIndex()), QRect()); @@ -651,9 +700,11 @@ void tst_QItemView::indexAt() QSKIP("This test takes too long to execute on IRIX", SkipAll); #endif QFETCH(QString, viewType); - view = testViews->createView(viewType); QFETCH(int, vscroll); QFETCH(int, hscroll); + + view = testViews->createView(viewType); + QVERIFY(view); view->setVerticalScrollMode((QAbstractItemView::ScrollMode)vscroll); view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll); view->show(); @@ -685,9 +736,11 @@ void tst_QItemView::scrollTo() QSKIP("This test takes too long to execute on IRIX", SkipAll); #endif QFETCH(QString, viewType); - view = testViews->createView(viewType); QFETCH(int, vscroll); QFETCH(int, hscroll); + + view = testViews->createView(viewType); + QVERIFY(view); view->setVerticalScrollMode((QAbstractItemView::ScrollMode)vscroll); view->setHorizontalScrollMode((QAbstractItemView::ScrollMode)hscroll); view->setModel(treeModel); @@ -735,6 +788,7 @@ void tst_QItemView::moveCursor() #endif QFETCH(QString, viewType); view = testViews->createView(viewType); + QVERIFY(view); if (view->objectName() == "QHeaderView") return; diff --git a/tests/auto/qitemview/viewstotest.cpp b/tests/auto/qitemview/viewstotest.cpp index 3aa355d..5e21daf 100644 --- a/tests/auto/qitemview/viewstotest.cpp +++ b/tests/auto/qitemview/viewstotest.cpp @@ -141,7 +141,6 @@ QAbstractItemView *ViewsToTest::createView(const QString &viewType) view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); view->setSelectionBehavior(QAbstractItemView::SelectItems); } - Q_ASSERT(view); return view; } diff --git a/tests/auto/qlibrary/tst_qlibrary.cpp b/tests/auto/qlibrary/tst_qlibrary.cpp index c79332d..a8c60c9 100644 --- a/tests/auto/qlibrary/tst_qlibrary.cpp +++ b/tests/auto/qlibrary/tst_qlibrary.cpp @@ -468,7 +468,7 @@ void tst_QLibrary::errorString() } break;} default: - Q_ASSERT(0); + QFAIL(qPrintable(QString("Unknown operation: %1").arg(operation))); break; } QRegExp re(errorString); diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index 9176174..d5d9029 100644 --- a/tests/auto/qlineedit/tst_qlineedit.cpp +++ b/tests/auto/qlineedit/tst_qlineedit.cpp @@ -282,6 +282,12 @@ private slots: void validateAndSet(); #endif + void bidiVisualMovement_data(); + void bidiVisualMovement(); + + void bidiLogicalMovement_data(); + void bidiLogicalMovement(); + protected slots: #ifdef QT3_SUPPORT void lostFocus(); @@ -3760,5 +3766,135 @@ void tst_QLineEdit::QTBUG13520_textNotVisible() } +void tst_QLineEdit::bidiVisualMovement_data() +{ + QTest::addColumn<QString>("logical"); + QTest::addColumn<int>("basicDir"); + QTest::addColumn<IntList>("positionList"); + + QTest::newRow("Latin text") + << QString::fromUtf8("abc") + << (int) QChar::DirL + << (IntList() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text, one item") + << QString::fromUtf8("\327\220\327\221\327\222") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text after Latin text") + << QString::fromUtf8("abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3); + QTest::newRow("Latin text after Hebrew text") + << QString::fromUtf8("\327\220\327\221\327\222abc") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3); + QTest::newRow("LTR, 3 items") + << QString::fromUtf8("abc\327\220\327\221\327\222abc") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9); + QTest::newRow("RTL, 3 items") + << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9); + QTest::newRow("LTR, 4 items") + << QString::fromUtf8("abc\327\220\327\221\327\222abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9); + QTest::newRow("RTL, 4 items") + << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222abc") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9); +} + +void tst_QLineEdit::bidiVisualMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + QFETCH(IntList, positionList); + + QLineEdit le; + le.setText(logical); + + le.setCursorMoveStyle(Qt::VisualMoveStyle); + le.setCursorPosition(0); + + bool moved; + int i = 0, oldPos, newPos = 0; + + do { + oldPos = newPos; + QVERIFY(oldPos == positionList[i]); + if (basicDir == QChar::DirL) { + QTest::keyClick(&le, Qt::Key_Right); + } else + QTest::keyClick(&le, Qt::Key_Left); + newPos = le.cursorPosition(); + moved = (oldPos != newPos); + i++; + } while (moved); + + QVERIFY(i == positionList.size()); + + do { + i--; + oldPos = newPos; + QVERIFY(oldPos == positionList[i]); + if (basicDir == QChar::DirL) { + QTest::keyClick(&le, Qt::Key_Left); + } else + { + QTest::keyClick(&le, Qt::Key_Right); + } + newPos = le.cursorPosition(); + moved = (oldPos != newPos); + } while (moved && i >= 0); +} + +void tst_QLineEdit::bidiLogicalMovement_data() +{ + bidiVisualMovement_data(); +} + +void tst_QLineEdit::bidiLogicalMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + + QLineEdit le; + le.setText(logical); + + le.setCursorMoveStyle(Qt::LogicalMoveStyle); + le.setCursorPosition(0); + + bool moved; + int i = 0, oldPos, newPos = 0; + + do { + oldPos = newPos; + QVERIFY(oldPos == i); + if (basicDir == QChar::DirL) { + QTest::keyClick(&le, Qt::Key_Right); + } else + QTest::keyClick(&le, Qt::Key_Left); + newPos = le.cursorPosition(); + moved = (oldPos != newPos); + i++; + } while (moved); + + do { + i--; + oldPos = newPos; + QVERIFY(oldPos == i); + if (basicDir == QChar::DirL) { + QTest::keyClick(&le, Qt::Key_Left); + } else + { + QTest::keyClick(&le, Qt::Key_Right); + } + newPos = le.cursorPosition(); + moved = (oldPos != newPos); + } while (moved && i >= 0); +} + QTEST_MAIN(tst_QLineEdit) #include "tst_qlineedit.moc" diff --git a/tests/auto/qlocale/tst_qlocale.cpp b/tests/auto/qlocale/tst_qlocale.cpp index 2b7eaae..2ffc9e9 100644 --- a/tests/auto/qlocale/tst_qlocale.cpp +++ b/tests/auto/qlocale/tst_qlocale.cpp @@ -326,7 +326,7 @@ void tst_QLocale::ctor() TEST_CTOR("en-GB", English, UnitedKingdom) TEST_CTOR("en-GB@bla", English, UnitedKingdom) - Q_ASSERT(QLocale::Norwegian == QLocale::NorwegianBokmal); + QVERIFY(QLocale::Norwegian == QLocale::NorwegianBokmal); TEST_CTOR("no", Norwegian, Norway) TEST_CTOR("nb", Norwegian, Norway) TEST_CTOR("nn", NorwegianNynorsk, Norway) @@ -431,7 +431,7 @@ void tst_QLocale::emptyCtor() TEST_CTOR("en_GB@bla", "en_GB") TEST_CTOR("de", "de_DE") - Q_ASSERT(QLocale::Norwegian == QLocale::NorwegianBokmal); + QVERIFY(QLocale::Norwegian == QLocale::NorwegianBokmal); TEST_CTOR("no", "nb_NO") TEST_CTOR("nb", "nb_NO") TEST_CTOR("nn", "nn_NO") diff --git a/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/simple/main.cpp b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/simple/main.cpp new file mode 100644 index 0000000..a023aa6 --- /dev/null +++ b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/simple/main.cpp @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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$ +** +****************************************************************************/ + + +int main(int,char**) +{ +} diff --git a/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/simple/simple.pro b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/simple/simple.pro new file mode 100644 index 0000000..2db08a2 --- /dev/null +++ b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/simple/simple.pro @@ -0,0 +1,5 @@ +TEMPLATE = app +SOURCES = main.cpp + +extratarget.commands = @echo extra target worked OK +QMAKE_EXTRA_TARGETS += extratarget diff --git a/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/subdir.pro b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/subdir.pro new file mode 100644 index 0000000..be0d80a --- /dev/null +++ b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/subdir.pro @@ -0,0 +1,7 @@ +TEMPLATE = subdirs +SUBDIRS = simple + +extratarget.CONFIG = recursive +extratarget.recurse = $$SUBDIRS +extratarget.recurse_target = extratarget +QMAKE_EXTRA_TARGETS += extratarget diff --git a/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/subdir_via_pro_file_extra_target.pro b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/subdir_via_pro_file_extra_target.pro new file mode 100644 index 0000000..7c07859 --- /dev/null +++ b/tests/auto/qmake/testdata/subdir_via_pro_file_extra_target/subdir_via_pro_file_extra_target.pro @@ -0,0 +1,7 @@ +TEMPLATE = subdirs +SUBDIRS = subdir.pro + +extratarget.CONFIG = recursive +extratarget.recurse = $$SUBDIRS +extratarget.recurse_target = extratarget +QMAKE_EXTRA_TARGETS += extratarget diff --git a/tests/auto/qmake/tst_qmake.cpp b/tests/auto/qmake/tst_qmake.cpp index 81a51e1..afd28e1 100644 --- a/tests/auto/qmake/tst_qmake.cpp +++ b/tests/auto/qmake/tst_qmake.cpp @@ -69,6 +69,7 @@ private slots: void simple_lib(); void simple_dll(); void subdirs(); + void subdir_via_pro_file_extra_target(); void functions(); void operators(); void variables(); @@ -234,6 +235,19 @@ void tst_qmake::subdirs() QVERIFY( test_compiler.removeMakefile( workDir ) ); } +void tst_qmake::subdir_via_pro_file_extra_target() +{ + QString workDir = base_path + "/testdata/subdir_via_pro_file_extra_target"; + + QDir D; + D.remove( workDir + "/Makefile"); + D.remove( workDir + "/Makefile.subdir"); + D.remove( workDir + "/simple/Makefile"); + D.remove( workDir + "/simple/Makefile.subdir"); + QVERIFY( test_compiler.qmake( workDir, "subdir_via_pro_file_extra_target" )); + QVERIFY( test_compiler.make( workDir, "extratarget" )); +} + void tst_qmake::functions() { QString workDir = base_path + "/testdata/functions"; diff --git a/tests/auto/qmenu/tst_qmenu.cpp b/tests/auto/qmenu/tst_qmenu.cpp index 1367e1f..c31361d 100644 --- a/tests/auto/qmenu/tst_qmenu.cpp +++ b/tests/auto/qmenu/tst_qmenu.cpp @@ -789,7 +789,7 @@ void tst_QMenu::task250673_activeMultiColumnSubMenuPosition() while (main.columnCount() < 2) { main.addAction(QString("Item %1").arg(i)); ++i; - Q_ASSERT(i<1000); + QVERIFY(i<1000); } main.setActiveAction(menuAction); sub.setActiveAction(subAction); diff --git a/tests/auto/qmessagebox/tst_qmessagebox.cpp b/tests/auto/qmessagebox/tst_qmessagebox.cpp index c11e76c..ed121ce 100644 --- a/tests/auto/qmessagebox/tst_qmessagebox.cpp +++ b/tests/auto/qmessagebox/tst_qmessagebox.cpp @@ -609,48 +609,43 @@ void tst_QMessageBox::testSymbols() button = QMessageBox::FlagMask; mb1.setText("Foo"); - QString text = mb1.text(); - Q_ASSERT(text == "Foo"); + QCOMPARE(mb1.text(), "Foo"); icon = mb1.icon(); - Q_ASSERT(icon == QMessageBox::NoIcon); + QVERIFY(icon == QMessageBox::NoIcon); mb1.setIcon(QMessageBox::Question); - Q_ASSERT(mb1.icon() == QMessageBox::Question); + QVERIFY(mb1.icon() == QMessageBox::Question); QPixmap iconPixmap = mb1.iconPixmap(); mb1.setIconPixmap(iconPixmap); - Q_ASSERT(mb1.icon() == QMessageBox::NoIcon); + QVERIFY(mb1.icon() == QMessageBox::NoIcon); - QString bt0 = mb1.buttonText(QMessageBox::Ok); - QString bt1 = mb1.buttonText(QMessageBox::Cancel); - QString bt2 = mb1.buttonText(QMessageBox::Ok | QMessageBox::Default); - - Q_ASSERT(bt0 == "OK"); - Q_ASSERT(bt1.isEmpty()); - Q_ASSERT(bt2.isEmpty()); + QCOMPARE(mb1.buttonText(QMessageBox::Ok), "OK"); + QCOMPARE(mb1.buttonText(QMessageBox::Cancel), QString()); + QCOMPARE(mb1.buttonText(QMessageBox::Ok | QMessageBox::Default), QString()); mb2.setButtonText(QMessageBox::Cancel, "Foo"); mb2.setButtonText(QMessageBox::Ok, "Bar"); mb2.setButtonText(QMessageBox::Ok | QMessageBox::Default, "Baz"); - Q_ASSERT(mb2.buttonText(QMessageBox::Cancel).isEmpty()); - Q_ASSERT(mb2.buttonText(QMessageBox::Ok) == "Bar"); + QCOMPARE(mb2.buttonText(QMessageBox::Cancel), QString()); + QCOMPARE(mb2.buttonText(QMessageBox::Ok), "Bar"); - Q_ASSERT(mb3b.buttonText(QMessageBox::Yes).endsWith("Yes")); - Q_ASSERT(mb3b.buttonText(QMessageBox::YesAll).isEmpty()); - Q_ASSERT(mb3b.buttonText(QMessageBox::Ok).isEmpty()); + QVERIFY(mb3b.buttonText(QMessageBox::Yes).endsWith("Yes")); + QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString()); + QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString()); mb3b.setButtonText(QMessageBox::Yes, "Blah"); mb3b.setButtonText(QMessageBox::YesAll, "Zoo"); mb3b.setButtonText(QMessageBox::Ok, "Zoo"); - Q_ASSERT(mb3b.buttonText(QMessageBox::Yes) == "Blah"); - Q_ASSERT(mb3b.buttonText(QMessageBox::YesAll).isEmpty()); - Q_ASSERT(mb3b.buttonText(QMessageBox::Ok).isEmpty()); + QCOMPARE(mb3b.buttonText(QMessageBox::Yes), "Blah"); + QCOMPARE(mb3b.buttonText(QMessageBox::YesAll), QString()); + QCOMPARE(mb3b.buttonText(QMessageBox::Ok), QString()); - Q_ASSERT(mb1.textFormat() == Qt::AutoText); + QCOMPARE(mb1.textFormat(), Qt::AutoText); mb1.setTextFormat(Qt::PlainText); - Q_ASSERT(mb1.textFormat() == Qt::PlainText); + QCOMPARE(mb1.textFormat(), Qt::PlainText); CONVENIENCE_FUNC_SYMS(information); CONVENIENCE_FUNC_SYMS_EXTRA(information); @@ -660,7 +655,7 @@ void tst_QMessageBox::testSymbols() CONVENIENCE_FUNC_SYMS(critical); QSize sizeHint = mb1.sizeHint(); - Q_ASSERT(sizeHint.width() > 20 && sizeHint.height() > 20); + QVERIFY(sizeHint.width() > 20 && sizeHint.height() > 20); #ifdef QT3_SUPPORT //test QT3_SUPPORT stuff @@ -672,8 +667,8 @@ void tst_QMessageBox::testSymbols() QPixmap pm = QMessageBox::standardIcon(QMessageBox::Question, Qt::GUIStyle(1)); QPixmap pm2 = QMessageBox::standardIcon(QMessageBox::Question); - Q_ASSERT(pm.toImage() == iconPixmap.toImage()); - Q_ASSERT(pm2.toImage() == iconPixmap.toImage()); + QVERIFY(pm.toImage() == iconPixmap.toImage()); + QVERIFY(pm2.toImage() == iconPixmap.toImage()); int ret1 = QMessageBox::message("title", "text"); int ret2 = QMessageBox::message("title", "text", "OK"); @@ -692,10 +687,10 @@ void tst_QMessageBox::testSymbols() Q_UNUSED(ret5); QPixmap pm3 = QMessageBox::standardIcon(QMessageBox::NoIcon); - Q_ASSERT(pm3.isNull()); + QVERIFY(pm3.isNull()); pm3 = QMessageBox::standardIcon(QMessageBox::Information); - Q_ASSERT(!pm3.isNull()); + QVERIFY(!pm3.isNull()); #endif //QT3_SUPPORT QMessageBox::about(&mb1, "title", "text"); diff --git a/tests/auto/qmetaobject/tst_qmetaobject.cpp b/tests/auto/qmetaobject/tst_qmetaobject.cpp index 13e3bcd..f1a909a 100644 --- a/tests/auto/qmetaobject/tst_qmetaobject.cpp +++ b/tests/auto/qmetaobject/tst_qmetaobject.cpp @@ -244,7 +244,12 @@ public: QObject *child; public slots: - void on_child1_destroyed(QObject *obj = 0) { ++invokeCount1; Q_ASSERT(obj && obj == child); } + void on_child1_destroyed(QObject *obj = 0) + { + ++invokeCount1; + if (!obj || obj != child) + qWarning() << "on_child1_destroyed invoked with wrong child object"; + } void on_child2_destroyed() { ++invokeCount2; } }; @@ -268,7 +273,12 @@ public: } private slots: - void on_child1_destroyed(QObject *obj) { ++invokeCount1; Q_ASSERT(obj && obj == child); } + void on_child1_destroyed(QObject *obj) + { + ++invokeCount1; + if (!obj || obj != child) + qWarning() << "on_child1_destroyed invoked with wrong child object"; + } void on_child1_destroyed() { ++invokeCount2; } }; diff --git a/tests/auto/qmetatype/tst_qmetatype.cpp b/tests/auto/qmetatype/tst_qmetatype.cpp index 67bbac2..ccf0ac5 100644 --- a/tests/auto/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/qmetatype/tst_qmetatype.cpp @@ -96,10 +96,18 @@ struct Bar Bar() { // check re-entrancy - Q_ASSERT(QMetaType::isRegistered(qRegisterMetaType<Foo>("Foo"))); + if (!QMetaType::isRegistered(qRegisterMetaType<Foo>("Foo"))) { + qWarning("%s: re-entrancy test failed", Q_FUNC_INFO); + ++failureCount; + } } + +public: + static int failureCount; }; +int Bar::failureCount = 0; + class MetaTypeTorturer: public QThread { Q_OBJECT @@ -113,17 +121,35 @@ protected: #ifdef Q_OS_LINUX pthread_yield(); #endif - Q_ASSERT(QMetaType::isRegistered(tp)); - Q_ASSERT(QMetaType::type(nm) == tp); - Q_ASSERT(QMetaType::typeName(tp) == name); + if (!QMetaType::isRegistered(tp)) { + ++failureCount; + qWarning() << name << "is not a registered metatype"; + } + if (QMetaType::type(nm) != tp) { + ++failureCount; + qWarning() << "Wrong metatype returned for" << name; + } + if (QMetaType::typeName(tp) != name) { + ++failureCount; + qWarning() << "Wrong typeName returned for" << tp; + } void *buf = QMetaType::construct(tp, 0); void *buf2 = QMetaType::construct(tp, buf); - Q_ASSERT(buf); - Q_ASSERT(buf2); + if (!buf) { + ++failureCount; + qWarning() << "Null buffer returned by QMetaType::construct(tp, 0)"; + } + if (!buf2) { + ++failureCount; + qWarning() << "Null buffer returned by QMetaType::construct(tp, buf)"; + } QMetaType::destroy(tp, buf); QMetaType::destroy(tp, buf2); } } +public: + MetaTypeTorturer() : failureCount(0) { } + int failureCount; }; void tst_QMetaType::threadSafety() @@ -139,6 +165,11 @@ void tst_QMetaType::threadSafety() QVERIFY(t1.wait()); QVERIFY(t2.wait()); QVERIFY(t3.wait()); + + QCOMPARE(t1.failureCount, 0); + QCOMPARE(t2.failureCount, 0); + QCOMPARE(t3.failureCount, 0); + QCOMPARE(Bar::failureCount, 0); } namespace TestSpace diff --git a/tests/auto/qmutex/tst_qmutex.cpp b/tests/auto/qmutex/tst_qmutex.cpp index a8c4b37..c3b3575 100644 --- a/tests/auto/qmutex/tst_qmutex.cpp +++ b/tests/auto/qmutex/tst_qmutex.cpp @@ -462,6 +462,7 @@ public: static QBasicAtomicInt lockCount; static QBasicAtomicInt sentinel; static QMutex mutex; + static int errorCount; void start() { t.start(); @@ -471,13 +472,13 @@ public: { while (t.elapsed() < one_minute) { mutex.lock(); - Q_ASSERT(!sentinel.ref()); - Q_ASSERT(sentinel.deref()); + if (sentinel.ref()) ++errorCount; + if (!sentinel.deref()) ++errorCount; lockCount.ref(); mutex.unlock(); if (mutex.tryLock()) { - Q_ASSERT(!sentinel.ref()); - Q_ASSERT(sentinel.deref()); + if (sentinel.ref()) ++errorCount; + if (!sentinel.deref()) ++errorCount; lockCount.ref(); mutex.unlock(); } @@ -487,6 +488,7 @@ public: QMutex StressTestThread::mutex; QBasicAtomicInt StressTestThread::lockCount = Q_BASIC_ATOMIC_INITIALIZER(0); QBasicAtomicInt StressTestThread::sentinel = Q_BASIC_ATOMIC_INITIALIZER(-1); +int StressTestThread::errorCount = 0; void tst_QMutex::stressTest() { @@ -496,6 +498,7 @@ void tst_QMutex::stressTest() QVERIFY(threads[0].wait(one_minute + 10000)); for (int i = 1; i < threadCount; ++i) QVERIFY(threads[i].wait(10000)); + QCOMPARE(StressTestThread::errorCount, 0); qDebug("locked %d times", int(StressTestThread::lockCount)); } @@ -534,7 +537,12 @@ void tst_QMutex::tryLockRace() TryLockRaceThread::mutex.unlock(); } +// Variable that will be protected by the mutex. Volatile so that the +// the optimiser doesn't mess with it based on the increment-then-decrement +// usage pattern. static volatile int qtbug16115_trylock_counter; +// Counter for how many times the protected variable has an incorrect value. +static int qtbug16115_failure_count = 0; void tst_QMutex::qtbug16115_trylock() { @@ -545,8 +553,10 @@ void tst_QMutex::qtbug16115_trylock() void run() { for (int i = 0; i < 1000000; ++i) { if (mut.tryLock(0)) { - Q_ASSERT((++qtbug16115_trylock_counter) == 1); - Q_ASSERT((--qtbug16115_trylock_counter) == 0); + if ((++qtbug16115_trylock_counter) != 1) + ++qtbug16115_failure_count; + if ((--qtbug16115_trylock_counter) != 0) + ++qtbug16115_failure_count; mut.unlock(); } } @@ -562,13 +572,16 @@ void tst_QMutex::qtbug16115_trylock() for (int i = 0; i < 1000000; ++i) { mut.lock(); - Q_ASSERT((++qtbug16115_trylock_counter) == 1); - Q_ASSERT((--qtbug16115_trylock_counter) == 0); + if ((++qtbug16115_trylock_counter) != 1) + ++qtbug16115_failure_count; + if ((--qtbug16115_trylock_counter) != 0) + ++qtbug16115_failure_count; mut.unlock(); } t1.wait(); t2.wait(); t3.wait(); + QCOMPARE(qtbug16115_failure_count, 0); } QTEST_MAIN(tst_QMutex) diff --git a/tests/auto/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp b/tests/auto/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp index 7787608..8939ffe 100644 --- a/tests/auto/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp +++ b/tests/auto/qnetworkconfigurationmanager/tst_qnetworkconfigurationmanager.cpp @@ -62,6 +62,7 @@ public slots: void cleanup(); private slots: + void usedInThread(); // this test must be first, or it will falsely pass void allConfigurations(); void defaultConfiguration(); void configurationFromIdentifier(); @@ -329,6 +330,49 @@ void tst_QNetworkConfigurationManager::configurationFromIdentifier() QVERIFY(!invalid.isValid()); } +class QNCMTestThread : public QThread +{ +protected: + virtual void run() + { + QNetworkConfigurationManager manager; + preScanConfigs = manager.allConfigurations(); + QSignalSpy spy(&manager, SIGNAL(updateCompleted())); + manager.updateConfigurations(); //initiate scans + QTRY_VERIFY(spy.count() == 1); //wait for scan to complete + configs = manager.allConfigurations(); + } +public: + QList<QNetworkConfiguration> configs; + QList<QNetworkConfiguration> preScanConfigs; +}; + +// regression test for QTBUG-18795 +void tst_QNetworkConfigurationManager::usedInThread() +{ +#if defined Q_OS_MAC && !defined (QT_NO_COREWLAN) + QSKIP("QTBUG-19070 Mac CoreWlan plugin is broken", SkipAll); +#else + QNCMTestThread thread; + connect(&thread, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + thread.start(); + QTestEventLoop::instance().enterLoop(100); //QTRY_VERIFY could take ~90 seconds to time out in the thread + QVERIFY(!QTestEventLoop::instance().timeout()); + qDebug() << "prescan:" << thread.preScanConfigs.count(); + qDebug() << "postscan:" << thread.configs.count(); + + QNetworkConfigurationManager manager; + QList<QNetworkConfiguration> preScanConfigs = manager.allConfigurations(); + QSignalSpy spy(&manager, SIGNAL(updateCompleted())); + manager.updateConfigurations(); //initiate scans + QTRY_VERIFY(spy.count() == 1); //wait for scan to complete + QList<QNetworkConfiguration> configs = manager.allConfigurations(); + QCOMPARE(thread.configs, configs); + //Don't compare pre scan configs, because these may be cached and therefore give different results + //which makes the test unstable. The post scan results should have all configurations every time + //QCOMPARE(thread.preScanConfigs, preScanConfigs); +#endif +} QTEST_MAIN(tst_QNetworkConfigurationManager) #include "tst_qnetworkconfigurationmanager.moc" diff --git a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp index e0c477b..9a58482 100644 --- a/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp +++ b/tests/auto/qnetworkcookie/tst_qnetworkcookie.cpp @@ -182,6 +182,14 @@ void tst_QNetworkCookie::parseSingleCookie_data() cookie.setValue("\"\\\"a, b; c\\\"\""); QTest::newRow("with-value-with-special5") << "a = \"\\\"a, b; c\\\"\"" << cookie; + cookie.setValue("b c"); + QTest::newRow("with-value-with-whitespace") << "a = b c" << cookie; + + cookie.setValue("\"b\""); + QTest::newRow("quoted-value") << "a = \"b\"" << cookie; + cookie.setValue("\"b c\""); + QTest::newRow("quoted-value-with-whitespace") << "a = \"b c\"" << cookie; + cookie.setValue("b"); cookie.setSecure(true); QTest::newRow("secure") << "a=b;secure" << cookie; diff --git a/tests/auto/qnetworkproxyfactory/qnetworkproxyfactory.pro b/tests/auto/qnetworkproxyfactory/qnetworkproxyfactory.pro index f05c423..17ad403 100644 --- a/tests/auto/qnetworkproxyfactory/qnetworkproxyfactory.pro +++ b/tests/auto/qnetworkproxyfactory/qnetworkproxyfactory.pro @@ -7,5 +7,5 @@ QT = core network SOURCES += tst_qnetworkproxyfactory.cpp -symbian: TARGET.CAPABILITY = NetworkServices +symbian: TARGET.CAPABILITY = NetworkServices ReadUserData diff --git a/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp b/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp index 2baee27..7060c11 100644 --- a/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp +++ b/tests/auto/qnetworkproxyfactory/tst_qnetworkproxyfactory.cpp @@ -41,20 +41,62 @@ #include <QtTest/QTest> +#include <QtTest/QTestEventLoop> #include <qcoreapplication.h> #include <qdebug.h> #include <qnetworkproxy.h> +#include <QThread> +#include <QNetworkConfiguration> +#include <QNetworkConfigurationManager> +#include <QNetworkSession> +#include <QNetworkAccessManager> +#include <QNetworkReply> +#include <QNetworkRequest> +#include <QList> + +Q_DECLARE_METATYPE(QNetworkConfiguration); +Q_DECLARE_METATYPE(QList<QNetworkProxy>); class tst_QNetworkProxyFactory : public QObject { Q_OBJECT + +public: + tst_QNetworkProxyFactory(); + + class QDebugProxyFactory : public QNetworkProxyFactory + { + public: + virtual QList<QNetworkProxy> queryProxy(const QNetworkProxyQuery &query = QNetworkProxyQuery()) + { + returnedList = QNetworkProxyFactory::systemProxyForQuery(query); + requestCounter++; + return returnedList; + } + QList<QNetworkProxy> returnedList; + int requestCounter; + }; + private slots: + void systemProxyForQueryCalledFromThread(); void systemProxyForQuery() const; +#ifndef QT_NO_BEARERMANAGEMENT + void fromConfigurations(); + void inNetworkAccessManager_data(); + void inNetworkAccessManager(); +#endif private: QString formatProxyName(const QNetworkProxy & proxy) const; + QDebugProxyFactory *factory; }; +tst_QNetworkProxyFactory::tst_QNetworkProxyFactory() +{ + factory = new QDebugProxyFactory; + QNetworkProxyFactory::setApplicationProxyFactory(factory); +} + QString tst_QNetworkProxyFactory::formatProxyName(const QNetworkProxy & proxy) const { QString proxyName; @@ -96,5 +138,137 @@ void tst_QNetworkProxyFactory::systemProxyForQuery() const QFAIL("One or more system proxy lookup failures occurred."); } +class QSPFQThread : public QThread +{ +protected: + virtual void run() + { + proxies = QNetworkProxyFactory::systemProxyForQuery(query); + } +public: + QNetworkProxyQuery query; + QList<QNetworkProxy> proxies; +}; + +//regression test for QTBUG-18799 +void tst_QNetworkProxyFactory::systemProxyForQueryCalledFromThread() +{ + QUrl url(QLatin1String("http://qt.nokia.com")); + QNetworkProxyQuery query(url); + QSPFQThread thread; + thread.query = query; + connect(&thread, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + thread.start(); + QTestEventLoop::instance().enterLoop(5); + QVERIFY(thread.isFinished()); + QCOMPARE(thread.proxies, QNetworkProxyFactory::systemProxyForQuery(query)); +} + +#ifndef QT_NO_BEARERMANAGEMENT + +//Purpose of this test is just to check systemProxyForQuery doesn't hang or crash +//with any given configuration including no configuration. +//We can't test it returns the right proxies without implementing the native proxy code +//again here, which would be testing our implementation against itself. +//Therefore it's just testing that something valid is returned (at least a NoProxy entry) +void tst_QNetworkProxyFactory::fromConfigurations() +{ + QNetworkConfigurationManager manager; + //update is done to get the active / discovered states + manager.updateConfigurations(); + connect(&manager, SIGNAL(updateCompleted()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(10); + QList<QNetworkProxy> proxies; + QUrl url(QLatin1String("http://qt.nokia.com")); + //get from known configurations + foreach (QNetworkConfiguration config, manager.allConfigurations()) { + QNetworkProxyQuery query(config, url, QNetworkProxyQuery::UrlRequest); + proxies = QNetworkProxyFactory::systemProxyForQuery(query); + QVERIFY(!proxies.isEmpty()); + foreach (QNetworkProxy proxy, proxies) { + qDebug() << config.name() << " - " << config.identifier() << " - " << formatProxyName(proxy); + } + } + + //get from default configuration + QNetworkProxyQuery defaultquery(url, QNetworkProxyQuery::UrlRequest); + proxies = QNetworkProxyFactory::systemProxyForQuery(defaultquery); + QVERIFY(!proxies.isEmpty()); + foreach (QNetworkProxy proxy, proxies) { + qDebug() << "default - " << formatProxyName(proxy); + } + + //get from active configuration + QNetworkSession session(manager.defaultConfiguration()); + session.open(); + QVERIFY(session.waitForOpened(30000)); + proxies = QNetworkProxyFactory::systemProxyForQuery(defaultquery); + QVERIFY(!proxies.isEmpty()); + foreach (QNetworkProxy proxy, proxies) { + qDebug() << "active - " << formatProxyName(proxy); + } + + //get from known configurations while there is one active + foreach (QNetworkConfiguration config, manager.allConfigurations()) { + QNetworkProxyQuery query(config, url, QNetworkProxyQuery::UrlRequest); + proxies = QNetworkProxyFactory::systemProxyForQuery(query); + QVERIFY(!proxies.isEmpty()); + foreach (QNetworkProxy proxy, proxies) { + qDebug() << config.name() << " - " << config.identifier() << " - " << formatProxyName(proxy); + } + } +} + +void tst_QNetworkProxyFactory::inNetworkAccessManager_data() +{ + QTest::addColumn<QNetworkConfiguration>("config"); + QTest::addColumn<QList<QNetworkProxy> >("proxies"); + QNetworkConfigurationManager manager; + //get from known configurations + foreach (QNetworkConfiguration config, manager.allConfigurations()) { + QNetworkProxyQuery query(config, QUrl(QString("http://qt.nokia.com")), QNetworkProxyQuery::UrlRequest); + QList<QNetworkProxy> proxies = QNetworkProxyFactory::systemProxyForQuery(query); + QTest::newRow(config.name().toUtf8()) << config << proxies; + } +} + +//Purpose of this test is to check that QNetworkAccessManager uses the proxy from the configuration it +//has been given. Needs two or more working configurations to be a good test. +void tst_QNetworkProxyFactory::inNetworkAccessManager() +{ + QFETCH(QNetworkConfiguration, config); + QFETCH(QList<QNetworkProxy>, proxies); + + int count = factory->requestCounter; + + QNetworkAccessManager manager; + manager.setConfiguration(config); + + //using an internet server, because cellular APs won't have a route to the test server. + QNetworkRequest req(QUrl(QString("http://qt.nokia.com"))); + QNetworkReply *reply = manager.get(req); + connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTestEventLoop::instance().enterLoop(30); + delete reply; + + if (count == factory->requestCounter) { + //RND phones are preconfigured with several test access points which won't work without a matching SIM + //If the network fails to start, QNAM won't ask the factory for proxies so we can't test. + QSKIP("network configuration didn't start", SkipSingle); + } + + qDebug() << "testing network configuration for" << config.name(); + foreach (QNetworkProxy proxy, factory->returnedList) { + qDebug() << formatProxyName(proxy); + } + qDebug() << " <vs> "; + foreach (QNetworkProxy proxy, proxies) { + qDebug() << formatProxyName(proxy); + } + QCOMPARE(factory->returnedList, proxies); +} + +#endif //QT_NO_BEARERMANAGEMENT + QTEST_MAIN(tst_QNetworkProxyFactory) #include "tst_qnetworkproxyfactory.moc" diff --git a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp index f509cea..95f2f8a 100644 --- a/tests/auto/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/qnetworkreply/tst_qnetworkreply.cpp @@ -622,9 +622,14 @@ public: } QIODevice *prepare(const QNetworkCacheMetaData &) - { Q_ASSERT(0 && "Should not have tried to add to the cache"); return 0; } + { + qFatal("%s: Should not have tried to add to the cache", Q_FUNC_INFO); + return 0; + } void insert(QIODevice *) - { Q_ASSERT(0 && "Should not have tried to add to the cache"); } + { + qFatal("%s: Should not have tried to add to the cache", Q_FUNC_INFO); + } void clear() { cache.clear(); } }; @@ -774,7 +779,9 @@ public: QTcpSocket* waitForNextConnectionSocket() { waitForNewConnection(-1); if (doSsl) { - Q_ASSERT(sslSocket); + if (!sslSocket) + qFatal("%s: sslSocket should not be null after calling waitForNewConnection()", + Q_FUNC_INFO); return sslSocket; } else { //qDebug() << "returning nextPendingConnection"; @@ -946,7 +953,8 @@ protected: while (dataIndex < wantedSize) { const int remainingBytes = wantedSize - measuredSentBytes; const int bytesToWrite = qMin(remainingBytes, static_cast<int>(BlockSize)); - Q_ASSERT(bytesToWrite); + if (bytesToWrite <= 0) + qFatal("%s: attempt to write %d bytes", Q_FUNC_INFO, bytesToWrite); measuredSentBytes += writeNextData(client, bytesToWrite); while (client->bytesToWrite() > 0) { @@ -1005,7 +1013,8 @@ public: // Wait for data to be readyRead bool ok = connect(&senderObj, SIGNAL(dataReady()), this, SLOT(slotDataReady())); - Q_ASSERT(ok); + if (!ok) + qFatal("%s: Cannot connect dataReady signal", Q_FUNC_INFO); } void wrapUp() @@ -1028,9 +1037,9 @@ protected: void timerEvent(QTimerEvent *) { //qDebug() << "RateControlledReader: timerEvent bytesAvailable=" << device->bytesAvailable(); - if (readBufferSize > 0) { - // This asserts passes all the time, except in the final flush. - //Q_ASSERT(device->bytesAvailable() <= readBufferSize); + if (readBufferSize > 0 && device->bytesAvailable() > readBufferSize) { + // This passes all the time, except in the final flush. + //qFatal("%s: Too many bytes available", Q_FUNC_INFO); } qint64 bytesRead = 0; @@ -1189,7 +1198,7 @@ QString tst_QNetworkReply::runSimpleRequest(QNetworkAccessManager::Operation op, break; default: - Q_ASSERT_X(false, "tst_QNetworkReply", "Invalid/unknown operation requested"); + qFatal("%s: Invalid/unknown operation requested", Q_FUNC_INFO); } reply->setParent(this); @@ -3237,16 +3246,16 @@ void tst_QNetworkReply::ioGetFromHttpWithCache_data() QTest::newRow("must-revalidate,200,prefer-network") << reply200 << "Reloaded" << content << int(QNetworkRequest::PreferNetwork) << QStringList() << false << true; QTest::newRow("must-revalidate,200,prefer-cache") - << reply200 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << QStringList() << true << false; + << reply200 << "Reloaded" << content << int(QNetworkRequest::PreferCache) << QStringList() << false << true; QTest::newRow("must-revalidate,200,always-cache") - << reply200 << "Not-reloaded" << content << int(QNetworkRequest::AlwaysCache) << QStringList() << true << false; + << reply200 << "" << content << int(QNetworkRequest::AlwaysCache) << QStringList() << false << false; QTest::newRow("must-revalidate,304,prefer-network") << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferNetwork) << QStringList() << true << true; QTest::newRow("must-revalidate,304,prefer-cache") - << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << QStringList() << true << false; + << reply304 << "Not-reloaded" << content << int(QNetworkRequest::PreferCache) << QStringList() << true << true; QTest::newRow("must-revalidate,304,always-cache") - << reply304 << "Not-reloaded" << content << int(QNetworkRequest::AlwaysCache) << QStringList() << true << false; + << reply304 << "" << content << int(QNetworkRequest::AlwaysCache) << QStringList() << false << false; // // Partial content @@ -4103,6 +4112,7 @@ void tst_QNetworkReply::ioPostToHttpFromMiddleOfQBufferFiveBytes() QUrl url = "http://" + QtNetworkSettings::serverName() + "/qtest/protected/cgi-bin/md5sum.cgi"; QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); QNetworkReplyPtr reply = manager.post(request, &uploadBuffer); connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -4353,6 +4363,7 @@ void tst_QNetworkReply::ioPostToHttpUploadProgress() // create the request QUrl url = QUrl(QString("http://127.0.0.1:%1/").arg(server.serverPort())); QNetworkRequest request(url); + request.setRawHeader("Content-Type", "application/octet-stream"); QNetworkReplyPtr reply = manager.post(request, &sourceFile); QSignalSpy spy(reply, SIGNAL(uploadProgress(qint64,qint64))); connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); @@ -4964,17 +4975,24 @@ void tst_QNetworkReply::httpProxyCommands() QNetworkProxy proxy(QNetworkProxy::HttpProxy, "127.0.0.1", proxyServer.serverPort()); manager.setProxy(proxy); - QNetworkReplyPtr reply = manager.get(QNetworkRequest(url)); - manager.setProxy(QNetworkProxy()); + QNetworkRequest request(url); + request.setRawHeader("User-Agent", "QNetworkReplyAutoTest/1.0"); + QNetworkReplyPtr reply = manager.get(request); + //clearing the proxy here causes the test to fail. + //the proxy isn't used until after the bearer has been started + //which is correct in general, because system proxy isn't known until that time. + //removing this line is safe, as the proxy is also reset by the cleanup() function + //manager.setProxy(QNetworkProxy()); // wait for the finished signal connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop())); - QTestEventLoop::instance().enterLoop(1); + QTestEventLoop::instance().enterLoop(15); QVERIFY(!QTestEventLoop::instance().timeout()); //qDebug() << reply->error() << reply->errorString(); + //qDebug() << proxyServer.receivedData; // we don't really care if the request succeeded // especially since it won't succeed in the HTTPS case @@ -4982,6 +5000,12 @@ void tst_QNetworkReply::httpProxyCommands() QString receivedHeader = proxyServer.receivedData.left(expectedCommand.length()); QCOMPARE(receivedHeader, expectedCommand); + + //QTBUG-17223 - make sure the user agent from the request is sent to proxy server even for CONNECT + int uapos = proxyServer.receivedData.indexOf("User-Agent"); + int uaend = proxyServer.receivedData.indexOf("\r\n", uapos); + QByteArray uaheader = proxyServer.receivedData.mid(uapos, uaend - uapos); + QCOMPARE(uaheader, QByteArray("User-Agent: QNetworkReplyAutoTest/1.0")); } class ProxyChangeHelper : public QObject { diff --git a/tests/auto/qobject/signalbug.cpp b/tests/auto/qobject/signalbug.cpp index f9c9650..55ef5b3 100644 --- a/tests/auto/qobject/signalbug.cpp +++ b/tests/auto/qobject/signalbug.cpp @@ -69,7 +69,8 @@ void Receiver::received () ::Step++; const int stepCopy = ::Step; TRACE (stepCopy, "Receiver::received()"); - Q_ASSERT (::Step == 2 || ::Step == 4); + if (::Step != 2 && ::Step != 4) + qFatal("%s: Incorrect Step: %d (should be 2 or 4)", Q_FUNC_INFO, ::Step); if (::Step == 2) s->fire (); @@ -91,7 +92,8 @@ void Disconnector::received () ::Step++; const int stepCopy = ::Step; TRACE (stepCopy, "Disconnector::received()"); - Q_ASSERT (::Step == 5 || ::Step == 6); + if (::Step != 5 && ::Step != 6) + qFatal("%s: Incorrect Step: %d (should be 5 or 6)", Q_FUNC_INFO, ::Step); fprintf (stderr, "Disconnector<%s>::received() sender=%s\n", (const char *) objectName ().toAscii (), sender ()->metaObject()->className()); @@ -124,7 +126,8 @@ void Sender::fire () ::Step++; const int stepCopy = ::Step; TRACE (stepCopy, "Sender::fire()"); - Q_ASSERT (::Step == 1 || ::Step == 3); + if (::Step != 1 && ::Step != 3) + qFatal("%s: Incorrect Step: %d (should be 1 or 3)", Q_FUNC_INFO, ::Step); emit fired (); TRACE (stepCopy, "ends Sender::fire()"); diff --git a/tests/auto/qobject/tst_qobject.cpp b/tests/auto/qobject/tst_qobject.cpp index 4b926e4..a7e8d79 100644 --- a/tests/auto/qobject/tst_qobject.cpp +++ b/tests/auto/qobject/tst_qobject.cpp @@ -403,6 +403,8 @@ public: } void reset() { + called_slot10 = 0; + called_slot9 = 0; called_slot8 = 0; called_slot7 = 0; called_slot6 = 0; @@ -421,6 +423,8 @@ public: int called_slot6; int called_slot7; int called_slot8; + int called_slot9; + int called_slot10; bool called(int slot) { switch (slot) { @@ -432,6 +436,8 @@ public: case 6: return called_slot6; case 7: return called_slot7; case 8: return called_slot8; + case 9: return called_slot9; + case 10: return called_slot10; default: return false; } } @@ -449,8 +455,8 @@ public slots: void slotLoopBack() { ++called_slot8; } protected slots: - void o() { Q_ASSERT(0); } - void on() { Q_ASSERT(0); } + void o() { ++called_slot9; } + void on() { ++called_slot10; } signals: void on_Sender_signalLoopBack(); @@ -473,6 +479,8 @@ void tst_QObject::connectByName() QCOMPARE(receiver.called(6), false); QCOMPARE(receiver.called(7), false); QCOMPARE(receiver.called(8), false); + QCOMPARE(receiver.called(9), false); + QCOMPARE(receiver.called(10), false); receiver.reset(); sender.emitSignalWithParams(0); @@ -484,6 +492,8 @@ void tst_QObject::connectByName() QCOMPARE(receiver.called(6), false); QCOMPARE(receiver.called(7), false); QCOMPARE(receiver.called(8), false); + QCOMPARE(receiver.called(9), false); + QCOMPARE(receiver.called(10), false); receiver.reset(); sender.emitSignalWithParams(0, "string"); @@ -495,6 +505,8 @@ void tst_QObject::connectByName() QCOMPARE(receiver.called(6), false); QCOMPARE(receiver.called(7), false); QCOMPARE(receiver.called(8), false); + QCOMPARE(receiver.called(9), false); + QCOMPARE(receiver.called(10), false); receiver.reset(); sender.emitSignalManyParams(1, 2, 3, "string", true); @@ -506,6 +518,8 @@ void tst_QObject::connectByName() QCOMPARE(receiver.called(6), false); QCOMPARE(receiver.called(7), false); QCOMPARE(receiver.called(8), false); + QCOMPARE(receiver.called(9), false); + QCOMPARE(receiver.called(10), false); receiver.reset(); sender.emitSignalManyParams2(1, 2, 3, "string", true); @@ -517,6 +531,8 @@ void tst_QObject::connectByName() QCOMPARE(receiver.called(6), false); QCOMPARE(receiver.called(7), true); QCOMPARE(receiver.called(8), false); + QCOMPARE(receiver.called(9), false); + QCOMPARE(receiver.called(10), false); receiver.reset(); sender.emitSignalLoopBack(); @@ -528,6 +544,8 @@ void tst_QObject::connectByName() QCOMPARE(receiver.called(6), false); QCOMPARE(receiver.called(7), false); QCOMPARE(receiver.called(8), true); + QCOMPARE(receiver.called(9), false); + QCOMPARE(receiver.called(10), false); receiver.reset(); } @@ -1312,14 +1330,16 @@ public: void customEvent(QEvent *) { - Q_ASSERT(customEventThread == 0); + if (customEventThread) + qFatal("%s: customEventThread should be null", Q_FUNC_INFO); customEventThread = QThread::currentThread(); emit theSignal(); } void timerEvent(QTimerEvent *) { - Q_ASSERT(timerEventThread == 0); + if (timerEventThread) + qFatal("%s: timerEventThread should be null", Q_FUNC_INFO); timerEventThread = QThread::currentThread(); emit theSignal(); } @@ -1327,7 +1347,8 @@ public: public slots: void theSlot() { - Q_ASSERT(slotThread == 0); + if (slotThread) + qFatal("%s: slotThread should be null", Q_FUNC_INFO); slotThread = QThread::currentThread(); emit theSignal(); } diff --git a/tests/auto/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index c21514b..9844434 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -72,11 +72,13 @@ #include <qgraphicsscene.h> #include <qgraphicsproxywidget.h> #include <qlayout.h> +#include <qfontdatabase.h> #if defined(Q_OS_SYMBIAN) # define SRCDIR "." #endif +Q_DECLARE_METATYPE(QGradientStops) Q_DECLARE_METATYPE(QLine) Q_DECLARE_METATYPE(QRect) Q_DECLARE_METATYPE(QSize) @@ -189,6 +191,7 @@ private slots: void fillRect_stretchToDeviceMode(); void monoImages(); + void linearGradientSymmetry_data(); void linearGradientSymmetry(); void gradientInterpolation(); @@ -264,6 +267,8 @@ private slots: void QTBUG17053_zeroDashPattern(); + void drawTextOutsideGuiThread(); + private: void fillData(); void setPenColor(QPainter& p); @@ -3983,8 +3988,42 @@ static QLinearGradient inverseGradient(QLinearGradient g) return g2; } +void tst_QPainter::linearGradientSymmetry_data() +{ + QTest::addColumn<QGradientStops>("stops"); + + if (sizeof(qreal) != sizeof(float)) { + QGradientStops stops; + stops << qMakePair(qreal(0.0), QColor(Qt::blue)); + stops << qMakePair(qreal(0.2), QColor(220, 220, 220, 0)); + stops << qMakePair(qreal(0.6), QColor(Qt::red)); + stops << qMakePair(qreal(0.9), QColor(220, 220, 220, 255)); + stops << qMakePair(qreal(1.0), QColor(Qt::black)); + QTest::newRow("multiple stops") << stops; + } + + { + QGradientStops stops; + stops << qMakePair(qreal(0.0), QColor(Qt::blue)); + stops << qMakePair(qreal(1.0), QColor(Qt::black)); + QTest::newRow("two stops") << stops; + } + + if (sizeof(qreal) != sizeof(float)) { + QGradientStops stops; + stops << qMakePair(qreal(0.3), QColor(Qt::blue)); + stops << qMakePair(qreal(0.6), QColor(Qt::black)); + QTest::newRow("two stops 2") << stops; + } +} + void tst_QPainter::linearGradientSymmetry() { +#ifdef Q_WS_QWS + QSKIP("QWS has limited resolution in the gradient color table", SkipAll); +#else + QFETCH(QGradientStops, stops); + QImage a(64, 8, QImage::Format_ARGB32_Premultiplied); QImage b(64, 8, QImage::Format_ARGB32_Premultiplied); @@ -3992,11 +4031,7 @@ void tst_QPainter::linearGradientSymmetry() b.fill(0); QLinearGradient gradient(QRectF(b.rect()).topLeft(), QRectF(b.rect()).topRight()); - gradient.setColorAt(0.0, Qt::blue); - gradient.setColorAt(0.2, QColor(220, 220, 220, 0)); - gradient.setColorAt(0.6, Qt::red); - gradient.setColorAt(0.9, QColor(220, 220, 220, 255)); - gradient.setColorAt(1.0, Qt::black); + gradient.setStops(stops); QPainter pa(&a); pa.fillRect(a.rect(), gradient); @@ -4008,6 +4043,7 @@ void tst_QPainter::linearGradientSymmetry() b = b.mirrored(true); QCOMPARE(a, b); +#endif } void tst_QPainter::gradientInterpolation() @@ -4706,6 +4742,44 @@ void tst_QPainter::QTBUG17053_zeroDashPattern() QCOMPARE(image, original); } +class TextDrawerThread : public QThread +{ +public: + void run(); + QImage rendering; +}; + +void TextDrawerThread::run() +{ + rendering = QImage(100, 100, QImage::Format_ARGB32_Premultiplied); + rendering.fill(0); + QPainter p(&rendering); + p.fillRect(10, 10, 100, 100, Qt::blue); + p.setPen(Qt::green); + p.drawText(20, 20, "some text"); + p.end(); +} + +void tst_QPainter::drawTextOutsideGuiThread() +{ + if (!QFontDatabase::supportsThreadedFontRendering()) + QSKIP("No threaded font rendering", SkipAll); + + QImage referenceRendering(100, 100, QImage::Format_ARGB32_Premultiplied); + referenceRendering.fill(0); + QPainter p(&referenceRendering); + p.fillRect(10, 10, 100, 100, Qt::blue); + p.setPen(Qt::green); + p.drawText(20, 20, "some text"); + p.end(); + + TextDrawerThread t; + t.start(); + t.wait(); + + QCOMPARE(referenceRendering, t.rendering); +} + QTEST_MAIN(tst_QPainter) #include "tst_qpainter.moc" diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 4d032e8..3462850 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -196,6 +196,9 @@ private slots: #if defined(Q_OS_SYMBIAN) && !defined(QT_NO_OPENVG) void vgImageReadBack(); #endif + + void drawPixmapWhilePainterOpen(); + void scaled_QTBUG19157(); }; static bool lenientCompare(const QPixmap &actual, const QPixmap &expected) @@ -1337,7 +1340,7 @@ void tst_QPixmap::toSymbianCFbsBitmap() void tst_QPixmap::onlyNullPixmapsOutsideGuiThread() { -#if !defined(Q_WS_WIN) +#if !defined(Q_WS_WIN) && !defined(Q_WS_MAC) class Thread : public QThread { public: @@ -1370,7 +1373,7 @@ void tst_QPixmap::onlyNullPixmapsOutsideGuiThread() thread.wait(); #endif -#endif // !defined(Q_WS_WIN) +#endif // !defined(Q_WS_WIN) && !defined(Q_WS_MAC) } void tst_QPixmap::refUnref() @@ -1696,8 +1699,8 @@ void tst_QPixmap::fromImageReaderAnimatedGif() QImageReader referenceReader(path); QImageReader pixmapReader(path); - Q_ASSERT(referenceReader.canRead()); - Q_ASSERT(referenceReader.imageCount() > 1); + QVERIFY(referenceReader.canRead()); + QVERIFY(referenceReader.imageCount() > 1); for (int i = 0; i < referenceReader.imageCount(); ++i) { QImage refImage = referenceReader.read(); @@ -1897,5 +1900,71 @@ void tst_QPixmap::vgImageReadBack() } #endif // Symbian & OpenVG +class PixmapWidget : public QWidget +{ +public: + PixmapWidget(QPixmap &pixmap) : QWidget(0), m_pixmap(pixmap) + { + resize(pixmap.width(), pixmap.height()); + } + +protected: + void paintEvent(QPaintEvent *) + { + QPainter p(this); + p.drawPixmap(0, 0, m_pixmap); + } + +private: + QPixmap &m_pixmap; +}; + +void tst_QPixmap::drawPixmapWhilePainterOpen() +{ + const int delay = 1000; + const int size = 100; + const QColor colors[] = { Qt::red, Qt::blue, Qt::green }; + + QPixmap pix(size, size); + pix.fill(colors[0]); + + PixmapWidget w(pix); + w.show(); + QTest::qWaitForWindowShown(&w); + QTest::qWait(delay); + + QPainter p(&pix); + p.fillRect(0, 0, size, size, colors[1]); + w.update(); + QTest::qWait(delay); + + p.fillRect(0, 0, size, size, colors[2]); + w.update(); + QTest::qWait(delay); + + QPixmap actual = QPixmap::grabWindow(w.effectiveWinId(), 0, 0, size, size); + + // If we captured some bogus content with grabWindow(), the comparison makes no sense + // because it cannot prove the feature is broken. + QPixmap guard(size, size); + bool matchesColors = false; + for (size_t i = 0; i < sizeof(colors) / sizeof(const QColor); ++i) { + guard.fill(colors[i]); + matchesColors |= lenientCompare(actual, guard); + } + if (!matchesColors) { + QSKIP("Skipping verification due to grabWindow() issue", SkipSingle); + } else { + QVERIFY(lenientCompare(actual, pix)); + } +} + +void tst_QPixmap::scaled_QTBUG19157() +{ + QPixmap foo(5000, 1); + foo = foo.scaled(1024, 1024, Qt::KeepAspectRatio); + QVERIFY(!foo.isNull()); +} + QTEST_MAIN(tst_QPixmap) #include "tst_qpixmap.moc" diff --git a/tests/auto/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/qplaintextedit/tst_qplaintextedit.cpp index d3e4fd0..8da5ba5 100644 --- a/tests/auto/qplaintextedit/tst_qplaintextedit.cpp +++ b/tests/auto/qplaintextedit/tst_qplaintextedit.cpp @@ -150,6 +150,7 @@ private slots: void lineWrapProperty(); void selectionChanged(); void blockCountChanged(); + void insertAndScrollToBottom(); private: void createSelection(); @@ -1504,5 +1505,22 @@ void tst_QPlainTextEdit::blockCountChanged() } +void tst_QPlainTextEdit::insertAndScrollToBottom() +{ + ed->setPlainText("First Line"); + ed->show(); + QString text; + for(int i = 0; i < 2000; ++i) { + text += QLatin1String("this is another line of text to be appended. It is quite long and will probably wrap around, meaning the number of lines is larger than the number of blocks in the text.\n"); + } + QTextCursor cursor = ed->textCursor(); + cursor.beginEditBlock(); + cursor.insertText(text); + cursor.endEditBlock(); + ed->verticalScrollBar()->setValue(ed->verticalScrollBar()->maximum()); + QCOMPARE(ed->verticalScrollBar()->value(), ed->verticalScrollBar()->maximum()); +} + + QTEST_MAIN(tst_QPlainTextEdit) #include "tst_qplaintextedit.moc" diff --git a/tests/auto/qpluginloader/tst_qpluginloader.cpp b/tests/auto/qpluginloader/tst_qpluginloader.cpp index 591ef5e..76c2f6e 100644 --- a/tests/auto/qpluginloader/tst_qpluginloader.cpp +++ b/tests/auto/qpluginloader/tst_qpluginloader.cpp @@ -370,15 +370,15 @@ if (sizeof(void*) == 8) { QPluginLoader lib1(SRCDIR "elftest/corrupt1.elf64.so"); QCOMPARE(lib1.load(), false); - QVERIFY(lib1.errorString().contains("not an ELF object")); + QVERIFY(lib1.errorString().contains("not a valid Qt plugin")); QPluginLoader lib2(SRCDIR "elftest/corrupt2.elf64.so"); QCOMPARE(lib2.load(), false); - QVERIFY(lib2.errorString().contains("invalid")); + QVERIFY(lib2.errorString().contains("not a valid Qt plugin")); QPluginLoader lib3(SRCDIR "elftest/corrupt3.elf64.so"); QCOMPARE(lib3.load(), false); - QVERIFY(lib3.errorString().contains("invalid")); + QVERIFY(lib3.errorString().contains("not a valid Qt plugin")); } else if (sizeof(void*) == 4) { QPluginLoader libW(SRCDIR "elftest/corrupt3.elf64.so"); QCOMPARE(libW.load(), false); diff --git a/tests/auto/qprocess/tst_qprocess.cpp b/tests/auto/qprocess/tst_qprocess.cpp index 2a8874e..3e0c3ff 100644 --- a/tests/auto/qprocess/tst_qprocess.cpp +++ b/tests/auto/qprocess/tst_qprocess.cpp @@ -668,7 +668,7 @@ void tst_QProcess::exitStatus() QSKIP("This test opens a crash dialog on Windows", SkipSingle); #endif - Q_ASSERT(processList.count() == exitStatus.count()); + QCOMPARE(exitStatus.count(), processList.count()); for (int i = 0; i < processList.count(); ++i) { process->start(processList.at(i)); QVERIFY(process->waitForStarted(5000)); diff --git a/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp b/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp index 1c26343..98d4890 100644 --- a/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp +++ b/tests/auto/qprocessenvironment/tst_qprocessenvironment.cpp @@ -43,10 +43,6 @@ #include <QObject> #include <QProcessEnvironment> -// Note: -// in cross-platform tests, ALWAYS use UPPERCASE variable names -// That's because on Windows, the variables are uppercased - class tst_QProcessEnvironment: public QObject { Q_OBJECT @@ -214,7 +210,7 @@ void tst_QProcessEnvironment::caseSensitivity() e.insert("foo", "bar"); #ifdef Q_OS_WIN - // on Windows, it's uppercased + // Windows is case-insensitive, but case-preserving QVERIFY(e.contains("foo")); QVERIFY(e.contains("FOO")); QVERIFY(e.contains("FoO")); @@ -223,8 +219,12 @@ void tst_QProcessEnvironment::caseSensitivity() QCOMPARE(e.value("FOO"), QString("bar")); QCOMPARE(e.value("FoO"), QString("bar")); + // Per Windows, this overwrites the value, but keeps the name's original capitalization + e.insert("Foo", "Bar"); + QStringList list = e.toStringList(); - QCOMPARE(list.at(0), QString("FOO=bar")); + QCOMPARE(list.length(), 1); + QCOMPARE(list.at(0), QString("foo=Bar")); #else // otherwise, it's case sensitive QVERIFY(e.contains("foo")); @@ -236,6 +236,7 @@ void tst_QProcessEnvironment::caseSensitivity() QCOMPARE(e.value("foo"), QString("bar")); QStringList list = e.toStringList(); + QCOMPARE(list.length(), 2); QVERIFY(list.contains("foo=bar")); QVERIFY(list.contains("FOO=baz")); #endif diff --git a/tests/auto/qrawfont/tst_qrawfont.cpp b/tests/auto/qrawfont/tst_qrawfont.cpp index 3aa4006..8c58407 100644 --- a/tests/auto/qrawfont/tst_qrawfont.cpp +++ b/tests/auto/qrawfont/tst_qrawfont.cpp @@ -91,6 +91,9 @@ private slots: void unsupportedWritingSystem_data(); void unsupportedWritingSystem(); + + void rawFontSetPixelSize_data(); + void rawFontSetPixelSize(); #endif // QT_NO_RAWFONT }; @@ -104,7 +107,7 @@ void tst_QRawFont::invalidRawFont() { QRawFont font; QVERIFY(!font.isValid()); - QCOMPARE(font.pixelSize(), -1); + QCOMPARE(font.pixelSize(), 0.0); QVERIFY(font.familyName().isEmpty()); QCOMPARE(font.style(), QFont::StyleNormal); QCOMPARE(font.weight(), -1); @@ -165,7 +168,7 @@ void tst_QRawFont::correctFontData_data() QTest::addColumn<QFont::Weight>("weight"); QTest::addColumn<QFont::HintingPreference>("hintingPreference"); QTest::addColumn<qreal>("unitsPerEm"); - QTest::addColumn<int>("pixelSize"); + QTest::addColumn<qreal>("pixelSize"); int hintingPreferences[] = { int(QFont::PreferDefaultHinting), @@ -189,7 +192,7 @@ void tst_QRawFont::correctFontData_data() << QFont::Normal << QFont::HintingPreference(*hintingPreference) << 1000.0 - << 10; + << 10.0; fileName = QLatin1String(SRCDIR "testfont_bold_italic.ttf"); title = fileName @@ -203,7 +206,7 @@ void tst_QRawFont::correctFontData_data() << QFont::Bold << QFont::HintingPreference(*hintingPreference) << 1000.0 - << 10; + << 10.0; ++hintingPreference; } @@ -217,7 +220,7 @@ void tst_QRawFont::correctFontData() QFETCH(QFont::Weight, weight); QFETCH(QFont::HintingPreference, hintingPreference); QFETCH(qreal, unitsPerEm); - QFETCH(int, pixelSize); + QFETCH(qreal, pixelSize); QRawFont font(fileName, 10, hintingPreference); QVERIFY(font.isValid()); @@ -284,7 +287,7 @@ void tst_QRawFont::textLayout() QString familyName = QString::fromLatin1("QtBidiTestFont"); QFont font(familyName); - font.setPixelSize(18); + font.setPixelSize(18.0); QCOMPARE(QFontInfo(font).family(), familyName); QTextLayout layout(QLatin1String("Foobar")); @@ -293,15 +296,15 @@ void tst_QRawFont::textLayout() layout.createLine(); layout.endLayout(); - QList<QGlyphs> glyphss = layout.glyphs(); - QCOMPARE(glyphss.size(), 1); + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 1); - QGlyphs glyphs = glyphss.at(0); + QGlyphRun glyphs = glyphRuns.at(0); - QRawFont rawFont = glyphs.font(); + QRawFont rawFont = glyphs.rawFont(); QVERIFY(rawFont.isValid()); QCOMPARE(rawFont.familyName(), familyName); - QCOMPARE(rawFont.pixelSize(), 18); + QCOMPARE(rawFont.pixelSize(), 18.0); QVector<quint32> expectedGlyphIndices; expectedGlyphIndices << 44 << 83 << 83 << 70 << 69 << 86; @@ -597,12 +600,12 @@ void tst_QRawFont::fromFont() QFont font(familyName); font.setHintingPreference(hintingPreference); - font.setPixelSize(26); + font.setPixelSize(26.0); QRawFont rawFont = QRawFont::fromFont(font, writingSystem); QVERIFY(rawFont.isValid()); QCOMPARE(rawFont.familyName(), familyName); - QCOMPARE(rawFont.pixelSize(), 26); + QCOMPARE(rawFont.pixelSize(), 26.0); QVERIFY(fontDatabase.removeApplicationFont(id)); } @@ -623,7 +626,7 @@ void tst_QRawFont::copyConstructor() { QString rawFontFamilyName; - int rawFontPixelSize; + qreal rawFontPixelSize; qreal rawFontAscent; qreal rawFontDescent; int rawFontTableSize; @@ -691,7 +694,7 @@ void tst_QRawFont::detach() { QString rawFontFamilyName; - int rawFontPixelSize; + qreal rawFontPixelSize; qreal rawFontAscent; qreal rawFontDescent; int rawFontTableSize; @@ -773,15 +776,15 @@ void tst_QRawFont::unsupportedWritingSystem() QFont font("QtBidiTestFont"); font.setHintingPreference(hintingPreference); - font.setPixelSize(12); + font.setPixelSize(12.0); QRawFont rawFont = QRawFont::fromFont(font, QFontDatabase::Any); QCOMPARE(rawFont.familyName(), QString::fromLatin1("QtBidiTestFont")); - QCOMPARE(rawFont.pixelSize(), 12); + QCOMPARE(rawFont.pixelSize(), 12.0); rawFont = QRawFont::fromFont(font, QFontDatabase::Hebrew); QCOMPARE(rawFont.familyName(), QString::fromLatin1("QtBidiTestFont")); - QCOMPARE(rawFont.pixelSize(), 12); + QCOMPARE(rawFont.pixelSize(), 12.0); QString arabicText = QFontDatabase::writingSystemSample(QFontDatabase::Arabic); @@ -792,21 +795,54 @@ void tst_QRawFont::unsupportedWritingSystem() layout.createLine(); layout.endLayout(); - QList<QGlyphs> glyphss = layout.glyphs(); - QCOMPARE(glyphss.size(), 1); + QList<QGlyphRun> glyphRuns = layout.glyphRuns(); + QCOMPARE(glyphRuns.size(), 1); - QGlyphs glyphs = glyphss.at(0); - QRawFont layoutFont = glyphs.font(); + QGlyphRun glyphs = glyphRuns.at(0); + QRawFont layoutFont = glyphs.rawFont(); QVERIFY(layoutFont.familyName() != QString::fromLatin1("QtBidiTestFont")); - QCOMPARE(layoutFont.pixelSize(), 12); + QCOMPARE(layoutFont.pixelSize(), 12.0); rawFont = QRawFont::fromFont(font, QFontDatabase::Arabic); QCOMPARE(rawFont.familyName(), layoutFont.familyName()); - QCOMPARE(rawFont.pixelSize(), 12); + QCOMPARE(rawFont.pixelSize(), 12.0); fontDatabase.removeApplicationFont(id); } +void tst_QRawFont::rawFontSetPixelSize_data() +{ + QTest::addColumn<QFont::HintingPreference>("hintingPreference"); + + QTest::newRow("Default hinting preference") << QFont::PreferDefaultHinting; + QTest::newRow("No hinting preference") << QFont::PreferNoHinting; + QTest::newRow("Vertical hinting preference") << QFont::PreferVerticalHinting; + QTest::newRow("Full hinting preference") << QFont::PreferFullHinting; +} + +void tst_QRawFont::rawFontSetPixelSize() +{ + QFETCH(QFont::HintingPreference, hintingPreference); + + QTextLayout layout("Foobar"); + + QFont font = layout.font(); + font.setHintingPreference(hintingPreference); + font.setPixelSize(12); + layout.setFont(font); + + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QGlyphRun glyphs = layout.glyphRuns().at(0); + QRawFont rawFont = glyphs.rawFont(); + QCOMPARE(rawFont.pixelSize(), 12.0); + + rawFont.setPixelSize(24); + QCOMPARE(rawFont.pixelSize(), 24.0); +} + #endif // QT_NO_RAWFONT QTEST_MAIN(tst_QRawFont) diff --git a/tests/auto/qreadwritelock/tst_qreadwritelock.cpp b/tests/auto/qreadwritelock/tst_qreadwritelock.cpp index e0cc2fa..0d575a1 100644 --- a/tests/auto/qreadwritelock/tst_qreadwritelock.cpp +++ b/tests/auto/qreadwritelock/tst_qreadwritelock.cpp @@ -362,34 +362,45 @@ void tst_QReadWriteLock::tryWriteLock() class Thread : public QThread { public: + Thread() : failureCount(0) { } void run() { testsTurn.release(); threadsTurn.acquire(); - Q_ASSERT(!readWriteLock.tryLockForWrite()); + if (readWriteLock.tryLockForWrite()) + failureCount++; testsTurn.release(); threadsTurn.acquire(); - Q_ASSERT(readWriteLock.tryLockForWrite()); - Q_ASSERT(lockCount.testAndSetRelaxed(0, 1)); - Q_ASSERT(lockCount.testAndSetRelaxed(1, 0)); + if (!readWriteLock.tryLockForWrite()) + failureCount++; + if (!lockCount.testAndSetRelaxed(0, 1)) + failureCount++; + if (!lockCount.testAndSetRelaxed(1, 0)) + failureCount++; readWriteLock.unlock(); testsTurn.release(); threadsTurn.acquire(); - Q_ASSERT(!readWriteLock.tryLockForWrite(1000)); + if (readWriteLock.tryLockForWrite(1000)) + failureCount++; testsTurn.release(); threadsTurn.acquire(); - Q_ASSERT(readWriteLock.tryLockForWrite(1000)); - Q_ASSERT(lockCount.testAndSetRelaxed(0, 1)); - Q_ASSERT(lockCount.testAndSetRelaxed(1, 0)); + if (!readWriteLock.tryLockForWrite(1000)) + failureCount++; + if (!lockCount.testAndSetRelaxed(0, 1)) + failureCount++; + if (!lockCount.testAndSetRelaxed(1, 0)) + failureCount++; readWriteLock.unlock(); testsTurn.release(); threadsTurn.acquire(); } + + int failureCount; }; Thread thread; @@ -419,6 +430,8 @@ void tst_QReadWriteLock::tryWriteLock() testsTurn.acquire(); threadsTurn.release(); thread.wait(); + + QCOMPARE(thread.failureCount, 0); } } diff --git a/tests/auto/qscriptable/tst_qscriptable.cpp b/tests/auto/qscriptable/tst_qscriptable.cpp index f5d36ea..97af050 100644 --- a/tests/auto/qscriptable/tst_qscriptable.cpp +++ b/tests/auto/qscriptable/tst_qscriptable.cpp @@ -137,8 +137,8 @@ int MyScriptable::getArgumentCount() void MyScriptable::foo() { m_lastEngine = engine(); - QVERIFY(engine() != 0); - context()->throwError("MyScriptable.foo"); + if (engine()) + context()->throwError("MyScriptable.foo"); } void MyScriptable::evalIsBar() @@ -164,15 +164,15 @@ void MyScriptable::setOtherEngine() void MyScriptable::setX(int x) { m_lastEngine = engine(); - Q_ASSERT(engine()); - thisObject().setProperty("x", QScriptValue(engine(), x)); + if (engine()) + thisObject().setProperty("x", QScriptValue(engine(), x)); } void MyScriptable::setX(const QString &x) { m_lastEngine = engine(); - Q_ASSERT(engine()); - thisObject().setProperty("x", QScriptValue(engine(), x)); + if (engine()) + thisObject().setProperty("x", QScriptValue(engine(), x)); } void MyScriptable::setX2(int) @@ -291,6 +291,7 @@ void tst_QScriptable::thisObject() "o.setX(123);" "o.__proto__ = Object.prototype;" "o.x"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.strictlyEquals(QScriptValue(&m_engine, 123)), true); } { @@ -298,46 +299,55 @@ void tst_QScriptable::thisObject() "o.setX2(456);" "o.__proto__ = Object.prototype;" "o.x"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.strictlyEquals(QScriptValue(&m_engine, 456)), true); } m_engine.evaluate("o.__proto__ = scriptable"); { QScriptValue ret = m_engine.evaluate("o.isBar()"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.strictlyEquals(QScriptValue(&m_engine, false)), true); } { QScriptValue ret = m_engine.evaluate("o.toString = function() { return 'foo@bar'; }; o.isBar()"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.strictlyEquals(QScriptValue(&m_engine, true)), true); } // property getter { QScriptValue ret = m_engine.evaluate("scriptable.zab"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.isQObject(), true); QCOMPARE(ret.toQObject(), (QObject *)&m_scriptable); } { QScriptValue ret = m_engine.evaluate("scriptable[1]"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.isQObject(), true); QCOMPARE(ret.toQObject(), (QObject *)&m_scriptable); } { QScriptValue ret = m_engine.evaluate("o.zab"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.toQObject(), (QObject *)0); } // property setter { QScriptValue ret = m_engine.evaluate("scriptable.setZab(null)"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.isQObject(), true); QCOMPARE(ret.toQObject(), (QObject *)&m_scriptable); } { QVERIFY(!m_scriptable.oofThisObject().isValid()); m_engine.evaluate("o.oof = 123"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QVERIFY(m_scriptable.oofThisObject().strictlyEquals(m_engine.evaluate("o"))); } { m_engine.evaluate("scriptable.oof = 123"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QVERIFY(m_scriptable.oofThisObject().strictlyEquals(m_engine.evaluate("scriptable"))); } @@ -345,13 +355,17 @@ void tst_QScriptable::thisObject() { { QScriptValue ret = m_engine.evaluate("scriptable.sig.connect(o, scriptable.setX)"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QVERIFY(ret.isUndefined()); } QVERIFY(m_engine.evaluate("o.x").strictlyEquals(QScriptValue(&m_engine, 456))); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); m_scriptable.emitSig(654321); QVERIFY(m_engine.evaluate("o.x").strictlyEquals(QScriptValue(&m_engine, 654321))); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); { QScriptValue ret = m_engine.evaluate("scriptable.sig.disconnect(o, scriptable.setX)"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QVERIFY(ret.isUndefined()); } } @@ -383,6 +397,7 @@ void tst_QScriptable::arguments() void tst_QScriptable::throwError() { QScriptValue ret = m_engine.evaluate("scriptable.foo()"); + QCOMPARE(m_scriptable.lastEngine(), &m_engine); QCOMPARE(ret.isError(), true); QCOMPARE(ret.toString(), QString("Error: MyScriptable.foo")); } diff --git a/tests/auto/qscriptclass/tst_qscriptclass.cpp b/tests/auto/qscriptclass/tst_qscriptclass.cpp index 9ab8318..4d27672 100644 --- a/tests/auto/qscriptclass/tst_qscriptclass.cpp +++ b/tests/auto/qscriptclass/tst_qscriptclass.cpp @@ -369,8 +369,7 @@ QVariant TestClass::extension(Extension extension, { m_lastExtensionType = extension; m_lastExtensionArgument = argument; - if (extension == Callable) { - Q_ASSERT(m_callableMode != NotCallable); + if (extension == Callable && m_callableMode != NotCallable) { QScriptContext *ctx = qvariant_cast<QScriptContext*>(argument); if (m_callableMode == CallableReturnsSum) { qsreal sum = 0; @@ -398,8 +397,7 @@ QVariant TestClass::extension(Extension extension, engine()->newQObject(ctx->thisObject(), engine()); return QVariant(); } - } else if (extension == HasInstance) { - Q_ASSERT(m_hasInstance); + } else if (extension == HasInstance && m_hasInstance) { QScriptValueList args = qvariant_cast<QScriptValueList>(argument); QScriptValue obj = args.at(0); QScriptValue value = args.at(1); diff --git a/tests/auto/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index bc4091d..b613405 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -5701,7 +5701,10 @@ void tst_QScriptEngine::collectGarbageAfterNativeArguments() static QScriptValue constructQObjectFromThisObject(QScriptContext *ctx, QScriptEngine *eng) { - Q_ASSERT(ctx->isCalledAsConstructor()); + if (!ctx->isCalledAsConstructor()) { + qWarning("%s: ctx->isCalledAsConstructor() returned false", Q_FUNC_INFO); + return QScriptValue(); + } return eng->newQObject(ctx->thisObject(), new QObject, QScriptEngine::ScriptOwnership); } @@ -5815,6 +5818,7 @@ void tst_QScriptEngine::dateConversionJSQt() QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate); QString jsUTCDateStr = jsDate.property("toISOString").call(jsDate).toString(); jsUTCDateStr.chop(5); // get rid of milliseconds (".000Z") + jsUTCDateStr.append("Z"); // append the timezone specifier again if (qtUTCDateStr != jsUTCDateStr) QFAIL(qPrintable(jsDate.toString())); secs += 2*60*60; @@ -5829,6 +5833,7 @@ void tst_QScriptEngine::dateConversionQtJS() QScriptValue jsDate = eng.newDate(qtDate); QString jsUTCDateStr = jsDate.property("toISOString").call(jsDate).toString(); jsUTCDateStr.chop(5); // get rid of milliseconds (".000Z") + jsUTCDateStr.append("Z"); // append the timezone specifier again QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate); if (jsUTCDateStr != qtUTCDateStr) QFAIL(qPrintable(qtDate.toString())); diff --git a/tests/auto/qscriptenginedebugger/tst_qscriptenginedebugger.cpp b/tests/auto/qscriptenginedebugger/tst_qscriptenginedebugger.cpp index 70adb58..1a3ad2c 100644 --- a/tests/auto/qscriptenginedebugger/tst_qscriptenginedebugger.cpp +++ b/tests/auto/qscriptenginedebugger/tst_qscriptenginedebugger.cpp @@ -76,9 +76,6 @@ public: tst_QScriptEngineDebugger(); virtual ~tst_QScriptEngineDebugger(); -protected slots: - void recordDebuggerStateAndContinue(); - private slots: void attachAndDetach(); void action(); @@ -89,9 +86,6 @@ private slots: void multithreadedDebugging(); void autoShowStandardWindow(); void standardWindowOwnership(); - -private: - QScriptEngineDebugger::DebuggerState m_recordedDebuggerState; }; tst_QScriptEngineDebugger::tst_QScriptEngineDebugger() @@ -102,14 +96,6 @@ tst_QScriptEngineDebugger::~tst_QScriptEngineDebugger() { } -void tst_QScriptEngineDebugger::recordDebuggerStateAndContinue() -{ - QScriptEngineDebugger *debugger = qobject_cast<QScriptEngineDebugger*>(sender()); - Q_ASSERT(debugger != 0); - m_recordedDebuggerState = debugger->state(); - debugger->action(QScriptEngineDebugger::ContinueAction)->trigger(); -} - void tst_QScriptEngineDebugger::attachAndDetach() { #if defined(Q_OS_WINCE) && _WIN32_WCE < 0x600 diff --git a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp index b35fd06..75c9acb 100644 --- a/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp +++ b/tests/auto/qscriptv8testsuite/tst_qscriptv8testsuite.cpp @@ -95,9 +95,11 @@ protected: static QScriptValue qscript_fail(QScriptContext *ctx, QScriptEngine *eng) { QScriptValue realFail = ctx->callee().data(); - Q_ASSERT(realFail.isFunction()); + if (!realFail.isFunction()) + qFatal("%s: realFail must be a function", Q_FUNC_INFO); QScriptValue ret = realFail.call(ctx->thisObject(), ctx->argumentsObject()); - Q_ASSERT(eng->hasUncaughtException()); + if (!eng->hasUncaughtException()) + qFatal("%s: realFail function did not throw an exception", Q_FUNC_INFO); ret.setProperty("expected", ctx->argument(0)); ret.setProperty("actual", ctx->argument(1)); ret.setProperty("message", ctx->argument(2)); @@ -153,10 +155,14 @@ void tst_QScriptV8TestSuite::runTestFunction(int testIndex) QScriptValue ret = engine.evaluate(contents); if (engine.hasUncaughtException()) { if (!ret.isError()) { - Q_ASSERT(ret.instanceOf(engine.globalObject().property("MjsUnitAssertionError"))); + int lineNumber = ret.property("lineNumber").toInt32(); + QTest::qVerify(ret.instanceOf(engine.globalObject().property("MjsUnitAssertionError")), + ret.toString().toLatin1(), + "", + path.toLatin1(), + lineNumber); QString actual = ret.property("actual").toString(); QString expected = ret.property("expected").toString(); - int lineNumber = ret.property("lineNumber").toInt32(); QString failMessage; if (shouldGenerateExpectedFailures) { if (ret.property("message").isString()) diff --git a/tests/auto/qscriptvaluegenerated/testgen/testgenerator.cpp b/tests/auto/qscriptvaluegenerated/testgen/testgenerator.cpp index 4d20f89..c9eacd4 100644 --- a/tests/auto/qscriptvaluegenerated/testgen/testgenerator.cpp +++ b/tests/auto/qscriptvaluegenerated/testgen/testgenerator.cpp @@ -467,7 +467,7 @@ QString generateCastDef<qsreal>(const QList<QPair<QString, qsreal> >& list) QString::number(list.count())); } -static QString generateCompareDef(const QString& comparisionType, const QList<QString> tags) +static QString generateCompareDef(const QString& comparisonType, const QList<QString> tags) { static const QString templ = "\n"\ "void tst_QScriptValueGenerated::%1_initData()\n"\ @@ -501,10 +501,11 @@ static QString generateCompareDef(const QString& comparisionType, const QList<QS "}\n"\ "\n"\ "DEFINE_TEST_FUNCTION(%1)\n"; - Q_ASSERT(comparisionType == "strictlyEquals" - || comparisionType == "equals" - || comparisionType == "lessThan" - || comparisionType == "instanceOf"); + if (comparisonType != "strictlyEquals" + && comparisonType != "equals" + && comparisonType != "lessThan" + && comparisonType != "instanceOf") + qFatal("%s: Unknown comparisonType: %s", Q_FUNC_INFO, qPrintable(comparisonType)); QString result = templ; QStringList set; @@ -516,7 +517,7 @@ static QString generateCompareDef(const QString& comparisionType, const QList<QS set.append(escape(tmp)); set.append("\""); } - return result.arg(comparisionType, set.join(""), QString::number(tags.count())); + return result.arg(comparisonType, set.join(""), QString::number(tags.count())); } static QString generateInitDef(const QVector<QString>& allDataTags) @@ -545,6 +546,17 @@ static void squashTags(QString dataTag, const QVector<bool>& results, QList<QStr } } +static QString streamStatusString(QDataStream::Status s) +{ + switch (s) { + case QDataStream::ReadPastEnd: + return QString("ReadPastEnd"); + case QDataStream::ReadCorruptData: + return QString("ReadCorruptData"); + default: + return QString("Unknown (%1)").arg(static_cast<int>(s)); + } +} QHash<QString, QString> TestGenerator::generateTest() { @@ -596,7 +608,10 @@ QHash<QString, QString> TestGenerator::generateTest() m_tempFile.seek(0); QDataStream in(&m_tempFile); in >> dataTags; - Q_ASSERT(in.status() == in.Ok); + if (in.status() != in.Ok) + qFatal("%s: stream has bad status %s after reading dataTags", + Q_FUNC_INFO, + qPrintable(streamStatusString(in.status()))); while(!in.atEnd()) { @@ -720,10 +735,13 @@ QHash<QString, QString> TestGenerator::generateTest() castUInt32List.append(QPair<QString, quint32>(dataTag, castUInt32Res)); castUInt16List.append(QPair<QString, quint16>(dataTag, castUInt16Res)); - Q_ASSERT(in.status() == in.Ok); + if (in.status() != in.Ok) + qFatal("%s: stream has bad status %s after reading data items", + Q_FUNC_INFO, + qPrintable(streamStatusString(in.status()))); } - - Q_ASSERT(in.atEnd()); + if (!in.atEnd()) + qFatal("%s: stream has more data after reading all data items", Q_FUNC_INFO); // Generate. QHash<QString, QString> result; diff --git a/tests/auto/qscriptvaluegenerated/testgen/testgenerator.h b/tests/auto/qscriptvaluegenerated/testgen/testgenerator.h index be4f79f..d3096c0 100644 --- a/tests/auto/qscriptvaluegenerated/testgen/testgenerator.h +++ b/tests/auto/qscriptvaluegenerated/testgen/testgenerator.h @@ -59,7 +59,8 @@ public: void run() { prepareData(); - Q_ASSERT(m_tempFile.size()); + if (!m_tempFile.size()) + qFatal("%s: prepareData failed to generate any data", Q_FUNC_INFO); save(generateTest()); } diff --git a/tests/auto/qscriptvalueiterator/tst_qscriptvalueiterator.cpp b/tests/auto/qscriptvalueiterator/tst_qscriptvalueiterator.cpp index 03e5c0f..1d4745e 100644 --- a/tests/auto/qscriptvalueiterator/tst_qscriptvalueiterator.cpp +++ b/tests/auto/qscriptvalueiterator/tst_qscriptvalueiterator.cpp @@ -106,7 +106,7 @@ void tst_QScriptValueIterator::iterateForward() QFETCH(QStringList, propertyNames); QFETCH(QStringList, propertyValues); QMap<QString, QString> pmap; - Q_ASSERT(propertyNames.size() == propertyValues.size()); + QVERIFY(propertyNames.size() == propertyValues.size()); QScriptEngine engine; QScriptValue object = engine.newObject(); @@ -165,7 +165,7 @@ void tst_QScriptValueIterator::iterateBackward() QFETCH(QStringList, propertyNames); QFETCH(QStringList, propertyValues); QMap<QString, QString> pmap; - Q_ASSERT(propertyNames.size() == propertyValues.size()); + QVERIFY(propertyNames.size() == propertyValues.size()); QScriptEngine engine; QScriptValue object = engine.newObject(); diff --git a/tests/auto/qscroller/qscroller.pro b/tests/auto/qscroller/qscroller.pro deleted file mode 100644 index 845dcb9..0000000 --- a/tests/auto/qscroller/qscroller.pro +++ /dev/null @@ -1,3 +0,0 @@ -load(qttest_p4) - -SOURCES += tst_qscroller.cpp diff --git a/tests/auto/qscroller/tst_qscroller.cpp b/tests/auto/qscroller/tst_qscroller.cpp deleted file mode 100644 index a9b3d9f..0000000 --- a/tests/auto/qscroller/tst_qscroller.cpp +++ /dev/null @@ -1,537 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the $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 <QtGui> -#include <QtTest> -// #include <QDebug> - -class tst_QScrollerWidget : public QWidget -{ -public: - tst_QScrollerWidget() - : QWidget() - { - reset(); - } - - void reset() - { - receivedPrepare = false; - receivedScroll = false; - receivedFirst = false; - receivedLast = false; - receivedOvershoot = false; - } - - bool event(QEvent *e) - { - switch (e->type()) { - case QEvent::Gesture: - e->setAccepted(false); // better reject the event or QGestureManager will make trouble - return false; - - case QEvent::ScrollPrepare: - { - receivedPrepare = true; - QScrollPrepareEvent *se = static_cast<QScrollPrepareEvent *>(e); - se->setViewportSize(QSizeF(100,100)); - se->setContentPosRange(scrollArea); - se->setContentPos(scrollPosition); - se->accept(); - return true; - } - - case QEvent::Scroll: - { - receivedScroll = true; - QScrollEvent *se = static_cast<QScrollEvent *>(e); - // qDebug() << "Scroll for"<<this<<"pos"<<se->scrollPos()<<"ov"<<se->overshoot()<<"first"<<se->isFirst()<<"last"<<se->isLast(); - - if (se->scrollState() == QScrollEvent::ScrollStarted) - receivedFirst = true; - if (se->scrollState() == QScrollEvent::ScrollFinished) - receivedLast = true; - - currentPos = se->contentPos(); - overshoot = se->overshootDistance(); - if (!qFuzzyCompare( overshoot.x() + 1.0, 1.0 ) || - !qFuzzyCompare( overshoot.y() + 1.0, 1.0 )) - receivedOvershoot = true; - return true; - } - - default: - return QObject::event(e); - } - } - - - QRectF scrollArea; - QPointF scrollPosition; - - bool receivedPrepare; - bool receivedScroll; - bool receivedFirst; - bool receivedLast; - bool receivedOvershoot; - - QPointF currentPos; - QPointF overshoot; -}; - - -class tst_QScroller : public QObject -{ - Q_OBJECT -public: - tst_QScroller() { } - ~tst_QScroller() { } - -private: - void kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd); - void kineticScrollNoTest( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd); - -private slots: - void staticScrollers(); - void scrollerProperties(); - void scrollTo(); - void scroll(); - void overshoot(); -}; - -/*! \internal - Generates touchBegin, touchUpdate and touchEnd events to trigger scrolling. - Tests some in between states but does not wait until scrolling is finished. -*/ -void tst_QScroller::kineticScroll( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd) -{ - sw->scrollPosition = from; - sw->currentPos= from; - - QScroller *s1 = QScroller::scroller(sw); - QCOMPARE( s1->state(), QScroller::Inactive ); - - QScrollerProperties sp1 = QScroller::scroller(sw)->scrollerProperties(); - int fps = 60; - - QTouchEvent::TouchPoint rawTouchPoint; - rawTouchPoint.setId(0); - - // send the touch begin event - QTouchEvent::TouchPoint touchPoint(0); - touchPoint.setState(Qt::TouchPointPressed); - touchPoint.setPos(touchStart); - touchPoint.setScenePos(touchStart); - touchPoint.setScreenPos(touchStart); - QTouchEvent touchEvent1(QEvent::TouchBegin, - QTouchEvent::TouchScreen, - Qt::NoModifier, - Qt::TouchPointPressed, - (QList<QTouchEvent::TouchPoint>() << touchPoint)); - QApplication::sendEvent(sw, &touchEvent1); - - QCOMPARE( s1->state(), QScroller::Pressed ); - - // send the touch update far enough to trigger a scroll - QTest::qWait(200); // we need to wait a little or else the speed would be infinite. now we have around 500 pixel per second. - touchPoint.setPos(touchUpdate); - touchPoint.setScenePos(touchUpdate); - touchPoint.setScreenPos(touchUpdate); - QTouchEvent touchEvent2(QEvent::TouchUpdate, - QTouchEvent::TouchScreen, - Qt::NoModifier, - Qt::TouchPointMoved, - (QList<QTouchEvent::TouchPoint>() << touchPoint)); - QApplication::sendEvent(sw, &touchEvent2); - - QCOMPARE( s1->state(), QScroller::Dragging ); - QCOMPARE( sw->receivedPrepare, true ); - - - QTest::qWait(1000 / fps * 2); // wait until the first scroll move - QCOMPARE( sw->receivedFirst, true ); - QCOMPARE( sw->receivedScroll, true ); - QCOMPARE( sw->receivedOvershoot, false ); - - // note that the scrolling goes in a different direction than the mouse move - QPoint calculatedPos = from.toPoint() - touchUpdate - touchStart; - QVERIFY(qAbs(sw->currentPos.x() - calculatedPos.x()) < 1.0); - QVERIFY(qAbs(sw->currentPos.y() - calculatedPos.y()) < 1.0); - - // send the touch end - touchPoint.setPos(touchEnd); - touchPoint.setScenePos(touchEnd); - touchPoint.setScreenPos(touchEnd); - QTouchEvent touchEvent5(QEvent::TouchEnd, - QTouchEvent::TouchScreen, - Qt::NoModifier, - Qt::TouchPointReleased, - (QList<QTouchEvent::TouchPoint>() << touchPoint)); - QApplication::sendEvent(sw, &touchEvent5); -} - -/*! \internal - Generates touchBegin, touchUpdate and touchEnd events to trigger scrolling. - This function does not have any in between tests, it does not expect the scroller to actually scroll. -*/ -void tst_QScroller::kineticScrollNoTest( tst_QScrollerWidget *sw, QPointF from, QPoint touchStart, QPoint touchUpdate, QPoint touchEnd) -{ - sw->scrollPosition = from; - sw->currentPos = from; - - QScroller *s1 = QScroller::scroller(sw); - QCOMPARE( s1->state(), QScroller::Inactive ); - - QScrollerProperties sp1 = s1->scrollerProperties(); - int fps = 60; - - QTouchEvent::TouchPoint rawTouchPoint; - rawTouchPoint.setId(0); - - // send the touch begin event - QTouchEvent::TouchPoint touchPoint(0); - touchPoint.setState(Qt::TouchPointPressed); - touchPoint.setPos(touchStart); - touchPoint.setScenePos(touchStart); - touchPoint.setScreenPos(touchStart); - QTouchEvent touchEvent1(QEvent::TouchBegin, - QTouchEvent::TouchScreen, - Qt::NoModifier, - Qt::TouchPointPressed, - (QList<QTouchEvent::TouchPoint>() << touchPoint)); - QApplication::sendEvent(sw, &touchEvent1); - - // send the touch update far enough to trigger a scroll - QTest::qWait(200); // we need to wait a little or else the speed would be infinite. now we have around 500 pixel per second. - touchPoint.setPos(touchUpdate); - touchPoint.setScenePos(touchUpdate); - touchPoint.setScreenPos(touchUpdate); - QTouchEvent touchEvent2(QEvent::TouchUpdate, - QTouchEvent::TouchScreen, - Qt::NoModifier, - Qt::TouchPointMoved, - (QList<QTouchEvent::TouchPoint>() << touchPoint)); - QApplication::sendEvent(sw, &touchEvent2); - - QTest::qWait(1000 / fps * 2); // wait until the first scroll move - - // send the touch end - touchPoint.setPos(touchEnd); - touchPoint.setScenePos(touchEnd); - touchPoint.setScreenPos(touchEnd); - QTouchEvent touchEvent5(QEvent::TouchEnd, - QTouchEvent::TouchScreen, - Qt::NoModifier, - Qt::TouchPointReleased, - (QList<QTouchEvent::TouchPoint>() << touchPoint)); - QApplication::sendEvent(sw, &touchEvent5); -} - - -void tst_QScroller::staticScrollers() -{ - // scrollers - { - QObject *o1 = new QObject(this); - QObject *o2 = new QObject(this); - - // get scroller for object - QScroller *s1 = QScroller::scroller(o1); - QScroller *s2 = QScroller::scroller(o2); - - QVERIFY(s1); - QVERIFY(s2); - QVERIFY(s1 != s2); - - QVERIFY(!QScroller::scroller(static_cast<const QObject*>(0))); - QCOMPARE(QScroller::scroller(o1), s1); - - delete o1; - delete o2; - } - - // the same for properties - { - QObject *o1 = new QObject(this); - QObject *o2 = new QObject(this); - - // get scroller for object - QScrollerProperties sp1 = QScroller::scroller(o1)->scrollerProperties(); - QScrollerProperties sp2 = QScroller::scroller(o2)->scrollerProperties(); - - // default properties should be the same - QVERIFY(sp1 == sp2); - - QCOMPARE(QScroller::scroller(o1)->scrollerProperties(), sp1); - - delete o1; - delete o2; - } -} - -void tst_QScroller::scrollerProperties() -{ - QObject *o1 = new QObject(this); - QScrollerProperties sp1 = QScroller::scroller(o1)->scrollerProperties(); - - QScrollerProperties::ScrollMetric metrics[] = - { - QScrollerProperties::MousePressEventDelay, // qreal [s] - QScrollerProperties::DragStartDistance, // qreal [m] - QScrollerProperties::DragVelocitySmoothingFactor, // qreal [0..1/s] (complex calculation involving time) v = v_new* DASF + v_old * (1-DASF) - QScrollerProperties::AxisLockThreshold, // qreal [0..1] atan(|min(dx,dy)|/|max(dx,dy)|) - - QScrollerProperties::DecelerationFactor, // slope of the curve - - QScrollerProperties::MinimumVelocity, // qreal [m/s] - QScrollerProperties::MaximumVelocity, // qreal [m/s] - QScrollerProperties::MaximumClickThroughVelocity, // qreal [m/s] - - QScrollerProperties::AcceleratingFlickMaximumTime, // qreal [s] - QScrollerProperties::AcceleratingFlickSpeedupFactor, // qreal [1..] - - QScrollerProperties::SnapPositionRatio, // qreal [0..1] - QScrollerProperties::SnapTime, // qreal [s] - - QScrollerProperties::OvershootDragResistanceFactor, // qreal [0..1] - QScrollerProperties::OvershootDragDistanceFactor, // qreal [0..1] - QScrollerProperties::OvershootScrollDistanceFactor, // qreal [0..1] - QScrollerProperties::OvershootScrollTime, // qreal [s] - }; - - for (unsigned int i = 0; i < sizeof(metrics) / sizeof(metrics[0]); i++) { - sp1.setScrollMetric(metrics[i], 0.9); - QCOMPARE(sp1.scrollMetric(metrics[i]).toDouble(), 0.9); - } - sp1.setScrollMetric(QScrollerProperties::ScrollingCurve, QEasingCurve(QEasingCurve::OutQuart)); - QCOMPARE(sp1.scrollMetric(QScrollerProperties::ScrollingCurve).toEasingCurve().type(), QEasingCurve::OutQuart); - - sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff)); - QCOMPARE(sp1.scrollMetric(QScrollerProperties::HorizontalOvershootPolicy).value<QScrollerProperties::OvershootPolicy>(), QScrollerProperties::OvershootAlwaysOff); - - sp1.setScrollMetric(QScrollerProperties::VerticalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn)); - QCOMPARE(sp1.scrollMetric(QScrollerProperties::VerticalOvershootPolicy).value<QScrollerProperties::OvershootPolicy>(), QScrollerProperties::OvershootAlwaysOn); - - sp1.setScrollMetric(QScrollerProperties::FrameRate, QVariant::fromValue(QScrollerProperties::Fps20)); - QCOMPARE(sp1.scrollMetric(QScrollerProperties::FrameRate).value<QScrollerProperties::FrameRates>(), QScrollerProperties::Fps20); -} - -void tst_QScroller::scrollTo() -{ - { - tst_QScrollerWidget *sw = new tst_QScrollerWidget(); - sw->scrollArea = QRectF( 0, 0, 1000, 1000 ); - sw->scrollPosition = QPointF( 500, 500 ); - - QScroller *s1 = QScroller::scroller(sw); - QCOMPARE( s1->state(), QScroller::Inactive ); - - // a normal scroll - s1->scrollTo(QPointF(100,100), 100); - QTest::qWait(200); - - QCOMPARE( sw->receivedPrepare, true ); - QCOMPARE( sw->receivedScroll, true ); - QCOMPARE( sw->receivedFirst, true ); - QCOMPARE( sw->receivedLast, true ); - QCOMPARE( sw->receivedOvershoot, false ); - QVERIFY(qFuzzyCompare( sw->currentPos.x(), 100 )); - QVERIFY(qFuzzyCompare( sw->currentPos.y(), 100 )); - - delete sw; - } -} - -void tst_QScroller::scroll() -{ -#if defined(Q_OS_MACX) && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6) - QSKIP("Mac OS X < 10.6 does not support QTouchEvents", SkipAll); - return; -#endif - -#ifndef QT_NO_GESTURES - // -- good case. normal scroll - tst_QScrollerWidget *sw = new tst_QScrollerWidget(); - sw->scrollArea = QRectF(0, 0, 1000, 1000); - QScroller::grabGesture(sw, QScroller::TouchGesture); - sw->setGeometry(100, 100, 400, 300); - - QScroller *s1 = QScroller::scroller(sw); - kineticScroll(sw, QPointF(500, 500), QPoint(0, 0), QPoint(100, 100), QPoint(200, 200)); - // now we should be scrolling - QCOMPARE( s1->state(), QScroller::Scrolling ); - - // wait until finished, check that no further first scroll is send - sw->receivedFirst = false; - sw->receivedScroll = false; - while (s1->state() == QScroller::Scrolling) - QTest::qWait(100); - - QCOMPARE( sw->receivedFirst, false ); - QCOMPARE( sw->receivedScroll, true ); - QCOMPARE( sw->receivedLast, true ); - QVERIFY(sw->currentPos.x() < 400); - QVERIFY(sw->currentPos.y() < 400); - - // -- try to scroll when nothing to scroll - - sw->reset(); - sw->scrollArea = QRectF(0, 0, 0, 1000); - kineticScrollNoTest(sw, QPointF(0, 500), QPoint(0, 0), QPoint(100, 0), QPoint(200, 0)); - - while (s1->state() != QScroller::Inactive) - QTest::qWait(20); - - QCOMPARE(sw->currentPos.x(), 0.0); - QCOMPARE(sw->currentPos.y(), 500.0); - - delete sw; -#endif -} - -void tst_QScroller::overshoot() -{ -#if defined(Q_OS_MACX) && (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6) - QSKIP("Mac OS X < 10.6 does not support QTouchEvents", SkipAll); - return; -#endif - -#ifndef QT_NO_GESTURES - tst_QScrollerWidget *sw = new tst_QScrollerWidget(); - sw->scrollArea = QRectF(0, 0, 1000, 1000); - QScroller::grabGesture(sw, QScroller::TouchGesture); - sw->setGeometry(100, 100, 400, 300); - - QScroller *s1 = QScroller::scroller(sw); - QScrollerProperties sp1 = s1->scrollerProperties(); - - sp1.setScrollMetric(QScrollerProperties::OvershootDragResistanceFactor, 0.5); - sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.2); - sp1.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.2); - - // -- try to scroll with overshoot (when scrollable good case) - - sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable)); - s1->setScrollerProperties(sp1); - kineticScrollNoTest(sw, QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); - - while (s1->state() != QScroller::Inactive) - QTest::qWait(20); - - //qDebug() << "Overshoot fuzzy: "<<sw->currentPos; - QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); - QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); - QCOMPARE( sw->receivedOvershoot, true ); - - // -- try to scroll with overshoot (when scrollable bad case) - sw->reset(); - sw->scrollArea = QRectF(0, 0, 0, 1000); - - sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootWhenScrollable)); - s1->setScrollerProperties(sp1); - kineticScrollNoTest(sw, QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); - - while (s1->state() != QScroller::Inactive) - QTest::qWait(20); - - //qDebug() << "Overshoot fuzzy: "<<sw->currentPos; - QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); - QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); - QCOMPARE( sw->receivedOvershoot, false ); - - // -- try to scroll with overshoot (always on) - sw->reset(); - sw->scrollArea = QRectF(0, 0, 0, 1000); - - sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn)); - s1->setScrollerProperties(sp1); - kineticScrollNoTest(sw, QPointF(0, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); - - while (s1->state() != QScroller::Inactive) - QTest::qWait(20); - - //qDebug() << "Overshoot fuzzy: "<<sw->currentPos; - - QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); - QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); - QCOMPARE( sw->receivedOvershoot, true ); - - // -- try to scroll with overshoot (always off) - sw->reset(); - sw->scrollArea = QRectF(0, 0, 1000, 1000); - - sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOff)); - s1->setScrollerProperties(sp1); - kineticScrollNoTest(sw, QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); - - while (s1->state() != QScroller::Inactive) - QTest::qWait(20); - - QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); - QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); - QCOMPARE( sw->receivedOvershoot, false ); - - // -- try to scroll with overshoot (always on but max overshoot = 0) - sp1.setScrollMetric(QScrollerProperties::OvershootDragDistanceFactor, 0.0); - sp1.setScrollMetric(QScrollerProperties::OvershootScrollDistanceFactor, 0.0); - sw->reset(); - sw->scrollArea = QRectF(0, 0, 1000, 1000); - - sp1.setScrollMetric(QScrollerProperties::HorizontalOvershootPolicy, QVariant::fromValue(QScrollerProperties::OvershootAlwaysOn)); - s1->setScrollerProperties(sp1); - kineticScrollNoTest(sw, QPointF(500, 500), QPoint(0, 0), QPoint(400, 0), QPoint(490, 0)); - - while (s1->state() != QScroller::Inactive) - QTest::qWait(20); - - QVERIFY(qFuzzyCompare( sw->currentPos.x(), 0 )); - QVERIFY(qFuzzyCompare( sw->currentPos.y(), 500 )); - QCOMPARE( sw->receivedOvershoot, false ); - - - delete sw; -#endif -} - - -QTEST_MAIN(tst_QScroller) - -#include "tst_qscroller.moc" diff --git a/tests/auto/qsharedpointer/externaltests.cpp b/tests/auto/qsharedpointer/externaltests.cpp index 1ba03dc..b0490c9 100644 --- a/tests/auto/qsharedpointer/externaltests.cpp +++ b/tests/auto/qsharedpointer/externaltests.cpp @@ -50,6 +50,7 @@ #include <QtCore/QDir> #include <QtCore/QDirIterator> #include <QtCore/QDateTime> +#include <QtCore/QDebug> #ifdef Q_OS_SYMBIAN #define DEFAULT_MAKESPEC "X:/STLsupport/mkspecs/symbian-abld/" @@ -342,7 +343,8 @@ namespace QTest { void QExternalTestPrivate::removeTemporaryDirectory() { - Q_ASSERT(!temporaryDir.isEmpty()); + if (temporaryDir.isEmpty()) + qWarning() << "Temporary directory is expected to be non-empty"; removeRecursive(temporaryDir); temporaryDir.clear(); } @@ -487,7 +489,8 @@ namespace QTest { bool QExternalTestPrivate::createProjectFile() { - Q_ASSERT(!temporaryDir.isEmpty()); + if (temporaryDir.isEmpty()) + qWarning() << "Temporary directory is expected to be non-empty"; QFile projectFile(temporaryDir + QLatin1String("/project.pro")); if (!projectFile.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) { @@ -599,7 +602,9 @@ namespace QTest { bool QExternalTestPrivate::runQmake() { - Q_ASSERT(!temporaryDir.isEmpty()); + if (temporaryDir.isEmpty()) + qWarning() << "Temporary directory is expected to be non-empty"; + if (!createProjectFile()) return false; @@ -633,7 +638,8 @@ namespace QTest { bool QExternalTestPrivate::runMake(Target target) { - Q_ASSERT(!temporaryDir.isEmpty()); + if (temporaryDir.isEmpty()) + qWarning() << "Temporary directory is expected to be non-empty"; QExternalProcess make; make.setWorkingDirectory(temporaryDir); diff --git a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp index bb04621..6250219 100644 --- a/tests/auto/qsharedpointer/tst_qsharedpointer.cpp +++ b/tests/auto/qsharedpointer/tst_qsharedpointer.cpp @@ -139,7 +139,8 @@ public: virtual ~Data() { - Q_ASSERT_X(generation > 0, "tst_QSharedPointer", "Double deletion!"); + if (generation <= 0) + qFatal("tst_qsharedpointer: Double deletion!"); generation = 0; ++destructorCounter; } @@ -283,8 +284,8 @@ void tst_QSharedPointer::operators() QSharedPointer<char> p1; QSharedPointer<char> p2(new char); qptrdiff diff = p2.data() - p1.data(); - Q_ASSERT(p1.data() != p2.data()); - Q_ASSERT(diff != 0); + QVERIFY(p1.data() != p2.data()); + QVERIFY(diff != 0); // operator- QCOMPARE(p2 - p1.data(), diff); @@ -867,8 +868,8 @@ void tst_QSharedPointer::differentPointers() { DiffPtrDerivedData *aData = new DiffPtrDerivedData; Data *aBase = aData; - Q_ASSERT(aData == aBase); - Q_ASSERT(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); + QVERIFY(aData == aBase); + QVERIFY(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); QSharedPointer<Data> baseptr = QSharedPointer<Data>(aData); QSharedPointer<DiffPtrDerivedData> ptr = qSharedPointerCast<DiffPtrDerivedData>(baseptr); @@ -885,8 +886,8 @@ void tst_QSharedPointer::differentPointers() { DiffPtrDerivedData *aData = new DiffPtrDerivedData; Data *aBase = aData; - Q_ASSERT(aData == aBase); - Q_ASSERT(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); + QVERIFY(aData == aBase); + QVERIFY(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); QSharedPointer<DiffPtrDerivedData> ptr = QSharedPointer<DiffPtrDerivedData>(aData); QSharedPointer<Data> baseptr = ptr; @@ -908,8 +909,8 @@ void tst_QSharedPointer::virtualBaseDifferentPointers() { VirtualDerived *aData = new VirtualDerived; Data *aBase = aData; - Q_ASSERT(aData == aBase); - Q_ASSERT(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); + QVERIFY(aData == aBase); + QVERIFY(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); QSharedPointer<VirtualDerived> ptr = QSharedPointer<VirtualDerived>(aData); QSharedPointer<Data> baseptr = qSharedPointerCast<Data>(ptr); @@ -928,8 +929,8 @@ void tst_QSharedPointer::virtualBaseDifferentPointers() { VirtualDerived *aData = new VirtualDerived; Data *aBase = aData; - Q_ASSERT(aData == aBase); - Q_ASSERT(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); + QVERIFY(aData == aBase); + QVERIFY(*reinterpret_cast<quintptr *>(&aData) != *reinterpret_cast<quintptr *>(&aBase)); QSharedPointer<VirtualDerived> ptr = QSharedPointer<VirtualDerived>(aData); QSharedPointer<Data> baseptr = ptr; @@ -1605,7 +1606,7 @@ void hashAndMapTest() QVERIFY(it != c.find(Key())); if (Ordered) { - Q_ASSERT(k0 < k1); + QVERIFY(k0 < k1); it = c.begin(); QCOMPARE(it.key(), k0); diff --git a/tests/auto/qsocketnotifier/qsocketnotifier.pro b/tests/auto/qsocketnotifier/qsocketnotifier.pro index c43c96a..27484c8 100644 --- a/tests/auto/qsocketnotifier/qsocketnotifier.pro +++ b/tests/auto/qsocketnotifier/qsocketnotifier.pro @@ -4,7 +4,7 @@ QT = core network requires(contains(QT_CONFIG,private_tests)) -include(../qnativesocketengine/qsocketengine.pri) +include(../platformsocketengine/platformsocketengine.pri) symbian: TARGET.CAPABILITY = NetworkServices diff --git a/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp b/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp index 5594dc3..f966e7f 100644 --- a/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp +++ b/tests/auto/qsocketnotifier/tst_qsocketnotifier.cpp @@ -53,6 +53,11 @@ #include <private/qnativesocketengine_p.h> #define NATIVESOCKETENGINE QNativeSocketEngine #endif +#ifdef Q_OS_UNIX +#include <private/qnet_unix_p.h> +#endif +#include <limits> +#include <select.h> class tst_QSocketNotifier : public QObject { @@ -64,6 +69,8 @@ public: private slots: void unexpectedDisconnection(); void mixingWithTimers(); + void posixSockets(); + void bogusFds(); }; tst_QSocketNotifier::tst_QSocketNotifier() @@ -114,6 +121,9 @@ signals: void tst_QSocketNotifier::unexpectedDisconnection() { +#ifdef Q_OS_SYMBIAN + QSKIP("Symbian socket engine pseudo descriptors can't be used for QSocketNotifier", SkipAll); +#else /* Given two sockets and two QSocketNotifiers registered on each their socket. If both sockets receive data, and the first slot @@ -163,10 +173,14 @@ void tst_QSocketNotifier::unexpectedDisconnection() UnexpectedDisconnectTester tester(&readEnd1, &readEnd2); + QTimer timer; + timer.setSingleShot(true); + timer.start(30000); do { // we have to wait until sequence value changes // as any event can make us jump out processing QCoreApplication::processEvents(QEventLoop::WaitForMoreEvents); + QVERIFY(timer.isActive); //escape if test would hang } while(tester.sequence <= 0); QVERIFY(readEnd1.state() == QAbstractSocket::ConnectedState); @@ -179,6 +193,7 @@ void tst_QSocketNotifier::unexpectedDisconnection() writeEnd1->close(); writeEnd2->close(); server.close(); +#endif } class MixingWithTimersHelper : public QObject @@ -243,5 +258,99 @@ void tst_QSocketNotifier::mixingWithTimers() QCOMPARE(helper.socketActivated, true); } +void tst_QSocketNotifier::posixSockets() +{ +#ifndef Q_OS_UNIX + QSKIP("test only for posix", SkipAll); +#else + + QTcpServer server; + QVERIFY(server.listen(QHostAddress::LocalHost, 0)); + + int posixSocket = qt_safe_socket(AF_INET, SOCK_STREAM, 0); + sockaddr_in addr; + addr.sin_addr.s_addr = htonl(0x7f000001); + addr.sin_family = AF_INET; + addr.sin_port = htons(server.serverPort()); + qt_safe_connect(posixSocket, (const struct sockaddr*)&addr, sizeof(sockaddr_in)); + QVERIFY(server.waitForNewConnection(5000)); + QScopedPointer<QTcpSocket> passive(server.nextPendingConnection()); + + ::fcntl(posixSocket, F_SETFL, ::fcntl(posixSocket, F_GETFL) | O_NONBLOCK); + + { + QSocketNotifier rn(posixSocket, QSocketNotifier::Read); + connect(&rn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QSignalSpy readSpy(&rn, SIGNAL(activated(int))); + QSocketNotifier wn(posixSocket, QSocketNotifier::Write); + connect(&wn, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QSignalSpy writeSpy(&wn, SIGNAL(activated(int))); + QSocketNotifier en(posixSocket, QSocketNotifier::Exception); + connect(&en, SIGNAL(activated(int)), &QTestEventLoop::instance(), SLOT(exitLoop())); + QSignalSpy errorSpy(&en, SIGNAL(activated(int))); + + passive->write("hello",6); + passive->waitForBytesWritten(5000); + + QTestEventLoop::instance().enterLoop(3); + QCOMPARE(readSpy.count(), 1); + QCOMPARE(writeSpy.count(), 0); + QCOMPARE(errorSpy.count(), 0); + + char buffer[100]; + qt_safe_read(posixSocket, buffer, 100); + QCOMPARE(buffer, "hello"); + + qt_safe_write(posixSocket, "goodbye", 8); + + QTestEventLoop::instance().enterLoop(3); + QCOMPARE(readSpy.count(), 1); + QCOMPARE(writeSpy.count(), 1); + QCOMPARE(errorSpy.count(), 0); + QCOMPARE(passive->readAll(), QByteArray("goodbye",8)); + } + qt_safe_close(posixSocket); +#endif +} + +void tst_QSocketNotifier::bogusFds() +{ +#ifndef Q_OS_WIN + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Internal error"); +#endif + QSocketNotifier max(std::numeric_limits<int>::max(), QSocketNotifier::Read); + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Invalid socket specified"); +#ifndef Q_OS_WIN + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Internal error"); +#endif + QSocketNotifier min(std::numeric_limits<int>::min(), QSocketNotifier::Write); +#ifndef Q_OS_WIN + QTest::ignoreMessage(QtWarningMsg, "QSocketNotifier: Internal error"); +#endif + //bogus magic number is the first pseudo socket descriptor from symbian socket engine. + QSocketNotifier bogus(0x40000000, QSocketNotifier::Exception); + QSocketNotifier largestlegal(FD_SETSIZE - 1, QSocketNotifier::Read); + + QSignalSpy maxspy(&max, SIGNAL(activated(int))); + QSignalSpy minspy(&min, SIGNAL(activated(int))); + QSignalSpy bogspy(&bogus, SIGNAL(activated(int))); + QSignalSpy llspy(&largestlegal, SIGNAL(activated(int))); + + //generate some unrelated socket activity + QTcpServer server; + QVERIFY(server.listen(QHostAddress::LocalHost)); + connect(&server, SIGNAL(newConnection()), &QTestEventLoop::instance(), SLOT(exitLoop())); + QTcpSocket client; + client.connectToHost(QHostAddress::LocalHost, server.serverPort()); + QTestEventLoop::instance().enterLoop(5); + QVERIFY(server.hasPendingConnections()); + + //check no activity on bogus notifiers + QCOMPARE(maxspy.count(), 0); + QCOMPARE(minspy.count(), 0); + QCOMPARE(bogspy.count(), 0); + QCOMPARE(llspy.count(), 0); +} + QTEST_MAIN(tst_QSocketNotifier) #include <tst_qsocketnotifier.moc> diff --git a/tests/auto/qsplitter/tst_qsplitter.cpp b/tests/auto/qsplitter/tst_qsplitter.cpp index 0482661..60be944 100644 --- a/tests/auto/qsplitter/tst_qsplitter.cpp +++ b/tests/auto/qsplitter/tst_qsplitter.cpp @@ -1340,14 +1340,14 @@ void tst_QSplitter::task187373_addAbstractScrollAreas() QFETCH(QString, className); QFETCH(bool, addInConstructor); QFETCH(bool, addOutsideConstructor); - Q_ASSERT(addInConstructor || addOutsideConstructor); + QVERIFY(addInConstructor || addOutsideConstructor); QSplitter *splitter = new QSplitter; splitter->show(); - Q_ASSERT(splitter->isVisible()); + QVERIFY(splitter->isVisible()); QAbstractScrollArea *w = task187373_createScrollArea(splitter, className, addInConstructor); - Q_ASSERT(w); + QVERIFY(w); if (addOutsideConstructor) splitter->addWidget(w); diff --git a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp index 4462659..185e046 100644 --- a/tests/auto/qsqldatabase/tst_qsqldatabase.cpp +++ b/tests/auto/qsqldatabase/tst_qsqldatabase.cpp @@ -767,7 +767,7 @@ void tst_QSqlDatabase::checkValues(const FieldDef fieldDefs[], QSqlDatabase db) Q3SqlCursor cur(qTableName("qtestfields", __FILE__), true, db); QVERIFY_SQL(cur, select()); QSqlRecord* rec = cur.primeInsert(); - Q_ASSERT(rec); + QVERIFY(rec); rec->setValue("id", pkey++); int i = 0; for (i = 0; !fieldDefs[ i ].typeName.isNull(); ++i) { @@ -828,7 +828,7 @@ void tst_QSqlDatabase::checkNullValues(const FieldDef fieldDefs[], QSqlDatabase Q3SqlCursor cur(qTableName("qtestfields", __FILE__), true, db); QVERIFY_SQL(cur, select()); QSqlRecord* rec = cur.primeInsert(); - Q_ASSERT(rec); + QVERIFY(rec); rec->setValue("id", pkey++); int i = 0; for (i = 0; !fieldDefs[ i ].typeName.isNull(); ++i) { diff --git a/tests/auto/qsslsocket/tst_qsslsocket.cpp b/tests/auto/qsslsocket/tst_qsslsocket.cpp index b508d47..9badd0b 100644 --- a/tests/auto/qsslsocket/tst_qsslsocket.cpp +++ b/tests/auto/qsslsocket/tst_qsslsocket.cpp @@ -156,6 +156,7 @@ private slots: void setSslConfiguration_data(); void setSslConfiguration(); void waitForEncrypted(); + void waitForEncryptedMinusOne(); void waitForConnectedEncryptedReadyRead(); void startClientEncryption(); void startServerEncryption(); @@ -1098,6 +1099,20 @@ void tst_QSslSocket::waitForEncrypted() QVERIFY(socket->waitForEncrypted(10000)); } +void tst_QSslSocket::waitForEncryptedMinusOne() +{ + if (!QSslSocket::supportsSsl()) + return; + + QSslSocketPtr socket = newSocket(); + this->socket = socket; + + connect(socket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(ignoreErrorSlot())); + socket->connectToHostEncrypted(QtNetworkSettings::serverName(), 443); + + QVERIFY(socket->waitForEncrypted(-1)); +} + void tst_QSslSocket::waitForConnectedEncryptedReadyRead() { if (!QSslSocket::supportsSsl()) @@ -1565,8 +1580,8 @@ protected: // delayed start of encryption QTest::qSleep(100); QSslSocket *socket = server.socket; - QVERIFY(socket); - QVERIFY(socket->isValid()); + if (!socket || !socket->isValid()) + return; // error socket->ignoreSslErrors(); socket->startServerEncryption(); if (!socket->waitForEncrypted(2000)) diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp index 3d80e80..37a899c 100644 --- a/tests/auto/qstring/tst_qstring.cpp +++ b/tests/auto/qstring/tst_qstring.cpp @@ -3429,9 +3429,9 @@ void tst_QString::fromLatin1Roundtrip() QFETCH(QString, unicode); // QtTest safety check: - Q_ASSERT(latin1.isNull() == unicode.isNull()); - Q_ASSERT(latin1.isEmpty() == unicode.isEmpty()); - Q_ASSERT(latin1.length() == unicode.length()); + QCOMPARE(latin1.isNull(), unicode.isNull()); + QCOMPARE(latin1.isEmpty(), unicode.isEmpty()); + QCOMPARE(latin1.length(), unicode.length()); if (!latin1.isEmpty()) while (latin1.length() < 128) { @@ -3484,12 +3484,12 @@ void tst_QString::toLatin1Roundtrip() QFETCH(QString, unicodedst); // QtTest safety check: - Q_ASSERT(latin1.isNull() == unicodesrc.isNull()); - Q_ASSERT(latin1.isEmpty() == unicodesrc.isEmpty()); - Q_ASSERT(latin1.length() == unicodesrc.length()); - Q_ASSERT(latin1.isNull() == unicodedst.isNull()); - Q_ASSERT(latin1.isEmpty() == unicodedst.isEmpty()); - Q_ASSERT(latin1.length() == unicodedst.length()); + QCOMPARE(latin1.isNull(), unicodesrc.isNull()); + QCOMPARE(latin1.isEmpty(), unicodesrc.isEmpty()); + QCOMPARE(latin1.length(), unicodesrc.length()); + QCOMPARE(latin1.isNull(), unicodedst.isNull()); + QCOMPARE(latin1.isEmpty(), unicodedst.isEmpty()); + QCOMPARE(latin1.length(), unicodedst.length()); if (!latin1.isEmpty()) while (latin1.length() < 128) { @@ -3519,12 +3519,12 @@ void tst_QString::stringRef_toLatin1Roundtrip() QFETCH(QString, unicodedst); // QtTest safety check: - Q_ASSERT(latin1.isNull() == unicodesrc.isNull()); - Q_ASSERT(latin1.isEmpty() == unicodesrc.isEmpty()); - Q_ASSERT(latin1.length() == unicodesrc.length()); - Q_ASSERT(latin1.isNull() == unicodedst.isNull()); - Q_ASSERT(latin1.isEmpty() == unicodedst.isEmpty()); - Q_ASSERT(latin1.length() == unicodedst.length()); + QCOMPARE(latin1.isNull(), unicodesrc.isNull()); + QCOMPARE(latin1.isEmpty(), unicodesrc.isEmpty()); + QCOMPARE(latin1.length(), unicodesrc.length()); + QCOMPARE(latin1.isNull(), unicodedst.isNull()); + QCOMPARE(latin1.isEmpty(), unicodedst.isEmpty()); + QCOMPARE(latin1.length(), unicodedst.length()); if (!latin1.isEmpty()) while (latin1.length() < 128) { diff --git a/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp b/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp index 36b6b80..463f200 100644 --- a/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp +++ b/tests/auto/qstringbuilder1/tst_qstringbuilder1.cpp @@ -44,8 +44,7 @@ // this is the "no harm done" version. Only operator% is active, // with NO_CAST * defined #define P % -#undef QT_USE_FAST_OPERATOR_PLUS -#undef QT_USE_FAST_CONCATENATION +#undef QT_USE_QSTRINGBUILDER #define QT_NO_CAST_FROM_ASCII #define QT_NO_CAST_TO_ASCII diff --git a/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp b/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp index 88b1f73..bcf88cb 100644 --- a/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp +++ b/tests/auto/qstringbuilder2/tst_qstringbuilder2.cpp @@ -45,8 +45,7 @@ // based version // with NO_CAST * defined #define P + -#define QT_USE_FAST_OPERATOR_PLUS -#define QT_USE_FAST_CONCATENATION +#define QT_USE_QSTRINGBUILDER #define QT_NO_CAST_FROM_ASCII #define QT_NO_CAST_TO_ASCII diff --git a/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp b/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp index afc3333..338fbf4 100644 --- a/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp +++ b/tests/auto/qstringbuilder3/tst_qstringbuilder3.cpp @@ -44,8 +44,7 @@ // this is the "no harm done" version. Only operator% is active, // with NO_CAST * _not_ defined #define P % -#undef QT_USE_FAST_OPERATOR_PLUS -#undef QT_USE_FAST_CONCATENATION +#undef QT_USE_QSTRINGBUILDER #undef QT_NO_CAST_FROM_ASCII #undef QT_NO_CAST_TO_ASCII diff --git a/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp b/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp index ae4100a..d046e59 100644 --- a/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp +++ b/tests/auto/qstringbuilder4/tst_qstringbuilder4.cpp @@ -45,8 +45,7 @@ // based version // with NO_CAST * _not_ defined #define P + -#define QT_USE_FAST_OPERATOR_PLUS -#define QT_USE_FAST_CONCATENATION +#define QT_USE_QSTRINGBUILDER #undef QT_NO_CAST_FROM_ASCII #undef QT_NO_CAST_TO_ASCII diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp index 380116d..d715914 100644 --- a/tests/auto/qtableview/tst_qtableview.cpp +++ b/tests/auto/qtableview/tst_qtableview.cpp @@ -3028,7 +3028,7 @@ void tst_QTableView::spans_data() << 1 << 2; - QTest::newRow("QTBUG-6004: No failing Q_ASSERT, then it passes.") + QTest::newRow("QTBUG-6004: No failing assertion, then it passes.") << 5 << 5 << (SpanList() << QRect(0, 0, 2, 2) << QRect(0, 0, 1, 1)) << false @@ -3036,7 +3036,7 @@ void tst_QTableView::spans_data() << 1 << 1; - QTest::newRow("QTBUG-6004 (follow-up): No failing Q_ASSERT, then it passes.") + QTest::newRow("QTBUG-6004 (follow-up): No failing assertion, then it passes.") << 10 << 10 << (SpanList() << QRect(2, 2, 1, 3) << QRect(2, 2, 1, 1)) << false diff --git a/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp index f287450..2f1adb4 100644 --- a/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp +++ b/tests/auto/qtconcurrentmap/tst_qtconcurrentmap.cpp @@ -2418,6 +2418,7 @@ void tst_QtConcurrentMap::incrementalResults() {} void tst_QtConcurrentMap::stressTest() {} void tst_QtConcurrentMap::throttling() {} void tst_QtConcurrentMap::stlContainers() {} +void tst_QtConcurrentMap::qFutureAssignmentLeak() { } void tst_QtConcurrentMap::noDetatch() {} QTEST_NOOP_MAIN diff --git a/tests/auto/qtcpserver/tst_qtcpserver.cpp b/tests/auto/qtcpserver/tst_qtcpserver.cpp index 9cddc00..2cd870f 100644 --- a/tests/auto/qtcpserver/tst_qtcpserver.cpp +++ b/tests/auto/qtcpserver/tst_qtcpserver.cpp @@ -430,6 +430,9 @@ void tst_QTcpServer::waitForConnectionTest() void tst_QTcpServer::setSocketDescriptor() { QTcpServer server; +#ifdef Q_OS_SYMBIAN + QTest::ignoreMessage(QtWarningMsg, "QSymbianSocketEngine::initialize - socket descriptor not found"); +#endif QVERIFY(!server.setSocketDescriptor(42)); QCOMPARE(server.serverError(), QAbstractSocket::UnsupportedSocketOperationError); #ifndef Q_OS_SYMBIAN diff --git a/tests/auto/qtcpsocket/test/test.pro b/tests/auto/qtcpsocket/test/test.pro index f4207d6..7bf5ba0 100644 --- a/tests/auto/qtcpsocket/test/test.pro +++ b/tests/auto/qtcpsocket/test/test.pro @@ -13,7 +13,7 @@ vxworks:QT -= gui symbian: { TARGET.EPOCHEAPSIZE="0x100 0x3000000" - TARGET.CAPABILITY = NetworkServices + TARGET.CAPABILITY = NetworkServices ReadUserData } TARGET = tst_qtcpsocket diff --git a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp index 623e02b..d19475f 100644 --- a/tests/auto/qtcpsocket/tst_qtcpsocket.cpp +++ b/tests/auto/qtcpsocket/tst_qtcpsocket.cpp @@ -166,7 +166,9 @@ private slots: void readLineString(); void readChunks(); void waitForBytesWritten(); + void waitForBytesWrittenMinusOne(); void waitForReadyRead(); + void waitForReadyReadMinusOne(); void flush(); void synchronousApi(); void dontCloseOnTimeout(); @@ -476,6 +478,9 @@ void tst_QTcpSocket::setInvalidSocketDescriptor() { QTcpSocket *socket = newSocket(); QCOMPARE(socket->socketDescriptor(), -1); +#ifdef Q_OS_SYMBIAN + QTest::ignoreMessage(QtWarningMsg, "QSymbianSocketEngine::initialize - socket descriptor not found"); +#endif QVERIFY(!socket->setSocketDescriptor(-5, QTcpSocket::UnconnectedState)); QCOMPARE(socket->socketDescriptor(), -1); @@ -1414,10 +1419,10 @@ void tst_QTcpSocket::readChunks() void tst_QTcpSocket::waitForBytesWritten() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 22); + socket->connectToHost(QtNetworkSettings::serverName(), 80); QVERIFY(socket->waitForConnected(10000)); - socket->write(QByteArray(10000, '@')); + socket->write("GET / HTTP/1.0\r\n\r\n"); qint64 toWrite = socket->bytesToWrite(); QVERIFY(socket->waitForBytesWritten(5000)); QVERIFY(toWrite > socket->bytesToWrite()); @@ -1426,11 +1431,37 @@ void tst_QTcpSocket::waitForBytesWritten() } //---------------------------------------------------------------------------------- +void tst_QTcpSocket::waitForBytesWrittenMinusOne() +{ + QTcpSocket *socket = newSocket(); + socket->connectToHost(QtNetworkSettings::serverName(), 80); + QVERIFY(socket->waitForConnected(10000)); + + socket->write("GET / HTTP/1.0\r\n\r\n"); + qint64 toWrite = socket->bytesToWrite(); + QVERIFY(socket->waitForBytesWritten(-1)); + QVERIFY(toWrite > socket->bytesToWrite()); + + delete socket; +} + +//---------------------------------------------------------------------------------- void tst_QTcpSocket::waitForReadyRead() { QTcpSocket *socket = newSocket(); - socket->connectToHost(QtNetworkSettings::serverName(), 22); - socket->waitForReadyRead(0); + socket->connectToHost(QtNetworkSettings::serverName(), 80); + socket->write("GET / HTTP/1.0\r\n\r\n"); + QVERIFY(socket->waitForReadyRead(5000)); + delete socket; +} + +//---------------------------------------------------------------------------------- +void tst_QTcpSocket::waitForReadyReadMinusOne() +{ + QTcpSocket *socket = newSocket(); + socket->connectToHost(QtNetworkSettings::serverName(), 80); + socket->write("GET / HTTP/1.0\r\n\r\n"); + QVERIFY(socket->waitForReadyRead(-1)); delete socket; } diff --git a/tests/auto/qtessellator/dataparser.cpp b/tests/auto/qtessellator/dataparser.cpp index bd17ee2..d6566cb2 100644 --- a/tests/auto/qtessellator/dataparser.cpp +++ b/tests/auto/qtessellator/dataparser.cpp @@ -98,8 +98,12 @@ static QList<QPointF> parsePoints(const QByteArray &line) QList<qreal> nums = parseNumbersList(it); QList<qreal>::const_iterator nitr; for (nitr = nums.begin(); nitr != nums.end(); ++nitr) { - qreal x = *nitr; ++nitr; - Q_ASSERT(nitr != nums.end()); + qreal x = *nitr; + ++nitr; + if (nitr == nums.end()) { + qWarning() << "parsePoints: Even number of co-ordinates required, odd number found: skipping last point"; + break; + } qreal y = *nitr; res.append(QPointF(x, y)); } diff --git a/tests/auto/qtessellator/oldtessellator.cpp b/tests/auto/qtessellator/oldtessellator.cpp index 78f117f..bc24d7e 100644 --- a/tests/auto/qtessellator/oldtessellator.cpp +++ b/tests/auto/qtessellator/oldtessellator.cpp @@ -80,19 +80,6 @@ struct QEdge { horizontal = p1.y == p2.y; } - inline qreal xAt(const qreal &y) const - { - Q_ASSERT(p1.y != p2.y); - XFixed yf = XDoubleToFixed(y); - - if (yf == p1.y) - return XFixedToDouble(p1.x); - else if (yf == p2.y) - return XFixedToDouble(p2.x); - - return (!vertical) ? (((y - b)*im)) : pf1.x(); - } - QPointF pf1, pf2; XPointFixed p1, p2; qreal m; @@ -218,7 +205,8 @@ void old_tesselate_polygon(QVector<XTrapezoid> *traps, const QPointF *pg, int pg qreal ymax(INT_MIN/256); //painter.begin(pg, pgSize); - Q_ASSERT(pg[0] == pg[pgSize-1]); + if (pg[0] != pg[pgSize-1]) + qWarning() << Q_FUNC_INFO << "Malformed polygon (first and last points must be identical)"; // generate edge table // qDebug() << "POINTS:"; for (int x = 0; x < pgSize-1; ++x) { @@ -383,7 +371,8 @@ void old_tesselate_polygon(QVector<XTrapezoid> *traps, const QPointF *pg, int pg isects[i].edge = edge; } - Q_ASSERT(isects.size()%2 == 1); + if (isects.size()%2 != 1) + qFatal("%s: number of intersection points must be odd", Q_FUNC_INFO); // sort intersection points qSort(&isects[0], &isects[isects.size()-1], compareIntersections); diff --git a/tests/auto/qtessellator/testtessellator.cpp b/tests/auto/qtessellator/testtessellator.cpp index 339f05f..d8d6f6f 100644 --- a/tests/auto/qtessellator/testtessellator.cpp +++ b/tests/auto/qtessellator/testtessellator.cpp @@ -42,6 +42,7 @@ #include <private/qtessellator_p.h> #include "math.h" +#include <QtCore/QDebug> class TestTessellator : public QTessellator { @@ -91,7 +92,8 @@ void test_tessellate_polygon_rect(QVector<XTrapezoid> *traps, const QPointF *poi bool winding) { // 5 points per rect - Q_ASSERT(nPoints % 5 == 0); + if (nPoints % 5 != 0) + qWarning() << Q_FUNC_INFO << "multiples of 5 points expected"; TestTessellator t; t.traps = traps; diff --git a/tests/auto/qtextblock/tst_qtextblock.cpp b/tests/auto/qtextblock/tst_qtextblock.cpp index 748d921..cec3a6a 100644 --- a/tests/auto/qtextblock/tst_qtextblock.cpp +++ b/tests/auto/qtextblock/tst_qtextblock.cpp @@ -76,7 +76,6 @@ private slots: void excludeParagraphSeparatorFragment(); void backwardsBlockIterator(); void previousBlock_qtbug18026(); - void removedBlock_qtbug18500(); private: QTextDocument *doc; @@ -182,16 +181,5 @@ void tst_QTextBlock::previousBlock_qtbug18026() QVERIFY(last.isValid()); } -void tst_QTextBlock::removedBlock_qtbug18500() -{ - cursor.insertText("line 1\nline 2\nline 3 \nline 4\n"); - cursor.setPosition(7); - QTextBlock block = cursor.block(); - cursor.setPosition(21, QTextCursor::KeepAnchor); - - cursor.removeSelectedText(); - QVERIFY(!block.isValid()); -} - QTEST_MAIN(tst_QTextBlock) #include "tst_qtextblock.moc" diff --git a/tests/auto/qtextboundaryfinder/tst_qtextboundaryfinder.cpp b/tests/auto/qtextboundaryfinder/tst_qtextboundaryfinder.cpp index 8003c44..e885942 100644 --- a/tests/auto/qtextboundaryfinder/tst_qtextboundaryfinder.cpp +++ b/tests/auto/qtextboundaryfinder/tst_qtextboundaryfinder.cpp @@ -123,14 +123,14 @@ void tst_QTextBoundaryFinder::graphemeBoundaries() if (test.at(pos).unicode() == 0xf7) breakPositions.append(strPos); else - Q_ASSERT(test.at(pos).unicode() == 0xd7); + QVERIFY(test.at(pos).unicode() == 0xd7); ++pos; if (pos < test.length()) { - Q_ASSERT(pos < test.length() - 4); + QVERIFY(pos < test.length() - 4); QString hex = test.mid(pos, 4); bool ok = true; testString.append(QChar(hex.toInt(&ok, 16))); - Q_ASSERT(ok); + QVERIFY(ok); pos += 4; } ++strPos; @@ -176,14 +176,14 @@ void tst_QTextBoundaryFinder::wordBoundaries() if (test.at(pos).unicode() == 0xf7) breakPositions.append(strPos); else - Q_ASSERT(test.at(pos).unicode() == 0xd7); + QVERIFY(test.at(pos).unicode() == 0xd7); ++pos; if (pos < test.length()) { - Q_ASSERT(pos < test.length() - 4); + QVERIFY(pos < test.length() - 4); QString hex = test.mid(pos, 4); bool ok = true; testString.append(QChar(hex.toInt(&ok, 16))); - Q_ASSERT(ok); + QVERIFY(ok); pos += 4; } ++strPos; @@ -228,14 +228,14 @@ void tst_QTextBoundaryFinder::sentenceBoundaries() if (test.at(pos).unicode() == 0xf7) breakPositions.append(strPos); else - Q_ASSERT(test.at(pos).unicode() == 0xd7); + QVERIFY(test.at(pos).unicode() == 0xd7); ++pos; if (pos < test.length()) { - Q_ASSERT(pos < test.length() - 4); + QVERIFY(pos < test.length() - 4); QString hex = test.mid(pos, 4); bool ok = true; testString.append(QChar(hex.toInt(&ok, 16))); - Q_ASSERT(ok); + QVERIFY(ok); pos += 4; } ++strPos; diff --git a/tests/auto/qtextcodec/tst_qtextcodec.cpp b/tests/auto/qtextcodec/tst_qtextcodec.cpp index 43656c8..34d34fa 100644 --- a/tests/auto/qtextcodec/tst_qtextcodec.cpp +++ b/tests/auto/qtextcodec/tst_qtextcodec.cpp @@ -106,6 +106,8 @@ private slots: void moreToFromUnicode_data(); void moreToFromUnicode(); + + void shiftJis(); }; void tst_QTextCodec::toUnicode_data() @@ -428,7 +430,7 @@ void tst_QTextCodec::flagCodepointFFFF() const QString input(ch); QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8 - Q_ASSERT(codec); + QVERIFY(codec); const QByteArray asDecoded(codec->fromUnicode(input)); QCOMPARE(asDecoded, QByteArray("?")); @@ -465,7 +467,7 @@ void tst_QTextCodec::flagF7808080() const QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8 - Q_ASSERT(codec); + QVERIFY(codec); //QVERIFY(!codec->canEncode(QChar(0x1C0000))); @@ -482,7 +484,7 @@ void tst_QTextCodec::flagEFBFBF() const invalidInput[2] = char(0xBF); const QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8 - Q_ASSERT(codec); + QVERIFY(codec); { //QVERIFY(!codec->canEncode(QChar(0xFFFF))); @@ -1627,7 +1629,7 @@ void tst_QTextCodec::utf8bom() QFETCH(QString, result); QTextCodec *const codec = QTextCodec::codecForMib(106); // UTF-8 - Q_ASSERT(codec); + QVERIFY(codec); QCOMPARE(codec->toUnicode(data.constData(), data.length(), 0), result); @@ -2236,6 +2238,19 @@ void tst_QTextCodec::moreToFromUnicode() QCOMPARE(testData, cStr); } +void tst_QTextCodec::shiftJis() +{ + QByteArray backslashTilde("\\~"); + QTextCodec* codec = QTextCodec::codecForName("shift_jis"); + QString string = codec->toUnicode(backslashTilde); + QCOMPARE(string.length(), 2); + QCOMPARE(string.at(0), QChar(QLatin1Char('\\'))); + QCOMPARE(string.at(1), QChar(QLatin1Char('~'))); + + QByteArray encoded = codec->fromUnicode(string); + QCOMPARE(encoded, backslashTilde); +} + struct DontCrashAtExit { ~DontCrashAtExit() { QTextCodec *c = QTextCodec::codecForName("utf8"); diff --git a/tests/auto/qtextdocument/tst_qtextdocument.cpp b/tests/auto/qtextdocument/tst_qtextdocument.cpp index 6675c99..7aa6578 100644 --- a/tests/auto/qtextdocument/tst_qtextdocument.cpp +++ b/tests/auto/qtextdocument/tst_qtextdocument.cpp @@ -180,6 +180,8 @@ private slots: void escape_data(); void escape(); + void copiedFontSize(); + private: void backgroundImage_checkExpectedHtml(const QTextDocument &doc); @@ -2734,5 +2736,29 @@ void tst_QTextDocument::escape() QCOMPARE(Qt::escape(original), expected); } +void tst_QTextDocument::copiedFontSize() +{ + QTextDocument documentInput; + QTextDocument documentOutput; + + QFont fontInput; + fontInput.setPixelSize(24); + + QTextCursor cursorInput(&documentInput); + QTextCharFormat formatInput = cursorInput.charFormat(); + formatInput.setFont(fontInput); + cursorInput.insertText("Should be the same font", formatInput); + cursorInput.select(QTextCursor::Document); + + QTextDocumentFragment fragmentInput(cursorInput); + QString html = fragmentInput.toHtml(); + + QTextCursor cursorOutput(&documentOutput); + QTextDocumentFragment fragmentOutput = QTextDocumentFragment::fromHtml(html); + cursorOutput.insertFragment(fragmentOutput); + + QCOMPARE(cursorOutput.charFormat().font().pixelSize(), 24); +} + QTEST_MAIN(tst_QTextDocument) #include "tst_qtextdocument.moc" diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp index 9ca17b9..6b9a541 100644 --- a/tests/auto/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/qtextedit/tst_qtextedit.cpp @@ -42,7 +42,6 @@ #include <QtTest/QtTest> - #include <qtextedit.h> #include <qtextcursor.h> #include <qtextlist.h> @@ -69,6 +68,7 @@ typedef QList<keyPairType> pairListType; Q_DECLARE_METATYPE(pairListType); Q_DECLARE_METATYPE(keyPairType); Q_DECLARE_METATYPE(QList<bool>); +Q_DECLARE_METATYPE(QList<int>); #ifdef Q_WS_MAC #include <Carbon/Carbon.h> @@ -205,6 +205,11 @@ private slots: #ifndef QT_NO_CONTEXTMENU void taskQTBUG_7902_contextMenuCrash(); #endif + void bidiVisualMovement_data(); + void bidiVisualMovement(); + + void bidiLogicalMovement_data(); + void bidiLogicalMovement(); private: void createSelection(); @@ -312,7 +317,7 @@ void tst_QTextEdit::getSetCheck() // void QTextEdit::setFontPointSize(qreal) obj1.setFontPointSize(qreal(1.1)); QCOMPARE(qreal(1.1), obj1.fontPointSize()); - // we currently Q_ASSERT_X in QFont::setPointSizeF for that + // we currently assert in QFont::setPointSizeF for that //obj1.setFontPointSize(0.0); //QCOMPARE(1.1, obj1.fontPointSize()); // Should not accept 0.0 => keep old @@ -322,7 +327,7 @@ void tst_QTextEdit::getSetCheck() QCOMPARE(1, obj1.fontWeight()); // Range<1, 99> obj1.setFontWeight(99); QCOMPARE(99, obj1.fontWeight()); // Range<1, 99> - /* Q_ASSERT_X in qfont.cpp + /* assertion in qfont.cpp obj1.setFontWeight(INT_MIN); QCOMPARE(1, obj1.fontWeight()); // Range<1, 99> obj1.setFontWeight(INT_MAX); @@ -2059,7 +2064,7 @@ void tst_QTextEdit::compareWidgetAndImage(QTextEdit &widget, const QString &imag QCOMPARE(original.isNull(), false); QCOMPARE(original.size(), image.size()); - Q_ASSERT(image.depth() == 32); + QCOMPARE(image.depth(), 32); QCOMPARE(original.depth(), image.depth()); const int bytesPerLine = image.bytesPerLine(); @@ -2235,5 +2240,147 @@ void tst_QTextEdit::taskQTBUG_7902_contextMenuCrash() } #endif +void tst_QTextEdit::bidiVisualMovement_data() +{ + QTest::addColumn<QString>("logical"); + QTest::addColumn<int>("basicDir"); + QTest::addColumn<QList<int> >("positionList"); + + QTest::newRow("Latin text") + << QString::fromUtf8("abc") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text, one item") + << QString::fromUtf8("\327\220\327\221\327\222") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 3); + QTest::newRow("Hebrew text after Latin text") + << QString::fromUtf8("abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3); + QTest::newRow("Latin text after Hebrew text") + << QString::fromUtf8("\327\220\327\221\327\222abc") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 6 << 5 << 4 << 3); + QTest::newRow("LTR, 3 items") + << QString::fromUtf8("abc\327\220\327\221\327\222abc") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9); + QTest::newRow("RTL, 3 items") + << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 9); + QTest::newRow("LTR, 4 items") + << QString::fromUtf8("abc\327\220\327\221\327\222abc\327\220\327\221\327\222") + << (int) QChar::DirL + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9); + QTest::newRow("RTL, 4 items") + << QString::fromUtf8("\327\220\327\221\327\222abc\327\220\327\221\327\222abc") + << (int) QChar::DirR + << (QList<int>() << 0 << 1 << 2 << 5 << 4 << 3 << 6 << 7 << 8 << 12 << 11 << 10 << 9); +} + +void tst_QTextEdit::bidiVisualMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + QFETCH(QList<int>, positionList); + + ed->setText(logical); + + QTextOption option = ed->document()->defaultTextOption(); + option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); + ed->document()->setDefaultTextOption(option); + + ed->document()->setDefaultCursorMoveStyle(Qt::VisualMoveStyle); + ed->moveCursor(QTextCursor::Start); + ed->show(); + + bool moved; + int i = 0, oldPos, newPos = 0; + + do { + oldPos = newPos; + QVERIFY(oldPos == positionList[i]); + if (basicDir == QChar::DirL) { + ed->moveCursor(QTextCursor::Right); + } else + { + ed->moveCursor(QTextCursor::Left); + } + newPos = ed->textCursor().position(); + moved = (oldPos != newPos); + i++; + } while (moved); + + QVERIFY(i == positionList.size()); + + do { + i--; + oldPos = newPos; + QVERIFY(oldPos == positionList[i]); + if (basicDir == QChar::DirL) { + ed->moveCursor(QTextCursor::Left); + } else + { + ed->moveCursor(QTextCursor::Right); + } + newPos = ed->textCursor().position(); + moved = (oldPos != newPos); + } while (moved && i >= 0); +} + +void tst_QTextEdit::bidiLogicalMovement_data() +{ + bidiVisualMovement_data(); +} + +void tst_QTextEdit::bidiLogicalMovement() +{ + QFETCH(QString, logical); + QFETCH(int, basicDir); + + ed->setText(logical); + + QTextOption option = ed->document()->defaultTextOption(); + option.setTextDirection(basicDir == QChar::DirL ? Qt::LeftToRight : Qt::RightToLeft); + ed->document()->setDefaultTextOption(option); + + ed->document()->setDefaultCursorMoveStyle(Qt::LogicalMoveStyle); + ed->moveCursor(QTextCursor::Start); + ed->show(); + + bool moved; + int i = 0, oldPos, newPos = 0; + + do { + oldPos = newPos; + QVERIFY(oldPos == i); + if (basicDir == QChar::DirL) { + ed->moveCursor(QTextCursor::Right); + } else + { + ed->moveCursor(QTextCursor::Left); + } + newPos = ed->textCursor().position(); + moved = (oldPos != newPos); + i++; + } while (moved); + + do { + i--; + oldPos = newPos; + QVERIFY(oldPos == i); + if (basicDir == QChar::DirL) { + ed->moveCursor(QTextCursor::Left); + } else + { + ed->moveCursor(QTextCursor::Right); + } + newPos = ed->textCursor().position(); + moved = (oldPos != newPos); + } while (moved && i >= 0); +} + QTEST_MAIN(tst_QTextEdit) #include "tst_qtextedit.moc" diff --git a/tests/auto/qtextodfwriter/tst_qtextodfwriter.cpp b/tests/auto/qtextodfwriter/tst_qtextodfwriter.cpp index 997cd68..ffce9a2 100644 --- a/tests/auto/qtextodfwriter/tst_qtextodfwriter.cpp +++ b/tests/auto/qtextodfwriter/tst_qtextodfwriter.cpp @@ -114,11 +114,14 @@ QString tst_QTextOdfWriter::getContentFromXml() xmlWriter->writeEndDocument(); buffer->close(); QString stringContent = QString::fromUtf8(buffer->data()); + QString ret; int index = stringContent.indexOf("<dummy"); - Q_ASSERT(index); - index = stringContent.indexOf('>', index); - stringContent = stringContent.mid(index+1, stringContent.length() - index - 10); - return stringContent; + if (index > 0) { + index = stringContent.indexOf('>', index); + if (index > 0) + ret = stringContent.mid(index+1, stringContent.length() - index - 10); + } + return ret; } void tst_QTextOdfWriter::testWriteParagraph_data() diff --git a/tests/auto/qthread/tst_qthread.cpp b/tests/auto/qthread/tst_qthread.cpp index 6ad0678..054a995 100644 --- a/tests/auto/qthread/tst_qthread.cpp +++ b/tests/auto/qthread/tst_qthread.cpp @@ -209,7 +209,7 @@ public: cond.wait(&mutex, five_minutes); } setTerminationEnabled(true); - Q_ASSERT_X(false, "tst_QThread", "test case hung"); + qFatal("tst_QThread: test case hung"); } }; diff --git a/tests/auto/qtipc/qsharedmemory/src/qsystemlock_unix.cpp b/tests/auto/qtipc/qsharedmemory/src/qsystemlock_unix.cpp index 6db84dd..647d857 100644 --- a/tests/auto/qtipc/qsharedmemory/src/qsystemlock_unix.cpp +++ b/tests/auto/qtipc/qsharedmemory/src/qsystemlock_unix.cpp @@ -207,7 +207,8 @@ bool QSystemLockPrivate::modifySemaphore(QSystemLockPrivate::Operation op, if ((lockCount == 0 && op == Lock) || (lockCount > 0 && op == Unlock)) { if (op == Unlock) { --lockCount; - Q_ASSERT(lockCount >= 0); + if (lockCount < 0) + qFatal("%s: lockCount must not be negative", Q_FUNC_INFO); if (lockCount > 0) return true; } diff --git a/tests/auto/qtipc/qsharedmemory/src/qsystemlock_win.cpp b/tests/auto/qtipc/qsharedmemory/src/qsystemlock_win.cpp index f6803f7..f7e4ab2 100644 --- a/tests/auto/qtipc/qsharedmemory/src/qsystemlock_win.cpp +++ b/tests/auto/qtipc/qsharedmemory/src/qsystemlock_win.cpp @@ -157,7 +157,8 @@ bool QSystemLockPrivate::modifySemaphore(QSystemLockPrivate::Operation op, if ((lockCount == 0 && op == Lock) || (lockCount > 0 && op == Unlock)) { if (op == Unlock) { --lockCount; - Q_ASSERT(lockCount >= 0); + if (lockCount < 0) + qFatal("%s: lockCount must not be negative", Q_FUNC_INFO); if (lockCount > 0) return true; } diff --git a/tests/auto/qtreeview/tst_qtreeview.cpp b/tests/auto/qtreeview/tst_qtreeview.cpp index c07c471..1f0c2ce 100644 --- a/tests/auto/qtreeview/tst_qtreeview.cpp +++ b/tests/auto/qtreeview/tst_qtreeview.cpp @@ -277,7 +277,8 @@ public: } int rowCount(const QModelIndex& parent = QModelIndex()) const { - Q_ASSERT(fetched); + if (!fetched) + qFatal("%s: rowCount should not be called before fetching", Q_FUNC_INFO); if ((parent.column() > 0) || (level(parent) > levels)) return 0; return rows; @@ -2536,7 +2537,7 @@ void tst_QTreeView::sortByColumn() /* This is a model that every time kill() is called it will completely change - all of its nodes for new nodes. It then asserts if you later use a dead node. + all of its nodes for new nodes. It then qFatal's if you later use a dead node. */ class EvilModel: public QAbstractItemModel { @@ -2567,7 +2568,8 @@ public: } } if (parent == 0) { - Q_ASSERT(children.isEmpty()); + if (!children.isEmpty()) + qFatal("%s: children should be empty when parent is null", Q_FUNC_INFO); populate(); } else { isDead = true; @@ -2624,7 +2626,8 @@ public: Node *parentNode = root; if (parent.isValid()) { parentNode = static_cast<Node*>(parent.internalPointer()); - Q_ASSERT(!parentNode->isDead); + if (parentNode->isDead) + qFatal("%s: parentNode is dead!", Q_FUNC_INFO); } return parentNode->children.count(); } @@ -2639,9 +2642,11 @@ public: Node *grandparentNode = static_cast<Node*>(parent.internalPointer()); Node *parentNode = root; if (parent.isValid()) { - Q_ASSERT(!grandparentNode->isDead); + if (grandparentNode->isDead) + qFatal("%s: grandparentNode is dead!", Q_FUNC_INFO); parentNode = grandparentNode->children[parent.row()]; - Q_ASSERT(!parentNode->isDead); + if (parentNode->isDead) + qFatal("%s: grandparentNode is dead!", Q_FUNC_INFO); } return createIndex(row, column, parentNode); } @@ -2661,7 +2666,8 @@ public: Node *parentNode = root; if (idx.isValid()) { parentNode = static_cast<Node*>(idx.internalPointer()); - Q_ASSERT(!parentNode->isDead); + if (parentNode->isDead) + qFatal("%s: grandparentNode is dead!", Q_FUNC_INFO); } return QString("[%1,%2,%3]").arg(idx.row()).arg(idx.column()) .arg(parentNode->isDead ? "dead" : "alive"); diff --git a/tests/auto/qundogroup/testdata/qundogroup.ts b/tests/auto/qundogroup/testdata/qundogroup.ts new file mode 100644 index 0000000..a059bcb --- /dev/null +++ b/tests/auto/qundogroup/testdata/qundogroup.ts @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="en"> +<context> + <name>QUndoGroup</name> + <message> + <source>Undo %1</source> + <translation>undo-prefix %1 undo-suffix</translation> + </message> + <message> + <source>Undo</source> + <comment>Default text for undo action</comment> + <translation>Undo-default-text</translation> + </message> + <message> + <source>Redo %1</source> + <translation>redo-prefix %1 redo-suffix</translation> + </message> + <message> + <source>Redo</source> + <comment>Default text for redo action</comment> + <translation>Redo-default-text</translation> + </message> +</context> +</TS> diff --git a/tests/auto/qundogroup/tst_qundogroup.cpp b/tests/auto/qundogroup/tst_qundogroup.cpp index 8927f85..d2909b7 100644 --- a/tests/auto/qundogroup/tst_qundogroup.cpp +++ b/tests/auto/qundogroup/tst_qundogroup.cpp @@ -201,6 +201,7 @@ private slots: void deleteStack(); void checkSignals(); void addStackAndDie(); + void commandTextFormat(); }; tst_QUndoGroup::tst_QUndoGroup() @@ -604,6 +605,42 @@ void tst_QUndoGroup::addStackAndDie() delete stack; } +void tst_QUndoGroup::commandTextFormat() +{ + QString binDir = QLibraryInfo::location(QLibraryInfo::BinariesPath); + QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/qundogroup.ts")); + + QTranslator translator; + QVERIFY(translator.load("testdata/qundogroup.qm")); + qApp->installTranslator(&translator); + + QUndoGroup group; + QAction *undo_action = group.createUndoAction(0); + QAction *redo_action = group.createRedoAction(0); + + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + QUndoStack stack(&group); + stack.setActive(); + QString str; + + stack.push(new AppendCommand(&str, "foo")); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + stack.push(new InsertCommand(&str, 0, "bar")); + stack.undo(); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("redo-prefix insert redo-suffix")); + + stack.undo(); + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("redo-prefix append redo-suffix")); + + qApp->removeTranslator(&translator); +} + #else class tst_QUndoGroup : public QObject { diff --git a/tests/auto/qundostack/testdata/qundostack.ts b/tests/auto/qundostack/testdata/qundostack.ts new file mode 100644 index 0000000..4584036 --- /dev/null +++ b/tests/auto/qundostack/testdata/qundostack.ts @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!DOCTYPE TS> +<TS version="2.0" language="en"> +<context> + <name>QUndoStack</name> + <message> + <source>Undo %1</source> + <translation>undo-prefix %1 undo-suffix</translation> + </message> + <message> + <source>Undo</source> + <comment>Default text for undo action</comment> + <translation>Undo-default-text</translation> + </message> + <message> + <source>Redo %1</source> + <translation>redo-prefix %1 redo-suffix</translation> + </message> + <message> + <source>Redo</source> + <comment>Default text for redo action</comment> + <translation>Redo-default-text</translation> + </message> +</context> +</TS> diff --git a/tests/auto/qundostack/tst_qundostack.cpp b/tests/auto/qundostack/tst_qundostack.cpp index 739d3f2..5aea0a1 100644 --- a/tests/auto/qundostack/tst_qundostack.cpp +++ b/tests/auto/qundostack/tst_qundostack.cpp @@ -101,6 +101,16 @@ private: QString m_text; }; +class IdleCommand : public QUndoCommand +{ +public: + IdleCommand(QUndoCommand *parent = 0); + ~IdleCommand(); + + virtual void undo(); + virtual void redo(); +}; + InsertCommand::InsertCommand(QString *str, int idx, const QString &text, QUndoCommand *parent) : QUndoCommand(parent) @@ -201,6 +211,26 @@ bool AppendCommand::mergeWith(const QUndoCommand *other) return true; } +IdleCommand::IdleCommand(QUndoCommand *parent) + : QUndoCommand(parent) +{ + // "idle-item" goes to QUndoStack::{redo,undo}Text + // "idle-action" goes to all other places (e.g. QUndoView) + setText("idle-item\nidle-action"); +} + +IdleCommand::~IdleCommand() +{ +} + +void IdleCommand::redo() +{ +} + +void IdleCommand::undo() +{ +} + /****************************************************************************** ** tst_QUndoStack */ @@ -220,6 +250,8 @@ private slots: void macroBeginEnd(); void compression(); void undoLimit(); + void commandTextFormat(); + void separateUndoText(); }; tst_QUndoStack::tst_QUndoStack() @@ -2935,6 +2967,68 @@ void tst_QUndoStack::undoLimit() true); // redoChanged } +void tst_QUndoStack::commandTextFormat() +{ + QString binDir = QLibraryInfo::location(QLibraryInfo::BinariesPath); + QVERIFY(!QProcess::execute(binDir + "/lrelease testdata/qundostack.ts")); + + QTranslator translator; + QVERIFY(translator.load("testdata/qundostack.qm")); + qApp->installTranslator(&translator); + + QUndoStack stack; + QAction *undo_action = stack.createUndoAction(0); + QAction *redo_action = stack.createRedoAction(0); + + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + QString str; + + stack.push(new AppendCommand(&str, "foo")); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("Redo-default-text")); + + stack.push(new InsertCommand(&str, 0, "bar")); + stack.undo(); + QCOMPARE(undo_action->text(), QString("undo-prefix append undo-suffix")); + QCOMPARE(redo_action->text(), QString("redo-prefix insert redo-suffix")); + + stack.undo(); + QCOMPARE(undo_action->text(), QString("Undo-default-text")); + QCOMPARE(redo_action->text(), QString("redo-prefix append redo-suffix")); + + qApp->removeTranslator(&translator); +} + +void tst_QUndoStack::separateUndoText() +{ + QUndoStack stack; + QAction *undo_action = stack.createUndoAction(0); + QAction *redo_action = stack.createRedoAction(0); + + QUndoCommand *command1 = new IdleCommand(); + QUndoCommand *command2 = new IdleCommand(); + stack.push(command1); + stack.push(command2); + stack.undo(); + + QCOMPARE(undo_action->text(), QString("Undo idle-action")); + QCOMPARE(redo_action->text(), QString("Redo idle-action")); + QCOMPARE(command1->actionText(), QString("idle-action")); + + QCOMPARE(command1->text(), QString("idle-item")); + QCOMPARE(stack.text(0), QString("idle-item")); + + command1->setText("idle"); + QCOMPARE(command1->actionText(), QString("idle")); + QCOMPARE(command1->text(), QString("idle")); + + command1->setText("idle-item\nidle-action"); + QCOMPARE(command1->actionText(), QString("idle-action")); + QCOMPARE(command1->text(), QString("idle-item")); +} + QTEST_MAIN(tst_QUndoStack) #include "tst_qundostack.moc" diff --git a/tests/auto/qvariant/tst_qvariant.cpp b/tests/auto/qvariant/tst_qvariant.cpp index 6ebe84e..492d0df 100644 --- a/tests/auto/qvariant/tst_qvariant.cpp +++ b/tests/auto/qvariant/tst_qvariant.cpp @@ -2650,7 +2650,6 @@ void tst_QVariant::invalidAsByteArray() void tst_QVariant::invalidQColor() const { QVariant va("An invalid QColor::name() value."); - QTest::ignoreMessage(QtWarningMsg, "QColor::setNamedColor: Unknown color name 'An invalid QColor::name() value.'"); QVERIFY(va.canConvert(QVariant::Color)); QVERIFY(!va.convert(QVariant::Color)); @@ -3240,18 +3239,24 @@ struct MyData { void *ptr; MyData() : ptr(this) {} - ~MyData() { Q_ASSERT(ptr == this); } - MyData(const MyData& o) : ptr(this) { Q_ASSERT(o.ptr == &o); } + ~MyData() + { + if (ptr != this) qWarning("%s: object has moved", Q_FUNC_INFO); + } + MyData(const MyData& o) : ptr(this) + { + if (o.ptr != &o) qWarning("%s: other object has moved", Q_FUNC_INFO); + } MyData &operator=(const MyData &o) { - Q_ASSERT(ptr == this); - Q_ASSERT(o.ptr == &o); + if (ptr != this) qWarning("%s: object has moved", Q_FUNC_INFO); + if (o.ptr != &o) qWarning("%s: other object has moved", Q_FUNC_INFO); return *this; } bool operator==(const MyData &o) const { - Q_ASSERT(ptr == this); - Q_ASSERT(o.ptr == &o); + if (ptr != this) qWarning("%s: object has moved", Q_FUNC_INFO); + if (o.ptr != &o) qWarning("%s: other object has moved", Q_FUNC_INFO); return true; } }; diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index 35014c9..e9cb480 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -345,6 +345,7 @@ private slots: void immediateRepaintAfterInvalidateBuffer(); #endif void effectiveWinId(); + void effectiveWinId2(); void customDpi(); void customDpiProperty(); @@ -4738,7 +4739,8 @@ void tst_QWidget::update() QCOMPARE(w.visibleRegion(), expectedVisible); QCOMPARE(w.paintedRegion, expectedVisible); #ifdef QT_MAC_USE_COCOA - QEXPECT_FAIL(0, "Cocoa compositor says to paint this.", Continue); + if (QApplicationPrivate::graphics_system_name != QLatin1String("raster")) + QEXPECT_FAIL(0, "Cocoa compositor says to paint this.", Continue); #endif QCOMPARE(child.numPaintEvents, 0); @@ -6336,11 +6338,15 @@ void tst_QWidget::compatibilityChildInsertedEvents() expected = EventRecorder::EventList() << qMakePair(&widget, QEvent::PolishRequest) - << qMakePair(&widget, QEvent::Type(QEvent::User + 1)) -#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_S60) || defined(Q_WS_QPA) - << qMakePair(&widget, QEvent::UpdateRequest) -#endif - ; + << qMakePair(&widget, QEvent::Type(QEvent::User + 1)); + +#ifndef QT_MAC_USE_CARBON +#ifdef QT_MAC_USE_COCOA + if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) +#endif // QT_MAC_USE_COCOA + expected << qMakePair(&widget, QEvent::UpdateRequest); +#endif // !QT_MAC_USE_CARBON + QCOMPARE(spy.eventList(), expected); } @@ -6432,11 +6438,15 @@ void tst_QWidget::compatibilityChildInsertedEvents() #endif << qMakePair(&widget, QEvent::PolishRequest) << qMakePair(&widget, QEvent::Type(QEvent::User + 1)) - << qMakePair(&widget, QEvent::Type(QEvent::User + 2)) -#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_S60) || defined(Q_WS_QPA) - << qMakePair(&widget, QEvent::UpdateRequest) -#endif - ; + << qMakePair(&widget, QEvent::Type(QEvent::User + 2)); + +#ifndef QT_MAC_USE_CARBON +#ifdef QT_MAC_USE_COCOA + if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) +#endif // QT_MAC_USE_COCOA + expected << qMakePair(&widget, QEvent::UpdateRequest); +#endif // !QT_MAC_USE_CARBON + QCOMPARE(spy.eventList(), expected); } @@ -6528,11 +6538,15 @@ void tst_QWidget::compatibilityChildInsertedEvents() #endif << qMakePair(&widget, QEvent::PolishRequest) << qMakePair(&widget, QEvent::Type(QEvent::User + 1)) - << qMakePair(&widget, QEvent::Type(QEvent::User + 2)) -#if defined(Q_WS_X11) || defined(Q_WS_WIN) || defined(Q_WS_QWS) || defined(Q_WS_S60) || defined(Q_WS_QPA) - << qMakePair(&widget, QEvent::UpdateRequest) -#endif - ; + << qMakePair(&widget, QEvent::Type(QEvent::User + 2)); + +#ifndef QT_MAC_USE_CARBON +#ifdef QT_MAC_USE_COCOA + if (QApplicationPrivate::graphics_system_name == QLatin1String("raster")) +#endif // QT_MAC_USE_COCOA + expected << qMakePair(&widget, QEvent::UpdateRequest); +#endif // !QT_MAC_USE_CARBON + QCOMPARE(spy.eventList(), expected); } } @@ -7220,8 +7234,7 @@ void tst_QWidget::render_systemClip2() QFETCH(bool, usePaintEvent); QFETCH(QColor, expectedColor); - Q_ASSERT_X(expectedColor != QColor(Qt::red), Q_FUNC_INFO, - "Qt::red is the reference color for the image, pick another color"); + QVERIFY2(expectedColor != QColor(Qt::red), "Qt::red is the reference color for the image, pick another color"); class MyWidget : public QWidget { @@ -8482,6 +8495,30 @@ void tst_QWidget::effectiveWinId() QVERIFY(child.effectiveWinId()); } +void tst_QWidget::effectiveWinId2() +{ + QWidget parent; + + class MyWidget : public QWidget { + bool event(QEvent *e) + { + if (e->type() == QEvent::WinIdChange) { + // Shouldn't crash. + effectiveWinId(); + } + + return QWidget::event(e); + } + }; + + MyWidget child; + child.setParent(&parent); + parent.show(); + + child.setParent(0); + child.setParent(&parent); +} + class CustomWidget : public QWidget { public: @@ -10384,7 +10421,7 @@ void tst_QWidget::taskQTBUG_7532_tabOrderWithFocusProxy() w.setFocusProxy(fp); QWidget::setTabOrder(&w, fp); - // No Q_ASSERT, then it's allright. + // In debug mode, no assertion failure means it's alright. } void tst_QWidget::movedAndResizedAttributes() diff --git a/tests/auto/qwizard/tst_qwizard.cpp b/tests/auto/qwizard/tst_qwizard.cpp index a813727..00b59a9 100644 --- a/tests/auto/qwizard/tst_qwizard.cpp +++ b/tests/auto/qwizard/tst_qwizard.cpp @@ -854,25 +854,26 @@ struct MyPage2 : public QWizardPage public: MyPage2() : init(0), cleanup(0), validate(0) {} - void initializePage() { ++init; QWizardPage::initializePage(); checkInvariant(); } - void cleanupPage() { ++cleanup; QWizardPage::cleanupPage(); checkInvariant(); } + void initializePage() { ++init; QWizardPage::initializePage(); } + void cleanupPage() { ++cleanup; QWizardPage::cleanupPage(); } bool validatePage() { ++validate; return QWizardPage::validatePage(); } - void check(int init, int cleanup) - { Q_ASSERT(init == this->init && cleanup == this->cleanup); Q_UNUSED(init); Q_UNUSED(cleanup); } + bool check(int init, int cleanup) + { + return init == this->init + && cleanup == this->cleanup + && (this->init == this->cleanup || this->init - 1 == this->cleanup); + } int init; int cleanup; int validate; - -private: - void checkInvariant() { Q_ASSERT(init == cleanup || init - 1 == cleanup); } }; #define CHECK_PAGE_INIT(i0, c0, i1, c1, i2, c2) \ - page0->check((i0), (c0)); \ - page1->check((i1), (c1)); \ - page2->check((i2), (c2)); + QVERIFY(page0->check((i0), (c0))); \ + QVERIFY(page1->check((i1), (c1))); \ + QVERIFY(page2->check((i2), (c2))); void tst_QWizard::setOption_IndependentPages() { @@ -1770,8 +1771,11 @@ public: ~TestWizard() { - foreach (int id, pageIds) - delete page(id); + foreach (int id, pageIds) { + QWizardPage *page_to_delete = page(id); + removePage(id); + delete page_to_delete; + } } void applyOperations(const QList<Operation *> &operations) @@ -2548,8 +2552,8 @@ void tst_QWizard::task177022_setFixedSize() QWizard wiz; QWizardPage page1; QWizardPage page2; - wiz.addPage(&page1); - wiz.addPage(&page2); + int page1_id = wiz.addPage(&page1); + int page2_id = wiz.addPage(&page2); wiz.setFixedSize(width, height); if (wiz.wizardStyle() == QWizard::AeroStyle) QEXPECT_FAIL("", "this probably relates to non-client area hack for AeroStyle titlebar " @@ -2576,6 +2580,8 @@ void tst_QWizard::task177022_setFixedSize() QCOMPARE(wiz.maximumWidth(), width); QCOMPARE(wiz.maximumHeight(), height); + wiz.removePage(page1_id); + wiz.removePage(page2_id); } void tst_QWizard::task248107_backButton() diff --git a/tests/auto/qxmlinputsource/tst_qxmlinputsource.cpp b/tests/auto/qxmlinputsource/tst_qxmlinputsource.cpp index c0029f5..a2c84cf 100644 --- a/tests/auto/qxmlinputsource/tst_qxmlinputsource.cpp +++ b/tests/auto/qxmlinputsource/tst_qxmlinputsource.cpp @@ -181,9 +181,7 @@ private slots: { if(bodyLength == -1) { - Q_ASSERT_X(false, Q_FUNC_INFO, - "No length was specified in the header."); - return; + qFatal("No length was specified in the header."); } QDomDocument domDoc; diff --git a/tests/auto/qxmlquery/MessageValidator.cpp b/tests/auto/qxmlquery/MessageValidator.cpp index 58b2b31..99a115e 100644 --- a/tests/auto/qxmlquery/MessageValidator.cpp +++ b/tests/auto/qxmlquery/MessageValidator.cpp @@ -51,9 +51,8 @@ MessageValidator::MessageValidator() : m_success(false) MessageValidator::~MessageValidator() { - Q_ASSERT_X(m_hasChecked, - Q_FUNC_INFO, - "You must call success()."); + if (!m_hasChecked) + qFatal("%s: You must call success().", Q_FUNC_INFO); } void MessageValidator::handleMessage(QtMsgType type, diff --git a/tests/auto/qxmlquery/NetworkOverrider.h b/tests/auto/qxmlquery/NetworkOverrider.h index 10a85c1..2f227ea 100644 --- a/tests/auto/qxmlquery/NetworkOverrider.h +++ b/tests/auto/qxmlquery/NetworkOverrider.h @@ -70,6 +70,7 @@ public: virtual QNetworkReply *createRequest(Operation op, const QNetworkRequest &req, QIODevice *outgoingData); + bool isValid() const; private: const QUrl m_rewriteFrom; @@ -77,11 +78,10 @@ private: }; NetworkOverrider::NetworkOverrider(const QUrl &rewriteFrom, - const QUrl &rewriteTo) : m_rewriteFrom(rewriteFrom) - , m_rewriteTo(rewriteTo) + const QUrl &rewriteTo) + : m_rewriteFrom(rewriteFrom) + , m_rewriteTo(rewriteTo) { - Q_ASSERT(m_rewriteFrom.isValid()); - Q_ASSERT(m_rewriteTo.isValid()); } QNetworkReply *NetworkOverrider::createRequest(Operation op, @@ -95,4 +95,9 @@ QNetworkReply *NetworkOverrider::createRequest(Operation op, return QNetworkAccessManager::createRequest(op, newReq, outgoingData); } + +bool NetworkOverrider::isValid() const +{ + return m_rewriteFrom.isValid() && m_rewriteTo.isValid(); +} #endif diff --git a/tests/auto/qxmlquery/PushBaseliner.h b/tests/auto/qxmlquery/PushBaseliner.h index 0648c90..8478a6a 100644 --- a/tests/auto/qxmlquery/PushBaseliner.h +++ b/tests/auto/qxmlquery/PushBaseliner.h @@ -65,9 +65,9 @@ public: const QXmlNamePool &namePool) : m_out(out) , m_namePool(namePool) { - Q_ASSERT(m_out.codec()); } + bool isValid() const; virtual void startElement(const QXmlName&); virtual void endElement(); virtual void attribute(const QXmlName&, const QStringRef&); @@ -86,6 +86,11 @@ private: const QXmlNamePool m_namePool; }; +bool PushBaseliner::isValid() const +{ + return m_out.codec(); +} + void PushBaseliner::startElement(const QXmlName &name) { m_out << "startElement(" << name.toClarkName(m_namePool) << ')'<< endl; diff --git a/tests/auto/qxmlquery/tst_qxmlquery.cpp b/tests/auto/qxmlquery/tst_qxmlquery.cpp index e3c97d2..01499d3 100644 --- a/tests/auto/qxmlquery/tst_qxmlquery.cpp +++ b/tests/auto/qxmlquery/tst_qxmlquery.cpp @@ -967,6 +967,7 @@ void tst_QXmlQuery::evaluateToReceiver() QString produced; QTextStream stream(&produced, QIODevice::WriteOnly); PushBaseliner push(stream, query.namePool()); + QVERIFY(push.isValid()); query.evaluateTo(&push); const QString baselineName(inputFile(QLatin1String(SRCDIR "pushBaselines/") + inputQuery.left(inputQuery.length() - 2) + QString::fromLatin1("ref"))); @@ -1685,6 +1686,7 @@ void tst_QXmlQuery::constCorrectness() const QString dummyString; QTextStream dummyStream(&dummyString); PushBaseliner dummy(dummyStream, query.namePool()); + QVERIFY(dummy.isValid()); query.evaluateTo(&dummy); } } @@ -3078,6 +3080,7 @@ void tst_QXmlQuery::setNetworkAccessManager() const { NetworkOverrider networkOverrider(QUrl(QLatin1String("tag:example.com:DOESNOTEXIST")), QUrl(inputFileAsURI(QLatin1String(XMLPATTERNSDIR "/queries/simpleDocument.xml")))); + QVERIFY(networkOverrider.isValid()); QXmlQuery query; query.setNetworkAccessManager(&networkOverrider); @@ -3094,6 +3097,7 @@ void tst_QXmlQuery::setNetworkAccessManager() const { NetworkOverrider networkOverrider(QUrl(QLatin1String("tag:example.com:DOESNOTEXIST")), QUrl(inputFileAsURI(QLatin1String(XMLPATTERNSDIR "/queries/concat.xq")))); + QVERIFY(networkOverrider.isValid()); QXmlQuery query; query.setNetworkAccessManager(&networkOverrider); @@ -3301,7 +3305,7 @@ void tst_QXmlQuery::bindVariableQXmlQueryInvalidate() const QXmlQuery query2; query2.setQuery("'query2'"); - query.bindVariable(QLatin1String("name"), query); + query.bindVariable(QLatin1String("name"), query2); QVERIFY(!query.isValid()); } diff --git a/tests/auto/qxmlsimplereader/tst_qxmlsimplereader.cpp b/tests/auto/qxmlsimplereader/tst_qxmlsimplereader.cpp index 565df30..0e49304 100644 --- a/tests/auto/qxmlsimplereader/tst_qxmlsimplereader.cpp +++ b/tests/auto/qxmlsimplereader/tst_qxmlsimplereader.cpp @@ -165,7 +165,7 @@ class tst_QXmlSimpleReader : public QObject void roundtripWithNamespaces() const; private: - static QDomDocument fromByteArray(const QString &title, const QByteArray &ba); + static QDomDocument fromByteArray(const QString &title, const QByteArray &ba, bool *ok); XmlServer *server; }; @@ -730,25 +730,27 @@ void tst_QXmlSimpleReader::reportNamespace_data() const << QString("http://example.com/"); } -QDomDocument tst_QXmlSimpleReader::fromByteArray(const QString &title, const QByteArray &ba) +QDomDocument tst_QXmlSimpleReader::fromByteArray(const QString &title, const QByteArray &ba, bool *ok) { QDomDocument doc(title); - const bool ret = doc.setContent(ba, true); - Q_ASSERT(ret); + *ok = doc.setContent(ba, true); return doc; } void tst_QXmlSimpleReader::roundtripWithNamespaces() const { - QEXPECT_FAIL("", "Known problem, see 154573. The fix happens to break uic.", Abort); - const char *const expected = "<element b:attr=\"value\" xmlns:a=\"http://www.example.com/A\" xmlns:b=\"http://www.example.com/B\" />\n"; + bool ok; { const char *const xml = "<element xmlns:b=\"http://www.example.com/B\" b:attr=\"value\" xmlns:a=\"http://www.example.com/A\"/>"; - const QDomDocument one(fromByteArray("document", xml)); - const QDomDocument two(fromByteArray("document2", one.toByteArray(2))); + const QDomDocument one(fromByteArray("document", xml, &ok)); + QVERIFY(ok); + const QDomDocument two(fromByteArray("document2", one.toByteArray(2), &ok)); + QVERIFY(ok); + + QEXPECT_FAIL("", "Known problem, see 154573. The fix happens to break uic.", Abort); QCOMPARE(expected, one.toByteArray().constData()); QCOMPARE(one.toByteArray(2).constData(), two.toByteArray(2).constData()); @@ -758,8 +760,10 @@ void tst_QXmlSimpleReader::roundtripWithNamespaces() const { const char *const xml = "<element b:attr=\"value\" xmlns:b=\"http://www.example.com/B\" xmlns:a=\"http://www.example.com/A\"/>"; - const QDomDocument one(fromByteArray("document", xml)); - const QDomDocument two(fromByteArray("document2", one.toByteArray(2))); + const QDomDocument one(fromByteArray("document", xml, &ok)); + QVERIFY(ok); + const QDomDocument two(fromByteArray("document2", one.toByteArray(2), &ok)); + QVERIFY(ok); QCOMPARE(expected, one.toByteArray().constData()); QCOMPARE(one.toByteArray(2).constData(), two.toByteArray(2).constData()); diff --git a/tests/auto/qxmlstream/qc14n.h b/tests/auto/qxmlstream/qc14n.h index bf80908..661ddee 100644 --- a/tests/auto/qxmlstream/qc14n.h +++ b/tests/auto/qxmlstream/qc14n.h @@ -47,17 +47,9 @@ QT_FORWARD_DECLARE_CLASS(QString) class QC14N { public: - enum Option - { - IgnoreProcessingInstruction, - IgnoreComments - }; - typedef QFlags<Option> Options; - static bool isEqual(QIODevice *const firstDocument, QIODevice *const secondDocument, - QString *const message = 0, - const Options options = Options()); + QString *const message = 0); private: static bool isDifferent(const QXmlStreamReader &r1, @@ -76,20 +68,17 @@ private: */ bool QC14N::isEqual(QIODevice *const firstDocument, QIODevice *const secondDocument, - QString *const message, - const Options options) + QString *const message) { qDebug() << Q_FUNC_INFO; - Q_ASSERT_X(firstDocument, Q_FUNC_INFO, - "A valid QIODevice pointer must be supplied"); - Q_ASSERT_X(secondDocument, Q_FUNC_INFO, - "A valid QIODevice pointer must be supplied"); - Q_ASSERT_X(firstDocument->isReadable(), Q_FUNC_INFO, "The device must be readable."); - Q_ASSERT_X(secondDocument->isReadable(), Q_FUNC_INFO, "The device must be readable."); - - Q_ASSERT_X(options == Options(), Q_FUNC_INFO, - "Not yet implemented."); - Q_UNUSED(options); + if (!firstDocument) + qFatal("%s: A valid firstDocument QIODevice pointer must be supplied", Q_FUNC_INFO); + if (!secondDocument) + qFatal("%s: A valid secondDocument QIODevice pointer must be supplied", Q_FUNC_INFO); + if (!firstDocument->isReadable()) + qFatal("%s: The firstDocument device must be readable.", Q_FUNC_INFO); + if (!secondDocument->isReadable()) + qFatal("%s: The secondDocument device must be readable.", Q_FUNC_INFO); QXmlStreamReader r1(firstDocument); QXmlStreamReader r2(secondDocument); @@ -202,9 +191,9 @@ bool QC14N::isDifferent(const QXmlStreamReader &r1, r2.processingInstructionData() == r2.processingInstructionData(); } + default: + qFatal("%s: Unknown tokenType: %d", Q_FUNC_INFO, static_cast<int>(r1.tokenType())); + return false; } - - Q_ASSERT_X(false, Q_FUNC_INFO, "This line should never be reached"); - return false; } diff --git a/tests/auto/qxmlstream/tst_qxmlstream.cpp b/tests/auto/qxmlstream/tst_qxmlstream.cpp index fd2f90e..946a19a 100644 --- a/tests/auto/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/qxmlstream/tst_qxmlstream.cpp @@ -221,8 +221,7 @@ static QString documentElement(const QByteArray &document) reader.readNext(); } - Q_ASSERT_X(false, Q_FUNC_INFO, - qPrintable(QString::fromLatin1("The input %1 didn't contain an element.").arg(QString::fromUtf8(document.constData())))); + qFatal("The input %s didn't contain an element", document.constData()); return QString(); } @@ -265,7 +264,8 @@ public: expected(aExpected), output(aOutput) { - Q_ASSERT(!aId.isEmpty()); + if (aId.isEmpty()) + qFatal("%s: aId must not be an empty string", Q_FUNC_INFO); } QString id; @@ -289,7 +289,8 @@ public: TestSuiteHandler(const QUrl &baseURI) : runCount(0), skipCount(0) { - Q_ASSERT(baseURI.isValid()); + if (!baseURI.isValid()) + qFatal("%s: baseURI must be valid", Q_FUNC_INFO); m_baseURI.push(baseURI); } @@ -461,7 +462,7 @@ public: } else { - Q_ASSERT_X(false, Q_FUNC_INFO, "The input catalog is invalid."); + qFatal("The input catalog is invalid."); return false; } } @@ -481,9 +482,12 @@ public: static bool isWellformed(QIODevice *const inputFile, const ParseMode mode) { - Q_ASSERT(inputFile); - Q_ASSERT_X(inputFile->isOpen(), Q_FUNC_INFO, "The caller is responsible for opening the device."); - Q_ASSERT(mode == ParseIncrementally || mode == ParseSinglePass); + if (!inputFile) + qFatal("%s: inputFile must be a valid QIODevice pointer", Q_FUNC_INFO); + if (!inputFile->isOpen()) + qFatal("%s: inputFile must be opened by the caller", Q_FUNC_INFO); + if (mode != ParseIncrementally && mode != ParseSinglePass) + qFatal("%s: mode must be either ParseIncrementally or ParseSinglePass", Q_FUNC_INFO); if(mode == ParseIncrementally) { diff --git a/tests/auto/selftests/alive/qtestalive.cpp b/tests/auto/selftests/alive/qtestalive.cpp index ba42367..e743eae 100644 --- a/tests/auto/selftests/alive/qtestalive.cpp +++ b/tests/auto/selftests/alive/qtestalive.cpp @@ -78,7 +78,8 @@ private: QTestAlivePinger::QTestAlivePinger(QObject *receiver, QObject *parent) : QObject(parent), rec(receiver), currentSequenceId(0), lastSequenceId(0) { - Q_ASSERT(rec); + if (!rec) + qFatal("Null receiver object passed to QTestAlivePinger::QTestAlivePinger()"); timerId = startTimer(850); } @@ -147,8 +148,8 @@ bool QTestAlive::event(QEvent *e) void QTestAlive::run() { - Q_ASSERT_X(QCoreApplication::instance(), "QTestAlive::run()", - "Cannot start QTestAlive without a QCoreApplication instance."); + if (!QCoreApplication::instance()) + qFatal("QTestAlive::run(): Cannot start QTestAlive without a QCoreApplication instance."); QTestAlivePinger p(this); pinger = &p; diff --git a/tests/auto/xmlpatterns/tst_xmlpatterns.cpp b/tests/auto/xmlpatterns/tst_xmlpatterns.cpp index 4d59f22..45aa8d6 100644 --- a/tests/auto/xmlpatterns/tst_xmlpatterns.cpp +++ b/tests/auto/xmlpatterns/tst_xmlpatterns.cpp @@ -107,13 +107,13 @@ tst_XmlPatterns::tst_XmlPatterns() : m_generatedTests(0) , m_dontRun(false) { Q_SET_DEFAULT_IAP - - Q_ASSERT(m_normalizeTestName.isValid()); - Q_ASSERT(m_filenameInStderr.isValid()); } void tst_XmlPatterns::initTestCase() { + QVERIFY(m_normalizeTestName.isValid()); + QVERIFY(m_filenameInStderr.isValid()); + QProcess process; process.start(m_command); @@ -121,7 +121,7 @@ void tst_XmlPatterns::initTestCase() { m_dontRun = true; QEXPECT_FAIL("", "The command line tool is not in the path, most likely because Qt " - "has been partically built, such as only the sub-src rule. No tests will be run.", Abort); + "has been partially built, such as only the sub-src rule. No tests will be run.", Abort); QVERIFY(false); } diff --git a/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro b/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro index 3e252f6..48c79d5 100644 --- a/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro +++ b/tests/auto/xmlpatternsdiagnosticsts/xmlpatternsdiagnosticsts.pro @@ -25,3 +25,5 @@ wince*|symbian { catalog.path = . DEPLOYMENT += catalog } + +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro b/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro index f36211e..0fb5fef 100644 --- a/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro +++ b/tests/auto/xmlpatternsschemats/xmlpatternsschemats.pro @@ -25,3 +25,5 @@ INCLUDEPATH += $$QT_SOURCE_TREE/tests/auto/xmlpatternssdk/ \ $$QT_SOURCE_TREE/tests/auto/xmlpatternsxqts \ ../xmlpatternsxqts \ ../xmlpatternssdk + +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/auto/xmlpatternsxqts/tst_suitetest.cpp b/tests/auto/xmlpatternsxqts/tst_suitetest.cpp index 62cc4bb..ff6121f 100644 --- a/tests/auto/xmlpatternsxqts/tst_suitetest.cpp +++ b/tests/auto/xmlpatternsxqts/tst_suitetest.cpp @@ -108,7 +108,7 @@ void tst_SuiteTest::runTestSuite() const /* Run the tests, and serialize the result(as according to XQTSResult.xsd) to standard out. */ TestSuiteResult *const result = ts->runSuite(); - Q_ASSERT(result); + QVERIFY(result); QFile out(m_candidateBaseline); QVERIFY(out.open(QIODevice::WriteOnly)); diff --git a/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro b/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro index e81888a..0ced633 100644 --- a/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro +++ b/tests/auto/xmlpatternsxqts/xmlpatternsxqts.pro @@ -19,3 +19,5 @@ INCLUDEPATH += $$(QTDIR)/include/QtXmlPatterns/private \ CONFIG += testlib QT += xml TARGET = tst_xmlpatternsxqts + +requires(contains(QT_CONFIG,private_tests)) diff --git a/tests/benchmarks/declarative/script/tst_script.cpp b/tests/benchmarks/declarative/script/tst_script.cpp index 2020a18..b07ffa1 100644 --- a/tests/benchmarks/declarative/script/tst_script.cpp +++ b/tests/benchmarks/declarative/script/tst_script.cpp @@ -70,6 +70,9 @@ private slots: void property_qobject(); void property_qmlobject(); + void setproperty_js(); + void setproperty_qmlobject(); + void function_js(); void function_cpp(); void function_qobject(); @@ -108,12 +111,13 @@ inline QUrl TEST_FILE(const QString &filename) class TestObject : public QObject { Q_OBJECT - Q_PROPERTY(int x READ x) + Q_PROPERTY(int x READ x WRITE setX) public: TestObject(QObject *parent = 0); int x(); + void setX(int x) { m_x = x; } void emitMySignal() { emit mySignal(); } void emitMySignalWithArgs(int n) { emit mySignalWithArgs(n); } @@ -323,6 +327,49 @@ void tst_script::property_qmlobject() } } +#define SETPROPERTY_PROGRAM \ + "(function(testObject) { return (function() { " \ + " for (var ii = 0; ii < 10000; ++ii) { " \ + " testObject.x = ii; " \ + " } " \ + "}); })" + +void tst_script::setproperty_js() +{ + QScriptEngine engine; + + QScriptValue v = engine.newObject(); + v.setProperty(QLatin1String("x"), 0); + + QScriptValueList args; + args << v; + QScriptValue prog = engine.evaluate(SETPROPERTY_PROGRAM).call(engine.globalObject(), args); + prog.call(); + + QBENCHMARK { + prog.call(); + } +} + +void tst_script::setproperty_qmlobject() +{ + QDeclarativeEngine qmlengine; + + QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(&qmlengine); + TestObject to; + + QScriptValue v = QDeclarativeEnginePrivate::get(&qmlengine)->objectClass->newQObject(&to); + + QScriptValueList args; + args << v; + QScriptValue prog = engine->evaluate(SETPROPERTY_PROGRAM).call(engine->globalObject(), args); + prog.call(); + + QBENCHMARK { + prog.call(); + } +} + #define FUNCTION_PROGRAM \ "(function(testObject) { return (function() { " \ " var test = 0; " \ diff --git a/tests/benchmarks/gui/graphicsview/graphicsview.pro b/tests/benchmarks/gui/graphicsview/graphicsview.pro index e4fed19..1509466 100644 --- a/tests/benchmarks/gui/graphicsview/graphicsview.pro +++ b/tests/benchmarks/gui/graphicsview/graphicsview.pro @@ -3,6 +3,7 @@ SUBDIRS = \ functional \ qgraphicsanchorlayout \ qgraphicsitem \ + qgraphicslayout \ qgraphicsscene \ qgraphicsview \ qgraphicswidget diff --git a/tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro b/tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro new file mode 100644 index 0000000..19e2979 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/qgraphicslayout/qgraphicslayout.pro @@ -0,0 +1,6 @@ +load(qttest_p4) +TEMPLATE = app +TARGET = tst_bench_qgraphicslayout + +SOURCES += tst_qgraphicslayout.cpp + diff --git a/tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp b/tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp new file mode 100644 index 0000000..4bdcfb3 --- /dev/null +++ b/tests/benchmarks/gui/graphicsview/qgraphicslayout/tst_qgraphicslayout.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 <QtGui/qgraphicslayout.h> +#include <QtGui/qgraphicslinearlayout.h> +#include <QtGui/qgraphicswidget.h> +#include <QtGui/qgraphicsview.h> + +class tst_QGraphicsLayout : public QObject +{ + Q_OBJECT +public: + tst_QGraphicsLayout() {} + ~tst_QGraphicsLayout() {} + +private slots: + void invalidate(); +}; + + +class RectWidget : public QGraphicsWidget +{ +public: + RectWidget(QGraphicsItem *parent = 0, Qt::WindowFlags wFlags = 0) : QGraphicsWidget(parent, wFlags), setGeometryCalls(0) {} + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + Q_UNUSED(option); + Q_UNUSED(widget); + painter->drawRoundRect(rect()); + painter->drawLine(rect().topLeft(), rect().bottomRight()); + painter->drawLine(rect().bottomLeft(), rect().topRight()); + } + + void setGeometry(const QRectF &rect) + { + //qDebug() << "setGeometry():" << this->data(0).toString(); + setGeometryCalls->insert(this, rect); + QGraphicsWidget::setGeometry(rect); + } + + void callUpdateGeometry() { + QGraphicsWidget::updateGeometry(); + } + + QMap<RectWidget*, QRectF> *setGeometryCalls; +}; + +/** + * Test to see how much time is needed to resize all widgets in a + * layout-widget-layout-widget-.... hierarchy from the point where a + * leaf widget changes its size hint. (updateGeometry() is called). + * + * If you run the test for 4.7 you'll get some really high numbers, but + * that's because they also include painting (and possible processing of + * some other events). + */ +void tst_QGraphicsLayout::invalidate() +{ + QGraphicsLayout::setInstantInvalidatePropagation(true); + QGraphicsScene scene; + QGraphicsView *view = new QGraphicsView(&scene); + QMap<RectWidget*, QRectF> setGeometryCalls; + + RectWidget *window = new RectWidget(0, Qt::Window); + window->setGeometryCalls = &setGeometryCalls; + window->setData(0, QString(QChar('a'))); + + scene.addItem(window); + RectWidget *leaf = 0; + const int depth = 100; + RectWidget *parent = window; + for (int i = 1; i < depth; ++i) { + QGraphicsLinearLayout *l = new QGraphicsLinearLayout(parent); + l->setContentsMargins(0,0,0,0); + RectWidget *child = new RectWidget; + child->setData(0, QString(QChar('a' + i))); + child->setGeometryCalls = &setGeometryCalls; + l->addItem(child); + parent = child; + } + leaf = parent; + leaf->setMinimumSize(QSizeF(1,1)); + + view->show(); + + QTest::qWaitForWindowShown(view); + + // ...then measure... + + int pass = 1; + + // should be as small as possible, to reduce overhead of painting + QSizeF size(1, 1); + setGeometryCalls.clear(); + QBENCHMARK { + leaf->setMinimumSize(size); + leaf->setMaximumSize(size); + while (setGeometryCalls.count() < depth) { + QApplication::sendPostedEvents(); + } + // force a resize on each widget, this will ensure + // that each iteration will resize all 50 widgets + int w = int(size.width()); + w^=2; + size.setWidth(w); + } + delete view; + QGraphicsLayout::setInstantInvalidatePropagation(false); +} + +QTEST_MAIN(tst_QGraphicsLayout) + +#include "tst_qgraphicslayout.moc" diff --git a/tests/benchmarks/gui/image/blendbench/main.cpp b/tests/benchmarks/gui/image/blendbench/main.cpp index a16fd5a..06c36e7 100644 --- a/tests/benchmarks/gui/image/blendbench/main.cpp +++ b/tests/benchmarks/gui/image/blendbench/main.cpp @@ -208,9 +208,9 @@ void BlendBench::unalignedBlendArgb32() uchar *srcMemory = static_cast<uchar*>(qMallocAligned((dimension * dimension * sizeof(quint32)) + 16, 16)); QFETCH(int, offset); - srcMemory += (offset * sizeof(quint32)); + uchar *imageSrcMemory = srcMemory + (offset * sizeof(quint32)); - QImage src(srcMemory, dimension, dimension, QImage::Format_ARGB32_Premultiplied); + QImage src(imageSrcMemory, dimension, dimension, QImage::Format_ARGB32_Premultiplied); src.fill(0x87654321); QPainter painter(&destination); diff --git a/tests/manual/qgraphicslayout/flicker/flicker.pro b/tests/manual/qgraphicslayout/flicker/flicker.pro new file mode 100644 index 0000000..323a30f --- /dev/null +++ b/tests/manual/qgraphicslayout/flicker/flicker.pro @@ -0,0 +1,8 @@ +TEMPLATE = app +TARGET = +DEPENDPATH += . +INCLUDEPATH += . + +# Input +HEADERS += window.h +SOURCES += main.cpp window.cpp diff --git a/tests/manual/qgraphicslayout/flicker/main.cpp b/tests/manual/qgraphicslayout/flicker/main.cpp new file mode 100644 index 0000000..7e75c2b --- /dev/null +++ b/tests/manual/qgraphicslayout/flicker/main.cpp @@ -0,0 +1,56 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 <windows.h> +#include "window.h" + +int main(int argc, char **argv) +{ + QApplication app(argc, argv); + Window *window = new Window(); + window->resize(800, 600); + + window->show(); + + return app.exec(); + +} diff --git a/tests/manual/qgraphicslayout/flicker/window.cpp b/tests/manual/qgraphicslayout/flicker/window.cpp new file mode 100644 index 0000000..ee4db3f --- /dev/null +++ b/tests/manual/qgraphicslayout/flicker/window.cpp @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 "window.h" + +void SlowWidget::setGeometry(const QRectF &rect) +{ + bool reiterate = false; + Statistics &stats = *m_stats; + if (stats.relayoutClicked) { + ++(stats.setGeometryTracker[this]); + ++stats.setGeometryCount; + qDebug() << "setGeometryCount:" << stats.setGeometryCount; + if (stats.setGeometryTracker.count() == m_window->m_depthSpinBox->value()) { + ++stats.currentBenchmarkIteration; + qDebug() << "currentBenchmarkIteration:" << stats.currentBenchmarkIteration; + if (stats.currentBenchmarkIteration == m_window->m_benchmarkIterationsSpinBox->value()) { + if (stats.output) + stats.output->setText(tr("DONE. Elapsed: %1, setGeometryCount: %2").arg(stats.time.elapsed()).arg(stats.setGeometryCount)); + } else { + reiterate = true; + } + stats.setGeometryTracker.clear(); + + } + } + + QGraphicsWidget::setGeometry(rect); + + if (reiterate) { + m_window->doAgain(); + //QTimer::singleShot(0, m_window, SLOT(doAgain())); + } +} + diff --git a/tests/manual/qgraphicslayout/flicker/window.h b/tests/manual/qgraphicslayout/flicker/window.h new file mode 100644 index 0000000..b4c42c0 --- /dev/null +++ b/tests/manual/qgraphicslayout/flicker/window.h @@ -0,0 +1,284 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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 WINDOW_H +#define WINDOW_H + + +#include <QtGui> + +static void qSleep(int msec) +{ + + struct Thread : public QThread + { + static void wait(int msec) + { + QThread::msleep(msec); + } + }; + Thread::wait(msec); +} + +struct Statistics { + Statistics() : output(0), + setGeometryCount(0), currentBenchmarkIteration(0), relayoutClicked(false), sleepMsecs(0) + { + } + QMap<QGraphicsWidget*, int> setGeometryTracker; + QTime time; + int setGeometryCount; + int sleepMsecs; + QLabel *output; + void sleep() + { + qSleep(sleepMsecs); + } + int currentBenchmarkIteration; + bool relayoutClicked; + +}; + + +class Window; + +class SlowWidget : public QGraphicsWidget { +public: + SlowWidget(QGraphicsWidget *w = 0, Qt::WindowFlags wFlags = 0) : QGraphicsWidget(w, wFlags) + { + m_window = 0; + } + + void setStats(Statistics *stats) + { + m_stats = stats; + } + + void setWindow(Window *window) + { + m_window = window; + } + + void setGeometry(const QRectF &rect); + + bool event(QEvent *e) + { + if (e->type() == QEvent::LayoutRequest) { + if (m_stats->sleepMsecs > 0) { + m_stats->sleep(); + qDebug("sleep %d ms\n", m_stats->sleepMsecs); + } + } + return QGraphicsWidget::event(e); + } + + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) + { + Q_UNUSED(option); + Q_UNUSED(widget); + painter->setBrush(m_brush); + painter->drawRoundRect(rect()); + painter->drawLine(rect().topLeft(), rect().bottomRight()); + painter->drawLine(rect().bottomLeft(), rect().topRight()); + } + + void setBrush(const QBrush &brush) + { + m_brush = brush; + } +private: + QBrush m_brush; + Statistics *m_stats; + Window *m_window; +}; + +class Window : public QWidget { + Q_OBJECT +public: + Window() : QWidget() + { + QGraphicsView *m_view = new QGraphicsView(&scene); + + m_window = 0; + m_leaf = 0; + + m_button = new QPushButton(tr("Relayout")); + m_button->setObjectName("button"); + + m_sleepLabel = new QLabel(tr("Sleep:")); + m_sleepSpinBox = new QSpinBox; + m_sleepSpinBox->setRange(0, 1000); + m_sleepSpinBox->setSingleStep(10); + + m_depthLabel = new QLabel(tr("Depth:")); + m_depthSpinBox = new QSpinBox; + m_depthSpinBox->setObjectName("depthSpinBox"); + m_depthSpinBox->setRange(1, 200); + m_depthSpinBox->setSingleStep(5); + + m_benchmarkIterationsLabel = new QLabel(tr("Benchmark iterations")); + m_benchmarkIterationsSpinBox = new QSpinBox; + m_benchmarkIterationsSpinBox->setObjectName("benchmarkIterationsSpinBox"); + m_benchmarkIterationsSpinBox->setRange(1, 1000); + m_benchmarkIterationsSpinBox->setValue(41); + m_benchmarkIterationsSpinBox->setSingleStep(10); + + m_instantCheckBox = new QCheckBox(tr("Instant propagation")); + m_instantCheckBox->setObjectName("instantPropagationCheckbox"); + QGraphicsLayout::setInstantInvalidatePropagation(true); + m_instantCheckBox->setChecked(QGraphicsLayout::instantInvalidatePropagation()); + + m_resultLabel = new QLabel(tr("Press relayout to start test")); + + QHBoxLayout *hbox = new QHBoxLayout; + hbox->addWidget(m_sleepLabel); + hbox->addWidget(m_sleepSpinBox); + hbox->addWidget(m_depthLabel); + hbox->addWidget(m_depthSpinBox); + hbox->addWidget(m_benchmarkIterationsLabel); + hbox->addWidget(m_benchmarkIterationsSpinBox); + hbox->addWidget(m_instantCheckBox); + hbox->addWidget(m_resultLabel); + hbox->addStretch(); + hbox->addWidget(m_button); + + QVBoxLayout *vbox = new QVBoxLayout; + vbox->addWidget(m_view); + vbox->addLayout(hbox); + setLayout(vbox); + + metaObject()->connectSlotsByName(this); + + m_depthSpinBox->setValue(20); // triggers purposedly on_depthSpinBox_valueChanged + } + +private slots: + void on_depthSpinBox_valueChanged(int value) + { + m_stats.relayoutClicked = false; + if (m_window) { + QApplication::processEvents(); + delete m_window; + } + m_window = new SlowWidget(0, Qt::Window); + m_window->setStats(&m_stats); + m_window->setWindow(this); + QColor col(Qt::black); + m_window->setBrush(col); + scene.addItem(m_window); + m_leaf = 0; + const int depth = value; + SlowWidget *parent = m_window; + for (int i = 1; i < depth; ++i) { + QGraphicsLinearLayout *l = new QGraphicsLinearLayout(parent); + l->setContentsMargins(2,2,2,2); + SlowWidget *child = new SlowWidget; + QColor col; + col.setHsl(0, 0, 255*i/(depth - 1)); + child->setBrush(col); + child->setStats(&m_stats); + child->setWindow(this); + l->addItem(child); + parent = child; + } + m_leaf = parent; + } + + void on_button_clicked(bool /*check = false*/) + { + m_stats.relayoutClicked = true; + if (m_leaf) { + QSizeF sz = m_leaf->size(); + int w = int(sz.width()); + w^=16; + sz = QSizeF(w,w); + m_stats.output = m_resultLabel; + m_stats.output->setText(QString("wait...")); + m_stats.setGeometryCount = 0; + m_stats.setGeometryTracker.clear(); + m_stats.sleepMsecs = m_sleepSpinBox->value(); + m_stats.time.start(); + m_stats.currentBenchmarkIteration = 0; + m_leaf->setMinimumSize(sz); + m_leaf->setMaximumSize(sz); + } + } + + void on_instantPropagationCheckbox_toggled(bool checked) + { + QGraphicsLayout::setInstantInvalidatePropagation(checked); + } + +public slots: + void doAgain() + { + if (m_leaf) { + QSizeF sz = m_leaf->size(); + int w = int(sz.width()); + w^=16; + sz = QSizeF(w,w); + m_leaf->setMinimumSize(sz); + m_leaf->setMaximumSize(sz); + } + } + +private: +public: + QGraphicsScene scene; + QGraphicsView *m_view; + QPushButton *m_button; + QLabel *m_sleepLabel; + QSpinBox *m_sleepSpinBox; + QLabel *m_depthLabel; + QSpinBox *m_depthSpinBox; + QLabel *m_benchmarkIterationsLabel; + QSpinBox *m_benchmarkIterationsSpinBox; + QCheckBox *m_instantCheckBox; + QLabel *m_resultLabel; + QGraphicsWidget *m_leaf; + SlowWidget *m_window; + Statistics m_stats; + + +}; + + +#endif //WINDOW_H diff --git a/tools/configure/configure.pro b/tools/configure/configure.pro index 1245646..c2f1b65 100644 --- a/tools/configure/configure.pro +++ b/tools/configure/configure.pro @@ -79,6 +79,8 @@ SOURCES = main.cpp configureapp.cpp environment.cpp tools.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qhash.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qlist.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qlocale.cpp \ + $$QT_SOURCE_TREE/src/corelib/tools/qlocale_win.cpp \ + $$QT_SOURCE_TREE/src/corelib/tools/qlocale_tools.cpp \ $$QT_SOURCE_TREE/src/corelib/tools/qvector.cpp \ $$QT_SOURCE_TREE/src/corelib/codecs/qutfcodec.cpp \ $$QT_SOURCE_TREE/src/corelib/codecs/qtextcodec.cpp \ diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index 494ea52..47e2ef9 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -3216,8 +3216,6 @@ void Configure::generateConfigfiles() if (dictionary.contains("XQMAKESPEC") && dictionary["XQMAKESPEC"].startsWith("symbian")) { // These features are not ported to Symbian (yet) - qconfigList += "QT_NO_CONCURRENT"; - qconfigList += "QT_NO_QFUTURE"; qconfigList += "QT_NO_CRASHHANDLER"; qconfigList += "QT_NO_PRINTER"; qconfigList += "QT_NO_SYSTEMTRAYICON"; diff --git a/tools/designer/src/components/tabordereditor/tabordereditor.cpp b/tools/designer/src/components/tabordereditor/tabordereditor.cpp index e372bdc..2932adc 100644 --- a/tools/designer/src/components/tabordereditor/tabordereditor.cpp +++ b/tools/designer/src/components/tabordereditor/tabordereditor.cpp @@ -208,7 +208,7 @@ bool TabOrderEditor::skipWidget(QWidget *w) const if (index != -1) { bool ok = false; Qt::FocusPolicy q = (Qt::FocusPolicy) Utils::valueOf(sheet->property(index), &ok); - return !ok || q == Qt::NoFocus; + return !ok || !(q & Qt::TabFocus); } } diff --git a/tools/designer/src/designer/qdesigner_workbench.cpp b/tools/designer/src/designer/qdesigner_workbench.cpp index ffc4b8c..df679eb 100644 --- a/tools/designer/src/designer/qdesigner_workbench.cpp +++ b/tools/designer/src/designer/qdesigner_workbench.cpp @@ -410,6 +410,9 @@ void QDesignerWorkbench::switchToDockedMode() switchToNeutralMode(); +#ifdef Q_WS_X11 + QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, false); +#endif #ifndef Q_WS_MAC QDesignerToolWindow *widgetBoxWrapper = widgetBoxToolWindow(); widgetBoxWrapper->action()->setVisible(true); @@ -477,6 +480,14 @@ void QDesignerWorkbench::switchToTopLevelMode() // The widget box is special, it gets the menubar and gets to be the main widget. m_core->setTopLevel(widgetBoxWrapper); +#ifdef Q_WS_X11 + // For now the appmenu protocol does not make it possible to associate a + // menubar with all application windows. This means in top level mode you + // can only reach the menubar when the widgetbox window is active. Since + // this is quite inconvenient, better not use the native menubar in this + // configuration and keep the menubar in the widgetbox window. + QApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, true); +#endif #ifndef Q_WS_MAC widgetBoxWrapper->setMenuBar(m_globalMenuBar); widgetBoxWrapper->action()->setVisible(false); diff --git a/tools/qdoc3/codemarker.h b/tools/qdoc3/codemarker.h index 21bc31f..00660e7 100644 --- a/tools/qdoc3/codemarker.h +++ b/tools/qdoc3/codemarker.h @@ -165,10 +165,11 @@ class CodeMarker static const Node *nodeForString(const QString& string); static QString stringForNode(const Node *node); + QString typified(const QString &string); + protected: virtual QString sortName(const Node *node); QString protect(const QString &string); - QString typified(const QString &string); QString taggedNode(const Node* node); #ifdef QDOC_QML QString taggedQmlNode(const Node* node); diff --git a/tools/qdoc3/config.cpp b/tools/qdoc3/config.cpp index 838f6ac..eaec327 100644 --- a/tools/qdoc3/config.cpp +++ b/tools/qdoc3/config.cpp @@ -48,7 +48,7 @@ #include <QFile> #include <QTemporaryFile> #include <QTextStream> - +#include <qdebug.h> #include "config.h" #include <stdlib.h> @@ -175,6 +175,7 @@ Config::Config(const QString& programName) } /*! + The destructor has nothing special to do. */ Config::~Config() { @@ -202,6 +203,30 @@ void Config::load(const QString& fileName) } /*! + Writes the qdoc configuration data to the named file. + The previous contents of the file are overwritten. + */ +void Config::unload(const QString& fileName) +{ + + QStringMultiMap::ConstIterator v = stringValueMap.begin(); + while (v != stringValueMap.end()) { + qDebug() << v.key() << " = " << v.value(); +#if 0 + if (v.key().startsWith(varDot)) { + QString subVar = v.key().mid(varDot.length()); + int dot = subVar.indexOf(QLatin1Char('.')); + if (dot != -1) + subVar.truncate(dot); + t.insert(subVar,v.value()); + } +#endif + ++v; + } + qDebug() << "fileName:" << fileName; +} + +/*! Joins all the strings in \a values into a single string with the individual \a values separated by ' '. Then it inserts the result into the string list map with \a var as the key. diff --git a/tools/qdoc3/config.h b/tools/qdoc3/config.h index 8e19ed2..94f0060 100644 --- a/tools/qdoc3/config.h +++ b/tools/qdoc3/config.h @@ -63,6 +63,7 @@ class Config ~Config(); void load(const QString& fileName); + void unload(const QString& fileName); void setStringList(const QString& var, const QStringList& values); const QString& programName() const { return prog; } diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp index 1bc4992..5f44cd8 100644 --- a/tools/qdoc3/ditaxmlgenerator.cpp +++ b/tools/qdoc3/ditaxmlgenerator.cpp @@ -92,6 +92,7 @@ QString DitaXmlGenerator::ditaTags[] = "apiDesc", "APIMap", "apiName", + "apiRelation", "audience", "author", "b", @@ -284,14 +285,15 @@ void DitaXmlGenerator::writeCharacters(const QString& text) with the \a href attribute and the \a text. */ void DitaXmlGenerator::addLink(const QString& href, - const QStringRef& text) + const QStringRef& text, + DitaTag t) { if (!href.isEmpty()) { - writeStartTag(DT_xref); + writeStartTag(t); // formathtml xmlWriter().writeAttribute("href", href); writeCharacters(text.toString()); - writeEndTag(); // </xref> + writeEndTag(); // </t> } else { writeCharacters(text.toString()); @@ -767,6 +769,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, case Atom::Code: { writeStartTag(DT_codeblock); + xmlWriter().writeAttribute("outputclass","cpp"); QString chars = trimmedTrailing(atom->string()); writeText(chars, marker, relative); writeEndTag(); // </codeblock> @@ -774,6 +777,7 @@ int DitaXmlGenerator::generateAtom(const Atom *atom, break; case Atom::Qml: writeStartTag(DT_codeblock); + xmlWriter().writeAttribute("outputclass","qml"); writeText(trimmedTrailing(atom->string()), marker, relative); writeEndTag(); // </codeblock> break; @@ -1718,7 +1722,7 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark */ generateHeader(inner, fullTitle); generateBrief(inner, marker); // <shortdesc> - writeProlog(inner,marker); + writeProlog(inner); writeStartTag(DT_cxxClassDetail); writeStartTag(DT_cxxClassDefinition); @@ -1838,7 +1842,7 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark generateHeader(inner, fullTitle); generateBrief(inner, marker); // <shortdesc> - writeProlog(inner,marker); + writeProlog(inner); writeStartTag(DT_cxxClassDetail); writeStartTag(DT_cxxClassDefinition); @@ -1974,7 +1978,7 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark */ generateHeader(inner, fullTitle); generateBrief(inner, marker); // <shortdesc> - writeProlog(inner,marker); + writeProlog(inner); writeStartTag(DT_cxxClassDetail); enterApiDesc(QString(),title); @@ -2093,7 +2097,7 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark generateHeader(inner, fullTitle); generateBrief(inner, marker); // <shortdesc> - writeProlog(inner,marker); + writeProlog(inner); writeStartTag(DT_cxxClassDetail); enterApiDesc(QString(),title); @@ -2195,7 +2199,7 @@ void DitaXmlGenerator::generateFakeNode(const FakeNode* fake, CodeMarker* marker generateHeader(fake, fullTitle); generateBrief(fake, marker); // <shortdesc> - writeProlog(fake, marker); + writeProlog(fake); writeStartTag(DT_body); enterSection(QString(),QString()); @@ -4712,7 +4716,7 @@ void DitaXmlGenerator::writeLocation(const Node* n) Write the <cxxFunction> elements. */ void DitaXmlGenerator::writeFunctions(const Section& s, - const Node* n, + const InnerNode* parent, CodeMarker* marker, const QString& attribute) { @@ -4775,7 +4779,7 @@ void DitaXmlGenerator::writeFunctions(const Section& s, } } - if (fn->name() == n->name()) { + if (fn->name() == parent->name()) { writeStartTag(DT_cxxFunctionConstructor); xmlWriter().writeAttribute("name","constructor"); xmlWriter().writeAttribute("value","constructor"); @@ -4789,7 +4793,8 @@ void DitaXmlGenerator::writeFunctions(const Section& s, } else { writeStartTag(DT_cxxFunctionDeclaredType); - writeCharacters(fn->returnType()); + QString src = marker->typified(fn->returnType()); + replaceTypesWithLinks(fn,parent,marker,src); writeEndTag(); // <cxxFunctionDeclaredType> } @@ -4825,7 +4830,7 @@ void DitaXmlGenerator::writeFunctions(const Section& s, writeEndTag(); // </cxxFunctionReimplemented> } } - writeParameters(fn); + writeParameters(fn,parent,marker); writeLocation(fn); writeEndTag(); // <cxxFunctionDefinition> @@ -4846,10 +4851,51 @@ void DitaXmlGenerator::writeFunctions(const Section& s, } } +static const QString typeTag("type"); +static const QChar charLangle = '<'; +static const QChar charAt = '@'; + +/*! + This function replaces class and enum names with <apiRelation> + elements, i.e. links. + */ +void DitaXmlGenerator::replaceTypesWithLinks(const Node* n, + const InnerNode* parent, + CodeMarker* marker, + QString& src) +{ + QStringRef arg; + QStringRef par1; + int srcSize = src.size(); + QString text; + for (int i=0; i<srcSize;) { + if (src.at(i) == charLangle && src.at(i+1) == charAt) { + if (!text.isEmpty()) { + writeCharacters(text); + text.clear(); + } + i += 2; + if (parseArg(src, typeTag, &i, srcSize, &arg, &par1)) { + const Node* tn = marker->resolveTarget(arg.toString(), myTree, parent, n); + addLink(linkForNode(tn,parent),arg,DT_apiRelation); + } + } + else { + text += src.at(i++); + } + } + if (!text.isEmpty()) { + writeCharacters(text); + text.clear(); + } +} + /*! This function writes the <cxxFunctionParameters> element. */ -void DitaXmlGenerator::writeParameters(const FunctionNode* fn) +void DitaXmlGenerator::writeParameters(const FunctionNode* fn, + const InnerNode* parent, + CodeMarker* marker) { const QList<Parameter>& parameters = fn->parameters(); if (!parameters.isEmpty()) { @@ -4858,7 +4904,9 @@ void DitaXmlGenerator::writeParameters(const FunctionNode* fn) while (p != parameters.end()) { writeStartTag(DT_cxxFunctionParameter); writeStartTag(DT_cxxFunctionParameterDeclaredType); - writeCharacters((*p).leftType()); + QString src = marker->typified((*p).leftType()); + replaceTypesWithLinks(fn,parent,marker,src); + //writeCharacters((*p).leftType()); if (!(*p).rightType().isEmpty()) writeCharacters((*p).rightType()); writeEndTag(); // <cxxFunctionParameterDeclaredType> @@ -5664,29 +5712,29 @@ QString DitaXmlGenerator::metadataDefault(DitaTag t) const \list \o <audience> * \o <author> * - \o <brand> + \o <brand> not used \o <category> * \o <compomnent> * \o <copyrholder> * \o <copyright> * - \o <created> + \o <created> not used \o <copyryear> * - \o <critdates> - \o <keyword> - \o <keywords> + \o <critdates> not used + \o <keyword> not used + \o <keywords> not used \o <metadata> * - \o <othermeta> + \o <othermeta> * \o <permissions> * - \o <platform> + \o <platform> not used \o <prodinfo> * \o <prodname> * \o <prolog> * \o <publisher> * - \o <resourceid> - \o <revised> - \o <source> - \o <tm> - \o <unknown> + \o <resourceid> not used + \o <revised> not used + \o <source> not used + \o <tm> not used + \o <unknown> not used \o <vrm> * \o <vrmlist> * \endlist @@ -5695,7 +5743,7 @@ QString DitaXmlGenerator::metadataDefault(DitaTag t) const */ void -DitaXmlGenerator::writeProlog(const InnerNode* inner, CodeMarker* marker) +DitaXmlGenerator::writeProlog(const InnerNode* inner) { if (!inner) return; diff --git a/tools/qdoc3/ditaxmlgenerator.h b/tools/qdoc3/ditaxmlgenerator.h index ffca234..0044eff 100644 --- a/tools/qdoc3/ditaxmlgenerator.h +++ b/tools/qdoc3/ditaxmlgenerator.h @@ -87,6 +87,7 @@ class DitaXmlGenerator : public PageGenerator DT_apiDesc, DT_APIMap, DT_apiName, + DT_apiRelation, DT_audience, DT_author, DT_b, @@ -292,11 +293,15 @@ class DitaXmlGenerator : public PageGenerator void writeDerivations(const ClassNode* cn, CodeMarker* marker); void writeLocation(const Node* n); void writeFunctions(const Section& s, - const Node* n, + const InnerNode* parent, CodeMarker* marker, const QString& attribute = QString()); void writeNestedClasses(const Section& s, const Node* n); - void writeParameters(const FunctionNode* fn); + void replaceTypesWithLinks(const Node* n, + const InnerNode* parent, + CodeMarker* marker, + QString& src); + void writeParameters(const FunctionNode* fn, const InnerNode* parent, CodeMarker* marker); void writeEnumerations(const Section& s, CodeMarker* marker, const QString& attribute = QString()); @@ -315,7 +320,7 @@ class DitaXmlGenerator : public PageGenerator void writePropertyParameter(const QString& tag, const NodeList& nlist); void writeRelatedLinks(const FakeNode* fake, CodeMarker* marker); void writeLink(const Node* node, const QString& tex, const QString& role); - void writeProlog(const InnerNode* inner, CodeMarker* marker); + void writeProlog(const InnerNode* inner); bool writeMetadataElement(const InnerNode* inner, DitaXmlGenerator::DitaTag t, bool force=true); @@ -438,7 +443,7 @@ class DitaXmlGenerator : public PageGenerator virtual void generateInnerNode(const InnerNode* node); QXmlStreamWriter& xmlWriter(); void writeApiDesc(const Node* node, CodeMarker* marker, const QString& title); - void addLink(const QString& href, const QStringRef& text); + void addLink(const QString& href, const QStringRef& text, DitaTag t = DT_xref); void writeDitaMap(); void writeStartTag(DitaTag t); void writeEndTag(DitaTag t=DT_NONE); diff --git a/tools/qdoc3/doc/corefeatures.qdoc b/tools/qdoc3/doc/corefeatures.qdoc new file mode 100644 index 0000000..ee579cf --- /dev/null +++ b/tools/qdoc3/doc/corefeatures.qdoc @@ -0,0 +1,35 @@ +/**************************************************************************** +** +** Copyright (C) 2011 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:FDL$ +** 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 Free Documentation License +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of this +** file. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +/*! + \page corefeatures.html + \title Core Features + + \input examples/signalandslots.qdocinc + \input examples/objectmodel.qdocinc + \input examples/layoutmanagement.qdocinc +*/ diff --git a/tools/qdoc3/doc/qdoc-manual.qdoc b/tools/qdoc3/doc/qdoc-manual.qdoc index 0e4055b..da0646e 100644 --- a/tools/qdoc3/doc/qdoc-manual.qdoc +++ b/tools/qdoc3/doc/qdoc-manual.qdoc @@ -66,6 +66,7 @@ \o \l {Compatibility Issues} \o \l {qt.qdocconf} \o \l {minimum.qdocconf} + \o \l {Generating DITA XML Output} \endlist \endlist @@ -3999,20 +4000,11 @@ Here are links to the \c .qdocinc files used above: \l{signalandslots.qdocinc}, \l{objectmodel.qdocinc}, - \l{layoutmanagement.qdocinc}. QDoc renders this page as: - - \quotation - \raw HTML - <h1>Core Features</h1> - \endraw - - \input examples/signalandslots.qdocinc - \input examples/objectmodel.qdocinc - \input examples/layoutmanagement.qdocinc - \endquotation + \l{layoutmanagement.qdocinc}. QDoc renders this page + \l{corefeatures.html} {as shown here}. \target 2-argument-form} - \section2 \\include filename snippet-identifier + \section2 \\include filename snippet-identifier \span {class="newStuff"} {(new)} It is kind of a pain to make a separate \c .qdocinc file for every QDoc include snippet you want to use in multiple places in the @@ -4046,48 +4038,77 @@ sent to the QDoc input stream. You can even nest these snippets, although it's not clear why you would want to do that. - \target meta-command + \target meta-command \section1 \\meta - The \\meta command is the QDoc equivalent to the HTML - \c meta tag. - - The command accepts two arguments: The first argument (the - following word) is equivalent to the HTML meta tag's \e name - variable, and the second argument (the rest of the line) is - equivalent to the tag's \e contents variable. - - \code - / *! - \meta author Summerfield - - \section1 Automatic Dialogs - - \abstract - This article shows how to maintain sets of - "attributes" (QVariant values), and how to allow - users to view and edit them using dialogs that are - created dynamically based on the attributes and - their types. - \endabstract - - The Attributes class described in this article holds a - set of QVariants, and can create a dialog to present - the QVariants to the user in an appropriate way. + The \\meta command is mainly used for including metadata in DITA + XML files. It is also used when generating HTML output for specifying + the \e maintainer(s) of a C++ class. - ... - * / - \endcode + The command has two arguments: The first argument is the name of the + metadata attribute you wish to set, and the second argument is the + value for the attribute. Each argument should be enclosed in curly + brackets, as shown in this example: - QDoc renders this as: + \code + / *! + \class QWidget + \brief The QWidget class is the base class of all user interface objects. + + \ingroup basicwidgets + + \meta {technology} {User Interface} + \meta {platform} {OS X 10.6} + \meta {platform} {Symbian} + \meta {platform} {MeeGo} + \meta {audience} {user} + \meta {audience} {programmer} + \meta {audience} {designer} + * / + \endcode - \code - <head> - ... - <meta name="author" content="Summerfield" /> - ... - </head> - \endcode + When running QDoc to generate HTML, the example above will have no + effect on the generated output, but if you run QDoc to generate + DITA XML, the example will generate the following: + + \code + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE cxxClass PUBLIC "-//NOKIA//DTD DITA C++ API Class Reference Type v0.6.0//EN" "dtd/cxxClass.dtd"> + <!--qwidget.cpp--> + <cxxClass id="id-9a14268e-6b09-4eee-b940-21a00a0961df"> + <apiName>QWidget</apiName> + <shortdesc>the QWidget class is the base class of all user interface objects.</shortdesc> + <prolog> + <author>Qt Development Frameworks</author> + <publisher>Nokia</publisher> + <copyright> + <copyryear year="2011"/> + <copyrholder>Nokia</copyrholder> + </copyright> + <permissions view="all"/> + <metadata> + <audience type="designer"/> + <audience type="programmer"/> + <audience type="user"/> + <category>Class reference</category> + <prodinfo> + <prodname>Qt Reference Documentation</prodname> + <vrmlist> + <vrm version="4" release="7" modification="3"/> + </vrmlist> + <component>QtGui</component> + </prodinfo> + <othermeta name="platform" content="MeeGo"/> + <othermeta name="platform" content="Symbian"/> + <othermeta name="platform" content="OS X 10.6"/> + <othermeta name="technology" content="User Interface"/> + </metadata> + </prolog> + \endcode + + In the example output, several values have been set using defualt + values obtained from the QDoc configuration file. See \l + {Generating DITA XML Output} for details. \target omit-command \section1 \\omit @@ -6932,7 +6953,7 @@ \page 21-1-minimum-qdocconf.html \previouspage qt.qdocconf \contentspage Table of Contents - \nextpage Table of Contents + \nextpage Generating DITA XML Output \title minimum.qdocconf @@ -6951,6 +6972,65 @@ */ /*! + \page 21-3-qt-dita-xml-output.html + \previouspage minimum.qdocconf + \contentspage Table of Contents + \nextpage Table of Contents + + \title Generating DITA XML Output + + QDoc can generate \l {http://dita.xml.org} {DITA XML output}. + + In your confifiguration file, set your \c {outputformats} variable + to \c {DITAXML}, and send the output to an appropriate directory: + + \code + outputdir = $QTDIR/doc/ditaxml + outputformats = DITAXML + \endcode + + And include these macros in your configuration file to prevent + QDoc from doing some escaping that doesn't validate in XML: + + \code + macro.aacute.DITAXML = "á" + macro.Aring.DITAXML = "Å" + macro.aring.DITAXML = "å" + macro.Auml.DITAXML = "Ä" + macro.br.DITAXML = " " + macro.BR.DITAXML = " " + macro.copyright.DITAXML = "©" + macro.eacute.DITAXML = "é" + macro.hr.DITAXML = " " + macro.iacute.DITAXML = "í" + macro.oslash.DITAXML = "ø" + macro.ouml.DITAXML = "ö" + macro.raisedaster.DITAXML = "<sup>*</sup>" + macro.rarrow.DITAXML = "→" + macro.reg.DITAXML = "<sup>®</sup>" + macro.uuml.DITAXML = "ü" + macro.mdash.DITAXML = "—" + macro.emptyspan.DITAXML = " " + \endcode + + You can also set default values for some of the tags in the DITA + \c {<prolog>} and \c {<metadata>} elements: + + \code + dita.metadata.default.author = Qt Development Frameworks + dita.metadata.default.permissions = all + dita.metadata.default.publisher = Nokia + dita.metadata.default.copyryear = 2011 + dita.metadata.default.copyrholder = Nokia + dita.metadata.default.audience = programmer + \endcode + + See the \l {12-0-qdoc-commands-miscellaneous.html#meta-command} + {\\meta} command for more details on DITA metadata. + +*/ + +/*! \page 22-qdoc-configuration-generalvariables.html \previouspage The QDoc Configuration File \contentspage Table of Contents @@ -6981,7 +7061,7 @@ information see the \l {Compatibility Issues} {compatibility section}. - See also \l {macro-command} {macro}. + See also \l {macro-variable} {macro}. \target codeindent-variable \section1 codeindent @@ -7480,23 +7560,27 @@ \target macro-variable \section1 macro - The \c macro variable can be used to create your own QDoc - commands. + The \c macro variable is used to create your own simple QDoc + commands. The syntax is \tt {macro.\e{command} = \e{definition}}, + where the definition is written using QDoc syntax. - The general syntax is \tt {macro.\e{command} = - "\e{definition}}". The definition can be described using QDoc - syntax. In addition it is possible to provide an HTML definition - by appending .HTML to the variable. - - For example in \l qt.qdocconf: + A macro variable can be restricted for use in one type of output + generation. By appending \c {.HTML} to the macro name, for + example, the macro is only used when generating HTML output. By + appending \c {.DITAXML} to the macro name, the macro is only used + when generating DITA XML. \code macro.gui = "\\bold" macro.raisedaster.HTML = "<sup>*</sup>" \endcode - makes sure that the \\gui command renders its argument using a - bold font, and that \\raisedaster renders a '*'. + The first macro defines the \\gui command to render its argument + using a bold font. The second macro defines the \\raisedaster + command to render a superscript asterisk, but only when generating + HTML. + + See also \l {alias-variable} {alias}. \target naturallanguage-variable \section1 naturallanguage diff --git a/tools/qdoc3/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 114db26..a6cf646 100644 --- a/tools/qdoc3/htmlgenerator.cpp +++ b/tools/qdoc3/htmlgenerator.cpp @@ -93,104 +93,6 @@ static QRegExp typeTag("(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)"); static QRegExp spanTag("</@(?:comment|preprocessor|string|char|number|op|type|name|keyword)>"); static QRegExp unknownTag("</?@[^>]*>"); -bool parseArg(const QString &src, - const QString &tag, - int *pos, - int n, - QStringRef *contents, - QStringRef *par1 = 0, - bool debug = false) -{ -#define SKIP_CHAR(c) \ - if (debug) \ - qDebug() << "looking for " << c << " at " << QString(src.data() + i, n - i); \ - if (i >= n || src[i] != c) { \ - if (debug) \ - qDebug() << " char '" << c << "' not found"; \ - return false; \ - } \ - ++i; - - -#define SKIP_SPACE \ - while (i < n && src[i] == ' ') \ - ++i; - - int i = *pos; - int j = i; - - // assume "<@" has been parsed outside - //SKIP_CHAR('<'); - //SKIP_CHAR('@'); - - if (tag != QStringRef(&src, i, tag.length())) { - if (0 && debug) - qDebug() << "tag " << tag << " not found at " << i; - return false; - } - - if (debug) - qDebug() << "haystack:" << src << "needle:" << tag << "i:" <<i; - - // skip tag - i += tag.length(); - - // parse stuff like: linkTag("(<@link node=\"([^\"]+)\">).*(</@link>)"); - if (par1) { - SKIP_SPACE; - // read parameter name - j = i; - while (i < n && src[i].isLetter()) - ++i; - if (src[i] == '=') { - if (debug) - qDebug() << "read parameter" << QString(src.data() + j, i - j); - SKIP_CHAR('='); - SKIP_CHAR('"'); - // skip parameter name - j = i; - while (i < n && src[i] != '"') - ++i; - *par1 = QStringRef(&src, j, i - j); - SKIP_CHAR('"'); - SKIP_SPACE; - } else { - if (debug) - qDebug() << "no optional parameter found"; - } - } - SKIP_SPACE; - SKIP_CHAR('>'); - - // find contents up to closing "</@tag> - j = i; - for (; true; ++i) { - if (i + 4 + tag.length() > n) - return false; - if (src[i] != '<') - continue; - if (src[i + 1] != '/') - continue; - if (src[i + 2] != '@') - continue; - if (tag != QStringRef(&src, i + 3, tag.length())) - continue; - if (src[i + 3 + tag.length()] != '>') - continue; - break; - } - - *contents = QStringRef(&src, j, i - j); - - i += tag.length() + 4; - - *pos = i; - if (debug) - qDebug() << " tag " << tag << " found: pos now: " << i; - return true; -#undef SKIP_CHAR -} - static void addLink(const QString &linkTarget, const QStringRef &nestedStuff, QString *res) @@ -1494,8 +1396,10 @@ void HtmlGenerator::generateFakeNode(const FakeNode *fake, CodeMarker *marker) QString allQmlMembersLink = generateAllQmlMembersFile(qml_cn, marker); if (!allQmlMembersLink.isEmpty()) { + out() << "<ul>\n"; out() << "<li><a href=\"" << allQmlMembersLink << "\">" << "List of all members, including inherited members</a></li>\n"; + out() << "</ul>\n"; } s = sections.begin(); @@ -2847,7 +2751,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, static const QString headerTag("headerfile"); static const QString funcTag("func"); static const QString linkTag("link"); - + // replace all <@link> tags: "(<@link node=\"([^\"]+)\">).*(</@link>)" bool done = false; for (int i = 0, srcSize = src.size(); i < srcSize;) { @@ -2882,6 +2786,7 @@ QString HtmlGenerator::highlightedCode(const QString& markedCode, if (src.at(i) == charLangle && src.at(i + 1) == charAt) { i += 2; if (parseArg(src, funcTag, &i, srcSize, &arg, &par1)) { + const Node* n = marker->resolveTarget(par1.toString(), myTree, relative); diff --git a/tools/qdoc3/pagegenerator.cpp b/tools/qdoc3/pagegenerator.cpp index d5564f7..d331d41 100644 --- a/tools/qdoc3/pagegenerator.cpp +++ b/tools/qdoc3/pagegenerator.cpp @@ -70,12 +70,6 @@ PageGenerator::~PageGenerator() endSubPage(); } -static QRegExp linkTag("(<@link node=\"([^\"]+)\">).*(</@link>)"); -static QRegExp funcTag("(<@func target=\"([^\"]*)\">)(.*)(</@func>)"); -static QRegExp typeTag("(<@(type|headerfile|func)(?: +[^>]*)?>)(.*)(</@\\2>)"); -static QRegExp spanTag("</@(?:comment|preprocessor|string|char)>"); -static QRegExp unknownTag("</?@[^>]*>"); - bool PageGenerator::parseArg(const QString& src, const QString& tag, int* pos, diff --git a/tools/qml/loggerwidget.cpp b/tools/qml/loggerwidget.cpp index 3f2337a..9a07402 100644 --- a/tools/qml/loggerwidget.cpp +++ b/tools/qml/loggerwidget.cpp @@ -139,10 +139,10 @@ QAction *LoggerWidget::showAction() void LoggerWidget::readSettings() { QSettings settings; - QString warningsPreferences = settings.value("warnings", "hide").toString(); - if (warningsPreferences == "show") { + QString warningsPreferences = settings.value(QLatin1String("warnings"), QLatin1String("hide")).toString(); + if (warningsPreferences == QLatin1String("show")) { m_visibility = ShowWarnings; - } else if (warningsPreferences == "hide") { + } else if (warningsPreferences == QLatin1String("hide")) { m_visibility = HideWarnings; } else { m_visibility = AutoShowWarnings; @@ -154,15 +154,15 @@ void LoggerWidget::saveSettings() if (m_visibilityOrigin != SettingsOrigin) return; - QString value = "autoShow"; + QString value = QLatin1String("autoShow"); if (defaultVisibility() == ShowWarnings) { - value = "show"; + value = QLatin1String("show"); } else if (defaultVisibility() == HideWarnings) { - value = "hide"; + value = QLatin1String("hide"); } QSettings settings; - settings.setValue("warnings", value); + settings.setValue(QLatin1String("warnings"), value); } void LoggerWidget::warningsPreferenceChanged(QAction *action) diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp index b2c7f4f..3b20996 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -50,8 +50,8 @@ #include <QDebug> #include <QMessageBox> #include <QAtomicInt> +#include <QLibraryInfo> #include "qdeclarativetester.h" -#include <private/qdeclarativedebughelper_p.h> QT_USE_NAMESPACE @@ -67,7 +67,7 @@ void exitApp(int i) // Debugging output is not visible by default on Windows - // therefore show modal dialog with errors instead. if (!warnings.isEmpty()) { - QMessageBox::warning(0, QApplication::tr("Qt QML Viewer"), warnings); + QMessageBox::warning(0, QApplication::translate("QDeclarativeViewer", "Qt QML Viewer"), warnings); } #endif exit(i); @@ -123,7 +123,7 @@ void myMessageOutput(QtMsgType type, const char *msg) static QDeclarativeViewer* globalViewer = 0; // The qml file that is shown if the user didn't specify a QML file -QString initialFile = "qrc:/startup/startup.qml"; +QString initialFile = QLatin1String("qrc:/startup/startup.qml"); void usage() { @@ -156,7 +156,9 @@ void usage() qWarning(" -P <directory> ........................... prepend to the plugin search path"); #if defined(Q_WS_MAC) qWarning(" -no-opengl ............................... don't use a QGLWidget for the viewport"); + qWarning(" -opengl .................................. use a QGLWidget for the viewport (default)"); #else + qWarning(" -no-opengl ............................... don't use a QGLWidget for the viewport (default)"); qWarning(" -opengl .................................. use a QGLWidget for the viewport"); #endif qWarning(" -script <path> ........................... set the script to use"); @@ -197,7 +199,7 @@ struct ViewerOptions fps(0.0), autorecord_from(0), autorecord_to(0), - dither("none"), + dither(QLatin1String("none")), runScript(false), devkeys(false), cache(0), @@ -334,57 +336,54 @@ static void parseCommandLineOptions(const QStringList &arguments) for (int i = 1; i < arguments.count(); ++i) { bool lastArg = (i == arguments.count() - 1); QString arg = arguments.at(i); - if (arg == "-frameless") { + if (arg == QLatin1String("-frameless")) { opts.frameless = true; - } else if (arg == "-maximized") { + } else if (arg == QLatin1String("-maximized")) { opts.maximized = true; - } else if (arg == "-fullscreen") { + } else if (arg == QLatin1String("-fullscreen")) { opts.fullScreen = true; - } else if (arg == "-stayontop") { + } else if (arg == QLatin1String("-stayontop")) { opts.stayOnTop = true; - } else if (arg == "-netcache") { + } else if (arg == QLatin1String("-netcache")) { if (lastArg) usage(); opts.cache = arguments.at(++i).toInt(); - } else if (arg == "-recordrate") { + } else if (arg == QLatin1String("-recordrate")) { if (lastArg) usage(); opts.fps = arguments.at(++i).toDouble(); - } else if (arg == "-recordfile") { + } else if (arg == QLatin1String("-recordfile")) { if (lastArg) usage(); opts.recordfile = arguments.at(++i); - } else if (arg == "-record") { + } else if (arg == QLatin1String("-record")) { if (lastArg) usage(); opts.recordargs << arguments.at(++i); - } else if (arg == "-recorddither") { + } else if (arg == QLatin1String("-recorddither")) { if (lastArg) usage(); opts.dither = arguments.at(++i); - } else if (arg == "-autorecord") { + } else if (arg == QLatin1String("-autorecord")) { if (lastArg) usage(); QString range = arguments.at(++i); - int dash = range.indexOf('-'); + int dash = range.indexOf(QLatin1Char('-')); if (dash > 0) opts.autorecord_from = range.left(dash).toInt(); opts.autorecord_to = range.mid(dash+1).toInt(); - } else if (arg == "-devicekeys") { + } else if (arg == QLatin1String("-devicekeys")) { opts.devkeys = true; - } else if (arg == "-dragthreshold") { + } else if (arg == QLatin1String("-dragthreshold")) { if (lastArg) usage(); qApp->setStartDragDistance(arguments.at(++i).toInt()); } else if (arg == QLatin1String("-v") || arg == QLatin1String("-version")) { qWarning("Qt QML Viewer version %s", QT_VERSION_STR); exitApp(0); - } else if (arg == "-translation") { + } else if (arg == QLatin1String("-translation")) { if (lastArg) usage(); opts.translationFile = arguments.at(++i); -#if defined(Q_WS_MAC) - } else if (arg == "-no-opengl") { + } else if (arg == QLatin1String("-no-opengl")) { opts.useGL = false; -#else - } else if (arg == "-opengl") { + } else if (arg == QLatin1String("-opengl")) { opts.useGL = true; -#endif - } else if (arg == "-qmlbrowser") { + } else if (arg == QLatin1String("-qmlbrowser")) { opts.useNativeFileBrowser = false; - } else if (arg == "-warnings") { + } else if (arg == QLatin1String("-warnings")) { if (lastArg) usage(); QString warningsStr = arguments.at(++i); if (warningsStr == QLatin1String("show")) { @@ -394,8 +393,8 @@ static void parseCommandLineOptions(const QStringList &arguments) } else { usage(); } - } else if (arg == "-I" || arg == "-L") { - if (arg == "-L") + } else if (arg == QLatin1String("-I") || arg == QLatin1String("-L")) { + if (arg == QLatin1String("-L")) qWarning("-L option provided for compatibility only, use -I instead"); if (lastArg) { QDeclarativeEngine tmpEngine; @@ -404,32 +403,32 @@ static void parseCommandLineOptions(const QStringList &arguments) exitApp(0); } opts.imports << arguments.at(++i); - } else if (arg == "-P") { + } else if (arg == QLatin1String("-P")) { if (lastArg) usage(); opts.plugins << arguments.at(++i); - } else if (arg == "-script") { + } else if (arg == QLatin1String("-script")) { if (lastArg) usage(); opts.script = arguments.at(++i); - } else if (arg == "-scriptopts") { + } else if (arg == QLatin1String("-scriptopts")) { if (lastArg) usage(); opts.scriptopts = arguments.at(++i); - } else if (arg == "-savescript") { + } else if (arg == QLatin1String("-savescript")) { if (lastArg) usage(); opts.script = arguments.at(++i); opts.runScript = false; - } else if (arg == "-playscript") { + } else if (arg == QLatin1String("-playscript")) { if (lastArg) usage(); opts.script = arguments.at(++i); opts.runScript = true; - } else if (arg == "-sizeviewtorootobject") { + } else if (arg == QLatin1String("-sizeviewtorootobject")) { opts.sizeToView = false; - } else if (arg == "-sizerootobjecttoview") { + } else if (arg == QLatin1String("-sizerootobjecttoview")) { opts.sizeToView = true; - } else if (arg == "-experimentalgestures") { + } else if (arg == QLatin1String("-experimentalgestures")) { opts.experimentalGestures = true; - } else if (!arg.startsWith('-')) { + } else if (!arg.startsWith(QLatin1Char('-'))) { fileNames.append(arg); - } else if (true || arg == "-help") { + } else if (true || arg == QLatin1String("-help")) { usage(); } } @@ -528,29 +527,39 @@ int main(int argc, char ** argv) //### default to using raster graphics backend for now bool gsSpecified = false; for (int i = 0; i < argc; ++i) { - QString arg = argv[i]; - if (arg == "-graphicssystem") { + QString arg = QString::fromAscii(argv[i]); + if (arg == QLatin1String("-graphicssystem")) { gsSpecified = true; break; } } if (!gsSpecified) - QApplication::setGraphicsSystem("raster"); + QApplication::setGraphicsSystem(QLatin1String("raster")); #endif - QDeclarativeDebugHelper::enableDebugging(); - Application app(argc, argv); - app.setApplicationName("QtQmlViewer"); - app.setOrganizationName("Nokia"); - app.setOrganizationDomain("nokia.com"); + app.setApplicationName(QLatin1String("QtQmlViewer")); + app.setOrganizationName(QLatin1String("Nokia")); + app.setOrganizationDomain(QLatin1String("nokia.com")); QDeclarativeViewer::registerTypes(); QDeclarativeTester::registerTypes(); parseCommandLineOptions(app.arguments()); + QTranslator translator; + QTranslator qtTranslator; + QString sysLocale = QLocale::system().name(); + if (translator.load(QLatin1String("qmlviewer_") + sysLocale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { + app.installTranslator(&translator); + if (qtTranslator.load(QLatin1String("qt_") + sysLocale, QLibraryInfo::location(QLibraryInfo::TranslationsPath))) { + app.installTranslator(&qtTranslator); + } else { + app.removeTranslator(&translator); + } + } + QTranslator qmlTranslator; if (!opts.translationFile.isEmpty()) { if (qmlTranslator.load(opts.translationFile)) { diff --git a/tools/qml/proxysettings.cpp b/tools/qml/proxysettings.cpp index c4dc087..78963da 100644 --- a/tools/qml/proxysettings.cpp +++ b/tools/qml/proxysettings.cpp @@ -54,17 +54,17 @@ ProxySettings::ProxySettings (QWidget * parent) #if !defined Q_WS_MAEMO_5 // the onscreen keyboard can't cope with masks - proxyServerEdit->setInputMask ("000.000.000.000;_"); + proxyServerEdit->setInputMask(QLatin1String("000.000.000.000;_")); #endif QIntValidator *validator = new QIntValidator (0, 9999, this); - proxyPortEdit->setValidator (validator); + proxyPortEdit->setValidator(validator); QSettings settings; - proxyCheckBox->setChecked (settings.value ("http_proxy/use", 0).toBool ()); - proxyServerEdit->insert (settings.value ("http_proxy/hostname", "").toString ()); - proxyPortEdit->insert (settings.value ("http_proxy/port", "80").toString ()); - usernameEdit->insert (settings.value ("http_proxy/username", "").toString ()); - passwordEdit->insert (settings.value ("http_proxy/password", "").toString ()); + proxyCheckBox->setChecked(settings.value(QLatin1String("http_proxy/use"), 0).toBool()); + proxyServerEdit->insert(settings.value(QLatin1String("http_proxy/hostname")).toString()); + proxyPortEdit->insert(settings.value(QLatin1String("http_proxy/port"), QLatin1String("80")).toString ()); + usernameEdit->insert(settings.value(QLatin1String("http_proxy/username")).toString ()); + passwordEdit->insert(settings.value(QLatin1String("http_proxy/password")).toString ()); } ProxySettings::~ProxySettings() @@ -75,11 +75,11 @@ void ProxySettings::accept () { QSettings settings; - settings.setValue ("http_proxy/use", proxyCheckBox->isChecked ()); - settings.setValue ("http_proxy/hostname", proxyServerEdit->text ()); - settings.setValue ("http_proxy/port", proxyPortEdit->text ()); - settings.setValue ("http_proxy/username", usernameEdit->text ()); - settings.setValue ("http_proxy/password", passwordEdit->text ()); + settings.setValue(QLatin1String("http_proxy/use"), proxyCheckBox->isChecked()); + settings.setValue(QLatin1String("http_proxy/hostname"), proxyServerEdit->text()); + settings.setValue(QLatin1String("http_proxy/port"), proxyPortEdit->text()); + settings.setValue(QLatin1String("http_proxy/username"), usernameEdit->text()); + settings.setValue(QLatin1String("http_proxy/password"), passwordEdit->text()); QDialog::accept (); } @@ -89,13 +89,13 @@ QNetworkProxy ProxySettings::httpProxy () QSettings settings; QNetworkProxy proxy; - bool proxyInUse = settings.value ("http_proxy/use", 0).toBool (); + bool proxyInUse = settings.value(QLatin1String("http_proxy/use"), 0).toBool(); if (proxyInUse) { proxy.setType (QNetworkProxy::HttpProxy); - proxy.setHostName (settings.value ("http_proxy/hostname", "").toString ());// "192.168.220.5" - proxy.setPort (settings.value ("http_proxy/port", 80).toInt ()); // 8080 - proxy.setUser (settings.value ("http_proxy/username", "").toString ()); - proxy.setPassword (settings.value ("http_proxy/password", "").toString ()); + proxy.setHostName (settings.value(QLatin1String("http_proxy/hostname")).toString());// "192.168.220.5" + proxy.setPort (settings.value(QLatin1String("http_proxy/port"), 80).toInt()); // 8080 + proxy.setUser (settings.value(QLatin1String("http_proxy/username")).toString()); + proxy.setPassword (settings.value(QLatin1String("http_proxy/password")).toString()); //QNetworkProxy::setApplicationProxy (proxy); } else { @@ -107,7 +107,7 @@ QNetworkProxy ProxySettings::httpProxy () bool ProxySettings::httpProxyInUse() { QSettings settings; - return settings.value ("http_proxy/use", 0).toBool (); + return settings.value(QLatin1String("http_proxy/use"), 0).toBool(); } QT_END_NAMESPACE diff --git a/tools/qml/proxysettings_maemo5.ui b/tools/qml/proxysettings_maemo5.ui index 83f0c2a..75875d8 100644 --- a/tools/qml/proxysettings_maemo5.ui +++ b/tools/qml/proxysettings_maemo5.ui @@ -6,8 +6,8 @@ <rect> <x>0</x> <y>0</y> - <width>449</width> - <height>164</height> + <width>447</width> + <height>162</height> </rect> </property> <property name="windowTitle"> @@ -88,7 +88,7 @@ <item row="1" column="1"> <widget class="QLineEdit" name="proxyPortEdit"> <property name="text"> - <string>8080</string> + <string notr="true">8080</string> </property> </widget> </item> diff --git a/tools/qml/qdeclarativetester.cpp b/tools/qml/qdeclarativetester.cpp index 11f81fc..fa8af8f 100644 --- a/tools/qml/qdeclarativetester.cpp +++ b/tools/qml/qdeclarativetester.cpp @@ -205,7 +205,7 @@ void QDeclarativeTester::save() QString filename = m_script + QLatin1String(".qml"); QFileInfo filenameInfo(filename); QDir saveDir = filenameInfo.absoluteDir(); - saveDir.mkpath("."); + saveDir.mkpath(QLatin1String(".")); QFile file(filename); file.open(QIODevice::WriteOnly); @@ -224,8 +224,8 @@ void QDeclarativeTester::save() if (!fe.hash.isEmpty()) { ts << " hash: \"" << fe.hash.toHex() << "\"\n"; } else if (!fe.image.isNull()) { - QString filename = filenameInfo.baseName() + "." + QString::number(imgCount) + ".png"; - fe.image.save(m_script + "." + QString::number(imgCount) + ".png"); + QString filename = filenameInfo.baseName() + QLatin1String(".") + QString::number(imgCount) + QLatin1String(".png"); + fe.image.save(m_script + QLatin1String(".") + QString::number(imgCount) + QLatin1String(".png")); imgCount++; ts << " image: \"" << filename << "\"\n"; } @@ -375,7 +375,7 @@ void QDeclarativeTester::updateCurrentTime(int msec) imagefailure(); } if (goodImage != img) { - QString reject(frame->image().toLocalFile() + ".reject.png"); + QString reject(frame->image().toLocalFile() + QLatin1String(".reject.png")); qWarning() << "QDeclarativeTester(" << m_script << "): Image mismatch. Reject saved to:" << reject; img.save(reject); @@ -393,7 +393,7 @@ void QDeclarativeTester::updateCurrentTime(int msec) } } } - QString diff(frame->image().toLocalFile() + ".diff.png"); + QString diff(frame->image().toLocalFile() + QLatin1String(".diff.png")); diffimg.save(diff); qWarning().nospace() << " Diff (" << diffCount << " pixels differed) saved to: " << diff; } diff --git a/tools/qml/qml.pro b/tools/qml/qml.pro index 84ebba8..3d1b84b 100644 --- a/tools/qml/qml.pro +++ b/tools/qml/qml.pro @@ -1,5 +1,5 @@ TEMPLATE = app -CONFIG += qt uic +CONFIG += qt uic declarative_debug DESTDIR = ../../bin include(qml.pri) @@ -10,6 +10,8 @@ INCLUDEPATH += ../../include/QtDeclarative INCLUDEPATH += ../../src/declarative/util INCLUDEPATH += ../../src/declarative/graphicsitems +DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII + target.path = $$[QT_INSTALL_BINS] INSTALLS += target diff --git a/tools/qml/qmlruntime.cpp b/tools/qml/qmlruntime.cpp index 36915d1..7422032 100644 --- a/tools/qml/qmlruntime.cpp +++ b/tools/qml/qmlruntime.cpp @@ -265,7 +265,7 @@ public: hz->setValidator(new QDoubleValidator(hz)); #endif for (int i=0; ffmpegprofiles[i].name; ++i) { - profile->addItem(ffmpegprofiles[i].name); + profile->addItem(QString::fromAscii(ffmpegprofiles[i].name)); } } @@ -273,9 +273,9 @@ public: { int i; for (i=0; ffmpegprofiles[i].args[0]; ++i) { - if (ffmpegprofiles[i].args == a) { + if (QString::fromAscii(ffmpegprofiles[i].args) == a) { profile->setCurrentIndex(i); - args->setText(QLatin1String(ffmpegprofiles[i].args)); + args->setText(QString::fromAscii(ffmpegprofiles[i].args)); return; } } @@ -465,14 +465,14 @@ private: } } QSettings settings; - settings.setValue("Cookies",data); + settings.setValue(QLatin1String("Cookies"), data); } void load() { QMutexLocker lock(&mutex); QSettings settings; - QByteArray data = settings.value("Cookies").toByteArray(); + QByteArray data = settings.value(QLatin1String("Cookies")).toByteArray(); setAllCookies(QNetworkCookie::parseCookies(data)); } @@ -490,7 +490,7 @@ public: if (proxyDirty) setupProxy(); QString protocolTag = query.protocolTag(); - if (httpProxyInUse && (protocolTag == "http" || protocolTag == "https")) { + if (httpProxyInUse && (protocolTag == QLatin1String("http") || protocolTag == QLatin1String("https"))) { QList<QNetworkProxy> ret; ret << httpProxy; return ret; @@ -597,7 +597,7 @@ QString QDeclarativeViewer::getVideoFileName() if (convertAvailable) types += tr("GIF Animation")+QLatin1String(" (*.gif)"); types += tr("Individual PNG frames")+QLatin1String(" (*.png)"); if (ffmpegAvailable) types += tr("All ffmpeg formats (*.*)"); - return QFileDialog::getSaveFileName(this, title, "", types.join(";; ")); + return QFileDialog::getSaveFileName(this, title, QString(), types.join(QLatin1String(";; "))); } QDeclarativeViewer::QDeclarativeViewer(QWidget *parent, Qt::WindowFlags flags) @@ -725,18 +725,18 @@ void QDeclarativeViewer::createMenu() connect(reloadAction, SIGNAL(triggered()), this, SLOT(reload())); QAction *snapshotAction = new QAction(tr("&Take Snapshot"), this); - snapshotAction->setShortcut(QKeySequence("F3")); + snapshotAction->setShortcut(QKeySequence(tr("F3"))); connect(snapshotAction, SIGNAL(triggered()), this, SLOT(takeSnapShot())); recordAction = new QAction(tr("Start Recording &Video"), this); - recordAction->setShortcut(QKeySequence("F9")); + recordAction->setShortcut(QKeySequence(tr("F9"))); connect(recordAction, SIGNAL(triggered()), this, SLOT(toggleRecordingWithSelection())); QAction *recordOptions = new QAction(tr("Video &Options..."), this); connect(recordOptions, SIGNAL(triggered()), this, SLOT(chooseRecordingOptions())); QAction *slowAction = new QAction(tr("&Slow Down Animations"), this); - slowAction->setShortcut(QKeySequence("Ctrl+.")); + slowAction->setShortcut(QKeySequence(tr("Ctrl+."))); slowAction->setCheckable(true); connect(slowAction, SIGNAL(triggered(bool)), this, SLOT(setSlowMode(bool))); @@ -755,7 +755,7 @@ void QDeclarativeViewer::createMenu() connect(fullscreenAction, SIGNAL(triggered()), this, SLOT(toggleFullScreen())); rotateAction = new QAction(tr("Rotate orientation"), this); - rotateAction->setShortcut(QKeySequence("Ctrl+T")); + rotateAction->setShortcut(QKeySequence(tr("Ctrl+T"))); connect(rotateAction, SIGNAL(triggered()), this, SLOT(rotateOrientation())); orientation = new QActionGroup(this); @@ -963,7 +963,7 @@ void QDeclarativeViewer::chooseRecordingOptions() // Profile - recdlg->setArguments(record_args.join(" ")); + recdlg->setArguments(record_args.join(QLatin1String(" "))); if (recdlg->exec()) { // File record_file = recdlg->file->text(); @@ -972,7 +972,7 @@ void QDeclarativeViewer::chooseRecordingOptions() // Rate record_rate = recdlg->videoRate(); // Profile - record_args = recdlg->arguments().split(" ",QString::SkipEmptyParts); + record_args = recdlg->arguments().split(QLatin1Char(' '),QString::SkipEmptyParts); } } @@ -983,8 +983,8 @@ void QDeclarativeViewer::toggleRecordingWithSelection() QString fileName = getVideoFileName(); if (fileName.isEmpty()) return; - if (!fileName.contains(QRegExp(".[^\\/]*$"))) - fileName += ".avi"; + if (!fileName.contains(QRegExp(QLatin1String(".[^\\/]*$")))) + fileName += QLatin1String(".avi"); setRecordFile(fileName); } } @@ -1026,7 +1026,7 @@ void QDeclarativeViewer::openFile() { QString cur = canvas->source().toLocalFile(); if (useQmlFileBrowser) { - open("qrc:/browser/Browser.qml"); + open(QLatin1String("qrc:/browser/Browser.qml")); } else { QString fileName = QFileDialog::getOpenFileName(this, tr("Open QML file"), cur, tr("QML Files (*.qml)")); if (!fileName.isEmpty()) { @@ -1072,7 +1072,7 @@ void QDeclarativeViewer::loadTranslationFile(const QString& directory) void QDeclarativeViewer::loadDummyDataFiles(const QString& directory) { - QDir dir(directory+"/dummydata", "*.qml"); + QDir dir(directory + QLatin1String("/dummydata"), QLatin1String("*.qml")); QStringList list = dir.entryList(); for (int i = 0; i < list.size(); ++i) { QString qml = list.at(i); @@ -1114,14 +1114,14 @@ bool QDeclarativeViewer::open(const QString& file_or_url) delete canvas->rootObject(); canvas->engine()->clearComponentCache(); QDeclarativeContext *ctxt = canvas->rootContext(); - ctxt->setContextProperty("qmlViewer", this); + ctxt->setContextProperty(QLatin1String("qmlViewer"), this); #ifdef Q_OS_SYMBIAN - ctxt->setContextProperty("qmlViewerFolder", "E:\\"); // Documents on your S60 phone + ctxt->setContextProperty(QLatin1String("qmlViewerFolder"), QLatin1String("E:\\")); // Documents on your S60 phone #else - ctxt->setContextProperty("qmlViewerFolder", QDir::currentPath()); + ctxt->setContextProperty(QLatin1String("qmlViewerFolder"), QDir::currentPath()); #endif - ctxt->setContextProperty("runtime", Runtime::instance()); + ctxt->setContextProperty(QLatin1String("runtime"), Runtime::instance()); QString fileName = url.toLocalFile(); if (!fileName.isEmpty()) { @@ -1224,26 +1224,26 @@ bool QDeclarativeViewer::event(QEvent *event) void QDeclarativeViewer::senseImageMagick() { QProcess proc; - proc.start("convert", QStringList() << "-h"); + proc.start(QLatin1String("convert"), QStringList() << QLatin1String("-h")); proc.waitForFinished(2000); - QString help = proc.readAllStandardOutput(); - convertAvailable = help.contains("ImageMagick"); + QString help = QString::fromAscii(proc.readAllStandardOutput()); + convertAvailable = help.contains(QLatin1String("ImageMagick")); } void QDeclarativeViewer::senseFfmpeg() { QProcess proc; - proc.start("ffmpeg", QStringList() << "-h"); + proc.start(QLatin1String("ffmpeg"), QStringList() << QLatin1String("-h")); proc.waitForFinished(2000); - QString ffmpegHelp = proc.readAllStandardOutput(); - ffmpegAvailable = ffmpegHelp.contains("-s "); - ffmpegHelp = tr("Video recording uses ffmpeg:")+"\n\n"+ffmpegHelp; + QString ffmpegHelp = QString::fromAscii(proc.readAllStandardOutput()); + ffmpegAvailable = ffmpegHelp.contains(QLatin1String("-s ")); + ffmpegHelp = tr("Video recording uses ffmpeg:") + QLatin1String("\n\n") + ffmpegHelp; QDialog *d = new QDialog(recdlg); QVBoxLayout *l = new QVBoxLayout(d); QTextBrowser *b = new QTextBrowser(d); QFont f = b->font(); - f.setFamily("courier"); + f.setFamily(QLatin1String("courier")); b->setFont(f); b->setText(ffmpegHelp); l->addWidget(b); @@ -1266,7 +1266,7 @@ void QDeclarativeViewer::setRecording(bool on) recordTimer.start(); frame_fmt = record_file.right(4).toLower(); frame = QImage(canvas->width(),canvas->height(),QImage::Format_RGB32); - if (frame_fmt != ".png" && (!convertAvailable || frame_fmt != ".gif")) { + if (frame_fmt != QLatin1String(".png") && (!convertAvailable || frame_fmt != QLatin1String(".gif"))) { // Stream video to ffmpeg QProcess *proc = new QProcess(this); @@ -1274,19 +1274,19 @@ void QDeclarativeViewer::setRecording(bool on) frame_stream = proc; QStringList args; - args << "-y"; - args << "-r" << QString::number(record_rate); - args << "-f" << "rawvideo"; - args << "-pix_fmt" << (frame_fmt == ".gif" ? "rgb24" : "rgb32"); - args << "-s" << QString("%1x%2").arg(canvas->width()).arg(canvas->height()); - args << "-i" << "-"; + args << QLatin1String("-y"); + args << QLatin1String("-r") << QString::number(record_rate); + args << QLatin1String("-f") << QLatin1String("rawvideo"); + args << QLatin1String("-pix_fmt") << (frame_fmt == QLatin1String(".gif") ? QLatin1String("rgb24") : QLatin1String("rgb32")); + args << QLatin1String("-s") << QString::fromAscii("%1x%2").arg(canvas->width()).arg(canvas->height()); + args << QLatin1String("-i") << QLatin1String("-"); if (record_outsize.isValid()) { - args << "-s" << QString("%1x%2").arg(record_outsize.width()).arg(record_outsize.height()); - args << "-aspect" << QString::number(double(canvas->width())/canvas->height()); + args << QLatin1String("-s") << QString::fromAscii("%1x%2").arg(record_outsize.width()).arg(record_outsize.height()); + args << QLatin1String("-aspect") << QString::number(double(canvas->width())/canvas->height()); } args += record_args; args << record_file; - proc->start("ffmpeg",args); + proc->start(QLatin1String("ffmpeg"), args); } else { // Store frames, save to GIF/PNG @@ -1309,14 +1309,14 @@ void QDeclarativeViewer::setRecording(bool on) QString framename; bool png_output = false; - if (record_file.right(4).toLower()==".png") { - if (record_file.contains('%')) + if (record_file.right(4).toLower() == QLatin1String(".png")) { + if (record_file.contains(QLatin1Char('%'))) framename = record_file; else - framename = record_file.left(record_file.length()-4)+"%04d"+record_file.right(4); + framename = record_file.left(record_file.length()-4) + QLatin1String("%04d") + record_file.right(4); png_output = true; } else { - framename = "tmp-frame%04d.png"; + framename = QLatin1String("tmp-frame%04d.png"); png_output = false; } foreach (QImage* img, frames) { @@ -1327,11 +1327,11 @@ void QDeclarativeViewer::setRecording(bool on) name.sprintf(framename.toLocal8Bit(),frame++); if (record_outsize.isValid()) *img = img->scaled(record_outsize,Qt::IgnoreAspectRatio,Qt::SmoothTransformation); - if (record_dither=="ordered") + if (record_dither==QLatin1String("ordered")) img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither|Qt::OrderedDither).save(name); - else if (record_dither=="threshold") + else if (record_dither==QLatin1String("threshold")) img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither|Qt::ThresholdDither).save(name); - else if (record_dither=="floyd") + else if (record_dither==QLatin1String("floyd")) img->convertToFormat(QImage::Format_Indexed8,Qt::PreferDither).save(name); else img->save(name); @@ -1341,25 +1341,26 @@ void QDeclarativeViewer::setRecording(bool on) if (!progress.wasCanceled()) { if (png_output) { - framename.replace(QRegExp("%\\d*."),"*"); + framename.replace(QRegExp(QLatin1String("%\\d*.")), QLatin1String("*")); qDebug() << "Wrote frames" << framename; inputs.clear(); // don't remove them } else { // ImageMagick and gifsicle for GIF encoding progress.setLabelText(tr("Converting frames to GIF file...")); QStringList args; - args << "-delay" << QString::number(period/10); + args << QLatin1String("-delay") << QString::number(period/10); args << inputs; args << record_file; qDebug() << "Converting..." << record_file << "(this may take a while)"; - if (0!=QProcess::execute("convert", args)) { + if (0!=QProcess::execute(QLatin1String("convert"), args)) { qWarning() << "Cannot run ImageMagick 'convert' - recorded frames not converted"; inputs.clear(); // don't remove them qDebug() << "Wrote frames tmp-frame*.png"; } else { - if (record_file.right(4).toLower() == ".gif") { + if (record_file.right(4).toLower() == QLatin1String(".gif")) { qDebug() << "Compressing..." << record_file; - if (0!=QProcess::execute("gifsicle", QStringList() << "-O2" << "-o" << record_file << record_file)) + if (0!=QProcess::execute(QLatin1String("gifsicle"), QStringList() << QLatin1String("-O2") + << QLatin1String("-o") << record_file << record_file)) qWarning() << "Cannot run 'gifsicle' - not compressed"; } qDebug() << "Wrote" << record_file; @@ -1410,7 +1411,7 @@ void QDeclarativeViewer::recordFrame() { canvas->QWidget::render(&frame); if (frame_stream) { - if (frame_fmt == ".gif") { + if (frame_fmt == QLatin1String(".gif")) { // ffmpeg can't do 32bpp with gif QImage rgb24 = frame.convertToFormat(QImage::Format_RGB888); frame_stream->write((char*)rgb24.bits(),rgb24.numBytes()); @@ -1541,8 +1542,8 @@ void QDeclarativeViewer::registerTypes() if (!registered) { // registering only for exposing the DeviceOrientation::Orientation enum - qmlRegisterUncreatableType<DeviceOrientation>("Qt",4,7,"Orientation",""); - qmlRegisterUncreatableType<DeviceOrientation>("QtQuick",1,0,"Orientation",""); + qmlRegisterUncreatableType<DeviceOrientation>("Qt", 4, 7, "Orientation", QString()); + qmlRegisterUncreatableType<DeviceOrientation>("QtQuick", 1, 0, "Orientation", QString()); registered = true; } } diff --git a/tools/qml/texteditautoresizer_maemo5.h b/tools/qml/texteditautoresizer_maemo5.h index 71dbce0..e82d006 100644 --- a/tools/qml/texteditautoresizer_maemo5.h +++ b/tools/qml/texteditautoresizer_maemo5.h @@ -41,7 +41,7 @@ #include <QtGui/qplaintextedit.h> #include <QtGui/qtextedit.h> -#include <QtGui/qscroller.h> +#include <QtGui/qabstractkineticscroller.h> #include <QtGui/qscrollarea.h> #include <QtDebug> @@ -102,11 +102,11 @@ void TextEditAutoResizer::textEditChanged() QPoint scrollto = area->widget()->mapFrom(edit, cursor.center()); QPoint margin(10 + cursor.width(), 2 * cursor.height()); -#ifdef Q_WS_MAEMO_5 - QScroller::scroller(area)->ensureVisible(scrollto, margin.x(), margin.y()); -#else - area->ensureVisible(scrollto.x(), scrollto.y(), margin.x(), margin.y()); -#endif + if (QAbstractKineticScroller *scroller = area->property("kineticScroller").value<QAbstractKineticScroller *>()) { + scroller->ensureVisible(scrollto, margin.x(), margin.y()); + } else { + area->ensureVisible(scrollto.x(), scrollto.y(), margin.x(), margin.y()); + } } } diff --git a/tools/qmlplugindump/Info.plist b/tools/qmlplugindump/Info.plist new file mode 100644 index 0000000..f35846d --- /dev/null +++ b/tools/qmlplugindump/Info.plist @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleSignature</key> + <string>@TYPEINFO@</string> + <key>CFBundleExecutable</key> + <string>@EXECUTABLE@</string> + <key>CFBundleIdentifier</key> + <string>com.nokia.qt.qmlplugindump</string> + <key>LSUIElement</key> + <string>1</string> +</dict> +</plist> diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp new file mode 100644 index 0000000..848b091 --- /dev/null +++ b/tools/qmlplugindump/main.cpp @@ -0,0 +1,597 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 <QtDeclarative/QtDeclarative> +#include <QtDeclarative/private/qdeclarativemetatype_p.h> +#include <QtDeclarative/private/qdeclarativeopenmetaobject_p.h> +#include <QtDeclarative/QDeclarativeView> + +#include <QtGui/QApplication> + +#include <QtCore/QSet> +#include <QtCore/QMetaObject> +#include <QtCore/QMetaProperty> +#include <QtCore/QDebug> +#include <QtCore/private/qobject_p.h> +#include <QtCore/private/qmetaobject_p.h> + +#include <iostream> + +#include "qmlstreamwriter.h" + +#ifdef QT_SIMULATOR +#include <QtGui/private/qsimulatorconnection_p.h> +#endif + +#ifdef Q_OS_UNIX +#include <signal.h> +#endif + +void collectReachableMetaObjects(const QMetaObject *meta, QSet<const QMetaObject *> *metas) +{ + if (! meta || metas->contains(meta)) + return; + + // dynamic meta objects break things badly, so just ignore them + const QMetaObjectPrivate *mop = reinterpret_cast<const QMetaObjectPrivate *>(meta->d.data); + if (!(mop->flags & DynamicMetaObject)) + metas->insert(meta); + + collectReachableMetaObjects(meta->superClass(), metas); +} + +QString currentProperty; + +void collectReachableMetaObjects(QObject *object, QSet<const QMetaObject *> *metas) +{ + if (! object) + return; + + const QMetaObject *meta = object->metaObject(); + qDebug() << "Processing object" << meta->className(); + collectReachableMetaObjects(meta, metas); + + for (int index = 0; index < meta->propertyCount(); ++index) { + QMetaProperty prop = meta->property(index); + if (QDeclarativeMetaType::isQObject(prop.userType())) { + qDebug() << " Processing property" << prop.name(); + currentProperty = QString("%1::%2").arg(meta->className(), prop.name()); + + // if the property was not initialized during construction, + // accessing a member of oo is going to cause a segmentation fault + QObject *oo = QDeclarativeMetaType::toQObject(prop.read(object)); + if (oo && !metas->contains(oo->metaObject())) + collectReachableMetaObjects(oo, metas); + currentProperty.clear(); + } + } +} + +void collectReachableMetaObjects(const QDeclarativeType *ty, QSet<const QMetaObject *> *metas) +{ + collectReachableMetaObjects(ty->metaObject(), metas); + if (ty->attachedPropertiesType()) + collectReachableMetaObjects(ty->attachedPropertiesType(), metas); +} + +/* We want to add the MetaObject for 'Qt' to the list, this is a + simple way to access it. +*/ +class FriendlyQObject: public QObject +{ +public: + static const QMetaObject *qtMeta() { return &staticQtMetaObject; } +}; + +/* When we dump a QMetaObject, we want to list all the types it is exported as. + To do this, we need to find the QDeclarativeTypes associated with this + QMetaObject. +*/ +static QHash<QByteArray, QSet<const QDeclarativeType *> > qmlTypesByCppName; + +static QHash<QByteArray, QByteArray> cppToId; + +/* Takes a C++ type name, such as Qt::LayoutDirection or QString and + maps it to how it should appear in the description file. + + These names need to be unique globally, so we don't change the C++ symbol's + name much. It is mostly used to for explicit translations such as + QString->string and translations for extended QML objects. +*/ +QByteArray convertToId(const QByteArray &cppName) +{ + return cppToId.value(cppName, cppName); +} + +QSet<const QMetaObject *> collectReachableMetaObjects(const QString &importCode, QDeclarativeEngine *engine) +{ + QSet<const QMetaObject *> metas; + metas.insert(FriendlyQObject::qtMeta()); + + QHash<QByteArray, QSet<QByteArray> > extensions; + foreach (const QDeclarativeType *ty, QDeclarativeMetaType::qmlTypes()) { + qmlTypesByCppName[ty->metaObject()->className()].insert(ty); + if (ty->isExtendedType()) { + extensions[ty->typeName()].insert(ty->metaObject()->className()); + } + collectReachableMetaObjects(ty, &metas); + } + + // Adjust ids of extended objects. + // The chain ends up being: + // __extended__.originalname - the base object + // __extension_0_.originalname - first extension + // .. + // __extension_n-2_.originalname - second to last extension + // originalname - last extension + // ### does this actually work for multiple extensions? it seems like the prototypes might be wrong + foreach (const QByteArray &extendedCpp, extensions.keys()) { + cppToId.remove(extendedCpp); + const QByteArray extendedId = convertToId(extendedCpp); + cppToId.insert(extendedCpp, "__extended__." + extendedId); + QSet<QByteArray> extensionCppNames = extensions.value(extendedCpp); + int c = 0; + foreach (const QByteArray &extensionCppName, extensionCppNames) { + if (c != extensionCppNames.size() - 1) { + QByteArray adjustedName = QString("__extension__%1.%2").arg(QString::number(c), QString(extendedId)).toAscii(); + cppToId.insert(extensionCppName, adjustedName); + } else { + cppToId.insert(extensionCppName, extendedId); + } + ++c; + } + } + + // find even more QMetaObjects by instantiating QML types and running + // over the instances + foreach (const QDeclarativeType *ty, QDeclarativeMetaType::qmlTypes()) { + if (ty->isExtendedType()) + continue; + + QByteArray tyName = ty->qmlTypeName(); + tyName = tyName.mid(tyName.lastIndexOf('/') + 1); + + QByteArray code = importCode.toUtf8(); + code += tyName; + code += " {}\n"; + + QDeclarativeComponent c(engine); + c.setData(code, QUrl("typeinstance")); + + QObject *object = c.create(); + if (object) + collectReachableMetaObjects(object, &metas); + else + qDebug() << "Could not create" << tyName << ":" << c.errorString(); + } + + return metas; +} + + +class Dumper +{ + QmlStreamWriter *qml; + QString relocatableModuleUri; + +public: + Dumper(QmlStreamWriter *qml) : qml(qml) {} + + void setRelocatableModuleUri(const QString &uri) + { + relocatableModuleUri = uri; + } + + void dump(const QMetaObject *meta) + { + qml->writeStartObject("Component"); + + QByteArray id = convertToId(meta->className()); + qml->writeScriptBinding(QLatin1String("name"), enquote(id)); + + for (int index = meta->classInfoCount() - 1 ; index >= 0 ; --index) { + QMetaClassInfo classInfo = meta->classInfo(index); + if (QLatin1String(classInfo.name()) == QLatin1String("DefaultProperty")) { + qml->writeScriptBinding(QLatin1String("defaultProperty"), enquote(QLatin1String(classInfo.value()))); + break; + } + } + + if (meta->superClass()) + qml->writeScriptBinding(QLatin1String("prototype"), enquote(convertToId(meta->superClass()->className()))); + + QSet<const QDeclarativeType *> qmlTypes = qmlTypesByCppName.value(meta->className()); + if (!qmlTypes.isEmpty()) { + QStringList exports; + + foreach (const QDeclarativeType *qmlTy, qmlTypes) { + QString qmlTyName = qmlTy->qmlTypeName(); + // some qmltype names are missing the actual names, ignore that import + if (qmlTyName.endsWith('/')) + continue; + if (qmlTyName.startsWith(relocatableModuleUri + QLatin1Char('/'))) { + qmlTyName.remove(0, relocatableModuleUri.size() + 1); + } + exports += enquote(QString("%1 %2.%3").arg( + qmlTyName, + QString::number(qmlTy->majorVersion()), + QString::number(qmlTy->minorVersion()))); + } + + // ensure exports are sorted and don't change order when the plugin is dumped again + exports.removeDuplicates(); + qSort(exports); + + qml->writeArrayBinding(QLatin1String("exports"), exports); + + if (const QMetaObject *attachedType = (*qmlTypes.begin())->attachedPropertiesType()) { + qml->writeScriptBinding(QLatin1String("attachedType"), enquote( + convertToId(attachedType->className()))); + } + } + + for (int index = meta->enumeratorOffset(); index < meta->enumeratorCount(); ++index) + dump(meta->enumerator(index)); + + for (int index = meta->propertyOffset(); index < meta->propertyCount(); ++index) + dump(meta->property(index)); + + for (int index = meta->methodOffset(); index < meta->methodCount(); ++index) + dump(meta->method(index)); + + qml->writeEndObject(); + } + + void writeEasingCurve() + { + qml->writeStartObject("Component"); + qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("QEasingCurve"))); + qml->writeScriptBinding(QLatin1String("prototype"), enquote(QLatin1String("QDeclarativeEasingValueType"))); + qml->writeEndObject(); + } + +private: + static QString enquote(const QString &string) + { + return QString("\"%1\"").arg(string); + } + + /* Removes pointer and list annotations from a type name, returning + what was removed in isList and isPointer + */ + static void removePointerAndList(QByteArray *typeName, bool *isList, bool *isPointer) + { + static QByteArray declListPrefix = "QDeclarativeListProperty<"; + + if (typeName->endsWith('*')) { + *isPointer = true; + typeName->truncate(typeName->length() - 1); + removePointerAndList(typeName, isList, isPointer); + } else if (typeName->startsWith(declListPrefix)) { + *isList = true; + typeName->truncate(typeName->length() - 1); // get rid of the suffix '>' + *typeName = typeName->mid(declListPrefix.size()); + removePointerAndList(typeName, isList, isPointer); + } + + *typeName = convertToId(*typeName); + } + + void writeTypeProperties(QByteArray typeName, bool isWritable) + { + bool isList = false, isPointer = false; + removePointerAndList(&typeName, &isList, &isPointer); + + qml->writeScriptBinding(QLatin1String("type"), enquote(typeName)); + if (isList) + qml->writeScriptBinding(QLatin1String("isList"), QLatin1String("true")); + if (!isWritable) + qml->writeScriptBinding(QLatin1String("isReadonly"), QLatin1String("true")); + if (isPointer) + qml->writeScriptBinding(QLatin1String("isPointer"), QLatin1String("true")); + } + + void dump(const QMetaProperty &prop) + { + qml->writeStartObject("Property"); + + qml->writeScriptBinding(QLatin1String("name"), enquote(QString::fromUtf8(prop.name()))); + writeTypeProperties(prop.typeName(), prop.isWritable()); + + qml->writeEndObject(); + } + + void dump(const QMetaMethod &meth) + { + if (meth.methodType() == QMetaMethod::Signal) { + if (meth.access() != QMetaMethod::Protected) + return; // nothing to do. + } else if (meth.access() != QMetaMethod::Public) { + return; // nothing to do. + } + + QByteArray name = meth.signature(); + int lparenIndex = name.indexOf('('); + if (lparenIndex == -1) { + return; // invalid signature + } + name = name.left(lparenIndex); + + if (meth.methodType() == QMetaMethod::Signal) + qml->writeStartObject(QLatin1String("Signal")); + else + qml->writeStartObject(QLatin1String("Method")); + + qml->writeScriptBinding(QLatin1String("name"), enquote(name)); + + const QString typeName = convertToId(meth.typeName()); + if (! typeName.isEmpty()) + qml->writeScriptBinding(QLatin1String("type"), enquote(typeName)); + + for (int i = 0; i < meth.parameterTypes().size(); ++i) { + QByteArray argName = meth.parameterNames().at(i); + + qml->writeStartObject(QLatin1String("Parameter")); + if (! argName.isEmpty()) + qml->writeScriptBinding(QLatin1String("name"), enquote(argName)); + writeTypeProperties(meth.parameterTypes().at(i), true); + qml->writeEndObject(); + } + + qml->writeEndObject(); + } + + void dump(const QMetaEnum &e) + { + qml->writeStartObject(QLatin1String("Enum")); + qml->writeScriptBinding(QLatin1String("name"), enquote(QString::fromUtf8(e.name()))); + + QList<QPair<QString, QString> > namesValues; + for (int index = 0; index < e.keyCount(); ++index) { + namesValues.append(qMakePair(enquote(QString::fromUtf8(e.key(index))), QString::number(e.value(index)))); + } + + qml->writeScriptObjectLiteralBinding(QLatin1String("values"), namesValues); + qml->writeEndObject(); + } +}; + + +enum ExitCode { + EXIT_INVALIDARGUMENTS = 1, + EXIT_SEGV = 2, + EXIT_IMPORTERROR = 3 +}; + +#ifdef Q_OS_UNIX +void sigSegvHandler(int) { + fprintf(stderr, "Error: SEGV\n"); + if (!currentProperty.isEmpty()) + fprintf(stderr, "While processing the property '%s', which probably has uninitialized data.\n", currentProperty.toLatin1().constData()); + exit(EXIT_SEGV); +} +#endif + +void printUsage(const QString &appName) +{ + qWarning() << qPrintable(QString( + "Usage: %1 [-notrelocatable] module.uri version [module/import/path]\n" + " %1 -path path/to/qmldir/directory [version]\n" + " %1 -builtins\n" + "Example: %1 Qt.labs.particles 4.7 /home/user/dev/qt-install/imports").arg( + appName)); +} + +int main(int argc, char *argv[]) +{ +#ifdef Q_OS_UNIX + // qmldump may crash, but we don't want any crash handlers to pop up + // therefore we intercept the segfault and just exit() ourselves + struct sigaction action; + + sigemptyset(&action.sa_mask); + action.sa_handler = &sigSegvHandler; + action.sa_flags = 0; + + sigaction(SIGSEGV, &action, 0); +#endif + +#ifdef QT_SIMULATOR + // Running this application would bring up the Qt Simulator (since it links QtGui), avoid that! + QtSimulatorPrivate::SimulatorConnection::createStubInstance(); +#endif + QApplication app(argc, argv); + const QStringList args = app.arguments(); + const QString appName = QFileInfo(app.applicationFilePath()).baseName(); + if (!(args.size() >= 3 + || (args.size() == 2 + && (args.at(1) == QLatin1String("--builtins") + || args.at(1) == QLatin1String("-builtins"))))) { + printUsage(appName); + return EXIT_INVALIDARGUMENTS; + } + + QString pluginImportUri; + QString pluginImportVersion; + QString pluginImportPath; + bool relocatable = true; + bool pathImport = false; + if (args.size() >= 3) { + QStringList positionalArgs; + foreach (const QString &arg, args) { + if (!arg.startsWith(QLatin1Char('-'))) { + positionalArgs.append(arg); + continue; + } + + if (arg == QLatin1String("--notrelocatable") + || arg == QLatin1String("-notrelocatable")) { + relocatable = false; + } else if (arg == QLatin1String("--path") + || arg == QLatin1String("-path")) { + pathImport = true; + } else { + qWarning() << "Invalid argument: " << arg; + return EXIT_INVALIDARGUMENTS; + } + } + + if (!pathImport) { + if (positionalArgs.size() != 3 && positionalArgs.size() != 4) { + qWarning() << "Incorrect number of positional arguments"; + return EXIT_INVALIDARGUMENTS; + } + pluginImportUri = positionalArgs[1]; + pluginImportVersion = positionalArgs[2]; + if (positionalArgs.size() >= 4) + pluginImportPath = positionalArgs[3]; + } else { + if (positionalArgs.size() != 2 && positionalArgs.size() != 3) { + qWarning() << "Incorrect number of positional arguments"; + return EXIT_INVALIDARGUMENTS; + } + pluginImportPath = positionalArgs[1]; + if (positionalArgs.size() == 3) + pluginImportVersion = positionalArgs[2]; + } + } + + QDeclarativeView view; + QDeclarativeEngine *engine = view.engine(); + if (!pluginImportPath.isEmpty()) + engine->addImportPath(pluginImportPath); + + // find all QMetaObjects reachable from the builtin module + QByteArray importCode("import QtQuick 1.0\n"); + QSet<const QMetaObject *> defaultReachable = collectReachableMetaObjects(importCode, engine); + + // this will hold the meta objects we want to dump information of + QSet<const QMetaObject *> metas; + + if (pluginImportUri.isEmpty() && !pathImport) { + metas = defaultReachable; + } else { + // find all QMetaObjects reachable when the specified module is imported + if (!pathImport) { + importCode += QString("import %0 %1\n").arg(pluginImportUri, pluginImportVersion).toAscii(); + } else { + // pluginImportVersion can be empty + importCode += QString("import \"%1\" %2\n").arg(pluginImportPath, pluginImportVersion).toAscii(); + } + + // create a component with these imports to make sure the imports are valid + // and to populate the declarative meta type system + { + QByteArray code = importCode; + code += "QtObject {}"; + QDeclarativeComponent c(engine); + + c.setData(code, QUrl("typelist")); + c.create(); + if (!c.errors().isEmpty()) { + foreach (const QDeclarativeError &error, c.errors()) + qWarning() << error.toString(); + return EXIT_IMPORTERROR; + } + } + + QSet<const QMetaObject *> candidates = collectReachableMetaObjects(importCode, engine); + candidates.subtract(defaultReachable); + + // Also eliminate meta objects with the same classname. + // This is required because extended objects seem not to share + // a single meta object instance. + QSet<QByteArray> defaultReachableNames; + foreach (const QMetaObject *mo, defaultReachable) + defaultReachableNames.insert(QByteArray(mo->className())); + foreach (const QMetaObject *mo, candidates) { + if (!defaultReachableNames.contains(mo->className())) + metas.insert(mo); + } + } + + // setup static rewrites of type names + cppToId.insert("QString", "string"); + cppToId.insert("QDeclarativeEasingValueType::Type", "Type"); + + // start dumping data + QByteArray bytes; + QmlStreamWriter qml(&bytes); + + qml.writeStartDocument(); + qml.writeLibraryImport(QLatin1String("QtQuick.tooling"), 1, 0); + qml.write("\n" + "// This file describes the plugin-supplied types contained in the library.\n" + "// It is used for QML tooling purposes only.\n" + "\n"); + qml.writeStartObject("Module"); + + // put the metaobjects into a map so they are always dumped in the same order + QMap<QString, const QMetaObject *> nameToMeta; + foreach (const QMetaObject *meta, metas) + nameToMeta.insert(convertToId(meta->className()), meta); + + Dumper dumper(&qml); + if (relocatable) + dumper.setRelocatableModuleUri(pluginImportUri); + foreach (const QMetaObject *meta, nameToMeta) { + dumper.dump(meta); + } + + // define QEasingCurve as an extension of QDeclarativeEasingValueType, this way + // properties using the QEasingCurve type get useful type information. + if (pluginImportUri.isEmpty()) + dumper.writeEasingCurve(); + + qml.writeEndObject(); + qml.writeEndDocument(); + + std::cout << bytes.constData(); + + // workaround to avoid crashes on exit + QTimer timer; + timer.setSingleShot(true); + timer.setInterval(0); + QObject::connect(&timer, SIGNAL(timeout()), &app, SLOT(quit())); + timer.start(); + + return app.exec(); +} diff --git a/tools/qmlplugindump/qmlplugindump.pro b/tools/qmlplugindump/qmlplugindump.pro new file mode 100644 index 0000000..53827e2 --- /dev/null +++ b/tools/qmlplugindump/qmlplugindump.pro @@ -0,0 +1,20 @@ +TEMPLATE = app +CONFIG += qt uic console +DESTDIR = ../../bin + +QT += declarative + +TARGET = qmlplugindump + +SOURCES += \ + main.cpp \ + qmlstreamwriter.cpp + +HEADERS += \ + qmlstreamwriter.h + +OTHER_FILES += Info.plist +macx: QMAKE_INFO_PLIST = Info.plist + +target.path = $$[QT_INSTALL_BINS] +INSTALLS += target diff --git a/tools/qmlplugindump/qmlstreamwriter.cpp b/tools/qmlplugindump/qmlstreamwriter.cpp new file mode 100644 index 0000000..d083f7b --- /dev/null +++ b/tools/qmlplugindump/qmlstreamwriter.cpp @@ -0,0 +1,183 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 "qmlstreamwriter.h" + +#include <QtCore/QBuffer> +#include <QtCore/QStringList> + +QmlStreamWriter::QmlStreamWriter(QByteArray *array) + : m_indentDepth(0) + , m_pendingLineLength(0) + , m_maybeOneline(false) + , m_stream(new QBuffer(array)) +{ + m_stream->open(QIODevice::WriteOnly); +} + +void QmlStreamWriter::writeStartDocument() +{ +} + +void QmlStreamWriter::writeEndDocument() +{ +} + +void QmlStreamWriter::writeLibraryImport(const QString &uri, int majorVersion, int minorVersion, const QString &as) +{ + m_stream->write(QString("import %1 %2.%3").arg(uri, QString::number(majorVersion), QString::number(minorVersion)).toUtf8()); + if (!as.isEmpty()) + m_stream->write(QString(" as %1").arg(as).toUtf8()); + m_stream->write("\n"); +} + +void QmlStreamWriter::writeStartObject(const QString &component) +{ + flushPotentialLinesWithNewlines(); + writeIndent(); + m_stream->write(QString("%1 {").arg(component).toUtf8()); + ++m_indentDepth; + m_maybeOneline = true; +} + +void QmlStreamWriter::writeEndObject() +{ + if (m_maybeOneline && !m_pendingLines.isEmpty()) { + --m_indentDepth; + for (int i = 0; i < m_pendingLines.size(); ++i) { + m_stream->write(" "); + m_stream->write(m_pendingLines.at(i).trimmed()); + if (i != m_pendingLines.size() - 1) + m_stream->write(";"); + } + m_stream->write(" }\n"); + m_pendingLines.clear(); + m_pendingLineLength = 0; + m_maybeOneline = false; + } else { + if (m_maybeOneline) + flushPotentialLinesWithNewlines(); + --m_indentDepth; + writeIndent(); + m_stream->write("}\n"); + } +} + +void QmlStreamWriter::writeScriptBinding(const QString &name, const QString &rhs) +{ + writePotentialLine(QString("%1: %2").arg(name, rhs).toUtf8()); +} + +void QmlStreamWriter::writeArrayBinding(const QString &name, const QStringList &elements) +{ + flushPotentialLinesWithNewlines(); + writeIndent(); + m_stream->write(QString("%1: [\n").arg(name).toUtf8()); + ++m_indentDepth; + for (int i = 0; i < elements.size(); ++i) { + writeIndent(); + m_stream->write(elements.at(i).toUtf8()); + if (i != elements.size() - 1) { + m_stream->write(",\n"); + } else { + m_stream->write("\n"); + } + } + --m_indentDepth; + writeIndent(); + m_stream->write("]\n"); +} + +void QmlStreamWriter::write(const QString &data) +{ + flushPotentialLinesWithNewlines(); + m_stream->write(data.toUtf8()); +} + +void QmlStreamWriter::writeScriptObjectLiteralBinding(const QString &name, const QList<QPair<QString, QString> > &keyValue) +{ + flushPotentialLinesWithNewlines(); + writeIndent(); + m_stream->write(QString("%1: {\n").arg(name).toUtf8()); + ++m_indentDepth; + for (int i = 0; i < keyValue.size(); ++i) { + const QString key = keyValue.at(i).first; + const QString value = keyValue.at(i).second; + writeIndent(); + m_stream->write(QString("%1: %2").arg(key, value).toUtf8()); + if (i != keyValue.size() - 1) { + m_stream->write(",\n"); + } else { + m_stream->write("\n"); + } + } + --m_indentDepth; + writeIndent(); + m_stream->write("}\n"); +} + +void QmlStreamWriter::writeIndent() +{ + m_stream->write(QByteArray(m_indentDepth * 4, ' ')); +} + +void QmlStreamWriter::writePotentialLine(const QByteArray &line) +{ + m_pendingLines.append(line); + m_pendingLineLength += line.size(); + if (m_pendingLineLength >= 80) { + flushPotentialLinesWithNewlines(); + } +} + +void QmlStreamWriter::flushPotentialLinesWithNewlines() +{ + if (m_maybeOneline) + m_stream->write("\n"); + foreach (const QByteArray &line, m_pendingLines) { + writeIndent(); + m_stream->write(line); + m_stream->write("\n"); + } + m_pendingLines.clear(); + m_pendingLineLength = 0; + m_maybeOneline = false; +} diff --git a/tools/qmlplugindump/qmlstreamwriter.h b/tools/qmlplugindump/qmlstreamwriter.h new file mode 100644 index 0000000..cd73aad --- /dev/null +++ b/tools/qmlplugindump/qmlstreamwriter.h @@ -0,0 +1,79 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the tools applications 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 QMLSTREAMWRITER_H +#define QMLSTREAMWRITER_H + +#include <QtCore/QIODevice> +#include <QtCore/QList> +#include <QtCore/QString> +#include <QtCore/QScopedPointer> +#include <QtCore/QPair> + +class QmlStreamWriter +{ +public: + QmlStreamWriter(QByteArray *array); + + void writeStartDocument(); + void writeEndDocument(); + void writeLibraryImport(const QString &uri, int majorVersion, int minorVersion, const QString &as = QString()); + //void writeFilesystemImport(const QString &file, const QString &as = QString()); + void writeStartObject(const QString &component); + void writeEndObject(); + void writeScriptBinding(const QString &name, const QString &rhs); + void writeScriptObjectLiteralBinding(const QString &name, const QList<QPair<QString, QString> > &keyValue); + void writeArrayBinding(const QString &name, const QStringList &elements); + void write(const QString &data); + +private: + void writeIndent(); + void writePotentialLine(const QByteArray &line); + void flushPotentialLinesWithNewlines(); + + int m_indentDepth; + QList<QByteArray> m_pendingLines; + int m_pendingLineLength; + bool m_maybeOneline; + QScopedPointer<QIODevice> m_stream; +}; + +#endif // QMLSTREAMWRITER_H diff --git a/tools/tools.pro b/tools/tools.pro index f090b86..7eecebd 100644 --- a/tools/tools.pro +++ b/tools/tools.pro @@ -23,7 +23,10 @@ TEMPLATE = subdirs unix:!symbian:!mac:!embedded:!qpa:SUBDIRS += qtconfig win32:!wince*:SUBDIRS += activeqt } - contains(QT_CONFIG, declarative):SUBDIRS += qml + contains(QT_CONFIG, declarative) { + SUBDIRS += qml + !symbian: SUBDIRS += qmlplugindump + } } !wince*:!symbian:SUBDIRS += linguist diff --git a/translations/designer_uk.ts b/translations/designer_uk.ts index dccfb5f..7d1065c 100644 --- a/translations/designer_uk.ts +++ b/translations/designer_uk.ts @@ -4860,21 +4860,21 @@ Please select another name.</source> <name>qdesigner_internal::PreviewDeviceSkin</name> <message> <source>&Portrait</source> - <translation>Книжка</translation> + <translation>&Книжка</translation> </message> <message> <source>Landscape (&CCW)</source> <extracomment>Rotate form preview counter-clockwise</extracomment> - <translation>Альбом (проти ГС)</translation> + <translation>Альбом (проти &ГС)</translation> </message> <message> <source>&Landscape (CW)</source> <extracomment>Rotate form preview clockwise</extracomment> - <translation>Альбом (за ГС)</translation> + <translation>А&льбом (за ГС)</translation> </message> <message> <source>&Close</source> - <translation>Закрити</translation> + <translation>З&акрити</translation> </message> </context> <context> @@ -5833,7 +5833,7 @@ This indicates an inconsistency in the ui-file.</source> <name>qdesigner_internal::ZoomablePreviewDeviceSkin</name> <message> <source>&Zoom</source> - <translation>Масштаб</translation> + <translation>Мас&штаб</translation> </message> </context> </TS> diff --git a/translations/qt_uk.ts b/translations/qt_uk.ts index 52e70a2..c3cfec0 100644 --- a/translations/qt_uk.ts +++ b/translations/qt_uk.ts @@ -1721,10 +1721,6 @@ to <translation>Властивість-псевдонім виходить за межі псевдоніму</translation> </message> <message> - <source>Invalid alias reference. An alias reference must be specified as <id> or <id>.<property></source> - <translation type="obsolete">Неправильне посилання на псевдонім. Посилання на псевдонім має бути вказане, як <id> або <id>.<property></translation> - </message> - <message> <source>Invalid alias reference. Unable to find id "%1"</source> <translation>Неправильне посилання на псевдонім. Неможливо знайти id "%1"</translation> </message> diff --git a/translations/translations.pro b/translations/translations.pro index 311b032..dc99beb 100644 --- a/translations/translations.pro +++ b/translations/translations.pro @@ -55,6 +55,7 @@ addTsTargets(assistant, ../tools/assistant/tools/tools.pro) addTsTargets(qt_help, ../tools/assistant/lib/lib.pro) addTsTargets(qtconfig, ../tools/qtconfig/qtconfig.pro) addTsTargets(qvfb, ../tools/qvfb/qvfb.pro) +addTsTargets(qmlviewer, ../tools/qml/qml.pro) check-ts.commands = (cd $$PWD && perl check-ts.pl) check-ts.depends = ts-all |