diff options
332 files changed, 7800 insertions, 3512 deletions
@@ -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 @@ -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 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/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc index 02d88ae..da87db2 100644 --- a/doc/src/declarative/qtbinding.qdoc +++ b/doc/src/declarative/qtbinding.qdoc @@ -108,7 +108,7 @@ These methods are shown below. Naturally these approaches are not exclusive; you these methods throughout your application as appropriate. -\section2 Loading QML components from C++ +\section2 Loading QML Components from C++ A QML document can be loaded with QDeclarativeComponent or QDeclarativeView. QDeclarativeComponent loads a QML component as a C++ object; QDeclarativeView also does this, @@ -180,7 +180,7 @@ required \c objectName. It is better for the C++ implementation to know as littl the QML user interface implementation and the composition of the QML object tree. -\section2 Embedding C++ objects into QML components +\section2 Embedding C++ Objects into QML Components When loading a QML scene into a C++ application, it can be useful to directly embed C++ data into the QML object. QDeclarativeContext enables this by exposing data to the context of a QML @@ -231,7 +231,7 @@ in QML views. Also see the QDeclarativeContext documentation for more information. -\section2 Defining new QML elements +\section2 Defining New QML Elements While new QML elements can be \l {Defining New Components}{defined in QML}, they can also be defined by C++ classes; in fact, many of the core \l {QML Elements} are implemented through @@ -270,7 +270,7 @@ For more information on defining new QML elements, see the \l {Tutorial: Writing -\section1 Exchanging data between QML and C++ +\section1 Exchanging Data between QML and C++ QML and C++ objects can communicate with one another through signals, slots and property modifications. For a C++ object, any data that is exposed to Qt's \l{The Meta-Object System}{Meta-Object System} @@ -279,7 +279,7 @@ the QML side, all QML object data is automatically made available to the meta-ob be accessed from C++. -\section2 Calling functions +\section2 Calling Functions QML functions can be called from C++ and vice-versa. @@ -314,7 +314,7 @@ same name but different arguments, the correct function will be called according the types of arguments that are provided. -\section2 Receiving signals +\section2 Receiving Signals All QML signals are automatically available to C++, and can be connected to using QObject::connect() like any ordinary Qt C++ signal. In return, any C++ signal can be received by a QML object using @@ -373,7 +373,7 @@ class that is emitting the signal, and that the enum is registered using Q_ENUMS See \l {Using enumerations of a custom type} below for details. -\section2 Modifying properties +\section2 Modifying Properties Any properties declared in a QML object are automatically accessible from C++. Given a QML item like this: @@ -454,7 +454,7 @@ To allow a custom C++ type to be created or used in QML, the C++ class must be r type using qmlRegisterType(), as shown in the \l {Defining new QML elements} section above. -\section2 JavaScript arrays and objects +\section2 JavaScript Arrays and Objects There is built-in support for automatic type conversion between QVariantList and JavaScript arrays, and QVariantMap and JavaScript objects. @@ -489,7 +489,7 @@ parameter, the value can be created as a JavaScript array or object in the QML side, and is automatically converted to a QVariantList or QVariantMap when it is passed to C++. -\section2 Using enumerations of a custom type +\section2 Using Enumerations of a Custom Type To use an enumeration from a custom C++ component, the enumeration must be declared with Q_ENUMS() to register it with Qt's meta object system. For example, the following C++ type has a \c Status enum: @@ -511,22 +511,22 @@ the \l {Extending QML Functionalities using C++} reference documentation for more information. -\section2 Using enumeration values as signal parameters +\section2 Using Enumeration Values as Signal Parameters C++ signals may pass enumeration values as signal parameters to QML, providing that the enumeration and the signal are declared within the same class, or that the enumeration value is one of those declared in the \l {Qt}{Qt Namespace}. Additionally, if a C++ signal with an enum parameter should be connectable to a QML function using the -\l {Connecting signals to methods and other signals}{connect()} function, the enum type must be -registered using qRegisterMetaType(). +\l{QML Signal and Handler Event System#Connecting Signals to Methods and Signals}{connect()} +function, the enum type must be registered using qRegisterMetaType(). For QML signals, enum values may be used as signal parameters using the \c int type: \snippet doc/src/snippets/declarative/qtbinding/enums/standalone.qml 1 -\section2 Automatic type conversion from strings +\section2 Automatic Type Conversion from Strings As a convenience, some basic types can be specified in QML using format strings to make it easier to pass simple values from QML to C++. diff --git a/doc/src/declarative/righttoleft.qdoc b/doc/src/declarative/righttoleft.qdoc index 7db6136..89e5147 100644 --- a/doc/src/declarative/righttoleft.qdoc +++ b/doc/src/declarative/righttoleft.qdoc @@ -106,7 +106,7 @@ Applying mirroring in this manner does not change the actual value of the releva direction of positioners and model views that takes the mirroring into account. Similarly the \l Text, \l TextInput and \l TextEdit elements have gained the read-only property \c effectiveHorizontalAlignment for querying the effective visual alignment of text. For anchors, the read only -\l {Item::anchors}{anchors.mirrored} property reflects whether anchors have been mirrored. +\l {Item::anchors.top}{anchors.mirrored} property reflects whether anchors have been mirrored. Note that application layouts and animations that are defined using \l {Item::}{x} property values (as opposed to anchors or positioner elements) are not affected by the \l LayoutMirroring attached property. diff --git a/doc/src/declarative/whatsnew.qdoc b/doc/src/declarative/whatsnew.qdoc index 04638fb..69c8877 100644 --- a/doc/src/declarative/whatsnew.qdoc +++ b/doc/src/declarative/whatsnew.qdoc @@ -194,7 +194,7 @@ Text { } \endcode -\e {import Qt 4.7} continues to work so existing applications wont break even +\e {import Qt 4.7} continues to work so existing applications won't break even if they aren't updated, but it is recommended that all import statements be modified to the new form. */ diff --git a/doc/src/examples/fingerpaint.qdoc b/doc/src/examples/fingerpaint.qdoc index eaef4eb..7f4d77c 100644 --- a/doc/src/examples/fingerpaint.qdoc +++ b/doc/src/examples/fingerpaint.qdoc @@ -29,8 +29,12 @@ \example touch/fingerpaint \title Finger Paint Example - The Finger Paint example shows the use of touch with a custom widget + The Finger Paint example shows the use of a touchscreen with a custom widget to create a simple painting application. \image touch-fingerpaint-example.png + + This example was specifically designed to work with a touchscreen, using + QTouchEvent instead of QMouseEvent to handle user input over the custom + widget. As a result, it is not possible to draw with the mouse cursor. */ diff --git a/doc/src/examples/orientation.qdoc b/doc/src/examples/orientation.qdoc index 8b84229..cfe1757 100644 --- a/doc/src/examples/orientation.qdoc +++ b/doc/src/examples/orientation.qdoc @@ -130,7 +130,7 @@ Synchronizing both UIs like this might become unfeasible when there are many things that can change. In that case it is better to make use of the - \l{An Introduction to Model/View Programming}{Model-View-Controller pattern} + \l{Introduction to Model/View Programming}{Model-View-Controller pattern} more extensively and share the content between both portrait and landscape widgets. Then an interface for displaying and manipulating it can be tailor made for both orientations. diff --git a/doc/src/examples/webftpclient.qdoc b/doc/src/examples/webftpclient.qdoc index 156dedd..469b645 100644 --- a/doc/src/examples/webftpclient.qdoc +++ b/doc/src/examples/webftpclient.qdoc @@ -144,8 +144,8 @@ implementation provided by QFtp to perform the low level work. In the \c FtpReply class, we need to reimplement four functions in the - QIODevice API to ensure that it will work correctly. These functions, - \l{QIODevice::}{abort()}, \l{QIODevice::}{bytesAvailable()}, + API to ensure that it will work correctly. These functions, + \l{QNetworkReply::}{abort()}, \l{QIODevice::}{bytesAvailable()}, \l{QIODevice::}{isSequential()}, \l{QIODevice::}{readData()}, rely on the rest of the implementation to fill a QByteArray with data and use an integer offset to track how much has been read from the device by diff --git a/doc/src/external-resources.qdoc b/doc/src/external-resources.qdoc index 1abeae9..c116ce3 100644 --- a/doc/src/external-resources.qdoc +++ b/doc/src/external-resources.qdoc @@ -483,3 +483,8 @@ \externalpage http://www.symbiansigned.com \title Symbian Signed */ + +/*! + \externalpage http://accessibility.linuxfoundation.org/a11yspecs/ia2/docs/html/_accessible_event_i_d_8idl.html + \title AccessibleEventID.idl File Reference +*/ diff --git a/doc/src/frameworks-technologies/model-view-programming.qdoc b/doc/src/frameworks-technologies/model-view-programming.qdoc index 58b51e5..2345990 100644 --- a/doc/src/frameworks-technologies/model-view-programming.qdoc +++ b/doc/src/frameworks-technologies/model-view-programming.qdoc @@ -1934,6 +1934,13 @@ \l{QSortFilterProxyModel::lessThan()}{lessThan()} function to perform custom comparisons. + \section3 Custom data models + + QIdentityProxyModel instances do not sort or filter the structure of the source model, + but provide a base class for creating a data proxy. This could be useful on top of a + QFileSystemModel for example to provide different colours for the BackgroundRole for + different types of files. + \section1 Model subclassing reference Model subclasses need to provide implementations of many of the virtual functions diff --git a/doc/src/getting-started/gettingstartedqt.qdoc b/doc/src/getting-started/gettingstartedqt.qdoc index 18f85f1..2cd303b 100644 --- a/doc/src/getting-started/gettingstartedqt.qdoc +++ b/doc/src/getting-started/gettingstartedqt.qdoc @@ -374,7 +374,7 @@ \code 25 Notepad::Notepad() 26 { -27 saveAction = new QAction(tr("&Open"), this); +27 openAction = new QAction(tr("&Open"), this); 28 saveAction = new QAction(tr("&Save"), this); 29 exitAction = new QAction(tr("E&xit"), this); 30 diff --git a/doc/src/getting-started/installation.qdoc b/doc/src/getting-started/installation.qdoc index 26ccf88..fd04e49 100644 --- a/doc/src/getting-started/installation.qdoc +++ b/doc/src/getting-started/installation.qdoc @@ -47,7 +47,7 @@ for your platform from the following list. \tableofcontents - Qt for X11 has some requirements that are given in more detail + Qt for X11 has some requirements that are given in more detail in the \l{Qt for X11 Requirements} document. \section1 Step 1: Installing the License File (commercial editions only) @@ -79,6 +79,8 @@ for your platform from the following list. \snippet doc/src/snippets/code/doc_src_installation.qdoc 1 Type \c{./configure -help} to get a list of all available options. + The \l{Configuration Options for Qt} page gives a brief overview + of these. To create the library and compile all the demos, examples, tools, and tutorials, type: @@ -90,7 +92,7 @@ for your platform from the following list. place. To do this (as root if necessary), type: \snippet doc/src/snippets/code/doc_src_installation.qdoc 3 - + Note that on some systems the make utility is named differently, e.g. gmake. The configure script tells you which make utility to use. @@ -218,7 +220,8 @@ for your platform from the following list. \snippet doc/src/snippets/code/doc_src_installation.qdoc 8 - Type \c{configure -help} to get a list of all available options. + Type \c{configure -help} to get a list of all available options. The + \l{Configuration Options for Qt} page gives a brief overview of these. If you have multiple compilers installed, and want to build the Qt library using a specific compiler, you must specify a \c qmake specification. @@ -286,7 +289,7 @@ script to uninstall the binary package. The script is located in /Developer/Tool must be run as root. \note Do not run the iPhone simulator while installing Qt. The -\l{http://openradar.appspot.com/7214991} +\l{http://openradar.appspot.com/7214991} {iPhone simulator conflicts with the package installer}. \section1 Step 1: Install the License File (commercial editions only) @@ -433,7 +436,9 @@ in the \l{Qt for Windows CE Requirements} document. If you want to configure Qt for another platform or with other options, type \c{configure -help} to get a list of all available - options. See the \c README file for the list of supported platforms. + options. The \l{Configuration Options for Qt} page gives a brief + overview of these. See the \c README file for the list of supported + platforms. \section1 Step 4: Build Qt Library @@ -562,17 +567,17 @@ Qt for the Symbian platform has some requirements that are given in more detail in the \l{Qt for the Symbian platform Requirements} document. This document describes how to install and configure Qt for -the Symbian platform from scratch. If you are using pre-built binaries, follow -the instructions given in the \l{Installing Qt for the Symbian platform from a +the Symbian platform from scratch. If you are using pre-built binaries, follow +the instructions given in the \l{Installing Qt for the Symbian platform from a Binary Package} document. \section1 Step 1: Set Up the Development Environment - Make sure your Symbian development environment is correctly installed + Make sure your Symbian development environment is correctly installed and patched as explained in the \l{Qt for the Symbian platform Requirements} document. - After you have finished the Symbian development environment setup, it is + After you have finished the Symbian development environment setup, it is good to verify that environment is functional for example by compiling one of the pure Symbian examples for both emulator and HW. This can be done from command prompt as follows: @@ -584,7 +589,7 @@ Binary Package} document. \section1 Step 2: Install Qt - Uncompress the \l{http://qt.nokia.com/downloads}{downloaded} source + Uncompress the \l{http://qt.nokia.com/downloads}{downloaded} source package into the directory you want Qt installed, e.g. \c{C:\Qt\%VERSION%}. \note Qt must be installed on the same drive as the Symbian SDK you are @@ -606,8 +611,8 @@ Binary Package} document. emulator. This is done by locating the Carbide.c++ submenu on the Start menu, and choosing "Configure environment for WINSCW command line". - If you are planning to use \c abld (the default build system that comes with - the S60 SDK) to build Qt, you will also need to set the following + If you are planning to use \c abld (the default build system that comes with + the S60 SDK) to build Qt, you will also need to set the following environment variable: \snippet doc/src/snippets/code/doc_src_installation.qdoc 33 @@ -620,13 +625,17 @@ Binary Package} document. \snippet doc/src/snippets/code/doc_src_installation.qdoc 23 (to build the tools using MinGW, and the libraries using abld) - + \bold or \snippet doc/src/snippets/code/doc_src_installation.qdoc 31 (to build the tools using MinGW, and the libraries using SBSv2) - SBSv2 (also known as \l{http://developer.symbian.org/wiki/index.php/Introduction_to_RAPTOR} {Raptor}) + Type \c{./configure -help} to get a list of all available options. + The \l{Configuration Options for Qt} page gives a brief overview + of these. + + SBSv2 (also known as \l{http://developer.symbian.org/wiki/index.php/Introduction_to_RAPTOR} {Raptor}) is a next-generation Symbian build system. SBSv2 is not officially supported by any of the S60 SDKs currently available from Forum Nokia. @@ -701,7 +710,7 @@ applications using Qt for Symbian can start right away. Qt for the Symbian platform has some requirements on the development platform. The Symbian SDK for Linux as well as a cross compiler for the ARM -processor used on Symbian devices should be present on the development +processor used on Symbian devices should be present on the development machine. See \l{http://qt.gitorious.org/qt/pages/QtCreatorSymbianLinux} for more details. @@ -718,7 +727,7 @@ directory you want Qt installed, e.g. \c{/home/user/qt/%VERSION%}. In order to build and use Qt, the \c PATH environment variable needs to be extended to fine Qt tools and also to find the Symbian platform tools: -First you need to set the \c EPOCROOT environment variable to point to the +First you need to set the \c EPOCROOT environment variable to point to the location of your S60 SDK: \snippet doc/src/snippets/code/doc_src_installation.qdoc 36 @@ -740,6 +749,9 @@ to build the libraries using RVCT or to build the libraries using GCCE. +Type \c{./configure -help} to get a list of all available options. +The \l{Configuration Options for Qt} page gives a brief overview +of these. \section1 Step 5: Build Qt @@ -1014,13 +1026,13 @@ We hope you will enjoy using Qt. Qt from its source code, you will also need to install the development packages for these libraries for your system. - \table 100% + \table 100% \header \o Name \o Library \o Notes \o Configuration options - \o Minimum working version + \o Minimum working version \row {id="OptionalColor"} \o XRender \o libXrender @@ -1028,13 +1040,13 @@ We hope you will enjoy using Qt. \o \tt{-xrender} or auto-detected \o 0.9.0 \row {id="OptionalColor"} - \o Xrandr + \o Xrandr \o libXrandr \o X Resize and Rotate Extension \o \tt{-xrandr} or auto-detected \o 1.0.2 \row {id="OptionalColor"} - \o Xcursor + \o Xcursor \o libXcursor \o X Cursor Extension \o \tt{-xcursor} or auto-detected @@ -1046,7 +1058,7 @@ We hope you will enjoy using Qt. \o \tt{-xfixes} or auto-detected \o 3.0.0 \row {id="OptionalColor"} - \o Xinerama + \o Xinerama \o libXinerama \o Multi-head support \o \tt{-xinerama} or auto-detected @@ -1062,7 +1074,7 @@ We hope you will enjoy using Qt. \o FreeType \o libfreetype \o Font engine - \o + \o \o 2.1.3 \row {id="DefaultColor"} @@ -1115,7 +1127,7 @@ We hope you will enjoy using Qt. \o Multithreading \o \o 2.3.5 - \endtable + \endtable \note You must compile with XRender support to get alpha transparency support for pixmaps and images. @@ -1199,7 +1211,7 @@ We hope you will enjoy using Qt. {Windows Mobile 5 Pocket PC} \o \l{http://www.microsoft.com/downloads/details.aspx?familyid=DC6C00CB-738A-4B97-8910-5CD29AB5F8D9&displaylang=en} {Windows Mobile 5 Smartphone} - \o \l{http://www.microsoft.com/downloads/details.aspx?familyid=06111A3A-A651-4745-88EF-3D48091A390B&displaylang=en } + \o \l{http://www.microsoft.com/downloads/details.aspx?familyid=06111A3A-A651-4745-88EF-3D48091A390B&displaylang=en} {Windows Mobile 6 Professional/Standard} \endlist @@ -1223,7 +1235,7 @@ We hope you will enjoy using Qt. \section3 Requirements \list - \o Development environment: + \o Development environment: \list \o Microsoft Visual Studio 2005 (Standard Edition) or higher \o ActivePerl @@ -1368,287 +1380,297 @@ We hope you will enjoy using Qt. /*! \page configure-options.html - \title Configure options for Qt + \title Configuration Options for Qt \ingroup installation - \brief Brief description of available options building Qt. - - This page gives a brief description of the different options - available when building Qt using configure. To build Qt using - default options, just call configure from the command line like - showed below. If you would like to customize your build, please - use the options listed in the following tables. - - \c {.\configure.exe} - - \section2 Cross platform options: - - \table - \header \o Option \o Description \o Note - \row \o \c {-buildkey } <key> \o Build the Qt library and plugins - using the specified \o - \row \o \c {<key>} \o When the library loads plugins, it will only - load those that have a matching <key>. \o - \row \o \c {-release } \o Compile and link Qt with debugging turned off. \o - \row \o \c {-debug } \o Compile and link Qt with debugging turned on. - \o Default value. - \row \o \c {-debug-and-release} \o Compile and link two Qt libraries, - with and without debugging turned on. \o This option denotes a default - value and needs to be evaluated. If the evaluation succeeds, the - feature is included. - \row \o \c {-opensource} \o Compile and link the Open-Source Edition - of Qt. \o - \row \o \c {-commercial } \o Compile and link the Commercial Edition - of Qt. \o - \row \o \c {-developer-build} \o Compile and link Qt with Qt developer - options including auto-tests exporting) \o - \row \o \c {-shared} \o Create and use shared Qt libraries. \o Default - value. - \row \o \c {-static} \o Create and use static Qt libraries. \o - \row \o \c {-ltcg} \o Use Link Time Code Generation. \o Apply to release - builds only. - \row \o \c {-no-ltcg} \o Do not use Link Time Code Generation. \o Default - value. - \row \o \c {-no-fast} \o Configure Qt normally by generating Makefiles for - all project files. \o Default value. - \row \o \c {-fast} \o Configure Qt quickly by generating Makefiles only for - library and subdirectory targets. \o All other Makefiles are created as - wrappers which will in turn run qmake. - \row \o \c {-no-exceptions} \o Disable exceptions on platforms that support - it. \o - \row \o \c {-exceptions} \o Enable exceptions on platforms that support it. - \o Default value. - \row \o \c {-no-accessibility} \o Do not compile Windows Active - Accessibility support. \o - \row \o \c {-accessibility} \o Compile Windows Active Accessibility - support. \o Default value. - \row \o \c {-no-stl} \o Do not compile STL support. \o - \row \o \c {-stl} \o Compile STL support. \o Default value. - \row \o \c {-no-sql-<driver>} \o Disable SQL <driver> entirely, by default - none are turned on. \o - \row \o \c {-qt-sql-<driver>} \o Enable a SQL <driver> in the Qt Library. - \o - \row \o \c {-plugin-sql-<driver>} \o Enable SQL <driver> as a plugin to be - linked to at run time. \o Available values for <driver>: mysql, psql, - oci, odbc, tds, db2, sqlite, sqlite2, ibase. Drivers marked with a - '+' during configure have been detected as available on this system. - \row \o \c {-system-sqlite} \o Use sqlite from the operating system. \o - \row \o \c {-no-qt3support} \o Disables the Qt 3 support functionality. \o - \row \o \c {-no-opengl} \o Disables OpenGL functionality \o - \row \o \c {-opengl <api>} \o Enable OpenGL support with specified API - version. \o Available values for <api>: desktop - Enable support for - Desktop OpenGL (Default), es1 - Enable support for OpenGL ES Common - Profile, es2 - Enable support for OpenGL ES 2.0. - \row \o \c {-no-openvg} \o Disables OpenVG functionality \o Default value. - \row \o \c {-openvg} \o Enables OpenVG functionality \o Requires EGL - support, typically supplied by an OpenGL or other graphics - implementation. - \row \o \c {-platform <spec> } \o The operating system and compiler you - are building on. \o The default value is %QMAKESPEC%. - \row \o \c {-xplatform <spec> } \o The operating system and compiler you - are cross compiling for. \o See the README file for a list of supported - operating systems and compilers. - \row \o \c {-qtnamespace <namespace>} \o Wraps all Qt library code in - 'namespace name {..} \o - \row \o \c {-qtlibinfix <infix>} \o Renames all Qt* libs to Qt*<infix> - \o - \row \o \c {-D <define>} \o Add an explicit define to the preprocessor. - \o - \row \o \c {-I <includepath>} \o Add an explicit include path. \o - \row \o \c {-L <librarypath>} \o Add an explicit library path. \o - \row \o \c {-l <libraryname>} \o Add an explicit library name, residing - in a librarypath. \o - \row \o \c {-graphicssystem <sys>} \o Specify which graphics system should - be used. \o Available values for <sys>: * raster - Software rasterizer, - opengl - Using OpenGL acceleration, experimental!, openvg - Using - OpenVG acceleration, experimental! - \row \o \c {-help, -h, -?} \o Display this information. \o - \endtable - - \section2 Third Party Libraries: - \table - \header \o Option \o Description \o Note - \row \o \c {-qt-zlib} \o Use the zlib bundled with Qt. \o - \row \o \c {-system-zlib} \o Use zlib from the operating system. - \o See http://www.gzip.org/zlib - \row \o \c {-no-gif} \o Do not compile GIF reading support. - \o This option denotes a default value and needs to be evaluated. - If the evaluation succeeds, the feature is included. - \row \o \c {-qt-gif} \o Compile GIF reading support. \o See also - src/gui/image/qgifhandler_p.h - \row \o \c {-no-libpng} \o Do not compile PNG support. \o - \row \o \c {-qt-libpng} \o Use the libpng bundled with Qt. - \o This option denotes a default value and needs to be evaluated. - If the evaluation succeeds, the feature is included. - \row \o \c {-system-libpng} \o Use libpng from the operating system. - \o See http://www.libpng.org/pub/png - \row \o \c {-no-libmng} \o Do not compile MNG support. \o This option - denotes a default value and needs to be evaluated. If the evaluation - succeeds, the feature is included. - \row \o \c {-qt-libmng} \o Use the libmng bundled with Qt. \o - \row \o \c {-system-libmng} \o Use libmng from the operating system. - \o See http://www.libmng.com - \row \o \c {-no-libtiff} \o Do not compile TIFF support. \o This option - denotes a default value and needs to be evaluated. If the evaluation - succeeds, the feature is included. - \row \o \c {-qt-libtiff} \o Use the libtiff bundled with Qt. \o - \row \o \c {-system-libtiff} \o Use libtiff from the operating system. - \o See http://www.libtiff.org - \row \o \c {-no-libjpeg} \o Do not compile JPEG support. \o This option - denotes a default value and needs to be evaluated. If the evaluation - succeeds, the feature is included. - \row \o \c {-qt-libjpeg} \o Use the libjpeg bundled with Qt. \o - \row \o \c {-system-libjpeg} \o Use libjpeg from the operating system. - \o See http://www.ijg.org. This option denotes a default value and - needs to be evaluated. If the evaluation succeeds, the feature is - included. - \endtable - - \section2 Qt for Windows only: - \table - \header \o Option \o Description \o Note - \row \o \c {-no-dsp} \o Do not generate VC++ .dsp files. \o - \row \o \c {-dsp} \o Generate VC++ .dsp files, only if spec "win32-msvc". - \o Default value. - \row \o \c {-no-vcproj} \o Do not generate VC++ .vcproj files. \o - \row \o \c {-vcproj} \o Generate VC++ .vcproj files, only if platform - "win32-msvc.net". \o Default value. - \row \o \c {-no-incredibuild-xge} \o Do not add IncrediBuild XGE distribution - commands to custom build steps. \o - \row \o \c {-incredibuild-xge} \o Add IncrediBuild XGE distribution commands - to custom build steps. This will distribute MOC and UIC steps, and other - custom buildsteps which are added to the INCREDIBUILD_XGE variable. - \o The IncrediBuild distribution commands are only added to Visual Studio - projects. This option denotes a default value and needs to be evaluated. - If the evaluation succeeds, the feature is included. - \row \o \c {-no-plugin-manifests} \o Do not embed manifests in plugins. \o - \row \o \c {-plugin-manifests} \o Embed manifests in plugins. - \o Default value. - \row \o \c {-no-qmake} \o Do not compile qmake. \o - \row \o \c {-qmake} \o Compile qmake. \o Default value - \row \o \c {-dont-process} \o Do not generate Makefiles/Project files. This - will override -no-fast if specified. \o - \row \o \c {-process} \o Generate Makefiles/Project files. \o Default value. - \row \o \c {-no-rtti} \o Do not compile runtime type information. \o - \row \o \c {-rtti} \o Compile runtime type information. \o Default value. - \row \o \c {-no-mmx} \o Do not compile with use of MMX instructions \o - \row \o \c {-mmx} \o Compile with use of MMX instructions \o This option - denotes a default value and needs to be evaluated. If the evaluation - succeeds, the feature is included. - \row \o \c {-no-3dnow} \o Do not compile with use of 3DNOW instructions \o - \row \o \c {-3dnow} \o Compile with use of 3DNOW instructions \o This - option denotes a default value and needs to be evaluated. If the - evaluation succeeds, the feature is included. - \row \o \c {-no-sse} \o Do not compile with use of SSE instructions \o - \row \o \c {-sse} \o Compile with use of SSE instructions \o This option - denotes a default value and needs to be evaluated. If the evaluation - succeeds, the feature is included. - \row \o \c {-no-sse2} \o Do not compile with use of SSE2 instructions \o - \row \o \c {-sse2} \o Compile with use of SSE2 instructions \o This option - denotes a default value and needs to be evaluated. If the evaluation - succeeds, the feature is included. - \row \o \c {-no-openssl} \o Do not compile in OpenSSL support \o - \row \o \c {-openssl} \o Compile in run-time OpenSSL support \o This option - denotes a default value and needs to be evaluated. If the evaluation - succeeds, the feature is included. - \row \o \c {-openssl-linked} \o Compile in linked OpenSSL support \o - \row \o \c {-no-dbus} \o Do not compile in D-Bus support \o - \row \o \c {-dbus} \o Compile in D-Bus support and load libdbus-1 dynamically. - \o This option denotes a default value and needs to be evaluated. - If the evaluation succeeds, the feature is included. - \row \o \c {-dbus-linked} \o Compile in D-Bus support and link to - libdbus-1 \o - \row \o \c {-no-phonon} \o Do not compile in the Phonon module \o - \row \o \c {-phonon} \o Compile the Phonon module. \o Phonon is built if a - decent C++ compiler is used. This option denotes a default value and needs - to be evaluated. If the evaluation succeeds, the feature is included. - \row \o \c {-no-phonon-backend} \o Do not compile the platform-specific - Phonon backend-plugin \o - \row \o \c {-phonon-backend} \o Compile in the platform-specific Phonon - backend-plugin \o Default value. - \row \o \c {-no-multimedia} \o Do not compile the multimedia module \o - \row \o \c {-multimedia} \o Compile in multimedia module \o Default value. - \row \o \c {-no-audio-backend} \o Do not compile in the platform audio - backend into QtMultimedia \o - \row \o \c {-audio-backend} \o Compile in the platform audio backend into - QtMultimedia \o This option denotes a default value and needs to be - evaluated. If the evaluation succeeds, the feature is included. - \row \o \c {-no-webkit} \o Do not compile in the WebKit module \o - \row \o \c {-webkit} \o Compile in the WebKit module \o WebKit is built - if a decent C++ compiler is used. This option denotes a default value - and needs to be evaluated. If the evaluation succeeds, the feature is - included. - \row \o \c {-webkit-debug} \o Compile in the WebKit module with debug - symbols. \o - \row \o \c {-no-script} \o Do not build the QtScript module. \o - \row \o \c {-script} \o Build the QtScript module. \o This option - denotes a default value and needs to be evaluated. If the evaluation - succeeds, the feature is included. - \row \o \c {-no-scripttools} \o Do not build the QtScriptTools module. \o - \row \o \c {-scripttools} \o Build the QtScriptTools module. \o This - option denotes a default value and needs to be evaluated. If the - evaluation succeeds, the feature is included. - \row \o \c {-no-declarative} \o Do not build the declarative module \o - \row \o \c {-declarative} \o Build the declarative module \o This option - denotes a default value and needs to be evaluated. If the evaluation - succeeds, the feature is included. - \row \o \c {-no-declarative-debug} \o Do not build the declarative debugging - support \o - \row \o \c {-declarative-debug} \o Build the declarative debugging support - \o Default value. - \row \o \c {-arch <arch>} \o Specify an architecture. \o Available values for - <arch>: * windows, windowsce, symbian, boundschecker, generic. - \row \o \c {-no-style-<style>} \o Disable <style> entirely. \o - \row \o \c {-qt-style-<style>} \o Enable <style> in the Qt Library. - \o Available styles: * windows, + windowsxp, + windowsvista, - * plastique, * cleanlooks, * motif, * cde, windowsce, windowsmobile, - s60 - \row \o \c {-no-native-gestures} \o Do not use native gestures on Windows 7. - \o - \row \o \c {-native-gestures} \o Use native gestures on Windows 7. - \o Default value. - \row \o \c {-no-mp} \o Do not use multiple processors for compiling with MSVC - \o Default value. - \row \o \c {-mp} \o Use multiple processors for compiling with MSVC (-MP) \o - \row \o \c {-loadconfig <config>} \o Run configure with the parameters from file - configure_<config>.cache. \o - \row \o \c {-saveconfig <config>} \o Run configure and save the parameters in - file configure_<config>.cache. \o - \row \o \c {-redo} \o Run configure with the same parameters as last time. \o -\endtable - -\section2 Qt for Windows CE only: - \table - \header \o Option \o Description \o Note - \row \o \c {-no-iwmmxt} \o Do not compile with use of IWMMXT instructions \o - \row \o \c {-iwmmxt} \o Do compile with use of IWMMXT instructions. \o This is - for Qt for Windows CE on Arm only. This option denotes a default value and - needs to be evaluated. If the evaluation succeeds, the feature is included. - \row \o \c {-no-crt} \o Do not add the C runtime to default deployment rules. - \o Default value. - \row \o \c {-qt-crt} \o Qt identifies C runtime during project generation \o - \row \o \c {-crt <path>} \o Specify path to C runtime used for project - generation. \o - \row \o \c {-no-cetest} \o Do not compile Windows CE remote test application \o - \row \o \c {-cetest} \o Compile Windows CE remote test application \o This - option denotes a default value and needs to be evaluated. If the evaluation - succeeds, the feature is included. - \row \o \c {-signature <file>} \o Use file for signing the target project \o - \row \o \c {-phonon-wince-ds9} \o Enable Phonon Direct Show 9 backend for - Windows CE \o Default value - \endtable - - \section2 Qt for Symbian OS only: - \table - \header \o Option \o Description \o Note - \row \o \c {-no-freetype} \o Do not compile in Freetype2 support. - \o Default value. - \row \o \c {-qt-freetype} \o Use the libfreetype bundled with Qt. \o - \row \o \c {-fpu <flags>} \o VFP type on ARM, supported options: - softvfp(default) |vfpv2 | softvfp+vfpv2 \o - \row \o \c {-no-s60} \o Do not compile in S60 support. \o - \row \o \c {-s60} \o Compile with support for the S60 UI Framework - \o Default value. - \row \o \c {-no-usedeffiles} \o Disable the usage of DEF files. \o - \row \o \c {-usedeffiles} \o Enable the usage of DEF files. \o - \endtable + \brief Brief description of available options for building Qt. + + This page gives a brief description of the different options available when + building Qt using the \c configure script or \c configure.exe binary. + To build Qt using the default options, just call configure from the command + line as shown below. + + When building on Linux, Mac OS X and Unix platforms: + + \c{./configure} + + On Windows, run the corresponding executable: + + \c{.\configure.exe} + + If you would like to customize your build, please use the options listed in + the following tables. To see the full list of options, invoke the configure + tool with the \c -help command line option. + + \section2 Cross platform options: + + \table + \header \o Option \o Description \o Note + \row \o \c {-buildkey} <key> \o Build the Qt library and plugins + using the specified \o + \row \o \c {<key>} \o When the library loads plugins, it will only + load those that have a matching <key>. \o + \row \o \c {-release} \o Compile and link Qt with debugging turned off. \o + \row \o \c {-debug} \o Compile and link Qt with debugging turned on. + \o Default value. + \row \o \c {-debug-and-release} \o Compile and link two Qt libraries, + with and without debugging turned on. \o This option denotes a default + value and needs to be evaluated. If the evaluation succeeds, the + feature is included. + \row \o \c {-opensource} \o Compile and link the Open-Source Edition + of Qt. \o + \row \o \c {-commercial} \o Compile and link the Commercial Edition + of Qt. \o + \row \o \c {-developer-build} \o Compile and link Qt with Qt developer + options including auto-tests exporting) \o + \row \o \c {-shared} \o Create and use shared Qt libraries. \o Default + value. + \row \o \c {-static} \o Create and use static Qt libraries. \o + \row \o \c {-ltcg} \o Use Link Time Code Generation. \o Apply to release + builds only. + \row \o \c {-no-ltcg} \o Do not use Link Time Code Generation. \o Default + value. + \row \o \c {-no-fast} \o Configure Qt normally by generating Makefiles for + all project files. \o Default value. + \row \o \c {-fast} \o Configure Qt quickly by generating Makefiles only for + library and subdirectory targets. \o All other Makefiles are created as + wrappers which will in turn run qmake. + \row \o \c {-no-exceptions} \o Disable exceptions on platforms that support + it. \o + \row \o \c {-exceptions} \o Enable exceptions on platforms that support it. + \o Default value. + \row \o \c {-no-accessibility} \o Do not compile Windows Active + Accessibility support. \o + \row \o \c {-accessibility} \o Compile Windows Active Accessibility + support. \o Default value. + \row \o \c {-no-stl} \o Do not compile STL support. \o + \row \o \c {-stl} \o Compile STL support. \o Default value. + \row \o \c {-no-sql-<driver>} \o Disable SQL <driver> entirely, by default + none are turned on. \o + \row \o \c {-qt-sql-<driver>} \o Enable a SQL <driver> in the Qt Library. + \o + \row \o \c {-plugin-sql-<driver>} \o Enable SQL <driver> as a plugin to be + linked to at run time. \o Available values for <driver>: mysql, psql, + oci, odbc, tds, db2, sqlite, sqlite2, ibase. Drivers marked with a + '+' during configure have been detected as available on this system. + \row \o \c {-system-sqlite} \o Use sqlite from the operating system. \o + \row \o \c {-no-qt3support} \o Disables the Qt 3 support functionality. \o + \row \o \c {-no-opengl} \o Disables OpenGL functionality \o + \row \o \c {-opengl <api>} \o Enable OpenGL support with specified API + version. \o Available values for <api>: desktop - Enable support for + Desktop OpenGL (Default), es1 - Enable support for OpenGL ES Common + Profile, es2 - Enable support for OpenGL ES 2.0. + \row \o \c {-no-openvg} \o Disables OpenVG functionality \o Default value. + \row \o \c {-openvg} \o Enables OpenVG functionality \o Requires EGL + support, typically supplied by an OpenGL or other graphics + implementation. + \row \o \c {-platform <spec>} \o The operating system and compiler you + are building on. \o The default value is %QMAKESPEC%. + \row \o \c {-xplatform <spec>} \o The operating system and compiler you + are cross compiling for. \o See the README file for a list of supported + operating systems and compilers. + \row \o \c {-qtnamespace <namespace>} \o Wraps all Qt library code in + 'namespace name {..} \o + \row \o \c {-qtlibinfix <infix>} \o Renames all Qt* libs to Qt*<infix> + \o + \row \o \c {-D <define>} \o Add an explicit define to the preprocessor. + \o + \row \o \c {-I <includepath>} \o Add an explicit include path. \o + \row \o \c {-L <librarypath>} \o Add an explicit library path. \o + \row \o \c {-l <libraryname>} \o Add an explicit library name, residing + in a librarypath. \o + \row \o \c {-graphicssystem <sys>} \o Specify which graphics system should + be used. \o Available values for <sys>: * raster - Software rasterizer, + opengl - Using OpenGL acceleration, experimental!, openvg - Using + OpenVG acceleration, experimental! + \row \o \c {-help, -h, -?} \o Display this information. \o + \endtable + + \section2 Third Party Libraries + + \table + \header \o Option \o Description \o Note + \row \o \c {-qt-zlib} \o Use the zlib bundled with Qt. \o + \row \o \c {-system-zlib} \o Use zlib from the operating system. + \o See http://www.gzip.org/zlib + \row \o \c {-no-gif} \o Do not compile GIF reading support. + \o This option denotes a default value and needs to be evaluated. + If the evaluation succeeds, the feature is included. + \row \o \c {-qt-gif} \o Compile GIF reading support. \o See also + src/gui/image/qgifhandler_p.h + \row \o \c {-no-libpng} \o Do not compile PNG support. \o + \row \o \c {-qt-libpng} \o Use the libpng bundled with Qt. + \o This option denotes a default value and needs to be evaluated. + If the evaluation succeeds, the feature is included. + \row \o \c {-system-libpng} \o Use libpng from the operating system. + \o See http://www.libpng.org/pub/png + \row \o \c {-no-libmng} \o Do not compile MNG support. \o This option + denotes a default value and needs to be evaluated. If the evaluation + succeeds, the feature is included. + \row \o \c {-qt-libmng} \o Use the libmng bundled with Qt. \o + \row \o \c {-system-libmng} \o Use libmng from the operating system. + \o See http://www.libmng.com + \row \o \c {-no-libtiff} \o Do not compile TIFF support. \o This option + denotes a default value and needs to be evaluated. If the evaluation + succeeds, the feature is included. + \row \o \c {-qt-libtiff} \o Use the libtiff bundled with Qt. \o + \row \o \c {-system-libtiff} \o Use libtiff from the operating system. + \o See http://www.libtiff.org + \row \o \c {-no-libjpeg} \o Do not compile JPEG support. \o This option + denotes a default value and needs to be evaluated. If the evaluation + succeeds, the feature is included. + \row \o \c {-qt-libjpeg} \o Use the libjpeg bundled with Qt. \o + \row \o \c {-system-libjpeg} \o Use libjpeg from the operating system. + \o See http://www.ijg.org. This option denotes a default value and + needs to be evaluated. If the evaluation succeeds, the feature is + included. + \endtable + + \section2 Qt for Windows only: + \table + \header \o Option \o Description \o Note + \row \o \c {-no-dsp} \o Do not generate VC++ .dsp files. \o + \row \o \c {-dsp} \o Generate VC++ .dsp files, only if spec "win32-msvc". + \o Default value. + \row \o \c {-no-vcproj} \o Do not generate VC++ .vcproj files. \o + \row \o \c {-vcproj} \o Generate VC++ .vcproj files, only if platform + "win32-msvc.net". \o Default value. + \row \o \c {-no-incredibuild-xge} \o Do not add IncrediBuild XGE distribution + commands to custom build steps. \o + \row \o \c {-incredibuild-xge} \o Add IncrediBuild XGE distribution commands + to custom build steps. This will distribute MOC and UIC steps, and other + custom buildsteps which are added to the INCREDIBUILD_XGE variable. + \o The IncrediBuild distribution commands are only added to Visual Studio + projects. This option denotes a default value and needs to be evaluated. + If the evaluation succeeds, the feature is included. + \row \o \c {-no-plugin-manifests} \o Do not embed manifests in plugins. \o + \row \o \c {-plugin-manifests} \o Embed manifests in plugins. + \o Default value. + \row \o \c {-no-qmake} \o Do not compile qmake. \o + \row \o \c {-qmake} \o Compile qmake. \o Default value + \row \o \c {-dont-process} \o Do not generate Makefiles/Project files. This + will override -no-fast if specified. \o + \row \o \c {-process} \o Generate Makefiles/Project files. \o Default value. + \row \o \c {-no-rtti} \o Do not compile runtime type information. \o + \row \o \c {-rtti} \o Compile runtime type information. \o Default value. + \row \o \c {-no-mmx} \o Do not compile with use of MMX instructions \o + \row \o \c {-mmx} \o Compile with use of MMX instructions \o This option + denotes a default value and needs to be evaluated. If the evaluation + succeeds, the feature is included. + \row \o \c {-no-3dnow} \o Do not compile with use of 3DNOW instructions \o + \row \o \c {-3dnow} \o Compile with use of 3DNOW instructions \o This + option denotes a default value and needs to be evaluated. If the + evaluation succeeds, the feature is included. + \row \o \c {-no-sse} \o Do not compile with use of SSE instructions \o + \row \o \c {-sse} \o Compile with use of SSE instructions \o This option + denotes a default value and needs to be evaluated. If the evaluation + succeeds, the feature is included. + \row \o \c {-no-sse2} \o Do not compile with use of SSE2 instructions \o + \row \o \c {-sse2} \o Compile with use of SSE2 instructions \o This option + denotes a default value and needs to be evaluated. If the evaluation + succeeds, the feature is included. + \row \o \c {-no-openssl} \o Do not compile in OpenSSL support \o + \row \o \c {-openssl} \o Compile in run-time OpenSSL support \o This option + denotes a default value and needs to be evaluated. If the evaluation + succeeds, the feature is included. + \row \o \c {-openssl-linked} \o Compile in linked OpenSSL support \o + \row \o \c {-no-dbus} \o Do not compile in D-Bus support \o + \row \o \c {-dbus} \o Compile in D-Bus support and load libdbus-1 dynamically. + \o This option denotes a default value and needs to be evaluated. + If the evaluation succeeds, the feature is included. + \row \o \c {-dbus-linked} \o Compile in D-Bus support and link to + libdbus-1 \o + \row \o \c {-no-phonon} \o Do not compile in the Phonon module \o + \row \o \c {-phonon} \o Compile the Phonon module. \o Phonon is built if a + decent C++ compiler is used. This option denotes a default value and needs + to be evaluated. If the evaluation succeeds, the feature is included. + \row \o \c {-no-phonon-backend} \o Do not compile the platform-specific + Phonon backend-plugin \o + \row \o \c {-phonon-backend} \o Compile in the platform-specific Phonon + backend-plugin \o Default value. + \row \o \c {-no-multimedia} \o Do not compile the multimedia module \o + \row \o \c {-multimedia} \o Compile in multimedia module \o Default value. + \row \o \c {-no-audio-backend} \o Do not compile in the platform audio + backend into QtMultimedia \o + \row \o \c {-audio-backend} \o Compile in the platform audio backend into + QtMultimedia \o This option denotes a default value and needs to be + evaluated. If the evaluation succeeds, the feature is included. + \row \o \c {-no-webkit} \o Do not compile in the WebKit module \o + \row \o \c {-webkit} \o Compile in the WebKit module \o WebKit is built + if a decent C++ compiler is used. This option denotes a default value + and needs to be evaluated. If the evaluation succeeds, the feature is + included. + \row \o \c {-webkit-debug} \o Compile in the WebKit module with debug + symbols. \o + \row \o \c {-no-script} \o Do not build the QtScript module. \o + \row \o \c {-script} \o Build the QtScript module. \o This option + denotes a default value and needs to be evaluated. If the evaluation + succeeds, the feature is included. + \row \o \c {-no-scripttools} \o Do not build the QtScriptTools module. \o + \row \o \c {-scripttools} \o Build the QtScriptTools module. \o This + option denotes a default value and needs to be evaluated. If the + evaluation succeeds, the feature is included. + \row \o \c {-no-declarative} \o Do not build the declarative module \o + \row \o \c {-declarative} \o Build the declarative module \o This option + denotes a default value and needs to be evaluated. If the evaluation + succeeds, the feature is included. + \row \o \c {-no-declarative-debug} \o Do not build the declarative debugging + support \o + \row \o \c {-declarative-debug} \o Build the declarative debugging support + \o Default value. + \row \o \c {-arch <arch>} \o Specify an architecture. \o Available values for + <arch>: * windows, windowsce, symbian, boundschecker, generic. + \row \o \c {-no-style-<style>} \o Disable <style> entirely. \o + \row \o \c {-qt-style-<style>} \o Enable <style> in the Qt Library. + \o Available styles: * windows, + windowsxp, + windowsvista, + * plastique, * cleanlooks, * motif, * cde, windowsce, windowsmobile, + s60 + \row \o \c {-no-native-gestures} \o Do not use native gestures on Windows 7. + \o + \row \o \c {-native-gestures} \o Use native gestures on Windows 7. + \o Default value. + \row \o \c {-no-mp} \o Do not use multiple processors for compiling with MSVC + \o Default value. + \row \o \c {-mp} \o Use multiple processors for compiling with MSVC (-MP) \o + \row \o \c {-loadconfig <config>} \o Run configure with the parameters from file + configure_<config>.cache. \o + \row \o \c {-saveconfig <config>} \o Run configure and save the parameters in + file configure_<config>.cache. \o + \row \o \c {-redo} \o Run configure with the same parameters as last time. \o + \endtable + + \section2 Qt for Windows CE only: + \table + \header \o Option \o Description \o Note + \row \o \c {-no-iwmmxt} \o Do not compile with use of IWMMXT instructions \o + \row \o \c {-iwmmxt} \o Do compile with use of IWMMXT instructions. \o This is + for Qt for Windows CE on Arm only. This option denotes a default value and + needs to be evaluated. If the evaluation succeeds, the feature is included. + \row \o \c {-no-crt} \o Do not add the C runtime to default deployment rules. + \o Default value. + \row \o \c {-qt-crt} \o Qt identifies C runtime during project generation \o + \row \o \c {-crt <path>} \o Specify path to C runtime used for project + generation. \o + \row \o \c {-no-cetest} \o Do not compile Windows CE remote test application \o + \row \o \c {-cetest} \o Compile Windows CE remote test application \o This + option denotes a default value and needs to be evaluated. If the evaluation + succeeds, the feature is included. + \row \o \c {-signature <file>} \o Use file for signing the target project \o + \row \o \c {-phonon-wince-ds9} \o Enable Phonon Direct Show 9 backend for + Windows CE \o Default value + \endtable + + \section2 Qt for Symbian OS only: + \table + \header \o Option \o Description \o Note + \row \o \c {-no-freetype} \o Do not compile in Freetype2 support. + \o Default value. + \row \o \c {-qt-freetype} \o Use the libfreetype bundled with Qt. \o + \row \o \c {-fpu <flags>} \o VFP type on ARM, supported options: + softvfp(default) |vfpv2 | softvfp+vfpv2 \o + \row \o \c {-no-s60} \o Do not compile in S60 support. \o + \row \o \c {-s60} \o Compile with support for the S60 UI Framework + \o Default value. + \row \o \c {-no-usedeffiles} \o Disable the usage of DEF files. \o + \row \o \c {-usedeffiles} \o Enable the usage of DEF files. \o + \endtable */ diff --git a/doc/src/platforms/emb-install.qdoc b/doc/src/platforms/emb-install.qdoc index 88bbae0..32a0848 100644 --- a/doc/src/platforms/emb-install.qdoc +++ b/doc/src/platforms/emb-install.qdoc @@ -74,6 +74,9 @@ \snippet doc/src/snippets/code/doc_src_emb-install.qdoc embedded help + The \l{Configuration Options for Qt} page gives a brief overview + of these. + Note that by default, \l{Qt for Embedded Linux} is configured for installation in the \c{/usr/local/Trolltech/QtEmbedded-%VERSION%} directory, but this can be changed by using the \c{-prefix} diff --git a/doc/src/platforms/platform-notes.qdoc b/doc/src/platforms/platform-notes.qdoc index 113ad86..24b297f 100644 --- a/doc/src/platforms/platform-notes.qdoc +++ b/doc/src/platforms/platform-notes.qdoc @@ -630,7 +630,7 @@ we need to do special bookkeeping in Qt to handle this correctly, which unfortunately make mixing in native panels hard. The best way at the moment to do this, is to follow the pattern below, where we post the call to the - function with native code rather than calling it directly. Then we now that + function with native code rather than calling it directly. Then we know that Qt has cleanly updated any pending event loop recursions before the native panel is shown: @@ -708,28 +708,8 @@ \section1 Supported Devices - Qt is designed to work on any device which runs one of the following - versions of Symbian: - - \table - \header \o Symbian Version - \row \o S60 3.1 - \row \o S60 3.2 - \row \o S60 5.0 (Symbian ^1) - \endtable - - Qt has received \l{Tier 1 Platforms}{Tier 1} testing on the following phone models: - - \table - \header \o Phone - \row \o Nokia 5800 - \row \o Nokia E71 - \row \o Nokia E72 - \row \o Nokia N78 - \row \o Nokia N95 - \row \o Nokia N97 - \row \o Samsung i8910 - \endtable + See the list of supported devices at + http://wiki.forum.nokia.com/index.php/Nokia_Smart_Installer_for_Symbian#Supported_Devices \section1 Supported Functionality @@ -742,8 +722,6 @@ \o Planned for future release. \row \o QtDBus \o No current plans to support this feature. - \row \o QtOpenGL ES - \o Planned for future release. \row \o Printing support \o No current plans to support this feature. \row \o Qt3Support @@ -837,6 +815,12 @@ plugin. If the Helix plugin fails to load, the MMF plugin, if present on the device, will be loaded instead. + \section1 QtOpenGL Support + + Qt 4.7 introduces the QtOpenGL module to Symbian^3. QtOpenGL is supported on + devices which support OpenGL ES 2.0. Symbian platforms prior to Symbian^3 + are not supported. + \section1 UI Performance in devices prior to Symbian^3 Qt uses the QPainter class to perform low-level painting on widgets and diff --git a/doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp b/doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp index cf40f9a..5919c01 100644 --- a/doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp +++ b/doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp @@ -86,38 +86,3 @@ beginMoveRows(parent, 2, 2, parent, 0); //! [9] beginMoveRows(parent, 2, 2, parent, 4); //! [9] - - -//! [10] -class CustomDataProxy : public QSortFilterProxyModel -{ - Q_OBJECT -public: - CustomDataProxy(QObject *parent) - : QSortFilterProxyModel(parent) - { - } - - ... - - QVariant data(const QModelIndex &index, int role) - { - if (role != Qt::BackgroundRole) - return QSortFilterProxyModel::data(index, role); - - if (m_customData.contains(index.row())) - return m_customData.value(index.row()); - return QSortFilterProxyModel::data(index, role); - } - -private slots: - void resetInternalData() - { - m_customData.clear(); - } - -private: - QHash<int, QVariant> m_customData; -}; -//! [10] - diff --git a/doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp b/doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp new file mode 100644 index 0000000..6bf6c89 --- /dev/null +++ b/doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp @@ -0,0 +1,64 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> +** 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: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$ +** +****************************************************************************/ + +//! [0] +class DateFormatProxyModel : public QIdentityProxyModel +{ + // ... + + void setDateFormatString(const QString &formatString) + { + m_formatString = formatString; + } + + QVariant data(const QModelIndex &index, int role) + { + if (role != Qt::DisplayRole) + return QIdentityProxyModel::data(index, role); + + const QDateTime dateTime = sourceModel()->data(SourceClass::DateRole).toDateTime(); + + return dateTime.toString(m_formatString); + } + +private: + QString m_formatString; +}; +//! [0] diff --git a/examples/declarative/touchinteraction/touchinteraction.pro b/examples/declarative/touchinteraction/touchinteraction.pro new file mode 100644 index 0000000..1beaeab --- /dev/null +++ b/examples/declarative/touchinteraction/touchinteraction.pro @@ -0,0 +1,4 @@ +TEMPLATE = subdirs +SUBDIRS = gestures \ + mousearea \ + pincharea diff --git a/examples/declarative/ui-components/main/qml/pics/niagara_falls.jpg b/examples/declarative/ui-components/main/qml/pics/niagara_falls.jpg Binary files differindex 618d808..d255543 100644 --- a/examples/declarative/ui-components/main/qml/pics/niagara_falls.jpg +++ b/examples/declarative/ui-components/main/qml/pics/niagara_falls.jpg diff --git a/examples/graphicsview/diagramscene/mainwindow.cpp b/examples/graphicsview/diagramscene/mainwindow.cpp index 87eb33e..b0aee87 100644 --- a/examples/graphicsview/diagramscene/mainwindow.cpp +++ b/examples/graphicsview/diagramscene/mainwindow.cpp @@ -85,8 +85,8 @@ void MainWindow::backgroundButtonGroupClicked(QAbstractButton *button) { QList<QAbstractButton *> buttons = backgroundButtonGroup->buttons(); foreach (QAbstractButton *myButton, buttons) { - if (myButton != button) - button->setChecked(false); + if (myButton != button) + myButton->setChecked(false); } QString text = button->text(); if (text == tr("Blue Grid")) 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/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.cpp b/src/corelib/global/qglobal.cpp index 1bd31db..a0709d0 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -2883,8 +2883,8 @@ int qrand() \relates <QtGlobal> \since 4.8 - \brief Hints the compiler that the enclosed condition, \a expr, is likely - to evaluate to \c true. + \brief Hints to the compiler that the enclosed condition, \a expr, is + likely to evaluate to \c true. Use of this macro can help the compiler to optimize the code. @@ -2900,8 +2900,8 @@ int qrand() \relates <QtGlobal> \since 4.8 - \brief Hints the compiler that the enclosed condition, \a expr, is likely - to evaluate to \c false. + \brief Hints to the compiler that the enclosed condition, \a expr, is + likely to evaluate to \c false. Use of this macro can help the compiler to optimize the code. diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 9434eb2..49f5f98 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -2755,7 +2755,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/io/qfile.cpp b/src/corelib/io/qfile.cpp index 0ade573..01fb231 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -1656,6 +1656,8 @@ bool QFile::atEnd() const } /*! + \fn bool QFile::seek(qint64 pos) + For random-access devices, this function sets the current position to \a pos, returning true on success, or false if an error occurred. For sequential devices, the default behavior is to do nothing and diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index c9ebaa4..742b05e 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 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/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/io/qurl.cpp b/src/corelib/io/qurl.cpp index efd3f45..cdc84f5 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -6088,7 +6088,7 @@ bool QUrl::isDetached() const "//servername/path/to/file.txt". Note that only certain platforms can actually open this file using QFile::open(). - \sa toLocalFile(), isLocalFile(), QDir::toNativeSeparators + \sa toLocalFile(), isLocalFile(), QDir::toNativeSeparators() */ QUrl QUrl::fromLocalFile(const QString &localFile) { diff --git a/src/corelib/kernel/qabstractitemmodel.h b/src/corelib/kernel/qabstractitemmodel.h index 6de3bf5..7bed3a2 100644 --- a/src/corelib/kernel/qabstractitemmodel.h +++ b/src/corelib/kernel/qabstractitemmodel.h @@ -162,6 +162,7 @@ class Q_CORE_EXPORT QAbstractItemModel : public QObject friend class QPersistentModelIndexData; friend class QAbstractItemViewPrivate; + friend class QIdentityProxyModel; public: explicit QAbstractItemModel(QObject *parent = 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/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp index ff87ffd..440bc32 100644 --- a/src/corelib/kernel/qtranslator.cpp +++ b/src/corelib/kernel/qtranslator.cpp @@ -637,8 +637,8 @@ static QString find_translation(const QLocale & locale, \o \c /opt/foolib/foo \endlist - For OSs where file system is case sensitive, QTranslator also tries to load - a lower-cased version of the locale name. + On operating systems where file system is case sensitive, QTranslator also + tries to load a lower-cased version of the locale name. */ bool QTranslator::load(const QLocale & locale, const QString & filename, 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/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index bab6cf8..bdade1d 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -300,7 +300,7 @@ void QThreadPrivate::createEventDispatcher(QThreadData *data) #ifndef QT_NO_THREAD -unsigned int __stdcall QThreadPrivate::start(void *arg) +unsigned int __stdcall QT_ENSURE_STACK_ALIGNED_FOR_SSE QThreadPrivate::start(void *arg) { QThread *thr = reinterpret_cast<QThread *>(arg); QThreadData *data = QThreadData::get2(thr); 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/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 5c4085a..857cc21 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -937,7 +937,7 @@ QLocale::Country QLocale::country() const name() will not contain it for compatibility reasons. Use bcp47Name() instead if you need a full locale name. - \sa QLocale(const QString &), language(), script(), country(), bcp47Name() + \sa QLocale(), language(), script(), country(), bcp47Name() */ QString QLocale::name() const @@ -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.qdoc b/src/corelib/tools/qlocale.qdoc index 605e3e0..1d5e5c5 100644 --- a/src/corelib/tools/qlocale.qdoc +++ b/src/corelib/tools/qlocale.qdoc @@ -769,6 +769,8 @@ \value Weekdays a QList<Qt::DayOfWeek> specifying the regular weekdays \value LocaleChanged this type is queried whenever the system locale is changed. \value ListToSeparatedString a string that represents a join of a given QStringList with a locale-defined separator. + \value NativeLanguageName a string that represents the name of the native language. + \value NativeCountryName a string that represents the name of the native country. */ /*! diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp index 60a5d70..2afa731 100644 --- a/src/corelib/tools/qscopedpointer.cpp +++ b/src/corelib/tools/qscopedpointer.cpp @@ -252,10 +252,9 @@ QT_BEGIN_NAMESPACE */ /*! - \fn QScopedArrayPointer::QScopedArrayPointer(T *p = 0) + \fn QScopedArrayPointer::QScopedArrayPointer() - Constructs this QScopedArrayPointer instance and sets its pointer - to \a p. + Constructs a QScopedArrayPointer instance. */ /*! diff --git a/src/corelib/tools/qscopedvaluerollback.cpp b/src/corelib/tools/qscopedvaluerollback.cpp index c9c83b8..00dcedf 100644 --- a/src/corelib/tools/qscopedvaluerollback.cpp +++ b/src/corelib/tools/qscopedvaluerollback.cpp @@ -65,7 +65,7 @@ QT_BEGIN_NAMESPACE /*! \fn QScopedValueRollback::QScopedValueRollback(T &var) - Stores the previous value of var internally, for revert on destruction. + Stores the previous value of \a var internally, for revert on destruction. */ /*! diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 5493ba9..f422b32 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -841,6 +841,25 @@ int QString::grow(int size) \sa QString::const_iterator */ +/*! + \typedef QString::const_reference + + The QString::const_reference typedef provides an STL-style + const reference for QString. +*/ +/*! + \typedef QString::reference + + The QString::const_reference typedef provides an STL-style + reference for QString. +*/ +/*! + \typedef QString::value_type + + The QString::const_reference typedef provides an STL-style + value type for QString. +*/ + /*! \fn QString::iterator QString::begin() Returns an \l{STL-style iterator} pointing to the first character in @@ -9115,7 +9134,7 @@ QByteArray QStringRef::toUtf8() const UCS-4 is a Unicode codec and is lossless. All characters from this string can be encoded in UCS-4. - \sa fromUtf8(), toAscii(), toLatin1(), toLocal8Bit(), QTextCodec, fromUcs4(), toWCharArray() + \sa toAscii(), toLatin1(), toLocal8Bit(), QTextCodec */ QVector<uint> QStringRef::toUcs4() const { diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 66cfa74..6418a8c 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 diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp index a5dff88..f249c52 100644 --- a/src/corelib/tools/qstringbuilder.cpp +++ b/src/corelib/tools/qstringbuilder.cpp @@ -142,7 +142,8 @@ QT_BEGIN_NAMESPACE characters. */ -/*! \fn QStringBuilder::operator QString() const +/*! + \fn operator QStringBuilder::QString() const Converts the \c QLatin1Literal into a \c QString object. */ diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp index 21269a8..eac61f5 100644 --- a/src/corelib/tools/qstringlist.cpp +++ b/src/corelib/tools/qstringlist.cpp @@ -683,7 +683,7 @@ int QtPrivate::QStringList_removeDuplicates(QStringList *that) /*! \fn QStringList::QStringList(std::initializer_list<QString> args) \since 4.8 - Construct a list from a std::initilizer_list. + Construct a list from a std::initializer_list given by \a args. This constructor is only enabled if the compiler supports C++0x */ diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc index 3c80c1c..4c15ad0 100644 --- a/src/corelib/tools/qvarlengtharray.qdoc +++ b/src/corelib/tools/qvarlengtharray.qdoc @@ -337,6 +337,20 @@ Typedef for const T &. Provided for STL compatibility. */ +/*! + \typedef QVarLengthArray::const_iterator + \since 4.7 + + Typedef for const T *. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::iterator + \since 4.7 + + Typedef for T *. Provided for STL compatibility. +*/ + /*! \fn void QVarLengthArray::prepend(const T &value) \since 4.8 @@ -501,7 +515,7 @@ \relates QVarLengthArray \since 4.8 - Returns true if the two array are equal; + Returns true if the two arrays, specified by \a left and \a right, are equal. Two arrays are considered equal if they contain the same values in the same order. @@ -516,7 +530,7 @@ \relates QVarLengthArray \since 4.8 - Returns true if the two array are different; + Returns true if the two arrays, specified by \a left and \a right, are \e not equal. Two arrays are considered equal if they contain the same values in the same order. diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp index 06ed6bb..0d79215 100644 --- a/src/corelib/tools/qvector.cpp +++ b/src/corelib/tools/qvector.cpp @@ -277,7 +277,7 @@ int QVectorData::grow(int sizeofTypedData, int size, int sizeofT, bool excessive /*! \fn QVector::QVector(std::initializer_list<T> args) \since 4.8 - Construct a vector from a std::initilizer_list. + Construct a vector from the std::initilizer_list given by \a args. This constructor is only enabled if the compiler supports C++0x */ diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index c8cf6ea..009d9b8 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -234,10 +234,11 @@ void QDBusConnectionManager::setConnection(const QString &name, QDBusConnectionP /*! \since 4.8 - \enum QDBusConnection::ConnectionCapabilities - The available capabilities for a D-Bus connection. + \enum QDBusConnection::ConnectionCapability - \value UnixFileDescriptorPassing passing of Unix file descriptors to other processes + This enum describes the available capabilities for a D-Bus connection. + + \value UnixFileDescriptorPassing enables passing of Unix file descriptors to other processes (see QDBusUnixFileDescriptor) \sa connectionCapabilities() diff --git a/src/dbus/qdbusunixfiledescriptor.cpp b/src/dbus/qdbusunixfiledescriptor.cpp index f45b6cc..178a663 100644 --- a/src/dbus/qdbusunixfiledescriptor.cpp +++ b/src/dbus/qdbusunixfiledescriptor.cpp @@ -99,7 +99,17 @@ QT_BEGIN_NAMESPACE invalid state and QDBusUnixFileDescriptor::isSupported() will return false. - \sa QDBusConnection::ConnectionCapabilities, QDBusConnection::connectionCapabilities + \sa QDBusConnection::ConnectionCapabilities, QDBusConnection::connectionCapabilities() +*/ + +/*! + \typedef QDBusUnixFileDescriptor::Data + \internal +*/ + +/*! + \variable QDBusUnixFileDescriptor::d + \internal */ class QDBusUnixFileDescriptorPrivate : public QSharedData { @@ -122,7 +132,7 @@ QExplicitlySharedDataPointer<QDBusUnixFileDescriptorPrivate>::~QExplicitlyShared This is equivalent to constructing the object with an invalid file descriptor (like -1). - \sa fileDescriptor, isValid + \sa fileDescriptor(), isValid() */ QDBusUnixFileDescriptor::QDBusUnixFileDescriptor() : d(0) @@ -140,7 +150,7 @@ QDBusUnixFileDescriptor::QDBusUnixFileDescriptor() If the \a fileDescriptor parameter is not valid, isValid() will return false and fileDescriptor() will return -1. - \sa setFileDescriptor, fileDescriptor + \sa setFileDescriptor(), fileDescriptor() */ QDBusUnixFileDescriptor::QDBusUnixFileDescriptor(int fileDescriptor) : d(0) @@ -227,7 +237,7 @@ bool QDBusUnixFileDescriptor::isSupported() /*! Sets the file descriptor that this QDBusUnixFileDescriptor object holds - to a copy of \a fileDescriptor.T he original file descriptor is not + to a copy of \a fileDescriptor. The original file descriptor is not touched and must be closed by the user. Note that the value returned by fileDescriptor() will be different from 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 6f46354..c7bdcb6 100644 --- a/src/declarative/debugger/qdeclarativedebugserver.cpp +++ b/src/declarative/debugger/qdeclarativedebugserver.cpp @@ -184,7 +184,7 @@ QDeclarativeDebugServer *QDeclarativeDebugServer::instance() int separatorIndex = appD->qmljsDebugArgumentsString().indexOf(QLatin1Char(',')); port = appD->qmljsDebugArgumentsString().mid(5, separatorIndex - 5).toInt(&ok); pluginName = QLatin1String("qmldbg_tcp"); - } else if (appD->qmljsDebugArgumentsString().contains("ost")) { + } else if (appD->qmljsDebugArgumentsString().contains(QLatin1String("ost"))) { pluginName = QLatin1String("qmldbg_ost"); ok = true; } diff --git a/src/declarative/graphicsitems/qdeclarativegridview.cpp b/src/declarative/graphicsitems/qdeclarativegridview.cpp index f30831d..ff442da 100644 --- a/src/declarative/graphicsitems/qdeclarativegridview.cpp +++ b/src/declarative/graphicsitems/qdeclarativegridview.cpp @@ -1796,7 +1796,7 @@ void QDeclarativeGridView::setHighlightRangeMode(HighlightRangeMode mode) \o Qt.LeftToRight (default) - Items will be laid out starting in the top, left corner. The flow is dependent on the \l GridView::flow property. \o Qt.RightToLeft - Items will be laid out starting in the top, right corner. The flow is dependent - on the \l GridView:flow property. + on the \l GridView::flow property. \endlist \bold Note: If GridView::flow is set to GridView.LeftToRight, this is not to be confused if diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp index 6602dda..0010757 100644 --- a/src/declarative/graphicsitems/qdeclarativeitem.cpp +++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp @@ -2605,6 +2605,17 @@ void QDeclarativeItem::setKeepMouseGrab(bool keep) If \a item is a \c null value, this maps the point from the coordinate system of the root QML view. */ + +/*! + Maps the point (\a x, \a y), which is in \a item's coordinate system, to + this item's coordinate system, and returns a script value with \c x and \c y + properties matching the mapped cooordinate. + + If \a item is a \c null value, this maps the point from the coordinate + system of the root QML view. + + \sa Item::mapFromItem() +*/ QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, qreal x, qreal y) const { QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject(); @@ -2631,6 +2642,17 @@ QScriptValue QDeclarativeItem::mapFromItem(const QScriptValue &item, qreal x, qr If \a item is a \c null value, this maps \a x and \a y to the coordinate system of the root QML view. */ + +/*! + Maps the point (\a x, \a y), which is in this item's coordinate system, to + \a item's coordinate system, and returns a script value with \c x and \c y + properties matching the mapped cooordinate. + + If \a item is a \c null value, this maps \a x and \a y to the coordinate + system of the root QML view. + + \sa Item::mapToItem() +*/ QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, qreal x, qreal y) const { QScriptValue sv = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(this))->newObject(); @@ -2650,8 +2672,17 @@ QScriptValue QDeclarativeItem::mapToItem(const QScriptValue &item, qreal x, qrea /*! \qmlmethod Item::forceActiveFocus() - Force active focus on the item. - This method sets focus on the item and makes sure that all the focus scopes higher in the object hierarchy are also given focus. + Forces active focus on the item. + + This method sets focus on the item and makes sure that all the focus scopes + higher in the object hierarchy are also given the focus. +*/ + +/*! + Forces active focus on the item. + + This method sets focus on the item and makes sure that all the focus scopes + higher in the object hierarchy are also given the focus. */ void QDeclarativeItem::forceActiveFocus() { @@ -2670,7 +2701,12 @@ void QDeclarativeItem::forceActiveFocus() Returns the visible child item at point (\a x, \a y), which is in this item's coordinate system, or \c null if there is no such item. - */ +*/ + +/*! + Returns the visible child item at point (\a x, \a y), which is in this + item's coordinate system, or 0 if there is no such item. +*/ QDeclarativeItem *QDeclarativeItem::childAt(qreal x, qreal y) const { const QList<QGraphicsItem *> children = childItems(); diff --git a/src/declarative/graphicsitems/qdeclarativepathview.cpp b/src/declarative/graphicsitems/qdeclarativepathview.cpp index 778b8b9..aed849b 100644 --- a/src/declarative/graphicsitems/qdeclarativepathview.cpp +++ b/src/declarative/graphicsitems/qdeclarativepathview.cpp @@ -1525,6 +1525,8 @@ void QDeclarativePathView::itemsRemoved(int modelIndex, int count) } else { d->regenerate(); d->updateCurrent(); + if (!d->flicking && !d->moving && d->haveHighlightRange && d->highlightRangeMode == QDeclarativePathView::StrictlyEnforceRange) + d->snapToCurrent(); } if (changedOffset) emit offsetChanged(); 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/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index ee241d6..4500a87 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -949,6 +949,8 @@ void QDeclarativeTextInput::setCursorDelegate(QDeclarativeComponent* c) //note that the components are owned by something else disconnect(d->control, SIGNAL(cursorPositionChanged(int,int)), this, SLOT(moveCursor())); + disconnect(d->control, SIGNAL(updateMicroFocus()), + this, SLOT(moveCursor())); delete d->cursorItem; }else{ d->startCreatingCursor(); @@ -961,7 +963,9 @@ void QDeclarativeTextInputPrivate::startCreatingCursor() { Q_Q(QDeclarativeTextInput); q->connect(control, SIGNAL(cursorPositionChanged(int,int)), - q, SLOT(moveCursor())); + q, SLOT(moveCursor()), Qt::UniqueConnection); + q->connect(control, SIGNAL(updateMicroFocus()), + q, SLOT(moveCursor()), Qt::UniqueConnection); if(cursorComponent->isReady()){ q->createCursor(); }else if(cursorComponent->isLoading()){ @@ -1164,9 +1168,10 @@ void QDeclarativeTextInput::mousePressEvent(QGraphicsSceneMouseEvent *event) } if (d->selectByMouse) { setKeepMouseGrab(false); + d->selectPressed = true; d->pressPos = event->pos(); } - bool mark = event->modifiers() & Qt::ShiftModifier; + bool mark = (event->modifiers() & Qt::ShiftModifier) && d->selectByMouse; int cursor = d->xToPos(event->pos().x()); d->control->moveCursor(cursor, mark); event->setAccepted(true); @@ -1177,7 +1182,7 @@ void QDeclarativeTextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event) Q_D(QDeclarativeTextInput); if (d->sendMouseEventToInputContext(event, QEvent::MouseMove)) return; - if (d->selectByMouse) { + if (d->selectPressed) { if (qAbs(int(event->pos().x() - d->pressPos.x())) > QApplication::startDragDistance()) setKeepMouseGrab(true); moveCursorSelection(d->xToPos(event->pos().x()), d->mouseSelectionMode); @@ -1196,8 +1201,10 @@ void QDeclarativeTextInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) Q_D(QDeclarativeTextInput); if (d->sendMouseEventToInputContext(event, QEvent::MouseButtonRelease)) return; - if (d->selectByMouse) + if (d->selectPressed) { + d->selectPressed = false; setKeepMouseGrab(false); + } if (!d->showInputPanelOnFocus) { // input panel on click if (d->focusOnPress && !isReadOnly() && boundingRect().contains(event->pos())) { if (QGraphicsView * view = qobject_cast<QGraphicsView*>(qApp->focusWidget())) { @@ -1253,8 +1260,10 @@ bool QDeclarativeTextInputPrivate::sendMouseEventToInputContext( bool QDeclarativeTextInput::sceneEvent(QEvent *event) { + Q_D(QDeclarativeTextInput); bool rv = QDeclarativeItem::sceneEvent(event); if (event->type() == QEvent::UngrabMouse) { + d->selectPressed = false; setKeepMouseGrab(false); } return rv; @@ -1867,6 +1876,7 @@ bool QDeclarativeTextInput::isInputMethodComposing() const void QDeclarativeTextInputPrivate::init() { Q_Q(QDeclarativeTextInput); + control->setParent(q); control->setCursorWidth(1); control->setPasswordCharacter(QLatin1Char('*')); q->setSmooth(smooth); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h index ed53e8f..7595b36 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h @@ -70,13 +70,14 @@ class Q_AUTOTEST_EXPORT QDeclarativeTextInputPrivate : public QDeclarativeImplic { Q_DECLARE_PUBLIC(QDeclarativeTextInput) public: - QDeclarativeTextInputPrivate() : control(new QLineControl(QString())), + QDeclarativeTextInputPrivate() : control(new QLineControl), color((QRgb)0), style(QDeclarativeText::Normal), styleColor((QRgb)0), hAlign(QDeclarativeTextInput::AlignLeft), mouseSelectionMode(QDeclarativeTextInput::SelectCharacters), inputMethodHints(Qt::ImhNone), hscroll(0), oldScroll(0), oldValidity(false), focused(false), focusOnPress(true), showInputPanelOnFocus(true), clickCausedFocus(false), cursorVisible(false), - autoScroll(true), selectByMouse(false), canPaste(false), hAlignImplicit(true) + autoScroll(true), selectByMouse(false), canPaste(false), hAlignImplicit(true), + selectPressed(false) { #ifdef Q_OS_SYMBIAN if (QSysInfo::symbianVersion() == QSysInfo::SV_SF_1 || QSysInfo::symbianVersion() == QSysInfo::SV_SF_3) { @@ -88,7 +89,6 @@ public: ~QDeclarativeTextInputPrivate() { - delete control; } int xToPos(int x, QTextLine::CursorPosition betweenOrOn = QTextLine::CursorBetweenCharacters) const @@ -142,6 +142,7 @@ public: bool selectByMouse:1; bool canPaste:1; bool hAlignImplicit:1; + bool selectPressed:1; static inline QDeclarativeTextInputPrivate *get(QDeclarativeTextInput *t) { return t->d_func(); diff --git a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp index 987aa23..1e6db3f 100644 --- a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp @@ -296,7 +296,7 @@ void QDeclarativeTextLayout::clearLayout() QTextLayout::clearLayout(); } -void QDeclarativeTextLayout::prepare() +void QDeclarativeTextLayout::prepare(QPainter *painter) { if (!d || !d->cached) { @@ -305,6 +305,7 @@ void QDeclarativeTextLayout::prepare() InertTextPainter *itp = inertTextPainter(); itp->device.begin(d); + itp->painter.setPen(painter->pen()); QTextLayout::draw(&itp->painter, QPointF(0, 0)); glyph_t *glyphPool = d->glyphs.data(); @@ -323,6 +324,12 @@ void QDeclarativeTextLayout::prepare() } } +// Defined in qpainter.cpp +extern Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray, + const QFixedPoint *positions, int glyphCount, + QFontEngine *fontEngine, const QFont &font, + const QTextCharFormat &charFormat); + void QDeclarativeTextLayout::draw(QPainter *painter, const QPointF &p) { QPainterPrivate *priv = QPainterPrivate::get(painter); @@ -337,7 +344,7 @@ void QDeclarativeTextLayout::draw(QPainter *painter, const QPointF &p) return; } - prepare(); + prepare(painter); int itemCount = d->items.count(); @@ -368,6 +375,10 @@ void QDeclarativeTextLayout::draw(QPainter *painter, const QPointF &p) currentColor = item.color; } priv->extended->drawStaticTextItem(&item); + + qt_draw_decoration_for_glyphs(painter, item.glyphs, item.glyphPositions, + item.numGlyphs, item.fontEngine(), painter->font(), + QTextCharFormat()); } if (currentColor != oldPen.color()) painter->setPen(oldPen); diff --git a/src/declarative/graphicsitems/qdeclarativetextlayout_p.h b/src/declarative/graphicsitems/qdeclarativetextlayout_p.h index 2c9264e..23b22a6 100644 --- a/src/declarative/graphicsitems/qdeclarativetextlayout_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextlayout_p.h @@ -61,7 +61,7 @@ public: void beginLayout(); void clearLayout(); - void prepare(); + void prepare(QPainter *); void draw(QPainter *, const QPointF & = QPointF()); private: 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/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/qdeclarativetypeloader.cpp b/src/declarative/qml/qdeclarativetypeloader.cpp index 26f3996..ff6a7c7 100644 --- a/src/declarative/qml/qdeclarativetypeloader.cpp +++ b/src/declarative/qml/qdeclarativetypeloader.cpp @@ -434,7 +434,7 @@ void QDeclarativeDataBlob::notifyComplete(QDeclarativeDataBlob *blob) /*! \class QDeclarativeDataLoader -\brief The QDeclarativeDataLoader class abstracts loading files and their dependecies over the network. +\brief The QDeclarativeDataLoader class abstracts loading files and their dependencies over the network. \internal The QDeclarativeDataLoader class is provided for the exclusive use of the QDeclarativeTypeLoader class. @@ -453,9 +453,11 @@ are required before processing can fully complete. To complete processing, the QDeclarativeDataBlob::done() callback is invoked. done() is called when one of these three preconditions are met. -1. The QDeclarativeDataBlob has no dependencies. -2. The QDeclarativeDataBlob has an error set. -3. All the QDeclarativeDataBlob's dependencies are themselves "done()". +\list 1 +\o The QDeclarativeDataBlob has no dependencies. +\o The QDeclarativeDataBlob has an error set. +\o All the QDeclarativeDataBlob's dependencies are themselves "done()". +\endlist Thus QDeclarativeDataBlob::done() will always eventually be called, even if the blob has an error set. */ @@ -616,13 +618,17 @@ void QDeclarativeDataLoader::setData(QDeclarativeDataBlob *blob, const QByteArra } /*! -\class QDeclarativeTypeLoader +Constructs a new type loader that uses the given \a engine. */ QDeclarativeTypeLoader::QDeclarativeTypeLoader(QDeclarativeEngine *engine) : QDeclarativeDataLoader(engine) { } +/*! +Destroys the type loader, first clearing the cache of any information about +loaded files. +*/ QDeclarativeTypeLoader::~QDeclarativeTypeLoader() { clearCache(); @@ -674,7 +680,7 @@ QDeclarativeTypeData *QDeclarativeTypeLoader::get(const QByteArray &data, const } /*! -Return a QDeclarativeScriptData for \a url. The QDeclarativeScriptData may be cached. +Returns a QDeclarativeScriptData for \a url. The QDeclarativeScriptData may be cached. */ QDeclarativeScriptData *QDeclarativeTypeLoader::getScript(const QUrl &url) { @@ -695,7 +701,7 @@ QDeclarativeScriptData *QDeclarativeTypeLoader::getScript(const QUrl &url) } /*! -Return a QDeclarativeQmldirData for \a url. The QDeclarativeQmldirData may be cached. +Returns a QDeclarativeQmldirData for \a url. The QDeclarativeQmldirData may be cached. */ QDeclarativeQmldirData *QDeclarativeTypeLoader::getQmldir(const QUrl &url) { @@ -715,6 +721,10 @@ QDeclarativeQmldirData *QDeclarativeTypeLoader::getQmldir(const QUrl &url) return qmldirData; } +/*! +Clears cached information about loaded files, including any type data, scripts +and qmldir information. +*/ void QDeclarativeTypeLoader::clearCache() { for (TypeCache::Iterator iter = m_typeCache.begin(); iter != m_typeCache.end(); ++iter) diff --git a/src/declarative/qml/qmetaobjectbuilder.cpp b/src/declarative/qml/qmetaobjectbuilder.cpp index dc941e2..a63656b 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(); @@ -2278,6 +2282,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 +2431,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/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp index 9221d78..a29854f 100644 --- a/src/declarative/util/qdeclarativepixmapcache.cpp +++ b/src/declarative/util/qdeclarativepixmapcache.cpp @@ -72,9 +72,7 @@ QT_BEGIN_NAMESPACE // The cache limit describes the maximum "junk" in the cache. // These are the same defaults as QPixmapCache -#if defined(Q_OS_SYMBIAN) -static int cache_limit = 1024 * 1024; // 1048 KB cache limit for symbian -#elif defined(Q_WS_QWS) || defined(Q_WS_WINCE) +#if defined(Q_WS_QWS) || defined(Q_WS_WINCE) static int cache_limit = 2048 * 1024; // 2048 KB cache limit for embedded #else static int cache_limit = 10240 * 1024; // 10 MB cache limit for desktop diff --git a/src/gui/accessible/qaccessible.h b/src/gui/accessible/qaccessible.h index c714173..1e9e55e 100644 --- a/src/gui/accessible/qaccessible.h +++ b/src/gui/accessible/qaccessible.h @@ -83,6 +83,42 @@ public: MenuCommand = 0x0018, + // Values from IAccessible2 + ActionChanged = 0x0101, + ActiveDescendantChanged, + AttributeChanged, + DocumentContentChanged, + DocumentLoadComplete, + DocumentLoadStopped, + DocumentReload, + HyperlinkEndIndexChanged, + HyperlinkNumberOfAnchorsChanged, + HyperlinkSelectedLinkChanged, + HypertextLinkActivated, + HypertextLinkSelected, + HyperlinkStartIndexChanged, + HypertextChanged, + HypertextNLinksChanged, + ObjectAttributeChanged, + PageChanged, + SectionChanged, + TableCaptionChanged, + TableColumnDescriptionChanged, + TableColumnHeaderChanged, + TableModelChanged, + TableRowDescriptionChanged, + TableRowHeaderChanged, + TableSummaryChanged, + TextAttributeChanged, + TextCaretMoved, + // TextChanged, deprecated, use TextUpdated + TextColumnChanged = TextCaretMoved + 2, + TextInserted, + TextRemoved, + TextUpdated, + TextSelectionChanged, + VisibleDataChanged, + ObjectCreated = 0x8000, ObjectDestroyed = 0x8001, ObjectShow = 0x8002, diff --git a/src/gui/accessible/qaccessibleobject.cpp b/src/gui/accessible/qaccessibleobject.cpp index 1d2d1da..0cb2c08 100644 --- a/src/gui/accessible/qaccessibleobject.cpp +++ b/src/gui/accessible/qaccessibleobject.cpp @@ -322,9 +322,7 @@ QString QAccessibleApplication::text(Text t, int) const { switch (t) { case Name: - if (QApplication::activeWindow()) - return QApplication::activeWindow()->windowTitle(); - break; + return QApplication::applicationName(); case Description: return QApplication::applicationFilePath(); default: diff --git a/src/gui/dialogs/qcolordialog_mac.mm b/src/gui/dialogs/qcolordialog_mac.mm index ee9b19a..9daf595 100644 --- a/src/gui/dialogs/qcolordialog_mac.mm +++ b/src/gui/dialogs/qcolordialog_mac.mm @@ -343,6 +343,7 @@ QT_USE_NAMESPACE mDialogIsExecuting = true; bool modalEnded = false; while (!modalEnded) { +#ifndef QT_NO_EXCEPTIONS @try { [NSApp runModalForWindow:mColorPanel]; modalEnded = true; @@ -351,6 +352,10 @@ QT_USE_NAMESPACE // clicking on 'SelectedMenuItemColor' from the 'Developer' // palette (tab three). } +#else + [NSApp runModalForWindow:mColorPanel]; + modalEnded = true; +#endif } QAbstractEventDispatcher::instance()->interrupt(); diff --git a/src/gui/dialogs/qfilesystemmodel.cpp b/src/gui/dialogs/qfilesystemmodel.cpp index cb8eb6a..ff4410d 100644 --- a/src/gui/dialogs/qfilesystemmodel.cpp +++ b/src/gui/dialogs/qfilesystemmodel.cpp @@ -1977,13 +1977,14 @@ bool QFileSystemModelPrivate::filtersAcceptsNode(const QFileSystemNode *node) co const bool hideHidden = !(filters & QDir::Hidden); const bool hideSystem = !(filters & QDir::System); const bool hideSymlinks = (filters & QDir::NoSymLinks); - const bool hideDotAndDotDot = (filters & QDir::NoDotAndDotDot); + const bool hideDot = (filters & QDir::NoDot) || (filters & QDir::NoDotAndDotDot); // ### Qt5: simplify (because NoDotAndDotDot=NoDot|NoDotDot) + const bool hideDotDot = (filters & QDir::NoDotDot) || (filters & QDir::NoDotAndDotDot); // ### Qt5: simplify (because NoDotAndDotDot=NoDot|NoDotDot) // Note that we match the behavior of entryList and not QFileInfo on this and this // incompatibility won't be fixed until Qt 5 at least - bool isDotOrDot = ( (node->fileName == QLatin1String(".") - || node->fileName == QLatin1String(".."))); - if ( (hideHidden && (!isDotOrDot && node->isHidden())) + bool isDot = (node->fileName == QLatin1String(".")); + bool isDotDot = (node->fileName == QLatin1String("..")); + if ( (hideHidden && !(isDot || isDotDot) && node->isHidden()) || (hideSystem && node->isSystem()) || (hideDirs && node->isDir()) || (hideFiles && node->isFile()) @@ -1991,7 +1992,8 @@ bool QFileSystemModelPrivate::filtersAcceptsNode(const QFileSystemNode *node) co || (hideReadable && node->isReadable()) || (hideWritable && node->isWritable()) || (hideExecutable && node->isExecutable()) - || (hideDotAndDotDot && isDotOrDot)) + || (hideDot && isDot) + || (hideDotDot && isDotDot)) return false; return nameFilterDisables || passNameFilters(node); 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..ce4452f 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 + \sa 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 \e{first 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 + \sa 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/qgraphicsscenebsptreeindex.cpp b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp index 92e4a55..4688fa0 100644 --- a/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp +++ b/src/gui/graphicsview/qgraphicsscenebsptreeindex.cpp @@ -50,14 +50,14 @@ QGraphicsSceneBspTreeIndex index use a BSP(Binary Space Partitioning) implementation to discover items quickly. This implementation is - very efficient for static scene. It has a depth that you can set. + very efficient for static scenes. It has a depth that you can set. The depth directly affects performance and memory usage; the latter growing exponentially with the depth of the tree. With an optimal tree depth, the index can instantly determine the locality of items, even for scenes with thousands or millions of items. This also greatly improves rendering performance. - By default, the value is 0, in which case Qt will guess a reasonable + By default, the depth value is 0, in which case Qt will guess a reasonable default depth based on the size, location and number of items in the scene. If these parameters change frequently, however, you may experience slowdowns as the index retunes the depth internally. You can avoid 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 5844f96..69fe9c9 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -2008,10 +2008,11 @@ void QImage::fill(uint pixel) /*! \fn void QImage::fill(Qt::GlobalColor color) - \overload - \since 4.8 + + Fills the image with the given \a color, described as a standard global + color. */ void QImage::fill(Qt::GlobalColor color) diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp index 34804e5..c34f6ac 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; } diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index 41fc6e9..ae772d8 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -91,9 +91,7 @@ QT_BEGIN_NAMESPACE \sa QCache, QPixmap */ -#if defined(Q_OS_SYMBIAN) -static int cache_limit = 1024; // 1048 KB cache limit for symbian -#elif defined(Q_WS_QWS) || defined(Q_WS_WINCE) +#if defined(Q_WS_QWS) || defined(Q_WS_WINCE) static int cache_limit = 2048; // 2048 KB cache limit for embedded #else static int cache_limit = 10240; // 10 MB cache limit for desktop 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_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp index 92f8384..06dc25c 100644 --- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp +++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp @@ -255,9 +255,13 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) // fall through intended case QEvent::KeyRelease: const QKeyEvent *keyEvent = static_cast<const QKeyEvent *>(event); + //If proxy exists, always use hints from proxy. + QWidget *proxy = focusWidget()->focusProxy(); + Qt::InputMethodHints currentHints = proxy ? proxy->inputMethodHints() : focusWidget()->inputMethodHints(); + switch (keyEvent->key()) { case Qt::Key_F20: - Q_ASSERT(m_lastImHints == focusWidget()->inputMethodHints()); + Q_ASSERT(m_lastImHints == currentHints); if (m_lastImHints & Qt::ImhHiddenText) { // Special case in Symbian. On editors with secret text, F20 is for some reason // considered to be a backspace. @@ -287,7 +291,7 @@ bool QCoeFepInputContext::filterEvent(const QEvent *event) } if (keyEvent->type() == QEvent::KeyPress - && focusWidget()->inputMethodHints() & Qt::ImhHiddenText + && currentHints & Qt::ImhHiddenText && !keyEvent->text().isEmpty()) { // Send some temporary preedit text in order to make text visible for a moment. m_preeditString = keyEvent->text(); @@ -588,9 +592,10 @@ void QCoeFepInputContext::updateHints(bool mustUpdateInputCapabilities) { QWidget *w = focusWidget(); if (w) { - Qt::InputMethodHints hints = w->inputMethodHints(); + QWidget *proxy = w->focusProxy(); + Qt::InputMethodHints hints = proxy ? proxy->inputMethodHints() : w->inputMethodHints(); - // Since splitview support works like an input method hint, yet it is private flag, + // Since splitview support works like an input method hint, yet it is private flag, // we need to update its state separately. if (QSysInfo::s60Version() > QSysInfo::SV_S60_5_0) { TInt currentFlags = m_fepState->Flags(); diff --git a/src/gui/itemviews/itemviews.pri b/src/gui/itemviews/itemviews.pri index bbc1e98..149bfd6 100644 --- a/src/gui/itemviews/itemviews.pri +++ b/src/gui/itemviews/itemviews.pri @@ -4,6 +4,7 @@ HEADERS += \ itemviews/qabstractitemview.h \ itemviews/qabstractitemview_p.h \ itemviews/qheaderview.h \ + itemviews/qidentityproxymodel.h \ itemviews/qlistview.h \ itemviews/qlistview_p.h \ itemviews/qbsptree_p.h \ @@ -44,6 +45,7 @@ HEADERS += \ SOURCES += \ itemviews/qabstractitemview.cpp \ itemviews/qheaderview.cpp \ + itemviews/qidentityproxymodel.cpp \ itemviews/qlistview.cpp \ itemviews/qbsptree.cpp \ itemviews/qtableview.cpp \ diff --git a/src/gui/itemviews/qabstractproxymodel.cpp b/src/gui/itemviews/qabstractproxymodel.cpp index 34ca7df..82b6c8d 100644 --- a/src/gui/itemviews/qabstractproxymodel.cpp +++ b/src/gui/itemviews/qabstractproxymodel.cpp @@ -121,15 +121,12 @@ QAbstractProxyModel::~QAbstractProxyModel() void QAbstractProxyModel::setSourceModel(QAbstractItemModel *sourceModel) { Q_D(QAbstractProxyModel); - if (d->model) { + if (d->model) disconnect(d->model, SIGNAL(destroyed()), this, SLOT(_q_sourceModelDestroyed())); - disconnect(d->model, SIGNAL(modelReset()), this, SLOT(resetInternalData())); - } if (sourceModel) { d->model = sourceModel; connect(d->model, SIGNAL(destroyed()), this, SLOT(_q_sourceModelDestroyed())); - connect(d->model, SIGNAL(modelReset()), this, SLOT(resetInternalData())); } else { d->model = QAbstractItemModelPrivate::staticEmptyModel(); } @@ -383,25 +380,6 @@ Qt::DropActions QAbstractProxyModel::supportedDropActions() const return d->model->supportedDropActions(); } -/* - \since 4.8 - - This slot is called just after the internal data of a model is cleared - while it is being reset. - - This slot is provided the convenience of subclasses of concrete proxy - models, such as subclasses of QSortFilterProxyModel which maintain extra - data. - - \snippet doc/src/snippets/code/src_corelib_kernel_qabstractitemmodel.cpp 10 - - \sa modelAboutToBeReset(), modelReset() -*/ -void QAbstractProxyModel::resetInternalData() -{ - -} - QT_END_NAMESPACE #include "moc_qabstractproxymodel.cpp" diff --git a/src/gui/itemviews/qabstractproxymodel.h b/src/gui/itemviews/qabstractproxymodel.h index 6e485ae..4f3bc18 100644 --- a/src/gui/itemviews/qabstractproxymodel.h +++ b/src/gui/itemviews/qabstractproxymodel.h @@ -95,9 +95,6 @@ public: QStringList mimeTypes() const; Qt::DropActions supportedDropActions() const; -protected Q_SLOTS: - void resetInternalData(); - protected: QAbstractProxyModel(QAbstractProxyModelPrivate &, QObject *parent); diff --git a/src/gui/itemviews/qidentityproxymodel.cpp b/src/gui/itemviews/qidentityproxymodel.cpp new file mode 100644 index 0000000..60f7d98 --- /dev/null +++ b/src/gui/itemviews/qidentityproxymodel.cpp @@ -0,0 +1,587 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> +** 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 "qidentityproxymodel.h" + +#ifndef QT_NO_IDENTITYPROXYMODEL + +#include "qitemselectionmodel.h" +#include <private/qabstractproxymodel_p.h> + +QT_BEGIN_NAMESPACE + +class QIdentityProxyModelPrivate : public QAbstractProxyModelPrivate +{ + QIdentityProxyModelPrivate() + : ignoreNextLayoutAboutToBeChanged(false), + ignoreNextLayoutChanged(false) + { + + } + + Q_DECLARE_PUBLIC(QIdentityProxyModel) + + bool ignoreNextLayoutAboutToBeChanged; + bool ignoreNextLayoutChanged; + QList<QPersistentModelIndex> layoutChangePersistentIndexes; + QModelIndexList proxyIndexes; + + void _q_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end); + void _q_sourceRowsInserted(const QModelIndex &parent, int start, int end); + void _q_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + void _q_sourceRowsRemoved(const QModelIndex &parent, int start, int end); + void _q_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + void _q_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + + void _q_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end); + void _q_sourceColumnsInserted(const QModelIndex &parent, int start, int end); + void _q_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end); + void _q_sourceColumnsRemoved(const QModelIndex &parent, int start, int end); + void _q_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + void _q_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest); + + void _q_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight); + void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last); + + void _q_sourceLayoutAboutToBeChanged(); + void _q_sourceLayoutChanged(); + void _q_sourceModelAboutToBeReset(); + void _q_sourceModelReset(); + +}; + +/*! + \since 4.8 + \class QIdentityProxyModel + \brief The QIdentityProxyModel class proxies its source model unmodified + + \ingroup model-view + + QIdentityProxyModel can be used to forward the structure of a source model exactly, with no sorting, filtering or other transformation. + This is similar in concept to an identity matrix where A.I = A. + + Because it does no sorting or filtering, this class is most suitable to proxy models which transform the data() of the source model. + For example, a proxy model could be created to define the font used, or the background colour, or the tooltip etc. This removes the + need to implement all data handling in the same class that creates the structure of the model, and can also be used to create + re-usable components. + + This also provides a way to change the data in the case where a source model is supplied by a third party which can not be modified. + + \snippet doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp 0 + + \sa QAbstractProxyModel, {Model/View Programming}, QAbstractItemModel + +*/ + +/*! + Constructs an identity model with the given \a parent. +*/ +QIdentityProxyModel::QIdentityProxyModel(QObject* parent) + : QAbstractProxyModel(*new QIdentityProxyModelPrivate, parent) +{ + +} + +/*! \internal + */ +QIdentityProxyModel::QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent) + : QAbstractProxyModel(dd, parent) +{ + +} + +/*! + Destroys this identity model. +*/ +QIdentityProxyModel::~QIdentityProxyModel() +{ +} + +/*! + \reimp + */ +int QIdentityProxyModel::columnCount(const QModelIndex& parent) const +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(const QIdentityProxyModel); + return d->model->columnCount(mapToSource(parent)); +} + +/*! + \reimp + */ +bool QIdentityProxyModel::dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(QIdentityProxyModel); + return d->model->dropMimeData(data, action, row, column, mapToSource(parent)); +} + +/*! + \reimp + */ +QModelIndex QIdentityProxyModel::index(int row, int column, const QModelIndex& parent) const +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(const QIdentityProxyModel); + if (!hasIndex(row, column, parent)) + return QModelIndex(); + const QModelIndex sourceParent = mapToSource(parent); + const QModelIndex sourceIndex = d->model->index(row, column, sourceParent); + Q_ASSERT(sourceIndex.isValid()); + return mapFromSource(sourceIndex); +} + +/*! + \reimp + */ +bool QIdentityProxyModel::insertColumns(int column, int count, const QModelIndex& parent) +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(QIdentityProxyModel); + return d->model->insertColumns(column, count, mapToSource(parent)); +} + +/*! + \reimp + */ +bool QIdentityProxyModel::insertRows(int row, int count, const QModelIndex& parent) +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(QIdentityProxyModel); + return d->model->insertRows(row, count, mapToSource(parent)); +} + +/*! + \reimp + */ +QModelIndex QIdentityProxyModel::mapFromSource(const QModelIndex& sourceIndex) const +{ + Q_D(const QIdentityProxyModel); + if (!d->model || !sourceIndex.isValid()) + return QModelIndex(); + + Q_ASSERT(sourceIndex.model() == d->model); + return createIndex(sourceIndex.row(), sourceIndex.column(), sourceIndex.internalPointer()); +} + +/*! + \reimp + */ +QItemSelection QIdentityProxyModel::mapSelectionFromSource(const QItemSelection& selection) const +{ + Q_D(const QIdentityProxyModel); + QItemSelection proxySelection; + + if (!d->model) + return proxySelection; + + QItemSelection::const_iterator it = selection.constBegin(); + const QItemSelection::const_iterator end = selection.constEnd(); + for ( ; it != end; ++it) { + Q_ASSERT(it->model() == d->model); + const QItemSelectionRange range(mapFromSource(it->topLeft()), mapFromSource(it->bottomRight())); + proxySelection.append(range); + } + + return proxySelection; +} + +/*! + \reimp + */ +QItemSelection QIdentityProxyModel::mapSelectionToSource(const QItemSelection& selection) const +{ + Q_D(const QIdentityProxyModel); + QItemSelection sourceSelection; + + if (!d->model) + return sourceSelection; + + QItemSelection::const_iterator it = selection.constBegin(); + const QItemSelection::const_iterator end = selection.constEnd(); + for ( ; it != end; ++it) { + Q_ASSERT(it->model() == this); + const QItemSelectionRange range(mapToSource(it->topLeft()), mapToSource(it->bottomRight())); + sourceSelection.append(range); + } + + return sourceSelection; +} + +/*! + \reimp + */ +QModelIndex QIdentityProxyModel::mapToSource(const QModelIndex& proxyIndex) const +{ + Q_D(const QIdentityProxyModel); + if (!d->model || !proxyIndex.isValid()) + return QModelIndex(); + Q_ASSERT(proxyIndex.model() == this); + return d->model->createIndex(proxyIndex.row(), proxyIndex.column(), proxyIndex.internalPointer()); +} + +/*! + \reimp + */ +QModelIndexList QIdentityProxyModel::match(const QModelIndex& start, int role, const QVariant& value, int hits, Qt::MatchFlags flags) const +{ + Q_D(const QIdentityProxyModel); + Q_ASSERT(start.isValid() ? start.model() == this : true); + if (!d->model) + return QModelIndexList(); + + const QModelIndexList sourceList = d->model->match(mapToSource(start), role, value, hits, flags); + QModelIndexList::const_iterator it = sourceList.constBegin(); + const QModelIndexList::const_iterator end = sourceList.constEnd(); + QModelIndexList proxyList; + for ( ; it != end; ++it) + proxyList.append(mapFromSource(*it)); + return proxyList; +} + +/*! + \reimp + */ +QModelIndex QIdentityProxyModel::parent(const QModelIndex& child) const +{ + Q_ASSERT(child.isValid() ? child.model() == this : true); + const QModelIndex sourceIndex = mapToSource(child); + const QModelIndex sourceParent = sourceIndex.parent(); + return mapFromSource(sourceParent); +} + +/*! + \reimp + */ +bool QIdentityProxyModel::removeColumns(int column, int count, const QModelIndex& parent) +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(QIdentityProxyModel); + return d->model->removeColumns(column, count, mapToSource(parent)); +} + +/*! + \reimp + */ +bool QIdentityProxyModel::removeRows(int row, int count, const QModelIndex& parent) +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(QIdentityProxyModel); + return d->model->removeRows(row, count, mapToSource(parent)); +} + +/*! + \reimp + */ +int QIdentityProxyModel::rowCount(const QModelIndex& parent) const +{ + Q_ASSERT(parent.isValid() ? parent.model() == this : true); + Q_D(const QIdentityProxyModel); + return d->model->rowCount(mapToSource(parent)); +} + +/*! + \reimp + */ +void QIdentityProxyModel::setSourceModel(QAbstractItemModel* sourceModel) +{ + beginResetModel(); + + if (sourceModel) { + disconnect(sourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), + this, SLOT(_q_sourceRowsAboutToBeInserted(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), + this, SLOT(_q_sourceRowsInserted(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)), + this, SLOT(_q_sourceRowsAboutToBeRemoved(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + this, SLOT(_q_sourceRowsRemoved(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + this, SLOT(_q_sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + disconnect(sourceModel, SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + this, SLOT(_q_sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + disconnect(sourceModel, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)), + this, SLOT(_q_sourceColumnsAboutToBeInserted(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(columnsInserted(const QModelIndex &, int, int)), + this, SLOT(_q_sourceColumnsInserted(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)), + this, SLOT(_q_sourceColumnsAboutToBeRemoved(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(columnsRemoved(const QModelIndex &, int, int)), + this, SLOT(_q_sourceColumnsRemoved(const QModelIndex &, int, int))); + disconnect(sourceModel, SIGNAL(columnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + this, SLOT(_q_sourceColumnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + disconnect(sourceModel, SIGNAL(columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + this, SLOT(_q_sourceColumnsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + disconnect(sourceModel, SIGNAL(modelAboutToBeReset()), + this, SLOT(_q_sourceModelAboutToBeReset())); + disconnect(sourceModel, SIGNAL(modelReset()), + this, SLOT(_q_sourceModelReset())); + disconnect(sourceModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + this, SLOT(_q_sourceDataChanged(const QModelIndex &, const QModelIndex &))); + disconnect(sourceModel, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), + this, SLOT(_q_sourceHeaderDataChanged(Qt::Orientation,int,int))); + disconnect(sourceModel, SIGNAL(layoutAboutToBeChanged()), + this, SLOT(_q_sourceLayoutAboutToBeChanged())); + disconnect(sourceModel, SIGNAL(layoutChanged()), + this, SLOT(_q_sourceLayoutChanged())); + } + + QAbstractProxyModel::setSourceModel(sourceModel); + + if (sourceModel) { + connect(sourceModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex &, int, int)), + SLOT(_q_sourceRowsAboutToBeInserted(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(rowsInserted(const QModelIndex &, int, int)), + SLOT(_q_sourceRowsInserted(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(rowsAboutToBeRemoved(const QModelIndex &, int, int)), + SLOT(_q_sourceRowsAboutToBeRemoved(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), + SLOT(_q_sourceRowsRemoved(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(rowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + SLOT(_q_sourceRowsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + connect(sourceModel, SIGNAL(rowsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + SLOT(_q_sourceRowsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + connect(sourceModel, SIGNAL(columnsAboutToBeInserted(const QModelIndex &, int, int)), + SLOT(_q_sourceColumnsAboutToBeInserted(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(columnsInserted(const QModelIndex &, int, int)), + SLOT(_q_sourceColumnsInserted(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(columnsAboutToBeRemoved(const QModelIndex &, int, int)), + SLOT(_q_sourceColumnsAboutToBeRemoved(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(columnsRemoved(const QModelIndex &, int, int)), + SLOT(_q_sourceColumnsRemoved(const QModelIndex &, int, int))); + connect(sourceModel, SIGNAL(columnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + SLOT(_q_sourceColumnsAboutToBeMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + connect(sourceModel, SIGNAL(columnsMoved(const QModelIndex &, int, int, const QModelIndex &, int)), + SLOT(_q_sourceColumnsMoved(const QModelIndex &, int, int, const QModelIndex &, int))); + connect(sourceModel, SIGNAL(modelAboutToBeReset()), + SLOT(_q_sourceModelAboutToBeReset())); + connect(sourceModel, SIGNAL(modelReset()), + SLOT(_q_sourceModelReset())); + connect(sourceModel, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), + SLOT(_q_sourceDataChanged(const QModelIndex &, const QModelIndex &))); + connect(sourceModel, SIGNAL(headerDataChanged(Qt::Orientation,int,int)), + SLOT(_q_sourceHeaderDataChanged(Qt::Orientation,int,int))); + connect(sourceModel, SIGNAL(layoutAboutToBeChanged()), + SLOT(_q_sourceLayoutAboutToBeChanged())); + connect(sourceModel, SIGNAL(layoutChanged()), + SLOT(_q_sourceLayoutChanged())); + } + + endResetModel(); +} + +void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeInserted(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + q->beginInsertColumns(q->mapFromSource(parent), start, end); +} + +void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true); + Q_ASSERT(destParent.isValid() ? destParent.model() == model : true); + Q_Q(QIdentityProxyModel); + q->beginMoveColumns(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destParent), dest); +} + +void QIdentityProxyModelPrivate::_q_sourceColumnsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + q->beginRemoveColumns(q->mapFromSource(parent), start, end); +} + +void QIdentityProxyModelPrivate::_q_sourceColumnsInserted(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + q->endInsertColumns(); +} + +void QIdentityProxyModelPrivate::_q_sourceColumnsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true); + Q_ASSERT(destParent.isValid() ? destParent.model() == model : true); + Q_Q(QIdentityProxyModel); + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destParent) + Q_UNUSED(dest) + q->endMoveColumns(); +} + +void QIdentityProxyModelPrivate::_q_sourceColumnsRemoved(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + q->endRemoveColumns(); +} + +void QIdentityProxyModelPrivate::_q_sourceDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight) +{ + Q_ASSERT(topLeft.isValid() ? topLeft.model() == model : true); + Q_ASSERT(bottomRight.isValid() ? bottomRight.model() == model : true); + Q_Q(QIdentityProxyModel); + q->dataChanged(q->mapFromSource(topLeft), q->mapFromSource(bottomRight)); +} + +void QIdentityProxyModelPrivate::_q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last) +{ + Q_Q(QIdentityProxyModel); + q->headerDataChanged(orientation, first, last); +} + +void QIdentityProxyModelPrivate::_q_sourceLayoutAboutToBeChanged() +{ + if (ignoreNextLayoutAboutToBeChanged) + return; + + Q_Q(QIdentityProxyModel); + + foreach(const QPersistentModelIndex &proxyPersistentIndex, q->persistentIndexList()) { + proxyIndexes << proxyPersistentIndex; + Q_ASSERT(proxyPersistentIndex.isValid()); + const QPersistentModelIndex srcPersistentIndex = q->mapToSource(proxyPersistentIndex); + Q_ASSERT(srcPersistentIndex.isValid()); + layoutChangePersistentIndexes << srcPersistentIndex; + } + + q->layoutAboutToBeChanged(); +} + +void QIdentityProxyModelPrivate::_q_sourceLayoutChanged() +{ + if (ignoreNextLayoutChanged) + return; + + Q_Q(QIdentityProxyModel); + + for (int i = 0; i < proxyIndexes.size(); ++i) { + q->changePersistentIndex(proxyIndexes.at(i), q->mapFromSource(layoutChangePersistentIndexes.at(i))); + } + + layoutChangePersistentIndexes.clear(); + proxyIndexes.clear(); + + q->layoutChanged(); +} + +void QIdentityProxyModelPrivate::_q_sourceModelAboutToBeReset() +{ + Q_Q(QIdentityProxyModel); + q->beginResetModel(); +} + +void QIdentityProxyModelPrivate::_q_sourceModelReset() +{ + Q_Q(QIdentityProxyModel); + q->endResetModel(); +} + +void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeInserted(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + q->beginInsertRows(q->mapFromSource(parent), start, end); +} + +void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true); + Q_ASSERT(destParent.isValid() ? destParent.model() == model : true); + Q_Q(QIdentityProxyModel); + q->beginMoveRows(q->mapFromSource(sourceParent), sourceStart, sourceEnd, q->mapFromSource(destParent), dest); +} + +void QIdentityProxyModelPrivate::_q_sourceRowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + q->beginRemoveRows(q->mapFromSource(parent), start, end); +} + +void QIdentityProxyModelPrivate::_q_sourceRowsInserted(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + q->endInsertRows(); +} + +void QIdentityProxyModelPrivate::_q_sourceRowsMoved(const QModelIndex &sourceParent, int sourceStart, int sourceEnd, const QModelIndex &destParent, int dest) +{ + Q_ASSERT(sourceParent.isValid() ? sourceParent.model() == model : true); + Q_ASSERT(destParent.isValid() ? destParent.model() == model : true); + Q_Q(QIdentityProxyModel); + Q_UNUSED(sourceParent) + Q_UNUSED(sourceStart) + Q_UNUSED(sourceEnd) + Q_UNUSED(destParent) + Q_UNUSED(dest) + q->endMoveRows(); +} + +void QIdentityProxyModelPrivate::_q_sourceRowsRemoved(const QModelIndex &parent, int start, int end) +{ + Q_ASSERT(parent.isValid() ? parent.model() == model : true); + Q_Q(QIdentityProxyModel); + Q_UNUSED(parent) + Q_UNUSED(start) + Q_UNUSED(end) + q->endRemoveRows(); +} + +QT_END_NAMESPACE + +#include "moc_qidentityproxymodel.cpp" + +#endif // QT_NO_IDENTITYPROXYMODEL diff --git a/src/gui/itemviews/qidentityproxymodel.h b/src/gui/itemviews/qidentityproxymodel.h new file mode 100644 index 0000000..4b3176a --- /dev/null +++ b/src/gui/itemviews/qidentityproxymodel.h @@ -0,0 +1,120 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> +** 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 QIDENTITYPROXYMODEL_H +#define QIDENTITYPROXYMODEL_H + +#include <QtGui/qabstractproxymodel.h> + +#ifndef QT_NO_IDENTITYPROXYMODEL + +QT_BEGIN_HEADER + +QT_BEGIN_NAMESPACE + +QT_MODULE(Gui) + +class QIdentityProxyModelPrivate; + +class Q_GUI_EXPORT QIdentityProxyModel : public QAbstractProxyModel +{ + Q_OBJECT +public: + explicit QIdentityProxyModel(QObject* parent = 0); + ~QIdentityProxyModel(); + + int columnCount(const QModelIndex& parent = QModelIndex()) const; + QModelIndex index(int row, int column, const QModelIndex& parent = QModelIndex()) const; + QModelIndex mapFromSource(const QModelIndex& sourceIndex) const; + QModelIndex mapToSource(const QModelIndex& proxyIndex) const; + QModelIndex parent(const QModelIndex& child) const; + int rowCount(const QModelIndex& parent = QModelIndex()) const; + bool dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent); + + QItemSelection mapSelectionFromSource(const QItemSelection& selection) const; + QItemSelection mapSelectionToSource(const QItemSelection& selection) const; + QModelIndexList match(const QModelIndex& start, int role, const QVariant& value, int hits = 1, Qt::MatchFlags flags = Qt::MatchFlags(Qt::MatchStartsWith|Qt::MatchWrap)) const; + void setSourceModel(QAbstractItemModel* sourceModel); + + bool insertColumns(int column, int count, const QModelIndex& parent = QModelIndex()); + bool insertRows(int row, int count, const QModelIndex& parent = QModelIndex()); + bool removeColumns(int column, int count, const QModelIndex& parent = QModelIndex()); + bool removeRows(int row, int count, const QModelIndex& parent = QModelIndex()); + +protected: + QIdentityProxyModel(QIdentityProxyModelPrivate &dd, QObject* parent); + +private: + Q_DECLARE_PRIVATE(QIdentityProxyModel) + Q_DISABLE_COPY(QIdentityProxyModel) + + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeInserted(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsInserted(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeRemoved(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsRemoved(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceRowsMoved(QModelIndex,int,int,QModelIndex,int)) + + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeInserted(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsInserted(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeRemoved(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsRemoved(QModelIndex,int,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceColumnsMoved(QModelIndex,int,int,QModelIndex,int)) + + Q_PRIVATE_SLOT(d_func(), void _q_sourceDataChanged(QModelIndex,QModelIndex)) + Q_PRIVATE_SLOT(d_func(), void _q_sourceHeaderDataChanged(Qt::Orientation orientation, int first, int last)) + + Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutAboutToBeChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_sourceLayoutChanged()) + Q_PRIVATE_SLOT(d_func(), void _q_sourceModelAboutToBeReset()) + Q_PRIVATE_SLOT(d_func(), void _q_sourceModelReset()) +}; + +QT_END_NAMESPACE + +QT_END_HEADER + +#endif // QT_NO_IDENTITYPROXYMODEL + +#endif // QIDENTITYPROXYMODEL_H + diff --git a/src/gui/itemviews/qitemselectionmodel.cpp b/src/gui/itemviews/qitemselectionmodel.cpp index 27a4a40..0b64452 100644 --- a/src/gui/itemviews/qitemselectionmodel.cpp +++ b/src/gui/itemviews/qitemselectionmodel.cpp @@ -1145,11 +1145,8 @@ void QItemSelectionModel::clearSelection() Q_D(QItemSelectionModel); if (d->ranges.count() == 0 && d->currentSelection.count() == 0) return; - QItemSelection selection = d->ranges; - selection.merge(d->currentSelection, d->currentCommand); - d->ranges.clear(); - d->currentSelection.clear(); - emit selectionChanged(QItemSelection(), selection); + + select(QItemSelection(), Clear); } diff --git a/src/gui/itemviews/qsortfilterproxymodel.cpp b/src/gui/itemviews/qsortfilterproxymodel.cpp index eb56f56..f73607b 100644 --- a/src/gui/itemviews/qsortfilterproxymodel.cpp +++ b/src/gui/itemviews/qsortfilterproxymodel.cpp @@ -1502,7 +1502,7 @@ void QSortFilterProxyModelPrivate::_q_sourceColumnsRemoved( \l{Model Subclassing Reference}. \sa QAbstractProxyModel, QAbstractItemModel, {Model/View Programming}, - {Basic Sort/Filter Model Example}, {Custom Sort/Filter Model Example} + {Basic Sort/Filter Model Example}, {Custom Sort/Filter Model Example}, QIdentityProxyModel */ /*! diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp index e494ee5..f9e9919 100644 --- a/src/gui/itemviews/qtableview.cpp +++ b/src/gui/itemviews/qtableview.cpp @@ -1102,6 +1102,21 @@ void QTableView::setRootIndex(const QModelIndex &index) } /*! + \internal +*/ +void QTableView::doItemsLayout() +{ + Q_D(QTableView); + QAbstractItemView::doItemsLayout(); + if (verticalScrollMode() == QAbstractItemView::ScrollPerItem) + d->verticalHeader->setOffsetToSectionPosition(verticalScrollBar()->value()); + else + d->verticalHeader->setOffset(verticalScrollBar()->value()); + if (!d->verticalHeader->updatesEnabled()) + d->verticalHeader->setUpdatesEnabled(true); +} + +/*! \reimp */ void QTableView::setSelectionModel(QItemSelectionModel *selectionModel) @@ -1285,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(); @@ -1975,9 +1989,13 @@ QModelIndexList QTableView::selectedIndexes() const previous number of rows is specified by \a oldCount, and the new number of rows is specified by \a newCount. */ -void QTableView::rowCountChanged(int /*oldCount*/, int /*newCount*/ ) +void QTableView::rowCountChanged(int oldCount, int newCount ) { Q_D(QTableView); + //when removing rows, we need to disable updates for the header until the geometries have been + //updated and the offset has been adjusted, or we risk calling paintSection for all the sections + if (newCount < oldCount) + d->verticalHeader->setUpdatesEnabled(false); d->doDelayedItemsLayout(); } diff --git a/src/gui/itemviews/qtableview.h b/src/gui/itemviews/qtableview.h index d4be086..7ab9d08 100644 --- a/src/gui/itemviews/qtableview.h +++ b/src/gui/itemviews/qtableview.h @@ -71,6 +71,7 @@ public: void setModel(QAbstractItemModel *model); void setRootIndex(const QModelIndex &index); void setSelectionModel(QItemSelectionModel *selectionModel); + void doItemsLayout(); QHeaderView *horizontalHeader() const; QHeaderView *verticalHeader() const; diff --git a/src/gui/kernel/qapplication_mac.mm b/src/gui/kernel/qapplication_mac.mm index f607a72..c0c97e9 100644 --- a/src/gui/kernel/qapplication_mac.mm +++ b/src/gui/kernel/qapplication_mac.mm @@ -2623,8 +2623,6 @@ OSStatus QApplicationPrivate::globalAppleEventProcessor(const AppleEvent *ae, Ap Return true if you want to stop the event from being processed. Return false for normal event dispatching. The default implementation returns false. - - \sa macEventFilter(void *nsevent) */ bool QApplication::macEventFilter(EventHandlerCallRef, EventRef) { diff --git a/src/gui/kernel/qapplication_qpa.cpp b/src/gui/kernel/qapplication_qpa.cpp index b754cf7..8441355 100644 --- a/src/gui/kernel/qapplication_qpa.cpp +++ b/src/gui/kernel/qapplication_qpa.cpp @@ -444,6 +444,9 @@ void QApplication::alert(QWidget *, int) { } +/*! + \internal +*/ QPlatformNativeInterface *QApplication::platformNativeInterface() { QPlatformIntegration *pi = QApplicationPrivate::platformIntegration(); diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp index 0a03397..6658300 100644 --- a/src/gui/kernel/qapplication_win.cpp +++ b/src/gui/kernel/qapplication_win.cpp @@ -2361,8 +2361,13 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa #ifndef QT_NO_ACCESSIBILITY case WM_GETOBJECT: { + /* On Win64, lParam can be 0x00000000fffffffc or 0xfffffffffffffffc (!), + but MSDN says that lParam should be converted to a DWORD + before its compared against OBJID_CLIENT + */ + const DWORD dwObjId = (DWORD)lParam; // Ignoring all requests while starting up - if (QApplication::startingUp() || QApplication::closingDown() || lParam != (LPARAM)OBJID_CLIENT) { + if (QApplication::startingUp() || QApplication::closingDown() || dwObjId != OBJID_CLIENT) { result = false; break; } 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..910b43a 100644 --- a/src/gui/kernel/qevent.cpp +++ b/src/gui/kernel/qevent.cpp @@ -3103,10 +3103,10 @@ QUrl QFileOpenEvent::url() const } /*! - \fn bool openFile(QFile &file, QIODevice::OpenMode flags) const + \fn bool QFileOpenEvent::openFile(QFile &file, QIODevice::OpenMode flags) const - Opens a QFile on the file referenced by this event. - Returns true if successful; otherwise returns false. + Opens a QFile on the \a file referenced by this event in the mode specified + by \a flags. Returns true if successful; otherwise returns false. This is necessary as some files cannot be opened by name, but require specific information stored in this event. diff --git a/src/gui/kernel/qgenericplugin_qpa.cpp b/src/gui/kernel/qgenericplugin_qpa.cpp index 43d6525..17453f3 100644 --- a/src/gui/kernel/qgenericplugin_qpa.cpp +++ b/src/gui/kernel/qgenericplugin_qpa.cpp @@ -53,7 +53,7 @@ QT_BEGIN_NAMESPACE \brief The QGenericPlugin class is an abstract base class for window-system related plugins in Qt QPA. - Note that this class is only available in \l{Qt QPA}. + Note that this class is only available in Qt QPA. A mouse plugin can be created by subclassing QGenericPlugin and reimplementing the pure virtual keys() and diff --git a/src/gui/kernel/qgenericpluginfactory_qpa.cpp b/src/gui/kernel/qgenericpluginfactory_qpa.cpp index abc575a..c77ea11 100644 --- a/src/gui/kernel/qgenericpluginfactory_qpa.cpp +++ b/src/gui/kernel/qgenericpluginfactory_qpa.cpp @@ -65,8 +65,7 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader, \brief The QGenericPluginFactory class creates window-system related plugin drivers in Qt QPA. - Note that this class is only available in \l{Qt QPA}. - + Note that this class is only available in Qt QPA. \sa QGenericPlugin */ 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/qplatformcursor_qpa.cpp b/src/gui/kernel/qplatformcursor_qpa.cpp index 2ea8332..13317b8 100644 --- a/src/gui/kernel/qplatformcursor_qpa.cpp +++ b/src/gui/kernel/qplatformcursor_qpa.cpp @@ -52,48 +52,46 @@ QT_BEGIN_NAMESPACE QList <QWeakPointer<QPlatformCursor> > QPlatformCursorPrivate::instances; /*! - \class QGraphicsSystemCursor + \class QPlatformCursor - \brief The QGraphicsSystemCursor class provides information about + \brief The QPlatformCursor class provides information about pointer device events (movement, buttons), and requests to change the currently displayed cursor. - Note that QGraphicsSystemCursor does not include any graphics for + Note that QPlatformCursor does not include any graphics for display. An application that sets a QCursor may provide its own graphics. - \sa QGraphicsSystemCursorImage + \sa QPlatformCursorImage */ /*! - \fn virtual void QGraphicsSystemCursor::pointerEvent(const QMouseEvent & event) + \fn virtual void QPlatformCursor::pointerEvent(const QMouseEvent & event) This method is called by Qt whenever a QMouseEvent is generated by the underlying pointer input. \a event is a reference to the QMouseEvent in question. A default do-nothing implementation is provided. - - \sa QApplicationPrivate::handleMouseEvent() */ /*! - \fn virtual void QGraphicsSystemCursor::changeCursor(QCursor * widgetCursor, QWidget * widget) + \fn virtual void QPlatformCursor::changeCursor(QCursor * widgetCursor, QWidget * widget) \brief This method is called by Qt whenever the cursor graphic should be changed. - Implementation of this method is mandatory for a subclass of QGraphicsSystemCursor. + Implementation of this method is mandatory for a subclass of QPlatformCursor. \a widgetCursor is a pointer to the QCursor that should be displayed. \a widget is a pointer to the widget currently displayed at QCursor::pos(). Note that this may be 0 if the current position is not occupied by a displayed widget. - \sa QApplicationPrivate::handleMouseEvent(), QCursor::pos() + \sa QCursor::pos() */ /*! - \fn QGraphicsSystemCursor::QGraphicsSystemCursor() + \fn QPlatformCursor::QPlatformCursor(QPlatformScreen *screen) - \brief Constructs a QGraphicsSystemCursor + Constructs a QPlatformCursor for the given \a screen. */ QPlatformCursor::QPlatformCursor(QPlatformScreen *scr ) : screen(scr) @@ -106,12 +104,12 @@ QPlatformCursor::QPlatformCursor(QPlatformScreen *scr ) // from src/gui/embedded/QGraphicsSystemCursorImage_qws.cpp /*! - \class QGraphicsSystemCursorImage + \class QPlatformCursorImage - \brief The QGraphicsSystemCursorImage class provides a set of graphics + \brief The QPlatformCursorImage class provides a set of graphics intended to be used as cursors. - \sa QGraphicsSystemCursor + \sa QPlatformCursor */ static QPlatformCursorImage *systemCursorTable[Qt::LastCursor+1]; @@ -502,7 +500,7 @@ void QPlatformCursorImage::createSystemCursor(int id) } /*! - \fn void QGraphicsSystemCursorImage::set(Qt::CursorShape id) + \fn void QPlatformCursorImage::set(Qt::CursorShape id) \brief Calling this method sets the cursor image to the specified shape @@ -531,15 +529,8 @@ void QPlatformCursorImage::set(Qt::CursorShape id) } /*! - \fn void QGraphicsSystemCursorImage::set(const QImage * image, int hx, int hy) - - \brief Set the cursor image to the specified QImage, with the hotsport at (hx, hy) - - \a image A pointer to a QImage - - \a hx The x coordinate of the cursor's hotspot - - \a hy the y coordinate of the cursor's hotspot + Sets the cursor image to the given \a image, with the hotspot at the + point specified by (\a hx, \a hy). */ void QPlatformCursorImage::set(const QImage &image, int hx, int hy) @@ -550,22 +541,19 @@ void QPlatformCursorImage::set(const QImage &image, int hx, int hy) } /*! - \fn void QGraphicsSystemCursorImage::set(const uchar *data, const uchar *mask, int width, int height, int hx, int hy) - - \brief set the cursor image to the graphic represented by the combination of data, mask, - width, and height - - \a data The pixel data of the graphic - - \a mask Mask data for the graphic. pixels in data with a corresponding mask bit of 0 are not drawn + \fn void QPlatformCursorImage::set(const uchar *data, const uchar *mask, int width, int height, int hx, int hy) - \a width The width of the graphic in pixels + Sets the cursor image to the graphic represented by the combination of + \a data and \a mask, with dimensions given by \a width and \a height and a + hotspot at the point specified by (\a hx, \a hy). - \a height The height of the graphic in pixels + The image data specified by \a data must be supplied in the format + described by QImage::Format_Indexed8. - \a hx The X hotspot of the cursor graphic - - \a hy The Y hotspot of the cursor graphic + The corresponding mask data specified by \a mask must be supplied in a + character array containing packed 1 bit per pixel format data, with any + padding bits at the end of the array. Bits of value 0 represent transparent + pixels in the image data. */ void QPlatformCursorImage::set(const uchar *data, const uchar *mask, int width, int height, int hx, int hy) @@ -625,34 +613,23 @@ void QPlatformCursorImage::set(const uchar *data, const uchar *mask, } /*! - \fn QGraphicsSystemCursorImage::QGraphicsSystemCursorImage(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY) - - \brief set the cursor image to the graphic represented by the combination of data, mask, - width, and height - - \a data The pixel data of the graphic - - \a mask Mask data for the graphic. pixels in data with a corresponding mask bit of 0 are not drawn - - \a width The width of the graphic in pixels - - \a height The height of the graphic in pixels - - \a hotX The X hotspot of the cursor graphic + \fn QPlatformCursorImage::QPlatformCursorImage(const uchar *data, const uchar *mask, int width, int height, int hotX, int hotY) - \a hotY The Y hotspot of the cursor graphic + Sets the cursor image to the graphic represented by the combination of + \a data and \a mask, with dimensions given by \a width and \a height and a + hotspot at the point specified by (\a hotX, \a hotY). - \sa set + \sa set() */ /*! - \fn QImage *QGraphicsSystemCursorImage::image() + \fn QImage *QPlatformCursorImage::image() \brief Return the cursor graphic as a pointer to a QImage */ /*! - \fn QPoint QGraphicsSystemCursorImage::hotspot() + \fn QPoint QPlatformCursorImage::hotspot() \brief Return the cursor's hotspot */ diff --git a/src/gui/kernel/qplatformintegration_qpa.cpp b/src/gui/kernel/qplatformintegration_qpa.cpp index d559c53..fa12518 100644 --- a/src/gui/kernel/qplatformintegration_qpa.cpp +++ b/src/gui/kernel/qplatformintegration_qpa.cpp @@ -132,20 +132,20 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const the recommended approach for making new platform plugin is to copy an existing plugin inside the QTSRCTREE/src/plugins/platform and develop the plugin inside the source tree. - The minimal platformintegration is the smallest platform integration it is possible to make, + The minimal platform integration is the smallest platform integration it is possible to make, which makes it an ideal starting point for new plugins. For a slightly more advanced plugin, consider reviewing the directfb plugin, or the testlite plugin. */ /*! - \fn QPixmapData *createPixmapData(QPixmapData::PixelType type) const + \fn QPixmapData *QPlatformIntegration::createPixmapData(QPixmapData::PixelType type) const Factory function for QPixmapData. PixelType can be either PixmapType or BitmapType. \sa QPixmapData */ /*! - \fn QPlatformWindow *createPlatformWindow(QWidget *widget, WId winId = 0) const + \fn QPlatformWindow *QPlatformIntegration::createPlatformWindow(QWidget *widget, WId winId = 0) const Factory function for QPlatformWindow. The widget parameter is a pointer to the top level widget(tlw) which the QPlatformWindow is suppose to be created for. The WId handle is actually @@ -162,7 +162,7 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const */ /*! - \fn QWindowSurface *createWindowSurface(QWidget *widget, WId winId) const + \fn QWindowSurface *QPlatformIntegration::createWindowSurface(QWidget *widget, WId winId) const Factory function for QWindowSurface. The QWidget parameter is a pointer to the top level widget(tlw) the window surface is created for. A QPlatformWindow is always created @@ -175,7 +175,7 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const */ /*! - \fn void moveToScreen(QWidget *window, int screen) + \fn void QPlatformIntegration::moveToScreen(QWidget *window, int screen) This function is called when a QWidget is displayed on screen, or the QWidget is to be displayed on a new screen. The QWidget parameter is a pointer to the top level widget and @@ -187,14 +187,14 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const */ /*! - \fn QList<QPlatformScreen *> screens() const + \fn QList<QPlatformScreen *> QPlatformIntegration::screens() const Accessor function to a list of all the screens on the current system. The screen with the index == 0 is the default/main screen. */ /*! - \fn bool isVirtualDesktop() + \fn bool QPlatformIntegration::isVirtualDesktop() Returns if the current windowing system configuration defines all the screens to be one desktop(virtual desktop), or if each screen is a desktop of its own. @@ -203,7 +203,7 @@ QPlatformNativeInterface * QPlatformIntegration::nativeInterface() const */ /*! - \fn QPixmap grabWindow(WId window, int x, int y, int width, int height) const + \fn QPixmap QPlatformIntegration::grabWindow(WId window, int x, int y, int width, int height) const This function is called when Qt needs to be able to grab the content of a window. @@ -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/qplatformscreen_qpa.cpp b/src/gui/kernel/qplatformscreen_qpa.cpp index c9f3dc6..806fa4b 100644 --- a/src/gui/kernel/qplatformscreen_qpa.cpp +++ b/src/gui/kernel/qplatformscreen_qpa.cpp @@ -66,12 +66,15 @@ QWidget *QPlatformScreen::topLevelAt(const QPoint & pos) const return 0; } -/*! \fn physicalSize() const - Reimplement in subclass to return the physical size of the screen. This function is used by - QFont to convert point sizes to pixel sizes. - - Default implementation takes the pixel size of the screen, considers a dpi of 100 and returns - the calculated (and probably wrong) physical size +/*! + Reimplement this function in subclass to return the physical size of the + screen. This function is used by QFont to convert point sizes to pixel + sizes. + + The default implementation takes the pixel size of the screen, considers a + resolution of 100 dots per inch, and returns the calculated physical size. + A device with a screen that has different resolutions will need to be + supported by a suitable reimplementation of this function. */ QSize QPlatformScreen::physicalSize() const { @@ -110,20 +113,20 @@ QPlatformScreen * QPlatformScreen::platformScreenForWidget(const QWidget *widget QPlatformScreen is also used by the public api QDesktopWidget for information about the desktop. */ -/*! \fn geometry() const +/*! \fn QRect QPlatformScreen::geometry() const = 0 Reimplement in subclass to return the pixel geometry of the screen */ -/*! \fn availableGeometry() const +/*! \fn QRect QPlatformScreen::availableGeometry() const Reimplement in subclass to return the pixel geometry of the available space This normally is the desktop screen minus the task manager, global menubar etc. */ -/*! \fn depth() const +/*! \fn int QPlatformScreen::depth() const = 0 Reimplement in subclass to return current depth of the screen */ -/*! \fn format() const +/*! \fn QImage::Format QPlatformScreen::format() const = 0 Reimplement in subclass to return the image format which corresponds to the screen format */ 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/qplatformwindowformat_qpa.cpp b/src/gui/kernel/qplatformwindowformat_qpa.cpp index c165c85..1a4c97e 100644 --- a/src/gui/kernel/qplatformwindowformat_qpa.cpp +++ b/src/gui/kernel/qplatformwindowformat_qpa.cpp @@ -122,8 +122,6 @@ public: \i \link setStencil() Stencil buffer.\endlink \i \link setStereo() Stereo buffers.\endlink \i \link setDirectRendering() Direct rendering.\endlink - \i \link setOverlay() Presence of an overlay.\endlink - \i \link setPlane() Plane of an overlay.\endlink \i \link setSampleBuffers() Multisample buffers.\endlink \endlist @@ -168,7 +166,7 @@ public: United States and other countries. \endlegalese - \sa QPlatformContext, QWidget + \sa QPlatformGLContext, QWidget */ /*! @@ -182,8 +180,6 @@ public: \i \link setStencil() Stencil buffer:\endlink Enabled. \i \link setStereo() Stereo:\endlink Disabled. \i \link setDirectRendering() Direct rendering:\endlink Enabled. - \i \link setOverlay() Overlay:\endlink Disabled. - \i \link setPlane() Plane:\endlink 0 (i.e., normal plane). \i \link setSampleBuffers() Multisample buffers:\endlink Disabled. \endlist */ @@ -207,14 +203,10 @@ QPlatformWindowFormat::QPlatformWindowFormat() \snippet doc/src/snippets/code/src_opengl_qgl.cpp 3 Note that there are QGL::FormatOption values to turn format settings - both on and off, e.g. QGL::DepthBuffer and QGL::NoDepthBuffer, + both on and off; e.g., QGL::DepthBuffer and QGL::NoDepthBuffer, QGL::DirectRendering and QGL::IndirectRendering, etc. - The \a plane parameter defaults to 0 and is the plane which this - format should be associated with. Not all OpenGL implementations - supports overlay/underlay rendering planes. - - \sa defaultFormat(), setOption(), setPlane() + \sa defaultFormat(), setOption() */ QPlatformWindowFormat::QPlatformWindowFormat(QPlatformWindowFormat::FormatOptions options) @@ -619,8 +611,6 @@ QPlatformGLContext *QPlatformWindowFormat::sharedGLContext() const Otherwise returns false. WindowSurface is enabled by default. - - \sa setOverlay() */ /*! @@ -628,9 +618,7 @@ QPlatformGLContext *QPlatformWindowFormat::sharedGLContext() const otherwise the QWidget will only have a QPlatformWindow. - This is useful for ie. QGLWidget where the QPlatformGLContext controls the surface. - - \sa hasOverlay() + This is useful for QGLWidget where the QPlatformGLContext controls the surface. */ void QPlatformWindowFormat::setWindowSurface(bool enable) @@ -894,7 +882,7 @@ void QPlatformWindowFormat::setDefaultFormat(const QPlatformWindowFormat &f) } -/*! +/* Returns the default QPlatformWindowFormat for overlay contexts. The default overlay format is: @@ -907,9 +895,7 @@ void QPlatformWindowFormat::setDefaultFormat(const QPlatformWindowFormat &f) \i \link setStencil() Stencil buffer:\endlink Disabled. \i \link setStereo() Stereo:\endlink Disabled. \i \link setDirectRendering() Direct rendering:\endlink Enabled. - \i \link setOverlay() Overlay:\endlink Disabled. \i \link setSampleBuffers() Multisample buffers:\endlink Disabled. - \i \link setPlane() Plane:\endlink 1 (i.e., first overlay plane). \endlist \sa setDefaultFormat() 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/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 2884f75..80d7b85 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -1588,6 +1588,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); @@ -11205,6 +11206,7 @@ void QWidget::setAccessibleName(const QString &name) { Q_D(QWidget); d->accessibleName = name; + QAccessible::updateAccessibility(this, 0, QAccessible::NameChanged); } QString QWidget::accessibleName() const @@ -11226,6 +11228,7 @@ void QWidget::setAccessibleDescription(const QString &description) { Q_D(QWidget); d->accessibleDescription = description; + QAccessible::updateAccessibility(this, 0, QAccessible::DescriptionChanged); } QString QWidget::accessibleDescription() const diff --git a/src/gui/kernel/qwidget_qpa.cpp b/src/gui/kernel/qwidget_qpa.cpp index 001810e..321eaa3 100644 --- a/src/gui/kernel/qwidget_qpa.cpp +++ b/src/gui/kernel/qwidget_qpa.cpp @@ -681,8 +681,10 @@ int QWidget::metric(PaintDeviceMetric m) const /*! \preliminary - Sets the window to be the \a window specified. - The QWidget takes ownership of the \a surface. + Sets the window to be the platform \a window specified. + + The widget takes ownership of the \a window. Any platform window + previously set on the widget will be destroyed. */ void QWidget::setPlatformWindow(QPlatformWindow *window) { @@ -711,6 +713,9 @@ QPlatformWindow *QWidget::platformWindow() const return 0; } +/*! + Sets the platform window format for the widget to the \a format specified. +*/ void QWidget::setPlatformWindowFormat(const QPlatformWindowFormat &format) { if (isWindow() || testAttribute(Qt::WA_NativeWindow)) { @@ -727,6 +732,9 @@ void QWidget::setPlatformWindowFormat(const QPlatformWindowFormat &format) } } +/*! + Returns the platform window format for the widget. +*/ QPlatformWindowFormat QWidget::platformWindowFormat() const { Q_D(const QWidget); diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 5ece7d6..241a13f 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(); diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index bf5764a..60297e6 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 + \a center point and \a radius, it will be re-adjusted to lie at a point on + the circle where it intersects with the line from \a center to + \a focalPoint. + \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,49 @@ 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 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 +2007,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 +2024,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 +2338,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/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index 5e75e4a..ae9993e 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; + v->dr = data->gradient.radial.center.radius - data->gradient.radial.focal.radius; + v->sqrfr = data->gradient.radial.focal.radius * data->gradient.radial.focal.radius; - const qreal bb = b * b; - const qreal delta_bb = delta_b * delta_b; + v->a = v->dr * v->dr - v->dx*v->dx - v->dy*v->dy; + v->inv2a = 1 / (2 * v->a); - 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; + v->extended = !qFuzzyIsNull(data->gradient.radial.focal.radius) || v->a <= 0; +} - 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; +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); + } - while (buffer < end) { - *buffer = qt_gradient_pixel(&data->gradient, qSafeSqrt(det) - b); + *buffer = result; - det += delta_det; - delta_det += delta_delta_det; - b += delta_b; + det += delta_det; + delta_det += delta_delta_det; + b += delta_b; - ++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)); - - *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]; @@ -7888,6 +7758,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 +7858,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/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp index 7870def..51171c5 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: { diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index 6eb09e5..35478f8 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -387,6 +387,7 @@ void QPaintEngine::drawPolygon(const QPoint *points, int pointCount, PolygonDraw \value MaxUser Last user type ID \value OpenGL2 \value PaintBuffer + \value Blitter */ /*! 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 bef6b7d..9e28102 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -98,10 +98,10 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QTextItem::RenderFlags flags, qreal width, const QTextCharFormat &charFormat); // Helper function to calculate left most position, width and flags for decoration drawing -static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray, - const QFixedPoint *positions, int glyphCount, - QFontEngine *fontEngine, const QFont &font, - const QTextCharFormat &charFormat); +Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray, + const QFixedPoint *positions, int glyphCount, + QFontEngine *fontEngine, const QFont &font, + const QTextCharFormat &charFormat); static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush) { @@ -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(); } +extern 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; @@ -5809,7 +5818,7 @@ 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()); for (int i=0; i<count; ++i) { QPointF processedPosition = position + glyphPositions.at(i); if (!paintEngineSupportsTransformations) @@ -6060,9 +6069,9 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText } d->extended->drawStaticTextItem(item); - drawDecorationForGlyphs(this, item->glyphs, item->glyphPositions, - item->numGlyphs, item->fontEngine(), staticText_d->font, - QTextCharFormat()); + qt_draw_decoration_for_glyphs(this, item->glyphs, item->glyphPositions, + item->numGlyphs, item->fontEngine(), staticText_d->font, + QTextCharFormat()); } if (currentColor != oldPen.color()) setPen(oldPen); @@ -6507,10 +6516,10 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const painter->setBrush(oldBrush); } -static void drawDecorationForGlyphs(QPainter *painter, const glyph_t *glyphArray, - const QFixedPoint *positions, int glyphCount, - QFontEngine *fontEngine, const QFont &font, - const QTextCharFormat &charFormat) +Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray, + const QFixedPoint *positions, int glyphCount, + QFontEngine *fontEngine, const QFont &font, + const QTextCharFormat &charFormat) { if (!(font.underline() || font.strikeOut() || font.overline())) return; diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index 4b2c447..1a432e6 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -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/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/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 8f99d6a..95ebdb4 100644 --- a/src/gui/styles/qcommonstyle.cpp +++ b/src/gui/styles/qcommonstyle.cpp @@ -223,16 +223,13 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q --yy; } if (!(opt->state & State_Enabled) && !(opt->state & State_On)) { - int pnt; - p->setPen(opt->palette.highlightedText().color()); - QPoint offset(1, 1); - for (pnt = 0; pnt < a.size(); ++pnt) - a[pnt].translate(offset.x(), offset.y()); + p->save(); + p->translate(1, 1); + p->setPen(opt->palette.light().color()); p->drawLines(a); - for (pnt = 0; pnt < a.size(); ++pnt) - a[pnt].translate(offset.x(), offset.y()); + p->restore(); } - p->setPen(opt->palette.text().color()); + p->setPen((opt->state & State_On) ? opt->palette.highlightedText().color() : opt->palette.text().color()); p->drawLines(a); break; } case PE_Frame: @@ -919,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); @@ -936,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/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm index 2d21628..18003ce 100644 --- a/src/gui/styles/qmacstyle_mac.mm +++ b/src/gui/styles/qmacstyle_mac.mm @@ -4707,7 +4707,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex HIThemeFrameDrawInfo fdi; fdi.version = qt_mac_hitheme_version; - fdi.state = kThemeStateInactive; + fdi.state = tds; fdi.kind = kHIThemeFrameTextFieldSquare; fdi.isFocused = false; HIRect hirect = qt_hirectForQRect(lineeditRect); 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 44f3f92..754486e 100644 --- a/src/gui/styles/qwindowsstyle.cpp +++ b/src/gui/styles/qwindowsstyle.cpp @@ -1858,8 +1858,8 @@ void QWindowsStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPai } QRect vCheckRect = visualRect(opt->direction, menuitem->rect, QRect(menuitem->rect.x(), menuitem->rect.y(), checkcol, menuitem->rect.height())); - if (checked) { - if (act && !dis) { + if (!menuitem->icon.isNull() && checked) { + if (act) { qDrawShadePanel(p, vCheckRect, menuitem->palette, true, 1, &menuitem->palette.brush(QPalette::Button)); @@ -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/styles/qwindowsvistastyle.cpp b/src/gui/styles/qwindowsvistastyle.cpp index 7f1a3ab..123741e 100644 --- a/src/gui/styles/qwindowsvistastyle.cpp +++ b/src/gui/styles/qwindowsvistastyle.cpp @@ -969,7 +969,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption if (const QStyleOptionButton *btn = qstyleoption_cast<const QStyleOptionButton *>(option)) { - if (QWindowsVistaAnimation *anim = d->widgetAnimation(widget)) { + QWindowsVistaAnimation *anim = d->widgetAnimation(widget); + if (anim && (btn->state & State_Enabled)) { anim->paint(painter, option); } else { name = QLatin1String("BUTTON"); @@ -996,7 +997,6 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption !(state & (State_Sunken | State_On)) && !(state & State_MouseOver) && (state & State_Enabled) && (state & State_Active)) { - QWindowsVistaAnimation *anim = d->widgetAnimation(widget); if (!anim && widget) { QImage startImage(option->rect.size(), QImage::Format_ARGB32_Premultiplied); startImage.fill(0); @@ -1074,8 +1074,8 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption } if (const QProgressBar *progressbar = qobject_cast<const QProgressBar *>(widget)) { - if (((progressbar->value() > 0 && d->transitionsEnabled()) || isIndeterminate)) { - if (!d->widgetAnimation(progressbar) && progressbar->value() < progressbar->maximum()) { + if (isIndeterminate || (progressbar->value() > 0 && (progressbar->value() < progressbar->maximum()) && d->transitionsEnabled())) { + if (!d->widgetAnimation(progressbar)) { QWindowsVistaAnimation *a = new QWindowsVistaAnimation; a->setWidget(const_cast<QWidget*>(widget)); a->setStartTime(QTime::currentTime()); @@ -2502,7 +2502,6 @@ void QWindowsVistaStylePrivate::timerEvent() animations[i]->widget()->update(); if (!animations[i]->widget() || - !animations[i]->widget()->isEnabled() || !animations[i]->widget()->isVisible() || animations[i]->widget()->window()->isMinimized() || !animations[i]->running() || diff --git a/src/gui/styles/qwindowsxpstyle.cpp b/src/gui/styles/qwindowsxpstyle.cpp index 74a20fc..4b2c3a5 100644 --- a/src/gui/styles/qwindowsxpstyle.cpp +++ b/src/gui/styles/qwindowsxpstyle.cpp @@ -1196,8 +1196,14 @@ QRect QWindowsXPStyle::subElementRect(SubElement sr, const QStyleOption *option, if (qstyleoption_cast<const QStyleOptionTabWidgetFrame *>(option)) { rect = QWindowsStyle::subElementRect(sr, option, widget); - if (sr == SE_TabWidgetTabContents) - rect.adjust(0, 0, -2, -2); + if (sr == SE_TabWidgetTabContents) { + if (const QTabWidget *tabWidget = qobject_cast<const QTabWidget *>(widget)) { + if (tabWidget->documentMode()) + break; + } + + rect.adjust(0, 0, -2, -2); + } } break; case SE_TabWidgetTabBar: { diff --git a/src/gui/text/qfontengine_coretext.mm b/src/gui/text/qfontengine_coretext.mm index 20b3730..d4df218 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, fontDef); +} + 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..bb80a9b 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,7 +120,8 @@ 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"; } protected: diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 8f2da9b..58bcca8 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -2069,6 +2069,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..6dbca7a 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: 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/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 2ec245e..39b06e2 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -1329,8 +1329,10 @@ bool QFontMetricsF::inFont(QChar ch) const } /*! - Returns true if the character encoded in UCS-4/UTF-32 is a valid - character in the font; otherwise returns false. + \fn bool QFontMetricsF::inFontUcs4(uint ch) const + + Returns true if the character given by \a ch, encoded in UCS-4/UTF-32, + is a valid character in the font; otherwise returns false. */ bool QFontMetricsF::inFontUcs4(uint ucs4) const { diff --git a/src/gui/text/qglyphs.cpp b/src/gui/text/qglyphs.cpp index 7d969f2..cfea6ec 100644 --- a/src/gui/text/qglyphs.cpp +++ b/src/gui/text/qglyphs.cpp @@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE /*! \class QGlyphs - \brief The QGlyphs class provides direct access to the internal glyphs in a font + \brief The QGlyphs class provides direct access to the internal glyphs in a font. \since 4.8 \ingroup text @@ -76,8 +76,8 @@ QT_BEGIN_NAMESPACE 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. - \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 + \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 QGlyphs if it is moved to a different thread. If the QGlyphs 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. diff --git a/src/gui/text/qplatformfontdatabase_qpa.cpp b/src/gui/text/qplatformfontdatabase_qpa.cpp index 9da54b6..dcee335 100644 --- a/src/gui/text/qplatformfontdatabase_qpa.cpp +++ b/src/gui/text/qplatformfontdatabase_qpa.cpp @@ -51,6 +51,13 @@ extern void qt_registerFont(const QString &familyname, const QString &foundrynam QFont::Style style, int stretch, bool antialiased,bool scalable, int pixelSize, const QSupportedWritingSystems &writingSystems, void *hanlde); +/*! + \fn void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *) + + Registers the pre-rendered QPF2 font contained in the given \a dataArray. + + \sa registerFont() +*/ void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void *handle) { if (dataArray.size() == 0) @@ -88,6 +95,32 @@ void QPlatformFontDatabase::registerQPF2Font(const QByteArray &dataArray, void * } } +/*! + \fn void QPlatformFontDatabase::registerFont(const QString &familyName, + const QString &foundryName, QFont::Weight weight, QFont::Style style, + QFont::Stretch stretch, bool antialiased, bool scalable, int pixelSize, + const QSupportedWritingSystems &writingSystems, void *usrPtr) + + Registers a font with the given set of attributes describing the font's + foundry, family name, style and stretch information, pixel size, and + supported writing systems. Additional information about whether the font + can be scaled and antialiased can also be provided. + + The foundry name and font family are described by \a foundryName and + \a familyName. The font weight (light, normal, bold, etc.), style (normal, + oblique, italic) and stretch information (condensed, expanded, unstretched, + etc.) are specified by \a weight, \a style and \a stretch. + + Some fonts can be antialiased and scaled; \a scalable and \a antialiased + can be set to true for fonts with these attributes. The intended pixel + size of non-scalable fonts is specified by \a pixelSize; this value will be + ignored for scalable fonts. + + The writing systems supported by the font are specified by the + \a writingSystems argument. + + \sa registerQPF2Font() +*/ void QPlatformFontDatabase::registerFont(const QString &familyname, const QString &foundryname, QFont::Weight weight, QFont::Style style, QFont::Stretch stretch, bool antialiased, bool scalable, int pixelSize, const QSupportedWritingSystems &writingSystems, void *usrPtr) @@ -219,6 +252,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; +} + /*! Returns a list of alternative fonts for the specified \a family and \a style and \a script using the \a styleHint given. @@ -233,10 +276,13 @@ QStringList QPlatformFontDatabase::fallbacksForFamily(const QString family, cons } /*! - Adds an application font described by the given \a fontData that can be - referenced using the specified \a fontName, which is the name for the font - family. Returns a list of family names, or an empty list if the font could - not be added + Adds an application font described by the font contained supplied \a fontData + or using the font contained in the file referenced by \a fileName. Returns + a list of family names, or an empty list if the font could not be added. + + \note The default implementation of this function does not add an application + font. Subclasses should reimplement this function to perform the necessary + loading and registration of fonts. */ QStringList QPlatformFontDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName) { 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..10112d5 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -87,16 +87,16 @@ 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 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. - \o \l It can be constructed by passing a file name or QByteArray directly to the QRawFont - constructor, or by calling loadFromFile() or loadFromData(). In this case, the - font will not be registered in QFontDatabase, and it will not be available as part of - regular font selection. + \o 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 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. + \o It can be constructed by passing a file name or QByteArray directly to the QRawFont + constructor, or by calling loadFromFile() or loadFromData(). In this case, the + font will not be registered in QFontDatabase, and it will not be available as part of + regular font selection. \endlist QRawFont is considered local to the thread in which it is constructed (either using a @@ -132,8 +132,9 @@ QRawFont::QRawFont() } /*! - Constructs a QRawFont representing the font contained in the file referenced by \a fileName, - with \a pixelSize size in pixels, and the selected \a hintingPreference. + Constructs a QRawFont representing the font contained in the file referenced + by \a fileName for the size (in pixels) given by \a pixelSize, and using the + hinting preference specified by \a hintingPreference. \note The referenced file must contain a TrueType or OpenType font. */ @@ -146,7 +147,9 @@ QRawFont::QRawFont(const QString &fileName, } /*! - Constructs a QRawFont representing the font contained in \a fontData. + Constructs a QRawFont representing the font contained in the supplied + \a fontData for the size (in pixels) given by \a pixelSize, and using the + hinting preference specified by \a hintingPreference. \note The data must contain a TrueType or OpenType font. */ @@ -192,7 +195,9 @@ bool QRawFont::isValid() const } /*! - Replaces the current QRawFont with the contents of the file references by \a fileName. + Replaces the current QRawFont with the contents of the file referenced + by \a fileName for the size (in pixels) given by \a pixelSize, and using the + hinting preference specified by \a hintingPreference. The file must reference a TrueType or OpenType font. @@ -208,7 +213,9 @@ void QRawFont::loadFromFile(const QString &fileName, } /*! - Replaces the current QRawFont with the contents of \a fontData. + Replaces the current QRawFont with the font contained in the supplied + \a fontData for the size (in pixels) given by \a pixelSize, and using the + hinting preference specified by \a hintingPreference. The \a fontData must contain a TrueType or OpenType font. @@ -226,8 +233,9 @@ void QRawFont::loadFromData(const QByteArray &fontData, } /*! - This function returns a rasterized image of the glyph at a given \a glyphIndex in the underlying - font, if the QRawFont is valid, otherwise it will return an invalid QImage. + This function returns a rasterized image of the glyph at the given + \a glyphIndex in the underlying font, using the \a transform specified. + If the QRawFont is not valid, this function will return an invalid QImage. If \a antialiasingType is set to QRawFont::SubPixelAntialiasing, then the resulting image will be in QImage::Format_RGB32 and the RGB values of each pixel will represent the subpixel opacities of @@ -370,11 +378,15 @@ int QRawFont::weight() const } /*! - Converts a string of unicode points to glyph indexes using the CMAP table in the - 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. + Converts the string of unicode points given by \a text to glyph indexes + using the CMAP table in the underlying font, and returns a vector containing + the result. + + 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, then call QTextLayout::glyphs() + to get the set of glyph index list and QRawFont pairs. \sa advancesForGlyphIndexes(), QGlyphs, QTextLayout::glyphs(), QTextFragment::glyphs() */ @@ -579,8 +591,19 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ */ void QRawFont::setPixelSize(int 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_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/text/qrawfont_qpa.cpp b/src/gui/text/qrawfont_qpa.cpp new file mode 100644 index 0000000..103619c --- /dev/null +++ b/src/gui/text/qrawfont_qpa.cpp @@ -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 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 <QtCore/qglobal.h> + +#if !defined(QT_NO_RAWFONT) + +#include "qrawfont_p.h" +#include <QtGui/qplatformfontdatabase_qpa.h> +#include <private/qapplication_p.h> + +QT_BEGIN_NAMESPACE + +void QRawFontPrivate::platformCleanUp() +{ +} + +void QRawFontPrivate::platformLoadFromData(const QByteArray &fontData, int pixelSize, + QFont::HintingPreference hintingPreference) +{ + Q_ASSERT(fontEngine == 0); + + QPlatformFontDatabase *pfdb = QApplicationPrivate::platformIntegration()->fontDatabase(); + fontEngine = pfdb->fontEngine(fontData, pixelSize, hintingPreference); + if (fontEngine != 0) + fontEngine->ref.ref(); +} + +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 faf4e77..4396730 100644 --- a/src/gui/text/qtextcontrol.cpp +++ b/src/gui/text/qtextcontrol.cpp @@ -1519,7 +1519,7 @@ void QTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton button, con const QTextCursor oldSelection = cursor; const int oldCursorPos = cursor.position(); - mousePressed = true; + mousePressed = (interactionFlags & Qt::TextSelectableByMouse); #ifndef QT_NO_DRAGANDDROP mightStartDrag = false; #endif @@ -1608,13 +1608,11 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons if (!(buttons & Qt::LeftButton)) return; - const bool selectable = interactionFlags & Qt::TextSelectableByMouse; const bool editable = interactionFlags & Qt::TextEditable; - if (!selectable && !editable) - return; - if (!(mousePressed + || editable + || mightStartDrag || selectedWordOnDoubleClick.hasSelection() || selectedBlockOnTrippleClick.hasSelection())) return; @@ -1628,7 +1626,7 @@ void QTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button, cons return; } - if (!selectable) + if (!mousePressed) return; const qreal mouseX = qreal(mousePos.x()); @@ -1696,10 +1694,8 @@ void QTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton button, c if (mousePressed) { mousePressed = false; #ifndef QT_NO_CLIPBOARD - if (interactionFlags & Qt::TextSelectableByMouse) { - setClipboardSelection(); - selectionChanged(true); - } + setClipboardSelection(); + selectionChanged(true); } else if (button == Qt::MidButton && (interactionFlags & Qt::TextEditable) && QApplication::clipboard()->supportsSelection()) { diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index 6ddfdb0..4f6857a 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 == QTextCursor::Visual; 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 QTextCursor::MoveStyle + + This enum describes the movement style available to QTextCursor. The options + are: + + \value Logical Within a left-to-right 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. + \value Visual 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. +*/ + QT_END_NAMESPACE diff --git a/src/gui/text/qtextcursor.h b/src/gui/text/qtextcursor.h index 4eaeb41..9e4c0b8 100644 --- a/src/gui/text/qtextcursor.h +++ b/src/gui/text/qtextcursor.h @@ -86,6 +86,10 @@ public: MoveAnchor, KeepAnchor }; + enum MoveStyle { + Logical, + Visual + }; void setPosition(int pos, MoveMode mode = MoveAnchor); int position() const; diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index 6dbd755..194058d 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 QTextCursor::Logical. +*/ +QTextCursor::MoveStyle QTextDocument::defaultCursorMoveStyle() const +{ + Q_D(const QTextDocument); + return d->defaultCursorMoveStyle; +} + +/*! + \since 4.8 + + Sets the default cursor movement style to the given \a style. +*/ +void QTextDocument::setDefaultCursorMoveStyle(QTextCursor::MoveStyle 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 diff --git a/src/gui/text/qtextdocument.h b/src/gui/text/qtextdocument.h index f87ccc9..e515b36 100644 --- a/src/gui/text/qtextdocument.h +++ b/src/gui/text/qtextdocument.h @@ -46,6 +46,7 @@ #include <QtCore/qsize.h> #include <QtCore/qrect.h> #include <QtGui/qfont.h> +#include <QtGui/qtextcursor.h> QT_BEGIN_HEADER @@ -60,7 +61,6 @@ class QPainter; class QPrinter; class QAbstractTextDocumentLayout; class QPoint; -class QTextCursor; class QTextObject; class QTextFormat; class QTextFrame; @@ -269,6 +269,9 @@ public: QTextOption defaultTextOption() const; void setDefaultTextOption(const QTextOption &option); + QTextCursor::MoveStyle defaultCursorMoveStyle() const; + void setDefaultCursorMoveStyle(QTextCursor::MoveStyle 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..779b1ff 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 = QTextCursor::Logical; 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..6563920 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; + QTextCursor::MoveStyle 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..c476485 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 == QTextCursor::Visual : 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.cpp b/src/gui/text/qtextformat.cpp index c4b75c1..d0c89d8 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -1270,16 +1270,18 @@ bool QTextFormat::operator==(const QTextFormat &rhs) const \value AlignNormal Adjacent characters are positioned in the standard way for text in the writing system in use. - \value AlignSuperScript Characters are placed above the baseline for + \value AlignSuperScript Characters are placed above the base line for normal text. - \value AlignSubScript Characters are placed below the baseline for + \value AlignSubScript Characters are placed below the base line for normal text. - \value AlignMiddle The center of the object is vertically aligned with the base line. - Currently, this is only implemented for inline objects. + \value AlignMiddle The center of the object is vertically aligned with the + base line. Currently, this is only implemented for + inline objects. \value AlignBottom The bottom edge of the object is vertically aligned with the base line. \value AlignTop The top edge of the object is vertically aligned with the base line. + \value AlignBaseline The base lines of the characters are aligned. */ /*! @@ -2143,8 +2145,9 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const \fn void QTextBlockFormat::setLineHeight(qreal height, int heightType) \since 4.8 - This sets the line height for the paragraph to the value in height - which is dependant on heightType, described by the LineHeightTypes enum. + Sets the line height for the paragraph to the value given by \a height + which is dependent on \a heightType in the way described by the + LineHeightTypes enum. \sa LineHeightTypes, lineHeight(), lineHeightType() */ @@ -2154,11 +2157,16 @@ QList<QTextOption::Tab> QTextBlockFormat::tabPositions() const \fn qreal QTextBlockFormat::lineHeight(qreal scriptLineHeight, qreal scaling) const \since 4.8 - This returns what the height of the lines in the paragraph will be depending - on the given height of the script line and the scaling. The value that is returned - is also dependant on the given LineHeightType of the paragraph as well as the LineHeight - setting that has been set for the paragraph. The scaling is needed for the heights - that include a fixed number of pixels, to scale them appropriately for printing. + Returns the height of the lines in the paragraph based on the height of the + script line given by \a scriptLineHeight and the specified \a scaling + factor. + + The value that is returned is also dependent on the given LineHeightType of + the paragraph as well as the LineHeight setting that has been set for the + paragraph. + + The scaling is needed for heights that include a fixed number of pixels, to + scale them appropriately for printing. \sa LineHeightTypes, setLineHeight(), lineHeightType() */ 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..557fa68 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -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 visual cursor movement style to the given \a 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 QTextCursor::Logical. + + \sa cursorMoveStyle() +*/ +void QTextLayout::setCursorMoveStyle(QTextCursor::MoveStyle style) +{ + d->visualMovement = style == QTextCursor::Visual ? true : false; +} + +/*! + The cursor movement style of this QTextLayout. The default is + QTextCursor::Logical. + + \sa setCursorMoveStyle() +*/ +QTextCursor::MoveStyle QTextLayout::cursorMoveStyle() const +{ + return d->visualMovement ? QTextCursor::Visual : QTextCursor::Logical; +} + +/*! 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) { @@ -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) @@ -2632,9 +2462,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 +2551,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 +2592,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 +2611,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 +2620,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 +2637,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 +2673,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 +2718,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..6aa81f9 100644 --- a/src/gui/text/qtextlayout.h +++ b/src/gui/text/qtextlayout.h @@ -50,6 +50,7 @@ #include <QtGui/qevent.h> #include <QtGui/qtextformat.h> #include <QtGui/qglyphs.h> +#include <QtGui/qtextcursor.h> QT_BEGIN_HEADER @@ -136,6 +137,9 @@ public: void setCacheEnabled(bool enable); bool cacheEnabled() const; + void setCursorMoveStyle(QTextCursor::MoveStyle style); + QTextCursor::MoveStyle 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; diff --git a/src/gui/text/text.pri b/src/gui/text/text.pri index df9398c..e5d57d0 100644 --- a/src/gui/text/text.pri +++ b/src/gui/text/text.pri @@ -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 index fdd2a95..f87c84c 100644 --- a/src/gui/util/qflickgesture.cpp +++ b/src/gui/util/qflickgesture.cpp @@ -218,10 +218,10 @@ public: 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) { + /* Qt::MouseButtons mouseButtons = QApplication::mouseButtons(); + for (int i = 0; i < 32; ++i) { if (mouseButtons & (1 << i)) { Qt::MouseButton b = static_cast<Qt::MouseButton>(1 << i); mouseButtons &= ~b; diff --git a/src/gui/util/qscroller.cpp b/src/gui/util/qscroller.cpp index 3a8c364..8f2212d 100644 --- a/src/gui/util/qscroller.cpp +++ b/src/gui/util/qscroller.cpp @@ -1777,10 +1777,7 @@ void QScrollerPrivate::setState(QScroller::State newstate) */ 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; 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 289faa9..4fb0f0c 100644 --- a/src/gui/widgets/qlinecontrol.cpp +++ b/src/gui/widgets/qlinecontrol.cpp @@ -651,7 +651,12 @@ void QLineControl::internalSetText(const QString &txt, int pos, bool edited) m_modifiedState = m_undoState = 0; m_cursor = (pos < 0 || pos > m_text.length()) ? m_text.length() : pos; m_textDirty = (oldText != m_text); - finishChange(-1, true, edited); + bool changed = finishChange(-1, true, edited); + +#ifndef QT_NO_ACCESSIBILITY + if (changed) + QAccessible::updateAccessibility(parent(), 0, QAccessible::TextUpdated); +#endif } @@ -1238,6 +1243,9 @@ void QLineControl::emitCursorPositionChanged() const int oldLast = m_lastCursorPos; m_lastCursorPos = m_cursor; cursorPositionChanged(oldLast, m_cursor); +#ifndef QT_NO_ACCESSIBILITY + QAccessible::updateAccessibility(parent(), 0, QAccessible::TextCaretMoved); +#endif } } @@ -1585,6 +1593,7 @@ void QLineControl::processKeyEvent(QKeyEvent* event) } bool unknown = false; + bool visual = cursorMoveStyle() == QTextCursor::Visual; if (false) { } @@ -1649,11 +1658,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) @@ -1664,11 +1673,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 3c505c8..0655276 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -61,10 +61,10 @@ #include "QtGui/qtextlayout.h" #include "QtGui/qstyleoption.h" #include "QtCore/qpointer.h" -#include "QtGui/qlineedit.h" #include "QtGui/qclipboard.h" #include "QtCore/qpoint.h" #include "QtGui/qcompleter.h" +#include "QtGui/qaccessible.h" QT_BEGIN_HEADER @@ -160,6 +160,8 @@ public: int cursorWidth() const { return m_cursorWidth; } void setCursorWidth(int value) { m_cursorWidth = value; } + QTextCursor::MoveStyle cursorMoveStyle() const { return m_textLayout.cursorMoveStyle(); } + void setCursorMoveStyle(QTextCursor::MoveStyle 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() == QTextCursor::Visual ? m_textLayout.rightCursorPosition(c) + : m_textLayout.nextCursorPosition(c); } else if (steps < 0) { while (steps++) - c = m_textLayout.previousCursorPosition(c); + c = cursorMoveStyle() == QTextCursor::Visual ? 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..3672047 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1112,6 +1112,41 @@ 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 QTextCursor::Visual, 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 QTextCursor::Logical (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. +*/ + +/*! + Returns the movement style for the cursor in the line edit. +*/ +QTextCursor::MoveStyle QLineEdit::cursorMoveStyle() const +{ + Q_D(const QLineEdit); + return d->control->cursorMoveStyle(); +} + +/*! + Sets the movement style for the cursor in the line edit to the given + \a style. +*/ +void QLineEdit::setCursorMoveStyle(QTextCursor::MoveStyle 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..73a736c 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> @@ -158,6 +159,9 @@ public: void setDragEnabled(bool b); bool dragEnabled() const; + void setCursorMoveStyle(QTextCursor::MoveStyle style); + QTextCursor::MoveStyle cursorMoveStyle() const; + QString inputMask() const; void setInputMask(const QString &inputMask); bool hasAcceptableInput() const; diff --git a/src/gui/widgets/qlineedit_p.cpp b/src/gui/widgets/qlineedit_p.cpp index 23ac613..03716d4 100644 --- a/src/gui/widgets/qlineedit_p.cpp +++ b/src/gui/widgets/qlineedit_p.cpp @@ -153,6 +153,7 @@ void QLineEditPrivate::init(const QString& txt) { Q_Q(QLineEdit); control = new QLineControl(txt); + control->setParent(q); control->setFont(q->font()); QObject::connect(control, SIGNAL(textChanged(QString)), q, SIGNAL(textChanged(QString))); diff --git a/src/gui/widgets/qlineedit_p.h b/src/gui/widgets/qlineedit_p.h index 32f6077..3169776 100644 --- a/src/gui/widgets/qlineedit_p.h +++ b/src/gui/widgets/qlineedit_p.h @@ -84,7 +84,6 @@ public: ~QLineEditPrivate() { - delete control; } QLineControl *control; diff --git a/src/gui/widgets/qmdiarea.cpp b/src/gui/widgets/qmdiarea.cpp index 2a486bb..2e274f2 100644 --- a/src/gui/widgets/qmdiarea.cpp +++ b/src/gui/widgets/qmdiarea.cpp @@ -2176,7 +2176,7 @@ void QMdiArea::setTabsClosable(bool closable) Tabs are not movable by default. - \sa QTabBar::tabsMovable, setViewMode() + \sa QTabBar::movable, setViewMode() */ bool QMdiArea::tabsMovable() const { diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp index b12e5c5..b0ea00f 100644 --- a/src/gui/widgets/qmenu.cpp +++ b/src/gui/widgets/qmenu.cpp @@ -228,6 +228,12 @@ QList<QPointer<QWidget> > QMenuPrivate::calcCausedStack() const void QMenuPrivate::updateActionRects() const { Q_Q(const QMenu); + updateActionRects(popupGeometry(q)); +} + +void QMenuPrivate::updateActionRects(const QRect &screen) const +{ + Q_Q(const QMenu); if (!itemsDirty) return; @@ -237,20 +243,10 @@ void QMenuPrivate::updateActionRects() const actionRects.resize(actions.count()); actionRects.fill(QRect()); - //let's try to get the last visible action - int lastVisibleAction = actions.count() - 1; - for(;lastVisibleAction >= 0; --lastVisibleAction) { - const QAction *action = actions.at(lastVisibleAction); - if (action->isVisible()) { - //removing trailing separators - if (action->isSeparator() && collapsibleSeparators) - continue; - break; - } - } + int lastVisibleAction = getLastVisibleAction(); int max_column_width = 0, - dh = popupGeometry(q).height(), + dh = screen.height(), y = 0; QStyle *style = q->style(); QStyleOption opt; @@ -351,7 +347,6 @@ void QMenuPrivate::updateActionRects() const const int min_column_width = q->minimumWidth() - (sfcMargin + leftmargin + rightmargin + 2 * (fw + hmargin)); max_column_width = qMax(min_column_width, max_column_width); - //calculate position const int base_y = vmargin + fw + topmargin + (scroll ? scroll->scrollOffset : 0) + @@ -382,6 +377,34 @@ void QMenuPrivate::updateActionRects() const itemsDirty = 0; } +QSize QMenuPrivate::adjustMenuSizeForScreen(const QRect &screen) +{ + Q_Q(QMenu); + QSize ret = screen.size(); + itemsDirty = true; + updateActionRects(screen); + const int fw = q->style()->pixelMetric(QStyle::PM_MenuPanelWidth, 0, q); + ret.setWidth(actionRects.at(getLastVisibleAction()).right() + fw); + return ret; +} + +int QMenuPrivate::getLastVisibleAction() const +{ + //let's try to get the last visible action + int lastVisibleAction = actions.count() - 1; + for (;lastVisibleAction >= 0; --lastVisibleAction) { + const QAction *action = actions.at(lastVisibleAction); + if (action->isVisible()) { + //removing trailing separators + if (action->isSeparator() && collapsibleSeparators) + continue; + break; + } + } + return lastVisibleAction; +} + + QRect QMenuPrivate::actionRect(QAction *act) const { int index = actions.indexOf(act); @@ -1813,9 +1836,20 @@ void QMenu::popup(const QPoint &p, QAction *atAction) else #endif screen = d->popupGeometry(QApplication::desktop()->screenNumber(p)); - const int desktopFrame = style()->pixelMetric(QStyle::PM_MenuDesktopFrameWidth, 0, this); bool adjustToDesktop = !window()->testAttribute(Qt::WA_DontShowOnScreen); + + // if the screens have very different geometries and the menu is too big, we have to recalculate + if (size.height() > screen.height() || size.width() > screen.width()) { + size = d->adjustMenuSizeForScreen(screen); + adjustToDesktop = true; + } + // Layout is not right, we might be able to save horizontal space + if (d->ncols >1 && size.height() < screen.height()) { + size = d->adjustMenuSizeForScreen(screen); + adjustToDesktop = true; + } + #ifdef QT_KEYPAD_NAVIGATION if (!atAction && QApplication::keypadNavigationEnabled()) { // Try to have one item activated @@ -1909,6 +1943,27 @@ void QMenu::popup(const QPoint &p, QAction *atAction) } } } + const int subMenuOffset = style()->pixelMetric(QStyle::PM_SubMenuOverlap, 0, this); + const QSize menuSize(sizeHint()); + QMenu *caused = qobject_cast<QMenu*>(d_func()->causedPopup.widget); + if (caused && caused->geometry().width() + menuSize.width() + subMenuOffset < screen.width()) { + QRect parentActionRect(caused->d_func()->actionRect(caused->d_func()->currentAction)); + const QPoint actionTopLeft = caused->mapToGlobal(parentActionRect.topLeft()); + parentActionRect.moveTopLeft(actionTopLeft); + if (isRightToLeft()) { + if ((pos.x() + menuSize.width() > parentActionRect.left() - subMenuOffset) + && (pos.x() < parentActionRect.right())) + { + pos.rx() = parentActionRect.right(); + } + } else { + if ((pos.x() < parentActionRect.right() + subMenuOffset) + && (pos.x() + menuSize.width() > parentActionRect.left())) + { + pos.rx() = parentActionRect.left() - menuSize.width(); + } + } + } setGeometry(QRect(pos, size)); #ifndef QT_NO_EFFECTS int hGuess = isRightToLeft() ? QEffects::LeftScroll : QEffects::RightScroll; @@ -2941,28 +2996,8 @@ void QMenu::internalDelayedPopup() const QRect actionRect(d->actionRect(d->currentAction)); const QSize menuSize(d->activeMenu->sizeHint()); const QPoint rightPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top()))); - const QPoint leftPos(mapToGlobal(QPoint(actionRect.left() - subMenuOffset - menuSize.width(), actionRect.top()))); QPoint pos(rightPos); - QMenu *caused = qobject_cast<QMenu*>(d->activeMenu->d_func()->causedPopup.widget); - - const QRect availGeometry(d->popupGeometry(caused)); - if (isRightToLeft()) { - pos = leftPos; - if ((caused && caused->x() < x()) || pos.x() < availGeometry.left()) { - if(rightPos.x() + menuSize.width() < availGeometry.right()) - pos = rightPos; - else - pos.rx() = availGeometry.left(); - } - } else { - if ((caused && caused->x() > x()) || pos.x() + menuSize.width() > availGeometry.right()) { - if(leftPos.x() < availGeometry.left()) - pos.rx() = availGeometry.right() - menuSize.width(); - else - pos = leftPos; - } - } //calc sloppy focus buffer if (style()->styleHint(QStyle::SH_Menu_SloppySubMenus, 0, this)) { diff --git a/src/gui/widgets/qmenu_p.h b/src/gui/widgets/qmenu_p.h index b6efde3..005ce1d 100644 --- a/src/gui/widgets/qmenu_p.h +++ b/src/gui/widgets/qmenu_p.h @@ -194,10 +194,13 @@ public: mutable QVector<QRect> actionRects; mutable QHash<QAction *, QWidget *> widgetItems; void updateActionRects() const; + void updateActionRects(const QRect &screen) const; QRect popupGeometry(const QWidget *widget) const; QRect popupGeometry(int screen = -1) const; mutable uint ncols : 4; //4 bits is probably plenty uint collapsibleSeparators : 1; + QSize adjustMenuSizeForScreen(const QRect & screen); + int getLastVisibleAction() const; bool activationRecursionGuard; @@ -296,7 +299,6 @@ public: void updateLayoutDirection(); - //menu fading/scrolling effects bool doChildEffects; 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/qtabwidget.cpp b/src/gui/widgets/qtabwidget.cpp index c296b77..f16205c 100644 --- a/src/gui/widgets/qtabwidget.cpp +++ b/src/gui/widgets/qtabwidget.cpp @@ -883,7 +883,7 @@ QSize QTabWidget::minimumSizeHint() const .expandedTo(QApplication::globalStrut()); } -/* +/*! \reimp */ int QTabWidget::heightForWidth(int width) const 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/qhttpmultipart.cpp b/src/network/access/qhttpmultipart.cpp index 640f9ea..07d5988 100644 --- a/src/network/access/qhttpmultipart.cpp +++ b/src/network/access/qhttpmultipart.cpp @@ -256,7 +256,7 @@ void QHttpPart::setBodyDevice(QIODevice *device) /*! Constructs a QHttpMultiPart with content type MixedType and sets - parent as the parent object. + \a parent as the parent object. \sa QHttpMultiPart::ContentType */ diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index 83156c6..07dd729 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -117,7 +117,6 @@ QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate() void QHttpNetworkConnectionPrivate::init() { - Q_Q(QHttpNetworkConnection); for (int i = 0; i < channelCount; i++) { channels[i].setConnection(this->q_func()); channels[i].ssl = encrypt; diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index 26e9bdf..faecf96 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -865,7 +865,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() */ 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/bearer/qnetworkconfigmanager.cpp b/src/network/bearer/qnetworkconfigmanager.cpp index 10fe74c..ad473d5 100644 --- a/src/network/bearer/qnetworkconfigmanager.cpp +++ b/src/network/bearer/qnetworkconfigmanager.cpp @@ -128,7 +128,7 @@ QNetworkConfigurationManagerPrivate *qNetworkConfigurationManagerPrivate() \fn void QNetworkConfigurationManager::configurationRemoved(const QNetworkConfiguration &config) This signal is emitted when a configuration is about to be removed from the system. The removed - \a configuration is invalid but retains name and identifier. + configuration, specified by \a config, is invalid but retains name and identifier. */ /*! diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index c108ad3..e9b6703 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"); @@ -442,9 +442,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; } } diff --git a/src/network/bearer/qnetworkconfigmanager_p.h b/src/network/bearer/qnetworkconfigmanager_p.h index 81f38c5..abc4b9b 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 { @@ -107,6 +108,7 @@ private Q_SLOTS: private: void startPolling(); + QTimer *pollTimer; private: mutable QMutex mutex; diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index a16d4ca..c86f510 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -288,7 +288,7 @@ QHostInfo QHostInfoPrivate::fromName(const QString &name, QSharedPointer<QNetwor #ifndef Q_OS_SYMBIAN // This function has a special implementation for symbian right now in qhostinfo_symbian.cpp but not on other OS. -QHostInfo QHostInfoAgent::fromName(const QString &hostName, QSharedPointer<QNetworkSession> networkSession) +QHostInfo QHostInfoAgent::fromName(const QString &hostName, QSharedPointer<QNetworkSession>) { return QHostInfoAgent::fromName(hostName); } diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp index 7af71cc..cfb1413 100644 --- a/src/network/socket/qabstractsocket.cpp +++ b/src/network/socket/qabstractsocket.cpp @@ -1877,7 +1877,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 +1904,7 @@ bool QAbstractSocket::waitForReadyRead(int msecs) if (state() != ConnectedState) return false; - } + } while (qt_timeout_value(msecs, stopWatch.elapsed()) > 0); return false; } 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..63fdbcc 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -675,8 +675,8 @@ QString QSslSocket::peerVerifyName() const /*! \since 4.8 - Sets a different hostname for the certificate validation instead of the one used for the TCP - connection. + Sets a different host name, given by \a hostName, for the certificate + validation instead of the one used for the TCP connection. \sa connectToHostEncrypted() */ 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..a2707e0 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); diff --git a/src/opengl/qgl_qpa.cpp b/src/opengl/qgl_qpa.cpp index 994344c..3778072 100644 --- a/src/opengl/qgl_qpa.cpp +++ b/src/opengl/qgl_qpa.cpp @@ -52,6 +52,9 @@ QT_BEGIN_NAMESPACE +/*! + Returns an OpenGL format for the platform window format specified by \a format. +*/ QGLFormat QGLFormat::fromPlatformWindowFormat(const QPlatformWindowFormat &format) { QGLFormat retFormat; @@ -83,6 +86,9 @@ QGLFormat QGLFormat::fromPlatformWindowFormat(const QPlatformWindowFormat &forma return retFormat; } +/*! + Returns a platform window format for the OpenGL format specified by \a format. +*/ QPlatformWindowFormat QGLFormat::toPlatformWindowFormat(const QGLFormat &format) { QPlatformWindowFormat retFormat; @@ -378,6 +384,10 @@ QGLContext::QGLContext(QPlatformGLContext *platformContext) d->setupSharing(); } +/*! + Returns a OpenGL context for the platform-specific OpenGL context given by + \a platformContext. +*/ QGLContext *QGLContext::fromPlatformGLContext(QPlatformGLContext *platformContext) { if (!platformContext) diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index f16b317..d882916 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -205,13 +205,16 @@ int QGLFramebufferObjectFormat::samples() const /*! \since 4.8 - Enables or disables mipmapping. Mipmapping is disabled by default. + Enables mipmapping if \a enabled is true; otherwise disables it. + + Mipmapping is disabled by default. + If mipmapping is enabled, additional memory will be allocated for the mipmap levels. The mipmap levels can be updated by binding the texture and calling glGenerateMipmap(). Mipmapping cannot be enabled for multisampled framebuffer objects. - \sa mipmap(), texture() + \sa mipmap(), QGLFramebufferObject::texture() */ void QGLFramebufferObjectFormat::setMipmap(bool enabled) { diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 9da811a..5fa9f32 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -2119,6 +2119,7 @@ void QOpenGLPaintEnginePrivate::fillPath(const QPainterPath &path) updateGLMatrix(); } +extern 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; -} +extern 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 70c1fde..8494283 100644 --- a/src/opengl/qwindowsurface_gl.cpp +++ b/src/opengl/qwindowsurface_gl.cpp @@ -610,6 +610,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); @@ -717,7 +728,6 @@ void QGLWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint & } else { glFlush(); } - return; } @@ -874,8 +884,22 @@ void QGLWindowSurface::updateGeometry() { bool hijack(true); QWidgetPrivate *wd = window()->d_func(); - if (wd->extraData() && wd->extraData()->glContext) - hijack = false; // we already have gl context for widget + if (wd->extraData() && wd->extraData()->glContext) { +#ifdef Q_OS_SYMBIAN // Symbian needs to recreate the context when native window size changes + if (d_ptr->size != geometry().size()) { + if (window() != qt_gl_share_widget()) + --(_qt_gl_share_widget()->widgetRefCount); + + delete wd->extraData()->glContext; + wd->extraData()->glContext = 0; + d_ptr->ctx = 0; + } + else +#endif + { + hijack = false; // we already have gl context for widget + } + } if (hijack) hijackWindow(window()); @@ -896,35 +920,6 @@ void QGLWindowSurface::updateGeometry() { d_ptr->size = surfSize; -#ifdef Q_OS_SYMBIAN - if (!hijack) { // Symbian needs to recreate EGL surface when native window size changes - if (ctx->d_func()->eglSurface != EGL_NO_SURFACE) { - eglDestroySurface(ctx->d_func()->eglContext->display(), - ctx->d_func()->eglSurface); - } - - ctx->d_func()->eglSurface = QEgl::createSurface(ctx->device(), - ctx->d_func()->eglContext->config()); - - eglGetError(); // Clear error state. - if (!d_ptr->destructive_swap_buffers) { - eglSurfaceAttrib(ctx->d_func()->eglContext->display(), - ctx->d_func()->eglSurface, - EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED); - - if (eglGetError() != EGL_SUCCESS) - qWarning("QGLWindowSurface: could not enable preserved swap behaviour"); - } else { - eglSurfaceAttrib(ctx->d_func()->eglContext->display(), - ctx->d_func()->eglSurface, - EGL_SWAP_BEHAVIOR, EGL_BUFFER_DESTROYED); - - if (eglGetError() != EGL_SUCCESS) - qWarning("QGLWindowSurface: could not enable destroyed swap behaviour"); - } - } -#endif - if (d_ptr->ctx) { #ifndef QT_OPENGL_ES_2 if (d_ptr->destructive_swap_buffers) diff --git a/src/openvg/qpaintengine_vg.cpp b/src/openvg/qpaintengine_vg.cpp index 588c35a..68a6a0b 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 + { + extern 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); } +extern 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/openvg/qwindowsurface_vgegl.cpp b/src/openvg/qwindowsurface_vgegl.cpp index 866453f..3205a11 100644 --- a/src/openvg/qwindowsurface_vgegl.cpp +++ b/src/openvg/qwindowsurface_vgegl.cpp @@ -269,19 +269,20 @@ static QEglContext *createContext(QPaintDevice *device) configProps.setPixelFormat(QImage::Format_ARGB32); // XXX configProps.setValue(EGL_ALPHA_MASK_SIZE, 1); #ifdef EGL_VG_ALPHA_FORMAT_PRE_BIT - configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | - EGL_VG_ALPHA_FORMAT_PRE_BIT); + configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT + | EGL_SWAP_BEHAVIOR_PRESERVED_BIT + | EGL_VG_ALPHA_FORMAT_PRE_BIT); configProps.setRenderableType(QEgl::OpenVG); if (!context->chooseConfig(configProps)) { // Try again without the "pre" bit. - configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); + configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT); if (!context->chooseConfig(configProps)) { delete context; return 0; } } #else - configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT); + configProps.setValue(EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT); configProps.setRenderableType(QEgl::OpenVG); if (!context->chooseConfig(configProps)) { delete context; diff --git a/src/plugins/accessible/widgets/complexwidgets.cpp b/src/plugins/accessible/widgets/complexwidgets.cpp index e638413..85be0b0 100644 --- a/src/plugins/accessible/widgets/complexwidgets.cpp +++ b/src/plugins/accessible/widgets/complexwidgets.cpp @@ -971,7 +971,11 @@ QString QAccessibleItemView::text(Text t, int child) const return QAccessibleAbstractScrollArea::text(t, child); QAccessibleItemRow item(itemView(), childIndex(child)); - return item.text(t, 1); + if (item.isValid()) { + return item.text(t, 1); + } else { + return QString(); + } } else { return QAccessibleAbstractScrollArea::text(t, child); } diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp index 09b5015..4402932 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp @@ -401,9 +401,14 @@ int QAccessibleStackedWidget::childCount() const int QAccessibleStackedWidget::indexOfChild(const QAccessibleInterface *child) const { - if (!child || (stackedWidget()->currentWidget() != child->object())) + if (!child) return -1; - return 1; + + QWidget* widget = qobject_cast<QWidget*>(child->object()); + int index = stackedWidget()->indexOf(widget); + if (index >= 0) // one based counting of children + return index + 1; + return -1; } int QAccessibleStackedWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const @@ -413,9 +418,9 @@ int QAccessibleStackedWidget::navigate(RelationFlag relation, int entry, QAccess QObject *targetObject = 0; switch (relation) { case Child: - if (entry != 1) + if (entry < 1 || entry > stackedWidget()->count()) return -1; - targetObject = stackedWidget()->currentWidget(); + targetObject = stackedWidget()->widget(entry-1); break; default: return QAccessibleWidgetEx::navigate(relation, entry, target); @@ -1334,7 +1339,7 @@ QRect QAccessibleTextEdit::characterRect(int offset, CoordinateType coordType) QRect r = edit->cursorRect(cursor); if (cursor.movePosition(QTextCursor::NextCharacter)) { - r.setWidth(edit->cursorRect(cursor).y() - r.y()); + r.setWidth(edit->cursorRect(cursor).x() - r.x()); } else { // we don't know the width of the character - maybe because we're at document end // in that case, IAccessible2 tells us to return the width of a default character @@ -1603,7 +1608,7 @@ void QAccessibleTextEdit::setAttributes(int startOffset, int endOffset, const QS #ifndef QT_NO_MAINWINDOW QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget) - : QAccessibleWidgetEx(widget, Application) { } + : QAccessibleWidgetEx(widget, Window) { } QVariant QAccessibleMainWindow::invokeMethodEx(QAccessible::Method /*method*/, int /*child*/, const QVariantList & /*params*/) { diff --git a/src/plugins/accessible/widgets/simplewidgets.cpp b/src/plugins/accessible/widgets/simplewidgets.cpp index 21d2d67..aa64630 100644 --- a/src/plugins/accessible/widgets/simplewidgets.cpp +++ b/src/plugins/accessible/widgets/simplewidgets.cpp @@ -131,7 +131,7 @@ QString QAccessibleButton::actionText(int action, Text text, int child) const /*! \reimp */ bool QAccessibleButton::doAction(int action, int child, const QVariantList ¶ms) { - if (child || !widget()->isEnabled() || !widget()->isVisible()) + if (child || !widget()->isEnabled()) return false; switch (action) { @@ -155,9 +155,6 @@ bool QAccessibleButton::doAction(int action, int child, const QVariantList ¶ QString QAccessibleButton::text(Text t, int child) const { QString str; - if (!widget()->isVisible()) - return str; - switch (t) { case Accelerator: { @@ -227,6 +224,9 @@ QString QAccessibleButton::description(int actionIndex) { switch (actionIndex) { case 0: + if (button()->isCheckable()) { + return QLatin1String("Toggles the button."); + } return QLatin1String("Clicks the button."); default: return QString(); @@ -237,6 +237,13 @@ QString QAccessibleButton::name(int actionIndex) { switch (actionIndex) { case 0: + if (button()->isCheckable()) { + if (button()->isChecked()) { + return QLatin1String("Uncheck"); + } else { + return QLatin1String("Check"); + } + } return QLatin1String("Press"); default: return QString(); @@ -247,6 +254,13 @@ QString QAccessibleButton::localizedName(int actionIndex) { switch (actionIndex) { case 0: + if (button()->isCheckable()) { + if (button()->isChecked()) { + return tr("Uncheck"); + } else { + return tr("Check"); + } + } return tr("Press"); default: return QString(); @@ -380,9 +394,6 @@ QRect QAccessibleToolButton::rect(int child) const QString QAccessibleToolButton::text(Text t, int child) const { QString str; - if (!toolButton()->isVisible()) - return str; - switch (t) { case Name: str = toolButton()->text(); @@ -454,7 +465,7 @@ QString QAccessibleToolButton::actionText(int action, Text text, int child) cons */ bool QAccessibleToolButton::doAction(int action, int child, const QVariantList ¶ms) { - if (!widget()->isEnabled() || !widget()->isVisible()) + if (!widget()->isEnabled()) return false; if (action == 1 || child == ButtonDropMenu) { if(!child) @@ -513,8 +524,6 @@ QAccessible::Role QAccessibleDisplay::role(int child) const QString QAccessibleDisplay::text(Text t, int child) const { QString str; - if (!widget()->isVisible()) - return str; switch (t) { case Name: str = widget()->accessibleName(); @@ -674,8 +683,6 @@ QLineEdit *QAccessibleLineEdit::lineEdit() const QString QAccessibleLineEdit::text(Text t, int child) const { QString str; - if (!lineEdit()->isVisible()) - return str; switch (t) { case Value: if (lineEdit()->echoMode() == QLineEdit::Normal) @@ -692,8 +699,6 @@ QString QAccessibleLineEdit::text(Text t, int child) const /*! \reimp */ void QAccessibleLineEdit::setText(Text t, int control, const QString &text) { - if (!lineEdit()->isVisible()) - return; if (t != Value || control) { QAccessibleWidgetEx::setText(t, control, text); return; 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/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/qwaylanddisplay.cpp b/src/plugins/platforms/wayland/qwaylanddisplay.cpp index 1c56561..876b46a 100644 --- a/src/plugins/platforms/wayland/qwaylanddisplay.cpp +++ b/src/plugins/platforms/wayland/qwaylanddisplay.cpp @@ -126,6 +126,7 @@ QWaylandDisplay::QWaylandDisplay(void) #ifdef QT_WAYLAND_GL_SUPPORT mEglIntegration = QWaylandGLIntegration::createGLIntegration(this); #endif + blockingReadEvents(); qRegisterMetaType<uint32_t>("uint32_t"); @@ -216,9 +217,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); @@ -252,17 +250,17 @@ void QWaylandDisplay::displayHandleGlobal(uint32_t id, { 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); 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/qwaylandintegration.cpp b/src/plugins/platforms/wayland/qwaylandintegration.cpp index 3f3ee5e..b6401f6 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.cpp +++ b/src/plugins/platforms/wayland/qwaylandintegration.cpp @@ -44,6 +44,7 @@ #include "qwaylanddisplay.h" #include "qwaylandshmsurface.h" #include "qwaylandshmwindow.h" +#include "qwaylandnativeinterface.h" #include "qgenericunixfontdatabase.h" @@ -62,9 +63,15 @@ QWaylandIntegration::QWaylandIntegration(bool useOpenGL) : mFontDb(new QGenericUnixFontDatabase()) , mDisplay(new QWaylandDisplay()) , mUseOpenGL(useOpenGL) + , mNativeInterface(new QWaylandNativeInterface) { } +QPlatformNativeInterface * QWaylandIntegration::nativeInterface() const +{ + return mNativeInterface; +} + QList<QPlatformScreen *> QWaylandIntegration::screens() const { diff --git a/src/plugins/platforms/wayland/qwaylandintegration.h b/src/plugins/platforms/wayland/qwaylandintegration.h index fc9b8d6..71f6d9c 100644 --- a/src/plugins/platforms/wayland/qwaylandintegration.h +++ b/src/plugins/platforms/wayland/qwaylandintegration.h @@ -63,12 +63,15 @@ public: QPlatformFontDatabase *fontDatabase() const; + QPlatformNativeInterface *nativeInterface() const; + private: bool hasOpenGL() const; QPlatformFontDatabase *mFontDb; QWaylandDisplay *mDisplay; bool mUseOpenGL; + QPlatformNativeInterface *mNativeInterface; }; 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..8d2d4b5 100644 --- a/src/plugins/platforms/wayland/wayland.pro +++ b/src/plugins/platforms/wayland/wayland.pro @@ -8,6 +8,7 @@ DEFINES += $$QMAKE_DEFINES_WAYLAND SOURCES = main.cpp \ qwaylandintegration.cpp \ + qwaylandnativeinterface.cpp \ qwaylandshmsurface.cpp \ qwaylandinputdevice.cpp \ qwaylandcursor.cpp \ @@ -17,6 +18,7 @@ SOURCES = main.cpp \ qwaylandshmwindow.cpp HEADERS = qwaylandintegration.h \ + qwaylandnativeinterface.h \ qwaylandcursor.h \ qwaylanddisplay.h \ qwaylandwindow.h \ 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/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index a3a965e..1c4f110 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -3820,7 +3820,7 @@ QStringList QScriptEngine::importedExtensions() const which did not support member template functions. It is advised to use the other form in new code. - \sa QScriptEngine::toScriptValue(), qscriptvalue_cast + \sa QScriptEngine::toScriptValue(), qscriptvalue_cast() */ /*! 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/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp index 99b516a..2f16f94 100644 --- a/src/sql/models/qsqltablemodel.cpp +++ b/src/sql/models/qsqltablemodel.cpp @@ -1006,7 +1006,8 @@ QString QSqlTableModel::orderByClause() const } /*! - Returns the index of the field \a fieldName. + Returns the index of the field \a fieldName, or -1 if no corresponding field + exists in the model. */ int QSqlTableModel::fieldIndex(const QString &fieldName) const { diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp index 9698860..3fbc08c 100644 --- a/src/svg/qsvghandler.cpp +++ b/src/svg/qsvghandler.cpp @@ -584,7 +584,7 @@ static qreal toDouble(const QChar *&str) ++str; } bool exponent = false; - if (*str == QLatin1Char('e') && pos < maxLen) { + if ((*str == QLatin1Char('e') || *str == QLatin1Char('E')) && pos < maxLen) { exponent = true; temp[pos++] = 'e'; ++str; 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..e63b14e 100644 --- a/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp +++ b/tests/auto/declarative/qdeclarativedebug/tst_qdeclarativedebug.cpp @@ -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,6 +678,7 @@ 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; @@ -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() @@ -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(); @@ -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() @@ -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/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..be8f221 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(); @@ -3081,6 +3082,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/qdeclarativepathview/tst_qdeclarativepathview.cpp b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp index 8000137..46c3519 100644 --- a/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp +++ b/tests/auto/declarative/qdeclarativepathview/tst_qdeclarativepathview.cpp @@ -458,6 +458,16 @@ void tst_QDeclarativePathView::dataModel() model.removeItem(model.count()-1); QCOMPARE(pathview->currentIndex(), model.count()-1); + // QTBUG-18825 + // Confirm that the target offset is adjusted when removing items + pathview->setCurrentIndex(model.count()-1); + QTRY_COMPARE(pathview->offset(), 1.); + pathview->setCurrentIndex(model.count()-5); + model.removeItem(model.count()-1); + model.removeItem(model.count()-1); + model.removeItem(model.count()-1); + QTRY_COMPARE(pathview->offset(), 2.); + delete canvas; } diff --git a/tests/auto/declarative/qdeclarativetextedit/data/mouseselection_false_readonly.qml b/tests/auto/declarative/qdeclarativetextedit/data/mouseselection_false_readonly.qml new file mode 100644 index 0000000..4aea611 --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextedit/data/mouseselection_false_readonly.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: false + readOnly: true +} diff --git a/tests/auto/declarative/qdeclarativetextedit/data/mouseselection_true_readonly.qml b/tests/auto/declarative/qdeclarativetextedit/data/mouseselection_true_readonly.qml new file mode 100644 index 0000000..959e683 --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextedit/data/mouseselection_true_readonly.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 + +TextEdit { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + readOnly: true +} diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp index 26a6fd8..2fad88d 100644 --- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp +++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp @@ -119,6 +119,10 @@ private slots: void moveCursorSelectionSequence(); void mouseSelection_data(); void mouseSelection(); + void deferEnableSelectByMouse_data(); + void deferEnableSelectByMouse(); + void deferDisableSelectByMouse_data(); + void deferDisableSelectByMouse(); void mouseSelectionMode_data(); void mouseSelectionMode(); void dragMouseSelection(); @@ -1360,6 +1364,86 @@ void tst_qdeclarativetextedit::mouseSelection() delete canvas; } +void tst_qdeclarativetextedit::deferEnableSelectByMouse_data() +{ + QTest::addColumn<QString>("qmlfile"); + + QTest::newRow("writable") << SRCDIR "/data/mouseselection_false.qml"; + QTest::newRow("read only") << SRCDIR "/data/mouseselection_false_readonly.qml"; +} + +void tst_qdeclarativetextedit::deferEnableSelectByMouse() +{ + // Verify text isn't selected if selectByMouse is enabled after the mouse button has been pressed. + QFETCH(QString, qmlfile); + + QDeclarativeView *canvas = createView(qmlfile); + + 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-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textEditObject->height()/2; + + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + textEditObject->setSelectByMouse(true); + //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QVERIFY(textEditObject->selectedText().isEmpty()); + + delete canvas; +} + +void tst_qdeclarativetextedit::deferDisableSelectByMouse_data() +{ + QTest::addColumn<QString>("qmlfile"); + + QTest::newRow("writable") << SRCDIR "/data/mouseselection_true.qml"; + QTest::newRow("read only") << SRCDIR "/data/mouseselection_true_readonly.qml"; +} + +void tst_qdeclarativetextedit::deferDisableSelectByMouse() +{ + // Verify text isn't selected if selectByMouse is enabled after the mouse button has been pressed. + QFETCH(QString, qmlfile); + + QDeclarativeView *canvas = createView(qmlfile); + + 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-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textEditObject->height()/2; + + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + textEditObject->setSelectByMouse(false); + //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QVERIFY(textEditObject->selectedText().length() > 3); + + delete canvas; +} + void tst_qdeclarativetextedit::dragMouseSelection() { QString qmlfile = SRCDIR "/data/mouseselection_true.qml"; @@ -1546,6 +1630,15 @@ void tst_qdeclarativetextedit::cursorDelegate() QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); } + const QString preedit = "preedit"; + for (int i = 0; i <= preedit.length(); i++) { + QInputMethodEvent event(preedit, QList<QInputMethodEvent::Attribute>() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, i, 1, QVariant())); + QApplication::sendEvent(view, &event); + + 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/qdeclarativetextinput/data/mouseselection_default.qml b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_default.qml new file mode 100644 index 0000000..eea83ed --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_default.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: false +} diff --git a/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_false.qml b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_false.qml new file mode 100644 index 0000000..eea83ed --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_false.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: false +} diff --git a/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_false_readonly.qml b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_false_readonly.qml new file mode 100644 index 0000000..36a9563 --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_false_readonly.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: false + readOnly: true +} diff --git a/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_false_words.qml b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_false_words.qml new file mode 100644 index 0000000..eea83ed --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_false_words.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: false +} diff --git a/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_true_readonly.qml b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_true_readonly.qml new file mode 100644 index 0000000..678a89a --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_true_readonly.qml @@ -0,0 +1,8 @@ +import QtQuick 1.0 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true + readOnly: true +} diff --git a/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_true_words.qml b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_true_words.qml new file mode 100644 index 0000000..8115ba0 --- /dev/null +++ b/tests/auto/declarative/qdeclarativetextinput/data/mouseselection_true_words.qml @@ -0,0 +1,7 @@ +import QtQuick 1.0 + +TextInput { + focus: true + text: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + selectByMouse: true +} diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp index baaf862..a241241 100644 --- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp +++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp @@ -95,6 +95,12 @@ private slots: void moveCursorSelection(); void moveCursorSelectionSequence_data(); void moveCursorSelectionSequence(); + void mouseSelection_data(); + void mouseSelection(); + void deferEnableSelectByMouse_data(); + void deferEnableSelectByMouse(); + void deferDisableSelectByMouse_data(); + void deferDisableSelectByMouse(); void dragMouseSelection(); void mouseSelectionMode_data(); void mouseSelectionMode(); @@ -911,6 +917,141 @@ void tst_qdeclarativetextinput::moveCursorSelectionSequence() QCOMPARE(textinputObject->selectionEnd(), selection2End); } +void tst_qdeclarativetextinput::mouseSelection_data() +{ + QTest::addColumn<QString>("qmlfile"); + QTest::addColumn<bool>("expectSelection"); + + // import installed + QTest::newRow("on") << SRCDIR "/data/mouseselection_true.qml" << true; + QTest::newRow("off") << SRCDIR "/data/mouseselection_false.qml" << false; + QTest::newRow("default") << SRCDIR "/data/mouseselection_default.qml" << false; + QTest::newRow("on word selection") << SRCDIR "/data/mouseselection_true_words.qml" << true; + QTest::newRow("off word selection") << SRCDIR "/data/mouseselection_false_words.qml" << false; + QTest::newRow("on read only") << SRCDIR "/data/mouseselection_true_readonly.qml" << true; + QTest::newRow("off read only") << SRCDIR "/data/mouseselection_false_readonly.qml" << false; +} + +void tst_qdeclarativetextinput::mouseSelection() +{ + QFETCH(QString, qmlfile); + QFETCH(bool, expectSelection); + + QDeclarativeView *canvas = createView(qmlfile); + + canvas->show(); + QApplication::setActiveWindow(canvas); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas)); + + QVERIFY(canvas->rootObject() != 0); + QDeclarativeTextInput *textInputObject = qobject_cast<QDeclarativeTextInput *>(canvas->rootObject()); + QVERIFY(textInputObject != 0); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textInputObject->height()/2; + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QString str = textInputObject->selectedText(); + if (expectSelection) + QVERIFY(str.length() > 3); // don't reallly care *what* was selected (and it's too sensitive to platform) + else + QVERIFY(str.isEmpty()); + + // Clicking and shift to clicking between the same points should select the same text. + textInputObject->setCursorPosition(0); + QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::NoModifier, canvas->mapFromScene(QPoint(x1,y))); + QTest::mouseClick(canvas->viewport(), Qt::LeftButton, Qt::ShiftModifier, canvas->mapFromScene(QPoint(x2,y))); + QCOMPARE(textInputObject->selectedText(), str); + + delete canvas; +} + +void tst_qdeclarativetextinput::deferEnableSelectByMouse_data() +{ + QTest::addColumn<QString>("qmlfile"); + + QTest::newRow("writable") << SRCDIR "/data/mouseselection_false.qml"; + QTest::newRow("read only") << SRCDIR "/data/mouseselection_false_readonly.qml"; +} + +void tst_qdeclarativetextinput::deferEnableSelectByMouse() +{ + // Verify text isn't selected if selectByMouse is enabled after the mouse button has been pressed. + QFETCH(QString, qmlfile); + + QDeclarativeView *canvas = createView(qmlfile); + + canvas->show(); + QApplication::setActiveWindow(canvas); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas)); + + QVERIFY(canvas->rootObject() != 0); + QDeclarativeTextInput *textInputObject = qobject_cast<QDeclarativeTextInput *>(canvas->rootObject()); + QVERIFY(textInputObject != 0); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textInputObject->height()/2; + + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + textInputObject->setSelectByMouse(true); + //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QVERIFY(textInputObject->selectedText().isEmpty()); + + delete canvas; +} + +void tst_qdeclarativetextinput::deferDisableSelectByMouse_data() +{ + QTest::addColumn<QString>("qmlfile"); + + QTest::newRow("writable") << SRCDIR "/data/mouseselection_true.qml"; + QTest::newRow("read only") << SRCDIR "/data/mouseselection_true_readonly.qml"; +} + +void tst_qdeclarativetextinput::deferDisableSelectByMouse() +{ + // Verify text isn't selected if selectByMouse is enabled after the mouse button has been pressed. + QFETCH(QString, qmlfile); + + QDeclarativeView *canvas = createView(qmlfile); + + canvas->show(); + QApplication::setActiveWindow(canvas); + QTest::qWaitForWindowShown(canvas); + QTRY_COMPARE(QApplication::activeWindow(), static_cast<QWidget *>(canvas)); + + QVERIFY(canvas->rootObject() != 0); + QDeclarativeTextInput *textInputObject = qobject_cast<QDeclarativeTextInput *>(canvas->rootObject()); + QVERIFY(textInputObject != 0); + + // press-and-drag-and-release from x1 to x2 + int x1 = 10; + int x2 = 70; + int y = textInputObject->height()/2; + + QTest::mousePress(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x1,y))); + textInputObject->setSelectByMouse(false); + //QTest::mouseMove(canvas->viewport(), canvas->mapFromScene(QPoint(x2,y))); // doesn't work + QMouseEvent mv(QEvent::MouseMove, canvas->mapFromScene(QPoint(x2,y)), Qt::LeftButton, Qt::LeftButton,Qt::NoModifier); + QApplication::sendEvent(canvas->viewport(), &mv); + QTest::mouseRelease(canvas->viewport(), Qt::LeftButton, 0, canvas->mapFromScene(QPoint(x2,y))); + QVERIFY(textInputObject->selectedText().length() > 3); + + delete canvas; +} + void tst_qdeclarativetextinput::dragMouseSelection() { QString qmlfile = SRCDIR "/data/mouseselection_true.qml"; @@ -1643,6 +1784,15 @@ void tst_qdeclarativetextinput::cursorDelegate() QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x())); QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y())); } + const QString preedit = "preedit"; + for (int i = 0; i <= preedit.length(); i++) { + QInputMethodEvent event(preedit, QList<QInputMethodEvent::Attribute>() + << QInputMethodEvent::Attribute(QInputMethodEvent::Cursor, i, 1, QVariant())); + QApplication::sendEvent(view, &event); + + QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x())); + QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y())); + } textInputObject->setCursorPosition(0); QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x())); QCOMPARE(textInputObject->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/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/gui.pro b/tests/auto/gui.pro index 0d77fff..22c5e51 100644 --- a/tests/auto/gui.pro +++ b/tests/auto/gui.pro @@ -84,6 +84,7 @@ SUBDIRS=\ qheaderview \ qicoimageformat \ qicon \ + qidentityproxymodel \ qimageiohandler \ qimagereader \ qimagewriter \ diff --git a/tests/auto/headers/tst_headers.cpp b/tests/auto/headers/tst_headers.cpp index b5c65ef..b6135d0 100644 --- a/tests/auto/headers/tst_headers.cpp +++ b/tests/auto/headers/tst_headers.cpp @@ -243,6 +243,10 @@ void tst_Headers::licenseCheck() QCOMPARE(content.at(i++), QString("**")); if (sourceFile.endsWith("/tests/auto/modeltest/dynamictreemodel.cpp") || sourceFile.endsWith("/tests/auto/modeltest/dynamictreemodel.h") + || sourceFile.endsWith("/src/gui/itemviews/qidentityproxymodel.h") + || sourceFile.endsWith("/src/gui/itemviews/qidentityproxymodel.cpp") + || sourceFile.endsWith("/doc/src/snippets/code/src_gui_itemviews_qidentityproxymodel.cpp") + || sourceFile.endsWith("/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp") || sourceFile.endsWith("/src/network/kernel/qnetworkproxy_p.h")) { // These files are not copyrighted by Nokia. 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/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/qaccessibility/tst_qaccessibility.cpp b/tests/auto/qaccessibility/tst_qaccessibility.cpp index 8d9603b..7ff1a08 100644 --- a/tests/auto/qaccessibility/tst_qaccessibility.cpp +++ b/tests/auto/qaccessibility/tst_qaccessibility.cpp @@ -245,10 +245,13 @@ private slots: void actionText(); void doAction(); + void applicationTest(); + void mainWindowTest(); void buttonTest(); void sliderTest(); void scrollBarTest(); void tabTest(); + void tabWidgetTest(); void menuTest(); void spinBoxTest(); void doubleSpinBoxTest(); @@ -479,6 +482,11 @@ void tst_QAccessibility::eventTest() QVERIFY_EVENT(button, 0, QAccessible::StateChanged); QVERIFY_EVENT(button, 0, QAccessible::StateChanged); + button->setAccessibleName("Olaf the second"); + QVERIFY_EVENT(button, 0, QAccessible::NameChanged); + button->setAccessibleDescription("This is a button labeled Olaf"); + QVERIFY_EVENT(button, 0, QAccessible::DescriptionChanged); + button->hide(); QVERIFY_EVENT(button, 0, QAccessible::ObjectHide); @@ -1821,49 +1829,100 @@ void tst_QAccessibility::doAction() #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 + + QLatin1String name = QLatin1String("I am the main window"); + mw.setWindowTitle(name); + QTest::qWaitForWindowShown(&mw); + + QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&mw); + 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 { + Q_OBJECT +public: + CounterButton(const QString& name, QWidget* parent) + : QPushButton(name, parent), clickCount(0) + { + connect(this, SIGNAL(clicked(bool)), SLOT(incClickCount())); + } + int clickCount; +public Q_SLOTS: + void incClickCount() { + ++clickCount; + } +}; + void tst_QAccessibility::buttonTest() { -//#ifdef QTEST_ACCESSIBILITY -#if 0 - QAccessibleInterface *test = 0; - Q3VBox vbox; +#ifdef QTEST_ACCESSIBILITY + QWidget window; + window.setLayout(new QVBoxLayout); // Standard push button - QPushButton pushButton("Ok", &vbox); + CounterButton pushButton("Ok", &window); - // toggle push button - QPushButton togglepush("Toggle", &vbox); - togglepush.setToggleButton(TRUE); - - // push button with a menu - QPushButton menuButton("Menu", &vbox); - Q3PopupMenu buttonMenu(&menuButton); - buttonMenu.insertItem("Some item"); - menuButton.setPopup(&buttonMenu); + // toggle button + QPushButton toggleButton("Toggle", &window); + toggleButton.setCheckable(true); // standard checkbox - QCheckBox checkBox("Check me!", &vbox); + QCheckBox checkBox("Check me!", &window); // tristate checkbox - QCheckBox tristate("Tristate!", &vbox); + QCheckBox tristate("Tristate!", &window); tristate.setTristate(TRUE); // radiobutton - QRadioButton radio("Radio me!", &vbox); + QRadioButton radio("Radio me!", &window); // standard toolbutton - QToolButton toolbutton(&vbox); + QToolButton toolbutton(&window); toolbutton.setText("Tool"); toolbutton.setMinimumSize(20,20); // standard toolbutton - QToolButton toggletool(&vbox); - toggletool.setToggleButton(TRUE); + QToolButton toggletool(&window); + toggletool.setCheckable(true); toggletool.setText("Toggle"); toggletool.setMinimumSize(20,20); +#if 0 + // QT3_SUPPORT + // push button with a menu + QPushButton menuButton("Menu", &window); + Q3PopupMenu buttonMenu(&menuButton); + buttonMenu.insertItem("Some item"); + menuButton.setPopup(&buttonMenu); + // menu toolbutton - QToolButton menuToolButton(&vbox); + QToolButton menuToolButton(&window); menuToolButton.setText("Menu Tool"); Q3PopupMenu toolMenu(&menuToolButton); toolMenu.insertItem("Some item"); @@ -1871,141 +1930,149 @@ void tst_QAccessibility::buttonTest() menuToolButton.setMinimumSize(20,20); // splitted menu toolbutton - QToolButton splitToolButton(&vbox); + QToolButton splitToolButton(&window); splitToolButton.setTextLabel("Split Tool"); Q3PopupMenu splitMenu(&splitToolButton); splitMenu.insertItem("Some item"); splitToolButton.setPopup(&splitMenu); splitToolButton.setPopupDelay(0); splitToolButton.setMinimumSize(20,20); +#endif // test push button - QVERIFY(QAccessible::queryAccessibleInterface(&pushButton, &test)); - QCOMPARE(test->role(0), QAccessible::PushButton); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - pushButton.setDown(TRUE); - QCOMPARE(test->state(0), (int)QAccessible::Pressed); - QVERIFY(test->doAction(QAccessible::Press, 0)); + QAccessibleInterface* interface = QAccessible::queryAccessibleInterface(&pushButton); + QAccessibleActionInterface* actionInterface = interface->actionInterface(); + QVERIFY(actionInterface != 0); + + QCOMPARE(interface->role(0), QAccessible::PushButton); + + // currently our buttons only have click as action, press and release are missing + QCOMPARE(actionInterface->actionCount(), 1); + QCOMPARE(actionInterface->name(0), QString("Press")); + QCOMPARE(pushButton.clickCount, 0); + actionInterface->doAction(0); QTest::qWait(500); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - test->release(); - - // test toggle push button - QVERIFY(QAccessible::queryAccessibleInterface(&togglepush, &test)); - QCOMPARE(test->role(0), QAccessible::CheckBox); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - QVERIFY(test->doAction(QAccessible::Press, 0)); + QCOMPARE(pushButton.clickCount, 1); + delete interface; + + // test toggle button + interface = QAccessible::queryAccessibleInterface(&toggleButton); + actionInterface = interface->actionInterface(); + QCOMPARE(interface->role(0), QAccessible::CheckBox); + QCOMPARE(actionInterface->description(0), QString("Toggles the button.")); + QCOMPARE(actionInterface->name(0), QString("Check")); + QVERIFY(!toggleButton.isChecked()); + QVERIFY((interface->state(0) & QAccessible::Checked) == 0); + actionInterface->doAction(0); QTest::qWait(500); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); - QCOMPARE(test->state(0), (int)QAccessible::Checked); - test->release(); - - // test menu push button - QVERIFY(QAccessible::queryAccessibleInterface(&menuButton, &test)); - QCOMPARE(test->role(0), QAccessible::ButtonMenu); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Open")); - QCOMPARE(test->state(0), (int)QAccessible::HasPopup); - test->release(); + QCOMPARE(actionInterface->name(0), QString("Uncheck")); + QVERIFY(toggleButton.isChecked()); + QVERIFY((interface->state(0) & QAccessible::Checked)); + delete interface; + +// // test menu push button +// QVERIFY(QAccessible::queryAccessibleInterface(&menuButton, &test)); +// QCOMPARE(test->role(0), QAccessible::ButtonMenu); +// QCOMPARE(test->defaultAction(0), QAccessible::Press); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Open")); +// QCOMPARE(test->state(0), (int)QAccessible::HasPopup); +// test->release(); // test check box - QVERIFY(QAccessible::queryAccessibleInterface(&checkBox, &test)); - QCOMPARE(test->role(0), QAccessible::CheckBox); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - QVERIFY(test->doAction(QAccessible::Press, 0)); + interface = QAccessible::queryAccessibleInterface(&checkBox); + actionInterface = interface->actionInterface(); + QCOMPARE(interface->role(0), QAccessible::CheckBox); + QCOMPARE(actionInterface->name(0), QString("Check")); + QVERIFY((interface->state(0) & QAccessible::Checked) == 0); + actionInterface->doAction(0); QTest::qWait(500); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); - QCOMPARE(test->state(0), (int)QAccessible::Checked); - test->release(); - - // test tristate check box - QVERIFY(QAccessible::queryAccessibleInterface(&tristate, &test)); - QCOMPARE(test->role(0), QAccessible::CheckBox); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Toggle")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - QVERIFY(test->doAction(QAccessible::Press, 0)); - QTest::qWait(500); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); - QCOMPARE(test->state(0), (int)QAccessible::Mixed); - QVERIFY(test->doAction(QAccessible::Press, 0)); - QTest::qWait(500); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); - QCOMPARE(test->state(0), (int)QAccessible::Checked); - test->release(); + QCOMPARE(actionInterface->name(0), QString("Uncheck")); + QVERIFY(interface->state(0) & QAccessible::Checked); + QVERIFY(checkBox.isChecked()); + delete interface; + +// // test tristate check box +// QVERIFY(QAccessible::queryAccessibleInterface(&tristate, &test)); +// QCOMPARE(test->role(0), QAccessible::CheckBox); +// QCOMPARE(test->defaultAction(0), QAccessible::Press); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Toggle")); +// QCOMPARE(test->state(0), (int)QAccessible::Normal); +// QVERIFY(test->doAction(QAccessible::Press, 0)); +// QTest::qWait(500); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); +// QCOMPARE(test->state(0), (int)QAccessible::Mixed); +// QVERIFY(test->doAction(QAccessible::Press, 0)); +// QTest::qWait(500); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); +// QCOMPARE(test->state(0), (int)QAccessible::Checked); +// test->release(); // test radiobutton - QVERIFY(QAccessible::queryAccessibleInterface(&radio, &test)); - QCOMPARE(test->role(0), QAccessible::RadioButton); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - QVERIFY(test->doAction(QAccessible::Press, 0)); - QTest::qWait(500); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); - QCOMPARE(test->state(0), (int)QAccessible::Checked); - test->release(); - - // test standard toolbutton - QVERIFY(QAccessible::queryAccessibleInterface(&toolbutton, &test)); - QCOMPARE(test->role(0), QAccessible::PushButton); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - test->release(); - - // toggle tool button - QVERIFY(QAccessible::queryAccessibleInterface(&toggletool, &test)); - QCOMPARE(test->role(0), QAccessible::CheckBox); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); - QCOMPARE(test->state(0), (int)QAccessible::Normal); - QVERIFY(test->doAction(QAccessible::Press, 0)); + interface = QAccessible::queryAccessibleInterface(&radio); + actionInterface = interface->actionInterface(); + QCOMPARE(interface->role(0), QAccessible::RadioButton); + QCOMPARE(actionInterface->name(0), QString("Check")); + QVERIFY((interface->state(0) & QAccessible::Checked) == 0); + actionInterface->doAction(0); QTest::qWait(500); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); - QCOMPARE(test->state(0), (int)QAccessible::Checked); - test->release(); - - // test menu toolbutton - QVERIFY(QAccessible::queryAccessibleInterface(&menuToolButton, &test)); - QCOMPARE(test->role(0), QAccessible::ButtonMenu); - QCOMPARE(test->defaultAction(0), 1); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Open")); - QCOMPARE(test->state(0), (int)QAccessible::HasPopup); - QCOMPARE(test->actionCount(0), 1); - QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 0), QString("Press")); - test->release(); - - // test splitted menu toolbutton - QVERIFY(QAccessible::queryAccessibleInterface(&splitToolButton, &test)); - QCOMPARE(test->childCount(), 2); - QCOMPARE(test->role(0), QAccessible::ButtonDropDown); - QCOMPARE(test->role(1), QAccessible::PushButton); - QCOMPARE(test->role(2), QAccessible::ButtonMenu); - QCOMPARE(test->defaultAction(0), QAccessible::Press); - QCOMPARE(test->defaultAction(1), QAccessible::Press); - QCOMPARE(test->defaultAction(2), QAccessible::Press); - QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press")); - QCOMPARE(test->state(0), (int)QAccessible::HasPopup); - QCOMPARE(test->actionCount(0), 1); - QCOMPARE(test->actionText(1, QAccessible::Name, 0), QString("Open")); - QCOMPARE(test->actionText(test->defaultAction(1), QAccessible::Name, 1), QString("Press")); - QCOMPARE(test->state(1), (int)QAccessible::Normal); - QCOMPARE(test->actionText(test->defaultAction(2), QAccessible::Name, 2), QString("Open")); - QCOMPARE(test->state(2), (int)QAccessible::HasPopup); - test->release(); + QCOMPARE(actionInterface->name(0), QString("Uncheck")); + QVERIFY(interface->state(0) & QAccessible::Checked); + QVERIFY(checkBox.isChecked()); + delete interface; + +// // test standard toolbutton +// QVERIFY(QAccessible::queryAccessibleInterface(&toolbutton, &test)); +// QCOMPARE(test->role(0), QAccessible::PushButton); +// QCOMPARE(test->defaultAction(0), QAccessible::Press); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press")); +// QCOMPARE(test->state(0), (int)QAccessible::Normal); +// test->release(); + +// // toggle tool button +// QVERIFY(QAccessible::queryAccessibleInterface(&toggletool, &test)); +// QCOMPARE(test->role(0), QAccessible::CheckBox); +// QCOMPARE(test->defaultAction(0), QAccessible::Press); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Check")); +// QCOMPARE(test->state(0), (int)QAccessible::Normal); +// QVERIFY(test->doAction(QAccessible::Press, 0)); +// QTest::qWait(500); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Uncheck")); +// QCOMPARE(test->state(0), (int)QAccessible::Checked); +// test->release(); + +// // test menu toolbutton +// QVERIFY(QAccessible::queryAccessibleInterface(&menuToolButton, &test)); +// QCOMPARE(test->role(0), QAccessible::ButtonMenu); +// QCOMPARE(test->defaultAction(0), 1); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Open")); +// QCOMPARE(test->state(0), (int)QAccessible::HasPopup); +// QCOMPARE(test->actionCount(0), 1); +// QCOMPARE(test->actionText(QAccessible::Press, QAccessible::Name, 0), QString("Press")); +// test->release(); + +// // test splitted menu toolbutton +// QVERIFY(QAccessible::queryAccessibleInterface(&splitToolButton, &test)); +// QCOMPARE(test->childCount(), 2); +// QCOMPARE(test->role(0), QAccessible::ButtonDropDown); +// QCOMPARE(test->role(1), QAccessible::PushButton); +// QCOMPARE(test->role(2), QAccessible::ButtonMenu); +// QCOMPARE(test->defaultAction(0), QAccessible::Press); +// QCOMPARE(test->defaultAction(1), QAccessible::Press); +// QCOMPARE(test->defaultAction(2), QAccessible::Press); +// QCOMPARE(test->actionText(test->defaultAction(0), QAccessible::Name, 0), QString("Press")); +// QCOMPARE(test->state(0), (int)QAccessible::HasPopup); +// QCOMPARE(test->actionCount(0), 1); +// QCOMPARE(test->actionText(1, QAccessible::Name, 0), QString("Open")); +// QCOMPARE(test->actionText(test->defaultAction(1), QAccessible::Name, 1), QString("Press")); +// QCOMPARE(test->state(1), (int)QAccessible::Normal); +// QCOMPARE(test->actionText(test->defaultAction(2), QAccessible::Name, 2), QString("Open")); +// QCOMPARE(test->state(2), (int)QAccessible::HasPopup); +// test->release(); QTestAccessibility::clearEvents(); #else -// QSKIP("Test needs accessibility support.", SkipAll); - QSKIP("No action interface in Qt 4 yet.", SkipAll); + QSKIP("Test needs accessibility support.", SkipAll); #endif } @@ -2350,6 +2417,99 @@ void tst_QAccessibility::tabTest() #endif } +void tst_QAccessibility::tabWidgetTest() +{ +#ifdef QTEST_ACCESSIBILITY + QTabWidget *tabWidget = new QTabWidget(); + tabWidget->show(); + + // the interface for the tab is just a container for tabbar and stacked widget + QAccessibleInterface * const interface = QAccessible::queryAccessibleInterface(tabWidget); + QVERIFY(interface); + QCOMPARE(interface->childCount(), 2); + QCOMPARE(interface->role(0), QAccessible::Client); + + // Create pages, check navigation + QLabel *label1 = new QLabel("Page 1", tabWidget); + tabWidget->addTab(label1, "Tab 1"); + QLabel *label2 = new QLabel("Page 2", tabWidget); + tabWidget->addTab(label2, "Tab 2"); + + QCOMPARE(interface->childCount(), 2); + + QAccessibleInterface* tabBarInterface = 0; + // there is no special logic to sort the children, so the contents will be 1, the tab bar 2 + QCOMPARE(interface->navigate(QAccessible::Child, 2 , &tabBarInterface), 0); + QVERIFY(tabBarInterface); + QCOMPARE(tabBarInterface->childCount(), 4); + QCOMPARE(tabBarInterface->role(0), QAccessible::PageTabList); + + QAccessibleInterface* tabButton1Interface = 0; + QCOMPARE(tabBarInterface->navigate(QAccessible::Child, 1 , &tabButton1Interface), 1); + QVERIFY(tabButton1Interface == 0); + + QCOMPARE(tabBarInterface->role(1), QAccessible::PageTab); + QCOMPARE(tabBarInterface->text(QAccessible::Name, 1), QLatin1String("Tab 1")); + QCOMPARE(tabBarInterface->role(2), QAccessible::PageTab); + QCOMPARE(tabBarInterface->text(QAccessible::Name, 2), QLatin1String("Tab 2")); + QCOMPARE(tabBarInterface->role(3), QAccessible::PushButton); + QCOMPARE(tabBarInterface->text(QAccessible::Name, 3), QLatin1String("Scroll Left")); + QCOMPARE(tabBarInterface->role(4), QAccessible::PushButton); + QCOMPARE(tabBarInterface->text(QAccessible::Name, 4), QLatin1String("Scroll Right")); + + QAccessibleInterface* stackWidgetInterface = 0; + QCOMPARE(interface->navigate(QAccessible::Child, 1, &stackWidgetInterface), 0); + QVERIFY(stackWidgetInterface); + QCOMPARE(stackWidgetInterface->childCount(), 2); + QCOMPARE(stackWidgetInterface->role(0), QAccessible::LayeredPane); + + QAccessibleInterface* stackChild1Interface = 0; + QCOMPARE(stackWidgetInterface->navigate(QAccessible::Child, 1, &stackChild1Interface), 0); + QVERIFY(stackChild1Interface); +#ifndef Q_CC_INTEL + QCOMPARE(stackChild1Interface->childCount(), 0); +#endif + QCOMPARE(stackChild1Interface->role(0), QAccessible::StaticText); + QCOMPARE(stackChild1Interface->text(QAccessible::Name, 0), QLatin1String("Page 1")); + QCOMPARE(label1, stackChild1Interface->object()); + + // Navigation in stack widgets should be consistent + QAccessibleInterface* parent = 0; + QCOMPARE(stackChild1Interface->navigate(QAccessible::Ancestor, 1, &parent), 0); + QVERIFY(parent); +#ifndef Q_CC_INTEL + QCOMPARE(parent->childCount(), 2); +#endif + QCOMPARE(parent->role(0), QAccessible::LayeredPane); + delete parent; + + QAccessibleInterface* stackChild2Interface = 0; + QCOMPARE(stackWidgetInterface->navigate(QAccessible::Child, 2, &stackChild2Interface), 0); + QVERIFY(stackChild2Interface); + QCOMPARE(stackChild2Interface->childCount(), 0); + QCOMPARE(stackChild2Interface->role(0), QAccessible::StaticText); + QCOMPARE(label2, stackChild2Interface->object()); // the text will be empty since it is not visible + + QCOMPARE(stackChild2Interface->navigate(QAccessible::Ancestor, 1, &parent), 0); + QVERIFY(parent); +#ifndef Q_CC_INTEL + QCOMPARE(parent->childCount(), 2); +#endif + QCOMPARE(parent->role(0), QAccessible::LayeredPane); + delete parent; + + delete tabBarInterface; + delete stackChild1Interface; + delete stackChild2Interface; + delete stackWidgetInterface; + delete interface; + delete tabWidget; + QTestAccessibility::clearEvents(); +#else + QSKIP("Test needs accessibility support.", SkipAll); +#endif +} + void tst_QAccessibility::menuTest() { #ifdef QTEST_ACCESSIBILITY @@ -2679,6 +2839,11 @@ void tst_QAccessibility::textEditTest() QCOMPARE(iface->text(QAccessible::Value, 4), QString("hello world")); QCOMPARE(iface->text(QAccessible::Value, 5), QString("how are you today?")); QCOMPARE(iface->text(QAccessible::Value, 6), QString()); + QCOMPARE(iface->textInterface()->characterCount(), 31); + QFontMetrics fm(edit.font()); + QCOMPARE(iface->textInterface()->characterRect(0, QAccessible2::RelativeToParent).size(), QSize(fm.width("h"), fm.height())); + QCOMPARE(iface->textInterface()->characterRect(5, QAccessible2::RelativeToParent).size(), QSize(fm.width(" "), fm.height())); + QCOMPARE(iface->textInterface()->characterRect(6, QAccessible2::RelativeToParent).size(), QSize(fm.width("w"), fm.height())); } QTestAccessibility::clearEvents(); #else @@ -3883,10 +4048,10 @@ void tst_QAccessibility::pushButtonTest() QAccessibleInterface *acc; QAccessibleInterface *acc2; int entry = accToplevel->childAt(pt.x(), pt.y()); - int child = accToplevel->navigate(QAccessible::Child, entry, &acc); + accToplevel->navigate(QAccessible::Child, entry, &acc); if (acc) { entry = acc->childAt(pt.x(), pt.y()); - child = acc->navigate(QAccessible::Child, entry, &acc2); + acc->navigate(QAccessible::Child, entry, &acc2); delete acc; acc = acc2; } diff --git a/tests/auto/qcomplextext/tst_qcomplextext.cpp b/tests/auto/qcomplextext/tst_qcomplextext.cpp index 3d8e290..58b31b4 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(QTextCursor::Visual); + 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/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/qfilesystemmodel/tst_qfilesystemmodel.cpp b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp index 53781c9..e8d0f57 100644 --- a/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp +++ b/tests/auto/qfilesystemmodel/tst_qfilesystemmodel.cpp @@ -632,7 +632,12 @@ void tst_QFileSystemModel::filters_data() QTest::addColumn<int>("rowCount"); #if !defined(Q_OS_WINCE) && !defined(Q_OS_SYMBIAN) QTest::newRow("no dirs") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs) << QStringList() << 2; - QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1; + QTest::newRow("no dirs - dot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 1; + QTest::newRow("no dirs - dotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 1; + QTest::newRow("no dirs - dotanddotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 0; + QTest::newRow("one dir - dot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 2; + QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 2; + QTest::newRow("one dir - dotanddotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1; QTest::newRow("one dir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs) << QStringList() << 3; QTest::newRow("no dir + hidden") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::Hidden) << QStringList() << 2; QTest::newRow("dir+hid+files") << (QStringList() << "a" << "b" << "c") << QStringList() << @@ -650,7 +655,12 @@ void tst_QFileSystemModel::filters_data() #else QTest::qWait(3000); // We need to calm down a bit... QTest::newRow("no dirs") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs) << QStringList() << 0; - QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1; + QTest::newRow("no dirs - dot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 1; + QTest::newRow("no dirs - dotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 1; + QTest::newRow("no dirs - dotanddotdot") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 0; + QTest::newRow("one dir - dot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDot) << QStringList() << 2; + QTest::newRow("one dir - dotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotDot) << QStringList() << 2; + QTest::newRow("one dir - dotanddotdot") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs | QDir::NoDotAndDotDot) << QStringList() << 1; QTest::newRow("one dir") << (QStringList() << "a" << "b" << "c") << (QStringList() << "Z") << (int)(QDir::Dirs) << QStringList() << 1; QTest::newRow("no dir + hidden") << (QStringList() << "a" << "b" << "c") << QStringList() << (int)(QDir::Dirs | QDir::Hidden) << QStringList() << 0; QTest::newRow("dir+hid+files") << (QStringList() << "a" << "b" << "c") << QStringList() << @@ -699,10 +709,23 @@ void tst_QFileSystemModel::filters() // Make sure that we do what QDir does QDir xFactor(tmp); QDir::Filters filters = (QDir::Filters)dirFilters; + QStringList dirEntries; + if (nameFilters.count() > 0) - QCOMPARE(xFactor.entryList(nameFilters, filters).count(), rowCount); + dirEntries = xFactor.entryList(nameFilters, filters); else - QVERIFY(xFactor.entryList(filters).count() == rowCount); + dirEntries = xFactor.entryList(filters); + + QCOMPARE(dirEntries.count(), rowCount); + + QStringList modelEntries; + + for (int i = 0; i < rowCount; ++i) + modelEntries.append(model->data(model->index(i, 0, root), QFileSystemModel::FileNameRole).toString()); + + qSort(dirEntries); + qSort(modelEntries); + QCOMPARE(dirEntries, modelEntries); #ifdef Q_OS_LINUX if (files.count() >= 3 && rowCount >= 3 && rowCount != 5) { diff --git a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp index e7c63d5..447385a 100644 --- a/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp +++ b/tests/auto/qgraphicsanchorlayout/tst_qgraphicsanchorlayout.cpp @@ -1091,6 +1091,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/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/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/qidentityproxymodel/qidentityproxymodel.pro b/tests/auto/qidentityproxymodel/qidentityproxymodel.pro new file mode 100644 index 0000000..f529e20 --- /dev/null +++ b/tests/auto/qidentityproxymodel/qidentityproxymodel.pro @@ -0,0 +1,6 @@ +load(qttest_p4) + +INCLUDEPATH += $$PWD/../modeltest + +SOURCES += tst_qidentityproxymodel.cpp ../modeltest/dynamictreemodel.cpp ../modeltest/modeltest.cpp +HEADERS += ../modeltest/dynamictreemodel.h ../modeltest/modeltest.h diff --git a/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp b/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp new file mode 100644 index 0000000..cfc3f1a --- /dev/null +++ b/tests/auto/qidentityproxymodel/tst_qidentityproxymodel.cpp @@ -0,0 +1,334 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com> +** 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 <QtTest/QtTest> +#include "../../shared/util.h" + +#include <QtCore> +#include <QtGui> + +#include "dynamictreemodel.h" +#include "qidentityproxymodel.h" + +//TESTED CLASS= +//TESTED_FILES= + +Q_DECLARE_METATYPE(QModelIndex) + +class tst_QIdentityProxyModel : public QObject +{ + Q_OBJECT + +public: + + tst_QIdentityProxyModel(); + virtual ~tst_QIdentityProxyModel(); + +public slots: + void initTestCase(); + void cleanupTestCase(); + void init(); + void cleanup(); + +private slots: + void insertRows(); + void removeRows(); + void moveRows(); + void reset(); + +protected: + void verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent = QModelIndex()); + +private: + QStandardItemModel *m_model; + QIdentityProxyModel *m_proxy; +}; + +tst_QIdentityProxyModel::tst_QIdentityProxyModel() + : m_model(0), m_proxy(0) +{ + +} + +tst_QIdentityProxyModel::~tst_QIdentityProxyModel() +{ + +} + +void tst_QIdentityProxyModel::initTestCase() +{ + qRegisterMetaType<QModelIndex>("QModelIndex"); + + m_model = new QStandardItemModel(0, 1); + m_proxy = new QIdentityProxyModel(); +} + +void tst_QIdentityProxyModel::cleanupTestCase() +{ + delete m_proxy; + delete m_model; +} + +void tst_QIdentityProxyModel::init() +{ +} + +void tst_QIdentityProxyModel::cleanup() +{ + m_model->clear(); + m_model->insertColumns(0, 1); +} + +void tst_QIdentityProxyModel::verifyIdentity(QAbstractItemModel *model, const QModelIndex &parent) +{ + const int rows = model->rowCount(parent); + const int columns = model->columnCount(parent); + const QModelIndex proxyParent = m_proxy->mapFromSource(parent); + + QVERIFY(m_proxy->mapToSource(proxyParent) == parent); + QVERIFY(rows == m_proxy->rowCount(proxyParent)); + QVERIFY(columns == m_proxy->columnCount(proxyParent)); + + for (int row = 0; row < rows; ++row) { + for (int column = 0; column < columns; ++column) { + const QModelIndex idx = model->index(row, column, parent); + const QModelIndex proxyIdx = m_proxy->mapFromSource(idx); + QVERIFY(proxyIdx.model() == m_proxy); + QVERIFY(m_proxy->mapToSource(proxyIdx) == idx); + QVERIFY(proxyIdx.isValid()); + QVERIFY(proxyIdx.row() == row); + QVERIFY(proxyIdx.column() == column); + QVERIFY(proxyIdx.parent() == proxyParent); + QVERIFY(proxyIdx.data() == idx.data()); + QVERIFY(proxyIdx.flags() == idx.flags()); + const int childCount = m_proxy->rowCount(proxyIdx); + const bool hasChildren = m_proxy->hasChildren(proxyIdx); + QVERIFY(model->hasChildren(idx) == hasChildren); + QVERIFY((childCount > 0) == hasChildren); + + if (hasChildren) + verifyIdentity(model, idx); + } + } +} + +/* + tests +*/ + +void tst_QIdentityProxyModel::insertRows() +{ + QStandardItem *parentItem = m_model->invisibleRootItem(); + for (int i = 0; i < 4; ++i) { + QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); + parentItem->appendRow(item); + parentItem = item; + } + + m_proxy->setSourceModel(m_model); + + verifyIdentity(m_model); + + QSignalSpy modelBeforeSpy(m_model, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int))); + QSignalSpy modelAfterSpy(m_model, SIGNAL(rowsInserted(QModelIndex,int,int))); + QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(rowsAboutToBeInserted(QModelIndex,int,int))); + QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(rowsInserted(QModelIndex,int,int))); + + QStandardItem *item = new QStandardItem(QString("new item")); + parentItem->appendRow(item); + + QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size()); + QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size()); + + QVERIFY(modelBeforeSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyBeforeSpy.first().first().value<QModelIndex>())); + QVERIFY(modelBeforeSpy.first().at(1) == proxyBeforeSpy.first().at(1)); + QVERIFY(modelBeforeSpy.first().at(2) == proxyBeforeSpy.first().at(2)); + + QVERIFY(modelAfterSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyAfterSpy.first().first().value<QModelIndex>())); + QVERIFY(modelAfterSpy.first().at(1) == proxyAfterSpy.first().at(1)); + QVERIFY(modelAfterSpy.first().at(2) == proxyAfterSpy.first().at(2)); + + verifyIdentity(m_model); + +} + +void tst_QIdentityProxyModel::removeRows() +{ + QStandardItem *parentItem = m_model->invisibleRootItem(); + for (int i = 0; i < 4; ++i) { + QStandardItem *item = new QStandardItem(QString("item %0").arg(i)); + parentItem->appendRow(item); + parentItem = item; + } + + m_proxy->setSourceModel(m_model); + + verifyIdentity(m_model); + + QSignalSpy modelBeforeSpy(m_model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int))); + QSignalSpy modelAfterSpy(m_model, SIGNAL(rowsRemoved(QModelIndex,int,int))); + QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int))); + QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(rowsRemoved(QModelIndex,int,int))); + + const QModelIndex topLevel = m_model->index(0, 0, QModelIndex()); + const QModelIndex secondLevel = m_model->index(0, 0, topLevel); + const QModelIndex thirdLevel = m_model->index(0, 0, secondLevel); + + QVERIFY(thirdLevel.isValid()); + + m_model->removeRow(0, secondLevel); + + QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size()); + QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size()); + + QVERIFY(modelBeforeSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyBeforeSpy.first().first().value<QModelIndex>())); + QVERIFY(modelBeforeSpy.first().at(1) == proxyBeforeSpy.first().at(1)); + QVERIFY(modelBeforeSpy.first().at(2) == proxyBeforeSpy.first().at(2)); + + QVERIFY(modelAfterSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyAfterSpy.first().first().value<QModelIndex>())); + QVERIFY(modelAfterSpy.first().at(1) == proxyAfterSpy.first().at(1)); + QVERIFY(modelAfterSpy.first().at(2) == proxyAfterSpy.first().at(2)); + + verifyIdentity(m_model); +} + +void tst_QIdentityProxyModel::moveRows() +{ + DynamicTreeModel model; + + { + ModelInsertCommand insertCommand(&model); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + { + ModelInsertCommand insertCommand(&model); + insertCommand.setAncestorRowNumbers(QList<int>() << 5); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + + m_proxy->setSourceModel(&model); + + verifyIdentity(&model); + + QSignalSpy modelBeforeSpy(&model, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy modelAfterSpy(&model, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(rowsAboutToBeMoved(QModelIndex,int,int,QModelIndex,int))); + QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(rowsMoved(QModelIndex,int,int,QModelIndex,int))); + + { + ModelMoveCommand moveCommand(&model, 0); + moveCommand.setAncestorRowNumbers(QList<int>() << 5); + moveCommand.setStartRow(3); + moveCommand.setEndRow(4); + moveCommand.setDestRow(1); + moveCommand.doCommand(); + } + + QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size()); + QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size()); + + QVERIFY(modelBeforeSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyBeforeSpy.first().first().value<QModelIndex>())); + QVERIFY(modelBeforeSpy.first().at(1) == proxyBeforeSpy.first().at(1)); + QVERIFY(modelBeforeSpy.first().at(2) == proxyBeforeSpy.first().at(2)); + QVERIFY(modelBeforeSpy.first().at(3).value<QModelIndex>() == m_proxy->mapToSource(proxyBeforeSpy.first().at(3).value<QModelIndex>())); + QVERIFY(modelBeforeSpy.first().at(4) == proxyBeforeSpy.first().at(4)); + + QVERIFY(modelAfterSpy.first().first().value<QModelIndex>() == m_proxy->mapToSource(proxyAfterSpy.first().first().value<QModelIndex>())); + QVERIFY(modelAfterSpy.first().at(1) == proxyAfterSpy.first().at(1)); + QVERIFY(modelAfterSpy.first().at(2) == proxyAfterSpy.first().at(2)); + QVERIFY(modelAfterSpy.first().at(3).value<QModelIndex>() == m_proxy->mapToSource(proxyAfterSpy.first().at(3).value<QModelIndex>())); + QVERIFY(modelAfterSpy.first().at(4) == proxyAfterSpy.first().at(4)); + + verifyIdentity(&model); + + m_proxy->setSourceModel(0); +} + +void tst_QIdentityProxyModel::reset() +{ + DynamicTreeModel model; + + { + ModelInsertCommand insertCommand(&model); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + { + ModelInsertCommand insertCommand(&model); + insertCommand.setAncestorRowNumbers(QList<int>() << 5); + insertCommand.setStartRow(0); + insertCommand.setEndRow(9); + insertCommand.doCommand(); + } + + m_proxy->setSourceModel(&model); + + verifyIdentity(&model); + + QSignalSpy modelBeforeSpy(&model, SIGNAL(modelAboutToBeReset())); + QSignalSpy modelAfterSpy(&model, SIGNAL(modelReset())); + QSignalSpy proxyBeforeSpy(m_proxy, SIGNAL(modelAboutToBeReset())); + QSignalSpy proxyAfterSpy(m_proxy, SIGNAL(modelReset())); + + { + ModelResetCommandFixed resetCommand(&model, 0); + resetCommand.setAncestorRowNumbers(QList<int>() << 5); + resetCommand.setStartRow(3); + resetCommand.setEndRow(4); + resetCommand.setDestRow(1); + resetCommand.doCommand(); + } + + QVERIFY(modelBeforeSpy.size() == 1 && 1 == proxyBeforeSpy.size()); + QVERIFY(modelAfterSpy.size() == 1 && 1 == proxyAfterSpy.size()); + + verifyIdentity(&model); + m_proxy->setSourceModel(0); +} + +QTEST_MAIN(tst_QIdentityProxyModel) +#include "tst_qidentityproxymodel.moc" diff --git a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp index 6e20fb2..d91b068 100644 --- a/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp +++ b/tests/auto/qitemselectionmodel/tst_qitemselectionmodel.cpp @@ -101,6 +101,7 @@ private slots: void testDifferentModels(); void testValidRangesInSelectionsAfterReset(); + void testChainedSelectionClear(); private: QAbstractItemModel *model; @@ -2655,5 +2656,58 @@ void tst_QItemSelectionModel::testValidRangesInSelectionsAfterReset() model.setStringList(strings); } +class DuplicateItemSelectionModel : public QItemSelectionModel +{ + Q_OBJECT +public: + DuplicateItemSelectionModel(QItemSelectionModel *target, QAbstractItemModel *model, QObject *parent = 0) + : QItemSelectionModel(model, parent), m_target(target) + { + + } + + void select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command) + { + QItemSelectionModel::select(selection, command); + m_target->select(selection, command); + } + + using QItemSelectionModel::select; + +private: + QItemSelectionModel *m_target; + +}; + +void tst_QItemSelectionModel::testChainedSelectionClear() +{ + QStringListModel model(QStringList() << "Apples" << "Pears"); + + QItemSelectionModel selectionModel(&model, 0); + DuplicateItemSelectionModel duplicate(&selectionModel, &model, 0); + + duplicate.select(model.index(0, 0), QItemSelectionModel::Select); + + { + QModelIndexList selectedIndexes = selectionModel.selection().indexes(); + QModelIndexList duplicatedIndexes = duplicate.selection().indexes(); + + QVERIFY(selectedIndexes.size() == duplicatedIndexes.size()); + QVERIFY(selectedIndexes.size() == 1); + QVERIFY(selectedIndexes.first() == model.index(0, 0)); + } + + duplicate.clearSelection(); + + { + QModelIndexList selectedIndexes = selectionModel.selection().indexes(); + QModelIndexList duplicatedIndexes = duplicate.selection().indexes(); + + QVERIFY(selectedIndexes.size() == duplicatedIndexes.size()); + QVERIFY(selectedIndexes.size() == 0); + } + +} + QTEST_MAIN(tst_QItemSelectionModel) #include "tst_qitemselectionmodel.moc" diff --git a/tests/auto/qlineedit/tst_qlineedit.cpp b/tests/auto/qlineedit/tst_qlineedit.cpp index 9176174..f45481c 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(QTextCursor::Visual); + 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(QTextCursor::Logical); + 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/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/qpainter/tst_qpainter.cpp b/tests/auto/qpainter/tst_qpainter.cpp index c21514b..76bc5d63 100644 --- a/tests/auto/qpainter/tst_qpainter.cpp +++ b/tests/auto/qpainter/tst_qpainter.cpp @@ -77,6 +77,7 @@ # define SRCDIR "." #endif +Q_DECLARE_METATYPE(QGradientStops) Q_DECLARE_METATYPE(QLine) Q_DECLARE_METATYPE(QRect) Q_DECLARE_METATYPE(QSize) @@ -189,6 +190,7 @@ private slots: void fillRect_stretchToDeviceMode(); void monoImages(); + void linearGradientSymmetry_data(); void linearGradientSymmetry(); void gradientInterpolation(); @@ -3983,8 +3985,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 +4028,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 +4040,7 @@ void tst_QPainter::linearGradientSymmetry() b = b.mirrored(true); QCOMPARE(a, b); +#endif } void tst_QPainter::gradientInterpolation() diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp index 4d032e8..98f7839 100644 --- a/tests/auto/qpixmap/tst_qpixmap.cpp +++ b/tests/auto/qpixmap/tst_qpixmap.cpp @@ -196,6 +196,8 @@ private slots: #if defined(Q_OS_SYMBIAN) && !defined(QT_NO_OPENVG) void vgImageReadBack(); #endif + + void drawPixmapWhilePainterOpen(); }; static bool lenientCompare(const QPixmap &actual, const QPixmap &expected) @@ -1337,7 +1339,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 +1372,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() @@ -1897,5 +1899,64 @@ 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)); + } +} + 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/qscriptengine/tst_qscriptengine.cpp b/tests/auto/qscriptengine/tst_qscriptengine.cpp index bc4091d..7ba2be2 100644 --- a/tests/auto/qscriptengine/tst_qscriptengine.cpp +++ b/tests/auto/qscriptengine/tst_qscriptengine.cpp @@ -5815,6 +5815,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 +5830,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/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp index d26f0cd..8e7f393 100644 --- a/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp +++ b/tests/auto/qsortfilterproxymodel/tst_qsortfilterproxymodel.cpp @@ -149,7 +149,6 @@ private slots: void testMultipleProxiesWithSelection(); void mapSelectionFromSource(); - void testResetInternalData(); void filteredColumns(); protected: @@ -3183,142 +3182,6 @@ void tst_QSortFilterProxyModel::taskQTBUG_10287_unnecessaryMapCreation() // No assert failure, it passes. } -/** - * A proxy which changes the background color for items ending in 'y' or 'r' - */ -class CustomDataProxy : public QSortFilterProxyModel -{ - Q_OBJECT - -public: - CustomDataProxy(QObject *parent = 0) - : QSortFilterProxyModel(parent) - { - setDynamicSortFilter(true); - } - - void setSourceModel(QAbstractItemModel *sourceModel) - { - // It would be possible to use only the modelReset signal of the source model to clear - // the data in *this, however, this requires that the slot is connected - // before QSortFilterProxyModel::setSourceModel is called, and even then depends - // on the order of invokation of slots being the same as the order of connection. - // ie, not reliable. -// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData())); - QSortFilterProxyModel::setSourceModel(sourceModel); - // Making the connect after the setSourceModel call clears the data too late. -// connect(sourceModel, SIGNAL(modelReset()), SLOT(resetInternalData())); - - // This could be done in data(), but the point is to need to cache something in the proxy - // which needs to be cleared on reset. - for (int i = 0; i < sourceModel->rowCount(); ++i) - { - if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('y'))) - { - m_backgroundColours.insert(i, Qt::blue); - } else if (sourceModel->index(i, 0).data().toString().endsWith(QLatin1Char('r'))) - { - m_backgroundColours.insert(i, Qt::red); - } - } - } - - QVariant data(const QModelIndex &index, int role) const - { - if (role != Qt::BackgroundRole) - return QSortFilterProxyModel::data(index, role); - return m_backgroundColours.value(index.row()); - } - -private slots: - void resetInternalData() - { - m_backgroundColours.clear(); - } - -private: - QHash<int, QColor> m_backgroundColours; -}; - -class ModelObserver : public QObject -{ - Q_OBJECT -public: - ModelObserver(QAbstractItemModel *model, QObject *parent = 0) - : QObject(parent), m_model(model) - { - connect(m_model, SIGNAL(modelAboutToBeReset()), SLOT(modelAboutToBeReset())); - connect(m_model, SIGNAL(modelReset()), SLOT(modelReset())); - } - -public slots: - void modelAboutToBeReset() - { - int reds = 0, blues = 0; - for (int i = 0; i < m_model->rowCount(); ++i) - { - QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>(); - if (color == Qt::blue) - ++blues; - if (color == Qt::red) - ++reds; - } - QCOMPARE(blues, 11); - QCOMPARE(reds, 4); - } - - void modelReset() - { - int reds = 0, blues = 0; - for (int i = 0; i < m_model->rowCount(); ++i) - { - QColor color = m_model->index(i, 0).data(Qt::BackgroundRole).value<QColor>(); - if (color == Qt::blue) - ++blues; - if (color == Qt::red) - ++reds; - } - QCOMPARE(reds, 0); - QCOMPARE(blues, 0); - } - -private: - QAbstractItemModel * const m_model; - -}; - -void tst_QSortFilterProxyModel::testResetInternalData() -{ - - QStringListModel model(QStringList() << "Monday" - << "Tuesday" - << "Wednesday" - << "Thursday" - << "Friday" - << "January" - << "February" - << "March" - << "April" - << "May" - << "Saturday" - << "June" - << "Sunday" - << "July" - << "August" - << "September" - << "October" - << "November" - << "December"); - - CustomDataProxy proxy; - proxy.setSourceModel(&model); - - ModelObserver observer(&proxy); - - // Cause the source model to reset. - model.setStringList(QStringList() << "Spam" << "Eggs"); -} - class FilteredColumnProxyModel : public QSortFilterProxyModel { Q_OBJECT diff --git a/tests/auto/qtablewidget/tst_qtablewidget.cpp b/tests/auto/qtablewidget/tst_qtablewidget.cpp index d17e064..40aece4 100644 --- a/tests/auto/qtablewidget/tst_qtablewidget.cpp +++ b/tests/auto/qtablewidget/tst_qtablewidget.cpp @@ -41,6 +41,7 @@ #include <QtTest/QtTest> +#include "../../shared/util.h" #include <qeventloop.h> #include <qlist.h> #include <qpair.h> @@ -1472,7 +1473,7 @@ void tst_QTableWidget::task219380_removeLastRow() testWidget->removeRow(19); //we remove the last row //we make sure the editor is at the cell position - QCOMPARE(testWidget->cellWidget(18, 0)->geometry(), testWidget->visualItemRect(&item)); + QTRY_COMPARE(testWidget->cellWidget(18, 0)->geometry(), testWidget->visualItemRect(&item)); } void tst_QTableWidget::task262056_sortDuplicate() diff --git a/tests/auto/qtextedit/tst_qtextedit.cpp b/tests/auto/qtextedit/tst_qtextedit.cpp index 9ca17b9..5a64593 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(); @@ -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(QTextCursor::Visual); + 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(QTextCursor::Logical); + 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/qwizard/tst_qwizard.cpp b/tests/auto/qwizard/tst_qwizard.cpp index a813727..5667d40 100644 --- a/tests/auto/qwizard/tst_qwizard.cpp +++ b/tests/auto/qwizard/tst_qwizard.cpp @@ -1770,8 +1770,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 +2551,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 +2579,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/benchmarks/corelib/io/qdir/qdir.pro b/tests/benchmarks/corelib/io/qdir/qdir.pro index c572566..2c18e75 100644 --- a/tests/benchmarks/corelib/io/qdir/qdir.pro +++ b/tests/benchmarks/corelib/io/qdir/qdir.pro @@ -1,2 +1,4 @@ TEMPLATE = subdirs -SUBDIRS = 10000 +SUBDIRS = \ + 10000 \ + tree 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/script/script.pro b/tests/benchmarks/script/script.pro index 80278d0..5da05e7 100644 --- a/tests/benchmarks/script/script.pro +++ b/tests/benchmarks/script/script.pro @@ -14,7 +14,6 @@ TRUSTED_BENCHMARKS += \ qscriptclass \ qscriptvalue \ qscriptengine \ - qscriptobject \ - context2d + qscriptqobject include(../trusted-benchmarks.pri) 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/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 69afde9..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> @@ -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/htmlgenerator.cpp b/tools/qdoc3/htmlgenerator.cpp index 88bc3e2..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) @@ -2849,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;) { @@ -2884,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/qdoc3/test/qdeclarative.qdocconf b/tools/qdoc3/test/qdeclarative.qdocconf index 4abe40c..2ae2fd6 100644 --- a/tools/qdoc3/test/qdeclarative.qdocconf +++ b/tools/qdoc3/test/qdeclarative.qdocconf @@ -6,7 +6,7 @@ include(qt-defines.qdocconf) project = Qml description = Qml Reference Documentation -url = http://qt.nokia.com/doc/4.7/ +url = http://qt.nokia.com/doc/4.8/ qmlonly = true edition.Console.modules = QtCore QtDBus QtNetwork QtScript QtSql QtXml \ @@ -29,9 +29,9 @@ qhp.Qml.indexTitle = Qml Reference # See also extraimages.HTML qhp.Qml.extraFiles = images/bg_l.png \ images/bg_l_blank.png \ - images/bg_ll_blank.png \ - images/bg_ul_blank.png \ - images/header_bg.png \ + images/bg_ll_blank.png \ + images/bg_ul_blank.png \ + images/header_bg.png \ images/bg_r.png \ images/box_bg.png \ images/breadcrumb.png \ diff --git a/tools/qdoc3/test/qt-html-templates-online.qdocconf b/tools/qdoc3/test/qt-html-templates-online.qdocconf index 77ab3c5..03ed6fa 100644 --- a/tools/qdoc3/test/qt-html-templates-online.qdocconf +++ b/tools/qdoc3/test/qt-html-templates-online.qdocconf @@ -19,7 +19,7 @@ HTML.postheader = \ " </div>\n" \ " <div id=\"shortCut\">\n" \ " <ul>\n" \ - " <li class=\"shortCut-topleft-inactive\"><span><a href=\"index.html\">Qt 4.7</a></span></li>\n" \ + " <li class=\"shortCut-topleft-inactive\"><span><a href=\"index.html\">Qt 4.8</a></span></li>\n" \ " <li class=\"shortCut-topleft-active\"><a href=\"http://doc.qt.nokia.com\">ALL VERSIONS" \ " </a></li>\n" \ " </ul>\n" \ diff --git a/tools/qdoc3/test/qt-html-templates_ja_JP-online.qdocconf b/tools/qdoc3/test/qt-html-templates_ja_JP-online.qdocconf index a69d7a1..8dc17af 100644 --- a/tools/qdoc3/test/qt-html-templates_ja_JP-online.qdocconf +++ b/tools/qdoc3/test/qt-html-templates_ja_JP-online.qdocconf @@ -24,7 +24,7 @@ HTML.postheader = \ " </div>\n" \ " <div id=\"shortCut\">\n" \ " <ul>\n" \ - " <li class=\"shortCut-topleft-inactive\"><span><a href=\"index.html\">Qt 4.7</a></span></li>\n" \ + " <li class=\"shortCut-topleft-inactive\"><span><a href=\"index.html\">Qt 4.8</a></span></li>\n" \ " <li class=\"shortCut-topleft-active\"><a href=\"http://qt.nokia.com/doc/\">ALL VERSIONS" \ " </a></li>\n" \ " </ul>\n" \ diff --git a/tools/qdoc3/test/qt-html-templates_zh_CN-online.qdocconf b/tools/qdoc3/test/qt-html-templates_zh_CN-online.qdocconf index ed2162e..e7e8220 100644 --- a/tools/qdoc3/test/qt-html-templates_zh_CN-online.qdocconf +++ b/tools/qdoc3/test/qt-html-templates_zh_CN-online.qdocconf @@ -24,7 +24,7 @@ HTML.postheader = \ " </div>\n" \ " <div id=\"shortCut\">\n" \ " <ul>\n" \ - " <li class=\"shortCut-topleft-inactive\"><span><a href=\"index.html\">Qt 4.7</a></span></li>\n" \ + " <li class=\"shortCut-topleft-inactive\"><span><a href=\"index.html\">Qt 4.8</a></span></li>\n" \ " <li class=\"shortCut-topleft-active\"><a href=\"http://qt.nokia.com/doc/\">ALL VERSIONS" \ " </a></li>\n" \ " </ul>\n" \ diff --git a/tools/qdoc3/test/qt-project.qdocconf b/tools/qdoc3/test/qt-project.qdocconf index d03dfd2..fca6545 100644 --- a/tools/qdoc3/test/qt-project.qdocconf +++ b/tools/qdoc3/test/qt-project.qdocconf @@ -5,8 +5,8 @@ include(qt-defines.qdocconf) project = Qt description = Qt Reference Documentation -url = http://qt.nokia.com/doc/4.7 -version = 4.7.3 +url = http://qt.nokia.com/doc/4.8 +version = 4.8.0 sourceencoding = UTF-8 outputencoding = UTF-8 @@ -15,14 +15,14 @@ naturallanguage = en_US qhp.projects = Qt qhp.Qt.file = qt.qhp -qhp.Qt.namespace = com.trolltech.qt.473 +qhp.Qt.namespace = com.trolltech.qt.480 qhp.Qt.virtualFolder = qdoc qhp.Qt.indexTitle = Qt Reference Documentation qhp.Qt.indexRoot = -qhp.Qt.filterAttributes = qt 4.7.3 qtrefdoc -qhp.Qt.customFilters.Qt.name = Qt 4.7.3 -qhp.Qt.customFilters.Qt.filterAttributes = qt 4.7.3 +qhp.Qt.filterAttributes = qt 4.8.0 qtrefdoc +qhp.Qt.customFilters.Qt.name = Qt 4.8.0 +qhp.Qt.customFilters.Qt.filterAttributes = qt 4.8.0 qhp.Qt.subprojects = classes overviews examples qhp.Qt.subprojects.classes.title = Classes qhp.Qt.subprojects.classes.indexTitle = Qt's Classes 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..24a4940 100644 --- a/tools/qml/main.cpp +++ b/tools/qml/main.cpp @@ -50,6 +50,7 @@ #include <QDebug> #include <QMessageBox> #include <QAtomicInt> +#include <QLibraryInfo> #include "qdeclarativetester.h" #include <private/qdeclarativedebughelper_p.h> @@ -67,7 +68,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 +124,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 +157,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 +200,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 +337,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 +394,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 +404,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 +528,41 @@ 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..defc368 100644 --- a/tools/qml/qml.pro +++ b/tools/qml/qml.pro @@ -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/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 |