summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Smith <msmith@trolltech.com>2010-05-04 07:29:14 (GMT)
committerMartin Smith <msmith@trolltech.com>2010-05-04 07:29:14 (GMT)
commit820568f3aedb91b411fd1a88c9a6733b883de0ef (patch)
treedc959cd08225f5421f7c9e19cc5fbc9e36e7a846
parentadf6f5fb5a4f7827df6f589cac9ca8503c50e3b1 (diff)
parente4c49c5344058aaa033a9928e96205c767b8e07d (diff)
downloadQt-820568f3aedb91b411fd1a88c9a6733b883de0ef.zip
Qt-820568f3aedb91b411fd1a88c9a6733b883de0ef.tar.gz
Qt-820568f3aedb91b411fd1a88c9a6733b883de0ef.tar.bz2
Merge branch '4.7' of git@scm.dev.nokia.troll.no:qt/oslo-staging-1 into 4.7
-rwxr-xr-xconfig.tests/unix/bsymbolic_functions.test3
-rwxr-xr-xconfigure4
-rw-r--r--doc/src/examples/dragdroprobot.qdoc334
-rw-r--r--doc/src/examples/elasticnodes.qdoc391
-rw-r--r--doc/src/getting-started/examples.qdoc4
-rw-r--r--examples/graphicsview/dragdroprobot/coloritem.cpp24
-rw-r--r--examples/graphicsview/dragdroprobot/coloritem.h2
-rw-r--r--examples/graphicsview/dragdroprobot/main.cpp8
-rw-r--r--examples/graphicsview/dragdroprobot/robot.cpp217
-rw-r--r--examples/graphicsview/dragdroprobot/robot.h29
-rw-r--r--examples/graphicsview/elasticnodes/edge.cpp30
-rw-r--r--examples/graphicsview/elasticnodes/edge.h6
-rw-r--r--examples/graphicsview/elasticnodes/graphwidget.cpp34
-rw-r--r--examples/graphicsview/elasticnodes/graphwidget.h4
-rw-r--r--examples/graphicsview/elasticnodes/node.cpp46
-rw-r--r--examples/graphicsview/elasticnodes/node.h2
-rw-r--r--mkspecs/common/symbian/symbian.conf2
-rw-r--r--qmake/generators/win32/msbuild_objectmodel.cpp24
-rw-r--r--qmake/generators/win32/msvc_vcproj.cpp19
-rw-r--r--qmake/generators/win32/msvc_vcxproj.cpp30
-rw-r--r--src/3rdparty/webkit/.tag2
-rw-r--r--src/3rdparty/webkit/VERSION2
-rw-r--r--src/3rdparty/webkit/WebCore/ChangeLog33
-rw-r--r--src/3rdparty/webkit/WebCore/WebCore.pro6
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp1
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp348
-rw-r--r--src/3rdparty/webkit/WebKit/qt/ChangeLog52
-rw-r--r--src/3rdparty/webkit/WebKit/qt/qtwebkit_version.pri4
-rw-r--r--src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp35
-rw-r--r--src/corelib/codecs/qtextcodec.cpp8
-rw-r--r--src/corelib/io/qurl.cpp4
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp23
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h7
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian.cpp2
-rw-r--r--src/corelib/kernel/qeventdispatcher_symbian_p.h1
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp2
-rw-r--r--src/corelib/plugin/qfactoryloader_p.h2
-rw-r--r--src/corelib/tools/qchar.cpp31
-rw-r--r--src/corelib/tools/qchar.h9
-rw-r--r--src/corelib/tools/qlocale.cpp12
-rw-r--r--src/corelib/tools/qlocale_p.h18
-rw-r--r--src/corelib/tools/qlocale_symbian.cpp53
-rw-r--r--src/corelib/tools/qmap.h20
-rw-r--r--src/gui/accessible/qaccessible.cpp4
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp44
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h6
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp76
-rw-r--r--src/gui/graphicsview/qgraphicsview_p.h11
-rw-r--r--src/gui/image/qicon.cpp2
-rw-r--r--src/gui/image/qimagereader.cpp14
-rw-r--r--src/gui/image/qimagewriter.cpp16
-rw-r--r--src/gui/inputmethod/qinputcontextfactory.cpp6
-rw-r--r--src/gui/itemviews/qtableview.cpp8
-rw-r--r--src/gui/kernel/qapplication.cpp17
-rw-r--r--src/gui/kernel/qapplication_win.cpp2
-rw-r--r--src/gui/kernel/qgesturemanager.cpp20
-rw-r--r--src/gui/kernel/qguiplatformplugin.cpp2
-rw-r--r--src/gui/painting/qgraphicssystemfactory.cpp6
-rw-r--r--src/gui/painting/qpaintengine_mac.cpp8
-rw-r--r--src/gui/styles/qcleanlooksstyle.cpp3
-rw-r--r--src/gui/styles/qstylefactory.cpp2
-rw-r--r--src/gui/text/qfontengine_mac.mm15
-rw-r--r--src/gui/text/qtextcontrol.cpp4
-rw-r--r--src/multimedia/multimedia/audio/qaudiodevicefactory.cpp14
-rw-r--r--src/network/bearer/qnetworkconfigmanager_p.cpp4
-rw-r--r--src/opengl/gl2paintengineex/qglengineshadersource_p.h16
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp6
-rw-r--r--src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h3
-rw-r--r--src/opengl/qgl.cpp37
-rw-r--r--src/opengl/qwindowsurface_gl.cpp1
-rw-r--r--src/plugins/imageformats/jpeg/qjpeghandler.cpp12
-rw-r--r--src/sql/kernel/qsqldatabase.cpp6
-rw-r--r--src/svg/qsvghandler.cpp2
-rw-r--r--tests/auto/gestures/tst_gestures.cpp71
-rw-r--r--tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp14
-rw-r--r--tests/auto/qgraphicsview/tst_qgraphicsview.cpp123
-rw-r--r--tests/auto/qtableview/tst_qtableview.cpp21
-rw-r--r--tests/auto/qurl/tst_qurl.cpp6
-rw-r--r--tests/auto/qvector/tst_qvector.cpp600
-rw-r--r--tests/benchmarks/corelib/kernel/events/events.pro1
-rw-r--r--tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro1
-rw-r--r--tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro2
-rw-r--r--tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro1
-rw-r--r--tests/benchmarks/corelib/tools/containers-associative/main.cpp1
-rw-r--r--tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro1
85 files changed, 2542 insertions, 555 deletions
diff --git a/config.tests/unix/bsymbolic_functions.test b/config.tests/unix/bsymbolic_functions.test
index 52fdb32..6c34895 100755
--- a/config.tests/unix/bsymbolic_functions.test
+++ b/config.tests/unix/bsymbolic_functions.test
@@ -4,11 +4,12 @@ BSYMBOLIC_FUNCTIONS_SUPPORT=no
COMPILER=$1
VERBOSE=$2
+
cat >>bsymbolic_functions.c << EOF
int main() { return 0; }
EOF
-"$COMPILER" -o libtest.so -shared -Wl,-Bsymbolic-functions -fPIC bsymbolic_functions.c >/dev/null 2>&1 && BSYMBOLIC_FUNCTIONS_SUPPORT=yes
+$COMPILER -o libtest.so -shared -Wl,-Bsymbolic-functions -fPIC bsymbolic_functions.c >/dev/null 2>&1 && BSYMBOLIC_FUNCTIONS_SUPPORT=yes
rm -f bsymbolic_functions.c libtest.so
# done
diff --git a/configure b/configure
index 6763969..47eec92 100755
--- a/configure
+++ b/configure
@@ -3097,8 +3097,8 @@ fi
# auto-detect support for separate debug info in objcopy
if [ "$CFG_SEPARATE_DEBUG_INFO" != "no" ] && [ "$CFG_SHARED" = "yes" ]; then
- TEST_COMPILER_CFLAGS=`getQMakeConf "$XQMAKESPEC" | sed -n -e 's%QMAKE_CFLAGS[^_].*=%%p' | tr '\n' ' '`
- TEST_COMPILER_CXXFLAGS=`getQMakeConf "$XQMAKESPEC" | sed -n -e 's%QMAKE_CXXFLAGS[^_].*=%%p' | tr '\n' ' '`
+ TEST_COMPILER_CFLAGS=`getQMakeConf "$XQMAKESPEC" | sed -n -e 's%QMAKE_CFLAGS[^_=]*[+*]*=%%p' | tr '\n' ' '`
+ TEST_COMPILER_CXXFLAGS=`getQMakeConf "$XQMAKESPEC" | sed -n -e 's%QMAKE_CXXFLAGS[^_=]*[+*]*=%%p' | tr '\n' ' '`
TEST_OBJCOPY=`getQMakeConf "$XQMAKESPEC" | grep "^QMAKE_OBJCOPY" | sed "s%.* *= *\(.*\)$%\1%" | tail -1`
COMPILER_WITH_FLAGS="$TEST_COMPILER $TEST_COMPILER_CXXFLAGS"
COMPILER_WITH_FLAGS=`echo "$COMPILER_WITH_FLAGS" | sed -e "s%\\$\\$QMAKE_CFLAGS%$TEST_COMPILER_CFLAGS%g"`
diff --git a/doc/src/examples/dragdroprobot.qdoc b/doc/src/examples/dragdroprobot.qdoc
index 413f190..887b254 100644
--- a/doc/src/examples/dragdroprobot.qdoc
+++ b/doc/src/examples/dragdroprobot.qdoc
@@ -43,9 +43,337 @@
\example graphicsview/dragdroprobot
\title Drag and Drop Robot Example
- This GraphicsView example shows how to implement drag and drop in
- a QGraphicsItem subclass, as well as how to animate items using
- QGraphicsItemAnimation and QTimeLine.
+ This GraphicsView example shows how to implement Drag and Drop in a
+ QGraphicsItem subclass, as well as how to animate items using Qt's
+ \l{Animation Framework}.
\image dragdroprobot-example.png
+
+ Graphics View provides the QGraphicsScene class for managing and
+ interacting with a large number of custom-made 2D graphical items derived
+ from the QGraphicsItem class, and a QGraphicsView widget for visualizing
+ the items, with support for zooming and rotation.
+
+ This example consists of a \c Robot class, a \c ColorItem class, and a main
+ function: the \c Robot class describes a simple robot consisting of several
+ \c RobotPart derived limbs, including \c RobotHead and \c RobotLimb, the \c
+ ColorItem class provides a draggable colored ellipse, and the \c main()
+ function provides the main application window.
+
+ We will first review the \c Robot class to see how to assemble the
+ different parts so that they can be individually rotated and animated using
+ QPropertyAnimation, and we will then review the \c ColorItem class to
+ demonstrate how to implement Drag and Drop between items. Finally we will
+ review the main() function to see how we can put all the pieces together,
+ to form the final application.
+
+ \section1 Robot Class Definition
+
+ The robot consists of three main classes: the \c RobotHead, the \c
+ RobotTorso, and the \c RobotLimb, which is used for the upper and lower
+ arms and legs. All parts derive from the \c RobotPart class, which in turn
+ inherits \c QGraphicsObject. The \c Robot class itself has no visual
+ appearance and serves only as a root node for the robot.
+
+ Let's start with the \c RobotPart class declaration.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.h 0
+
+ This base class inherits QGraphicsObject. QGraphicsObject provides signals
+ and slots through inheriting QObject, and it also declares QGraphicsItem's
+ properties using Q_PROPERTY, which makes the properties accessible for
+ QPropertyAnimation.
+
+ RobotPart also implements the three most important event handlers for
+ accepting drop events:
+ \l{QGraphicsItem::dragEnterEvent()}{dragEnterEvent()},
+ \l{QGraphicsItem::dragLeaveEvent()}{dragLeaveEvent()}, and
+ \l{QGraphicsItem::dropEvent()}{dropEvent()}.
+
+ The color is stored as a member variable, along with the \c dragOver
+ variable, which we will use later to indicate visually that the limb can
+ accept colors that are is dragged onto it.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 0
+
+ \c RobotPart's constructor initializes the dragOver member and sets the
+ color to Qt::lightGray. In the constructor body we enable support for
+ accepting drop events by calling
+ \l{QGraphicsItem::setAcceptDrops()}{setAcceptDrops(true)}.
+
+ The rest of this class's implementation is to support Drag and Drop.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 1
+
+ The \l{QGraphicsItem::dragEnterEvent()}{dragEnterEvent()} handler is called
+ when a Drag and Drop element is dragged into the robot part's area.
+
+ The handler implementation determines whether or not this item as a whole
+ can accept the mime data assiciated with the incoming drag object. \c
+ RobotPart provides a base behavior for all parts that accepts color drops.
+ So if the incoming drag object contains a color, the event is accepted, we
+ set \c dragOver to \c true and call update() to help provide positive
+ visual feedback to the user; otherwise the event is ignored, which in turn
+ allows the event to propagate to parent elements.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 2
+
+ The \l{QGraphicsItem::dragLeaveEvent()}{dragLeaveEvent()} handler is called
+ when a Drag and Drop element is dragged away from the robot part's area.
+ Our implementation simply resets \e dragOver to false and calls
+ \l{QGraphicsItem::update()}{update()} to help provide visual feedback that
+ the drag has left this item.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 3
+
+ The \l{QGraphicsItem::dropEvent()}{dropEvent()} handler is called when a
+ Drag and Drop element is dropped onto an item (i.e., when the mouse button
+ is released over the item while dragging).
+
+ We reset \c dragOver to false, assign the item's new color, and call
+ \l{QGraphicsItem::update()}{update()}.
+
+ The declaration and implementation of \c RobotHead, \c RobotTorso, and \c
+ RobotLimb are practically identical. We will review \c RobotHead in detail,
+ as this class has one minor difference, and leave the other classes as an
+ exercise for the reader.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.h 1
+
+ The \c RobotHead class inherits \c RobotPart and provides the necessary
+ implementations of \l{QGraphicsItem::boundingRect()}{boundingRect()} and
+ \l{QGraphicsItem::paint()}{paint()}. It also reimplements
+ \l{QGraphicsItem::dragEnterEvent()}{dragEnterEvent()} and dropEvent() to
+ provide special handling of image drops.
+
+ The class contains a private pixmap member that we can use to implement
+ support for accepting image drops.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 4
+
+ \c RobotHead has a rather plain constructor that simply forwards to
+ \c RobotPart's constructor.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 5
+
+ The \l{QGraphicsItem::boundingRect()}{boundingRect()} reimplementation
+ returns the extents for the head. Because we want the center of rotation to
+ be the bottom center of the item, we have chosen a bounding rectangle that
+ starts at (-15, -50) and extends to 30 units wide and 50 units tall. When
+ rotating the head, the "neck" will stay still while the top of the head
+ tilts from side to side.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 6
+
+ In \l{QGraphicsItem::paint()}{paint()} we draw the actual head. The
+ implementation is split into two sections; if an image has been dropped
+ onto the head, we draw the image, otherwise we draw a round rectangular
+ robot head with simple vector graphics.
+
+ For performance reasons, depending on the complexity of what is painted, it
+ can often be faster to draw the head as an image rather than using a
+ sequence of vector operations.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 7
+
+ The robot head can accept image drops. In order to support this, its
+ reimplementation of \l{QGraphicsItem::dragEnterEvent()}{dragEnterEvent()}
+ checks if the drag object contains image data, and if it does, then the
+ event is accepted. Otherwise we fall back to the base \c RobotPart
+ implementation.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 8
+
+ To follow up on image support, we must also implement
+ \l{QGraphicsItem::dropEvent()}{dropEvent()}. We check if the drag object
+ contains image data, and if it does, we store this data as a member pixmap
+ and call \l{QGraphicsItem::update()}{update()}. This pixmap is used inside
+ the \l{QGraphicsItem::paint()}{paint()} implementation that we reviewed
+ before.
+
+ \c RobotTorso and \c RobotLimb are similar to \c RobotHead, so let's
+ skip directly to the \c Robot class.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.h 4
+
+ The \c Robot class also inherits \c RobotPart, and like the other parts it
+ also implements \l{QGraphicsItem::boundingRect()}{boundingRect()} and
+ \l{QGraphicsItem::paint()}{paint()}. It provides a rather special
+ implementation, though:
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 9
+
+ Because the \c Robot class is only used as a base node for the rest of the
+ robot, it has no visual representation. Its
+ \l{QGraphicsItem::boundingRect()}{boundingRect()} implementation can
+ therefore return a null QRectF, and its paint() function does nothing.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 10
+
+ The constuctor starts by setting the flag
+ \l{QGraphicsItem::ItemHasNoContents}{ItemHasNoContents}, which is a minor
+ optimization for items that have no visual appearance.
+
+ We then construct all the robot parts (head, torso, and upper/lower arms
+ and legs). The stacking order is very important, and we use the
+ parent-child hierarchy to ensure the elements rotate and move properly. We
+ construct the torso first, as this is the root element. We then construct
+ the head and pass the torso to \c HeadItem's constructor. This will make
+ the head a child of the torso; if you rotate the torso, the head will
+ follow. The same pattern is applied to the rest of the limbs.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 11
+
+ Each robot part is carefully positioned. For example, the upper left arm is
+ moved precisely to the top-left area of the torso, and the upper right arm
+ is moved to the top-right area.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 12
+
+ The next section creates all animation objects. This snippet shows the two
+ animations that operate on the head's scale and rotation. The two
+ QPropertyAnimation instances simply set the object, property, and
+ respective start and end values.
+
+ All animations are controlled by one top-level parallel animation group.
+ The scale and rotation animations are added to this group.
+
+ The rest of the animations are defined in a similar way.
+
+ \snippet examples/graphicsview/dragdroprobot/robot.cpp 13
+
+ Finally we set an easing curve and duration on each animation, ensure the
+ toplevel animation group loops forever, and start the toplevel animation.
+
+ \section1 ColorItem Class Definition
+
+ The \c ColorItem class represents a circular item that can be pressed to
+ drag colors onto robot parts.
+
+ \snippet examples/graphicsview/dragdroprobot/coloritem.h 0
+
+ This class is very simple. It does not use animations, and has no need for
+ properties nor signals and slots, so to save resources, it's most natural
+ that it inherits QGraphicsItem (as opposed to QGraphicsObject).
+
+ It declares the mandatory \l{QGraphicsItem::boundingRect()}{boundingRect()}
+ and \l{QGraphicsItem::paint()}{paint()} functions, and adds
+ reimplementations of
+ \l{QGraphicsItem::mousePressEvent()}{mousePressEvent()},
+ \l{QGraphicsItem::mouseMoveEvent()}{mouseMoveEvent()}, and
+ \l{QGraphicsItem::mouseReleaseEvent()}{mouseReleaseEvent()}. It contains a
+ single private color member.
+
+ Let's take a look at its implementation.
+
+ \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 0
+
+ \c ColorItem's constructor assigns an opaque random color to its color
+ member by making use of qrand(). For improved usability, it assigns a
+ tooltip that provides a useful hint to the user, and it also sets a
+ suitable cursor. This ensures that the cursor will chance to
+ Qt::OpenHandCursor when the mouse pointer hovers over the item.
+
+ Finally, we call
+ \l{QGraphicsItem::setAcceptedMouseButtons()}{setAcceptedMouseButtons()} to
+ ensure that this item can only process Qt::LeftButton. This simplifies the
+ mouse event handlers greatly, as we can always assume that only the left
+ mouse button is pressed and released.
+
+ \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 1
+
+ The item's bounding rect is a fixed 30x30 units centered around the item's
+ origin (0, 0), and adjusted by 0.5 units in all directions to allow a
+ scalable pen to draw its outline. For a final visual touch the bounds
+ also compensate with a few units down and to the right to make room
+ for a simple dropshadow.
+
+ \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 2
+
+ The \l{QGraphicsItem::paint()}{paint()} implementation draws an ellipse
+ with a 1-unit black outline, a plain color fill, and a dark gray
+ dropshadow.
+
+ \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 3
+
+ The \l{QGraphicsItem::mousePressEvent()}{mousePressEvent()} handler is
+ called when you press the mouse button inside the item's area. Our
+ implementation simply sets the cursor to Qt::ClosedHandCursor.
+
+ \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 4
+
+ The \l{QGraphicsItem::mouseReleaseEvent()}{mouseReleaseEvent()} handler is
+ called when you release the mouse button after having pressed it inside an
+ item's area. Our implementation sets the cursor back to Qt::OpenHandCursor.
+ The mouse press and release event handlers together provide useful visual
+ feedback to the user: when you move the mouse pointer over a \c CircleItem,
+ the cursor changes to an open hand. Pressing the item will show a closed
+ hand cursor. Releasing will restore to an open hand cursor again.
+
+ \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 5
+
+ The \l{QGraphicsItem::mouseMoveEvent()}{mouseMoveEvent()} handler is called
+ when you move the mouse around after pressing the mouse button inside the
+ \c ColorItem's area. This implementation provides the most important piece
+ of logic for \c CircleItem: the code that starts and manages drags.
+
+ The implementation starts by checking if the mouse has been dragged far
+ enough to eliminate mouse jitter noise. We only want to start a drag if the
+ mouse has been dragged farther than the application start drag distance.
+
+ Continuing, we create a QDrag object, passing the event
+ \l{QGraphicsSceneEvent::widget()}{widget} (i.e., the QGraphicsView
+ viewport) to its constructor. Qt will ensure that this object is deleted at
+ the right time. We also create a QMimeData instance that can contain our
+ color or image data, and assign this to the drag object.
+
+ \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 6
+
+ This snippet has a somewhat random outcome: once in a while, a special
+ image is assigned to the drag object's mime data. The pixmap is also
+ assiged as the drag object's pixmap. This will ensure that you can see the
+ image that is being dragged as a pixmap under the mouse cursor.
+
+ \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 7
+
+ Otherwise, and this is the most common outcome, a simple color is assigned
+ to the drag object's mime data. We render this \c ColorItem into a new
+ pixmap to give the user visual feedback that the color is being "dragged".
+
+ \snippet examples/graphicsview/dragdroprobot/coloritem.cpp 8
+
+ Finally we execute the drag. QDrag::exec() will reenter the event loop, and
+ only exit if the drag has either been dropped, or canceled. In any case we
+ reset the cursor to Qt::OpenHandCursor.
+
+ \section1 The main() Function
+
+ Now that the \c Robot and \c ColorItem classes are complete, we can put all
+ the pieces together inside the main() function.
+
+ \snippet examples/graphicsview/dragdroprobot/main.cpp 0
+
+ We start off by constructing QApplication, and initializing the random
+ number generator. This ensures that the color items have different colors
+ every time the application starts.
+
+ \snippet examples/graphicsview/dragdroprobot/main.cpp 1
+
+ We construct a fixed size scene, and create 10 \c ColorItem instances
+ arranged in a circle. Each item is added to the scene.
+
+ In the center of this circle we create one \c Robot instance. The
+ robot is scaled and moved up a few units. It is then added to the scene.
+
+ \snippet examples/graphicsview/dragdroprobot/main.cpp 2
+
+ Finally we create a QGraphicsView window, and assign the scene to it.
+
+ For increased visual quality, we enable antialiasing. We also choose to use
+ bounding rectangle updates to simplify visual update handling.
+ The view is given a fixed sand-colored background, and a window title.
+
+ We then show the view. The animations start immediately after
+ control enters the event loop.
*/
+
diff --git a/doc/src/examples/elasticnodes.qdoc b/doc/src/examples/elasticnodes.qdoc
index f7b1c37..edc62d8 100644
--- a/doc/src/examples/elasticnodes.qdoc
+++ b/doc/src/examples/elasticnodes.qdoc
@@ -43,7 +43,396 @@
\example graphicsview/elasticnodes
\title Elastic Nodes Example
- This GraphicsView example shows how to implement edges between nodes in a graph.
+ This GraphicsView example shows how to implement edges between nodes in a
+ graph, with basic interaction. You can click to drag a node around, and
+ zoom in and out using the mouse wheel or the keyboard. Hitting the space
+ bar will randomize the nodes. The example is also resolution independent;
+ as you zoom in, the graphics remain crisp.
\image elasticnodes-example.png
+
+ Graphics View provides the QGraphicsScene class for managing and
+ interacting with a large number of custom-made 2D graphical items derived
+ from the QGraphicsItem class, and a QGraphicsView widget for visualizing
+ the items, with support for zooming and rotation.
+
+ This example consists of a \c Node class, an \c Edge class, a \c
+ GraphWidget test, and a \c main function: the \c Node class represents
+ draggable yellow nodes in a grid, the \c Edge class represents the lines
+ between the nodes, the \c GraphWidget class represents the application
+ window, and the \c main() function creates and shows this window, and runs
+ the event loop.
+
+ \section1 Node Class Definition
+
+ The \c Node class serves three purposes:
+
+ \list
+ \o Painting a yellow gradient "ball" in two states: sunken and raised.
+ \o Managing connections to other nodes.
+ \o Calculating forces pulling and pushing the nodes in the grid.
+ \endlist
+
+ Let's start by looking at the \c Node class declaration.
+
+ \snippet examples/graphicsview/elasticnodes/node.h 0
+
+ The \c Node class inherits QGraphicsItem, and reimplements the two
+ mandatory functions \l{QGraphicsItem::boundingRect()}{boundingRect()} and
+ \l{QGraphicsItem::paint()}{paint()} to provide its visual appearance. It
+ also reimplements \l{QGraphicsItem::shape()}{shape()} to ensure its hit
+ area has an elliptic shape (as opposed to the default bounding rectangle).
+
+ For edge management purposes the node provides a simple API for adding
+ edges to a node, and for listing all connected edges.
+
+ The \l{QGraphicsItem::advance()}{advance()} reimplementation is called
+ whenever the scene's state advances by one step. The calculateForces()
+ function is called to calculate the forces that push and pull on this node
+ and its neighbors.
+
+ The \c Node class also reimplements
+ \l{QGraphicsItem::itemChange()}{itemChange()} to react to state changes (in
+ this case, position changes), and
+ \l{QGraphicsItem::mousePressEvent()}{mousePressEvent()} and
+ \l{QGraphicsItem::mouseReleaseEvent()}{mouseReleaseEvent()} to update the
+ item's visual appearance.
+
+ We will start reviewing the \c Node implementation by looking at its
+ constructor:
+
+ \snippet examples/graphicsview/elasticnodes/node.cpp 0
+
+ In the constructor, we set the
+ \l{QGraphicsItem::ItemIsMovable}{ItemIsMovable} flag to allow the item to
+ move in response to mouse dragging, and
+ \l{QGraphicsItem::ItemSendsGeometryChanges}{ItemSendsGeometryChanges} to
+ enable \l{QGraphicsItem::itemChange()}{itemChange()} notifications for
+ position and transformation changes. We also enable
+ \l{QGraphicsItem::DeviceCoordinateCache}{DeviceCoordinateCache} to speed up
+ rendering performance. To ensure that the nodes are always stacked on top
+ of edges, we finally set the item's Z value to -1.
+
+ \c Node's constructor takes a \c GraphWidget pointer and stores this as a
+ member variable. We will revisit this pointer later on.
+
+ \snippet examples/graphicsview/elasticnodes/node.cpp 1
+
+ The addEdge() function adds the input edge to a list of attached edges. The
+ edge is then adjusted so that the end points for the edge match the
+ positions of the source and destination nodes.
+
+ The edges() function simply returns the list of attached edges.
+
+ \snippet examples/graphicsview/elasticnodes/node.cpp 2
+
+ The \e calculateForces() function implements the elastic forces effect that
+ pulls and pushes on nodes in the grid. In addition to this algorithm, the
+ user can move one node around with the mouse. Because we do not want the
+ two to interfere, we start by checking if this \c Node is the current mouse
+ grabber item (i.e., QGraphicsScene::mouseGrabberItem()). Because we need to
+ find all neighboring (but not necessarily connected) nodes, we also make
+ sure the item is part of a scene in the first place.
+
+ \snippet examples/graphicsview/elasticnodes/node.cpp 3
+
+ The algorithm has two steps: the first is to calculate the forces that push
+ the nodes apart, and the second is to subtract the forces that pull the
+ nodes together. First we need to find all the nodes in the graph. We call
+ QGraphicsScene::items() to find all items in the scene, and then use
+ qgraphicsitem_cast() to look for \c Node instances.
+
+ We make use of \l{QGraphicsItem::mapFromItem()}{mapFromItem()} to create a
+ vector pointing from this node to each other node, in \l{The Graphics View
+ Coordinate System}{local coordinates}. We use the decomposed components of
+ this vector to determine the direction and strength of force that apply to
+ the node. The forces are added up for each node, and weighted so that the
+ closest nodes are given the strongest force. The sum of all forces are
+ stored in \e xvel (X-velocity) and \e yvel (Y-velocity).
+
+ \snippet examples/graphicsview/elasticnodes/node.cpp 4
+
+ The edges between the nodes represent the forces that pull the nodes
+ together. By visiting each edge that is connected to this node, we can use
+ a similar approach as above to find the direction and strength of all
+ forces. These forces are subtracted from \e xvel and \e yvel.
+
+ \snippet examples/graphicsview/elasticnodes/node.cpp 5
+
+ In theory, the sum of pushing and pulling forces should stabilize to
+ precisely 0. In practise, however, they never do. To circumvent errors in
+ numerical precision, we simply force the sum of forces to be 0 when they
+ are less than 0.1.
+
+ \snippet examples/graphicsview/elasticnodes/node.cpp 6
+
+ The final step of \e calculateForces() determines the node's new position.
+ We add the force to the node's current position. We also make sure the new
+ position stays inside of our defined boundaries. We don't actually move the
+ item in this function; that's done in a separate step, from \e advance().
+
+ \snippet examples/graphicsview/elasticnodes/node.cpp 7
+
+ The \e advance() function updates the item's current position. It is called
+ from \e GraphWidget::timerEvent(). If the node's position changed, the
+ function returns true; otherwise false is returned.
+
+ \snippet examples/graphicsview/elasticnodes/node.cpp 8
+
+ The \e Node's bounding rectangle is a 20x20 sized rectangle centered around
+ its origin (0, 0), adjusted by 2 units in all directions to compensate for
+ the node's outline stroke, and by 3 units down and to the right to make
+ room for a simple drop shadow.
+
+ \snippet examples/graphicsview/elasticnodes/node.cpp 9
+
+ The shape is a simple ellipse. This ensures that you must click inside the
+ node's elliptic shape in order to drag it around. You can test this effect
+ by running the example, and zooming far enough in so that the nodes become
+ very large. Without reimplementing \l{QGraphicsItem::shape()}{shape()}, the
+ item's hit area would be identical to its bounding rectangle (i.e.,
+ rectangular).
+
+ \snippet examples/graphicsview/elasticnodes/node.cpp 10
+
+ This function implements the node's painting. We start by drawing a simple
+ dark gray elliptic drop shadow at (-7, -7), that is, (3, 3) units down and
+ to the right.
+
+ We then draw an ellipse with a radial gradient fill. This fill is either
+ Qt::yellow to Qt::darkYellow when raised, or the opposite when sunken. In
+ sunken state we also shift the center and focal point by (3, 3) to
+ emphasize the impression that something has been pushed down.
+
+ Drawing filled ellipses with gradients can be quite slow, especially when
+ using complex gradients such as QRadialGradient. This is why this example
+ uses \l{QGraphicsItem::DeviceCoordinateCache}{DeviceCoordinateCache}, a
+ simple yet effective measure that prevents unnecessary redrawing.
+
+ \snippet examples/graphicsview/elasticnodes/node.cpp 11
+
+ We reimplement \l{QGraphicsItem::itemChange()}{itemChange()} to adjust the
+ position of all connected edges, and to notify the scene that an item has
+ moved (i.e., "something has happened"). This will trigger new force
+ calculations.
+
+ This notification is the only reason why the nodes need to keep a pointer
+ back to the \e GraphWidget. Another approach could be to provide such
+ notification using a signal; in such case, \e Node would need to inherit
+ from QGraphicsObject.
+
+ \snippet examples/graphicsview/elasticnodes/node.cpp 12
+
+ Because we have set the \l{QGraphicsItem::ItemIsMovable}{ItemIsMovable}
+ flag, we don't need to implement the logic that moves the node according to
+ mouse input; this is already provided for us. We still need to reimplement
+ the mouse press and release handlers though, to update the nodes' visual
+ appearance (i.e., sunken or raised).
+
+ \section1 Edge Class Definition
+
+ The \e Edge class represents the arrow-lines between the nodes in this
+ example. The class is very simple: it maintains a source- and destination
+ node pointer, and provides an \e adjust() function that makes sure the line
+ starts at the position of the source, and ends at the position of the
+ destination. The edges are the only items that change continuously as
+ forces pull and push on the nodes.
+
+ Let's take a look at the class declaration:
+
+ \snippet examples/graphicsview/elasticnodes/edge.h 0
+
+ \e Edge inherits from QGraphicsItem, as it's a simple class that has no use
+ for signals, slots, and properties (compare to QGraphicsObject).
+
+ The constructor takes two node pointers as input. Both pointers are
+ mandatory in this example. We also provide get-functions for each node.
+
+ The \e adjust() function repositions the edge, and the item also implements
+ \l{QGraphicsItem::boundingRect()}{boundingRect()} and
+ \{QGraphicsItem::paint()}{paint()}.
+
+ We will now review its implementation.
+
+ \snippet examples/graphicsview/elasticnodes/edge.cpp 0
+
+ The \e Edge constructor initializes its arrowSize data member to 10 units;
+ this determines the size of the arrow which is drawn in
+ \l{QGraphicsItem::paint()}{paint()}.
+
+ In the constructor body, we call
+ \l{QGraphicsItem::setAcceptedMouseButtons()}{setAcceptedMouseButtons(0)}.
+ This ensures that the edge items are not considered for mouse input at all
+ (i.e., you cannot click the edges). Then, the source and destination
+ pointers are updated, this edge is registered with each node, and we call
+ \e adjust() to update this edge's start end end position.
+
+ \snippet examples/graphicsview/elasticnodes/edge.cpp 1
+
+ The source and destination get-functions simply return the respective
+ pointers.
+
+ \snippet examples/graphicsview/elasticnodes/edge.cpp 2
+
+ In \e adjust(), we define two points: \e sourcePoint, and \e destPoint,
+ pointing at the source and destination nodes' origins respectively. Each
+ point is calculated using \l{The Graphics View Coordinate System}{local
+ coordinates}.
+
+ We want the tip of the edge's arrows to point to the exact outline of the
+ nodes, as opposed to the center of the nodes. To find this point, we first
+ decompose the vector pointing from the center of the source to the center
+ of the destination node into X and Y, and then normalize the components by
+ dividing by the length of the vector. This gives us an X and Y unit delta
+ that, when multiplied by the radius of the node (which is 10), gives us the
+ offset that must be added to one point of the edge, and subtracted from the
+ other.
+
+ If the length of the vector is less than 20 (i.e., if two nodes overlap),
+ then we fix the source and destination pointer at the center of the source
+ node. In practise this case is very hard to reproduce manually, as the
+ forces between the two nodes is then at its maximum.
+
+ It's important to notice that we call
+ \l{QGraphicsItem::prepareGeometryChange()}{prepareGeometryChange()} in this
+ function. The reason is that the variables \e sourcePoint and \e destPoint
+ are used directly when painting, and they are returned from the
+ \l{QGraphicsItem::boundingRect()}{boundingRect()} reimplementation. We must
+ always call
+ \l{QGraphicsItem::prepareGeometryChange()}{prepareGeometryChange()} before
+ changing what \l{QGraphicsItem::boundingRect()}{boundingRect()} returns,
+ and before these variables can be used by
+ \l{QGraphicsItem::paint()}{paint()}, to keep Graphics View's internal
+ bookkeeping clean. It's safest to call this function once, immediately
+ before any such variable is modified.
+
+ \snippet examples/graphicsview/elasticnodes/edge.cpp 3
+
+ The edge's bounding rectangle is defined as the smallest rectangle that
+ includes both the start and the end point of the edge. Because we draw an
+ arrow on each edge, we also need to compensate by adjusting with half the
+ arrow size and half the pen width in all directions. The pen is used to
+ draw the outline of the arrow, and we can assume that half of the outline
+ can be drawn outside of the arrow's area, and half will be drawn inside.
+
+ \snippet examples/graphicsview/elasticnodes/edge.cpp 4
+
+ We start the reimplementation of \l{QGraphicsItem::paint()}{paint()} by
+ checking a few preconditions. Firstly, if either the source or destination
+ node is not set, then we return immediately; there is nothing to draw.
+
+ At the same time, we check if the length of the edge is approximately 0,
+ and if it is, then we also return.
+
+ \snippet examples/graphicsview/elasticnodes/edge.cpp 5
+
+ We draw the line using a pen that has round joins and caps. If you run the
+ example, zoom in and study the edge in detail, you will see that there are
+ no sharp/square edges.
+
+ \snippet examples/graphicsview/elasticnodes/edge.cpp 6
+
+ We proceed to drawing one arrow at each end of the edge. Each arrow is
+ drawn as a polygon with a black fill. The coordinates for the arrow are
+ determined using simple trigonometry.
+
+ \section1 GraphWidget Class Definition
+
+ \e GraphWidget is a subclass of QGraphicsView, which provides the main
+ window with scrollbars.
+
+ \snippet examples/graphicsview/elasticnodes/graphwidget.h 0
+
+ It provides a basic constructor that initializes the scene, an \e
+ itemMoved() function to notify changes in the scene's node graph, a few
+ event handlers, a reimplementation of
+ \l{QGraphicsView::drawBackground()}{drawBackground()}, and a helper
+ function for scaling the view by mouse or keyboard.
+
+ \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 0
+
+ \e GraphicsWidget's constructor creates the scene, and because most items
+ move around most of the time, it sets QGraphicsScene::NoIndex. Then the
+ scene gets a fixed \l{QGraphicsScene::sceneRect}{scene rectangle}.
+ The scene is then assigned to the \e GraphWidget view.
+
+ The view enables QGraphicsView::CacheBackground to cache rendering of its
+ static and somewhat complex background. Because the graph renders a close
+ collection of small items that all move around, it's unnecessary for
+ Graphics View to waste time finding accurate update regions, so we set the
+ QGraphicsView::BoundingRectViewportUpdate viewport update mode. The default
+ would work fine, but this mode is noticably faster for this example.
+
+ To improve rendering quality, we set QPainter::Antialiasing.
+
+ The transformation anchor decides how the view should scroll when you
+ transform the view, or in our case, when we zoom in or out. We have chosen
+ QGraphicsView::AnchorUnderMouse, which centers the view on the point under
+ the mouse cursor. This makes it easy to zoom towards a point in the scene
+ by moving the mouse over it, and then rolling the mouse wheel.
+
+ Finally we give the window a minimum size that matches the scene's default
+ size, and set a suitable window title.
+
+ \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 1
+
+ The last part of the constructor creates the grid of nodes and edges, and
+ gives each node an initial position.
+
+ \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 2
+
+ \e GraphWidget is notified of node movement through this \e itemMoved()
+ function. Its job is simply to restart the main timer in case it's not
+ running already. The timer is designed to stop when the graph stabilizes,
+ and start once it's unstable again.
+
+ \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 3
+
+ This is \e GraphWidget's key event handler. The arrow keys move the center
+ node around, the '+' and '-' keys zoom in and out by calling \e
+ scaleView(), and the enter and space keys randomize the positions of the
+ nodes. All other key events (e.g., page up and page down) are handled by
+ QGraphicsView's default implementation.
+
+ \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 4
+
+ The timer event handler's job is to run the whole force calculation
+ machinery as a smooth animation. Each time the timer is triggered, the
+ handler will find all nodes in the scene, and call \e
+ Node::calculateForces() on each node, one at a time. Then, in a final step
+ it will call \e Node::advance() to move all nodes to their new positions.
+ By checking the return value of \e advance(), we can decide if the grid
+ stabilized (i.e., no nodes moved). If so, we can stop the timer.
+
+ \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 5
+
+ In the wheel event handler, we convert the mouse wheel delta to a scale
+ factor, and pass this factor to \e scaleView(). This approach takes into
+ account the speed that the wheel is rolled. The faster you roll the mouse
+ wheel, the faster the view will zoom.
+
+ \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 6
+
+ The view's background is rendered in a reimplementation of
+ QGraphicsView::drawBackground(). We draw a large rectangle filled with a
+ linear gradient, with a drop shadow, and then render text in top. The text
+ is rendered twice to give a similar simple drop-shadow effect.
+
+ This background rendering is quite expensive; this is why the view enables
+ QGraphicsView::CacheBackground.
+
+ \snippet examples/graphicsview/elasticnodes/graphwidget.cpp 7
+
+ The \e scaleView() helper function checks that the scale factor stays
+ within certain limits (i.e., you cannot zoom too far in nor too far out),
+ and then applies this scale.
+
+ \section1 The main() Function
+
+ In contrast to the complexity of the rest of this example, the \e main()
+ function is very simple: We create a QApplication instance, seed the
+ randomizer using qsrand(), and then create and show an instance of \e
+ GraphWidget. Because all nodes in the grid are moved initially, the \e
+ GraphWidget timer will start immediately after control has returned to the
+ event loop.
*/
diff --git a/doc/src/getting-started/examples.qdoc b/doc/src/getting-started/examples.qdoc
index 071a107..542f672 100644
--- a/doc/src/getting-started/examples.qdoc
+++ b/doc/src/getting-started/examples.qdoc
@@ -649,8 +649,8 @@
\list
\o \l{graphicsview/collidingmice}{Colliding Mice}\raisedaster
\o \l{graphicsview/diagramscene}{Diagram Scene}\raisedaster
- \o \l{graphicsview/dragdroprobot}{Drag and Drop Robot}
- \o \l{graphicsview/elasticnodes}{Elastic Nodes}
+ \o \l{graphicsview/dragdroprobot}{Drag and Drop Robot}\raisedaster
+ \o \l{graphicsview/elasticnodes}{Elastic Nodes}\raisedaster
\o \l{graphicsview/portedasteroids}{Ported Asteroids}
\o \l{graphicsview/portedcanvas}{Ported Canvas}
\endlist
diff --git a/examples/graphicsview/dragdroprobot/coloritem.cpp b/examples/graphicsview/dragdroprobot/coloritem.cpp
index 95878b1..08edd38 100644
--- a/examples/graphicsview/dragdroprobot/coloritem.cpp
+++ b/examples/graphicsview/dragdroprobot/coloritem.cpp
@@ -43,6 +43,7 @@
#include "coloritem.h"
+//! [0]
ColorItem::ColorItem()
: color(qrand() % 256, qrand() % 256, qrand() % 256)
{
@@ -50,13 +51,18 @@ ColorItem::ColorItem()
.arg(color.red()).arg(color.green()).arg(color.blue())
.arg("Click and drag this color onto the robot!"));
setCursor(Qt::OpenHandCursor);
+ setAcceptedMouseButtons(Qt::LeftButton);
}
+//! [0]
+//! [1]
QRectF ColorItem::boundingRect() const
{
return QRectF(-15.5, -15.5, 34, 34);
}
+//! [1]
+//! [2]
void ColorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
Q_UNUSED(option);
@@ -68,17 +74,16 @@ void ColorItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
painter->setBrush(QBrush(color));
painter->drawEllipse(-15, -15, 30, 30);
}
+//! [2]
+//! [3]
void ColorItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
- if (event->button() != Qt::LeftButton) {
- event->ignore();
- return;
- }
-
setCursor(Qt::ClosedHandCursor);
}
+//! [3]
+//! [5]
void ColorItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if (QLineF(event->screenPos(), event->buttonDownScreenPos(Qt::LeftButton))
@@ -89,7 +94,9 @@ void ColorItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
QDrag *drag = new QDrag(event->widget());
QMimeData *mime = new QMimeData;
drag->setMimeData(mime);
+//! [5]
+//! [6]
static int n = 0;
if (n++ > 2 && (qrand() % 3) == 0) {
QImage image(":/images/head.png");
@@ -97,6 +104,8 @@ void ColorItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
drag->setPixmap(QPixmap::fromImage(image).scaled(30, 40));
drag->setHotSpot(QPoint(15, 30));
+//! [6]
+//! [7]
} else {
mime->setColorData(color);
mime->setText(QString("#%1%2%3")
@@ -118,12 +127,17 @@ void ColorItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
drag->setPixmap(pixmap);
drag->setHotSpot(QPoint(15, 20));
}
+//! [7]
+//! [8]
drag->exec();
setCursor(Qt::OpenHandCursor);
}
+//! [8]
+//! [4]
void ColorItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *)
{
setCursor(Qt::OpenHandCursor);
}
+//! [4]
diff --git a/examples/graphicsview/dragdroprobot/coloritem.h b/examples/graphicsview/dragdroprobot/coloritem.h
index 788d19e..eb19db6 100644
--- a/examples/graphicsview/dragdroprobot/coloritem.h
+++ b/examples/graphicsview/dragdroprobot/coloritem.h
@@ -44,6 +44,7 @@
#include <QGraphicsItem>
+//! [0]
class ColorItem : public QGraphicsItem
{
public:
@@ -60,5 +61,6 @@ protected:
private:
QColor color;
};
+//! [0]
#endif
diff --git a/examples/graphicsview/dragdroprobot/main.cpp b/examples/graphicsview/dragdroprobot/main.cpp
index 02585e1..2669c41 100644
--- a/examples/graphicsview/dragdroprobot/main.cpp
+++ b/examples/graphicsview/dragdroprobot/main.cpp
@@ -46,12 +46,14 @@
#include <math.h>
+//! [0]
int main(int argc, char **argv)
{
QApplication app(argc, argv);
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
-
+//! [0]
+//! [1]
QGraphicsScene scene(-200, -200, 400, 400);
for (int i = 0; i < 10; ++i) {
@@ -66,7 +68,8 @@ int main(int argc, char **argv)
robot->scale(1.2, 1.2);
robot->setPos(0, -20);
scene.addItem(robot);
-
+//! [1]
+//! [2]
QGraphicsView view(&scene);
view.setRenderHint(QPainter::Antialiasing);
view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
@@ -76,3 +79,4 @@ int main(int argc, char **argv)
return app.exec();
}
+//! [2]
diff --git a/examples/graphicsview/dragdroprobot/robot.cpp b/examples/graphicsview/dragdroprobot/robot.cpp
index 9ac6d26..705bd9d 100644
--- a/examples/graphicsview/dragdroprobot/robot.cpp
+++ b/examples/graphicsview/dragdroprobot/robot.cpp
@@ -43,16 +43,18 @@
#include "robot.h"
+//! [0]
RobotPart::RobotPart(QGraphicsItem *parent)
- : QGraphicsItem(parent), color(Qt::lightGray), dragOver(false)
+ : QGraphicsObject(parent), color(Qt::lightGray), dragOver(false)
{
setAcceptDrops(true);
}
+//! [0]
+//! [1]
void RobotPart::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
- if (event->mimeData()->hasColor()
- || (qgraphicsitem_cast<RobotHead *>(this) && event->mimeData()->hasImage())) {
+ if (event->mimeData()->hasColor()) {
event->setAccepted(true);
dragOver = true;
update();
@@ -60,34 +62,42 @@ void RobotPart::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
event->setAccepted(false);
}
}
+//! [1]
+//! [2]
void RobotPart::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
{
Q_UNUSED(event);
dragOver = false;
update();
}
+//! [2]
+//! [3]
void RobotPart::dropEvent(QGraphicsSceneDragDropEvent *event)
{
dragOver = false;
if (event->mimeData()->hasColor())
color = qVariantValue<QColor>(event->mimeData()->colorData());
- else if (event->mimeData()->hasImage())
- pixmap = qVariantValue<QPixmap>(event->mimeData()->imageData());
update();
}
+//! [3]
+//! [4]
RobotHead::RobotHead(QGraphicsItem *parent)
: RobotPart(parent)
{
}
+//! [4]
+//! [5]
QRectF RobotHead::boundingRect() const
{
return QRectF(-15, -50, 30, 50);
}
+//! [5]
+//! [6]
void RobotHead::paint(QPainter *painter,
const QStyleOptionGraphicsItem *option, QWidget *widget)
{
@@ -110,11 +120,33 @@ void RobotHead::paint(QPainter *painter,
painter->drawPixmap(QPointF(-15 * 4.4, -50 * 3.54), pixmap);
}
}
+//! [6]
-int RobotHead::type() const
+//! [7]
+void RobotHead::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
{
- return Type;
+ if (event->mimeData()->hasImage()) {
+ event->setAccepted(true);
+ dragOver = true;
+ update();
+ } else {
+ RobotPart::dragEnterEvent(event);
+ }
}
+//! [7]
+
+//! [8]
+void RobotHead::dropEvent(QGraphicsSceneDragDropEvent *event)
+{
+ if (event->mimeData()->hasImage()) {
+ dragOver = false;
+ pixmap = qVariantValue<QPixmap>(event->mimeData()->imageData());
+ update();
+ } else {
+ RobotPart::dropEvent(event);
+ }
+}
+//! [8]
RobotTorso::RobotTorso(QGraphicsItem *parent)
: RobotPart(parent)
@@ -161,19 +193,25 @@ void RobotLimb::paint(QPainter *painter,
painter->drawEllipse(-5, -5, 10, 10);
}
-Robot::Robot()
+//! [10]
+Robot::Robot(QGraphicsItem *parent)
+ : RobotPart(parent)
{
- QGraphicsItem *torsoItem = new RobotTorso(this);
- QGraphicsItem *headItem = new RobotHead(torsoItem);
- QGraphicsItem *upperLeftArmItem = new RobotLimb(torsoItem);
- QGraphicsItem *lowerLeftArmItem = new RobotLimb(upperLeftArmItem);
- QGraphicsItem *upperRightArmItem = new RobotLimb(torsoItem);
- QGraphicsItem *lowerRightArmItem = new RobotLimb(upperRightArmItem);
- QGraphicsItem *upperRightLegItem = new RobotLimb(torsoItem);
- QGraphicsItem *lowerRightLegItem = new RobotLimb(upperRightLegItem);
- QGraphicsItem *upperLeftLegItem = new RobotLimb(torsoItem);
- QGraphicsItem *lowerLeftLegItem = new RobotLimb(upperLeftLegItem);
-
+ setFlag(ItemHasNoContents);
+
+ QGraphicsObject *torsoItem = new RobotTorso(this);
+ QGraphicsObject *headItem = new RobotHead(torsoItem);
+ QGraphicsObject *upperLeftArmItem = new RobotLimb(torsoItem);
+ QGraphicsObject *lowerLeftArmItem = new RobotLimb(upperLeftArmItem);
+ QGraphicsObject *upperRightArmItem = new RobotLimb(torsoItem);
+ QGraphicsObject *lowerRightArmItem = new RobotLimb(upperRightArmItem);
+ QGraphicsObject *upperRightLegItem = new RobotLimb(torsoItem);
+ QGraphicsObject *lowerRightLegItem = new RobotLimb(upperRightLegItem);
+ QGraphicsObject *upperLeftLegItem = new RobotLimb(torsoItem);
+ QGraphicsObject *lowerLeftLegItem = new RobotLimb(upperLeftLegItem);
+//! [10]
+
+//! [11]
headItem->setPos(0, -18);
upperLeftArmItem->setPos(-15, -10);
lowerLeftArmItem->setPos(30, 0);
@@ -183,82 +221,78 @@ Robot::Robot()
lowerRightLegItem->setPos(30, 0);
upperLeftLegItem->setPos(-10, 32);
lowerLeftLegItem->setPos(30, 0);
+//! [11]
- timeLine = new QTimeLine;
-
- QGraphicsItemAnimation *headAnimation = new QGraphicsItemAnimation;
- headAnimation->setItem(headItem);
- headAnimation->setTimeLine(timeLine);
- headAnimation->setRotationAt(0, 20);
- headAnimation->setRotationAt(1, -20);
- headAnimation->setScaleAt(1, 1.1, 1.1);
-
- QGraphicsItemAnimation *upperLeftArmAnimation = new QGraphicsItemAnimation;
- upperLeftArmAnimation->setItem(upperLeftArmItem);
- upperLeftArmAnimation->setTimeLine(timeLine);
- upperLeftArmAnimation->setRotationAt(0, 190);
- upperLeftArmAnimation->setRotationAt(1, 180);
-
- QGraphicsItemAnimation *lowerLeftArmAnimation = new QGraphicsItemAnimation;
- lowerLeftArmAnimation->setItem(lowerLeftArmItem);
- lowerLeftArmAnimation->setTimeLine(timeLine);
- lowerLeftArmAnimation->setRotationAt(0, 50);
- lowerLeftArmAnimation->setRotationAt(1, 10);
-
- QGraphicsItemAnimation *upperRightArmAnimation = new QGraphicsItemAnimation;
- upperRightArmAnimation->setItem(upperRightArmItem);
- upperRightArmAnimation->setTimeLine(timeLine);
- upperRightArmAnimation->setRotationAt(0, 300);
- upperRightArmAnimation->setRotationAt(1, 310);
-
- QGraphicsItemAnimation *lowerRightArmAnimation = new QGraphicsItemAnimation;
- lowerRightArmAnimation->setItem(lowerRightArmItem);
- lowerRightArmAnimation->setTimeLine(timeLine);
- lowerRightArmAnimation->setRotationAt(0, 0);
- lowerRightArmAnimation->setRotationAt(1, -70);
-
- QGraphicsItemAnimation *upperLeftLegAnimation = new QGraphicsItemAnimation;
- upperLeftLegAnimation->setItem(upperLeftLegItem);
- upperLeftLegAnimation->setTimeLine(timeLine);
- upperLeftLegAnimation->setRotationAt(0, 150);
- upperLeftLegAnimation->setRotationAt(1, 80);
-
- QGraphicsItemAnimation *lowerLeftLegAnimation = new QGraphicsItemAnimation;
- lowerLeftLegAnimation->setItem(lowerLeftLegItem);
- lowerLeftLegAnimation->setTimeLine(timeLine);
- lowerLeftLegAnimation->setRotationAt(0, 70);
- lowerLeftLegAnimation->setRotationAt(1, 10);
-
- QGraphicsItemAnimation *upperRightLegAnimation = new QGraphicsItemAnimation;
- upperRightLegAnimation->setItem(upperRightLegItem);
- upperRightLegAnimation->setTimeLine(timeLine);
- upperRightLegAnimation->setRotationAt(0, 40);
- upperRightLegAnimation->setRotationAt(1, 120);
-
- QGraphicsItemAnimation *lowerRightLegAnimation = new QGraphicsItemAnimation;
- lowerRightLegAnimation->setItem(lowerRightLegItem);
- lowerRightLegAnimation->setTimeLine(timeLine);
- lowerRightLegAnimation->setRotationAt(0, 10);
- lowerRightLegAnimation->setRotationAt(1, 50);
-
- QGraphicsItemAnimation *torsoAnimation = new QGraphicsItemAnimation;
- torsoAnimation->setItem(torsoItem);
- torsoAnimation->setTimeLine(timeLine);
- torsoAnimation->setRotationAt(0, 5);
- torsoAnimation->setRotationAt(1, -20);
-
- timeLine->setUpdateInterval(1000 / 25);
- timeLine->setCurveShape(QTimeLine::SineCurve);
- timeLine->setLoopCount(0);
- timeLine->setDuration(2000);
- timeLine->start();
-}
+//! [12]
+ QParallelAnimationGroup *animation = new QParallelAnimationGroup(this);
-Robot::~Robot()
-{
- delete timeLine;
+ QPropertyAnimation *headAnimation = new QPropertyAnimation(headItem, "rotation");
+ headAnimation->setStartValue(20);
+ headAnimation->setEndValue(-20);
+ QPropertyAnimation *headScaleAnimation = new QPropertyAnimation(headItem, "scale");
+ headScaleAnimation->setEndValue(1.1);
+ animation->addAnimation(headAnimation);
+ animation->addAnimation(headScaleAnimation);
+//! [12]
+
+ QPropertyAnimation *upperLeftArmAnimation = new QPropertyAnimation(upperLeftArmItem, "rotation");
+ upperLeftArmAnimation->setStartValue(190);
+ upperLeftArmAnimation->setEndValue(180);
+ animation->addAnimation(upperLeftArmAnimation);
+
+ QPropertyAnimation *lowerLeftArmAnimation = new QPropertyAnimation(lowerLeftArmItem, "rotation");
+ lowerLeftArmAnimation->setStartValue(50);
+ lowerLeftArmAnimation->setEndValue(10);
+ animation->addAnimation(lowerLeftArmAnimation);
+
+ QPropertyAnimation *upperRightArmAnimation = new QPropertyAnimation(upperRightArmItem, "rotation");
+ upperRightArmAnimation->setStartValue(300);
+ upperRightArmAnimation->setEndValue(310);
+ animation->addAnimation(upperRightArmAnimation);
+
+ QPropertyAnimation *lowerRightArmAnimation = new QPropertyAnimation(lowerRightArmItem, "rotation");
+ lowerRightArmAnimation->setStartValue(0);
+ lowerRightArmAnimation->setEndValue(-70);
+ animation->addAnimation(lowerRightArmAnimation);
+
+ QPropertyAnimation *upperLeftLegAnimation = new QPropertyAnimation(upperLeftLegItem, "rotation");
+ upperLeftLegAnimation->setStartValue(150);
+ upperLeftLegAnimation->setEndValue(80);
+ animation->addAnimation(upperLeftLegAnimation);
+
+ QPropertyAnimation *lowerLeftLegAnimation = new QPropertyAnimation(lowerLeftLegItem, "rotation");
+ lowerLeftLegAnimation->setStartValue(70);
+ lowerLeftLegAnimation->setEndValue(10);
+ animation->addAnimation(lowerLeftLegAnimation);
+
+ QPropertyAnimation *upperRightLegAnimation = new QPropertyAnimation(upperRightLegItem, "rotation");
+ upperRightLegAnimation->setStartValue(40);
+ upperRightLegAnimation->setEndValue(120);
+ animation->addAnimation(upperRightLegAnimation);
+
+ QPropertyAnimation *lowerRightLegAnimation = new QPropertyAnimation(lowerRightLegItem, "rotation");
+ lowerRightLegAnimation->setStartValue(10);
+ lowerRightLegAnimation->setEndValue(50);
+ animation->addAnimation(lowerRightLegAnimation);
+
+ QPropertyAnimation *torsoAnimation = new QPropertyAnimation(torsoItem, "rotation");
+ torsoAnimation->setStartValue(5);
+ torsoAnimation->setEndValue(-20);
+ animation->addAnimation(torsoAnimation);
+
+//! [13]
+ for (int i = 0; i < animation->animationCount(); ++i) {
+ QPropertyAnimation *anim = qobject_cast<QPropertyAnimation *>(animation->animationAt(i));
+ anim->setEasingCurve(QEasingCurve::SineCurve);
+ anim->setDuration(2000);
+ }
+
+ animation->setLoopCount(-1);
+ animation->start();
+//! [13]
}
+//! [9]
QRectF Robot::boundingRect() const
{
return QRectF();
@@ -271,3 +305,4 @@ void Robot::paint(QPainter *painter,
Q_UNUSED(option);
Q_UNUSED(widget);
}
+//! [9]
diff --git a/examples/graphicsview/dragdroprobot/robot.h b/examples/graphicsview/dragdroprobot/robot.h
index 88c4364..f5ff32c 100644
--- a/examples/graphicsview/dragdroprobot/robot.h
+++ b/examples/graphicsview/dragdroprobot/robot.h
@@ -46,10 +46,11 @@
QT_BEGIN_NAMESPACE
class QGraphicsSceneMouseEvent;
-class QTimeLine;
+class QParallelAnimationGroup;
QT_END_NAMESPACE
-class RobotPart : public QGraphicsItem
+//! [0]
+class RobotPart : public QGraphicsObject
{
public:
RobotPart(QGraphicsItem *parent = 0);
@@ -59,11 +60,12 @@ protected:
void dragLeaveEvent(QGraphicsSceneDragDropEvent *event);
void dropEvent(QGraphicsSceneDragDropEvent *event);
- QPixmap pixmap;
QColor color;
bool dragOver;
};
+//! [0]
+//! [1]
class RobotHead : public RobotPart
{
public:
@@ -72,10 +74,16 @@ public:
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
- enum { Type = UserType + 1 };
- int type() const;
+protected:
+ void dragEnterEvent(QGraphicsSceneDragDropEvent *event);
+ void dropEvent(QGraphicsSceneDragDropEvent *event);
+
+private:
+ QPixmap pixmap;
};
+//! [1]
+//! [2]
class RobotTorso : public RobotPart
{
public:
@@ -84,7 +92,9 @@ public:
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
};
+//! [2]
+//! [3]
class RobotLimb : public RobotPart
{
public:
@@ -93,18 +103,17 @@ public:
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
};
+//! [3]
+//! [4]
class Robot : public RobotPart
{
public:
- Robot();
- ~Robot();
+ Robot(QGraphicsItem *parent = 0);
QRectF boundingRect() const;
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = 0);
-
-private:
- QTimeLine *timeLine;
};
+//! [4]
#endif
diff --git a/examples/graphicsview/elasticnodes/edge.cpp b/examples/graphicsview/elasticnodes/edge.cpp
index 25c769b..634fbee 100644
--- a/examples/graphicsview/elasticnodes/edge.cpp
+++ b/examples/graphicsview/elasticnodes/edge.cpp
@@ -49,6 +49,7 @@
static const double Pi = 3.14159265358979323846264338327950288419717;
static double TwoPi = 2.0 * Pi;
+//! [0]
Edge::Edge(Node *sourceNode, Node *destNode)
: arrowSize(10)
{
@@ -59,33 +60,21 @@ Edge::Edge(Node *sourceNode, Node *destNode)
dest->addEdge(this);
adjust();
}
+//! [0]
-Edge::~Edge()
-{
-}
-
+//! [1]
Node *Edge::sourceNode() const
{
return source;
}
-void Edge::setSourceNode(Node *node)
-{
- source = node;
- adjust();
-}
-
Node *Edge::destNode() const
{
return dest;
}
+//! [1]
-void Edge::setDestNode(Node *node)
-{
- dest = node;
- adjust();
-}
-
+//! [2]
void Edge::adjust()
{
if (!source || !dest)
@@ -104,7 +93,9 @@ void Edge::adjust()
sourcePoint = destPoint = line.p1();
}
}
+//! [2]
+//! [3]
QRectF Edge::boundingRect() const
{
if (!source || !dest)
@@ -118,7 +109,9 @@ QRectF Edge::boundingRect() const
.normalized()
.adjusted(-extra, -extra, extra, extra);
}
+//! [3]
+//! [4]
void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
if (!source || !dest)
@@ -127,11 +120,15 @@ void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
QLineF line(sourcePoint, destPoint);
if (qFuzzyCompare(line.length(), qreal(0.)))
return;
+//! [4]
+//! [5]
// Draw the line itself
painter->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
painter->drawLine(line);
+//! [5]
+//! [6]
// Draw the arrows
double angle = ::acos(line.dx() / line.length());
if (line.dy() >= 0)
@@ -150,3 +147,4 @@ void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
painter->drawPolygon(QPolygonF() << line.p1() << sourceArrowP1 << sourceArrowP2);
painter->drawPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2);
}
+//! [6]
diff --git a/examples/graphicsview/elasticnodes/edge.h b/examples/graphicsview/elasticnodes/edge.h
index b6b951f..58cc89c 100644
--- a/examples/graphicsview/elasticnodes/edge.h
+++ b/examples/graphicsview/elasticnodes/edge.h
@@ -46,17 +46,14 @@
class Node;
+//! [0]
class Edge : public QGraphicsItem
{
public:
Edge(Node *sourceNode, Node *destNode);
- ~Edge();
Node *sourceNode() const;
- void setSourceNode(Node *node);
-
Node *destNode() const;
- void setDestNode(Node *node);
void adjust();
@@ -74,5 +71,6 @@ private:
QPointF destPoint;
qreal arrowSize;
};
+//! [0]
#endif
diff --git a/examples/graphicsview/elasticnodes/graphwidget.cpp b/examples/graphicsview/elasticnodes/graphwidget.cpp
index 7c244be..8b419b8 100644
--- a/examples/graphicsview/elasticnodes/graphwidget.cpp
+++ b/examples/graphicsview/elasticnodes/graphwidget.cpp
@@ -43,14 +43,13 @@
#include "edge.h"
#include "node.h"
-#include <QDebug>
-#include <QGraphicsScene>
-#include <QWheelEvent>
+#include <QtGui>
#include <math.h>
-GraphWidget::GraphWidget()
- : timerId(0)
+//! [0]
+GraphWidget::GraphWidget(QWidget *parent)
+ : QGraphicsView(parent), timerId(0)
{
QGraphicsScene *scene = new QGraphicsScene(this);
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
@@ -60,8 +59,12 @@ GraphWidget::GraphWidget()
setViewportUpdateMode(BoundingRectViewportUpdate);
setRenderHint(QPainter::Antialiasing);
setTransformationAnchor(AnchorUnderMouse);
- setResizeAnchor(AnchorViewCenter);
+ scale(qreal(0.8), qreal(0.8));
+ setMinimumSize(400, 400);
+ setWindowTitle(tr("Elastic Nodes"));
+//! [0]
+//! [1]
Node *node1 = new Node(this);
Node *node2 = new Node(this);
Node *node3 = new Node(this);
@@ -102,18 +105,18 @@ GraphWidget::GraphWidget()
node7->setPos(-50, 50);
node8->setPos(0, 50);
node9->setPos(50, 50);
-
- scale(qreal(0.8), qreal(0.8));
- setMinimumSize(400, 400);
- setWindowTitle(tr("Elastic Nodes"));
}
+//! [1]
+//! [2]
void GraphWidget::itemMoved()
{
if (!timerId)
timerId = startTimer(1000 / 25);
}
+//! [2]
+//! [3]
void GraphWidget::keyPressEvent(QKeyEvent *event)
{
switch (event->key()) {
@@ -146,7 +149,9 @@ void GraphWidget::keyPressEvent(QKeyEvent *event)
QGraphicsView::keyPressEvent(event);
}
}
+//! [3]
+//! [4]
void GraphWidget::timerEvent(QTimerEvent *event)
{
Q_UNUSED(event);
@@ -171,12 +176,16 @@ void GraphWidget::timerEvent(QTimerEvent *event)
timerId = 0;
}
}
+//! [4]
+//! [5]
void GraphWidget::wheelEvent(QWheelEvent *event)
{
scaleView(pow((double)2, -event->delta() / 240.0));
}
+//! [5]
+//! [6]
void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
{
Q_UNUSED(rect);
@@ -213,12 +222,15 @@ void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect)
painter->setPen(Qt::black);
painter->drawText(textRect, message);
}
+//! [6]
+//! [7]
void GraphWidget::scaleView(qreal scaleFactor)
{
- qreal factor = matrix().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
+ qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width();
if (factor < 0.07 || factor > 100)
return;
scale(scaleFactor, scaleFactor);
}
+//! [7]
diff --git a/examples/graphicsview/elasticnodes/graphwidget.h b/examples/graphicsview/elasticnodes/graphwidget.h
index 6f67b4e..3f78a5f 100644
--- a/examples/graphicsview/elasticnodes/graphwidget.h
+++ b/examples/graphicsview/elasticnodes/graphwidget.h
@@ -46,12 +46,13 @@
class Node;
+//! [0]
class GraphWidget : public QGraphicsView
{
Q_OBJECT
public:
- GraphWidget();
+ GraphWidget(QWidget *parent = 0);
void itemMoved();
@@ -67,5 +68,6 @@ private:
int timerId;
Node *centerNode;
};
+//! [0]
#endif
diff --git a/examples/graphicsview/elasticnodes/node.cpp b/examples/graphicsview/elasticnodes/node.cpp
index 774046c..495aa89 100644
--- a/examples/graphicsview/elasticnodes/node.cpp
+++ b/examples/graphicsview/elasticnodes/node.cpp
@@ -48,6 +48,7 @@
#include "node.h"
#include "graphwidget.h"
+//! [0]
Node::Node(GraphWidget *graphWidget)
: graph(graphWidget)
{
@@ -56,7 +57,9 @@ Node::Node(GraphWidget *graphWidget)
setCacheMode(DeviceCoordinateCache);
setZValue(-1);
}
+//! [0]
+//! [1]
void Node::addEdge(Edge *edge)
{
edgeList << edge;
@@ -67,14 +70,18 @@ QList<Edge *> Node::edges() const
{
return edgeList;
}
+//! [1]
+//! [2]
void Node::calculateForces()
{
if (!scene() || scene()->mouseGrabberItem() == this) {
newPos = pos();
return;
}
-
+//! [2]
+
+//! [3]
// Sum up all forces pushing this item away
qreal xvel = 0;
qreal yvel = 0;
@@ -83,37 +90,45 @@ void Node::calculateForces()
if (!node)
continue;
- QLineF line(mapFromItem(node, 0, 0), QPointF(0, 0));
- qreal dx = line.dx();
- qreal dy = line.dy();
+ QPointF vec = mapToItem(node, 0, 0);
+ qreal dx = vec.x();
+ qreal dy = vec.y();
double l = 2.0 * (dx * dx + dy * dy);
if (l > 0) {
xvel += (dx * 150.0) / l;
yvel += (dy * 150.0) / l;
}
}
+//! [3]
+//! [4]
// Now subtract all forces pulling items together
double weight = (edgeList.size() + 1) * 10;
foreach (Edge *edge, edgeList) {
- QPointF pos;
+ QPointF vec;
if (edge->sourceNode() == this)
- pos = mapFromItem(edge->destNode(), 0, 0);
+ vec = mapToItem(edge->destNode(), 0, 0);
else
- pos = mapFromItem(edge->sourceNode(), 0, 0);
- xvel += pos.x() / weight;
- yvel += pos.y() / weight;
+ vec = mapToItem(edge->sourceNode(), 0, 0);
+ xvel -= vec.x() / weight;
+ yvel -= vec.y() / weight;
}
-
+//! [4]
+
+//! [5]
if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1)
xvel = yvel = 0;
+//! [5]
+//! [6]
QRectF sceneRect = scene()->sceneRect();
newPos = pos() + QPointF(xvel, yvel);
newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10));
newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10));
}
+//! [6]
+//! [7]
bool Node::advance()
{
if (newPos == pos())
@@ -122,21 +137,27 @@ bool Node::advance()
setPos(newPos);
return true;
}
+//! [7]
+//! [8]
QRectF Node::boundingRect() const
{
qreal adjust = 2;
return QRectF(-10 - adjust, -10 - adjust,
23 + adjust, 23 + adjust);
}
+//! [8]
+//! [9]
QPainterPath Node::shape() const
{
QPainterPath path;
path.addEllipse(-10, -10, 20, 20);
return path;
}
+//! [9]
+//! [10]
void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
painter->setPen(Qt::NoPen);
@@ -157,7 +178,9 @@ void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWid
painter->setPen(QPen(Qt::black, 0));
painter->drawEllipse(-10, -10, 20, 20);
}
+//! [10]
+//! [11]
QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
{
switch (change) {
@@ -172,7 +195,9 @@ QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value)
return QGraphicsItem::itemChange(change, value);
}
+//! [11]
+//! [12]
void Node::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
update();
@@ -184,3 +209,4 @@ void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
update();
QGraphicsItem::mouseReleaseEvent(event);
}
+//! [12]
diff --git a/examples/graphicsview/elasticnodes/node.h b/examples/graphicsview/elasticnodes/node.h
index 0df579d..990346e 100644
--- a/examples/graphicsview/elasticnodes/node.h
+++ b/examples/graphicsview/elasticnodes/node.h
@@ -51,6 +51,7 @@ QT_BEGIN_NAMESPACE
class QGraphicsSceneMouseEvent;
QT_END_NAMESPACE
+//! [0]
class Node : public QGraphicsItem
{
public:
@@ -80,5 +81,6 @@ private:
QPointF newPos;
GraphWidget *graph;
};
+//! [0]
#endif
diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf
index 0bd0bf2..89034ca 100644
--- a/mkspecs/common/symbian/symbian.conf
+++ b/mkspecs/common/symbian/symbian.conf
@@ -66,7 +66,7 @@ QMAKE_LINK_OBJECT_MAX =
QMAKE_LINK_OBJECT_SCRIPT=
QMAKE_LIBS = -llibc -llibm -leuser -llibdl
-QMAKE_LIBS_CORE = $$QMAKE_LIBS -lefsrv -lhal
+QMAKE_LIBS_CORE = $$QMAKE_LIBS -lefsrv -lhal -lbafl
QMAKE_LIBS_GUI = $$QMAKE_LIBS_CORE -lfbscli -lbitgdi -lgdi -lws32 -lapgrfx -lcone -leikcore -lmediaclientaudio -leikcoctl -leiksrv -lapparc -lcentralrepository
QMAKE_LIBS_NETWORK =
QMAKE_LIBS_EGL = -llibEGL
diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp
index d011c5c..522d517 100644
--- a/qmake/generators/win32/msbuild_objectmodel.cpp
+++ b/qmake/generators/win32/msbuild_objectmodel.cpp
@@ -2837,6 +2837,18 @@ XmlOutput &operator<<(XmlOutput &xml, const VCXProjectSingleConfig &tool)
// ResourceCompiler
xml << tool.Configuration.resource;
+ // Post build event
+ if ( tool.Configuration.postBuild.UseInBuild != unset )
+ xml << tool.Configuration.postBuild;
+
+ // Pre build event
+ if ( tool.Configuration.preBuild.UseInBuild != unset )
+ xml << tool.Configuration.preBuild;
+
+ // Pre link event
+ if ( tool.Configuration.preLink.UseInBuild != unset )
+ xml << tool.Configuration.preLink;
+
xml << closetag();
QFile filterFile;
@@ -3266,6 +3278,18 @@ XmlOutput &operator<<(XmlOutput &xml, VCXProject &tool)
// ResourceCompiler
xml << tool.SingleProjects.at(i).Configuration.resource;
+ // Post build event
+ if ( tool.SingleProjects.at(i).Configuration.postBuild.UseInBuild != unset )
+ xml << tool.SingleProjects.at(i).Configuration.postBuild;
+
+ // Pre build event
+ if ( tool.SingleProjects.at(i).Configuration.preBuild.UseInBuild != unset )
+ xml << tool.SingleProjects.at(i).Configuration.preBuild;
+
+ // Pre link event
+ if ( tool.SingleProjects.at(i).Configuration.preLink.UseInBuild != unset )
+ xml << tool.SingleProjects.at(i).Configuration.preLink;
+
xml << closetag();
}
diff --git a/qmake/generators/win32/msvc_vcproj.cpp b/qmake/generators/win32/msvc_vcproj.cpp
index 8c9bba8..35e4896 100644
--- a/qmake/generators/win32/msvc_vcproj.cpp
+++ b/qmake/generators/win32/msvc_vcproj.cpp
@@ -917,14 +917,12 @@ void VcprojGenerator::initCompilerTool()
conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS"));
if(project->isActiveConfig("debug")){
// Debug version
- conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_DEBUG"));
if((projectTarget == Application) || (projectTarget == StaticLib))
conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DBG"));
else
conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DLLDBG"));
} else {
// Release version
- conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_RELEASE"));
conf.compiler.PreprocessorDefinitions += "QT_NO_DEBUG";
conf.compiler.PreprocessorDefinitions += "NDEBUG";
if((projectTarget == Application) || (projectTarget == StaticLib))
@@ -934,10 +932,6 @@ void VcprojGenerator::initCompilerTool()
}
// Common for both release and debug
- if(project->isActiveConfig("warn_off"))
- conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_WARN_OFF"));
- else if(project->isActiveConfig("warn_on"))
- conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_WARN_ON"));
if(project->isActiveConfig("windows"))
conf.compiler.PreprocessorDefinitions += project->values("MSVCPROJ_WINCONDEF");
@@ -1000,22 +994,9 @@ void VcprojGenerator::initLinkerTool()
conf.linker.OutputFile += project->first("MSVCPROJ_TARGET");
- if(project->isActiveConfig("debug")){
- conf.linker.parseOptions(project->values("QMAKE_LFLAGS_DEBUG"));
- } else {
- conf.linker.parseOptions(project->values("QMAKE_LFLAGS_RELEASE"));
- }
-
if(project->isActiveConfig("dll")){
conf.linker.parseOptions(project->values("QMAKE_LFLAGS_QT_DLL"));
}
-
- if(project->isActiveConfig("console")){
- conf.linker.parseOptions(project->values("QMAKE_LFLAGS_CONSOLE"));
- } else {
- conf.linker.parseOptions(project->values("QMAKE_LFLAGS_WINDOWS"));
- }
-
}
void VcprojGenerator::initResourceTool()
diff --git a/qmake/generators/win32/msvc_vcxproj.cpp b/qmake/generators/win32/msvc_vcxproj.cpp
index 6a91c6b..da93fe3 100644
--- a/qmake/generators/win32/msvc_vcxproj.cpp
+++ b/qmake/generators/win32/msvc_vcxproj.cpp
@@ -294,14 +294,12 @@ void VcxprojGenerator::initCompilerTool()
conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS"));
if(project->isActiveConfig("debug")){
// Debug version
- conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_DEBUG"));
if((projectTarget == Application) || (projectTarget == StaticLib))
conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DBG"));
else
conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_MT_DLLDBG"));
} else {
// Release version
- conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_RELEASE"));
conf.compiler.PreprocessorDefinitions += "QT_NO_DEBUG";
conf.compiler.PreprocessorDefinitions += "NDEBUG";
if((projectTarget == Application) || (projectTarget == StaticLib))
@@ -311,10 +309,6 @@ void VcxprojGenerator::initCompilerTool()
}
// Common for both release and debug
- if(project->isActiveConfig("warn_off"))
- conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_WARN_OFF"));
- else if(project->isActiveConfig("warn_on"))
- conf.compiler.parseOptions(project->values("QMAKE_CXXFLAGS_WARN_ON"));
if(project->isActiveConfig("windows"))
conf.compiler.PreprocessorDefinitions += project->values("MSVCPROJ_WINCONDEF");
@@ -363,22 +357,9 @@ void VcxprojGenerator::initLinkerTool()
conf.linker.OutputFile += project->first("MSVCPROJ_TARGET");
- if(project->isActiveConfig("debug")){
- conf.linker.parseOptions(project->values("QMAKE_LFLAGS_DEBUG"));
- } else {
- conf.linker.parseOptions(project->values("QMAKE_LFLAGS_RELEASE"));
- }
-
if(project->isActiveConfig("dll")){
conf.linker.parseOptions(project->values("QMAKE_LFLAGS_QT_DLL"));
}
-
- if(project->isActiveConfig("console")){
- conf.linker.parseOptions(project->values("QMAKE_LFLAGS_CONSOLE"));
- } else {
- conf.linker.parseOptions(project->values("QMAKE_LFLAGS_WINDOWS"));
- }
-
}
void VcxprojGenerator::initResourceTool()
@@ -403,20 +384,24 @@ void VcxprojGenerator::initPostBuildEventTools()
QString cmdline = var("QMAKE_POST_LINK");
conf.postBuild.CommandLine = cmdline;
conf.postBuild.Description = cmdline;
+ conf.postBuild.UseInBuild = _True;
}
QString signature = !project->isEmpty("SIGNATURE_FILE") ? var("SIGNATURE_FILE") : var("DEFAULT_SIGNATURE");
bool useSignature = !signature.isEmpty() && !project->isActiveConfig("staticlib") &&
!project->isEmpty("CE_SDK") && !project->isEmpty("CE_ARCH");
- if(useSignature)
- conf.postBuild.CommandLine.prepend(QLatin1String("signtool sign /F ") + signature + " \"$(TargetPath)\"\n" +
- (!conf.postBuild.CommandLine.isEmpty() ? " && " : ""));
+ if(useSignature) {
+ conf.postBuild.CommandLine.prepend(QLatin1String("signtool sign /F ") + signature + " \"$(TargetPath)\"\n" +
+ (!conf.postBuild.CommandLine.isEmpty() ? " && " : ""));
+ conf.postBuild.UseInBuild = _True;
+ }
if(!project->values("MSVCPROJ_COPY_DLL").isEmpty()) {
if(!conf.postBuild.CommandLine.isEmpty())
conf.postBuild.CommandLine += " && ";
conf.postBuild.Description += var("MSVCPROJ_COPY_DLL_DESC");
conf.postBuild.CommandLine += var("MSVCPROJ_COPY_DLL");
+ conf.postBuild.UseInBuild = _True;
}
}
@@ -549,6 +534,7 @@ void VcxprojGenerator::initPreLinkEventTools()
QString cmdline = var("QMAKE_PRE_LINK");
conf.preLink.Description = cmdline;
conf.preLink.CommandLine = cmdline;
+ conf.preLink.UseInBuild = _True;
}
}
diff --git a/src/3rdparty/webkit/.tag b/src/3rdparty/webkit/.tag
index c750e67..b6feeb1 100644
--- a/src/3rdparty/webkit/.tag
+++ b/src/3rdparty/webkit/.tag
@@ -1 +1 @@
-8941bee5706ef2171ed5def63834deefc7440d11
+992e57ee469bd8c6a2afef6b15896a161ab8aeb3
diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION
index 23cae67..c3d6314 100644
--- a/src/3rdparty/webkit/VERSION
+++ b/src/3rdparty/webkit/VERSION
@@ -4,4 +4,4 @@ This is a snapshot of the Qt port of WebKit from
and has the sha1 checksum
- 540ae4ccd25609e1bfe1673195ce126255e36774
+ 3f0f51f4c87e65bfe04165c6af4c00934b0ca1e2
diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog
index b8825bd..05fc2af 100644
--- a/src/3rdparty/webkit/WebCore/ChangeLog
+++ b/src/3rdparty/webkit/WebCore/ChangeLog
@@ -1,3 +1,36 @@
+2010-05-03 Janne Koskinen <janne.p.koskinen@digia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Fix qtlibraryinfix not to contain space
+
+ List catenation with += adds whitespace cutting the infix
+ from the final target.
+
+ * WebCore.pro:
+
+2010-05-03 Thomas Zander <t.zander@nokia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] Fix library infix usage when compiling inside of Qt
+
+ Don't apply the infix when building inside Qt, as that's done through the
+ inclusion of qbase.pri.
+
+ * WebCore.pro:
+
+2010-04-29 Janne Koskinen <janne.p.koskinen@digia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] QtWebKit versioning added
+ https://bugs.webkit.org/show_bug.cgi?id=37207
+
+ QtWebkit releases separated from Qt release cycle.
+
+ * WebCore.pro:
+
2010-03-27 Robert Hogan <robert@webkit.org>
Reviewed by nobody, fix typo in previous commit.
diff --git a/src/3rdparty/webkit/WebCore/WebCore.pro b/src/3rdparty/webkit/WebCore/WebCore.pro
index 2a64982..3d57562 100644
--- a/src/3rdparty/webkit/WebCore/WebCore.pro
+++ b/src/3rdparty/webkit/WebCore/WebCore.pro
@@ -69,13 +69,13 @@ CONFIG(standalone_package) {
CONFIG(QTDIR_build) {
include($$QT_SOURCE_TREE/src/qbase.pri)
- # Qt will set the version for us when building in Qt's tree
} else {
- VERSION = $${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}
DESTDIR = $$OUTPUT_DIR/lib
!static: DEFINES += QT_MAKEDLL
- symbian: TARGET +=$${QT_LIBINFIX}
+ symbian: TARGET =$$TARGET$${QT_LIBINFIX}
}
+include($$PWD/../WebKit/qt/qtwebkit_version.pri)
+VERSION = $${QT_WEBKIT_MAJOR_VERSION}.$${QT_WEBKIT_MINOR_VERSION}.$${QT_WEBKIT_PATCH_VERSION}
unix {
QMAKE_PKGCONFIG_REQUIRES = QtCore QtGui QtNetwork
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp
index 3c86770..1efae16 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qgraphicswebview.cpp
@@ -292,6 +292,7 @@ void QGraphicsWebViewPrivate::update(const QRect & dirtyRect)
if (overlay)
overlay->update(QRectF(dirtyRect));
#if USE(ACCELERATED_COMPOSITING)
+ updateCompositingScrollPosition();
syncLayers();
#endif
}
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
index f28524a..b8b50b7 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
@@ -3191,233 +3191,255 @@ QWebPluginFactory *QWebPage::pluginFactory() const
\o %AppVersion% expands to QCoreApplication::applicationName()/QCoreApplication::applicationVersion() if they're set; otherwise defaulting to Qt and the current Qt version.
\endlist
*/
-QString QWebPage::userAgentForUrl(const QUrl& url) const
+QString QWebPage::userAgentForUrl(const QUrl&) const
{
- Q_UNUSED(url)
- QString ua = QLatin1String("Mozilla/5.0 ("
+ // splitting the string in three and user QStringBuilder is better than using QString::arg()
+ static QString firstPart;
+ static QString secondPart;
+ static QString thirdPart;
+
+ if (firstPart.isNull() || secondPart.isNull() || thirdPart.isNull()) {
+ QString firstPartTemp;
+ firstPartTemp.reserve(150);
+ firstPartTemp += QString::fromLatin1("Mozilla/5.0 ("
// Platform
#ifdef Q_WS_MAC
- "Macintosh"
+ "Macintosh"
#elif defined Q_WS_QWS
- "QtEmbedded"
+ "QtEmbedded"
#elif defined Q_WS_WIN
- "Windows"
+ "Windows"
#elif defined Q_WS_X11
- "X11"
+ "X11"
#elif defined Q_OS_SYMBIAN
- "SymbianOS"
+ "SymbianOS"
#else
- "Unknown"
+ "Unknown"
#endif
- // Placeholder for Platform Version
- "%1; "
+ );
+
+ firstPartTemp += QString::fromLatin1("; ");
- // Placeholder for security strength (N or U)
- "%2; "
+ // SSL support
+#if !defined(QT_NO_OPENSSL)
+ // we could check QSslSocket::supportsSsl() here, but this makes
+ // OpenSSL, certificates etc being loaded in all cases were QWebPage
+ // is used. This loading is not needed for non-https.
+ firstPartTemp += QString::fromLatin1("U; ");
+ // this may lead to a false positive: We indicate SSL since it is
+ // compiled in even though supportsSsl() might return false
+#else
+ firstPartTemp += QString::fromLatin1("N; ");
+#endif
- // Subplatform"
+ // Operating system
#ifdef Q_OS_AIX
- "AIX"
+ firstPartTemp += QString::fromLatin1("AIX");
#elif defined Q_OS_WIN32
- "%3"
+
+ switch (QSysInfo::WindowsVersion) {
+ case QSysInfo::WV_32s:
+ firstPartTemp += QString::fromLatin1("Windows 3.1");
+ break;
+ case QSysInfo::WV_95:
+ firstPartTemp += QString::fromLatin1("Windows 95");
+ break;
+ case QSysInfo::WV_98:
+ firstPartTemp += QString::fromLatin1("Windows 98");
+ break;
+ case QSysInfo::WV_Me:
+ firstPartTemp += QString::fromLatin1("Windows 98; Win 9x 4.90");
+ break;
+ case QSysInfo::WV_NT:
+ firstPartTemp += QString::fromLatin1("WinNT4.0");
+ break;
+ case QSysInfo::WV_2000:
+ firstPartTemp += QString::fromLatin1("Windows NT 5.0");
+ break;
+ case QSysInfo::WV_XP:
+ firstPartTemp += QString::fromLatin1("Windows NT 5.1");
+ break;
+ case QSysInfo::WV_2003:
+ firstPartTemp += QString::fromLatin1("Windows NT 5.2");
+ break;
+ case QSysInfo::WV_VISTA:
+ firstPartTemp += QString::fromLatin1("Windows NT 6.0");
+ break;
+ case QSysInfo::WV_WINDOWS7:
+ firstPartTemp += QString::fromLatin1("Windows NT 6.1");
+ break;
+ case QSysInfo::WV_CE:
+ firstPartTemp += QString::fromLatin1("Windows CE");
+ break;
+ case QSysInfo::WV_CENET:
+ firstPartTemp += QString::fromLatin1("Windows CE .NET");
+ break;
+ case QSysInfo::WV_CE_5:
+ firstPartTemp += QString::fromLatin1("Windows CE 5.x");
+ break;
+ case QSysInfo::WV_CE_6:
+ firstPartTemp += QString::fromLatin1("Windows CE 6.x");
+ break;
+ }
+
#elif defined Q_OS_DARWIN
#ifdef __i386__ || __x86_64__
- "Intel Mac OS X"
+ firstPartTemp += QString::fromLatin1("Intel Mac OS X");
#else
- "PPC Mac OS X"
+ firstPartTemp += QString::fromLatin1("PPC Mac OS X");
#endif
#elif defined Q_OS_BSDI
- "BSD"
+ firstPartTemp += QString::fromLatin1("BSD");
#elif defined Q_OS_BSD4
- "BSD Four"
+ firstPartTemp += QString::fromLatin1("BSD Four");
#elif defined Q_OS_CYGWIN
- "Cygwin"
+ firstPartTemp += QString::fromLatin1("Cygwin");
#elif defined Q_OS_DGUX
- "DG/UX"
+ firstPartTemp += QString::fromLatin1("DG/UX");
#elif defined Q_OS_DYNIX
- "DYNIX/ptx"
+ firstPartTemp += QString::fromLatin1("DYNIX/ptx");
#elif defined Q_OS_FREEBSD
- "FreeBSD"
+ firstPartTemp += QString::fromLatin1("FreeBSD");
#elif defined Q_OS_HPUX
- "HP-UX"
+ firstPartTemp += QString::fromLatin1("HP-UX");
#elif defined Q_OS_HURD
- "GNU Hurd"
+ firstPartTemp += QString::fromLatin1("GNU Hurd");
#elif defined Q_OS_IRIX
- "SGI Irix"
+ firstPartTemp += QString::fromLatin1("SGI Irix");
#elif defined Q_OS_LINUX
- "Linux"
+
+#if defined(__x86_64__)
+ firstPartTemp += QString::fromLatin1("Linux x86_64");
+#elif defined(__i386__)
+ firstPartTemp += QString::fromLatin1("Linux i686");
+#else
+ firstPartTemp += QString::fromLatin1("Linux");
+#endif
+
#elif defined Q_OS_LYNX
- "LynxOS"
+ firstPartTemp += QString::fromLatin1("LynxOS");
#elif defined Q_OS_NETBSD
- "NetBSD"
+ firstPartTemp += QString::fromLatin1("NetBSD");
#elif defined Q_OS_OS2
- "OS/2"
+ firstPartTemp += QString::fromLatin1("OS/2");
#elif defined Q_OS_OPENBSD
- "OpenBSD"
+ firstPartTemp += QString::fromLatin1("OpenBSD");
#elif defined Q_OS_OS2EMX
- "OS/2"
+ firstPartTemp += QString::fromLatin1("OS/2");
#elif defined Q_OS_OSF
- "HP Tru64 UNIX"
+ firstPartTemp += QString::fromLatin1("HP Tru64 UNIX");
#elif defined Q_OS_QNX6
- "QNX RTP Six"
+ firstPartTemp += QString::fromLatin1("QNX RTP Six");
#elif defined Q_OS_QNX
- "QNX"
+ firstPartTemp += QString::fromLatin1("QNX");
#elif defined Q_OS_RELIANT
- "Reliant UNIX"
+ firstPartTemp += QString::fromLatin1("Reliant UNIX");
#elif defined Q_OS_SCO
- "SCO OpenServer"
+ firstPartTemp += QString::fromLatin1("SCO OpenServer");
#elif defined Q_OS_SOLARIS
- "Sun Solaris"
+ firstPartTemp += QString::fromLatin1("Sun Solaris");
#elif defined Q_OS_ULTRIX
- "DEC Ultrix"
-#elif defined Q_WS_S60
- "Series60"
-#elif defined Q_OS_UNIX
- "UNIX BSD/SYSV system"
-#elif defined Q_OS_UNIXWARE
- "UnixWare Seven, Open UNIX Eight"
-#else
- "Unknown"
-#endif
- // Placeholder for SubPlatform Version
- "%4; ");
-
- // Platform Version
- QString osVer;
-#ifdef Q_OS_SYMBIAN
- QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion();
- switch (symbianVersion) {
- case QSysInfo::SV_9_2:
- osVer = "/9.2";
- break;
- case QSysInfo::SV_9_3:
- osVer = "/9.3";
- break;
- case QSysInfo::SV_9_4:
- osVer = "/9.4";
- break;
- default:
- osVer = "Unknown";
- }
-#endif
- ua = ua.arg(osVer);
-
- QChar securityStrength(QLatin1Char('N'));
-#if !defined(QT_NO_OPENSSL)
- // we could check QSslSocket::supportsSsl() here, but this makes
- // OpenSSL, certificates etc being loaded in all cases were QWebPage
- // is used. This loading is not needed for non-https.
- securityStrength = QLatin1Char('U');
- // this may lead to a false positive: We indicate SSL since it is
- // compiled in even though supportsSsl() might return false
-#endif
- ua = ua.arg(securityStrength);
-
-#if defined Q_OS_WIN32
- QString ver;
- switch (QSysInfo::WindowsVersion) {
- case QSysInfo::WV_32s:
- ver = "Windows 3.1";
- break;
- case QSysInfo::WV_95:
- ver = "Windows 95";
- break;
- case QSysInfo::WV_98:
- ver = "Windows 98";
- break;
- case QSysInfo::WV_Me:
- ver = "Windows 98; Win 9x 4.90";
- break;
- case QSysInfo::WV_NT:
- ver = "WinNT4.0";
+ firstPartTemp += QString::fromLatin1("DEC Ultrix");
+#elif defined Q_OS_SYMBIAN
+ firstPartTemp += QString::fromLatin1("SymbianOS");
+ QSysInfo::SymbianVersion symbianVersion = QSysInfo::symbianVersion();
+ switch (symbianVersion) {
+ case QSysInfo::SV_9_2:
+ firstPartTemp += QString::fromLatin1("/9.2");
break;
- case QSysInfo::WV_2000:
- ver = "Windows NT 5.0";
+ case QSysInfo::SV_9_3:
+ firstPartTemp += QString::fromLatin1("/9.3");
break;
- case QSysInfo::WV_XP:
- ver = "Windows NT 5.1";
+ case QSysInfo::SV_9_4:
+ firstPartTemp += QString::fromLatin1("/9.4");
break;
- case QSysInfo::WV_2003:
- ver = "Windows NT 5.2";
+ default:
+ firstPartTemp += QString::fromLatin1("/Unknown");
+ }
+
+#if defined Q_WS_S60
+ firstPartTemp += QLatin1Char(' ');
+ firstPartTemp += QString::fromLatin1("Series60");
+ QSysInfo::S60Version s60Version = QSysInfo::s60Version();
+ switch (s60Version) {
+ case QSysInfo::SV_S60_3_1:
+ firstPartTemp += QString::fromLatin1("/3.1");
break;
- case QSysInfo::WV_VISTA:
- ver = "Windows NT 6.0";
+ case QSysInfo::SV_S60_3_2:
+ firstPartTemp += QString::fromLatin1("/3.2");
break;
-#if QT_VERSION > 0x040500
- case QSysInfo::WV_WINDOWS7:
- ver = "Windows NT 6.1";
+ case QSysInfo::SV_S60_5_0:
+ firstPartTemp += QString::fromLatin1("/5.0");
break;
+ default:
+ firstPartTemp += QString::fromLatin1("/Unknown");
+ }
#endif
- case QSysInfo::WV_CE:
- ver = "Windows CE";
- break;
- case QSysInfo::WV_CENET:
- ver = "Windows CE .NET";
- break;
- case QSysInfo::WV_CE_5:
- ver = "Windows CE 5.x";
- break;
- case QSysInfo::WV_CE_6:
- ver = "Windows CE 6.x";
- break;
- }
- ua = QString(ua).arg(ver);
+
+#elif defined Q_OS_UNIX
+ firstPartTemp += QString::fromLatin1("UNIX BSD/SYSV system");
+#elif defined Q_OS_UNIXWARE
+ firstPartTemp += QString::fromLatin1("UnixWare Seven, Open UNIX Eight");
+#else
+ firstPartTemp += QString::fromLatin1("Unknown");
#endif
- // SubPlatform Version
- QString subPlatformVer;
-#ifdef Q_OS_SYMBIAN
- QSysInfo::S60Version s60Version = QSysInfo::s60Version();
- switch (s60Version) {
- case QSysInfo::SV_S60_3_1:
- subPlatformVer = "/3.1";
- break;
- case QSysInfo::SV_S60_3_2:
- subPlatformVer = "/3.2";
- break;
- case QSysInfo::SV_S60_5_0:
- subPlatformVer = "/5.0";
- break;
- default:
- subPlatformVer = " Unknown";
- }
+ // language is the split
+ firstPartTemp += QString::fromLatin1("; ");
+ firstPartTemp.squeeze();
+ firstPart = firstPartTemp;
+
+ QString secondPartTemp;
+ secondPartTemp.reserve(150);
+ secondPartTemp += QString::fromLatin1(") ");
+
+ // webkit/qt version
+ secondPartTemp += QString::fromLatin1("AppleWebKit/");
+ secondPartTemp += qWebKitVersion();
+ secondPartTemp += QString::fromLatin1(" (KHTML, like Gecko) ");
+
+
+ // Application name split the third part
+ secondPartTemp.squeeze();
+ secondPart = secondPartTemp;
+
+ QString thirdPartTemp;
+ thirdPartTemp.reserve(150);
+#if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
+ thirdPartTemp + QLatin1String(" Mobile Safari/");
+#else
+ thirdPartTemp += QLatin1String(" Safari/");
#endif
- ua = ua.arg(subPlatformVer);
+ thirdPartTemp += qWebKitVersion();
+ thirdPartTemp.squeeze();
+ thirdPart = thirdPartTemp;
+ Q_ASSERT(!firstPart.isNull());
+ Q_ASSERT(!secondPart.isNull());
+ Q_ASSERT(!thirdPart.isNull());
+ }
// Language
- QLocale locale;
+ QString languageName;
if (d->client && d->client->ownerWidget())
- locale = d->client->ownerWidget()->locale();
- QString name = locale.name();
- name[2] = QLatin1Char('-');
- ua.append(name);
- ua.append(QLatin1String(") "));
-
- // webkit/qt version
- ua.append(QString(QLatin1String("AppleWebKit/%1 (KHTML, like Gecko) "))
- .arg(QString(qWebKitVersion())));
+ languageName = d->client->ownerWidget()->locale().name();
+ else
+ languageName = QLocale().name();
+ languageName[2] = QLatin1Char('-');
// Application name/version
QString appName = QCoreApplication::applicationName();
if (!appName.isEmpty()) {
- ua.append(appName);
QString appVer = QCoreApplication::applicationVersion();
if (!appVer.isEmpty())
- ua.append(QLatin1Char('/') + appVer);
+ appName.append(QLatin1Char('/') + appVer);
} else {
// Qt version
- ua.append(QLatin1String("Qt/"));
- ua.append(QLatin1String(qVersion()));
+ appName = QString::fromLatin1("Qt/") + QString::fromLatin1(qVersion());
}
-#if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
- ua.append(QString(QLatin1String(" Mobile Safari/%1")).arg(qWebKitVersion()));
-#else
- ua.append(QString(QLatin1String(" Safari/%1")).arg(qWebKitVersion()));
-#endif
- return ua;
+ return firstPart + languageName + secondPart + appName + thirdPart;
}
diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog
index 8594f09..6e450c2 100644
--- a/src/3rdparty/webkit/WebKit/qt/ChangeLog
+++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog
@@ -1,3 +1,55 @@
+2010-04-29 Janne Koskinen <janne.p.koskinen@digia.com>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] QtWebKit versioning added
+ https://bugs.webkit.org/show_bug.cgi?id=37207
+
+ QtWebkit releases separated from Qt release cycle.
+
+ * qtwebkit_version.pri: Added.
+
+2010-05-02 Benjamin Poulain <benjamin.poulain@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] QWebPage::userAgentForUrl is terrible API
+ https://bugs.webkit.org/show_bug.cgi?id=33875
+
+ Simplify the creation of the user agent string to avoid some
+ overhead for each loaded url.
+
+ The static part of the user agent is cached so it only have
+ to be made once.
+ This creation has been made in order to simplify the code.
+
+ The two variable: application name and current language are
+ set dynamically when needed.
+ The default locale is non longer created if the widget locale
+ is used.
+
+ * Api/qwebpage.cpp:
+ (QWebPage::userAgentForUrl):
+ * tests/qwebpage/tst_qwebpage.cpp:
+ (tst_QWebPage::userAgentApplicationName):
+ (tst_QWebPage::userAgentLocaleChange):
+
+2010-05-02 Noam Rosenthal <noam.rosenthal@nokia.com>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] GraphicsLayer: animation incorrect when scrolling
+ https://bugs.webkit.org/show_bug.cgi?id=38371
+
+ This is a regression introduced with the invalidate-on-scroll code path, that uses QGraphicsWebViewPrivate::update()
+ instead of QGraphicsWebViewPrivate::scroll(). The patch makes sure that the scrolling position is correct on
+ each content update - this shouldn't have a performance impact - the only overhead is an additional value-test on each update.
+
+ Tested by http://www.the-art-of-web.com/css/css-animation/
+
+ * Api/qgraphicswebview.cpp:
+ (QGraphicsWebViewPrivate::update):
+
2010-04-29 Andreas Kling <andreas.kling@nokia.com>
Reviewed by Simon Hausmann.
diff --git a/src/3rdparty/webkit/WebKit/qt/qtwebkit_version.pri b/src/3rdparty/webkit/WebKit/qt/qtwebkit_version.pri
new file mode 100644
index 0000000..ffd192c
--- /dev/null
+++ b/src/3rdparty/webkit/WebKit/qt/qtwebkit_version.pri
@@ -0,0 +1,4 @@
+QT_WEBKIT_VERSION = 4.7.0
+QT_WEBKIT_MAJOR_VERSION = 4
+QT_WEBKIT_MINOR_VERSION = 7
+QT_WEBKIT_PATCH_VERSION = 0
diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
index 85d4b60..f7eddd5 100644
--- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp
@@ -23,6 +23,7 @@
#include <QDir>
#include <QGraphicsWidget>
#include <QLineEdit>
+#include <QLocale>
#include <QMenu>
#include <QPushButton>
#include <QtTest/QtTest>
@@ -106,6 +107,8 @@ private slots:
void errorPageExtension();
void errorPageExtensionInIFrames();
void errorPageExtensionInFrameset();
+ void userAgentApplicationName();
+ void userAgentLocaleChange();
void crashTests_LazyInitializationOfMainFrame();
@@ -1748,6 +1751,38 @@ void tst_QWebPage::errorPageExtensionInFrameset()
m_view->setPage(0);
}
+class FriendlyWebPage : public QWebPage
+{
+public:
+ friend class tst_QWebPage;
+};
+
+void tst_QWebPage::userAgentApplicationName()
+{
+ const QString oldApplicationName = QCoreApplication::applicationName();
+ FriendlyWebPage page;
+
+ const QString applicationNameMarker = QString::fromUtf8("StrangeName\342\210\236");
+ QCoreApplication::setApplicationName(applicationNameMarker);
+ QVERIFY(page.userAgentForUrl(QUrl()).contains(applicationNameMarker));
+
+ QCoreApplication::setApplicationName(oldApplicationName);
+}
+
+void tst_QWebPage::userAgentLocaleChange()
+{
+ FriendlyWebPage page;
+ m_view->setPage(&page);
+
+ const QString markerString = QString::fromLatin1(" nn-NO)");
+
+ if (page.userAgentForUrl(QUrl()).contains(markerString))
+ QSKIP("marker string already present", SkipSingle);
+
+ m_view->setLocale(QLocale(QString::fromLatin1("nn_NO")));
+ QVERIFY(page.userAgentForUrl(QUrl()).contains(markerString));
+}
+
void tst_QWebPage::crashTests_LazyInitializationOfMainFrame()
{
{
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index 59a601e..c9fbec8 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -105,7 +105,7 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_NO_TEXTCODECPLUGIN
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_TEXTCODECPLUGIN)
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QTextCodecFactoryInterface_iid, QLatin1String("/codecs")))
#endif
@@ -149,7 +149,7 @@ static bool nameMatch(const QByteArray &name, const QByteArray &test)
static QTextCodec *createForName(const QByteArray &name)
{
-#ifndef QT_NO_TEXTCODECPLUGIN
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_TEXTCODECPLUGIN)
QFactoryLoader *l = loader();
QStringList keys = l->keys();
for (int i = 0; i < keys.size(); ++i) {
@@ -1141,7 +1141,7 @@ QList<QByteArray> QTextCodec::availableCodecs()
locker.unlock();
#endif
-#ifndef QT_NO_TEXTCODECPLUGIN
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_TEXTCODECPLUGIN)
QFactoryLoader *l = loader();
QStringList keys = l->keys();
for (int i = 0; i < keys.size(); ++i) {
@@ -1181,7 +1181,7 @@ QList<int> QTextCodec::availableMibs()
locker.unlock();
#endif
-#ifndef QT_NO_TEXTCODECPLUGIN
+#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_TEXTCODECPLUGIN)
QFactoryLoader *l = loader();
QStringList keys = l->keys();
for (int i = 0; i < keys.size(); ++i) {
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index a60f206..4e580dd 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -2997,7 +2997,9 @@ bool qt_check_std3rules(const QChar *uc, int len)
// only LDH is present
if (c == '-' || (c >= '0' && c <= '9')
|| (c >= 'A' && c <= 'Z')
- || (c >= 'a' && c <= 'z'))
+ || (c >= 'a' && c <= 'z')
+ //underscore is not supposed to be allowed, but other browser accept it (QTBUG-7434)
+ || c == '_')
continue;
return false;
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index bf2e2e4..4e6e6b9 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -63,6 +63,7 @@
#include <qvarlengtharray.h>
#include <private/qfactoryloader_p.h>
#include <private/qfunctions_p.h>
+#include <private/qlocale_p.h>
#ifdef Q_OS_SYMBIAN
# include <exception>
@@ -514,13 +515,16 @@ QCoreApplication::QCoreApplication(int &argc, char **argv)
{
init();
QCoreApplicationPrivate::eventDispatcher->startingUp();
-#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_LIBRARY)
// Refresh factoryloader, as text codecs are requested during lib path
// resolving process and won't be therefore properly loaded.
// Unknown if this is symbian specific issue.
QFactoryLoader::refreshAll();
#endif
+#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
+ d_func()->symbianInit();
+#endif
}
// ### move to QCoreApplicationPrivate constructor?
@@ -597,6 +601,15 @@ void QCoreApplication::init()
qt_startup_hook();
}
+#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
+void QCoreApplicationPrivate::symbianInit()
+{
+ if (!environmentChangeNotifier)
+ environmentChangeNotifier.reset(new QEnvironmentChangeNotifier);
+}
+#endif
+
+
/*!
Destroys the QCoreApplication object.
*/
@@ -2189,7 +2202,7 @@ QString QCoreApplication::applicationVersion()
return coreappdata()->applicationVersion;
}
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive))
@@ -2291,13 +2304,11 @@ QStringList QCoreApplication::libraryPaths()
*/
void QCoreApplication::setLibraryPaths(const QStringList &paths)
{
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
QMutexLocker locker(libraryPathMutex());
if (!coreappdata()->app_libpaths)
coreappdata()->app_libpaths = new QStringList;
*(coreappdata()->app_libpaths) = paths;
QFactoryLoader::refreshAll();
-#endif
}
/*!
@@ -2318,7 +2329,6 @@ void QCoreApplication::setLibraryPaths(const QStringList &paths)
*/
void QCoreApplication::addLibraryPath(const QString &path)
{
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
if (path.isEmpty())
return;
@@ -2333,7 +2343,6 @@ void QCoreApplication::addLibraryPath(const QString &path)
coreappdata()->app_libpaths->prepend(canonicalPath);
QFactoryLoader::refreshAll();
}
-#endif
}
/*!
@@ -2344,7 +2353,6 @@ void QCoreApplication::addLibraryPath(const QString &path)
*/
void QCoreApplication::removeLibraryPath(const QString &path)
{
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
if (path.isEmpty())
return;
@@ -2356,7 +2364,6 @@ void QCoreApplication::removeLibraryPath(const QString &path)
QString canonicalPath = QDir(path).canonicalPath();
coreappdata()->app_libpaths->removeAll(canonicalPath);
QFactoryLoader::refreshAll();
-#endif
}
#endif //QT_NO_LIBRARY
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index 77188d3..e066137 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -65,6 +65,9 @@ QT_BEGIN_NAMESPACE
typedef QList<QTranslator*> QTranslatorList;
+#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
+class QEnvironmentChangeNotifier;
+#endif
class QAbstractEventDispatcher;
class Q_CORE_EXPORT QCoreApplicationPrivate : public QObjectPrivate
@@ -113,6 +116,10 @@ public:
bool aboutToQuitEmitted;
QString cachedApplicationDirPath;
QString cachedApplicationFilePath;
+#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
+ QScopedPointer<QEnvironmentChangeNotifier> environmentChangeNotifier;
+ void symbianInit();
+#endif
static bool isTranslatorInstalled(QTranslator *translator);
diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp
index a6d486e..687a6d9 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian.cpp
+++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp
@@ -1105,3 +1105,5 @@ void CQtActiveScheduler::Error(TInt aError) const
}
QT_END_NAMESPACE
+
+#include "moc_qeventdispatcher_symbian_p.cpp"
diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h
index 05758ca..bc42753 100644
--- a/src/corelib/kernel/qeventdispatcher_symbian_p.h
+++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h
@@ -221,6 +221,7 @@ public: // from CActiveScheduler
class Q_CORE_EXPORT QEventDispatcherSymbian : public QAbstractEventDispatcher
{
+ Q_OBJECT
Q_DECLARE_PRIVATE(QAbstractEventDispatcher)
public:
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index 87decc6..62d565a 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -41,7 +41,7 @@
#include "qfactoryloader_p.h"
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
#include "qfactoryinterface.h"
#include "qmap.h"
#include <qdir.h>
diff --git a/src/corelib/plugin/qfactoryloader_p.h b/src/corelib/plugin/qfactoryloader_p.h
index 51426ba..10e6e2a 100644
--- a/src/corelib/plugin/qfactoryloader_p.h
+++ b/src/corelib/plugin/qfactoryloader_p.h
@@ -57,7 +57,7 @@
#include "QtCore/qstringlist.h"
#include "private/qlibrary_p.h"
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QT_BEGIN_NAMESPACE
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp
index 67ea00d..2f09b0e 100644
--- a/src/corelib/tools/qchar.cpp
+++ b/src/corelib/tools/qchar.cpp
@@ -653,14 +653,41 @@ bool QChar::isSymbol() const
\fn bool QChar::isHighSurrogate() const
Returns true if the QChar is the high part of a utf16 surrogate
- (ie. if its code point is between 0xd800 and 0xdbff).
+ (ie. if its code point is between 0xd800 and 0xdbff, inclusive).
*/
/*!
\fn bool QChar::isLowSurrogate() const
Returns true if the QChar is the low part of a utf16 surrogate
- (ie. if its code point is between 0xdc00 and 0xdfff).
+ (ie. if its code point is between 0xdc00 and 0xdfff, inclusive).
+*/
+
+/*!
+ \fn static bool QChar::isHighSurrogate(uint ucs4)
+ \since 4.7
+
+ Returns true if the UCS-4-encoded character specified by \a ucs4
+ is the high part of a utf16 surrogate
+ (ie. if its code point is between 0xd800 and 0xdbff, inclusive).
+*/
+
+/*!
+ \fn static bool QChar::isLowSurrogate(uint ucs4)
+ \since 4.7
+
+ Returns true if the UCS-4-encoded character specified by \a ucs4
+ is the high part of a utf16 surrogate
+ (ie. if its code point is between 0xdc00 and 0xdfff, inclusive).
+*/
+
+/*!
+ \fn static bool QChar::requiresSurrogates(uint ucs4)
+ \since 4.7
+
+ Returns true if the UCS-4-encoded character specified by \a ucs4
+ can be splited to the high and low parts of a utf16 surrogate
+ (ie. if its code point is greater than or equals to 0x10000).
*/
/*!
diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h
index 1432c7f..205f911 100644
--- a/src/corelib/tools/qchar.h
+++ b/src/corelib/tools/qchar.h
@@ -285,6 +285,15 @@ public:
inline void setCell(uchar cell);
inline void setRow(uchar row);
+ static inline bool isHighSurrogate(uint ucs4) {
+ return ((ucs4 & 0xfffffc00) == 0xd800);
+ }
+ static inline bool isLowSurrogate(uint ucs4) {
+ return ((ucs4 & 0xfffffc00) == 0xdc00);
+ }
+ static inline bool requiresSurrogates(uint ucs4) {
+ return (ucs4 >= 0x10000);
+ }
static inline uint surrogateToUcs4(ushort high, ushort low) {
return (uint(high)<<10) + low - 0x35fdc00;
}
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index c3f6783..20c2e27 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -129,6 +129,11 @@ inline bool isascii(int c)
}
#endif
+#if defined(Q_OS_SYMBIAN)
+void qt_symbianUpdateSystemPrivate();
+void qt_symbianInitSystemLocale();
+#endif
+
/******************************************************************************
** Helpers for accessing Qt locale database
*/
@@ -1407,6 +1412,9 @@ static const QSystemLocale *systemLocale()
{
if (_systemLocale)
return _systemLocale;
+#if defined(Q_OS_SYMBIAN)
+ qt_symbianInitSystemLocale();
+#endif
return QSystemLocale_globalSystemLocale();
}
@@ -1417,6 +1425,10 @@ void QLocalePrivate::updateSystemPrivate()
system_lp = globalLocalePrivate();
*system_lp = *sys_locale->fallbackLocale().d();
+#if defined(Q_OS_SYMBIAN)
+ qt_symbianUpdateSystemPrivate();
+#endif
+
QVariant res = sys_locale->query(QSystemLocale::LanguageId, QVariant());
if (!res.isNull())
system_lp->m_language_id = res.toInt();
diff --git a/src/corelib/tools/qlocale_p.h b/src/corelib/tools/qlocale_p.h
index ecf79e9..6205745 100644
--- a/src/corelib/tools/qlocale_p.h
+++ b/src/corelib/tools/qlocale_p.h
@@ -58,6 +58,10 @@
#include "qlocale.h"
+#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
+class CEnvironmentChangeNotifier;
+#endif
+
QT_BEGIN_NAMESPACE
struct Q_CORE_EXPORT QLocalePrivate
@@ -201,6 +205,20 @@ inline char QLocalePrivate::digitToCLocale(const QChar &in) const
return 0;
}
+#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
+class QEnvironmentChangeNotifier
+{
+public:
+ QEnvironmentChangeNotifier();
+ ~QEnvironmentChangeNotifier();
+
+ static TInt localeChanged(TAny *data);
+
+private:
+ CEnvironmentChangeNotifier *iChangeNotifier;
+};
+#endif
+
QT_END_NAMESPACE
#endif // QLOCALE_P_H
diff --git a/src/corelib/tools/qlocale_symbian.cpp b/src/corelib/tools/qlocale_symbian.cpp
index 01f56cc..6e36dcd 100644
--- a/src/corelib/tools/qlocale_symbian.cpp
+++ b/src/corelib/tools/qlocale_symbian.cpp
@@ -46,8 +46,14 @@
#include <QThread>
#include <e32std.h>
+#include <e32const.h>
+#include <e32base.h>
+#include <e32property.h>
+#include <bacntf.h>
#include "private/qcore_symbian_p.h"
-
+#include "private/qcoreapplication_p.h"
+#include "private/qlocale_p.h"
+#include <qdebug.h>
QT_BEGIN_NAMESPACE
@@ -771,13 +777,18 @@ static QLocale::MeasurementSystem symbianMeasurementSystem()
return QLocale::MetricSystem;
}
-QLocale QSystemLocale::fallbackLocale() const
+void qt_symbianUpdateSystemPrivate()
{
// load system data before query calls
+ _s60Locale.LoadSystemSettings();
+}
+
+void qt_symbianInitSystemLocale()
+{
static QBasicAtomicInt initDone = Q_BASIC_ATOMIC_INITIALIZER(0);
+ if (initDone == 2)
+ return;
if (initDone.testAndSetRelaxed(0, 1)) {
- _s60Locale.LoadSystemSettings();
-
// Initialize platform version dependent function pointers
ptrTimeFormatL = reinterpret_cast<FormatFunc>
(qt_resolveS60PluginFunc(S60Plugin_TimeFormatL));
@@ -801,7 +812,10 @@ QLocale QSystemLocale::fallbackLocale() const
}
while(initDone != 2)
QThread::yieldCurrentThread();
+}
+QLocale QSystemLocale::fallbackLocale() const
+{
TLanguage lang = User::Language();
QString locale = QLatin1String(qt_symbianLocaleName(lang));
return QLocale(locale);
@@ -884,4 +898,35 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
return QVariant();
}
+#if !defined(QT_NO_SYSTEMLOCALE)
+QEnvironmentChangeNotifier::QEnvironmentChangeNotifier()
+{
+ // Create the change notifier and install the callback function
+ const TCallBack callback(&QEnvironmentChangeNotifier::localeChanged, this);
+ QT_TRAP_THROWING(iChangeNotifier = CEnvironmentChangeNotifier::NewL(CActive::EPriorityStandard, callback));
+ iChangeNotifier->Start();
+}
+
+TInt QEnvironmentChangeNotifier::localeChanged(TAny *data)
+{
+ QEnvironmentChangeNotifier *that = reinterpret_cast<QEnvironmentChangeNotifier *>(data);
+
+ TInt flag = that->iChangeNotifier->Change();
+ if (flag & EChangesLocale) {
+ static bool first = true;
+ if (!first) { // skip the first notification on app startup
+ QT_TRYCATCH_LEAVING(QLocalePrivate::updateSystemPrivate());
+ QT_TRYCATCH_LEAVING(QCoreApplication::postEvent(qApp, new QEvent(QEvent::LocaleChange)));
+ }
+ first = false;
+ }
+ return KErrNone;
+}
+
+QEnvironmentChangeNotifier::~QEnvironmentChangeNotifier()
+{
+ delete iChangeNotifier;
+}
+#endif
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index df0ae46..5696ba6 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -125,6 +125,10 @@ template <class Key, class T>
struct QMapNode {
Key key;
T value;
+
+private:
+ // never access these members through this structure.
+ // see below
QMapData::Node *backward;
QMapData::Node *forward[1];
};
@@ -134,6 +138,22 @@ struct QMapPayloadNode
{
Key key;
T value;
+
+private:
+ // QMap::e is a pointer to QMapData::Node, which matches the member
+ // below. However, the memory allocation node in QMapData::node_create
+ // allocates sizeof(QMapPayloNode) and incorrectly calculates the offset
+ // of 'backward' below. If the alignment of QMapPayloadNode is larger
+ // than the alignment of a pointer, the 'backward' member is aligned to
+ // the end of this structure, not to 'value' above, and will occupy the
+ // tail-padding area.
+ //
+ // e.g., on a 32-bit archictecture with Key = int and
+ // sizeof(T) = alignof(T) = 8
+ // 0 4 8 12 16 20 24 byte
+ // | key | PAD | value |backward| PAD | correct layout
+ // | key | PAD | value | |backward| how it's actually used
+ // |<----- value of QMap::payload() = 20 ----->|
QMapData::Node *backward;
};
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index a55a061..0921bdb 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -389,7 +389,7 @@ QT_BEGIN_NAMESPACE
\internal
*/
-#if !defined(QT_NO_LIBRARY) && (!defined(QT_NO_SETTINGS) || !defined(Q_OS_WIN))
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QAccessibleFactoryInterface_iid, QLatin1String("/accessible")))
#endif
@@ -532,7 +532,7 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
if (iface)
return iface;
}
-#if !defined(QT_NO_LIBRARY) && (!defined(QT_NO_SETTINGS) || !defined(Q_OS_WIN))
+#ifndef QT_NO_LIBRARY
QAccessibleFactoryInterface *factory = qobject_cast<QAccessibleFactoryInterface*>(loader()->instance(cn));
if (factory) {
iface = factory->create(cn, object);
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 8cee021..0d4e48a 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -297,6 +297,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
scenePosDescendantsUpdatePending(false),
stickyFocus(false),
hasFocus(false),
+ rectAdjust(2),
focusItem(0),
lastFocusItem(0),
tabFocusFirst(0),
@@ -3217,7 +3218,10 @@ void QGraphicsScene::update(const QRectF &rect)
// Update all views.
for (int i = 0; i < d->views.size(); ++i) {
QGraphicsView *view = d->views.at(i);
- view->d_func()->updateRegion(QRegion(view->mapFromScene(rect).boundingRect()));
+ if (view->isTransformed())
+ view->d_func()->updateRectF(view->viewportTransform().mapRect(rect));
+ else
+ view->d_func()->updateRectF(rect);
}
} else {
d->updatedRects << rect;
@@ -4701,11 +4705,11 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
if (drawItem) {
const QRectF brect = adjustedItemEffectiveBoundingRect(item);
ENSURE_TRANSFORM_PTR
- QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toRect()
- : transformPtr->mapRect(brect).toRect();
+ QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toAlignedRect()
+ : transformPtr->mapRect(brect).toAlignedRect();
+ viewBoundingRect.adjust(-rectAdjust, -rectAdjust, rectAdjust, rectAdjust);
if (widget)
item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect);
- viewBoundingRect.adjust(-1, -1, 1, 1);
drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect)
: !viewBoundingRect.normalized().isEmpty();
if (!drawItem) {
@@ -4954,34 +4958,29 @@ static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate
if (itemIsUntransformable) {
const QTransform xform = itemq->deviceTransform(viewq->viewportTransform());
if (!item->hasBoundingRegionGranularity)
- return view->updateRect(xform.mapRect(rect).toRect());
- return view->updateRegion(xform.map(QRegion(rect.toRect())));
+ return view->updateRectF(xform.mapRect(rect));
+ return view->updateRegion(rect, xform);
}
if (item->sceneTransformTranslateOnly && view->identityMatrix) {
const qreal dx = item->sceneTransform.dx();
const qreal dy = item->sceneTransform.dy();
- if (!item->hasBoundingRegionGranularity) {
- QRectF r(rect);
- r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll());
- return view->updateRect(r.toRect());
- }
- QRegion r(rect.toRect());
- r.translate(qRound(dx) - view->horizontalScroll(), qRound(dy) - view->verticalScroll());
- return view->updateRegion(r);
+ QRectF r(rect);
+ r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll());
+ return view->updateRectF(r);
}
if (!viewq->isTransformed()) {
if (!item->hasBoundingRegionGranularity)
- return view->updateRect(item->sceneTransform.mapRect(rect).toRect());
- return view->updateRegion(item->sceneTransform.map(QRegion(rect.toRect())));
+ return view->updateRectF(item->sceneTransform.mapRect(rect));
+ return view->updateRegion(rect, item->sceneTransform);
}
QTransform xform = item->sceneTransform;
xform *= viewq->viewportTransform();
if (!item->hasBoundingRegionGranularity)
- return view->updateRect(xform.mapRect(rect).toRect());
- return view->updateRegion(xform.map(QRegion(rect.toRect())));
+ return view->updateRectF(xform.mapRect(rect));
+ return view->updateRegion(rect, xform);
}
void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren,
@@ -5197,8 +5196,14 @@ void QGraphicsScene::drawItems(QPainter *painter,
// Determine view, expose and flags.
QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0;
QRegion *expose = 0;
- if (view)
+ const quint32 oldRectAdjust = d->rectAdjust;
+ if (view) {
expose = &view->d_func()->exposedRegion;
+ if (view->d_func()->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
+ d->rectAdjust = 1;
+ else
+ d->rectAdjust = 2;
+ }
// Find all toplevels, they are already sorted.
QList<QGraphicsItem *> topLevelItems;
@@ -5211,6 +5216,7 @@ void QGraphicsScene::drawItems(QPainter *painter,
}
}
+ d->rectAdjust = oldRectAdjust;
// Reset discovery bits.
for (int i = 0; i < topLevelItems.size(); ++i)
topLevelItems.at(i)->d_ptr->itemDiscovered = 0;
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 11e250e..0a85f0e 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -136,8 +136,10 @@ public:
QBrush backgroundBrush;
QBrush foregroundBrush;
- bool stickyFocus;
- bool hasFocus;
+ quint32 stickyFocus : 1;
+ quint32 hasFocus : 1;
+ quint32 padding : 30;
+ quint32 rectAdjust;
QGraphicsItem *focusItem;
QGraphicsItem *lastFocusItem;
QGraphicsWidget *tabFocusFirst;
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index c951dce..0bba7e9 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -854,10 +854,7 @@ void QGraphicsViewPrivate::processPendingUpdates()
if (fullUpdatePending) {
viewport->update();
} else if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) {
- if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
- viewport->update(dirtyBoundingRect.adjusted(-1, -1, 1, 1));
- else
- viewport->update(dirtyBoundingRect.adjusted(-2, -2, 2, 2));
+ viewport->update(dirtyBoundingRect);
} else {
viewport->update(dirtyRegion); // Already adjusted in updateRect/Region.
}
@@ -882,46 +879,44 @@ static inline void QRect_unite(QRect *rect, const QRect &other)
}
}
-bool QGraphicsViewPrivate::updateRegion(const QRegion &r)
+bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xform)
{
- if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate || r.isEmpty())
+ if (rect.isEmpty())
return false;
- const QRect boundingRect = r.boundingRect();
- if (!intersectsViewport(boundingRect, viewport->width(), viewport->height()))
- return false; // Update region outside viewport.
-
- switch (viewportUpdateMode) {
- case QGraphicsView::FullViewportUpdate:
- fullUpdatePending = true;
- viewport->update();
- break;
- case QGraphicsView::BoundingRectViewportUpdate:
- QRect_unite(&dirtyBoundingRect, boundingRect);
- if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) {
- fullUpdatePending = true;
- viewport->update();
- }
- break;
- case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE
- case QGraphicsView::MinimalViewportUpdate:
- {
- const QVector<QRect> &rects = r.rects();
- for (int i = 0; i < rects.size(); ++i) {
- if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
- dirtyRegion += rects.at(i).adjusted(-1, -1, 1, 1);
- else
- dirtyRegion += rects.at(i).adjusted(-2, -2, 2, 2);
- }
- break;
+ if (viewportUpdateMode != QGraphicsView::MinimalViewportUpdate
+ && viewportUpdateMode != QGraphicsView::SmartViewportUpdate) {
+ // No point in updating with QRegion granularity; use the rect instead.
+ return updateRectF(xform.mapRect(rect));
}
- default:
- break;
+
+ // Update mode is either Minimal or Smart, so we have to do a potentially slow operation,
+ // which is clearly documented here: QGraphicsItem::setBoundingRegionGranularity.
+ const QRegion region = xform.map(QRegion(rect.toAlignedRect()));
+ QRect viewRect = region.boundingRect();
+ const bool dontAdjustForAntialiasing = optimizationFlags & QGraphicsView::DontAdjustForAntialiasing;
+ if (dontAdjustForAntialiasing)
+ viewRect.adjust(-1, -1, 1, 1);
+ else
+ viewRect.adjust(-2, -2, 2, 2);
+ if (!intersectsViewport(viewRect, viewport->width(), viewport->height()))
+ return false; // Update region for sure outside viewport.
+
+ const QVector<QRect> &rects = region.rects();
+ for (int i = 0; i < rects.size(); ++i) {
+ viewRect = rects.at(i);
+ if (dontAdjustForAntialiasing)
+ viewRect.adjust(-1, -1, 1, 1);
+ else
+ viewRect.adjust(-2, -2, 2, 2);
+ dirtyRegion += viewRect;
}
return true;
}
+// NB! Assumes the rect 'r' is already aligned and adjusted for antialiasing.
+// For QRectF use updateRectF(const QRectF &) to ensure proper adjustments.
bool QGraphicsViewPrivate::updateRect(const QRect &r)
{
if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate
@@ -943,10 +938,7 @@ bool QGraphicsViewPrivate::updateRect(const QRect &r)
break;
case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE
case QGraphicsView::MinimalViewportUpdate:
- if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
- dirtyRegion += r.adjusted(-1, -1, 1, 1);
- else
- dirtyRegion += r.adjusted(-2, -2, 2, 2);
+ dirtyRegion += r;
break;
default:
break;
@@ -3403,8 +3395,14 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
// Items
if (!(d->optimizationFlags & IndirectPainting)) {
+ const quint32 oldRectAdjust = d->scene->d_func()->rectAdjust;
+ if (d->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
+ d->scene->d_func()->rectAdjust = 1;
+ else
+ d->scene->d_func()->rectAdjust = 2;
d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0,
&d->exposedRegion, viewport());
+ d->scene->d_func()->rectAdjust = oldRectAdjust;
// Make sure the painter's world transform is restored correctly when
// drawing without painter state protection (DontSavePainterState).
// We only change the worldTransform() so there's no need to do a full-blown
diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h
index 80e3ec1..aeff28a 100644
--- a/src/gui/graphicsview/qgraphicsview_p.h
+++ b/src/gui/graphicsview/qgraphicsview_p.h
@@ -192,8 +192,17 @@ public:
#endif
}
+ inline bool updateRectF(const QRectF &rect)
+ {
+ if (rect.isEmpty())
+ return false;
+ if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
+ return updateRect(rect.toAlignedRect().adjusted(-1, -1, 1, 1));
+ return updateRect(rect.toAlignedRect().adjusted(-2, -2, 2, 2));
+ }
+
bool updateRect(const QRect &rect);
- bool updateRegion(const QRegion &region);
+ bool updateRegion(const QRectF &rect, const QTransform &xform);
bool updateSceneSlotReimplementedChecked;
QRegion exposedRegion;
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index bc52e99..891b1db 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -441,7 +441,7 @@ void QPixmapIconEngine::virtual_hook(int id, void *data)
}
}
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive))
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loaderV2,
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 27f9627..93d5cd3 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -144,7 +144,7 @@
QT_BEGIN_NAMESPACE
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats")))
#endif
@@ -205,7 +205,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
QByteArray form = format.toLower();
QImageIOHandler *handler = 0;
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
// check if we have plugins that support the image format
QFactoryLoader *l = loader();
QStringList keys = l->keys();
@@ -217,7 +217,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
<< keys.size() << "plugins available: " << keys;
#endif
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
int suffixPluginIndex = -1;
if (device && format.isEmpty() && autoDetectImageFormat && !ignoresFormatAndExtension) {
// if there's no format, see if \a device is a file, and if so, find
@@ -246,7 +246,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
if (ignoresFormatAndExtension)
testFormat = QByteArray();
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
if (suffixPluginIndex != -1) {
// check if the plugin that claims support for this format can load
// from this device with this format.
@@ -331,7 +331,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
#endif
}
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) {
// check if any of our plugins recognize the file from its contents.
const qint64 pos = device ? device->pos() : 0;
@@ -350,7 +350,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
if (device && !device->isSequential())
device->seek(pos);
}
-#endif
+#endif // QT_NO_LIBRARY
if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) {
// check if any of our built-in handlers recognize the file from its
@@ -1414,7 +1414,7 @@ QList<QByteArray> QImageReader::supportedImageFormats()
for (int i = 0; i < _qt_NumFormats; ++i)
formats << _qt_BuiltInFormats[i].extension;
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QFactoryLoader *l = loader();
QStringList keys = l->keys();
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index 503a1b2..552729f 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -117,7 +117,7 @@
QT_BEGIN_NAMESPACE
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats")))
#endif
@@ -129,7 +129,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
QByteArray suffix;
QImageIOHandler *handler = 0;
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
// check if any plugins can write the image
QFactoryLoader *l = loader();
QStringList keys = l->keys();
@@ -142,7 +142,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
// this allows plugins to override our built-in handlers.
if (QFile *file = qobject_cast<QFile *>(device)) {
if (!(suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1()).isEmpty()) {
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
int index = keys.indexOf(QString::fromLatin1(suffix));
if (index != -1)
suffixPluginIndex = index;
@@ -153,7 +153,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
QByteArray testFormat = !form.isEmpty() ? form : suffix;
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
if (suffixPluginIndex != -1) {
// when format is missing, check if we can find a plugin for the
// suffix.
@@ -161,7 +161,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
if (plugin && (plugin->capabilities(device, suffix) & QImageIOPlugin::CanWrite))
handler = plugin->create(device, suffix);
}
-#endif // Q_NO_LIBRARY
+#endif // QT_NO_LIBRARY
// check if any built-in handlers can write the image
if (!handler && !testFormat.isEmpty()) {
@@ -192,7 +192,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
}
}
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
if (!testFormat.isEmpty()) {
for (int i = 0; i < keys.size(); ++i) {
QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i)));
@@ -203,7 +203,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
}
}
}
-#endif
+#endif // QT_NO_LIBRARY
if (!handler)
return 0;
@@ -670,7 +670,7 @@ QList<QByteArray> QImageWriter::supportedImageFormats()
formats << "png";
#endif
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QFactoryLoader *l = loader();
QStringList keys = l->keys();
for (int i = 0; i < keys.count(); ++i) {
diff --git a/src/gui/inputmethod/qinputcontextfactory.cpp b/src/gui/inputmethod/qinputcontextfactory.cpp
index d47e343..ec8d8e2 100644
--- a/src/gui/inputmethod/qinputcontextfactory.cpp
+++ b/src/gui/inputmethod/qinputcontextfactory.cpp
@@ -81,7 +81,7 @@
QT_BEGIN_NAMESPACE
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QInputContextFactoryInterface_iid, QLatin1String("/inputmethods")))
#endif
@@ -153,7 +153,7 @@ QInputContext *QInputContextFactory::create( const QString& key, QObject *parent
result = new QCoeFepInputContext;
}
#endif
-#if defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS)
+#ifdef QT_NO_LIBRARY
Q_UNUSED(key);
#else
if (QInputContextFactoryInterface *factory =
@@ -193,7 +193,7 @@ QStringList QInputContextFactory::keys()
#if defined(Q_WS_S60)
result << QLatin1String("coefep");
#endif
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
result += loader()->keys();
#endif // QT_NO_LIBRARY
return result;
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index 80334a6..4492e53 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -2145,8 +2145,8 @@ int QTableView::sizeHintForRow(int row) const
ensurePolished();
- int left = qMax(0, columnAt(0));
- int right = columnAt(d->viewport->width());
+ int left = qMax(0, d->horizontalHeader->visualIndexAt(0));
+ int right = d->horizontalHeader->visualIndexAt(d->viewport->width());
if (right == -1) // the table don't have enough columns to fill the viewport
right = d->model->columnCount(d->root) - 1;
@@ -2204,8 +2204,8 @@ int QTableView::sizeHintForColumn(int column) const
ensurePolished();
- int top = qMax(0, rowAt(0));
- int bottom = rowAt(d->viewport->height());
+ int top = qMax(0, d->verticalHeader->visualIndexAt(0));
+ int bottom = d->verticalHeader->visualIndexAt(d->viewport->height());
if (!isVisible() || bottom == -1) // the table don't have enough rows to fill the viewport
bottom = d->model->rowCount(d->root) - 1;
diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp
index ec635d4..7b62de1 100644
--- a/src/gui/kernel/qapplication.cpp
+++ b/src/gui/kernel/qapplication.cpp
@@ -788,6 +788,10 @@ void QApplicationPrivate::construct(
qt_gui_eval_init(application_type);
#endif
+#if defined(Q_OS_SYMBIAN) && !defined(QT_NO_SYSTEMLOCALE)
+ symbianInit();
+#endif
+
#ifndef QT_NO_LIBRARY
if(load_testability) {
QLibrary testLib(QLatin1String("qttestability"));
@@ -2364,6 +2368,19 @@ bool QApplication::event(QEvent *e)
if (!(w->windowType() == Qt::Desktop))
postEvent(w, new QEvent(QEvent::LanguageChange));
}
+#ifndef Q_OS_WIN
+ } else if (e->type() == QEvent::LocaleChange) {
+ // on Windows the event propagation is taken care by the
+ // WM_SETTINGCHANGE event handler.
+ QWidgetList list = topLevelWidgets();
+ for (int i = 0; i < list.size(); ++i) {
+ QWidget *w = list.at(i);
+ if (!(w->windowType() == Qt::Desktop)) {
+ if (!w->testAttribute(Qt::WA_SetLocale))
+ w->d_func()->setLocale_helper(QLocale(), true);
+ }
+ }
+#endif
} else if (e->type() == QEvent::Timer) {
QTimerEvent *te = static_cast<QTimerEvent*>(e);
Q_ASSERT(te != 0);
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index fb2837e..50b9759 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -1936,6 +1936,8 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa
QLocalePrivate::updateSystemPrivate();
if (!widget->testAttribute(Qt::WA_SetLocale))
widget->dptr()->setLocale_helper(QLocale(), true);
+ QEvent e(QEvent::LocaleChange);
+ QApplication::sendEvent(qApp, &e);
}
}
else if (msg.wParam == SPI_SETICONTITLELOGFONT) {
diff --git a/src/gui/kernel/qgesturemanager.cpp b/src/gui/kernel/qgesturemanager.cpp
index aa6720e..a806629 100644
--- a/src/gui/kernel/qgesturemanager.cpp
+++ b/src/gui/kernel/qgesturemanager.cpp
@@ -132,20 +132,20 @@ void QGestureManager::unregisterGestureRecognizer(Qt::GestureType type)
QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g);
if (list.contains(recognizer)) {
m_deletedRecognizers.insert(g, recognizer);
- m_gestureToRecognizer.remove(g);
}
}
- foreach (QGestureRecognizer *recognizer, list) {
- QList<QGesture *> obsoleteGestures;
- QMap<ObjectGesture, QList<QGesture *> >::Iterator iter = m_objectGestures.begin();
- while (iter != m_objectGestures.end()) {
- ObjectGesture objectGesture = iter.key();
- if (objectGesture.gesture == type)
- obsoleteGestures << iter.value();
- ++iter;
+ QMap<ObjectGesture, QList<QGesture *> >::const_iterator iter = m_objectGestures.begin();
+ while (iter != m_objectGestures.end()) {
+ ObjectGesture objectGesture = iter.key();
+ if (objectGesture.gesture == type) {
+ foreach (QGesture *g, iter.value()) {
+ QGestureRecognizer *recognizer = m_gestureToRecognizer.value(g);
+ m_gestureToRecognizer.remove(g);
+ m_obsoleteGestures[recognizer].append(g);
+ }
}
- m_obsoleteGestures.insert(recognizer, obsoleteGestures);
+ ++iter;
}
}
diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/gui/kernel/qguiplatformplugin.cpp
index c4119af..2dd251b 100644
--- a/src/gui/kernel/qguiplatformplugin.cpp
+++ b/src/gui/kernel/qguiplatformplugin.cpp
@@ -81,7 +81,7 @@ QGuiPlatformPlugin *qt_guiPlatformPlugin()
static QGuiPlatformPlugin *plugin;
if (!plugin)
{
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QString key = QString::fromLocal8Bit(qgetenv("QT_PLATFORM_PLUGIN"));
#ifdef Q_WS_X11
diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp
index 29f24a3..3c09894 100644
--- a/src/gui/painting/qgraphicssystemfactory.cpp
+++ b/src/gui/painting/qgraphicssystemfactory.cpp
@@ -50,7 +50,7 @@
QT_BEGIN_NAMESPACE
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QGraphicsSystemFactoryInterface_iid, QLatin1String("/graphicssystems"), Qt::CaseInsensitive))
#endif
@@ -79,7 +79,7 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key)
else if (system.isEmpty() || system == QLatin1String("native"))
return 0;
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
if (!ret) {
if (QGraphicsSystemFactoryInterface *factory = qobject_cast<QGraphicsSystemFactoryInterface*>(loader()->instance(system)))
ret = factory->create(system);
@@ -100,7 +100,7 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key)
*/
QStringList QGraphicsSystemFactory::keys()
{
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QStringList list = loader()->keys();
#else
QStringList list;
diff --git a/src/gui/painting/qpaintengine_mac.cpp b/src/gui/painting/qpaintengine_mac.cpp
index ac2fcf4..14ba94e 100644
--- a/src/gui/painting/qpaintengine_mac.cpp
+++ b/src/gui/painting/qpaintengine_mac.cpp
@@ -118,9 +118,10 @@ QMacCGContext::QMacCGContext(QPainter *p)
QRegion clip = p->paintEngine()->systemClip();
QTransform native = p->deviceTransform();
QTransform logical = p->combinedTransform();
+
if (p->hasClipping()) {
QRegion r = p->clipRegion();
- r.translate(native.dx() - logical.dx(), native.dy() - logical.dy());
+ r.translate(native.dx(), native.dy());
if (clip.isEmpty())
clip = r;
else
@@ -128,10 +129,7 @@ QMacCGContext::QMacCGContext(QPainter *p)
}
qt_mac_clip_cg(context, clip, 0);
- QPainterState *state = static_cast<QPainterState *>(pe->state);
- Q_ASSERT(state);
- if (!state->redirectionMatrix.isIdentity())
- CGContextTranslateCTM(context, state->redirectionMatrix.dx(), state->redirectionMatrix.dy());
+ CGContextTranslateCTM(context, native.dx(), native.dy());
}
}
CGContextRetain(context);
diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp
index 0f39b23..ba24d97 100644
--- a/src/gui/styles/qcleanlooksstyle.cpp
+++ b/src/gui/styles/qcleanlooksstyle.cpp
@@ -3714,6 +3714,9 @@ int QCleanlooksStyle::pixelMetric(PixelMetric metric, const QStyleOption *option
{
int ret = -1;
switch (metric) {
+ case PM_ToolTipLabelFrameWidth:
+ ret = 2;
+ break;
case PM_ButtonDefaultIndicator:
ret = 0;
break;
diff --git a/src/gui/styles/qstylefactory.cpp b/src/gui/styles/qstylefactory.cpp
index 0dbb21f..9009878 100644
--- a/src/gui/styles/qstylefactory.cpp
+++ b/src/gui/styles/qstylefactory.cpp
@@ -81,7 +81,7 @@ QT_BEGIN_INCLUDE_NAMESPACE
QT_END_INCLUDE_NAMESPACE
#endif
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QStyleFactoryInterface_iid, QLatin1String("/styles"), Qt::CaseInsensitive))
#endif
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index 0bfdbc0..a6510cb 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -226,8 +226,19 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
QFixed *outAdvances_y = glyphs->advances_y;
glyph_t *initialGlyph = outGlyphs;
- if (arraySize == 0)
- return false;
+ if (arraySize == 0) {
+ // CoreText failed to shape the text we gave it, so we assume one glyph
+ // per character and build a list of invalid glyphs with zero advance
+ *nglyphs = len;
+ for (int i = 0; i < len; ++i) {
+ outGlyphs[i] = 0;
+ logClusters[i] = i;
+ outAdvances_x[i] = QFixed();
+ outAdvances_y[i] = QFixed();
+ outAttributes[i].clusterStart = true;
+ }
+ return true;
+ }
const bool rtl = (CTRunGetStatus(static_cast<CTRunRef>(CFArrayGetValueAtIndex(array, 0))) & kCTRunStatusRightToLeft);
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index 3c596e5..a2ee659 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -885,8 +885,10 @@ void QTextControl::processEvent(QEvent *e, const QPointF &coordinateOffset, QWid
void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *contextWidget)
{
Q_D(QTextControl);
- if (d->interactionFlags & Qt::NoTextInteraction)
+ if (d->interactionFlags == Qt::NoTextInteraction) {
+ e->ignore();
return;
+ }
d->contextWidget = contextWidget;
diff --git a/src/multimedia/multimedia/audio/qaudiodevicefactory.cpp b/src/multimedia/multimedia/audio/qaudiodevicefactory.cpp
index 74add64..96545b4 100644
--- a/src/multimedia/multimedia/audio/qaudiodevicefactory.cpp
+++ b/src/multimedia/multimedia/audio/qaudiodevicefactory.cpp
@@ -67,7 +67,7 @@
QT_BEGIN_NAMESPACE
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QAudioEngineFactoryInterface_iid, QLatin1String("/audio"), Qt::CaseInsensitive))
#endif
@@ -139,7 +139,7 @@ QList<QAudioDeviceInfo> QAudioDeviceFactory::availableDevices(QAudio::Mode mode)
#endif
#endif
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QFactoryLoader* l = loader();
foreach (QString const& key, l->keys()) {
@@ -158,7 +158,7 @@ QList<QAudioDeviceInfo> QAudioDeviceFactory::availableDevices(QAudio::Mode mode)
QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice()
{
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QAudioEngineFactoryInterface* plugin = qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(QLatin1String("default")));
if (plugin) {
@@ -178,7 +178,7 @@ QAudioDeviceInfo QAudioDeviceFactory::defaultInputDevice()
QAudioDeviceInfo QAudioDeviceFactory::defaultOutputDevice()
{
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QAudioEngineFactoryInterface* plugin = qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(QLatin1String("default")));
if (plugin) {
@@ -207,7 +207,7 @@ QAbstractAudioDeviceInfo* QAudioDeviceFactory::audioDeviceInfo(const QString &re
#endif
#endif
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QAudioEngineFactoryInterface* plugin =
qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(realm));
@@ -238,7 +238,7 @@ QAbstractAudioInput* QAudioDeviceFactory::createInputDevice(QAudioDeviceInfo con
return new QAudioInputPrivate(deviceInfo.handle(), format);
#endif
#endif
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QAudioEngineFactoryInterface* plugin =
qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(deviceInfo.realm()));
@@ -260,7 +260,7 @@ QAbstractAudioOutput* QAudioDeviceFactory::createOutputDevice(QAudioDeviceInfo c
#endif
#endif
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QAudioEngineFactoryInterface* plugin =
qobject_cast<QAudioEngineFactoryInterface*>(loader()->instance(deviceInfo.realm()));
diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp
index a7bd2d5..471927a 100644
--- a/src/network/bearer/qnetworkconfigmanager_p.cpp
+++ b/src/network/bearer/qnetworkconfigmanager_p.cpp
@@ -54,8 +54,10 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QBearerEngineFactoryInterface_iid, QLatin1String("/bearer")))
+#endif
QNetworkConfigurationManagerPrivate::QNetworkConfigurationManagerPrivate()
: pollTimer(0), mutex(QMutex::Recursive), forcedPolling(0), firstUpdate(true)
@@ -354,6 +356,7 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations()
updating = false;
+#ifndef QT_NO_LIBRARY
QFactoryLoader *l = loader();
QBearerEngine *generic = 0;
@@ -387,6 +390,7 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations()
if (generic)
sessionEngines.append(generic);
+#endif // QT_NO_LIBRARY
}
QBearerEngine *engine = qobject_cast<QBearerEngine *>(sender());
diff --git a/src/opengl/gl2paintengineex/qglengineshadersource_p.h b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
index 3379296..8dba951 100644
--- a/src/opengl/gl2paintengineex/qglengineshadersource_p.h
+++ b/src/opengl/gl2paintengineex/qglengineshadersource_p.h
@@ -282,7 +282,7 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\n\
uniform mediump vec2 halfViewportSize; \n\
uniform highp vec2 invertedTextureSize; \n\
uniform highp mat3 brushTransform; \n\
- varying highp vec2 textureCoords; \n\
+ varying highp vec2 brushTextureCoords; \n\
void setPosition(void) \n\
{ \n\
highp mat3 pmvMatrix = mat3(pmvMatrix1, pmvMatrix2, pmvMatrix3); \n\
@@ -292,7 +292,7 @@ static const char* const qglslPositionWithTextureBrushVertexShader = "\n\
mediump vec3 hTexCoords = brushTransform * vec3(viewportCoords, 1); \n\
mediump float invertedHTexCoordsZ = 1.0 / hTexCoords.z; \n\
gl_Position = vec4(gl_Position.xy * invertedHTexCoordsZ, 0.0, invertedHTexCoordsZ); \n\
- textureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\
+ brushTextureCoords.xy = (hTexCoords.xy * invertedTextureSize) * gl_Position.w; \n\
}\n";
static const char* const qglslAffinePositionWithTextureBrushVertexShader
@@ -303,28 +303,28 @@ static const char* const qglslAffinePositionWithTextureBrushVertexShader
// we emulate GL_REPEAT by only taking the fractional part of the texture coords.
// TODO: Special case POT textures which don't need this emulation
static const char* const qglslTextureBrushSrcFragmentShader = "\n\
- varying highp vec2 textureCoords; \n\
+ varying highp vec2 brushTextureCoords; \n\
uniform lowp sampler2D brushTexture; \n\
lowp vec4 srcPixel() { \n\
- return texture2D(brushTexture, fract(textureCoords)); \n\
+ return texture2D(brushTexture, fract(brushTextureCoords)); \n\
}\n";
#else
static const char* const qglslTextureBrushSrcFragmentShader = "\n\
- varying highp vec2 textureCoords; \n\
+ varying highp vec2 brushTextureCoords; \n\
uniform lowp sampler2D brushTexture; \n\
lowp vec4 srcPixel() \n\
{ \n\
- return texture2D(brushTexture, textureCoords); \n\
+ return texture2D(brushTexture, brushTextureCoords); \n\
}\n";
#endif
static const char* const qglslTextureBrushSrcWithPatternFragmentShader = "\n\
- varying highp vec2 textureCoords; \n\
+ varying highp vec2 brushTextureCoords; \n\
uniform lowp vec4 patternColor; \n\
uniform lowp sampler2D brushTexture; \n\
lowp vec4 srcPixel() \n\
{ \n\
- return patternColor * (1.0 - texture2D(brushTexture, textureCoords).r); \n\
+ return patternColor * (1.0 - texture2D(brushTexture, brushTextureCoords).r); \n\
}\n";
// Solid Fill Brush
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
index 8460430..4461358 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2.cpp
@@ -1337,9 +1337,12 @@ void QGL2PaintEngineEx::drawStaticTextItem(QStaticTextItem *textItem)
d->drawCachedGlyphs(glyphType, textItem, true);
}
-void QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src)
+bool QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const QSize &size, const QRectF &src)
{
Q_D(QGL2PaintEngineEx);
+ if (!d->shaderManager)
+ return false;
+
ensureActive();
d->transferMode(ImageDrawingMode);
@@ -1354,6 +1357,7 @@ void QGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, const
d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
state()->renderHints & QPainter::SmoothPixmapTransform, textureId);
d->drawTexture(dest, srcRect, size, false);
+ return true;
}
void QGL2PaintEngineEx::drawTextItem(const QPointF &p, const QTextItem &textItem)
diff --git a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
index 30f6634..6ba0c42 100644
--- a/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
+++ b/src/opengl/gl2paintengineex/qpaintengineex_opengl2_p.h
@@ -123,7 +123,6 @@ public:
virtual void renderHintsChanged();
virtual void transformChanged();
- virtual void drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr);
virtual void drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr);
virtual void drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount, const QPixmap &pixmap,
QPainter::PixmapFragmentHints hints);
@@ -136,6 +135,8 @@ public:
virtual void drawStaticTextItem(QStaticTextItem *textItem);
+ bool drawTexture(const QRectF &r, GLuint textureId, const QSize &size, const QRectF &sr);
+
Type type() const { return OpenGL2; }
virtual void setState(QPainterState *s);
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index bf77eda..cfacf26 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -1259,11 +1259,24 @@ QGLFormat::OpenGLVersionFlags Q_AUTOTEST_EXPORT qOpenGLVersionFlagsFromString(co
versionFlags |= QGLFormat::OpenGL_Version_3_2;
case '1':
versionFlags |= QGLFormat::OpenGL_Version_3_1;
+ case '0':
+ break;
default:
+ versionFlags |= QGLFormat::OpenGL_Version_3_1 |
+ QGLFormat::OpenGL_Version_3_2;
break;
}
} else {
- qWarning("Unrecognised OpenGL version");
+ versionFlags |= QGLFormat::OpenGL_Version_1_1 |
+ QGLFormat::OpenGL_Version_1_2 |
+ QGLFormat::OpenGL_Version_1_3 |
+ QGLFormat::OpenGL_Version_1_4 |
+ QGLFormat::OpenGL_Version_1_5 |
+ QGLFormat::OpenGL_Version_2_0 |
+ QGLFormat::OpenGL_Version_2_1 |
+ QGLFormat::OpenGL_Version_3_0 |
+ QGLFormat::OpenGL_Version_3_1 |
+ QGLFormat::OpenGL_Version_3_2;
}
}
return versionFlags;
@@ -2782,8 +2795,8 @@ void QGLContext::drawTexture(const QRectF &target, GLuint textureId, GLenum text
if (!eng->isNativePaintingActive()) {
QRectF src(0, 0, target.width(), target.height());
QSize size(target.width(), target.height());
- eng->drawTexture(target, textureId, size, src);
- return;
+ if (eng->drawTexture(target, textureId, size, src))
+ return;
}
}
@@ -2858,8 +2871,8 @@ void QGLContext::drawTexture(const QPointF &point, GLuint textureId, GLenum text
QRectF dest(point, QSizeF(textureWidth, textureHeight));
QRectF src(0, 0, textureWidth, textureHeight);
QSize size(textureWidth, textureHeight);
- eng->drawTexture(dest, textureId, size, src);
- return;
+ if (eng->drawTexture(dest, textureId, size, src))
+ return;
}
}
@@ -5169,11 +5182,17 @@ Q_OPENGL_EXPORT void qt_set_gl_library_name(const QString& name)
Q_OPENGL_EXPORT const QString qt_gl_library_name()
{
if (qt_gl_lib_name()->isNull()) {
-#if defined(Q_WS_X11) || defined(Q_WS_QWS)
- return QLatin1String("GL");
-#else // Q_WS_MAC
+#ifdef Q_WS_MAC
return QLatin1String("/System/Library/Frameworks/OpenGL.framework/Versions/A/Libraries/libGL.dylib");
-#endif
+#else
+# if defined(QT_OPENGL_ES_1)
+ return QLatin1String("GLES_CM");
+# elif defined(QT_OPENGL_ES_2)
+ return QLatin1String("GLESv2");
+# else
+ return QLatin1String("GL");
+# endif
+#endif // defined Q_WS_MAC
}
return *qt_gl_lib_name();
}
diff --git a/src/opengl/qwindowsurface_gl.cpp b/src/opengl/qwindowsurface_gl.cpp
index 92a347b..7efa9bc 100644
--- a/src/opengl/qwindowsurface_gl.cpp
+++ b/src/opengl/qwindowsurface_gl.cpp
@@ -97,7 +97,6 @@ extern Q_GUI_EXPORT bool qt_win_owndc_required;
QGLGraphicsSystem::QGLGraphicsSystem(bool useX11GL)
: QGraphicsSystem(), m_useX11GL(useX11GL)
{
- QGLWindowSurface::surfaceFormat.setSampleBuffers(true);
#if defined(Q_WS_X11) && !defined(QT_OPENGL_ES)
// only override the system defaults if the user hasn't already
// picked a visual
diff --git a/src/plugins/imageformats/jpeg/qjpeghandler.cpp b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
index 1c6a289..72dde15 100644
--- a/src/plugins/imageformats/jpeg/qjpeghandler.cpp
+++ b/src/plugins/imageformats/jpeg/qjpeghandler.cpp
@@ -121,8 +121,8 @@ static boolean qt_fill_input_buffer(j_decompress_ptr cinfo)
{
my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src;
if (src->memDevice) {
- src->next_input_byte = (const JOCTET *)src->memDevice->data().constData();
- src->bytes_in_buffer = (size_t)src->memDevice->data().size();
+ src->next_input_byte = (const JOCTET *)(src->memDevice->data().constData() + src->memDevice->pos());
+ src->bytes_in_buffer = (size_t)(src->memDevice->data().size() - src->memDevice->pos());
return true;
}
src->next_input_byte = src->buffer;
@@ -169,7 +169,13 @@ static void qt_term_source(j_decompress_ptr cinfo)
{
my_jpeg_source_mgr* src = (my_jpeg_source_mgr*)cinfo->src;
if (!src->device->isSequential())
- src->device->seek(src->device->pos() - src->bytes_in_buffer);
+ {
+ // read() isn't used for memDevice, so seek past everything that was used
+ if (src->memDevice)
+ src->device->seek(src->device->pos() + (src->memDevice->data().size() - src->memDevice->pos() - src->bytes_in_buffer));
+ else
+ src->device->seek(src->device->pos() - src->bytes_in_buffer);
+ }
}
#if defined(Q_C_CALLBACKS)
diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp
index 1416ee3..76bc2b0 100644
--- a/src/sql/kernel/qsqldatabase.cpp
+++ b/src/sql/kernel/qsqldatabase.cpp
@@ -98,7 +98,7 @@
QT_BEGIN_NAMESPACE
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QSqlDriverFactoryInterface_iid,
QLatin1String("/sqldrivers")))
@@ -576,7 +576,7 @@ QStringList QSqlDatabase::drivers()
list << QLatin1String("QIBASE");
#endif
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
if (QFactoryLoader *fl = loader()) {
QStringList keys = fl->keys();
for (QStringList::const_iterator i = keys.constBegin(); i != keys.constEnd(); ++i) {
@@ -774,7 +774,7 @@ void QSqlDatabasePrivate::init(const QString &type)
}
}
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
if (!driver && loader()) {
if (QSqlDriverFactoryInterface *factory = qobject_cast<QSqlDriverFactoryInterface*>(loader()->instance(type)))
driver = factory->create(type);
diff --git a/src/svg/qsvghandler.cpp b/src/svg/qsvghandler.cpp
index b6e771f..d545440 100644
--- a/src/svg/qsvghandler.cpp
+++ b/src/svg/qsvghandler.cpp
@@ -3751,7 +3751,7 @@ bool QSvgHandler::characters(const QStringRef &str)
QCss::Parser(css).parse(&sheet);
m_selector->styleSheets.append(sheet);
return true;
- } else if (m_skipNodes.isEmpty() || m_skipNodes.top() == Unknown)
+ } else if (m_skipNodes.isEmpty() || m_skipNodes.top() == Unknown || m_nodes.isEmpty())
return true;
if (m_nodes.top()->type() == QSvgNode::TEXT || m_nodes.top()->type() == QSvgNode::TEXTAREA) {
diff --git a/tests/auto/gestures/tst_gestures.cpp b/tests/auto/gestures/tst_gestures.cpp
index f8ecca3..dfadf48 100644
--- a/tests/auto/gestures/tst_gestures.cpp
+++ b/tests/auto/gestures/tst_gestures.cpp
@@ -50,6 +50,7 @@
#include <qgesturerecognizer.h>
#include <qgraphicsitem.h>
#include <qgraphicsview.h>
+#include <qmainwindow.h>
#include <qdebug.h>
@@ -355,6 +356,7 @@ private slots:
void deleteGestureTargetItem();
void viewportCoordinates();
void partialGesturePropagation();
+ void testQGestureRecognizerCleanup();
};
tst_Gestures::tst_Gestures()
@@ -1949,5 +1951,74 @@ void tst_Gestures::partialGesturePropagation()
QCOMPARE(item4->gestureEventsReceived, 0);
}
+class WinNativePan : public QPanGesture {
+public:
+ WinNativePan() {}
+};
+
+class Pan : public QPanGesture {
+public:
+ Pan() {}
+};
+
+class CustomPan : public QPanGesture {
+public:
+ CustomPan() {}
+};
+
+// Recognizer for active gesture triggers on mouse press
+class PanRecognizer : public QGestureRecognizer {
+public:
+ enum PanType { Platform, Default, Custom };
+
+ PanRecognizer(int id) : m_id(id) {}
+ QGesture *create(QObject *) {
+ switch(m_id) {
+ case Platform: return new WinNativePan();
+ case Default: return new Pan();
+ default: return new CustomPan();
+ }
+ }
+
+ Result recognize(QGesture *, QObject *, QEvent *) { return QGestureRecognizer::Ignore; }
+
+ const int m_id;
+};
+
+void tst_Gestures::testQGestureRecognizerCleanup()
+{
+ // Clean first the current recognizers in QGManager
+ QGestureRecognizer::unregisterRecognizer(Qt::PanGesture);
+
+ // v-- Qt singleton QGManager initialization
+
+ // Mimic QGestureManager: register both default and "platform" recognizers
+ // (this is done in windows when QT_NO_NATIVE_GESTURES is not defined)
+ PanRecognizer *def = new PanRecognizer(PanRecognizer::Default);
+ QGestureRecognizer::registerRecognizer(def);
+ PanRecognizer *plt = new PanRecognizer(PanRecognizer::Platform);
+ QGestureRecognizer::registerRecognizer(plt);
+ qDebug () << "register: default =" << def << "; platform =" << plt;
+
+ // ^-- Qt singleton QGManager initialization
+
+ // Here, application code would start
+
+ // Create QGV (has a QAScrollArea, which uses Qt::PanGesture)
+ QMainWindow *w = new QMainWindow;
+ QGraphicsView *v = new QGraphicsView();
+ w->setCentralWidget(v);
+
+ // Unregister Qt recognizers
+ QGestureRecognizer::unregisterRecognizer(Qt::PanGesture);
+
+ // Register a custom Pan recognizer
+ //QGestureRecognizer::registerRecognizer(new PanRecognizer(PanRecognizer::Custom));
+
+ w->show();
+ QTest::qWaitForWindowShown(w);
+ delete w;
+}
+
QTEST_MAIN(tst_Gestures)
#include "tst_gestures.moc"
diff --git a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
index 055ae80..81097be 100644
--- a/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
+++ b/tests/auto/qgraphicsitem/tst_qgraphicsitem.cpp
@@ -7293,7 +7293,7 @@ void tst_QGraphicsItem::update()
QCOMPARE(item->repaints, 1);
QCOMPARE(view.repaints, 1);
QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform())
- .mapRect(item->boundingRect()).toRect();
+ .mapRect(item->boundingRect()).toAlignedRect();
QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2);
// The entire item's bounding rect (adjusted for antialiasing) should have been painted.
QCOMPARE(view.paintedRegion, expectedRegion);
@@ -7372,7 +7372,7 @@ void tst_QGraphicsItem::update()
scene.addItem(parent);
QTest::qWait(50);
itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform())
- .mapRect(item->boundingRect()).toRect();
+ .mapRect(item->boundingRect()).toAlignedRect();
expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2);
view.reset();
item->repaints = 0;
@@ -7648,7 +7648,7 @@ void tst_QGraphicsItem::moveItem()
// Item's boundingRect: (-10, -10, 20, 20).
QRect parentDeviceBoundingRect = parent->deviceTransform(view.viewportTransform())
- .mapRect(parent->boundingRect()).toRect()
+ .mapRect(parent->boundingRect()).toAlignedRect()
.adjusted(-2, -2, 2, 2); // Adjusted for antialiasing.
parent->setPos(20, 20);
@@ -7711,8 +7711,14 @@ void tst_QGraphicsItem::moveLineItem()
QTest::qWait(200);
view.reset();
+ QRectF brect = item->boundingRect();
+ // Do same adjustments as in qgraphicsscene.cpp
+ if (!brect.width())
+ brect.adjust(qreal(-0.00001), 0, qreal(0.00001), 0);
+ if (!brect.height())
+ brect.adjust(0, qreal(-0.00001), 0, qreal(0.00001));
const QRect itemDeviceBoundingRect = item->deviceTransform(view.viewportTransform())
- .mapRect(item->boundingRect()).toRect();
+ .mapRect(brect).toAlignedRect();
QRegion expectedRegion = itemDeviceBoundingRect.adjusted(-2, -2, 2, 2); // antialiasing
// Make sure the calculated region is correct.
diff --git a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
index d0752af..1df9a37 100644
--- a/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
+++ b/tests/auto/qgraphicsview/tst_qgraphicsview.cpp
@@ -216,6 +216,8 @@ private slots:
void exposeRegion();
void update_data();
void update();
+ void update2_data();
+ void update2();
void inputMethodSensitivity();
void inputContextReset();
void indirectPainting();
@@ -1383,28 +1385,48 @@ void tst_QGraphicsView::itemsInRect_cosmeticAdjust_data()
{
QTest::addColumn<QRect>("updateRect");
QTest::addColumn<int>("numPaints");
+ QTest::addColumn<bool>("adjustForAntialiasing");
- QTest::newRow("nil") << QRect() << 1;
- QTest::newRow("0, 0, 300, 100") << QRect(0, 0, 300, 100) << 1;
- QTest::newRow("0, 0, 100, 300") << QRect(0, 0, 100, 300) << 1;
- QTest::newRow("200, 0, 100, 300") << QRect(200, 0, 100, 300) << 1;
- QTest::newRow("0, 200, 300, 100") << QRect(0, 200, 300, 100) << 1;
- QTest::newRow("0, 0, 300, 99") << QRect(0, 0, 300, 99) << 0;
- QTest::newRow("0, 0, 99, 300") << QRect(0, 0, 99, 300) << 0;
- QTest::newRow("201, 0, 99, 300") << QRect(201, 0, 99, 300) << 0;
- QTest::newRow("0, 201, 300, 99") << QRect(0, 201, 300, 99) << 0;
+ // Aliased.
+ QTest::newRow("nil") << QRect() << 1 << false;
+ QTest::newRow("0, 0, 300, 100") << QRect(0, 0, 300, 100) << 1 << false;
+ QTest::newRow("0, 0, 100, 300") << QRect(0, 0, 100, 300) << 1 << false;
+ QTest::newRow("200, 0, 100, 300") << QRect(200, 0, 100, 300) << 1 << false;
+ QTest::newRow("0, 200, 300, 100") << QRect(0, 200, 300, 100) << 1 << false;
+ QTest::newRow("0, 0, 300, 99") << QRect(0, 0, 300, 99) << 0 << false;
+ QTest::newRow("0, 0, 99, 300") << QRect(0, 0, 99, 300) << 0 << false;
+ QTest::newRow("201, 0, 99, 300") << QRect(201, 0, 99, 300) << 0 << false;
+ QTest::newRow("0, 201, 300, 99") << QRect(0, 201, 300, 99) << 0 << false;
+
+ // Anti-aliased.
+ QTest::newRow("nil") << QRect() << 1 << true;
+ QTest::newRow("0, 0, 300, 100") << QRect(0, 0, 300, 100) << 1 << true;
+ QTest::newRow("0, 0, 100, 300") << QRect(0, 0, 100, 300) << 1 << true;
+ QTest::newRow("200, 0, 100, 300") << QRect(200, 0, 100, 300) << 1 << true;
+ QTest::newRow("0, 200, 300, 100") << QRect(0, 200, 300, 100) << 1 << true;
+ QTest::newRow("0, 0, 300, 99") << QRect(0, 0, 300, 99) << 1 << true;
+ QTest::newRow("0, 0, 99, 300") << QRect(0, 0, 99, 300) << 1 << true;
+ QTest::newRow("201, 0, 99, 300") << QRect(201, 0, 99, 300) << 1 << true;
+ QTest::newRow("0, 201, 300, 99") << QRect(0, 201, 300, 99) << 1 << true;
+ QTest::newRow("0, 0, 300, 98") << QRect(0, 0, 300, 98) << 0 << false;
+ QTest::newRow("0, 0, 98, 300") << QRect(0, 0, 98, 300) << 0 << false;
+ QTest::newRow("202, 0, 98, 300") << QRect(202, 0, 98, 300) << 0 << false;
+ QTest::newRow("0, 202, 300, 98") << QRect(0, 202, 300, 98) << 0 << false;
}
void tst_QGraphicsView::itemsInRect_cosmeticAdjust()
{
QFETCH(QRect, updateRect);
QFETCH(int, numPaints);
+ QFETCH(bool, adjustForAntialiasing);
QGraphicsScene scene(-100, -100, 200, 200);
CountPaintItem *rect = new CountPaintItem(QRectF(-50, -50, 100, 100));
scene.addItem(rect);
QGraphicsView view(&scene);
+ view.setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing, !adjustForAntialiasing);
+ view.setRenderHint(QPainter::Antialiasing, adjustForAntialiasing);
view.setFrameStyle(0);
view.resize(300, 300);
view.show();
@@ -2219,8 +2241,8 @@ void tst_QGraphicsView::viewportUpdateMode()
QTRY_VERIFY(!view.lastUpdateRegions.isEmpty());
#ifndef QT_MAC_USE_COCOA //cocoa doesn't support drawing regions
QCOMPARE(view.lastUpdateRegions.last().rects().size(), 2);
- QCOMPARE(view.lastUpdateRegions.last().rects().at(0).size(), QSize(15, 15));
- QCOMPARE(view.lastUpdateRegions.last().rects().at(1).size(), QSize(15, 15));
+ QCOMPARE(view.lastUpdateRegions.last().rects().at(0).size(), QSize(14, 14));
+ QCOMPARE(view.lastUpdateRegions.last().rects().at(1).size(), QSize(14, 14));
#endif
// Set full update mode.
@@ -2254,7 +2276,7 @@ void tst_QGraphicsView::viewportUpdateMode()
// The view gets one bounding rect update.
QCOMPARE(view.lastUpdateRegions.last().rects().size(), 1);
- QCOMPARE(view.lastUpdateRegions.last().rects().at(0).size(), QSize(33, 33));
+ QCOMPARE(view.lastUpdateRegions.last().rects().at(0).size(), QSize(32, 32));
// Set no update mode
view.setViewportUpdateMode(QGraphicsView::NoViewportUpdate);
@@ -3647,7 +3669,6 @@ void tst_QGraphicsView::update()
const bool intersects = updateRect.intersects(viewportRect);
QGraphicsViewPrivate *viewPrivate = static_cast<QGraphicsViewPrivate *>(qt_widget_private(&view));
QTRY_COMPARE(viewPrivate->updateRect(updateRect), intersects);
- QCOMPARE(viewPrivate->updateRegion(updateRect), intersects);
view.lastUpdateRegions.clear();
viewPrivate->processPendingUpdates();
@@ -3658,13 +3679,85 @@ void tst_QGraphicsView::update()
QTRY_VERIFY(view.lastUpdateRegions.isEmpty());
} else {
QTRY_COMPARE(view.lastUpdateRegions.size(), 1);
- // Note that we adjust by 2 for antialiasing.
- QTRY_COMPARE(view.lastUpdateRegions.at(0), QRegion(updateRect.adjusted(-2, -2, 2, 2) & viewportRect));
+ QTRY_COMPARE(view.lastUpdateRegions.at(0), QRegion(updateRect) & viewportRect);
}
QTRY_VERIFY(!viewPrivate->fullUpdatePending);
#endif
}
+void tst_QGraphicsView::update2_data()
+{
+ QTest::addColumn<qreal>("penWidth");
+ QTest::addColumn<bool>("antialiasing");
+
+ // Anti-aliased.
+ QTest::newRow("pen width: 0.0, antialiasing: true") << 0.0 << true;
+ QTest::newRow("pen width: 1.5, antialiasing: true") << 1.5 << true;
+ QTest::newRow("pen width: 2.0, antialiasing: true") << 2.0 << true;
+ QTest::newRow("pen width: 3.0, antialiasing: true") << 3.0 << true;
+
+ // Aliased.
+ QTest::newRow("pen width: 0.0, antialiasing: false") << 0.0 << false;
+ QTest::newRow("pen width: 1.5, antialiasing: false") << 1.5 << false;
+ QTest::newRow("pen width: 2.0, antialiasing: false") << 2.0 << false;
+ QTest::newRow("pen width: 3.0, antialiasing: false") << 3.0 << false;
+}
+
+void tst_QGraphicsView::update2()
+{
+ QFETCH(qreal, penWidth);
+ QFETCH(bool, antialiasing);
+
+ // Create a rect item.
+ const QRectF rawItemRect(-50.4, -50.3, 100.2, 100.1);
+ CountPaintItem *rect = new CountPaintItem(rawItemRect);
+ QPen pen;
+ pen.setWidthF(penWidth);
+ rect->setPen(pen);
+
+ // Add item to a scene.
+ QGraphicsScene scene(-100, -100, 200, 200);
+ scene.addItem(rect);
+
+ // Create a view on the scene.
+ CustomView view(&scene);
+ view.setOptimizationFlag(QGraphicsView::DontAdjustForAntialiasing, !antialiasing);
+ view.setRenderHint(QPainter::Antialiasing, antialiasing);
+ view.setFrameStyle(0);
+ view.resize(200, 200);
+ view.show();
+ QTest::qWaitForWindowShown(&view) ;
+ QTRY_VERIFY(rect->numPaints > 0);
+
+ // Calculate expected update region for the rect.
+ QRectF expectedItemBoundingRect = rawItemRect;
+ const qreal halfPenWidth = penWidth / qreal(2.0);
+ expectedItemBoundingRect.adjust(-halfPenWidth, -halfPenWidth, halfPenWidth, halfPenWidth);
+ QCOMPARE(rect->boundingRect(), expectedItemBoundingRect);
+
+ QRect expectedItemDeviceBoundingRect = rect->deviceTransform(view.viewportTransform())
+ .mapRect(expectedItemBoundingRect).toAlignedRect();
+ if (antialiasing)
+ expectedItemDeviceBoundingRect.adjust(-2, -2, 2, 2);
+ else
+ expectedItemDeviceBoundingRect.adjust(-1, -1, 1, 1);
+ const QRegion expectedUpdateRegion(expectedItemDeviceBoundingRect);
+
+ // Reset.
+ rect->numPaints = 0;
+ view.lastUpdateRegions.clear();
+ view.painted = false;
+
+ rect->update();
+ QTRY_VERIFY(view.painted);
+
+#ifndef QT_MAC_USE_COCOA //cocoa doesn't support drawing regions
+ QTRY_VERIFY(view.painted);
+ QCOMPARE(view.lastUpdateRegions.size(), 1);
+ QCOMPARE(view.lastUpdateRegions.at(0), expectedUpdateRegion);
+#endif
+}
+
class FocusItem : public QGraphicsRectItem
{
public:
diff --git a/tests/auto/qtableview/tst_qtableview.cpp b/tests/auto/qtableview/tst_qtableview.cpp
index 2062e8e..3e5d077 100644
--- a/tests/auto/qtableview/tst_qtableview.cpp
+++ b/tests/auto/qtableview/tst_qtableview.cpp
@@ -202,6 +202,7 @@ private slots:
void taskQTBUG_8585_crashForNoGoodReason();
void taskQTBUG_7774_RtoLVisualRegionForSelection();
void taskQTBUG_8777_scrollToSpans();
+ void taskQTBUG_10169_sizeHintForRow();
void mouseWheel_data();
void mouseWheel();
@@ -478,6 +479,11 @@ public:
return QTableView::selectedIndexes();
}
+ int sizeHintForRow(int row) const
+ {
+ return QTableView::sizeHintForRow(row);
+ }
+
bool checkSignalOrder;
public slots:
void currentChanged(QModelIndex , QModelIndex ) {
@@ -4042,5 +4048,20 @@ void tst_QTableView::taskQTBUG_8777_scrollToSpans()
QVERIFY(table.verticalScrollBar()->value() > 10);
}
+void tst_QTableView::taskQTBUG_10169_sizeHintForRow()
+{
+ QtTestTableView tableView;
+ QStandardItemModel model(1, 3);
+ model.setData(model.index(0, 0), "Word wrapping text goes here.");
+ tableView.setModel(&model);
+ tableView.verticalHeader()->setResizeMode(QHeaderView::ResizeToContents);
+ const int orderedHeight = tableView.sizeHintForRow(0);
+ tableView.horizontalHeader()->moveSection(2, 0);
+ const int reorderedHeight = tableView.sizeHintForRow(0);
+
+ //the order of the columns shouldn't matter.
+ QCOMPARE(orderedHeight, reorderedHeight);
+}
+
QTEST_MAIN(tst_QTableView)
#include "tst_qtableview.moc"
diff --git a/tests/auto/qurl/tst_qurl.cpp b/tests/auto/qurl/tst_qurl.cpp
index b7cbdb8..fa42adc 100644
--- a/tests/auto/qurl/tst_qurl.cpp
+++ b/tests/auto/qurl/tst_qurl.cpp
@@ -1632,6 +1632,10 @@ void tst_QUrl::toString_data()
QTest::newRow("nopath_task31320") << QString::fromLatin1("host://protocol")
<< uint(QUrl::None)
<< QString::fromLatin1("host://protocol");
+
+ QTest::newRow("underscore_QTBUG-7434") << QString::fromLatin1("http://foo_bar.host.com/rss.php")
+ << uint(QUrl::None)
+ << QString::fromLatin1("http://foo_bar.host.com/rss.php");
}
void tst_QUrl::toString()
@@ -3244,7 +3248,6 @@ void tst_QUrl::std3violations_data()
QTest::newRow("question") << "foo?bar" << true;
QTest::newRow("at") << "foo@bar" << true;
QTest::newRow("backslash") << "foo\\bar" << false;
- QTest::newRow("underline") << "foo_bar" << false;
// these characters are transformed by NFKC to non-LDH characters
QTest::newRow("dot-like") << QString::fromUtf8("foo\342\200\244bar") << false; // U+2024 ONE DOT LEADER
@@ -3289,6 +3292,7 @@ void tst_QUrl::std3deviations_data()
QTest::newRow("ending-dot") << "example.com.";
QTest::newRow("ending-dot3002") << QString("example.com") + QChar(0x3002);
+ QTest::newRow("underline") << "foo_bar"; //QTBUG-7434
}
void tst_QUrl::std3deviations()
diff --git a/tests/auto/qvector/tst_qvector.cpp b/tests/auto/qvector/tst_qvector.cpp
index ebc19ed..2bc8d15 100644
--- a/tests/auto/qvector/tst_qvector.cpp
+++ b/tests/auto/qvector/tst_qvector.cpp
@@ -55,10 +55,610 @@ public:
virtual ~tst_QVector() {}
private slots:
+ void constructors() const;
+ void append() const;
+ void at() const;
+ void capacity() const;
+ void clear() const;
+ void constData() const;
+ void contains() const;
+ void count() const;
+ void data() const;
+ void empty() const;
+ void endsWith() const;
+ void fill() const;
+ void first() const;
+ void fromList() const;
+ void fromStdVector() const;
+ void indexOf() const;
+ void insert() const;
+ void isEmpty() const;
+ void last() const;
+ void lastIndexOf() const;
+ void mid() const;
+ void prepend() const;
+ void remove() const;
+ void size() const;
+ void startsWith() const;
+ void toList() const;
+ void toStdVector() const;
+ void value() const;
+
+ void testOperators() const;
+
void outOfMemory();
void QTBUG6416_reserve();
};
+void tst_QVector::constructors() const
+{
+ // pre-reserve capacity
+ {
+ QVector<int> myvec(5);
+
+ QVERIFY(myvec.capacity() == 5);
+ }
+
+ // default-initialise items
+ {
+ QVector<int> myvec(5, 42);
+
+ QVERIFY(myvec.capacity() == 5);
+
+ // make sure all items are initialised ok
+ foreach (int meaningoflife, myvec) {
+ QCOMPARE(meaningoflife, 42);
+ }
+ }
+}
+
+void tst_QVector::append() const
+{
+ QVector<int> myvec;
+ myvec.append(42);
+ myvec.append(43);
+ myvec.append(44);
+
+ QVERIFY(myvec.size() == 3);
+ QCOMPARE(myvec, QVector<int>() << 42 << 43 << 44);
+}
+
+void tst_QVector::at() const
+{
+ QVector<QString> myvec;
+ myvec << "foo" << "bar" << "baz";
+
+ QVERIFY(myvec.size() == 3);
+ QCOMPARE(myvec.at(0), QLatin1String("foo"));
+ QCOMPARE(myvec.at(1), QLatin1String("bar"));
+ QCOMPARE(myvec.at(2), QLatin1String("baz"));
+
+ // append an item
+ myvec << "hello";
+ QVERIFY(myvec.size() == 4);
+ QCOMPARE(myvec.at(0), QLatin1String("foo"));
+ QCOMPARE(myvec.at(1), QLatin1String("bar"));
+ QCOMPARE(myvec.at(2), QLatin1String("baz"));
+ QCOMPARE(myvec.at(3), QLatin1String("hello"));
+
+ // remove an item
+ myvec.remove(1);
+ QVERIFY(myvec.size() == 3);
+ QCOMPARE(myvec.at(0), QLatin1String("foo"));
+ QCOMPARE(myvec.at(1), QLatin1String("baz"));
+ QCOMPARE(myvec.at(2), QLatin1String("hello"));
+}
+
+void tst_QVector::capacity() const
+{
+ QVector<QString> myvec;
+
+ // TODO: is this guarenteed? seems a safe assumption, but I suppose preallocation of a
+ // few items isn't an entirely unforseeable possibility.
+ QVERIFY(myvec.capacity() == 0);
+
+ // test it gets a size
+ myvec << "aaa" << "bbb" << "ccc";
+ QVERIFY(myvec.capacity() >= 3);
+
+ // make sure it grows ok
+ myvec << "aaa" << "bbb" << "ccc";
+ QVERIFY(myvec.capacity() >= 6);
+
+ // let's try squeeze a bit
+ myvec.remove(3);
+ myvec.remove(3);
+ myvec.remove(3);
+ // TODO: is this a safe assumption? presumably it won't release memory until shrink(), but can we asser that is true?
+ QVERIFY(myvec.capacity() >= 6);
+ myvec.squeeze();
+ QVERIFY(myvec.capacity() >= 3);
+
+ myvec.remove(0);
+ myvec.remove(0);
+ myvec.remove(0);
+ // TODO: as above note
+ QVERIFY(myvec.capacity() >= 3);
+ myvec.squeeze();
+ QVERIFY(myvec.capacity() == 0);
+}
+
+void tst_QVector::clear() const
+{
+ QVector<QString> myvec;
+ myvec << "aaa" << "bbb" << "ccc";
+
+ QVERIFY(myvec.size() == 3);
+ myvec.clear();
+ QVERIFY(myvec.size() == 0);
+ QVERIFY(myvec.capacity() == 0);
+}
+
+void tst_QVector::constData() const
+{
+ int arr[] = { 42, 43, 44 };
+ QVector<int> myvec;
+ myvec << 42 << 43 << 44;
+
+ QVERIFY(memcmp(myvec.constData(), reinterpret_cast<const int *>(&arr), sizeof(int) * 3) == 0);
+}
+
+void tst_QVector::contains() const
+{
+ QVector<QString> myvec;
+ myvec << "aaa" << "bbb" << "ccc";
+
+ QVERIFY(myvec.contains(QLatin1String("aaa")));
+ QVERIFY(myvec.contains(QLatin1String("bbb")));
+ QVERIFY(myvec.contains(QLatin1String("ccc")));
+ QVERIFY(!myvec.contains(QLatin1String("I don't exist")));
+
+ // add it and make sure it does :)
+ myvec.append(QLatin1String("I don't exist"));
+ QVERIFY(myvec.contains(QLatin1String("I don't exist")));
+}
+
+void tst_QVector::count() const
+{
+ // total size
+ {
+ // zero size
+ QVector<int> myvec;
+ QVERIFY(myvec.count() == 0);
+
+ // grow
+ myvec.append(42);
+ QVERIFY(myvec.count() == 1);
+ myvec.append(42);
+ QVERIFY(myvec.count() == 2);
+
+ // shrink
+ myvec.remove(0);
+ QVERIFY(myvec.count() == 1);
+ myvec.remove(0);
+ QVERIFY(myvec.count() == 0);
+ }
+
+ // count of items
+ {
+ QVector<QString> myvec;
+ myvec << "aaa" << "bbb" << "ccc";
+
+ // initial tests
+ QVERIFY(myvec.count(QLatin1String("aaa")) == 1);
+ QVERIFY(myvec.count(QLatin1String("pirates")) == 0);
+
+ // grow
+ myvec.append(QLatin1String("aaa"));
+ QVERIFY(myvec.count(QLatin1String("aaa")) == 2);
+
+ // shrink
+ myvec.remove(0);
+ QVERIFY(myvec.count(QLatin1String("aaa")) == 1);
+ }
+}
+
+void tst_QVector::data() const
+{
+ QVector<int> myvec;
+ myvec << 42 << 43 << 44;
+
+ // make sure it starts off ok
+ QCOMPARE(*(myvec.data() + 1), 43);
+
+ // alter it
+ *(myvec.data() + 1) = 69;
+
+ // check it altered
+ QCOMPARE(*(myvec.data() + 1), 69);
+
+ int arr[] = { 42, 69, 44 };
+ QVERIFY(memcmp(myvec.data(), reinterpret_cast<int *>(&arr), sizeof(int) * 3) == 0);
+}
+
+void tst_QVector::empty() const
+{
+ QVector<int> myvec;
+
+ // starts empty
+ QVERIFY(myvec.empty());
+
+ // not empty
+ myvec.append(1);
+ QVERIFY(!myvec.empty());
+
+ // empty again
+ myvec.remove(0);
+ QVERIFY(myvec.empty());
+}
+
+void tst_QVector::endsWith() const
+{
+ QVector<int> myvec;
+
+ // empty vector
+ QVERIFY(!myvec.endsWith(1));
+
+ // add the one, should work
+ myvec.append(1);
+ QVERIFY(myvec.endsWith(1));
+
+ // add something else, fails now
+ myvec.append(3);
+ QVERIFY(!myvec.endsWith(1));
+
+ // remove it again :)
+ myvec.remove(1);
+ QVERIFY(myvec.endsWith(1));
+}
+
+void tst_QVector::fill() const
+{
+ QVector<int> myvec;
+
+ // resize
+ myvec.resize(5);
+ myvec.fill(69);
+ QCOMPARE(myvec, QVector<int>() << 69 << 69 << 69 << 69 << 69);
+
+ // make sure it can resize itself too
+ myvec.fill(42, 10);
+ QCOMPARE(myvec, QVector<int>() << 42 << 42 << 42 << 42 << 42 << 42 << 42 << 42 << 42 << 42);
+}
+
+void tst_QVector::first() const
+{
+ QVector<int> myvec;
+ myvec << 69 << 42 << 3;
+
+ // test it starts ok
+ QCOMPARE(myvec.first(), 69);
+
+ // test removal changes
+ myvec.remove(0);
+ QCOMPARE(myvec.first(), 42);
+
+ // test prepend changes
+ myvec.prepend(23);
+ QCOMPARE(myvec.first(), 23);
+}
+
+void tst_QVector::fromList() const
+{
+ QList<QString> list;
+ list << "aaa" << "bbb" << "ninjas" << "pirates";
+
+ QVector<QString> myvec;
+ myvec = QVector<QString>::fromList(list);
+
+ // test it worked ok
+ QCOMPARE(myvec, QVector<QString>() << "aaa" << "bbb" << "ninjas" << "pirates");
+ QCOMPARE(list, QList<QString>() << "aaa" << "bbb" << "ninjas" << "pirates");
+}
+
+void tst_QVector::fromStdVector() const
+{
+ // stl = :(
+ std::vector<QString> svec;
+ svec.push_back(QLatin1String("aaa"));
+ svec.push_back(QLatin1String("bbb"));
+ svec.push_back(QLatin1String("ninjas"));
+ svec.push_back(QLatin1String("pirates"));
+ QVector<QString> myvec = QVector<QString>::fromStdVector(svec);
+
+ // test it converts ok
+ QCOMPARE(myvec, QVector<QString>() << "aaa" << "bbb" << "ninjas" << "pirates");
+}
+
+void tst_QVector::indexOf() const
+{
+ QVector<QString> myvec;
+ myvec << "A" << "B" << "C" << "B" << "A";
+
+ QVERIFY(myvec.indexOf("B") == 1);
+ QVERIFY(myvec.indexOf("B", 1) == 1);
+ QVERIFY(myvec.indexOf("B", 2) == 3);
+ QVERIFY(myvec.indexOf("X") == -1);
+ QVERIFY(myvec.indexOf("X", 2) == -1);
+
+ // add an X
+ myvec << "X";
+ QVERIFY(myvec.indexOf("X") == 5);
+ QVERIFY(myvec.indexOf("X", 5) == 5);
+ QVERIFY(myvec.indexOf("X", 6) == -1);
+
+ // remove first A
+ myvec.remove(0);
+ QVERIFY(myvec.indexOf("A") == 3);
+ QVERIFY(myvec.indexOf("A", 3) == 3);
+ QVERIFY(myvec.indexOf("A", 4) == -1);
+}
+
+void tst_QVector::insert() const
+{
+ QVector<QString> myvec;
+ myvec << "A" << "B" << "C";
+
+ // first position
+ QCOMPARE(myvec.at(0), QLatin1String("A"));
+ myvec.insert(0, QLatin1String("X"));
+ QCOMPARE(myvec.at(0), QLatin1String("X"));
+ QCOMPARE(myvec.at(1), QLatin1String("A"));
+
+ // middle
+ myvec.insert(1, QLatin1String("Z"));
+ QCOMPARE(myvec.at(0), QLatin1String("X"));
+ QCOMPARE(myvec.at(1), QLatin1String("Z"));
+ QCOMPARE(myvec.at(2), QLatin1String("A"));
+
+ // end
+ myvec.insert(5, QLatin1String("T"));
+ QCOMPARE(myvec.at(5), QLatin1String("T"));
+ QCOMPARE(myvec.at(4), QLatin1String("C"));
+
+ // insert a lot of garbage in the middle
+ myvec.insert(2, 2, QLatin1String("infinity"));
+ QCOMPARE(myvec, QVector<QString>() << "X" << "Z" << "infinity" << "infinity"
+ << "A" << "B" << "C" << "T");
+}
+
+void tst_QVector::isEmpty() const
+{
+ QVector<QString> myvec;
+
+ // starts ok
+ QVERIFY(myvec.isEmpty());
+
+ // not empty now
+ myvec.append(QLatin1String("hello there"));
+ QVERIFY(!myvec.isEmpty());
+
+ // empty again
+ myvec.remove(0);
+ QVERIFY(myvec.isEmpty());
+}
+
+void tst_QVector::last() const
+{
+ QVector<QString> myvec;
+ myvec << "A" << "B" << "C";
+
+ // test starts ok
+ QCOMPARE(myvec.last(), QLatin1String("C"));
+
+ // test it changes ok
+ myvec.append(QLatin1String("X"));
+ QCOMPARE(myvec.last(), QLatin1String("X"));
+
+ // and remove again
+ myvec.remove(3);
+ QCOMPARE(myvec.last(), QLatin1String("C"));
+}
+
+void tst_QVector::lastIndexOf() const
+{
+ QVector<QString> myvec;
+ myvec << "A" << "B" << "C" << "B" << "A";
+
+ QVERIFY(myvec.lastIndexOf("B") == 3);
+ QVERIFY(myvec.lastIndexOf("B", 2) == 1);
+ QVERIFY(myvec.lastIndexOf("X") == -1);
+ QVERIFY(myvec.lastIndexOf("X", 2) == -1);
+
+ // add an X
+ myvec << "X";
+ QVERIFY(myvec.lastIndexOf("X") == 5);
+ QVERIFY(myvec.lastIndexOf("X", 5) == 5);
+ QVERIFY(myvec.lastIndexOf("X", 3) == -1);
+
+ // remove first A
+ myvec.remove(0);
+ QVERIFY(myvec.lastIndexOf("A") == 3);
+ QVERIFY(myvec.lastIndexOf("A", 3) == 3);
+ QVERIFY(myvec.lastIndexOf("A", 2) == -1);
+}
+
+void tst_QVector::mid() const
+{
+ QVector<QString> list;
+ list << "foo" << "bar" << "baz" << "bak" << "buck" << "hello" << "kitty";
+
+ QCOMPARE(list.mid(3, 3), QVector<QString>() << "bak" << "buck" << "hello");
+ QCOMPARE(list.mid(4), QVector<QString>() << "buck" << "hello" << "kitty");
+}
+
+void tst_QVector::prepend() const
+{
+ QVector<QString> myvec;
+ myvec << "A" << "B" << "C";
+
+ // starts ok
+ QVERIFY(myvec.size() == 3);
+ QCOMPARE(myvec.at(0), QLatin1String("A"));
+
+ // add something
+ myvec.prepend(QLatin1String("X"));
+ QCOMPARE(myvec.at(0), QLatin1String("X"));
+ QCOMPARE(myvec.at(1), QLatin1String("A"));
+ QVERIFY(myvec.size() == 4);
+
+ // something else
+ myvec.prepend(QLatin1String("Z"));
+ QCOMPARE(myvec.at(0), QLatin1String("Z"));
+ QCOMPARE(myvec.at(1), QLatin1String("X"));
+ QCOMPARE(myvec.at(2), QLatin1String("A"));
+ QVERIFY(myvec.size() == 5);
+
+ // clear and append to an empty vector
+ myvec.clear();
+ QVERIFY(myvec.size() == 0);
+ myvec.prepend(QLatin1String("ninjas"));
+ QVERIFY(myvec.size() == 1);
+ QCOMPARE(myvec.at(0), QLatin1String("ninjas"));
+}
+
+void tst_QVector::remove() const
+{
+ QVector<QString> myvec;
+ myvec << "A" << "B" << "C";
+
+ // remove middle
+ myvec.remove(1);
+ QCOMPARE(myvec, QVector<QString>() << "A" << "C");
+
+ // remove rest
+ myvec.remove(0, 2);
+ QCOMPARE(myvec, QVector<QString>());
+}
+
+// ::reserve() is really hard to think of tests for, so not doing it.
+// ::resize() is tested in ::capacity().
+
+void tst_QVector::size() const
+{
+ // total size
+ {
+ // zero size
+ QVector<int> myvec;
+ QVERIFY(myvec.size() == 0);
+
+ // grow
+ myvec.append(42);
+ QVERIFY(myvec.size() == 1);
+ myvec.append(42);
+ QVERIFY(myvec.size() == 2);
+
+ // shrink
+ myvec.remove(0);
+ QVERIFY(myvec.size() == 1);
+ myvec.remove(0);
+ QVERIFY(myvec.size() == 0);
+ }
+}
+
+// ::squeeze() is tested in ::capacity().
+
+void tst_QVector::startsWith() const
+{
+ QVector<int> myvec;
+
+ // empty vector
+ QVERIFY(!myvec.startsWith(1));
+
+ // add the one, should work
+ myvec.prepend(1);
+ QVERIFY(myvec.startsWith(1));
+
+ // add something else, fails now
+ myvec.prepend(3);
+ QVERIFY(!myvec.startsWith(1));
+
+ // remove it again :)
+ myvec.remove(0);
+ QVERIFY(myvec.startsWith(1));
+}
+
+void tst_QVector::toList() const
+{
+ QVector<QString> myvec;
+ myvec << "A" << "B" << "C";
+
+ // make sure it converts and doesn't modify the original vector
+ QCOMPARE(myvec.toList(), QList<QString>() << "A" << "B" << "C");
+ QCOMPARE(myvec, QVector<QString>() << "A" << "B" << "C");
+}
+
+void tst_QVector::toStdVector() const
+{
+ QVector<QString> myvec;
+ myvec << "A" << "B" << "C";
+
+ std::vector<QString> svec = myvec.toStdVector();
+ QCOMPARE(svec.at(0), QLatin1String("A"));
+ QCOMPARE(svec.at(1), QLatin1String("B"));
+ QCOMPARE(svec.at(2), QLatin1String("C"));
+
+ QCOMPARE(myvec, QVector<QString>() << "A" << "B" << "C");
+}
+
+void tst_QVector::value() const
+{
+ QVector<QString> myvec;
+ myvec << "A" << "B" << "C";
+
+ // valid calls
+ QCOMPARE(myvec.value(0), QLatin1String("A"));
+ QCOMPARE(myvec.value(1), QLatin1String("B"));
+ QCOMPARE(myvec.value(2), QLatin1String("C"));
+
+ // default calls
+ QCOMPARE(myvec.value(-1), QString());
+ QCOMPARE(myvec.value(3), QString());
+
+ // test calls with a provided default, valid calls
+ QCOMPARE(myvec.value(0, QLatin1String("default")), QLatin1String("A"));
+ QCOMPARE(myvec.value(1, QLatin1String("default")), QLatin1String("B"));
+ QCOMPARE(myvec.value(2, QLatin1String("default")), QLatin1String("C"));
+
+ // test calls with a provided default that will return the default
+ QCOMPARE(myvec.value(-1, QLatin1String("default")), QLatin1String("default"));
+ QCOMPARE(myvec.value(3, QLatin1String("default")), QLatin1String("default"));
+}
+
+void tst_QVector::testOperators() const
+{
+ QVector<QString> myvec;
+ myvec << "A" << "B" << "C";
+ QVector<QString> myvectwo;
+ myvectwo << "D" << "E" << "F";
+ QVector<QString> combined;
+ combined << "A" << "B" << "C" << "D" << "E" << "F";
+
+ // !=
+ QVERIFY(myvec != myvectwo);
+
+ // +
+ QCOMPARE(myvec + myvectwo, combined);
+ QCOMPARE(myvec, QVector<QString>() << "A" << "B" << "C");
+ QCOMPARE(myvectwo, QVector<QString>() << "D" << "E" << "F");
+
+ // +=
+ myvec += myvectwo;
+ QCOMPARE(myvec, combined);
+
+ // ==
+ QVERIFY(myvec == combined);
+
+ // []
+ QCOMPARE(myvec[0], QLatin1String("A"));
+ QCOMPARE(myvec[1], QLatin1String("B"));
+ QCOMPARE(myvec[2], QLatin1String("C"));
+ QCOMPARE(myvec[3], QLatin1String("D"));
+ QCOMPARE(myvec[4], QLatin1String("E"));
+ QCOMPARE(myvec[5], QLatin1String("F"));
+}
+
+
int fooCtor;
int fooDtor;
diff --git a/tests/benchmarks/corelib/kernel/events/events.pro b/tests/benchmarks/corelib/kernel/events/events.pro
index 43a7131..d7d770a 100644
--- a/tests/benchmarks/corelib/kernel/events/events.pro
+++ b/tests/benchmarks/corelib/kernel/events/events.pro
@@ -5,3 +5,4 @@ DEPENDPATH += .
INCLUDEPATH += .
# Input
SOURCES += main.cpp
+QT -= gui
diff --git a/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro b/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro
index 9c6b16b..5ecb94c 100644
--- a/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro
+++ b/tests/benchmarks/corelib/kernel/qtimer_vs_qmetaobject/qtimer_vs_qmetaobject.pro
@@ -9,3 +9,4 @@ CONFIG += release
SOURCES += tst_qtimer_vs_qmetaobject.cpp
+QT -= gui
diff --git a/tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro b/tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro
index 654b7b6..e8014d6 100644
--- a/tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro
+++ b/tests/benchmarks/corelib/thread/qthreadstorage/qthreadstorage.pro
@@ -3,4 +3,4 @@ TEMPLATE = app
TARGET = tst_bench_qthreadstorage
SOURCES += tst_qthreadstorage.cpp
-
+QT -= gui
diff --git a/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro b/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro
index 3e3bf2b..0dcee4f 100644
--- a/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro
+++ b/tests/benchmarks/corelib/tools/containers-associative/containers-associative.pro
@@ -6,3 +6,4 @@ INCLUDEPATH += .
# Input
SOURCES += main.cpp
+QT -= gui
diff --git a/tests/benchmarks/corelib/tools/containers-associative/main.cpp b/tests/benchmarks/corelib/tools/containers-associative/main.cpp
index 4c6dae4..afb1ea5 100644
--- a/tests/benchmarks/corelib/tools/containers-associative/main.cpp
+++ b/tests/benchmarks/corelib/tools/containers-associative/main.cpp
@@ -38,7 +38,6 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-#include <QtGui>
#include <QString>
#include <qtest.h>
diff --git a/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro b/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro
index 4236b35..656510e 100644
--- a/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro
+++ b/tests/benchmarks/corelib/tools/containers-sequential/containers-sequential.pro
@@ -6,3 +6,4 @@ INCLUDEPATH += .
# Input
SOURCES += main.cpp
+QT -= gui