summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorn Potter <lorn.potter@nokia.com>2010-06-21 19:54:16 (GMT)
committerLorn Potter <lorn.potter@nokia.com>2010-06-21 19:54:16 (GMT)
commitc888f0212e6f1f2c09984527ae27d6a87e7e0d89 (patch)
tree0c96c3c15feead446bc488fcb64a475503ef99c7
parent066fe8ab70508af6310c49e6eb9cdd74962b6401 (diff)
parent02c83c2adf0513041d9a3866d4e589ad79d61bda (diff)
downloadQt-c888f0212e6f1f2c09984527ae27d6a87e7e0d89.zip
Qt-c888f0212e6f1f2c09984527ae27d6a87e7e0d89.tar.gz
Qt-c888f0212e6f1f2c09984527ae27d6a87e7e0d89.tar.bz2
Merge branch '4.7' of git://gitorious.org/qt/qt into 4.7
-rwxr-xr-xbin/createpackage.pl33
-rwxr-xr-xbin/patch_capabilities.pl3
-rw-r--r--demos/declarative/samegame/samegame.qml4
-rw-r--r--demos/declarative/snake/content/Link.qml2
-rw-r--r--demos/qtdemo/qmlShell.qml11
-rw-r--r--dist/changes-4.7.06
-rw-r--r--doc/src/declarative/extending.qdoc3
-rw-r--r--doc/src/declarative/pics/ListViewSections.pngbin7596 -> 5491 bytes
-rw-r--r--doc/src/declarative/qdeclarativeperformance.qdoc12
-rw-r--r--doc/src/declarative/qtbinding.qdoc5
-rw-r--r--doc/src/examples/qml-examples.qdoc2
-rw-r--r--doc/src/platforms/symbian-introduction.qdoc2
-rw-r--r--examples/declarative/modelviews/listview/PetsModel.qml3
-rw-r--r--examples/declarative/modelviews/listview/RecipesModel.qml1
-rw-r--r--examples/declarative/modelviews/listview/content/PressAndHoldButton.qml11
-rw-r--r--examples/declarative/modelviews/listview/dynamiclist.qml2
-rw-r--r--examples/declarative/modelviews/listview/expandingdelegates.qml4
-rw-r--r--examples/declarative/modelviews/listview/highlight.qml4
-rw-r--r--examples/declarative/modelviews/listview/highlightranges.qml20
-rw-r--r--examples/declarative/modelviews/listview/sections.qml3
-rw-r--r--examples/declarative/modelviews/parallax/parallax.qml1
-rw-r--r--mkspecs/features/sis_targets.prf25
-rw-r--r--qmake/generators/win32/msbuild_objectmodel.cpp1
-rw-r--r--qmake/generators/win32/msvc_objectmodel.cpp7
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog17
-rw-r--r--src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp18
-rw-r--r--src/3rdparty/javascriptcore/VERSION4
-rw-r--r--src/3rdparty/phonon/ds9/videorenderer_evr.cpp16
-rw-r--r--src/3rdparty/webkit/.tag2
-rw-r--r--src/3rdparty/webkit/ChangeLog13
-rw-r--r--src/3rdparty/webkit/JavaScriptCore/ChangeLog13
-rw-r--r--src/3rdparty/webkit/VERSION2
-rw-r--r--src/3rdparty/webkit/WebCore/ChangeLog201
-rw-r--r--src/3rdparty/webkit/WebCore/page/FocusController.cpp176
-rw-r--r--src/3rdparty/webkit/WebCore/page/FrameView.cpp54
-rw-r--r--src/3rdparty/webkit/WebCore/page/FrameView.h14
-rw-r--r--src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp25
-rw-r--r--src/3rdparty/webkit/WebCore/page/SpatialNavigation.h7
-rw-r--r--src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp18
-rw-r--r--src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp23
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp45
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp7
-rw-r--r--src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h3
-rw-r--r--src/3rdparty/webkit/WebKit/qt/ChangeLog37
-rw-r--r--src/corelib/io/qiodevice.cpp21
-rw-r--r--src/corelib/io/qiodevice_p.h9
-rw-r--r--src/corelib/kernel/qabstracteventdispatcher.cpp24
-rw-r--r--src/declarative/graphicsitems/qdeclarativeborderimage.cpp5
-rw-r--r--src/declarative/graphicsitems/qdeclarativeborderimage_p.h1
-rw-r--r--src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h11
-rw-r--r--src/declarative/graphicsitems/qdeclarativeflickable.cpp22
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitem.cpp9
-rw-r--r--src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp16
-rw-r--r--src/declarative/graphicsitems/qdeclarativelistview.cpp37
-rw-r--r--src/declarative/graphicsitems/qdeclarativemousearea.cpp12
-rw-r--r--src/declarative/graphicsitems/qdeclarativepositioners.cpp8
-rw-r--r--src/declarative/graphicsitems/qdeclarativerepeater.cpp13
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp100
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p.h2
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p_p.h1
-rw-r--r--src/declarative/qml/qdeclarativecompiledbindings.cpp2
-rw-r--r--src/declarative/qml/qdeclarativecomponent.cpp25
-rw-r--r--src/declarative/qml/qdeclarativeengine.cpp11
-rw-r--r--src/declarative/qml/qdeclarativemetatype.cpp19
-rw-r--r--src/declarative/qml/qdeclarativemetatype_p.h2
-rw-r--r--src/declarative/qml/qdeclarativeprivate.h4
-rw-r--r--src/declarative/util/qdeclarativeanimation.cpp24
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp71
-rw-r--r--src/gui/graphicsview/qgraphicsgridlayout.cpp12
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp3
-rw-r--r--src/gui/graphicsview/qgraphicslinearlayout.cpp2
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp3
-rw-r--r--src/gui/graphicsview/qgridlayoutengine_p.h4
-rw-r--r--src/gui/image/qimage.cpp274
-rw-r--r--src/gui/image/qimage_p.h3
-rw-r--r--src/gui/image/qpixmap_raster.cpp201
-rw-r--r--src/gui/image/qpixmap_raster_p.h3
-rw-r--r--src/gui/image/qpixmapdata.cpp2
-rw-r--r--src/gui/itemviews/qabstractitemdelegate.cpp10
-rw-r--r--src/gui/painting/qoutlinemapper.cpp12
-rw-r--r--src/gui/painting/qoutlinemapper_p.h4
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp11
-rw-r--r--src/gui/painting/qpaintengineex.cpp4
-rw-r--r--src/gui/painting/qpainter.cpp2
-rw-r--r--src/gui/styles/qcleanlooksstyle.cpp2
-rw-r--r--src/gui/text/qfontdatabase.cpp13
-rw-r--r--src/gui/text/qfontengine_mac.mm3
-rw-r--r--src/plugins/imageformats/gif/qgifhandler.cpp14
-rw-r--r--src/script/api/qscriptengine.cpp30
-rw-r--r--src/script/api/qscriptengine_p.h6
-rw-r--r--src/script/api/qscriptvalue.cpp4
-rw-r--r--tests/auto/declarative/qdeclarativeitem/data/childrenRectBug2.qml53
-rw-r--r--tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp27
-rw-r--r--tests/auto/declarative/qdeclarativeqt/data/createComponent_lib.js7
-rw-r--r--tests/auto/declarative/qdeclarativeqt/data/createComponent_lib.qml10
-rw-r--r--tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp14
-rw-r--r--tests/auto/declarative/qdeclarativerepeater/data/repeater2.qml5
-rw-r--r--tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp44
-rw-r--r--tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp1
-rw-r--r--tests/auto/declarative/qdeclarativeworkerscript/data/BaseWorker.qml2
-rw-r--r--tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp6
-rw-r--r--tests/auto/declarative/qmlvisual/qdeclarativetextinput/LineEdit.qml9
-rw-r--r--tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp86
-rw-r--r--tests/auto/qpixmap/loadFromData/designer_argb32.pngbin0 -> 4189 bytes
-rw-r--r--tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.gifbin0 -> 3317 bytes
-rw-r--r--tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.pngbin0 -> 2431 bytes
-rw-r--r--tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.gifbin0 -> 2086 bytes
-rw-r--r--tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.pngbin0 -> 1405 bytes
-rw-r--r--tests/auto/qpixmap/loadFromData/designer_rgb32.jpgbin0 -> 11810 bytes
-rw-r--r--tests/auto/qpixmap/loadFromData/designer_rgb32.pngbin0 -> 4282 bytes
-rw-r--r--tests/auto/qpixmap/tst_qpixmap.cpp37
-rw-r--r--tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp140
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.cpp89
-rw-r--r--tests/auto/qscriptvalue/tst_qscriptvalue.h2
-rw-r--r--tools/assistant/tools/assistant/helpviewer_qwv.cpp23
-rw-r--r--tools/assistant/tools/assistant/helpviewer_qwv.h3
-rw-r--r--tools/qdoc3/ditaxmlgenerator.cpp227
-rw-r--r--tools/qdoc3/ditaxmlgenerator.h22
-rw-r--r--tools/qdoc3/node.cpp14
-rw-r--r--tools/qdoc3/node.h7
-rw-r--r--tools/qml/deviceorientation_maemo.cpp123
-rw-r--r--tools/qml/main.cpp7
-rw-r--r--tools/qml/qml.pri1
123 files changed, 2342 insertions, 548 deletions
diff --git a/bin/createpackage.pl b/bin/createpackage.pl
index 939c38e..8b787cb 100755
--- a/bin/createpackage.pl
+++ b/bin/createpackage.pl
@@ -78,6 +78,7 @@ Where supported options are as follows:
as a comments. Also empty lines are ignored. The paths in
<file> can be absolute or relative to <file>.
[-u|unsigned] = Preserves the unsigned package.
+ [-o|only-unsigned] = Creates only unsigned package.
[-s|stub] = Generates stub sis for ROM.
[-n|sisname <name>] = Specifies the final sis name.
Where parameters are as follows:
@@ -121,11 +122,13 @@ my $certfile = "";
my $preserveUnsigned = "";
my $stub = "";
my $signed_sis_name = "";
+my $onlyUnsigned = "";
unless (GetOptions('i|install' => \$install,
'p|preprocess' => \$preprocessonly,
'c|certfile=s' => \$certfile,
'u|unsigned' => \$preserveUnsigned,
+ 'o|only-unsigned' => \$onlyUnsigned,
's|stub' => \$stub,
'n|sisname=s' => \$signed_sis_name,)) {
Usage();
@@ -292,7 +295,10 @@ if($stub) {
# Create stub SIS.
system ("makesis -s $pkgoutput $stub_sis_name");
} else {
- if ($certtext eq "Self Signed" && !@certificates && $templatepkg !~ m/_installer\.pkg$/i) {
+ if ($certtext eq "Self Signed"
+ && !@certificates
+ && $templatepkg !~ m/_installer\.pkg$/i
+ && !$onlyUnsigned) {
print("Auto-patching capabilities for self signed package.\n");
system ("patch_capabilities $pkgoutput");
}
@@ -302,6 +308,25 @@ if($stub) {
system ("makesis $pkgoutput $unsigned_sis_name") and die ("makesis failed");
print("\n");
+ my $targetInsert = "";
+ if ($targetplatform ne "-") {
+ $targetInsert = " for $targetplatform";
+ }
+
+ if ($onlyUnsigned) {
+ stat($unsigned_sis_name);
+ if( -e _ ) {
+ print ("Successfully created unsigned package ${unsigned_sis_name}${targetInsert}!\n");
+ } else {
+ print ("\nUnsigned package creation failed!\n");
+ }
+
+ if (!$preservePkgOutput) {
+ unlink $pkgoutput;
+ }
+ exit;
+ }
+
# Sign SIS with certificate info given as an argument.
my $relcert = File::Spec->abs2rel($certificate);
my $relkey = File::Spec->abs2rel($key);
@@ -311,11 +336,7 @@ if($stub) {
# Check if creating signed SIS Succeeded
stat($signed_sis_name);
if( -e _ ) {
- my $targetInsert = "";
- if ($targetplatform ne "-") {
- $targetInsert = "for $targetplatform ";
- }
- print ("Successfully created $signed_sis_name ${targetInsert}using certificate: $certtext!\n");
+ print ("Successfully created signed package ${signed_sis_name}${targetInsert} using certificate: $certtext!\n");
# Sign with additional certificates & keys
for my $row ( @certificates ) {
diff --git a/bin/patch_capabilities.pl b/bin/patch_capabilities.pl
index 9741bc3..501939a 100755
--- a/bin/patch_capabilities.pl
+++ b/bin/patch_capabilities.pl
@@ -269,7 +269,8 @@ if (@ARGV)
}
print ("\n");
- print ("NOTE: A patched package should not be used for distribution!\n");
+ print ("NOTE: A patched package may not work as expected due to reduced capabilities.\n");
+ print (" Therefore it should not be used for any kind of Symbian signing or distribution!\n");
print ("\n");
}
}
diff --git a/demos/declarative/samegame/samegame.qml b/demos/declarative/samegame/samegame.qml
index 9a721da..10bf79f 100644
--- a/demos/declarative/samegame/samegame.qml
+++ b/demos/declarative/samegame/samegame.qml
@@ -46,6 +46,7 @@ import "SamegameCore/samegame.js" as Logic
Rectangle {
id: screen
width: 490; height: 720
+ property bool inAnotherDemo: false //Samegame often is just plonked straight into other demos
SystemPalette { id: activePalette }
@@ -115,6 +116,8 @@ Rectangle {
id: nameInputText
anchors { verticalCenter: parent.verticalCenter; left: dialogText.right }
focus: false
+ autoScroll: false
+ maximumLength: 24
onTextChanged: {
var newWidth = nameInputText.width + dialogText.width + 40;
if ( (newWidth > nameInputDialog.width && newWidth < screen.width)
@@ -141,6 +144,7 @@ Rectangle {
}
Button {
+ visible: !inAnotherDemo
text: "Quit"
anchors { left: newGameButton.right; leftMargin: 3; verticalCenter: parent.verticalCenter }
onClicked: Qt.quit();
diff --git a/demos/declarative/snake/content/Link.qml b/demos/declarative/snake/content/Link.qml
index 9aa6006..f4d7165 100644
--- a/demos/declarative/snake/content/Link.qml
+++ b/demos/declarative/snake/content/Link.qml
@@ -73,12 +73,14 @@ Item { id:link
}
}
+ /*
transform: Rotation {
id: actualImageRotation
origin.x: width/2; origin.y: height/2;
angle: rotation * 90
Behavior on angle { NumberAnimation { duration: spawned ? 200 : 0} }
}
+ */
}
Image {
diff --git a/demos/qtdemo/qmlShell.qml b/demos/qtdemo/qmlShell.qml
index b1ee79a..5c5f96c 100644
--- a/demos/qtdemo/qmlShell.qml
+++ b/demos/qtdemo/qmlShell.qml
@@ -73,12 +73,17 @@ Item {
clip: true
source: qmlFile
anchors.centerIn: parent
- onStatusChanged: if(status == Loader.Ready) {
+ onStatusChanged:{
+ if(status == Loader.Null) {
+ loader.focus = false;//fixes QTBUG11411, probably because the focusScope needs to gain focus to focus the right child
+ }else if(status == Loader.Ready) {
if(loader.item.width > 640)
loader.item.width = 640;
if(loader.item.height > 480)
loader.item.height = 480;
- }
+ if(loader.item.inAnotherDemo != undefined)
+ loader.item.inAnotherDemo = true;
+ }}
}
Rectangle{ id: frame
@@ -139,7 +144,7 @@ Item {
MouseArea{
z: 8
enabled: main.show
- hoverEnabled: true //To steal focus from the buttons
+ hoverEnabled: main.show //To steal focus from the buttons
anchors.fill: parent
onClicked: main.show=false;
}
diff --git a/dist/changes-4.7.0 b/dist/changes-4.7.0
index 95cff56..c19bf15 100644
--- a/dist/changes-4.7.0
+++ b/dist/changes-4.7.0
@@ -377,3 +377,9 @@ QtCore:
ABIs, but it also allowed for unaligned access. Qt never generates
or uses unaligned access and the new EABI aligns as expected, so
the flag was removed.
+
+QtNetwork:
+ - Qt does no longer provide its own CA bundle, but uses system APIs for
+ retrieving the default system certificates. On Symbian,
+ QSslSocket::systemCaCertificates() provides an empty list of
+ certificates.
diff --git a/doc/src/declarative/extending.qdoc b/doc/src/declarative/extending.qdoc
index 173fb6d..03c0ec4 100644
--- a/doc/src/declarative/extending.qdoc
+++ b/doc/src/declarative/extending.qdoc
@@ -425,6 +425,9 @@ value will not be accessible from script.
\l {Extending QML - Signal Support Example} shows the complete code used to
implement the onPartyStarted signal property.
+If you want to use signals from items not created in QML, you can access their
+signals with the \l {Connections} element.
+
\section1 Property Value Sources
\snippet examples/declarative/cppextensions/referenceexamples/valuesource/example.qml 0
diff --git a/doc/src/declarative/pics/ListViewSections.png b/doc/src/declarative/pics/ListViewSections.png
index 9270126..4e8f076 100644
--- a/doc/src/declarative/pics/ListViewSections.png
+++ b/doc/src/declarative/pics/ListViewSections.png
Binary files differ
diff --git a/doc/src/declarative/qdeclarativeperformance.qdoc b/doc/src/declarative/qdeclarativeperformance.qdoc
index b535e4b..c866724 100644
--- a/doc/src/declarative/qdeclarativeperformance.qdoc
+++ b/doc/src/declarative/qdeclarativeperformance.qdoc
@@ -117,4 +117,16 @@ a Loader as needed.
\o Fast data access - ensure the data model is as fast as possible.
\endlist
+\section1 Image resources over composition
+
+If possible, provide a single image resource, rather than using composition
+of a number of elements. For example, a frame with a shadow could be created using
+a Rectangle placed over an Image providing the shadow. It is more efficient to
+provide an image that includes the frame and the shadow.
+
+\section1 Limit JavaScript
+
+Avoid running JavaScript during animation. For example, running a complex
+JavaScript expression for each frame of an x property animation.
+
*/
diff --git a/doc/src/declarative/qtbinding.qdoc b/doc/src/declarative/qtbinding.qdoc
index 7d696d7..784c59a 100644
--- a/doc/src/declarative/qtbinding.qdoc
+++ b/doc/src/declarative/qtbinding.qdoc
@@ -269,5 +269,10 @@ For example:
\c [project/main.qml]
\snippet doc/src/snippets/declarative/qtbinding/resources/main.qml 0
+Note that the resource system cannot be accessed from QML directly. If the main QML file is
+loaded as a resource, all files specifed as relative paths in QML will also be loaded from
+the resource system. Using the resource system is completely transparent to the QML layer.
+This also means that if the main QML file is not loaded as a resource then files in the resource
+system cannot be accessed from QML.
*/
diff --git a/doc/src/examples/qml-examples.qdoc b/doc/src/examples/qml-examples.qdoc
index b6069f2..ee708a8 100644
--- a/doc/src/examples/qml-examples.qdoc
+++ b/doc/src/examples/qml-examples.qdoc
@@ -213,7 +213,7 @@
\title Models and Views: ListView
\example declarative/modelviews/listview
- This example shows how to use the ListView element.
+ These examples show how to use the ListView element.
*/
/*!
diff --git a/doc/src/platforms/symbian-introduction.qdoc b/doc/src/platforms/symbian-introduction.qdoc
index 6ffc568..316764b 100644
--- a/doc/src/platforms/symbian-introduction.qdoc
+++ b/doc/src/platforms/symbian-introduction.qdoc
@@ -127,6 +127,7 @@
\row \o \c run \o Run the application on the emulator.
\row \o \c runonphone \o Run the application on a device.
\row \o \c sis \o Create signed \c .sis file for project.
+ \row \o \c unsigned_sis \o Create unsigned \c .sis file for project.
\row \o \c installer_sis \o Create signed \l{Smart Installer}{smart installer}
\c .sis file for project.
Smart installer will attempt to download
@@ -193,6 +194,7 @@
\row \o -p \o Only preprocess the template \c .pkg file.
\row \o -c <file> \o Read certificate information from a file.
\row \o -u \o Preserves unsigned package.
+ \row \o -o \o Creates only unsigned package.
\row \o -s \o Generates stub sis for ROM.
\row \o -n <name> \o Specifies the final sis name.
\endtable
diff --git a/examples/declarative/modelviews/listview/PetsModel.qml b/examples/declarative/modelviews/listview/PetsModel.qml
index 70cdcdd..b77557d 100644
--- a/examples/declarative/modelviews/listview/PetsModel.qml
+++ b/examples/declarative/modelviews/listview/PetsModel.qml
@@ -40,10 +40,7 @@
import Qt 4.7
-// ListModel allows free form list models to be defined and populated.
-
ListModel {
- id: petsModel
ListElement {
name: "Polly"
type: "Parrot"
diff --git a/examples/declarative/modelviews/listview/RecipesModel.qml b/examples/declarative/modelviews/listview/RecipesModel.qml
index 03ab961..e6d829f 100644
--- a/examples/declarative/modelviews/listview/RecipesModel.qml
+++ b/examples/declarative/modelviews/listview/RecipesModel.qml
@@ -41,7 +41,6 @@
import Qt 4.7
ListModel {
- id: recipesModel
ListElement {
title: "Pancakes"
picture: "content/pics/pancakes.jpg"
diff --git a/examples/declarative/modelviews/listview/content/PressAndHoldButton.qml b/examples/declarative/modelviews/listview/content/PressAndHoldButton.qml
index 7c174e3..0d5a255 100644
--- a/examples/declarative/modelviews/listview/content/PressAndHoldButton.qml
+++ b/examples/declarative/modelviews/listview/content/PressAndHoldButton.qml
@@ -51,6 +51,11 @@ Image {
scale: pressed ? 0.9 : 1
+ function release() {
+ autoRepeatClicks.stop()
+ container.pressed = false
+ }
+
SequentialAnimation on pressed {
id: autoRepeatClicks
running: false
@@ -70,10 +75,8 @@ Image {
anchors.fill: parent
onPressed: autoRepeatClicks.start()
- onReleased: {
- autoRepeatClicks.stop()
- container.pressed = false
- }
+ onReleased: container.release()
+ onCanceled: container.release()
}
}
diff --git a/examples/declarative/modelviews/listview/dynamiclist.qml b/examples/declarative/modelviews/listview/dynamiclist.qml
index 0e290f5..12c331b 100644
--- a/examples/declarative/modelviews/listview/dynamiclist.qml
+++ b/examples/declarative/modelviews/listview/dynamiclist.qml
@@ -45,7 +45,7 @@ import "content"
Rectangle {
id: container
- width: 640; height: 480
+ width: 500; height: 400
color: "#343434"
// The model:
diff --git a/examples/declarative/modelviews/listview/expandingdelegates.qml b/examples/declarative/modelviews/listview/expandingdelegates.qml
index 94ea48f..24d6386 100644
--- a/examples/declarative/modelviews/listview/expandingdelegates.qml
+++ b/examples/declarative/modelviews/listview/expandingdelegates.qml
@@ -138,7 +138,8 @@ Rectangle {
id: flick
width: parent.width
anchors { top: methodTitle.bottom; bottom: parent.bottom }
- contentHeight: methodText.height; clip: true
+ contentHeight: methodText.height
+ clip: true
Text { id: methodText; text: method; wrapMode: Text.WordWrap; width: details.width }
}
@@ -197,6 +198,5 @@ Rectangle {
anchors.fill: parent
model: RecipesModel {}
delegate: recipeDelegate
- clip: true
}
}
diff --git a/examples/declarative/modelviews/listview/highlight.qml b/examples/declarative/modelviews/listview/highlight.qml
index 5748974..9f43409 100644
--- a/examples/declarative/modelviews/listview/highlight.qml
+++ b/examples/declarative/modelviews/listview/highlight.qml
@@ -38,6 +38,10 @@
**
****************************************************************************/
+// This example shows how to create your own highlight delegate for a ListView
+// that uses a SpringFollow animation to provide custom movement when the
+// highlight bar is moved between items.
+
import Qt 4.7
Rectangle {
diff --git a/examples/declarative/modelviews/listview/highlightranges.qml b/examples/declarative/modelviews/listview/highlightranges.qml
index 162d8b7..f0d7f75 100644
--- a/examples/declarative/modelviews/listview/highlightranges.qml
+++ b/examples/declarative/modelviews/listview/highlightranges.qml
@@ -43,31 +43,31 @@ import Qt 4.7
Rectangle {
width: 600; height: 300
- // Show the model in three lists, with different highlight ranges.
- // preferredHighlightBegin and preferredHighlightEnd set the
- // range in which to attempt to maintain the highlight.
+ // This example shows the same model in three different ListView items,
+ // with different highlight ranges. The highlight ranges are set by the
+ // preferredHighlightBegin and preferredHighlightEnd properties in ListView.
//
- // The second and third ListView set their currentIndex to be the
- // same as the first, and the first ListView is given keyboard focus.
+ // The second and third ListViews set their currentIndex to be the
+ // same as the first. The first ListView is given keyboard focus.
//
- // The first list does not set a highlight range, so its currentItem
+ // The first ListView does not set a highlight range, so its currentItem
// can move freely within the visible area. If it moves outside the
// visible area, the view is automatically scrolled to keep the current
// item visible.
//
- // The second list sets a highlight range which attempts to keep the
+ // The second ListView sets a highlight range which attempts to keep the
// current item within the the bounds of the range. However,
// items will not scroll beyond the beginning or end of the view,
// forcing the highlight to move outside the range at the ends.
//
- // The third list sets the highlightRangeMode to StrictlyEnforceRange
+ // The third ListView sets the highlightRangeMode to StrictlyEnforceRange
// and sets a range smaller than the height of an item. This
// forces the current item to change when the view is flicked,
// since the highlight is unable to move.
//
// Note that the first ListView sets its currentIndex to be equal to
- // the third ListView's currentIndex. By flicking List3 with
- // the mouse, the current index of List1 will be changed.
+ // the third ListView's currentIndex. By flicking the third ListView with
+ // the mouse, the current index of the first ListView will be changed.
ListView {
id: list1
diff --git a/examples/declarative/modelviews/listview/sections.qml b/examples/declarative/modelviews/listview/sections.qml
index 8c038a0..8e0a49f 100644
--- a/examples/declarative/modelviews/listview/sections.qml
+++ b/examples/declarative/modelviews/listview/sections.qml
@@ -38,6 +38,9 @@
**
****************************************************************************/
+// This example shows how a ListView can be separated into sections using
+// the ListView.section attached property.
+
import Qt 4.7
//! [0]
diff --git a/examples/declarative/modelviews/parallax/parallax.qml b/examples/declarative/modelviews/parallax/parallax.qml
index ec52a24..3b5c70a 100644
--- a/examples/declarative/modelviews/parallax/parallax.qml
+++ b/examples/declarative/modelviews/parallax/parallax.qml
@@ -73,6 +73,7 @@ Rectangle {
width: 300; height: 400
clip: true;
source: "../../../../demos/declarative/samegame/samegame.qml"
+ Component.onCompleted: item.inAnotherDemo = true;
}
}
diff --git a/mkspecs/features/sis_targets.prf b/mkspecs/features/sis_targets.prf
index b149a22..37b758b 100644
--- a/mkspecs/features/sis_targets.prf
+++ b/mkspecs/features/sis_targets.prf
@@ -32,6 +32,24 @@ equals(GENERATE_SIS_TARGETS, true) {
ok_sis_target.commands = createpackage.bat $(QT_SIS_OPTIONS) $$basename(TARGET)_template.pkg \
$(QT_SIS_TARGET) $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)
+ unsigned_sis_target.target = unsigned_sis
+ unsigned_sis_target.commands = $(if $(wildcard $$basename(TARGET)_template.pkg), \
+ $(if $(wildcard $$make_cache_name), \
+ $(MAKE) -f $(MAKEFILE) ok_unsigned_sis MAKEFILES=$$make_cache_name \
+ , \
+ $(if $(QT_SIS_TARGET), \
+ $(MAKE) -f $(MAKEFILE) ok_unsigned_sis \
+ , \
+ $(MAKE) -f $(MAKEFILE) fail_sis_nocache \
+ ) \
+ ) \
+ , \
+ $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \
+ )
+
+ ok_unsigned_sis_target.target = ok_unsigned_sis
+ ok_unsigned_sis_target.commands = createpackage.bat $(QT_SIS_OPTIONS) -o $$basename(TARGET)_template.pkg $(QT_SIS_TARGET)
+
target_sis_target.target = $${sis_destdir}$${TARGET}.sis
target_sis_target.commands = $(MAKE) -f $(MAKEFILE) sis
@@ -74,6 +92,8 @@ equals(GENERATE_SIS_TARGETS, true) {
QMAKE_EXTRA_TARGETS += sis_target \
ok_sis_target \
+ unsigned_sis_target \
+ ok_unsigned_sis_target \
target_sis_target \
installer_sis_target \
ok_installer_sis_target \
@@ -114,6 +134,10 @@ equals(GENERATE_SIS_TARGETS, true) {
- $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE)
sis_target.depends = first
+ unsigned_sis_target.target = unsigned_sis
+ unsigned_sis_target.commands = createpackage $(QT_SIS_OPTIONS) -o $$basename(TARGET)_template.pkg
+ unsigned_sis_target.depends = first
+
target_sis_target.target = $${sis_destdir}$${TARGET}.sis
target_sis_target.commands = $(MAKE) -f $(MAKEFILE) sis
@@ -128,6 +152,7 @@ equals(GENERATE_SIS_TARGETS, true) {
}
QMAKE_EXTRA_TARGETS += sis_target \
+ unsigned_sis_target \
target_sis_target \
installer_sis_target
}
diff --git a/qmake/generators/win32/msbuild_objectmodel.cpp b/qmake/generators/win32/msbuild_objectmodel.cpp
index 75fc910..bf874b2 100644
--- a/qmake/generators/win32/msbuild_objectmodel.cpp
+++ b/qmake/generators/win32/msbuild_objectmodel.cpp
@@ -385,6 +385,7 @@ VCXCLCompilerTool::VCXCLCompilerTool()
DisableLanguageExtensions(unset),
EnableFiberSafeOptimizations(unset),
EnablePREfast(unset),
+ ExceptionHandling("false"),
ExpandAttributedSource(unset),
FloatingPointExceptions(unset),
ForceConformanceInForLoopScope(unset),
diff --git a/qmake/generators/win32/msvc_objectmodel.cpp b/qmake/generators/win32/msvc_objectmodel.cpp
index 1e060a0..e23e119 100644
--- a/qmake/generators/win32/msvc_objectmodel.cpp
+++ b/qmake/generators/win32/msvc_objectmodel.cpp
@@ -360,8 +360,11 @@ inline XmlOutput::xml_output xformUsePrecompiledHeaderForNET2005(pchOption whatP
inline XmlOutput::xml_output xformExceptionHandlingNET2005(exceptionHandling eh, DotNET compilerVersion)
{
- if (eh == ehDefault)
- return noxml();
+ if (eh == ehDefault) {
+ if (compilerVersion >= NET2005)
+ return attrE(_ExceptionHandling, ehNone);
+ return attrS(_ExceptionHandling, "false");
+ }
if (compilerVersion >= NET2005)
return attrE(_ExceptionHandling, eh);
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog b/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog
index fd6125f..b0873ab 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/ChangeLog
@@ -12,6 +12,23 @@
* wtf/Platform.h:
+2010-04-28 Simon Hausmann <simon.hausmann@nokia.com>, Kent Hansen <kent.hansen@nokia.com>
+
+ Reviewed by Darin Adler.
+
+ JSC's currentThreadStackBase is not reentrant on some platforms
+ https://bugs.webkit.org/show_bug.cgi?id=37195
+
+ This function needs to be reentrant to avoid memory corruption on platforms where
+ the implementation uses global variables.
+
+ This patch adds a mutex lock where necessary and makes the Symbian implementation
+ reentrant.
+
+ * runtime/Collector.cpp:
+ (JSC::currentThreadStackBaseMutex):
+ (JSC::currentThreadStackBase):
+
2010-04-14 Kent Hansen <kent.hansen@nokia.com>
Reviewed by Maciej Stachowiak.
diff --git a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
index 57f2a92..eafcc23 100644
--- a/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
+++ b/src/3rdparty/javascriptcore/JavaScriptCore/runtime/Collector.cpp
@@ -637,6 +637,8 @@ static inline void* currentThreadStackBase()
#elif OS(HPUX)
return hpux_get_stack_base();
#elif OS(QNX)
+ AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
+ MutexLocker locker(mutex);
return currentThreadStackBaseQNX();
#elif OS(SOLARIS)
stack_t s;
@@ -660,19 +662,17 @@ static inline void* currentThreadStackBase()
pthread_stackseg_np(thread, &stack);
return stack.ss_sp;
#elif OS(SYMBIAN)
- static void* stackBase = 0;
- if (stackBase == 0) {
- TThreadStackInfo info;
- RThread thread;
- thread.StackInfo(info);
- stackBase = (void*)info.iBase;
- }
- return (void*)stackBase;
+ TThreadStackInfo info;
+ RThread thread;
+ thread.StackInfo(info);
+ return (void*)info.iBase;
#elif OS(HAIKU)
thread_info threadInfo;
get_thread_info(find_thread(NULL), &threadInfo);
return threadInfo.stack_end;
#elif OS(UNIX)
+ AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
+ MutexLocker locker(mutex);
static void* stackBase = 0;
static size_t stackSize = 0;
static pthread_t stackThread;
@@ -695,6 +695,8 @@ static inline void* currentThreadStackBase()
}
return static_cast<char*>(stackBase) + stackSize;
#elif OS(WINCE)
+ AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
+ MutexLocker locker(mutex);
if (g_stackBase)
return g_stackBase;
else {
diff --git a/src/3rdparty/javascriptcore/VERSION b/src/3rdparty/javascriptcore/VERSION
index 1b5109a..daecc37 100644
--- a/src/3rdparty/javascriptcore/VERSION
+++ b/src/3rdparty/javascriptcore/VERSION
@@ -4,8 +4,8 @@ This is a snapshot of JavaScriptCore from
The commit imported was from the
- javascriptcore-snapshot-19052010 branch/tag
+ javascriptcore-snapshot-16062010 branch/tag
and has the sha1 checksum
- 8039ba79702d6516cf6841c9f15b324ec499bbf3
+ 8b2d3443afca194f8ac50a63151dc9d19a150582
diff --git a/src/3rdparty/phonon/ds9/videorenderer_evr.cpp b/src/3rdparty/phonon/ds9/videorenderer_evr.cpp
index d23d9ce..de3f46f 100644
--- a/src/3rdparty/phonon/ds9/videorenderer_evr.cpp
+++ b/src/3rdparty/phonon/ds9/videorenderer_evr.cpp
@@ -43,14 +43,12 @@ namespace Phonon
{
//normally we should use IID_IMFGetService but this introduces another dependency
//so here we simply define our own IId with the same value
+ ComPointer<T> ret;
ComPointer<IMFGetService> getService(filter, IID_IMFGetService);
- Q_ASSERT(getService);
- T *ptr = 0;
- HRESULT hr = getService->GetService(guidService, riid, reinterpret_cast<void **>(&ptr));
- if (!SUCCEEDED(hr) || ptr == 0)
- Q_ASSERT(!SUCCEEDED(hr) && ptr != 0);
- ComPointer<T> service(ptr);
- return service;
+ if (getService) {
+ getService->GetService(guidService, riid, reinterpret_cast<void**>(ret.pparam()));
+ }
+ return ret;
}
VideoRendererEVR::~VideoRendererEVR()
@@ -70,6 +68,10 @@ namespace Phonon
}
ComPointer<IMFVideoDisplayControl> filterControl = getService<IMFVideoDisplayControl>(m_filter, MR_VIDEO_RENDER_SERVICE, IID_IMFVideoDisplayControl);
+ if (!filterControl) {
+ m_filter = Filter(); //will release the interface
+ return;
+ }
filterControl->SetVideoWindow(reinterpret_cast<HWND>(target->winId()));
filterControl->SetAspectRatioMode(MFVideoARMode_None); // We're in control of the size
diff --git a/src/3rdparty/webkit/.tag b/src/3rdparty/webkit/.tag
index 07a02d7..f5b6af3 100644
--- a/src/3rdparty/webkit/.tag
+++ b/src/3rdparty/webkit/.tag
@@ -1 +1 @@
-40c2d6907ef75288b4f15e7fad334b9138acdbbf
+6623b5da196390748dc619461739f9cb84524736
diff --git a/src/3rdparty/webkit/ChangeLog b/src/3rdparty/webkit/ChangeLog
index c2862fd..51d08a0 100644
--- a/src/3rdparty/webkit/ChangeLog
+++ b/src/3rdparty/webkit/ChangeLog
@@ -1,3 +1,16 @@
+2010-06-17 Mark Brand <mabrand@mabrand.nl>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] use "win32-g++*" scope to match all MinGW makespecs
+
+ The scope "win32-g++" comes from the name of the makespec. However, it
+ is frequently used to check for MinGW. This works fine as long as
+ win32-g++ is the only makespec for MinGW. Now we need the wildcard
+ to cover "win32-g++-cross" as well.
+
+ * WebKit.pri:
+
2010-05-04 Laszlo Gombos <laszlo.1.gombos@nokia.com>
Unreviewed, build fix for Symbian.
diff --git a/src/3rdparty/webkit/JavaScriptCore/ChangeLog b/src/3rdparty/webkit/JavaScriptCore/ChangeLog
index d9b2987..adaf390 100644
--- a/src/3rdparty/webkit/JavaScriptCore/ChangeLog
+++ b/src/3rdparty/webkit/JavaScriptCore/ChangeLog
@@ -1,3 +1,16 @@
+2010-06-17 Mark Brand <mabrand@mabrand.nl>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] use "win32-g++*" scope to match all MinGW makespecs
+
+ The scope "win32-g++" comes from the name of the makespec. However, it
+ is frequently used to check for MinGW. This works fine as long as
+ win32-g++ is the only makespec for MinGW. Now we need the wildcard
+ to cover "win32-g++-cross" as well.
+
+ * JavaScriptCore.pro:
+
2010-06-07 Benjamin Poulain <benjamin.poulain@nokia.com>
Reviewed by Simon Hausmann.
diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION
index b648b94..1e7351f 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
- 40c2d6907ef75288b4f15e7fad334b9138acdbbf
+ 6623b5da196390748dc619461739f9cb84524736
diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog
index 6a7da30..c17a8aa 100644
--- a/src/3rdparty/webkit/WebCore/ChangeLog
+++ b/src/3rdparty/webkit/WebCore/ChangeLog
@@ -1,3 +1,204 @@
+2010-06-17 Mark Brand <mabrand@mabrand.nl>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] use "win32-g++*" scope to match all MinGW makespecs
+
+ The scope "win32-g++" comes from the name of the makespec. However, it
+ is frequently used to check for MinGW. This works fine as long as
+ win32-g++ is the only makespec for MinGW. Now we need the wildcard
+ to cover "win32-g++-cross" as well.
+
+ * WebCore.pro:
+
+2010-06-16 Antonio Gomes <tonikitoo@webkit.org>
+
+ Reviewed by Kenneth Christiansen.
+
+ Spatial Navigation: using offset{Left,Top} is not enough to get the proper inner frames position
+ https://bugs.webkit.org/show_bug.cgi?id=39439
+
+ As pointed out by Darin Adler in https://bugs.webkit.org/show_bug.cgi?id=18662#c20,
+ "It's not correct to use the offsetLeft and offsetTop of the frame owner element's renderer because
+ that's just the distance from the offsetParent, not the absolute position".
+
+ Patch fixes that behavior by now considering the offsetTop and offsetLeft the offsetParent recursively,
+ starting from the HtmlFrameOwnerElement. Previously, only calling offsetTop and offsetLeft works
+ because all tests were done in htmls where the {i}frame element was a directly a child of the body,
+ e.g. <html>...<body><iframe src=xxx>....<body></html>.
+
+ Test: fast/events/spatial-navigation/snav-iframe-recursive-offset-parent.html
+
+ * page/SpatialNavigation.cpp:
+ (WebCore::renderRectRelativeToRootDocument):
+
+2010-06-16 Antonio Gomes <tonikitoo@webkit.org>
+
+ Reviewed by Simon Fraser.
+
+ Spatial Navigation: refactor scrollInDirection to work with scrollable content
+ https://bugs.webkit.org/show_bug.cgi?id=39195
+
+ scrollInDirection now receives as parameter the node that the Spatial Navigation
+ found as the more appropriated to move focus to. If it is in a scrollable container
+ (e.g. <div> with clipped overflow content), it scrolls recursively starting from
+ the container, not the current focused node.
+
+ Test: fast/events/spatial-navigation/snav-only-clipped-overflow-content.html
+
+ * page/FocusController.cpp:
+ (WebCore::FocusController::advanceFocusDirectionally):
+ * page/SpatialNavigation.cpp:
+ (WebCore::scrollInDirection):
+ * page/SpatialNavigation.h:
+
+2010-05-28 Viatcheslav Ostapenko <ostapenko.viatcheslav@nokia.com>
+
+ Reviewed by Simon Hausmann, Antti Koivisto
+
+ Make repaint throttling parameters runtime configurable.
+ https://bugs.webkit.org/show_bug.cgi?id=38401
+
+ REPAINT_THROTTLING now chooses default values for throttling parameters.
+ Should be removed when applications start using runtime configuration.
+
+ * page/FrameView.cpp:
+ (WebCore::FrameView::reset):
+ (WebCore::FrameView::updateDeferredRepaintDelay):
+ (WebCore::FrameView::setRepaintThrottlingDeferredRepaintDelay):
+ (WebCore::FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading):
+ (WebCore::FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading):
+ (WebCore::FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading):
+ * page/FrameView.h:
+
+2010-06-16 Dawit Alemayehu <adawit@kde.org>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] QtWebKit crashes while initializing flash plugin 10.1.53.64.
+ https://bugs.webkit.org/show_bug.cgi?id=40567
+
+ Avoid preventable crashes by ensuring gtk_init() is called in the
+ flash viewer plugins before calling NP_Initialize.
+
+ * plugins/qt/PluginPackageQt.cpp:
+ (WebCore::PluginPackage::load):
+
+2010-04-21 Zoltan Herczeg <zherczeg@webkit.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ [Qt] startAnimation() is not needed to preceede nativeImageForCurrentFrame()
+ https://bugs.webkit.org/show_bug.cgi?id=37844
+
+ nativeImageForCurrentFrame() resets the m_decoder parameter under Qt,
+ which is required by startAnimation() to detect frame and repetition counts.
+ Hence, Image::drawTiled cannot start animations under Qt:
+ <html><body background="animated.gif"></body></html> does not work
+
+ * platform/graphics/qt/ImageDecoderQt.cpp:
+ (WebCore::ImageDecoderQt::internalHandleCurrentImage):
+
+2010-05-28 Peter Kasting <pkasting@google.com>
+
+ Reviewed by Darin Adler.
+
+ https://bugs.webkit.org/show_bug.cgi?id=39857
+ Make GIFs loop the correct number of times. Previously, everyone looped
+ one time too few for non-infinitely-looping GIFs.
+
+ Modified a Qt manual test to be correct and moved it to the general
+ manual test directory.
+
+ * manual-tests/animated-gif-looping.html: Copied from WebCore/manual-tests/qt/qt-gif-test.html.
+ * manual-tests/qt/qt-10loop-anim.gif: Removed.
+ * manual-tests/qt/qt-anim.gif: Removed.
+ * manual-tests/qt/qt-gif-test.html: Removed.
+ * manual-tests/qt/qt-noanim.gif: Removed.
+ * manual-tests/resources/animated-10x.gif: Copied from WebCore/manual-tests/qt/qt-10loop-anim.gif and modified.
+ * manual-tests/resources/animated-infinite.gif: Copied from WebCore/manual-tests/qt/qt-anim.gif.
+ * manual-tests/resources/non-animated.gif: Copied from WebCore/manual-tests/qt/qt-noanim.gif.
+ * platform/graphics/BitmapImage.cpp:
+ (WebCore::BitmapImage::internalAdvanceAnimation): For a loop count of n, show a total of n + 1 animation cycles.
+ * platform/graphics/ImageSource.h:
+ * platform/graphics/cg/ImageSourceCG.cpp:
+ (WebCore::ImageSource::repetitionCount):
+ * platform/graphics/qt/ImageDecoderQt.cpp:
+ (WebCore::ImageDecoderQt::repetitionCount): Remove translation code now that WebCore matches Qt's internal handling of the loop count. Qt itself may still have a bug here.
+ * platform/image-decoders/gif/GIFImageDecoder.cpp:
+ (WebCore::GIFImageDecoder::repetitionCount):
+ * platform/image-decoders/gif/GIFImageReader.cpp:
+ (GIFImageReader::read): Translate loop count 0 to "loop infinitely" (by restoring one piece of the Mozilla code we'd removed).
+
+2010-05-04 Tucker Jay <jay.tucker@nokia.com>
+
+ Reviewed by Holger Freyther.
+
+ Animated GIF images does not animate 10x as expected by default.
+ https://bugs.webkit.org/show_bug.cgi?id=36818
+
+ Added test case to existing manual test to test the
+ fixed functionality.
+
+ * manual-tests/qt/qt-10loop-anim.gif: Added.
+ * manual-tests/qt/qt-gif-test.html:
+ * platform/graphics/qt/ImageDecoderQt.cpp:
+ (WebCore::ImageDecoderQt::repetitionCount):
+
+2010-05-16 Antonio Gomes <tonikitoo@webkit.org>
+
+ Unreviewed naming fixes of local variables used in Spatial Navigation methods.
+
+ Summary:
+ * "candidate" renamed to "node";
+ * "currentFocusCandidate" renamed to "candidate"
+ * "closestFocusCandidate" renamed to "closest"
+
+ That way naming is more consistent in the various Spatial Navigation methods.
+
+ * page/FocusController.cpp:
+ (WebCore::FocusController::findFocusableNodeInDirection):
+ (WebCore::FocusController::deepFindFocusableNodeInDirection):
+
+2010-06-14 Antonio Gomes <tonikitoo@webkit.org>
+
+ Reviewed by Simon Fraser and Kenneth Christiansen.
+
+ Spatial Navigation: make it work with focusable elements in overflow content
+ https://bugs.webkit.org/show_bug.cgi?id=36463
+
+ This patch addresses the problem with Spatial Navigation. It currently does not
+ properly traverse scrollable contents, including scrollable div's. For this to work,
+ a new class member called scrollableEnclosingBox was introduced to FocusCandidate class which
+ keeps track of the current scrollable box Node wrapping a FocusCandidate.
+
+ To make use of enclosingScrollableBox of FocusCandidate, the DOM traversal routine
+ (FocusController::findNextFocusableInDirection) was changed as follows: when it
+ encounters a scrollable Node, each focusable node which is 'inner' keeps track of
+ the container reference. By the time a sibling of the scrollable Node is encountered,
+ there is no need to track this reference any more and the traversal algorithm continues
+ normally.
+
+ The common case is obviously that there is no scrollable container wrapping it.
+
+ updateFocusCandiditeIfCloser logic was also adapted to fit the need of the
+ newly introduced enclosingScrollableBox class member, getting simpler and more
+ easily maintainable.
+
+ Tests: fast/events/spatial-navigation/snav-div-scrollable-but-without-focusable-content.html
+ fast/events/spatial-navigation/snav-clipped-overflow-content.html
+
+ * page/FocusController.cpp:
+ (WebCore::updateFocusCandidateInSameContainer):
+ (WebCore::updateFocusCandidateIfCloser):
+ (WebCore::FocusController::findFocusableNodeInDirection):
+ (WebCore::FocusController::deepFindFocusableNodeInDirection):
+ * page/SpatialNavigation.cpp:
+ (WebCore::isScrollableContainerNode):
+ * page/SpatialNavigation.h:
+ (WebCore::FocusCandidate::FocusCandidate):
+ (WebCore::FocusCandidate::isInScrollableContainer):
+
2010-06-15 Jocelyn Turcotte <jocelyn.turcotte@nokia.com>
Reviewed by Simon Hausmann.
diff --git a/src/3rdparty/webkit/WebCore/page/FocusController.cpp b/src/3rdparty/webkit/WebCore/page/FocusController.cpp
index 6c2a956..a285e52 100644
--- a/src/3rdparty/webkit/WebCore/page/FocusController.cpp
+++ b/src/3rdparty/webkit/WebCore/page/FocusController.cpp
@@ -319,7 +319,7 @@ bool FocusController::advanceFocusDirectionally(FocusDirection direction, Keyboa
// if |node| element is not in the viewport.
if (hasOffscreenRect(node)) {
Frame* frame = node->document()->view()->frame();
- scrollInDirection(frame, direction);
+ scrollInDirection(frame, direction, focusCandidate);
return true;
}
@@ -341,105 +341,152 @@ bool FocusController::advanceFocusDirectionally(FocusDirection direction, Keyboa
return true;
}
-// FIXME: Make this method more modular, and simpler to understand and maintain.
-static void updateFocusCandidateIfCloser(Node* focusedNode, const FocusCandidate& candidate, FocusCandidate& closest)
+static void updateFocusCandidateInSameContainer(const FocusCandidate& candidate, FocusCandidate& closest)
{
- bool sameDocument = candidate.document() == closest.document();
- if (sameDocument) {
- if (closest.alignment > candidate.alignment
- || (closest.parentAlignment && candidate.alignment > closest.parentAlignment))
- return;
- } else if (closest.alignment > candidate.alignment
- && (closest.parentAlignment && candidate.alignment > closest.parentAlignment))
+ if (closest.isNull()) {
+ closest = candidate;
return;
+ }
- if (candidate.alignment != None
- || (closest.parentAlignment >= candidate.alignment
- && closest.document() == candidate.document())) {
+ if (candidate.alignment == closest.alignment) {
+ if (candidate.distance < closest.distance)
+ closest = candidate;
+ return;
+ }
- // If we are now in an higher precedent case, lets reset the current closest's
- // distance so we force it to be bigger than any result we will get from
- // spatialDistance().
- if (closest.alignment < candidate.alignment
- && closest.parentAlignment < candidate.alignment)
- closest.distance = maxDistance();
+ if (candidate.alignment > closest.alignment)
+ closest = candidate;
+}
- closest.alignment = candidate.alignment;
+static void updateFocusCandidateIfCloser(Node* focusedNode, const FocusCandidate& candidate, FocusCandidate& closest)
+{
+ // First, check the common case: neither candidate nor closest are
+ // inside scrollable content, then no need to care about enclosingScrollableBox
+ // heuristics or parent{Distance,Alignment}, but only distance and alignment.
+ if (!candidate.inScrollableContainer() && !closest.inScrollableContainer()) {
+ updateFocusCandidateInSameContainer(candidate, closest);
+ return;
}
- // Bail out if candidate's distance is larger than that of the closest candidate.
- if (candidate.distance >= closest.distance)
+ bool sameContainer = candidate.document() == closest.document() && candidate.enclosingScrollableBox == closest.enclosingScrollableBox;
+
+ // Second, if candidate and closest are in the same "container" (i.e. {i}frame or any
+ // scrollable block element), we can handle them as common case.
+ if (sameContainer) {
+ updateFocusCandidateInSameContainer(candidate, closest);
return;
+ }
- if (closest.isNull()) {
+ // Last, we are considering moving to a candidate located in a different enclosing
+ // scrollable box than closest.
+ bool isInInnerDocument = !isInRootDocument(focusedNode);
+
+ bool sameContainerAsCandidate = isInInnerDocument ? focusedNode->document() == candidate.document() :
+ focusedNode->isDescendantOf(candidate.enclosingScrollableBox);
+
+ bool sameContainerAsClosest = isInInnerDocument ? focusedNode->document() == closest.document() :
+ focusedNode->isDescendantOf(closest.enclosingScrollableBox);
+
+ // sameContainerAsCandidate and sameContainerAsClosest are mutually exclusive.
+ ASSERT(!(sameContainerAsCandidate && sameContainerAsClosest));
+
+ if (sameContainerAsCandidate) {
closest = candidate;
return;
}
- // If the focused node and the candadate are in the same document and current
- // closest candidate is not in an {i}frame that is preferable to get focused ...
- if (focusedNode->document() == candidate.document()
- && candidate.distance < closest.parentDistance)
- closest = candidate;
- else if (focusedNode->document() != candidate.document()) {
- // If the focusedNode is in an inner document and candidate is in a
- // different document, we only consider to change focus if there is not
- // another already good focusable candidate in the same document as focusedNode.
- if (!((isInRootDocument(candidate.node) && !isInRootDocument(focusedNode))
- && focusedNode->document() == closest.document()))
+ if (sameContainerAsClosest) {
+ // Nothing to be done.
+ return;
+ }
+
+ // NOTE: !sameContainerAsCandidate && !sameContainerAsClosest
+ // If distance is shorter, and we are talking about scrollable container,
+ // lets compare parent distance and alignment before anything.
+ if (candidate.distance < closest.distance) {
+ if (candidate.alignment >= closest.parentAlignment
+ || candidate.parentAlignment == closest.parentAlignment) {
closest = candidate;
+ return;
+ }
+
+ } else if (candidate.parentDistance < closest.distance) {
+ if (candidate.parentAlignment >= closest.alignment) {
+ closest = candidate;
+ return;
+ }
}
}
void FocusController::findFocusableNodeInDirection(Node* outer, Node* focusedNode,
FocusDirection direction, KeyboardEvent* event,
- FocusCandidate& closestFocusCandidate,
- const FocusCandidate& candidateParent)
+ FocusCandidate& closest, const FocusCandidate& candidateParent)
{
ASSERT(outer);
ASSERT(candidateParent.isNull()
|| candidateParent.node->hasTagName(frameTag)
- || candidateParent.node->hasTagName(iframeTag));
+ || candidateParent.node->hasTagName(iframeTag)
+ || isScrollableContainerNode(candidateParent.node));
+
+ // Walk all the child nodes and update closest if we find a nearer node.
+ Node* node = outer;
+ while (node) {
- // Walk all the child nodes and update closestFocusCandidate if we find a nearer node.
- Node* candidate = outer;
- while (candidate) {
// Inner documents case.
+ if (node->isFrameOwnerElement()) {
+ deepFindFocusableNodeInDirection(node, focusedNode, direction, event, closest);
- if (candidate->isFrameOwnerElement())
- deepFindFocusableNodeInDirection(candidate, focusedNode, direction, event, closestFocusCandidate);
- else if (candidate != focusedNode && candidate->isKeyboardFocusable(event)) {
- FocusCandidate currentFocusCandidate(candidate);
+ // Scrollable block elements (e.g. <div>, etc) case.
+ } else if (isScrollableContainerNode(node)) {
+ deepFindFocusableNodeInDirection(node, focusedNode, direction, event, closest);
+ node = node->traverseNextSibling();
+ continue;
+
+ } else if (node != focusedNode && node->isKeyboardFocusable(event)) {
+ FocusCandidate candidate(node);
+
+ // There are two ways to identify we are in a recursive call from deepFindFocusableNodeInDirection
+ // (i.e. processing an element in an iframe, frame or a scrollable block element):
+
+ // 1) If candidateParent is not null, and it holds the distance and alignment data of the
+ // parent container element itself;
+ // 2) Parent of outer is <frame> or <iframe>;
+ // 3) Parent is any other scrollable block element.
+ if (!candidateParent.isNull()) {
+ candidate.parentAlignment = candidateParent.alignment;
+ candidate.parentDistance = candidateParent.distance;
+ candidate.enclosingScrollableBox = candidateParent.node;
+
+ } else if (!isInRootDocument(outer)) {
+ if (Document* document = static_cast<Document*>(outer->parent()))
+ candidate.enclosingScrollableBox = static_cast<Node*>(document->ownerElement());
+
+ } else if (isScrollableContainerNode(outer->parent()))
+ candidate.enclosingScrollableBox = outer->parent();
// Get distance and alignment from current candidate.
- distanceDataForNode(direction, focusedNode, currentFocusCandidate);
+ distanceDataForNode(direction, focusedNode, candidate);
// Bail out if distance is maximum.
- if (currentFocusCandidate.distance == maxDistance()) {
- candidate = candidate->traverseNextNode(outer->parent());
+ if (candidate.distance == maxDistance()) {
+ node = node->traverseNextNode(outer->parent());
continue;
}
- // If candidateParent is not null, it means that we are in a recursive call
- // from deepFineFocusableNodeInDirection (i.e. processing an element in an iframe),
- // and holds the distance and alignment data of the iframe element itself.
- if (!candidateParent.isNull()) {
- currentFocusCandidate.parentAlignment = candidateParent.alignment;
- currentFocusCandidate.parentDistance = candidateParent.distance;
- }
-
- updateFocusCandidateIfCloser(focusedNode, currentFocusCandidate, closestFocusCandidate);
+ updateFocusCandidateIfCloser(focusedNode, candidate, closest);
}
- candidate = candidate->traverseNextNode(outer->parent());
+ node = node->traverseNextNode(outer->parent());
}
}
void FocusController::deepFindFocusableNodeInDirection(Node* container, Node* focusedNode,
FocusDirection direction, KeyboardEvent* event,
- FocusCandidate& closestFocusCandidate)
+ FocusCandidate& closest)
{
- ASSERT(container->hasTagName(frameTag) || container->hasTagName(iframeTag));
+ ASSERT(container->hasTagName(frameTag)
+ || container->hasTagName(iframeTag)
+ || isScrollableContainerNode(container));
// Track if focusedNode is a descendant of the current container node being processed.
bool descendantOfContainer = false;
@@ -459,10 +506,15 @@ void FocusController::deepFindFocusableNodeInDirection(Node* container, Node* fo
descendantOfContainer = innerDocument == focusedNode->document();
firstChild = innerDocument->firstChild();
+ // Scrollable block elements (e.g. <div>, etc)
+ } else if (isScrollableContainerNode(container)) {
+
+ firstChild = container->firstChild();
+ descendantOfContainer = focusedNode->isDescendantOf(container);
}
if (descendantOfContainer) {
- findFocusableNodeInDirection(firstChild, focusedNode, direction, event, closestFocusCandidate);
+ findFocusableNodeInDirection(firstChild, focusedNode, direction, event, closest);
return;
}
@@ -476,8 +528,8 @@ void FocusController::deepFindFocusableNodeInDirection(Node* container, Node* fo
return;
// FIXME: Consider alignment?
- if (candidateParent.distance < closestFocusCandidate.distance)
- findFocusableNodeInDirection(firstChild, focusedNode, direction, event, closestFocusCandidate, candidateParent);
+ if (candidateParent.distance < closest.distance)
+ findFocusableNodeInDirection(firstChild, focusedNode, direction, event, closest, candidateParent);
}
static bool relinquishesEditingFocus(Node *node)
diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.cpp b/src/3rdparty/webkit/WebCore/page/FrameView.cpp
index bc0519f..a53db36 100644
--- a/src/3rdparty/webkit/WebCore/page/FrameView.cpp
+++ b/src/3rdparty/webkit/WebCore/page/FrameView.cpp
@@ -80,23 +80,25 @@ using namespace HTMLNames;
double FrameView::sCurrentPaintTimeStamp = 0.0;
+// REPAINT_THROTTLING now chooses default values for throttling parameters.
+// Should be removed when applications start using runtime configuration.
#if ENABLE(REPAINT_THROTTLING)
// Normal delay
-static const double deferredRepaintDelay = 0.025;
+double FrameView::s_deferredRepaintDelay = 0.025;
// Negative value would mean that first few repaints happen without a delay
-static const double initialDeferredRepaintDelayDuringLoading = 0;
+double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
// The delay grows on each repaint to this maximum value
-static const double maxDeferredRepaintDelayDuringLoading = 2.5;
+double FrameView::s_maxDeferredRepaintDelayDuringLoading = 2.5;
// On each repaint the delay increses by this amount
-static const double deferredRepaintDelayIncrementDuringLoading = 0.5;
+double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0.5;
#else
// FIXME: Repaint throttling could be good to have on all platform.
// The balance between CPU use and repaint frequency will need some tuning for desktop.
// More hooks may be needed to reset the delay on things like GIF and CSS animations.
-static const double deferredRepaintDelay = 0;
-static const double initialDeferredRepaintDelayDuringLoading = 0;
-static const double maxDeferredRepaintDelayDuringLoading = 0;
-static const double deferredRepaintDelayIncrementDuringLoading = 0;
+double FrameView::s_deferredRepaintDelay = 0;
+double FrameView::s_initialDeferredRepaintDelayDuringLoading = 0;
+double FrameView::s_maxDeferredRepaintDelayDuringLoading = 0;
+double FrameView::s_deferredRepaintDelayIncrementDuringLoading = 0;
#endif
// The maximum number of updateWidgets iterations that should be done before returning.
@@ -200,7 +202,7 @@ void FrameView::reset()
m_deferringRepaints = 0;
m_repaintCount = 0;
m_repaintRects.clear();
- m_deferredRepaintDelay = initialDeferredRepaintDelayDuringLoading;
+ m_deferredRepaintDelay = s_initialDeferredRepaintDelayDuringLoading;
m_deferredRepaintTimer.stop();
m_lastPaintTime = 0;
m_paintBehavior = PaintBehaviorNormal;
@@ -1218,13 +1220,13 @@ void FrameView::updateDeferredRepaintDelay()
{
Document* document = m_frame->document();
if (!document || (!document->parsing() && !document->docLoader()->requestCount())) {
- m_deferredRepaintDelay = deferredRepaintDelay;
+ m_deferredRepaintDelay = s_deferredRepaintDelay;
return;
}
- if (m_deferredRepaintDelay < maxDeferredRepaintDelayDuringLoading) {
- m_deferredRepaintDelay += deferredRepaintDelayIncrementDuringLoading;
- if (m_deferredRepaintDelay > maxDeferredRepaintDelayDuringLoading)
- m_deferredRepaintDelay = maxDeferredRepaintDelayDuringLoading;
+ if (m_deferredRepaintDelay < s_maxDeferredRepaintDelayDuringLoading) {
+ m_deferredRepaintDelay += s_deferredRepaintDelayIncrementDuringLoading;
+ if (m_deferredRepaintDelay > s_maxDeferredRepaintDelayDuringLoading)
+ m_deferredRepaintDelay = s_maxDeferredRepaintDelayDuringLoading;
}
}
@@ -2143,4 +2145,28 @@ IntPoint FrameView::convertFromContainingView(const IntPoint& parentPoint) const
return parentPoint;
}
+// Normal delay
+void FrameView::setRepaintThrottlingDeferredRepaintDelay(double p)
+{
+ s_deferredRepaintDelay = p;
+}
+
+// Negative value would mean that first few repaints happen without a delay
+void FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p)
+{
+ s_initialDeferredRepaintDelayDuringLoading = p;
+}
+
+// The delay grows on each repaint to this maximum value
+void FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p)
+{
+ s_maxDeferredRepaintDelayDuringLoading = p;
+}
+
+// On each repaint the delay increases by this amount
+void FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p)
+{
+ s_deferredRepaintDelayIncrementDuringLoading = p;
+}
+
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/FrameView.h b/src/3rdparty/webkit/WebCore/page/FrameView.h
index 71e2966..71fa8cd 100644
--- a/src/3rdparty/webkit/WebCore/page/FrameView.h
+++ b/src/3rdparty/webkit/WebCore/page/FrameView.h
@@ -210,6 +210,15 @@ public:
bool isFrameViewScrollCorner(RenderScrollbarPart* scrollCorner) const { return m_scrollCorner == scrollCorner; }
void invalidateScrollCorner();
+ // Normal delay
+ static void setRepaintThrottlingDeferredRepaintDelay(double p);
+ // Negative value would mean that first few repaints happen without a delay
+ static void setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(double p);
+ // The delay grows on each repaint to this maximum value
+ static void setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(double p);
+ // On each repaint the delay increses by this amount
+ static void setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(double p);
+
protected:
virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
@@ -340,6 +349,11 @@ private:
// Renderer to hold our custom scroll corner.
RenderScrollbarPart* m_scrollCorner;
+
+ static double s_deferredRepaintDelay;
+ static double s_initialDeferredRepaintDelayDuringLoading;
+ static double s_maxDeferredRepaintDelayDuringLoading;
+ static double s_deferredRepaintDelayIncrementDuringLoading;
};
#if ENABLE(INSPECTOR)
diff --git a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp
index d7eaf25..1ce61c3 100644
--- a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp
+++ b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.cpp
@@ -124,8 +124,11 @@ static IntRect renderRectRelativeToRootDocument(RenderObject* render)
// Handle nested frames.
for (Frame* frame = render->document()->frame(); frame; frame = frame->tree()->parent()) {
- if (HTMLFrameOwnerElement* ownerElement = frame->ownerElement())
- rect.move(ownerElement->offsetLeft(), ownerElement->offsetTop());
+ if (Element* element = static_cast<Element*>(frame->ownerElement())) {
+ do {
+ rect.move(element->offsetLeft(), element->offsetTop());
+ } while ((element = element->offsetParent()));
+ }
}
return rect;
@@ -444,7 +447,7 @@ bool hasOffscreenRect(Node* node)
// In a bottom-up way, this method tries to scroll |frame| in a given direction
// |direction|, going up in the frame tree hierarchy in case it does not succeed.
-bool scrollInDirection(Frame* frame, FocusDirection direction)
+bool scrollInDirection(Frame* frame, FocusDirection direction, const FocusCandidate& candidate)
{
if (!frame)
return false;
@@ -468,6 +471,9 @@ bool scrollInDirection(Frame* frame, FocusDirection direction)
return false;
}
+ if (!candidate.isNull() && isScrollableContainerNode(candidate.enclosingScrollableBox))
+ return frame->eventHandler()->scrollRecursively(scrollDirection, ScrollByLine, candidate.enclosingScrollableBox);
+
return frame->eventHandler()->scrollRecursively(scrollDirection, ScrollByLine);
}
@@ -526,4 +532,17 @@ static bool checkNegativeCoordsForNode(Node* node, const IntRect& curRect)
return canBeScrolled;
}
+bool isScrollableContainerNode(Node* node)
+{
+ if (!node)
+ return false;
+
+ if (RenderObject* renderer = node->renderer()) {
+ return (renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()
+ && node->hasChildNodes() && !node->isDocumentNode());
+ }
+
+ return false;
+}
+
} // namespace WebCore
diff --git a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h
index 309b095..06389a3 100644
--- a/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h
+++ b/src/3rdparty/webkit/WebCore/page/SpatialNavigation.h
@@ -97,6 +97,7 @@ enum RectsAlignment {
struct FocusCandidate {
FocusCandidate()
: node(0)
+ , enclosingScrollableBox(0)
, distance(maxDistance())
, parentDistance(maxDistance())
, alignment(None)
@@ -106,6 +107,7 @@ struct FocusCandidate {
FocusCandidate(Node* n)
: node(n)
+ , enclosingScrollableBox(0)
, distance(maxDistance())
, parentDistance(maxDistance())
, alignment(None)
@@ -114,9 +116,11 @@ struct FocusCandidate {
}
bool isNull() const { return !node; }
+ bool inScrollableContainer() const { return node && enclosingScrollableBox; }
Document* document() const { return node ? node->document() : 0; }
Node* node;
+ Node* enclosingScrollableBox;
long long distance;
long long parentDistance;
RectsAlignment alignment;
@@ -124,10 +128,11 @@ struct FocusCandidate {
};
void distanceDataForNode(FocusDirection direction, Node* start, FocusCandidate& candidate);
-bool scrollInDirection(Frame*, FocusDirection);
+bool scrollInDirection(Frame*, FocusDirection, const FocusCandidate& candidate = FocusCandidate());
void scrollIntoView(Element*);
bool hasOffscreenRect(Node*);
bool isInRootDocument(Node*);
+bool isScrollableContainerNode(Node*);
} // namspace WebCore
diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
index b10cc71..cc707da 100644
--- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
+++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/ImageDecoderQt.cpp
@@ -115,22 +115,8 @@ size_t ImageDecoderQt::frameCount()
int ImageDecoderQt::repetitionCount() const
{
- if (m_reader && m_reader->supportsAnimation()) {
+ if (m_reader && m_reader->supportsAnimation())
m_repetitionCount = m_reader->loopCount();
-
- // Qt and WebCore have a incompatible understanding of
- // the loop count and we can not completely map everything.
- // Qt | WebCore | description
- // -1 | 0 | infinite animation
- // 0 | cAnimationLoopOnce | show every frame once
- // n | n | no idea if that is supported
- // n/a | cAnimationNone | show only the first frame
- if (m_repetitionCount == -1)
- m_repetitionCount = 0;
- else if (m_repetitionCount == 0)
- m_repetitionCount = cAnimationLoopOnce;
- }
-
return m_repetitionCount;
}
@@ -205,6 +191,8 @@ bool ImageDecoderQt::internalHandleCurrentImage(size_t frameIndex)
// Now get the QImage from Qt and place it in the RGBA32Buffer
QImage img;
if (!m_reader->read(&img)) {
+ frameCount();
+ repetitionCount();
clearPointers();
return false;
}
diff --git a/src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp b/src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp
index 74deaf6..d5292fe 100644
--- a/src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp
+++ b/src/3rdparty/webkit/WebCore/plugins/qt/PluginPackageQt.cpp
@@ -35,6 +35,8 @@
namespace WebCore {
+typedef void gtkInitFunc(int *argc, char ***argv);
+
bool PluginPackage::fetchInfo()
{
if (!load())
@@ -109,6 +111,7 @@ bool PluginPackage::load()
NP_InitializeFuncPtr NP_Initialize;
NPError npErr;
+ gtkInitFunc* gtkInit;
NP_Initialize = (NP_InitializeFuncPtr)m_module->resolve("NP_Initialize");
m_NPP_Shutdown = (NPP_ShutdownProcPtr)m_module->resolve("NP_Shutdown");
@@ -127,6 +130,26 @@ bool PluginPackage::load()
m_browserFuncs.getvalue = staticPluginQuirkRequiresGtkToolKit_NPN_GetValue;
}
+ // WORKAROUND: Prevent gtk based plugin crashes such as BR# 40567 by
+ // explicitly forcing the initializing of Gtk, i.e. calling gtk_init,
+ // whenver the symbol is present in the plugin library loaded above.
+ // Note that this workaround is based on code from the NSPluginClass ctor
+ // in KDE's kdebase/apps/nsplugins/viewer/nsplugin.cpp file.
+ gtkInit = (gtkInitFunc*)m_module->resolve("gtk_init");
+ if (gtkInit) {
+ // Prevent gtk_init() from replacing the X error handlers, since the Gtk
+ // handlers abort when they receive an X error, thus killing the viewer.
+#ifdef Q_WS_X11
+ int (*old_error_handler)(Display*, XErrorEvent*) = XSetErrorHandler(0);
+ int (*old_io_error_handler)(Display*) = XSetIOErrorHandler(0);
+#endif
+ gtkInit(0, 0);
+#ifdef Q_WS_X11
+ XSetErrorHandler(old_error_handler);
+ XSetIOErrorHandler(old_io_error_handler);
+#endif
+ }
+
#if defined(XP_UNIX)
npErr = NP_Initialize(&m_browserFuncs, &m_pluginFuncs);
#else
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
index 8c7b93d..4460ad3 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp
@@ -1371,6 +1371,14 @@ void QWebPagePrivate::inputMethodEvent(QInputMethodEvent *ev)
}
#ifndef QT_NO_PROPERTIES
+typedef struct {
+ const char* name;
+ double deferredRepaintDelay;
+ double initialDeferredRepaintDelayDuringLoading;
+ double maxDeferredRepaintDelayDuringLoading;
+ double deferredRepaintDelayIncrementDuringLoading;
+} QRepaintThrottlingPreset;
+
void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* event)
{
if (event->propertyName() == "_q_viewMode") {
@@ -1388,7 +1396,42 @@ void QWebPagePrivate::dynamicPropertyChangeEvent(QDynamicPropertyChangeEvent* ev
} else if (event->propertyName() == "_q_HTMLTokenizerTimeDelay") {
double timeDelay = q->property("_q_HTMLTokenizerTimeDelay").toDouble();
q->handle()->page->setCustomHTMLTokenizerTimeDelay(timeDelay);
- }
+ } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelay") {
+ double p = q->property("_q_RepaintThrottlingDeferredRepaintDelay").toDouble();
+ FrameView::setRepaintThrottlingDeferredRepaintDelay(p);
+ } else if (event->propertyName() == "_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading") {
+ double p = q->property("_q_RepaintThrottlingnInitialDeferredRepaintDelayDuringLoading").toDouble();
+ FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(p);
+ } else if (event->propertyName() == "_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading") {
+ double p = q->property("_q_RepaintThrottlingMaxDeferredRepaintDelayDuringLoading").toDouble();
+ FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(p);
+ } else if (event->propertyName() == "_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading") {
+ double p = q->property("_q_RepaintThrottlingDeferredRepaintDelayIncrementDuringLoading").toDouble();
+ FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(p);
+ } else if (event->propertyName() == "_q_RepaintThrottlingPreset") {
+ static const QRepaintThrottlingPreset presets[] = {
+ { "NoThrottling", 0, 0, 0, 0 },
+ { "Legacy", 0.025, 0, 2.5, 0.5 },
+ { "Minimal", 0.01, 0, 1, 0.2 },
+ { "Medium", 0.025, 1, 5, 0.5 },
+ { "Heavy", 0.1, 2, 10, 1 }
+ };
+
+ QString p = q->property("_q_RepaintThrottlingPreset").toString();
+ for(int i = 0; i < sizeof(presets) / sizeof(presets[0]); i++) {
+ if(p == presets[i].name) {
+ FrameView::setRepaintThrottlingDeferredRepaintDelay(
+ presets[i].deferredRepaintDelay);
+ FrameView::setRepaintThrottlingnInitialDeferredRepaintDelayDuringLoading(
+ presets[i].initialDeferredRepaintDelayDuringLoading);
+ FrameView::setRepaintThrottlingMaxDeferredRepaintDelayDuringLoading(
+ presets[i].maxDeferredRepaintDelayDuringLoading);
+ FrameView::setRepaintThrottlingDeferredRepaintDelayIncrementDuringLoading(
+ presets[i].deferredRepaintDelayIncrementDuringLoading);
+ break;
+ }
+ }
+ }
#if ENABLE(TILED_BACKING_STORE)
else if (event->propertyName() == "_q_TiledBackingStoreTileSize") {
WebCore::Frame* frame = QWebFramePrivate::core(q->mainFrame());
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp
index a5fc794..47b4f3b 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.cpp
@@ -245,6 +245,10 @@ void QWebSettingsPrivate::apply()
settings->setTiledBackingStoreEnabled(value);
#endif
+ value = attributes.value(QWebSettings::SiteSpecificQuirksEnabled,
+ global->attributes.value(QWebSettings::SiteSpecificQuirksEnabled));
+ settings->setNeedsSiteSpecificQuirks(value);
+
settings->setUsesPageCache(WebCore::pageCache()->capacity());
} else {
QList<QWebSettingsPrivate*> settings = *::allSettings();
@@ -426,6 +430,8 @@ QWebSettings* QWebSettings::globalSettings()
and at other times scrolling the page itself. For this reason iframes and framesets are
barely usable on touch devices. This will flatten all the frames to become one scrollable page.
This is disabled by default.
+ \value SiteSpecificQuirksEnabled This setting enables WebKit's workaround for broken sites. It is
+ enabled by default.
*/
/*!
@@ -461,6 +467,7 @@ QWebSettings::QWebSettings()
d->attributes.insert(QWebSettings::AcceleratedCompositingEnabled, true);
d->attributes.insert(QWebSettings::TiledBackingStoreEnabled, false);
d->attributes.insert(QWebSettings::FrameFlatteningEnabled, false);
+ d->attributes.insert(QWebSettings::SiteSpecificQuirksEnabled, true);
d->offlineStorageDefaultQuota = 5 * 1024 * 1024;
d->defaultTextEncoding = QLatin1String("iso-8859-1");
}
diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h
index b978f5e..207a9b6 100644
--- a/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h
+++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebsettings.h
@@ -73,7 +73,8 @@ public:
SpatialNavigationEnabled,
LocalContentCanAccessFileUrls,
TiledBackingStoreEnabled,
- FrameFlatteningEnabled
+ FrameFlatteningEnabled,
+ SiteSpecificQuirksEnabled
};
enum WebGraphic {
MissingImageGraphic,
diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog
index 671acec..475d22d 100644
--- a/src/3rdparty/webkit/WebKit/qt/ChangeLog
+++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog
@@ -1,3 +1,40 @@
+2010-06-17 Mark Brand <mabrand@mabrand.nl>
+
+ Reviewed by Simon Hausmann.
+
+ [Qt] use "win32-g++*" scope to match all MinGW makespecs
+
+ The scope "win32-g++" comes from the name of the makespec. However, it
+ is frequently used to check for MinGW. This works fine as long as
+ win32-g++ is the only makespec for MinGW. Now we need the wildcard
+ to cover "win32-g++-cross" as well.
+
+ * Api/DerivedSources.pro:
+
+2010-05-28 Viatcheslav Ostapenko <ostapenko.viatcheslav@nokia.com>
+
+ Reviewed by Simon Hausmann, Antti Koivisto
+
+ [Qt] Add internal Qt Api to configure repaint throttling parameters.
+ https://bugs.webkit.org/show_bug.cgi?id=38401
+
+ * Api/qwebpage.cpp:
+ (QWebPagePrivate::dynamicPropertyChangeEvent):
+
+2010-06-12 Dawit Alemayehu <adawit@kde.org>
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Added an attribute to enable/disable site specific quirks mode in WebKit.
+ The attribute is enabled by default.
+
+ https://bugs.webkit.org/show_bug.cgi?id=40073
+
+ * Api/qwebsettings.cpp:
+ (QWebSettingsPrivate::apply):
+ (QWebSettings::QWebSettings):
+ * Api/qwebsettings.h:
+
2010-06-09 Pierre Rossi <pierre.rossi@nokia.com>
Reviewed by Kenneth Rohde Christiansen.
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 223df9b..d2e4f75 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -1476,10 +1476,13 @@ bool QIODevice::getChar(char *c)
*/
qint64 QIODevice::peek(char *data, qint64 maxSize)
{
+ Q_D(QIODevice);
qint64 readBytes = read(data, maxSize);
- int i = readBytes;
- while (i > 0)
- ungetChar(data[i-- - 1]);
+ if (readBytes <= 0)
+ return readBytes;
+
+ d->buffer.ungetBlock(data, readBytes);
+ d->pos -= readBytes;
return readBytes;
}
@@ -1502,11 +1505,15 @@ qint64 QIODevice::peek(char *data, qint64 maxSize)
*/
QByteArray QIODevice::peek(qint64 maxSize)
{
+ Q_D(QIODevice);
QByteArray result = read(maxSize);
- int i = result.size();
- const char *data = result.constData();
- while (i > 0)
- ungetChar(data[i-- - 1]);
+
+ if (result.isEmpty())
+ return result;
+
+ d->buffer.ungetBlock(result.constData(), result.size());
+ d->pos -= result.size();
+
return result;
}
diff --git a/src/corelib/io/qiodevice_p.h b/src/corelib/io/qiodevice_p.h
index 94dadca..225a0b9 100644
--- a/src/corelib/io/qiodevice_p.h
+++ b/src/corelib/io/qiodevice_p.h
@@ -151,6 +151,15 @@ public:
len++;
*first = c;
}
+ void ungetBlock(const char* block, int size) {
+ if ((first - buf) < size) {
+ // underflow, the existing valid data needs to move to the end of the (potentially bigger) buffer
+ makeSpace(len + size, freeSpaceAtStart);
+ memcpy(first - size, block, size);
+ }
+ first -= size;
+ len += size;
+ }
private:
enum FreeSpacePos {freeSpaceAtStart, freeSpaceAtEnd};
diff --git a/src/corelib/kernel/qabstracteventdispatcher.cpp b/src/corelib/kernel/qabstracteventdispatcher.cpp
index ee3c4f2..bcf4477 100644
--- a/src/corelib/kernel/qabstracteventdispatcher.cpp
+++ b/src/corelib/kernel/qabstracteventdispatcher.cpp
@@ -393,6 +393,27 @@ void QAbstractEventDispatcher::closingDown()
\snippet doc/src/snippets/code/src_corelib_kernel_qabstracteventdispatcher.cpp 0
+ Note that the type of the \a message is platform dependent. The
+ following table shows the \a {message}'s type on Windows, Mac, and
+ X11. You can do a static cast to these types.
+
+ \table
+ \header
+ \o Platform
+ \o type
+ \row
+ \o Windows
+ \o MSG
+ \row
+ \o X11
+ \o XEvent
+ \row
+ \o Mac
+ \o NSEvent
+ \endtable
+
+
+
\sa setEventFilter(), filterEvent()
*/
@@ -434,6 +455,9 @@ QAbstractEventDispatcher::EventFilter QAbstractEventDispatcher::setEventFilter(E
compatibility with any extensions that may be used in the
application.
+ Note that the type of \a message is platform dependent. See
+ QAbstractEventDispatcher::EventFilter for details.
+
\sa setEventFilter()
*/
bool QAbstractEventDispatcher::filterEvent(void *message)
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
index cf458da..d4ca9eb 100644
--- a/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeborderimage.cpp
@@ -449,6 +449,11 @@ void QDeclarativeBorderImage::sciRequestFinished()
}
}
+void QDeclarativeBorderImage::doUpdate()
+{
+ update();
+}
+
void QDeclarativeBorderImage::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
{
Q_D(QDeclarativeBorderImage);
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage_p.h b/src/declarative/graphicsitems/qdeclarativeborderimage_p.h
index 5e725ca..07f049e 100644
--- a/src/declarative/graphicsitems/qdeclarativeborderimage_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeborderimage_p.h
@@ -91,6 +91,7 @@ private:
void setGridScaledImage(const QDeclarativeGridScaledImage& sci);
private Q_SLOTS:
+ void doUpdate();
void requestFinished();
void sciRequestFinished();
diff --git a/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h b/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h
index 3535109..01e4a00 100644
--- a/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativeborderimage_p_p.h
@@ -77,11 +77,20 @@ public:
{
}
+
QDeclarativeScaleGrid *getScaleGrid()
{
Q_Q(QDeclarativeBorderImage);
- if (!border)
+ if (!border) {
border = new QDeclarativeScaleGrid(q);
+ static int borderChangedSignalIdx = -1;
+ static int doUpdateSlotIdx = -1;
+ if (borderChangedSignalIdx < 0)
+ borderChangedSignalIdx = QDeclarativeScaleGrid::staticMetaObject.indexOfSignal("borderChanged()");
+ if (doUpdateSlotIdx < 0)
+ doUpdateSlotIdx = QDeclarativeBorderImage::staticMetaObject.indexOfSlot("doUpdate()");
+ QMetaObject::connect(border, borderChangedSignalIdx, q, doUpdateSlotIdx);
+ }
return border;
}
diff --git a/src/declarative/graphicsitems/qdeclarativeflickable.cpp b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
index fdc1444..3f681b7 100644
--- a/src/declarative/graphicsitems/qdeclarativeflickable.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeflickable.cpp
@@ -914,8 +914,14 @@ void QDeclarativeFlickable::timerEvent(QTimerEvent *event)
d->delayedPressTimer.stop();
if (d->delayedPressEvent) {
QDeclarativeItem *grabber = scene() ? qobject_cast<QDeclarativeItem*>(scene()->mouseGrabberItem()) : 0;
- if (!grabber || grabber != this)
- scene()->sendEvent(d->delayedPressTarget, d->delayedPressEvent);
+ if (!grabber || grabber != this) {
+ // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay)
+ // so we reset the grabber
+ if (scene()->mouseGrabberItem() == d->delayedPressTarget)
+ d->delayedPressTarget->ungrabMouse();
+ //Use the event handler that will take care of finding the proper item to propagate the event
+ QApplication::sendEvent(scene(), d->delayedPressEvent);
+ }
delete d->delayedPressEvent;
d->delayedPressEvent = 0;
}
@@ -1206,14 +1212,24 @@ bool QDeclarativeFlickable::sendMouseEvent(QGraphicsSceneMouseEvent *event)
break;
case QEvent::GraphicsSceneMouseRelease:
if (d->delayedPressEvent) {
- scene()->sendEvent(d->delayedPressTarget, d->delayedPressEvent);
+ // We replay the mouse press but the grabber we had might not be interessted by the event (e.g. overlay)
+ // so we reset the grabber
+ if (s->mouseGrabberItem() == d->delayedPressTarget)
+ d->delayedPressTarget->ungrabMouse();
+ //Use the event handler that will take care of finding the proper item to propagate the event
+ QApplication::sendEvent(scene(), d->delayedPressEvent);
d->clearDelayedPress();
+ // We send the release
+ scene()->sendEvent(s->mouseGrabberItem(), event);
+ // And the event has been consumed
+ return true;
}
d->handleMouseReleaseEvent(&mouseEvent);
break;
default:
break;
}
+ stealThisEvent = d->stealMouse; // Update stealThisEvent and grabber in case changed by function calls above
grabber = qobject_cast<QDeclarativeItem*>(s->mouseGrabberItem());
if (grabber && stealThisEvent && !grabber->keepMouseGrab() && grabber != this) {
d->clearDelayedPress();
diff --git a/src/declarative/graphicsitems/qdeclarativeitem.cpp b/src/declarative/graphicsitems/qdeclarativeitem.cpp
index 42b370b..336010f 100644
--- a/src/declarative/graphicsitems/qdeclarativeitem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitem.cpp
@@ -345,10 +345,11 @@ void QDeclarativeContents::complete()
void QDeclarativeContents::itemGeometryChanged(QDeclarativeItem *changed, const QRectF &newGeometry, const QRectF &oldGeometry)
{
- if (newGeometry.width() != oldGeometry.width())
- calcWidth(changed);
- if (newGeometry.height() != oldGeometry.height())
- calcHeight(changed);
+ //### we can only pass changed if the left edge has moved left, or the right edge has moved right
+ if (newGeometry.width() != oldGeometry.width() || newGeometry.x() != oldGeometry.x())
+ calcWidth(/*changed*/);
+ if (newGeometry.height() != oldGeometry.height() || newGeometry.y() != oldGeometry.y())
+ calcHeight(/*changed*/);
}
void QDeclarativeContents::itemDestroyed(QDeclarativeItem *item)
diff --git a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
index 0be8dac..b198077 100644
--- a/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
+++ b/src/declarative/graphicsitems/qdeclarativeitemsmodule.cpp
@@ -79,8 +79,24 @@
#endif
#include "private/qdeclarativeanchors_p.h"
+static QDeclarativePrivate::AutoParentResult qgraphicsobject_autoParent(QObject *obj, QObject *parent)
+{
+ QGraphicsObject* gobj = qobject_cast<QGraphicsObject*>(obj);
+ if (!gobj)
+ return QDeclarativePrivate::IncompatibleObject;
+
+ QGraphicsObject* gparent = qobject_cast<QGraphicsObject*>(parent);
+ if (!gparent)
+ return QDeclarativePrivate::IncompatibleParent;
+
+ gobj->setParentItem(gparent);
+ return QDeclarativePrivate::Parented;
+}
+
void QDeclarativeItemModule::defineModule()
{
+ QDeclarativePrivate::registerAutoParentFunction(qgraphicsobject_autoParent);
+
#ifdef QT_NO_MOVIE
qmlRegisterTypeNotAvailable("Qt",4,7,"AnimatedImage",
qApp->translate("QDeclarativeAnimatedImage","Qt was built without support for QMovie"));
diff --git a/src/declarative/graphicsitems/qdeclarativelistview.cpp b/src/declarative/graphicsitems/qdeclarativelistview.cpp
index 48ac4a4..b0728c1 100644
--- a/src/declarative/graphicsitems/qdeclarativelistview.cpp
+++ b/src/declarative/graphicsitems/qdeclarativelistview.cpp
@@ -1379,7 +1379,7 @@ void QDeclarativeListViewPrivate::flick(AxisData &data, qreal minExtent, qreal m
to set \e {clip: true} in order to have the out of view items clipped
nicely.
- \sa ListModel, GridView
+ \sa ListModel, GridView, {declarative/modelviews/listview}{ListView examples}
*/
QDeclarativeListView::QDeclarativeListView(QDeclarativeItem *parent)
@@ -1663,7 +1663,7 @@ int QDeclarativeListView::count() const
so as to stay with the current item, unless the highlightFollowsCurrentItem
property is false.
- \sa highlightItem, highlightFollowsCurrentItem
+ \sa highlightItem, highlightFollowsCurrentItem, {declarative/modelviews/listview}{ListView examples}
*/
QDeclarativeComponent *QDeclarativeListView::highlight() const
{
@@ -1940,28 +1940,41 @@ void QDeclarativeListView::setCacheBuffer(int b)
These properties hold the expression to be evaluated for the \l section attached property.
- \c section.property hold the name of the property to use to determine
- the section that holds the item.
+ The \l section attached property enables a ListView to be visually
+ separated into different parts. These properties determine how sections
+ are created.
+
+ \c section.property holds the name of the property that is the basis
+ of each section.
- \c section.criteria holds the criteria to use to access the section. It
- can be either:
+ \c section.criteria holds the criteria for forming each section based on
+ \c section.property. This value can be one of:
\list
- \o ViewSection.FullString (default) - section is the value of the property.
- \o ViewSection.FirstCharacter - section is the first character of the property value.
+ \o ViewSection.FullString (default) - sections are created based on the
+ \c section.property value.
+ \o ViewSection.FirstCharacter - sections are created based on the first
+ character of the \c section.property value (for example, 'A', 'B', 'C'
+ sections, etc. for an address book)
\endlist
\c section.delegate holds the delegate component for each section.
Each item in the list has attached properties named \c ListView.section and
\c ListView.prevSection. These may be used to place a section header for
- related items. The example below assumes that the model is sorted by size of
- pet. The section expression is the size property. If \c ListView.section and
- \c ListView.prevSection differ, the item will display a section header.
-
+ related items.
+
+ For example, here is a ListView that displays a list of animals, separated
+ into sections. Each item in the ListView is placed in a different section
+ depending on the "size" property of the model item. The \c sectionHeading
+ delegate component provides the light blue bar that marks the beginning of
+ each section.
+
\snippet examples/declarative/modelviews/listview/sections.qml 0
\image ListViewSections.png
+
+ \sa {declarative/modelviews/listview}{ListView examples}
*/
QDeclarativeViewSection *QDeclarativeListView::sectionCriteria()
{
diff --git a/src/declarative/graphicsitems/qdeclarativemousearea.cpp b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
index c4956df..0bed41b 100644
--- a/src/declarative/graphicsitems/qdeclarativemousearea.cpp
+++ b/src/declarative/graphicsitems/qdeclarativemousearea.cpp
@@ -294,12 +294,12 @@ QDeclarativeMouseAreaPrivate::~QDeclarativeMouseAreaPrivate()
/*!
\qmlsignal MouseArea::onCanceled()
- This handler is called when the mouse events are canceled, either because the event was not accepted or
- another element stole the mouse event handling. This signal is for advanced users, it's useful in case there
- is more than one mouse areas handling input, or when there is a mouse area inside a flickable. In the latter
- case, if you do some logic on pressed and then start dragging, the flickable will steal the mouse handling
- from the mouse area. In these cases, to reset the logic when there is no mouse handling anymore, you should
- use onCanceled, in addition to onReleased.
+ This handler is called when mouse events have been canceled, either because an event was not accepted, or
+ because another element stole the mouse event handling. This signal is for advanced use: it is useful when
+ there is more than one MouseArea that is handling input, or when there is a MouseArea inside a \l Flickable. In the latter
+ case, if you execute some logic on the pressed signal and then start dragging, the \l Flickable will steal the mouse handling
+ from the MouseArea. In these cases, to reset the logic when the MouseArea has lost the mouse handling to the
+ \l Flickable, \c onCanceled should be used in addition to onReleased.
*/
/*!
diff --git a/src/declarative/graphicsitems/qdeclarativepositioners.cpp b/src/declarative/graphicsitems/qdeclarativepositioners.cpp
index ad61bab..b9231a1 100644
--- a/src/declarative/graphicsitems/qdeclarativepositioners.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepositioners.cpp
@@ -358,6 +358,8 @@ Column {
positioner may exhibit strange behaviour. If you need to perform any of these
actions, consider positioning the items without the use of a Column.
+ Items with a width or height of 0 will not be positioned.
+
\sa Row, {declarative/positioners}{Positioners example}
*/
/*!
@@ -502,6 +504,8 @@ Row {
positioner may exhibit strange behaviour. If you need to perform any of these
actions, consider positioning the items without the use of a Row.
+ Items with a width or height of 0 will not be positioned.
+
\sa Column, {declarative/positioners}{Positioners example}
*/
/*!
@@ -657,6 +661,8 @@ Grid {
positioner may exhibit strange behaviour. If you need to perform any of these
actions, consider positioning the items without the use of a Grid.
+ Items with a width or height of 0 will not be positioned.
+
\sa Flow, {declarative/positioners}{Positioners example}
*/
/*!
@@ -913,6 +919,8 @@ void QDeclarativeGrid::reportConflictingAnchors()
positioner may exhibit strange behaviour. If you need to perform any of these
actions, consider positioning the items without the use of a Flow.
+ Items with a width or height of 0 will not be positioned.
+
\sa Grid, {declarative/positioners}{Positioners example}
*/
/*!
diff --git a/src/declarative/graphicsitems/qdeclarativerepeater.cpp b/src/declarative/graphicsitems/qdeclarativerepeater.cpp
index 995e22a..87da904 100644
--- a/src/declarative/graphicsitems/qdeclarativerepeater.cpp
+++ b/src/declarative/graphicsitems/qdeclarativerepeater.cpp
@@ -83,17 +83,10 @@ QDeclarativeRepeaterPrivate::~QDeclarativeRepeaterPrivate()
\image repeater-simple.png
- The \l model of a Repeater can be specified as a model object, a number, a string list
- or an object list. If a model object is used, the
- \l delegate can access the model roles as named properties, just as for view elements like
- ListView and GridView.
+ The \l model of a Repeater can be any of the supported \l {qmlmodels}{Data Models}.
- The \l delegate can also access two additional properties:
-
- \list
- \o \c index - the index of the delegate's item
- \o \c modelData - the data element for the delegate, which is useful where the \l model is a string or object list
- \endlist
+ The index of a delegate is exposed as an accessible \c index property in the delegate.
+ Properties of the model are also available depending upon the type of \l {qmlmodels}{Data Model}.
Here is a Repeater that uses the \c index property inside the instantiated items:
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index cba01ef..9e5dfb5 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -100,6 +100,7 @@ void QDeclarativeTextInput::setText(const QString &s)
if(s == text())
return;
d->control->setText(s);
+ d->updateHorizontalScroll();
//emit textChanged();
}
@@ -337,6 +338,7 @@ void QDeclarativeTextInput::setHAlign(HAlignment align)
return;
d->hAlign = align;
updateRect();
+ d->updateHorizontalScroll();
emit horizontalAlignmentChanged(d->hAlign);
}
@@ -554,7 +556,9 @@ void QDeclarativeTextInput::setAutoScroll(bool b)
return;
d->autoScroll = b;
-
+ d->updateHorizontalScroll();
+ //We need to repaint so that the scrolling is taking into account.
+ updateSize(true);
emit autoScrollChanged(d->autoScroll);
}
@@ -836,17 +840,23 @@ void QDeclarativeTextInput::moveCursor()
Q_D(QDeclarativeTextInput);
if(!d->cursorItem)
return;
+ d->updateHorizontalScroll();
d->cursorItem->setX(d->control->cursorToX() - d->hscroll);
}
/*!
- \qmlmethod rect TextInput::positionToRectangle(int x)
+ \qmlmethod rect TextInput::positionToRectangle(int pos)
+
+ This function takes a character position and returns the rectangle that the
+ cursor would occupy, if it was placed at that character position.
+
+ This is similar to setting the cursorPosition, and then querying the cursor
+ rectangle, but the cursorPosition is not changed.
*/
-QRectF QDeclarativeTextInput::positionToRectangle(int x) const
+QRectF QDeclarativeTextInput::positionToRectangle(int pos) const
{
Q_D(const QDeclarativeTextInput);
- QFontMetrics fm = QFontMetrics(d->font);
- return QRectF(d->control->cursorToX(x)-d->hscroll,
+ return QRectF(d->control->cursorToX(pos)-d->hscroll,
0.0,
d->control->cursorWidth(),
cursorRectangle().height());
@@ -1006,61 +1016,73 @@ void QDeclarativeTextInput::geometryChanged(const QRectF &newGeometry,
QDeclarativePaintedItem::geometryChanged(newGeometry, oldGeometry);
}
-void QDeclarativeTextInput::drawContents(QPainter *p, const QRect &r)
+void QDeclarativeTextInputPrivate::updateHorizontalScroll()
{
- Q_D(QDeclarativeTextInput);
- p->setRenderHint(QPainter::TextAntialiasing, true);
- p->save();
- p->setPen(QPen(d->color));
- int flags = QLineControl::DrawText;
- if(!isReadOnly() && d->cursorVisible && !d->cursorItem)
- flags |= QLineControl::DrawCursor;
- if (d->control->hasSelectedText())
- flags |= QLineControl::DrawSelections;
- QPoint offset = QPoint(0,0);
- QFontMetrics fm = QFontMetrics(d->font);
- int cix = qRound(d->control->cursorToX());
- QRect br(boundingRect().toRect());
+ Q_Q(QDeclarativeTextInput);
+ QFontMetrics fm = QFontMetrics(font);
+ int cix = qRound(control->cursorToX());
+ QRect br(q->boundingRect().toRect());
//###Is this using bearing appropriately?
int minLB = qMax(0, -fm.minLeftBearing());
int minRB = qMax(0, -fm.minRightBearing());
- int widthUsed = qRound(d->control->naturalTextWidth()) + 1 + minRB;
- if (d->autoScroll) {
+ int widthUsed = qRound(control->naturalTextWidth()) + 1 + minRB;
+ if (autoScroll) {
if ((minLB + widthUsed) <= br.width()) {
// text fits in br; use hscroll for alignment
- switch (d->hAlign & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) {
+ switch (hAlign & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) {
case Qt::AlignRight:
- d->hscroll = widthUsed - br.width() + 1;
+ hscroll = widthUsed - br.width() + 1;
break;
case Qt::AlignHCenter:
- d->hscroll = (widthUsed - br.width()) / 2;
+ hscroll = (widthUsed - br.width()) / 2;
break;
default:
// Left
- d->hscroll = 0;
+ hscroll = 0;
break;
}
- d->hscroll -= minLB;
- } else if (cix - d->hscroll >= br.width()) {
+ hscroll -= minLB;
+ } else if (cix - hscroll >= br.width()) {
// text doesn't fit, cursor is to the right of br (scroll right)
- d->hscroll = cix - br.width() + 1;
- } else if (cix - d->hscroll < 0 && d->hscroll < widthUsed) {
+ hscroll = cix - br.width() + 1;
+ } else if (cix - hscroll < 0 && hscroll < widthUsed) {
// text doesn't fit, cursor is to the left of br (scroll left)
- d->hscroll = cix;
- } else if (widthUsed - d->hscroll < br.width()) {
+ hscroll = cix;
+ } else if (widthUsed - hscroll < br.width()) {
// text doesn't fit, text document is to the left of br; align
// right
- d->hscroll = widthUsed - br.width() + 1;
+ hscroll = widthUsed - br.width() + 1;
+ }
+ } else {
+ if(hAlign == QDeclarativeTextInput::AlignRight){
+ hscroll = q->width() - widthUsed;
+ }else if(hAlign == QDeclarativeTextInput::AlignHCenter){
+ hscroll = (q->width() - widthUsed) / 2;
+ } else {
+ hscroll = 0;
}
+ hscroll -= minLB;
+ }
+}
+
+void QDeclarativeTextInput::drawContents(QPainter *p, const QRect &r)
+{
+ Q_D(QDeclarativeTextInput);
+ p->setRenderHint(QPainter::TextAntialiasing, true);
+ p->save();
+ p->setPen(QPen(d->color));
+ int flags = QLineControl::DrawText;
+ if(!isReadOnly() && d->cursorVisible && !d->cursorItem)
+ flags |= QLineControl::DrawCursor;
+ if (d->control->hasSelectedText())
+ flags |= QLineControl::DrawSelections;
+ QPoint offset = QPoint(0,0);
+ QFontMetrics fm = QFontMetrics(d->font);
+ QRect br(boundingRect().toRect());
+ if (d->autoScroll) {
// the y offset is there to keep the baseline constant in case we have script changes in the text.
offset = br.topLeft() - QPoint(d->hscroll, d->control->ascent() - fm.ascent());
} else {
- if(d->hAlign == AlignRight){
- d->hscroll = width() - widthUsed;
- }else if(d->hAlign == AlignHCenter){
- d->hscroll = (width() - widthUsed) / 2;
- }
- d->hscroll -= minLB;
offset = QPoint(d->hscroll, 0);
}
d->control->draw(p, offset, r, flags);
@@ -1230,6 +1252,7 @@ void QDeclarativeTextInput::moveCursorSelection(int position)
{
Q_D(QDeclarativeTextInput);
d->control->moveCursor(position, true);
+ d->updateHorizontalScroll();
}
/*!
@@ -1420,6 +1443,7 @@ void QDeclarativeTextInput::selectionChanged()
void QDeclarativeTextInput::q_textChanged()
{
Q_D(QDeclarativeTextInput);
+ d->updateHorizontalScroll();
updateSize();
emit textChanged();
if(hasAcceptableInput() != d->oldValidity){
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
index c539bd3..03f55ae 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
@@ -112,7 +112,7 @@ public:
//Auxilliary functions needed to control the TextInput from QML
Q_INVOKABLE int positionAt(int x) const;
- Q_INVOKABLE QRectF positionToRectangle(int x) const;
+ Q_INVOKABLE QRectF positionToRectangle(int pos) const;
Q_INVOKABLE void moveCursorSelection(int pos);
Q_INVOKABLE void openSoftwareInputPanel();
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
index 6865147..8b74bcc 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p_p.h
@@ -99,6 +99,7 @@ public:
void init();
void startCreatingCursor();
void focusChanged(bool hasFocus);
+ void updateHorizontalScroll();
QLineControl* control;
diff --git a/src/declarative/qml/qdeclarativecompiledbindings.cpp b/src/declarative/qml/qdeclarativecompiledbindings.cpp
index ad05e80..507e47b 100644
--- a/src/declarative/qml/qdeclarativecompiledbindings.cpp
+++ b/src/declarative/qml/qdeclarativecompiledbindings.cpp
@@ -64,7 +64,7 @@ DEFINE_BOOL_CONFIG_OPTION(bindingsDump, QML_BINDINGS_DUMP);
Q_GLOBAL_STATIC(QDeclarativeFastProperties, fastProperties);
-#ifdef __GNUC__
+#if defined(Q_CC_GNU) && (!defined(Q_CC_INTEL) || __INTEL_COMPILER >= 1200)
# define QML_THREADED_INTERPRETER
#endif
diff --git a/src/declarative/qml/qdeclarativecomponent.cpp b/src/declarative/qml/qdeclarativecomponent.cpp
index 55ee783..b4919ff 100644
--- a/src/declarative/qml/qdeclarativecomponent.cpp
+++ b/src/declarative/qml/qdeclarativecomponent.cpp
@@ -60,7 +60,6 @@
#include <QFileInfo>
#include <QtCore/qdebug.h>
#include <QApplication>
-#include <QGraphicsObject>
QT_BEGIN_NAMESPACE
@@ -579,20 +578,26 @@ QScriptValue QDeclarativeComponent::createObject(QObject* parent)
if (!ret)
return QScriptValue(QScriptValue::NullValue);
- QGraphicsObject* gobj = qobject_cast<QGraphicsObject*>(ret);
- bool needParent = (gobj != 0);
- if(parent){
+
+ if (parent) {
ret->setParent(parent);
- if (gobj) {
- QGraphicsObject* gparent = qobject_cast<QGraphicsObject*>(parent);
- if(gparent){
- gobj->setParentItem(gparent);
+ QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions();
+
+ bool needParent = false;
+
+ for (int ii = 0; ii < functions.count(); ++ii) {
+ QDeclarativePrivate::AutoParentResult res = functions.at(ii)(ret, parent);
+ if (res == QDeclarativePrivate::Parented) {
needParent = false;
+ break;
+ } else if (res == QDeclarativePrivate::IncompatibleParent) {
+ needParent = true;
}
}
+
+ if (needParent)
+ qWarning("QDeclarativeComponent: Created graphical object was not placed in the graphics scene.");
}
- if(needParent)
- qWarning("QDeclarativeComponent: Created graphical object was not placed in the graphics scene.");
QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(d->engine);
QDeclarativeData::get(ret, true)->setImplicitDestructible();
diff --git a/src/declarative/qml/qdeclarativeengine.cpp b/src/declarative/qml/qdeclarativeengine.cpp
index 0715624..5c4d229 100644
--- a/src/declarative/qml/qdeclarativeengine.cpp
+++ b/src/declarative/qml/qdeclarativeengine.cpp
@@ -93,7 +93,6 @@
#include <QtGui/qcolor.h>
#include <QtGui/qvector3d.h>
#include <QtGui/qsound.h>
-#include <QGraphicsObject>
#include <QtCore/qcryptographichash.h>
#include <private/qobject_p.h>
@@ -1195,10 +1194,12 @@ QScriptValue QDeclarativeEnginePrivate::createQmlObject(QScriptContext *ctxt, QS
Q_ASSERT(obj);
obj->setParent(parentArg);
- QGraphicsObject* gobj = qobject_cast<QGraphicsObject*>(obj);
- QGraphicsObject* gparent = qobject_cast<QGraphicsObject*>(parentArg);
- if(gobj && gparent)
- gobj->setParentItem(gparent);
+
+ QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions();
+ for (int ii = 0; ii < functions.count(); ++ii) {
+ if (QDeclarativePrivate::Parented == functions.at(ii)(obj, parentArg))
+ break;
+ }
QDeclarativeData::get(obj, true)->setImplicitDestructible();
return activeEnginePriv->objectClass->newQObject(obj, QMetaType::QObjectStar);
diff --git a/src/declarative/qml/qdeclarativemetatype.cpp b/src/declarative/qml/qdeclarativemetatype.cpp
index 5fcb7ee..c32cab6 100644
--- a/src/declarative/qml/qdeclarativemetatype.cpp
+++ b/src/declarative/qml/qdeclarativemetatype.cpp
@@ -112,6 +112,8 @@ struct QDeclarativeMetaTypeData
QBitArray objects;
QBitArray interfaces;
QBitArray lists;
+
+ QList<QDeclarativePrivate::AutoParentFunction> parentFunctions;
};
Q_GLOBAL_STATIC(QDeclarativeMetaTypeData, metaTypeData)
Q_GLOBAL_STATIC(QReadWriteLock, metaTypeDataLock)
@@ -483,6 +485,16 @@ int QDeclarativeType::index() const
return d->m_index;
}
+int QDeclarativePrivate::registerAutoParentFunction(AutoParentFunction function)
+{
+ QWriteLocker lock(metaTypeDataLock());
+ QDeclarativeMetaTypeData *data = metaTypeData();
+
+ data->parentFunctions.append(function);
+
+ return data->parentFunctions.count() - 1;
+}
+
int QDeclarativePrivate::registerType(const QDeclarativePrivate::RegisterInterface &interface)
{
if (interface.version > 0)
@@ -583,6 +595,13 @@ bool QDeclarativeMetaType::isModule(const QByteArray &module, int versionMajor,
((*it).vmajor_min == versionMajor && (*it).vminor_min <= versionMinor))));
}
+QList<QDeclarativePrivate::AutoParentFunction> QDeclarativeMetaType::parentFunctions()
+{
+ QReadLocker lock(metaTypeDataLock());
+ QDeclarativeMetaTypeData *data = metaTypeData();
+ return data->parentFunctions;
+}
+
QObject *QDeclarativeMetaType::toQObject(const QVariant &v, bool *ok)
{
if (!isQObject(v.userType())) {
diff --git a/src/declarative/qml/qdeclarativemetatype_p.h b/src/declarative/qml/qdeclarativemetatype_p.h
index bf6a700..4c98b6f 100644
--- a/src/declarative/qml/qdeclarativemetatype_p.h
+++ b/src/declarative/qml/qdeclarativemetatype_p.h
@@ -99,6 +99,8 @@ public:
static StringConverter customStringConverter(int);
static bool isModule(const QByteArray &module, int versionMajor, int versionMinor);
+
+ static QList<QDeclarativePrivate::AutoParentFunction> parentFunctions();
};
class QDeclarativeTypePrivate;
diff --git a/src/declarative/qml/qdeclarativeprivate.h b/src/declarative/qml/qdeclarativeprivate.h
index e657dd5..cd859fe 100644
--- a/src/declarative/qml/qdeclarativeprivate.h
+++ b/src/declarative/qml/qdeclarativeprivate.h
@@ -214,6 +214,10 @@ namespace QDeclarativePrivate
const char *iid;
};
+ enum AutoParentResult { Parented, IncompatibleObject, IncompatibleParent };
+ typedef AutoParentResult (*AutoParentFunction)(QObject *object, QObject *parent);
+
+ int Q_DECLARATIVE_EXPORT registerAutoParentFunction(AutoParentFunction);
int Q_DECLARATIVE_EXPORT registerType(const RegisterType &);
int Q_DECLARATIVE_EXPORT registerType(const RegisterInterface &);
diff --git a/src/declarative/util/qdeclarativeanimation.cpp b/src/declarative/util/qdeclarativeanimation.cpp
index 25cf133..f807866 100644
--- a/src/declarative/util/qdeclarativeanimation.cpp
+++ b/src/declarative/util/qdeclarativeanimation.cpp
@@ -1344,24 +1344,14 @@ void QDeclarativeRotationAnimation::setTo(qreal t)
Possible values are:
- \table
- \row
- \o RotationAnimation.Numerical
- \o Rotate by linearly interpolating between the two numbers.
+ \list
+ \o RotationAnimation.Numerical (default) - Rotate by linearly interpolating between the two numbers.
A rotation from 10 to 350 will rotate 340 degrees clockwise.
- \row
- \o RotationAnimation.Clockwise
- \o Rotate clockwise between the two values
- \row
- \o RotationAnimation.Counterclockwise
- \o Rotate counterclockwise between the two values
- \row
- \o RotationAnimation.Shortest
- \o Rotate in the direction that produces the shortest animation path.
+ \o RotationAnimation.Clockwise - Rotate clockwise between the two values
+ \o RotationAnimation.Counterclockwise - Rotate counterclockwise between the two values
+ \o RotationAnimation.Shortest - Rotate in the direction that produces the shortest animation path.
A rotation from 10 to 350 will rotate 20 degrees counterclockwise.
- \endtable
-
- The default direction is RotationAnimation.Numerical.
+ \endlist
*/
QDeclarativeRotationAnimation::RotationDirection QDeclarativeRotationAnimation::direction() const
{
@@ -1747,7 +1737,7 @@ void QDeclarativePropertyAnimation::setFrom(const QVariant &f)
/*!
\qmlproperty real PropertyAnimation::to
This property holds the ending value.
- If not set, then the value defined in the end state of the transition or Behavior.
+ If not set, then the value defined in the end state of the transition or \l Behavior.
*/
QVariant QDeclarativePropertyAnimation::to() const
{
diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index 4adef25..bfd25be 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -148,6 +148,7 @@ public:
QDeclarativeXmlQuery(QObject *parent=0)
: QThread(parent), m_quit(false), m_abortQueryId(-1), m_queryIds(XMLLISTMODEL_CLEAR_ID + 1) {
qRegisterMetaType<QDeclarativeXmlQueryResult>("QDeclarativeXmlQueryResult");
+ m_currentJob.queryId = -1;
}
~QDeclarativeXmlQuery() {
@@ -161,6 +162,13 @@ public:
void abort(int id) {
QMutexLocker locker(&m_mutex);
+ QQueue<XmlQueryJob>::iterator it;
+ for (it = m_jobs.begin(); it != m_jobs.end(); ++it) {
+ if ((*it).queryId == id) {
+ m_jobs.erase(it);
+ return;
+ }
+ }
m_abortQueryId = id;
}
@@ -188,7 +196,7 @@ public:
m_queryIds++;
if (!isRunning())
- start();
+ start(QThread::IdlePriority);
else
m_condition.wakeOne();
return job.queryId;
@@ -202,24 +210,28 @@ protected:
void run() {
while (!m_quit) {
m_mutex.lock();
- doQueryJob();
- doSubQueryJob();
+ if (!m_jobs.isEmpty())
+ m_currentJob = m_jobs.dequeue();
m_mutex.unlock();
- m_mutex.lock();
- const XmlQueryJob &job = m_jobs.dequeue();
- if (m_abortQueryId != job.queryId) {
- QDeclarativeXmlQueryResult r;
- r.queryId = job.queryId;
+ QDeclarativeXmlQueryResult r;
+ if (m_currentJob.queryId != -1) {
+ doQueryJob();
+ doSubQueryJob();
+ r.queryId = m_currentJob.queryId;
r.size = m_size;
r.data = m_modelData;
r.inserted = m_insertedItemRanges;
r.removed = m_removedItemRanges;
- r.keyRoleResultsCache = job.keyRoleResultsCache;
- emit queryCompleted(r);
+ r.keyRoleResultsCache = m_currentJob.keyRoleResultsCache;
}
+
+ m_mutex.lock();
+ if (m_currentJob.queryId != -1 && m_abortQueryId != m_currentJob.queryId)
+ emit queryCompleted(r);
if (m_jobs.isEmpty())
m_condition.wait(&m_mutex);
+ m_currentJob.queryId = -1;
m_abortQueryId = -1;
m_mutex.unlock();
}
@@ -235,6 +247,7 @@ private:
QMutex m_mutex;
QWaitCondition m_condition;
QQueue<XmlQueryJob> m_jobs;
+ XmlQueryJob m_currentJob;
bool m_quit;
int m_abortQueryId;
QString m_prefix;
@@ -249,15 +262,14 @@ Q_GLOBAL_STATIC(QDeclarativeXmlQuery, globalXmlQuery)
void QDeclarativeXmlQuery::doQueryJob()
{
- Q_ASSERT(!m_jobs.isEmpty());
- XmlQueryJob &job = m_jobs.head();
+ Q_ASSERT(m_currentJob.queryId != -1);
QString r;
QXmlQuery query;
- QBuffer buffer(&job.data);
+ QBuffer buffer(&m_currentJob.data);
buffer.open(QIODevice::ReadOnly);
query.bindVariable(QLatin1String("src"), &buffer);
- query.setQuery(job.namespaces + job.query);
+ query.setQuery(m_currentJob.namespaces + m_currentJob.query);
query.evaluateTo(&r);
//always need a single root element
@@ -265,9 +277,9 @@ void QDeclarativeXmlQuery::doQueryJob()
QBuffer b(&xml);
b.open(QIODevice::ReadOnly);
- QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + job.namespaces;
+ QString namespaces = QLatin1String("declare namespace dummy=\"http://qtsotware.com/dummy\";\n") + m_currentJob.namespaces;
QString prefix = QLatin1String("doc($inputDocument)/dummy:items") +
- job.query.mid(job.query.lastIndexOf(QLatin1Char('/')));
+ m_currentJob.query.mid(m_currentJob.query.lastIndexOf(QLatin1Char('/')));
//figure out how many items we are dealing with
int count = -1;
@@ -282,7 +294,7 @@ void QDeclarativeXmlQuery::doQueryJob()
count = item.toAtomicValue().toInt();
}
- job.data = xml;
+ m_currentJob.data = xml;
m_prefix = namespaces + prefix + QLatin1Char('/');
m_size = 0;
if (count > 0)
@@ -291,9 +303,9 @@ void QDeclarativeXmlQuery::doQueryJob()
void QDeclarativeXmlQuery::getValuesOfKeyRoles(QStringList *values, QXmlQuery *query) const
{
- Q_ASSERT(!m_jobs.isEmpty());
+ Q_ASSERT(m_currentJob.queryId != -1);
- const QStringList &keysQueries = m_jobs.head().keyRoleQueries;
+ const QStringList &keysQueries = m_currentJob.keyRoleQueries;
QString keysQuery;
if (keysQueries.count() == 1)
keysQuery = m_prefix + keysQueries[0];
@@ -323,11 +335,10 @@ void QDeclarativeXmlQuery::addIndexToRangeList(QList<QDeclarativeXmlListRange> *
void QDeclarativeXmlQuery::doSubQueryJob()
{
- Q_ASSERT(!m_jobs.isEmpty());
- XmlQueryJob &job = m_jobs.head();
+ Q_ASSERT(m_currentJob.queryId != -1);
m_modelData.clear();
- QBuffer b(&job.data);
+ QBuffer b(&m_currentJob.data);
b.open(QIODevice::ReadOnly);
QXmlQuery subquery;
@@ -340,16 +351,16 @@ void QDeclarativeXmlQuery::doSubQueryJob()
m_insertedItemRanges.clear();
m_removedItemRanges.clear();
- if (job.keyRoleResultsCache.isEmpty()) {
+ if (m_currentJob.keyRoleResultsCache.isEmpty()) {
m_insertedItemRanges << qMakePair(0, m_size);
} else {
- if (keyRoleResults != job.keyRoleResultsCache) {
+ if (keyRoleResults != m_currentJob.keyRoleResultsCache) {
QStringList temp;
- for (int i=0; i<job.keyRoleResultsCache.count(); i++) {
- if (!keyRoleResults.contains(job.keyRoleResultsCache[i]))
+ for (int i=0; i<m_currentJob.keyRoleResultsCache.count(); i++) {
+ if (!keyRoleResults.contains(m_currentJob.keyRoleResultsCache[i]))
addIndexToRangeList(&m_removedItemRanges, i);
else
- temp << job.keyRoleResultsCache[i];
+ temp << m_currentJob.keyRoleResultsCache[i];
}
for (int i=0; i<keyRoleResults.count(); i++) {
@@ -360,11 +371,11 @@ void QDeclarativeXmlQuery::doSubQueryJob()
}
}
}
- job.keyRoleResultsCache = keyRoleResults;
+ m_currentJob.keyRoleResultsCache = keyRoleResults;
// Get the new values for each role.
//### we might be able to condense even further (query for everything in one go)
- const QStringList &queries = job.roleQueries;
+ const QStringList &queries = m_currentJob.roleQueries;
for (int i = 0; i < queries.size(); ++i) {
QList<QVariant> resultList;
if (!queries[i].isEmpty()) {
@@ -378,7 +389,7 @@ void QDeclarativeXmlQuery::doSubQueryJob()
item = resultItems.next();
}
} else {
- emit error(job.roleQueryErrorId.at(i), queries[i]);
+ emit error(m_currentJob.roleQueryErrorId.at(i), queries[i]);
}
}
//### should warn here if things have gone wrong.
diff --git a/src/gui/graphicsview/qgraphicsgridlayout.cpp b/src/gui/graphicsview/qgraphicsgridlayout.cpp
index 6ca799d..83db3ec 100644
--- a/src/gui/graphicsview/qgraphicsgridlayout.cpp
+++ b/src/gui/graphicsview/qgraphicsgridlayout.cpp
@@ -572,6 +572,18 @@ void QGraphicsGridLayout::removeAt(int index)
if (QGraphicsLayoutItem *layoutItem = gridItem->layoutItem())
layoutItem->setParentLayoutItem(0);
d->engine.removeItem(gridItem);
+
+ // recalculate rowInfo.count if we remove an item that is on the right/bottommost row
+ for (int j = 0; j < NOrientations; ++j) {
+ // 0: Hor, 1: Ver
+ const Qt::Orientation orient = (j == 0 ? Qt::Horizontal : Qt::Vertical);
+ const int oldCount = d->engine.rowCount(orient);
+ if (gridItem->lastRow(orient) == oldCount - 1) {
+ const int newCount = d->engine.effectiveLastRow(orient) + 1;
+ d->engine.removeRows(newCount, oldCount - newCount, orient);
+ }
+ }
+
delete gridItem;
invalidate();
}
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 8042c46..c9176d1 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -3277,7 +3277,8 @@ void QGraphicsItemPrivate::setFocusHelper(Qt::FocusReason focusReason, bool clim
*/
void QGraphicsItem::clearFocus()
{
- d_ptr->clearFocusHelper(/* giveFocusToParent = */ true);
+ if (hasFocus())
+ d_ptr->clearFocusHelper(/* giveFocusToParent = */ true);
}
/*!
diff --git a/src/gui/graphicsview/qgraphicslinearlayout.cpp b/src/gui/graphicsview/qgraphicslinearlayout.cpp
index 9722683..b828722 100644
--- a/src/gui/graphicsview/qgraphicslinearlayout.cpp
+++ b/src/gui/graphicsview/qgraphicslinearlayout.cpp
@@ -147,7 +147,7 @@ void QGraphicsLinearLayoutPrivate::removeGridItem(QGridLayoutItem *gridItem)
{
int index = gridItem->firstRow(orientation);
engine.removeItem(gridItem);
- engine.removeRow(index, orientation);
+ engine.removeRows(index, 1, orientation);
}
void QGraphicsLinearLayoutPrivate::fixIndex(int *index) const
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index 6c5623e..ca3b56f 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -6277,7 +6277,8 @@ void QGraphicsScenePrivate::cancelGesturesForChildren(QGesture *original)
{
Q_ASSERT(original);
QGraphicsItem *originalItem = gestureTargets.value(original);
- Q_ASSERT(originalItem);
+ if (originalItem == 0) // we only act on accepted gestures, which implies it has a target.
+ return;
// iterate over all active gestures and for each find the owner
// if the owner is part of our sub-hierarchy, cancel it.
diff --git a/src/gui/graphicsview/qgridlayoutengine_p.h b/src/gui/graphicsview/qgridlayoutengine_p.h
index cbf704e..9ac9a8e 100644
--- a/src/gui/graphicsview/qgridlayoutengine_p.h
+++ b/src/gui/graphicsview/qgridlayoutengine_p.h
@@ -363,8 +363,8 @@ public:
QGridLayoutItem *itemAt(int row, int column, Qt::Orientation orientation = Qt::Vertical) const;
inline void insertRow(int row, Qt::Orientation orientation = Qt::Vertical)
{ insertOrRemoveRows(row, +1, orientation); }
- inline void removeRow(int row, Qt::Orientation orientation = Qt::Vertical)
- { insertOrRemoveRows(row, -1, orientation); }
+ inline void removeRows(int row, int count, Qt::Orientation orientation)
+ { insertOrRemoveRows(row, -count, orientation); }
void invalidate();
void setGeometries(const QLayoutStyleInfo &styleInfo, const QRectF &contentsGeometry);
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index adc2632..bb8a994 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -2274,6 +2274,8 @@ bool QImage::create(const QSize& size, int depth, int numColors, QImage::Endian
typedef void (*Image_Converter)(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags);
+typedef bool (*InPlace_Image_Converter)(QImageData *data, Qt::ImageConversionFlags);
+
static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
Q_ASSERT(src->format == QImage::Format_ARGB32);
@@ -2298,6 +2300,169 @@ static void convert_ARGB_to_ARGB_PM(QImageData *dest, const QImageData *src, Qt:
}
}
+static bool convert_ARGB_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_ARGB32);
+
+ const int pad = (data->bytes_per_line >> 2) - data->width;
+ QRgb *rgb_data = (QRgb *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ const QRgb *end = rgb_data + data->width;
+ while (rgb_data < end) {
+ *rgb_data = PREMUL(*rgb_data);
+ ++rgb_data;
+ }
+ rgb_data += pad;
+ }
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ return true;
+}
+
+static bool convert_indexed8_to_ARGB_PM_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_Indexed8);
+ const int depth = 32;
+
+ const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const int nbytes = dst_bytes_per_line * data->height;
+ uchar *const newData = (uchar *)realloc(data->data, nbytes);
+ if (!newData)
+ return false;
+
+ data->data = newData;
+
+ // start converting from the end because the end image is bigger than the source
+ uchar *src_data = newData + data->nbytes; // end of src
+ quint32 *dest_data = (quint32 *) (newData + nbytes); // end of dest > end of src
+ const int width = data->width;
+ const int src_pad = data->bytes_per_line - width;
+ const int dest_pad = (dst_bytes_per_line >> 2) - width;
+
+ for (int i = 0; i < data->height; ++i) {
+ src_data -= src_pad;
+ dest_data -= dest_pad;
+ for (int pixI = 0; pixI < width; ++pixI) {
+ --src_data;
+ --dest_data;
+ const uint pixel = data->colortable[*src_data];
+ *dest_data = (quint32) PREMUL(pixel);
+ }
+ }
+
+ data->format = QImage::Format_ARGB32_Premultiplied;
+ data->bytes_per_line = dst_bytes_per_line;
+ data->depth = depth;
+ data->nbytes = nbytes;
+
+ return true;
+}
+
+static bool convert_indexed8_to_RGB_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_Indexed8);
+ const int depth = 32;
+
+ const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const int nbytes = dst_bytes_per_line * data->height;
+ uchar *const newData = (uchar *)realloc(data->data, nbytes);
+ if (!newData)
+ return false;
+
+ data->data = newData;
+
+ // start converting from the end because the end image is bigger than the source
+ uchar *src_data = newData + data->nbytes;
+ quint32 *dest_data = (quint32 *) (newData + nbytes);
+ const int width = data->width;
+ const int src_pad = data->bytes_per_line - width;
+ const int dest_pad = (dst_bytes_per_line >> 2) - width;
+
+ for (int i = 0; i < data->height; ++i) {
+ src_data -= src_pad;
+ dest_data -= dest_pad;
+ for (int pixI = 0; pixI < width; ++pixI) {
+ --src_data;
+ --dest_data;
+ *dest_data = (quint32) data->colortable[*src_data];
+ }
+ }
+
+ data->format = QImage::Format_RGB32;
+ data->bytes_per_line = dst_bytes_per_line;
+ data->depth = depth;
+ data->nbytes = nbytes;
+
+ return true;
+}
+
+static bool convert_indexed8_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_Indexed8);
+ const int depth = 16;
+
+ const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const int nbytes = dst_bytes_per_line * data->height;
+ uchar *const newData = (uchar *)realloc(data->data, nbytes);
+ if (!newData)
+ return false;
+
+ data->data = newData;
+
+ // start converting from the end because the end image is bigger than the source
+ uchar *src_data = newData + data->nbytes;
+ quint16 *dest_data = (quint16 *) (newData + nbytes);
+ const int width = data->width;
+ const int src_pad = data->bytes_per_line - width;
+ const int dest_pad = (dst_bytes_per_line >> 1) - width;
+
+ for (int i = 0; i < data->height; ++i) {
+ src_data -= src_pad;
+ dest_data -= dest_pad;
+ for (int pixI = 0; pixI < width; ++pixI) {
+ --src_data;
+ --dest_data;
+ const uint pixel = data->colortable[*src_data];
+ *dest_data = qt_colorConvert<quint16, quint32>(pixel, 0);
+ }
+ }
+
+ data->format = QImage::Format_RGB16;
+ data->bytes_per_line = dst_bytes_per_line;
+ data->depth = depth;
+ data->nbytes = nbytes;
+
+ return true;
+}
+
+static bool convert_RGB_to_RGB16_inplace(QImageData *data, Qt::ImageConversionFlags)
+{
+ Q_ASSERT(data->format == QImage::Format_RGB32);
+ const int depth = 16;
+
+ const int dst_bytes_per_line = ((data->width * depth + 31) >> 5) << 2;
+ const int src_bytes_per_line = data->bytes_per_line;
+ quint32 *src_data = (quint32 *) data->data;
+ quint16 *dst_data = (quint16 *) data->data;
+
+ for (int i = 0; i < data->height; ++i) {
+ qt_memconvert(dst_data, src_data, data->width);
+ src_data = (quint32 *) (((char*)src_data) + src_bytes_per_line);
+ dst_data = (quint16 *) (((char*)dst_data) + dst_bytes_per_line);
+ }
+ data->format = QImage::Format_RGB16;
+ data->bytes_per_line = dst_bytes_per_line;
+ data->depth = depth;
+ data->nbytes = dst_bytes_per_line * data->height;
+ uchar *const newData = (uchar *)realloc(data->data, data->nbytes);
+ if (newData) {
+ data->data = newData;
+ return true;
+ } else {
+ return false;
+ }
+}
+
static void convert_ARGB_PM_to_ARGB(QImageData *dest, const QImageData *src, Qt::ImageConversionFlags)
{
Q_ASSERT(src->format == QImage::Format_ARGB32_Premultiplied);
@@ -3447,6 +3612,103 @@ static const Image_Converter converter_map[QImage::NImageFormats][QImage::NImage
} // Format_ARGB4444_Premultiplied
};
+static const InPlace_Image_Converter inplace_converter_map[QImage::NImageFormats][QImage::NImageFormats] =
+{
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ },
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_Mono
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_MonoLSB
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_indexed8_to_RGB_inplace,
+ convert_indexed8_to_ARGB_PM_inplace,
+ convert_indexed8_to_RGB16_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_Indexed8
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_RGB_to_RGB16_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_ARGB32
+ {
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ convert_ARGB_to_ARGB_PM_inplace,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ }, // Format_ARGB32
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_ARGB32_Premultiplied
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB16
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_ARGB8565_Premultiplied
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB666
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_ARGB6666_Premultiplied
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB555
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_ARGB8555_Premultiplied
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB888
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ }, // Format_RGB444
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ } // Format_ARGB4444_Premultiplied
+};
+
/*!
Returns a copy of the image in the given \a format.
@@ -6276,6 +6538,18 @@ QTransform QImage::trueMatrix(const QTransform &matrix, int w, int h)
return matrix * QTransform().translate(-delta.x(), -delta.y());
}
+bool QImageData::convertInPlace(QImage::Format newFormat, Qt::ImageConversionFlags flags)
+{
+ if (format == newFormat)
+ return true;
+
+ const InPlace_Image_Converter *const converterPtr = &inplace_converter_map[format][newFormat];
+ InPlace_Image_Converter converter = *converterPtr;
+ if (converter)
+ return converter(this, flags);
+ else
+ return false;
+}
/*!
\typedef QImage::DataPtr
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 0c19647..f1a0c47 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -96,6 +96,9 @@ struct Q_GUI_EXPORT QImageData { // internal image data
bool checkForAlphaPixels() const;
+ // Convert the image in-place, minimizing memory reallocation
+ // Return false if the conversion cannot be done in-place.
+ bool convertInPlace(QImage::Format newFormat, Qt::ImageConversionFlags);
#ifndef QT_NO_IMAGE_TEXT
QMap<QString, QString> text;
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 9dc15fc..13c03a1 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -47,6 +47,9 @@
#include "qbitmap.h"
#include "qimage.h"
+#include <QBuffer>
+#include <QImageReader>
+#include <private/qsimd_p.h>
#include <private/qwidget_p.h>
#include <private/qdrawhelper_p.h>
@@ -127,91 +130,26 @@ void QRasterPixmapData::resize(int width, int height)
setSerialNumber(image.serialNumber());
}
+bool QRasterPixmapData::fromData(const uchar *buffer, uint len, const char *format,
+ Qt::ImageConversionFlags flags)
+{
+ QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
+ QBuffer b(&a);
+ b.open(QIODevice::ReadOnly);
+ QImage image = QImageReader(&b, format).read();
+ if (image.isNull())
+ return false;
+
+ createPixmapForImage(image, flags, /* inplace = */true);
+ return !isNull();
+}
+
void QRasterPixmapData::fromImage(const QImage &sourceImage,
Qt::ImageConversionFlags flags)
{
Q_UNUSED(flags);
-
-#ifdef Q_WS_QWS
- QImage::Format format;
- if (pixelType() == BitmapType) {
- format = QImage::Format_Mono;
- } else {
- format = QScreen::instance()->pixelFormat();
- if (format == QImage::Format_Invalid)
- format = QImage::Format_ARGB32_Premultiplied;
- else if (format == QImage::Format_Indexed8) // currently not supported
- format = QImage::Format_RGB444;
- }
-
- if (sourceImage.hasAlphaChannel()
- && ((flags & Qt::NoOpaqueDetection)
- || const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels())) {
- switch (format) {
- case QImage::Format_RGB16:
- format = QImage::Format_ARGB8565_Premultiplied;
- break;
- case QImage::Format_RGB666:
- format = QImage::Format_ARGB6666_Premultiplied;
- break;
- case QImage::Format_RGB555:
- format = QImage::Format_ARGB8555_Premultiplied;
- break;
- case QImage::Format_RGB444:
- format = QImage::Format_ARGB4444_Premultiplied;
- break;
- default:
- format = QImage::Format_ARGB32_Premultiplied;
- break;
- }
- } else if (format == QImage::Format_Invalid) {
- format = QImage::Format_ARGB32_Premultiplied;
- }
-
- image = sourceImage.convertToFormat(format);
-#else
- if (pixelType() == BitmapType) {
- image = sourceImage.convertToFormat(QImage::Format_MonoLSB);
- } else {
- if (sourceImage.depth() == 1) {
- image = sourceImage.hasAlphaChannel()
- ? sourceImage.convertToFormat(QImage::Format_ARGB32_Premultiplied)
- : sourceImage.convertToFormat(QImage::Format_RGB32);
- } else {
-
- QImage::Format opaqueFormat = QNativeImage::systemFormat();
- QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
-
-#ifndef QT_HAVE_NEON
- switch (opaqueFormat) {
- case QImage::Format_RGB16:
- alphaFormat = QImage::Format_ARGB8565_Premultiplied;
- break;
- default: // We don't care about the others...
- break;
- }
-#endif
-
- if (!sourceImage.hasAlphaChannel()
- || ((flags & Qt::NoOpaqueDetection) == 0
- && !const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels())) {
- image = sourceImage.convertToFormat(opaqueFormat);
- } else {
- image = sourceImage.convertToFormat(alphaFormat);
- }
- }
- }
-#endif
- if (image.d) {
- w = image.d->width;
- h = image.d->height;
- d = image.d->depth;
- } else {
- w = h = d = 0;
- }
- is_null = (w <= 0 || h <= 0);
-
- setSerialNumber(image.serialNumber());
+ QImage image = sourceImage;
+ createPixmapForImage(image, flags, /* inplace = */false);
}
// from qwindowsurface.cpp
@@ -240,7 +178,7 @@ void QRasterPixmapData::fill(const QColor &color)
if (alpha != 255) {
if (!image.hasAlphaChannel()) {
QImage::Format toFormat;
-#ifndef QT_HAVE_NEON
+#if !(defined(QT_HAVE_NEON) || defined(QT_ALWAYS_HAVE_SSE2))
if (image.format() == QImage::Format_RGB16)
toFormat = QImage::Format_ARGB8565_Premultiplied;
else if (image.format() == QImage::Format_RGB666)
@@ -398,6 +336,105 @@ int QRasterPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
return 0;
}
+void QRasterPixmapData::createPixmapForImage(QImage &sourceImage, Qt::ImageConversionFlags flags, bool inPlace)
+{
+ QImage::Format format;
+#ifdef Q_WS_QWS
+ if (pixelType() == BitmapType) {
+ format = QImage::Format_Mono;
+ } else {
+ format = QScreen::instance()->pixelFormat();
+ if (format == QImage::Format_Invalid)
+ format = QImage::Format_ARGB32_Premultiplied;
+ else if (format == QImage::Format_Indexed8) // currently not supported
+ format = QImage::Format_RGB444;
+ }
+
+ if (sourceImage.hasAlphaChannel()
+ && ((flags & Qt::NoOpaqueDetection)
+ || const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels())) {
+ switch (format) {
+ case QImage::Format_RGB16:
+ format = QImage::Format_ARGB8565_Premultiplied;
+ break;
+ case QImage::Format_RGB666:
+ format = QImage::Format_ARGB6666_Premultiplied;
+ break;
+ case QImage::Format_RGB555:
+ format = QImage::Format_ARGB8555_Premultiplied;
+ break;
+ case QImage::Format_RGB444:
+ format = QImage::Format_ARGB4444_Premultiplied;
+ break;
+ default:
+ format = QImage::Format_ARGB32_Premultiplied;
+ break;
+ }
+ } else if (format == QImage::Format_Invalid) {
+ format = QImage::Format_ARGB32_Premultiplied;
+ }
+#else
+ if (pixelType() == BitmapType) {
+ format = QImage::Format_MonoLSB;
+ } else {
+ if (sourceImage.depth() == 1) {
+ format = sourceImage.hasAlphaChannel()
+ ? QImage::Format_ARGB32_Premultiplied
+ : QImage::Format_RGB32;
+ } else {
+ QImage::Format opaqueFormat = QNativeImage::systemFormat();
+ QImage::Format alphaFormat = QImage::Format_ARGB32_Premultiplied;
+
+#if !defined(QT_HAVE_NEON) && !defined(QT_ALWAYS_HAVE_SSE2)
+ switch (opaqueFormat) {
+ case QImage::Format_RGB16:
+ alphaFormat = QImage::Format_ARGB8565_Premultiplied;
+ break;
+ default: // We don't care about the others...
+ break;
+ }
+#endif
+
+ if (!sourceImage.hasAlphaChannel()) {
+ format = opaqueFormat;
+ } else if ((flags & Qt::NoOpaqueDetection) == 0
+ && !const_cast<QImage &>(sourceImage).data_ptr()->checkForAlphaPixels())
+ {
+ // image has alpha format but is really opaque, so try to do a
+ // more efficient conversion
+ if (sourceImage.format() == QImage::Format_ARGB32
+ || sourceImage.format() == QImage::Format_ARGB32_Premultiplied)
+ {
+ if (!inPlace)
+ sourceImage.detach();
+ sourceImage.d->format = QImage::Format_RGB32;
+ }
+ format = opaqueFormat;
+ } else {
+ format = alphaFormat;
+ }
+ }
+ }
+#endif
+
+ if (inPlace && sourceImage.d->convertInPlace(format, flags)) {
+ image = sourceImage;
+ } else {
+ image = sourceImage.convertToFormat(format);
+ }
+
+ if (image.d) {
+ w = image.d->width;
+ h = image.d->height;
+ d = image.d->depth;
+ } else {
+ w = h = d = 0;
+ }
+ is_null = (w <= 0 || h <= 0);
+
+ setSerialNumber(image.serialNumber());
+}
+
QImage* QRasterPixmapData::buffer()
{
return &image;
diff --git a/src/gui/image/qpixmap_raster_p.h b/src/gui/image/qpixmap_raster_p.h
index 6cdd3d7..d7e3f85 100644
--- a/src/gui/image/qpixmap_raster_p.h
+++ b/src/gui/image/qpixmap_raster_p.h
@@ -72,6 +72,7 @@ public:
void resize(int width, int height);
void fromFile(const QString &filename, Qt::ImageConversionFlags flags);
+ bool fromData(const uchar *buffer, uint len, const char *format, Qt::ImageConversionFlags flags);
void fromImage(const QImage &image, Qt::ImageConversionFlags flags);
bool scroll(int dx, int dy, const QRect &rect);
@@ -85,6 +86,8 @@ public:
protected:
int metric(QPaintDevice::PaintDeviceMetric metric) const;
+ void createPixmapForImage(QImage &sourceImage, Qt::ImageConversionFlags flags, bool inPlace);
+ void setImage(const QImage &image);
QImage image;
private:
diff --git a/src/gui/image/qpixmapdata.cpp b/src/gui/image/qpixmapdata.cpp
index ea4fe6b..31ca909 100644
--- a/src/gui/image/qpixmapdata.cpp
+++ b/src/gui/image/qpixmapdata.cpp
@@ -146,7 +146,7 @@ bool QPixmapData::fromData(const uchar *buf, uint len, const char *format, Qt::I
void QPixmapData::copy(const QPixmapData *data, const QRect &rect)
{
- fromImage(data->toImage().copy(rect), Qt::AutoColor);
+ fromImage(data->toImage().copy(rect), Qt::NoOpaqueDetection);
}
bool QPixmapData::scroll(int dx, int dy, const QRect &rect)
diff --git a/src/gui/itemviews/qabstractitemdelegate.cpp b/src/gui/itemviews/qabstractitemdelegate.cpp
index 775bf7d..0ea6d67 100644
--- a/src/gui/itemviews/qabstractitemdelegate.cpp
+++ b/src/gui/itemviews/qabstractitemdelegate.cpp
@@ -291,8 +291,14 @@ void QAbstractItemDelegate::updateEditorGeometry(QWidget *,
}
/*!
- Whenever an event occurs, this function is called with the \a event
- \a model \a option and the \a index that corresponds to the item being edited.
+ When editing of an item starts, this function is called with the
+ \a event that triggered the editing, the \a model, the \a index of
+ the item, and the \a option used for rendering the item.
+
+ Mouse events are sent to editorEvent() even if they don't start
+ editing of the item. This can, for instance, be useful if you wish
+ to open a context menu when the right mouse button is pressed on
+ an item.
The base implementation returns false (indicating that it has not
handled the event).
diff --git a/src/gui/painting/qoutlinemapper.cpp b/src/gui/painting/qoutlinemapper.cpp
index 1b01960..bf03545 100644
--- a/src/gui/painting/qoutlinemapper.cpp
+++ b/src/gui/painting/qoutlinemapper.cpp
@@ -234,12 +234,12 @@ void QOutlineMapper::endOutline()
// Check for out of dev bounds...
- const bool do_clip = (controlPointRect.left() < -QT_RASTER_COORD_LIMIT
+ const bool do_clip = !m_in_clip_elements && ((controlPointRect.left() < -QT_RASTER_COORD_LIMIT
|| controlPointRect.right() > QT_RASTER_COORD_LIMIT
|| controlPointRect.top() < -QT_RASTER_COORD_LIMIT
|| controlPointRect.bottom() > QT_RASTER_COORD_LIMIT
|| controlPointRect.width() > QT_RASTER_COORD_LIMIT
- || controlPointRect.height() > QT_RASTER_COORD_LIMIT);
+ || controlPointRect.height() > QT_RASTER_COORD_LIMIT));
if (do_clip) {
clipElements(elements, elementTypes(), element_count);
@@ -353,7 +353,13 @@ void QOutlineMapper::clipElements(const QPointF *elements,
// instead of going through convenience functionallity, but since
// this part of code hardly every used, it shouldn't matter.
+ m_in_clip_elements = true;
+
QPainterPath path;
+
+ if (!(m_outline.flags & QT_FT_OUTLINE_EVEN_ODD_FILL))
+ path.setFillRule(Qt::WindingFill);
+
if (types) {
for (int i=0; i<element_count; ++i) {
switch (types[i]) {
@@ -389,6 +395,8 @@ void QOutlineMapper::clipElements(const QPointF *elements,
else
convertPath(clippedPath);
m_txop = old_txop;
+
+ m_in_clip_elements = false;
}
QT_END_NAMESPACE
diff --git a/src/gui/painting/qoutlinemapper_p.h b/src/gui/painting/qoutlinemapper_p.h
index 39b7593..f64d03b 100644
--- a/src/gui/painting/qoutlinemapper_p.h
+++ b/src/gui/painting/qoutlinemapper_p.h
@@ -95,7 +95,8 @@ public:
m_tags(0),
m_contours(0),
m_polygon_dev(0),
- m_round_coords(false)
+ m_round_coords(false),
+ m_in_clip_elements(false)
{
}
@@ -235,6 +236,7 @@ public:
qreal m_dy;
bool m_valid;
+ bool m_in_clip_elements;
private:
bool m_round_coords;
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index f10f12f..a212718 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -459,13 +459,12 @@ bool QRasterPaintEngine::begin(QPaintDevice *device)
QRasterPaintEngineState *s = state();
ensureOutlineMapper();
- d->outlineMapper->m_clip_rect = d->deviceRect.adjusted(-10, -10, 10, 10);
-
- // This is the upp
- QRect bounds(-QT_RASTER_COORD_LIMIT, -QT_RASTER_COORD_LIMIT,
- QT_RASTER_COORD_LIMIT*2 - 1, QT_RASTER_COORD_LIMIT * 2 - 1);
- d->outlineMapper->m_clip_rect = bounds.intersected(d->outlineMapper->m_clip_rect);
+ d->outlineMapper->m_clip_rect = d->deviceRect;
+ if (d->outlineMapper->m_clip_rect.width() > QT_RASTER_COORD_LIMIT)
+ d->outlineMapper->m_clip_rect.setWidth(QT_RASTER_COORD_LIMIT);
+ if (d->outlineMapper->m_clip_rect.height() > QT_RASTER_COORD_LIMIT)
+ d->outlineMapper->m_clip_rect.setHeight(QT_RASTER_COORD_LIMIT);
d->rasterizer->setClipRect(d->deviceRect);
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index ff82d59..e0746fb 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -494,11 +494,9 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
} else {
d->activeStroker->moveTo(points[0], points[1]);
points += 2;
- ++types;
while (points < lastPoint) {
d->activeStroker->lineTo(points[0], points[1]);
points += 2;
- ++types;
}
if (path.hasImplicitClose())
d->activeStroker->lineTo(path.points()[0], path.points()[1]);
@@ -561,12 +559,10 @@ void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
QPointF p = ((QPointF *)points)[0] * state()->matrix;
d->activeStroker->moveTo(p.x(), p.y());
points += 2;
- ++types;
while (points < lastPoint) {
QPointF p = ((QPointF *)points)[0] * state()->matrix;
d->activeStroker->lineTo(p.x(), p.y());
points += 2;
- ++types;
}
if (path.hasImplicitClose())
d->activeStroker->lineTo(p.x(), p.y());
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index d17c711..71bc990 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -2391,6 +2391,8 @@ void QPainter::setCompositionMode(CompositionMode mode)
qWarning("QPainter::setCompositionMode: Painter not active");
return;
}
+ if (d->state->composition_mode == mode)
+ return;
if (d->extended) {
d->state->composition_mode = mode;
d->extended->compositionModeChanged();
diff --git a/src/gui/styles/qcleanlooksstyle.cpp b/src/gui/styles/qcleanlooksstyle.cpp
index 883f511..ada5293 100644
--- a/src/gui/styles/qcleanlooksstyle.cpp
+++ b/src/gui/styles/qcleanlooksstyle.cpp
@@ -884,7 +884,7 @@ void QCleanlooksStyle::drawPrimitive(PrimitiveElement elem,
}
painter->restore();
break;
-#ifndef QT_NO_LINEDIT
+#ifndef QT_NO_LINEEDIT
case PE_FrameLineEdit:
// fall through
#endif // QT_NO_LINEEDIT
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index ff29462..139139f 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -145,18 +145,18 @@ struct QtFontEncoding
struct QtFontSize
{
- unsigned short pixelSize;
-
#ifdef Q_WS_X11
- int count;
QtFontEncoding *encodings;
QtFontEncoding *encodingID(int id, uint xpoint = 0, uint xres = 0,
uint yres = 0, uint avgwidth = 0, bool add = false);
+ unsigned short count : 16;
#endif // Q_WS_X11
#if defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
QByteArray fileName;
int fileIndex;
#endif // defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN)
+
+ unsigned short pixelSize : 16;
};
@@ -284,7 +284,12 @@ QtFontSize *QtFontStyle::pixelSize(unsigned short size, bool add)
if (!add)
return 0;
- if (!(count % 8)) {
+ if (!pixelSizes) {
+ // Most style have only one font size, we avoid waisting memory
+ QtFontSize *newPixelSizes = (QtFontSize *)malloc(sizeof(QtFontSize));
+ Q_CHECK_PTR(newPixelSizes);
+ pixelSizes = newPixelSizes;
+ } else if (!(count % 8) || count == 1) {
QtFontSize *newPixelSizes = (QtFontSize *)
realloc(pixelSizes,
(((count+8) >> 3) << 3) * sizeof(QtFontSize));
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index 3be6d28..7ceed61 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -237,7 +237,8 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
*nglyphs = len;
for (int i = 0; i < len; ++i) {
outGlyphs[i] = 0;
- logClusters[i] = i;
+ if (logClusters)
+ logClusters[i] = i;
outAdvances_x[i] = QFixed();
outAdvances_y[i] = QFixed();
outAttributes[i].clusterStart = true;
diff --git a/src/plugins/imageformats/gif/qgifhandler.cpp b/src/plugins/imageformats/gif/qgifhandler.cpp
index 591e40b..129a11b 100644
--- a/src/plugins/imageformats/gif/qgifhandler.cpp
+++ b/src/plugins/imageformats/gif/qgifhandler.cpp
@@ -132,8 +132,8 @@ private:
int code_size, clear_code, end_code, max_code_size, max_code;
int firstcode, oldcode, incode;
- short table[2][1<< max_lzw_bits];
- short stack[(1<<(max_lzw_bits))*2];
+ short* table[2];
+ short* stack;
short *sp;
bool needfirst;
int x, y;
@@ -162,6 +162,9 @@ QGIFFormat::QGIFFormat()
lcmap = false;
newFrame = false;
partialNewFrame = false;
+ table[0] = 0;
+ table[1] = 0;
+ stack = 0;
}
/*!
@@ -171,6 +174,7 @@ QGIFFormat::~QGIFFormat()
{
if (globalcmap) delete[] globalcmap;
if (localcmap) delete[] localcmap;
+ delete [] stack;
}
void QGIFFormat::disposePrevious(QImage *image)
@@ -237,6 +241,12 @@ int QGIFFormat::decode(QImage *image, const uchar *buffer, int length,
// CompuServe Incorporated. GIF(sm) is a Service Mark property of
// CompuServe Incorporated."
+ if (!stack) {
+ stack = new short[(1 << max_lzw_bits) * 4];
+ table[0] = &stack[(1 << max_lzw_bits) * 2];
+ table[1] = &stack[(1 << max_lzw_bits) * 3];
+ }
+
image->detach();
int bpl = image->bytesPerLine();
unsigned char *bits = image->bits();
diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp
index f02ea52..e2999c1 100644
--- a/src/script/api/qscriptengine.cpp
+++ b/src/script/api/qscriptengine.cpp
@@ -1011,12 +1011,17 @@ JSC::JSValue QScriptEnginePrivate::arrayFromVariantList(JSC::ExecState *exec, co
return arr;
}
-QVariantList QScriptEnginePrivate::variantListFromArray(JSC::ExecState *exec, JSC::JSValue arr)
+QVariantList QScriptEnginePrivate::variantListFromArray(JSC::ExecState *exec, JSC::JSArray *arr)
{
+ QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(exec);
+ if (eng->visitedConversionObjects.contains(arr))
+ return QVariantList(); // Avoid recursion.
+ eng->visitedConversionObjects.insert(arr);
QVariantList lst;
uint len = toUInt32(exec, property(exec, arr, exec->propertyNames().length));
for (uint i = 0; i < len; ++i)
lst.append(toVariant(exec, property(exec, arr, i)));
+ eng->visitedConversionObjects.remove(arr);
return lst;
}
@@ -1029,14 +1034,19 @@ JSC::JSValue QScriptEnginePrivate::objectFromVariantMap(JSC::ExecState *exec, co
return obj;
}
-QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSValue obj)
+QVariantMap QScriptEnginePrivate::variantMapFromObject(JSC::ExecState *exec, JSC::JSObject *obj)
{
+ QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(exec);
+ if (eng->visitedConversionObjects.contains(obj))
+ return QVariantMap(); // Avoid recursion.
+ eng->visitedConversionObjects.insert(obj);
JSC::PropertyNameArray propertyNames(exec);
- JSC::asObject(obj)->getOwnPropertyNames(exec, propertyNames, JSC::IncludeDontEnumProperties);
+ obj->getOwnPropertyNames(exec, propertyNames, JSC::IncludeDontEnumProperties);
QVariantMap vmap;
JSC::PropertyNameArray::const_iterator it = propertyNames.begin();
for( ; it != propertyNames.end(); ++it)
vmap.insert(it->ustring(), toVariant(exec, property(exec, obj, *it)));
+ eng->visitedConversionObjects.remove(obj);
return vmap;
}
@@ -1661,16 +1671,10 @@ QVariant QScriptEnginePrivate::toVariant(JSC::ExecState *exec, JSC::JSValue valu
return QVariant(toRegExp(exec, value));
#endif
else if (isArray(value))
- return variantListFromArray(exec, value);
+ return variantListFromArray(exec, JSC::asArray(value));
else if (QScriptDeclarativeClass *dc = declarativeClass(value))
return dc->toVariant(declarativeObject(value));
- // try to convert to primitive
- JSC::JSValue savedException;
- saveException(exec, &savedException);
- JSC::JSValue prim = value.toPrimitive(exec);
- restoreException(exec, savedException);
- if (!prim.isObject())
- return toVariant(exec, prim);
+ return variantMapFromObject(exec, JSC::asObject(value));
} else if (value.isNumber()) {
return QVariant(toNumber(exec, value));
} else if (value.isString()) {
@@ -3129,12 +3133,12 @@ bool QScriptEnginePrivate::convertValue(JSC::ExecState *exec, JSC::JSValue value
} break;
case QMetaType::QVariantList:
if (isArray(value)) {
- *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(exec, value);
+ *reinterpret_cast<QVariantList *>(ptr) = variantListFromArray(exec, JSC::asArray(value));
return true;
} break;
case QMetaType::QVariantMap:
if (isObject(value)) {
- *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(exec, value);
+ *reinterpret_cast<QVariantMap *>(ptr) = variantMapFromObject(exec, JSC::asObject(value));
return true;
} break;
case QMetaType::QVariant:
diff --git a/src/script/api/qscriptengine_p.h b/src/script/api/qscriptengine_p.h
index fd47208..56366e2 100644
--- a/src/script/api/qscriptengine_p.h
+++ b/src/script/api/qscriptengine_p.h
@@ -215,10 +215,10 @@ public:
static QStringList stringListFromArray(JSC::ExecState*, JSC::JSValue arr);
static JSC::JSValue arrayFromVariantList(JSC::ExecState*, const QVariantList &lst);
- static QVariantList variantListFromArray(JSC::ExecState*, JSC::JSValue arr);
+ static QVariantList variantListFromArray(JSC::ExecState*, JSC::JSArray *arr);
static JSC::JSValue objectFromVariantMap(JSC::ExecState*, const QVariantMap &vmap);
- static QVariantMap variantMapFromObject(JSC::ExecState*, JSC::JSValue obj);
+ static QVariantMap variantMapFromObject(JSC::ExecState*, JSC::JSObject *obj);
JSC::JSValue defaultPrototype(int metaTypeId) const;
void setDefaultPrototype(int metaTypeId, JSC::JSValue prototype);
@@ -378,6 +378,8 @@ public:
QHash<intptr_t, QScript::UStringSourceProviderWithFeedback*> loadedScripts;
QScriptValue m_currentException;
+ QSet<JSC::JSObject*> visitedConversionObjects;
+
#ifndef QT_NO_QOBJECT
QHash<QObject*, QScript::QObjectData*> m_qobjectData;
#endif
diff --git a/src/script/api/qscriptvalue.cpp b/src/script/api/qscriptvalue.cpp
index 1310c8c..451d1b0 100644
--- a/src/script/api/qscriptvalue.cpp
+++ b/src/script/api/qscriptvalue.cpp
@@ -1215,8 +1215,8 @@ qsreal QScriptValue::toInteger() const
\row \o QObject Object \o A QVariant containing a pointer to the QObject.
\row \o Date Object \o A QVariant containing the date value (toDateTime()).
\row \o RegExp Object \o A QVariant containing the regular expression value (toRegExp()).
- \row \o Array Object \o The array is converted to a QVariantList.
- \row \o Object \o If the value is primitive, then the result is converted to a QVariant according to the above rules; otherwise, an invalid QVariant is returned.
+ \row \o Array Object \o The array is converted to a QVariantList. Each element is converted to a QVariant, recursively; cyclic references are not followed.
+ \row \o Object \o The object is converted to a QVariantMap. Each property is converted to a QVariant, recursively; cyclic references are not followed.
\endtable
\sa isVariant()
diff --git a/tests/auto/declarative/qdeclarativeitem/data/childrenRectBug2.qml b/tests/auto/declarative/qdeclarativeitem/data/childrenRectBug2.qml
new file mode 100644
index 0000000..225d8d4
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeitem/data/childrenRectBug2.qml
@@ -0,0 +1,53 @@
+import Qt 4.7
+
+Rectangle {
+ width:360;
+ height: 200
+
+ Item {
+ objectName: "theItem"
+ anchors.centerIn: parent
+ width: childrenRect.width
+ height: childrenRect.height
+ Rectangle {
+ id: header1
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.top: parent.top
+ width: 100; height: 50
+ color: "green"
+ }
+ Rectangle {
+ id: text1
+ anchors.top: header1.bottom
+ anchors.topMargin: 10
+ anchors.horizontalCenter: parent.horizontalCenter
+ width: 100; height: 50
+ color: "blue"
+ }
+ }
+
+ states: [
+ State {
+ name: "row"
+ AnchorChanges {
+ target: header1
+ anchors.horizontalCenter: undefined
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+ anchors.top: undefined
+ }
+ AnchorChanges {
+ target: text1
+ anchors.horizontalCenter: undefined
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.top: undefined
+ anchors.left: header1.right
+ }
+ PropertyChanges {
+ target: text1
+ anchors.leftMargin: 10
+ anchors.topMargin: 0
+ }
+ }
+ ]
+}
diff --git a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp
index 0a66245..4a57def 100644
--- a/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp
+++ b/tests/auto/declarative/qdeclarativeitem/tst_qdeclarativeitem.cpp
@@ -44,7 +44,8 @@
#include <QtDeclarative/qdeclarativecomponent.h>
#include <QtDeclarative/qdeclarativecontext.h>
#include <QtDeclarative/qdeclarativeview.h>
-#include <QtDeclarative/qdeclarativeitem.h>
+#include <private/qdeclarativerectangle_p.h>
+#include <private/qdeclarativeitem_p.h>
#include "../../../shared/util.h"
#ifdef Q_OS_SYMBIAN
@@ -73,6 +74,7 @@ private slots:
void transforms_data();
void childrenRect();
void childrenRectBug();
+ void childrenRectBug2();
void childrenProperty();
void resourcesProperty();
@@ -753,6 +755,29 @@ void tst_QDeclarativeItem::childrenRectBug()
delete canvas;
}
+// QTBUG-11465
+void tst_QDeclarativeItem::childrenRectBug2()
+{
+ QDeclarativeView *canvas = new QDeclarativeView(0);
+ canvas->setSource(QUrl::fromLocalFile(SRCDIR "/data/childrenRectBug2.qml"));
+ canvas->show();
+
+ QDeclarativeRectangle *rect = qobject_cast<QDeclarativeRectangle*>(canvas->rootObject());
+ QVERIFY(rect);
+ QDeclarativeItem *item = rect->findChild<QDeclarativeItem*>("theItem");
+ QCOMPARE(item->width(), qreal(100));
+ QCOMPARE(item->height(), qreal(110));
+ QCOMPARE(item->x(), qreal(130));
+
+ QDeclarativeItemPrivate *rectPrivate = QDeclarativeItemPrivate::get(rect);
+ rectPrivate->setState("row");
+ QCOMPARE(item->width(), qreal(210));
+ QCOMPARE(item->height(), qreal(50));
+ QCOMPARE(item->x(), qreal(75));
+
+ delete canvas;
+}
+
template<typename T>
T *tst_QDeclarativeItem::findItem(QGraphicsObject *parent, const QString &objectName)
{
diff --git a/tests/auto/declarative/qdeclarativeqt/data/createComponent_lib.js b/tests/auto/declarative/qdeclarativeqt/data/createComponent_lib.js
new file mode 100644
index 0000000..c165e29
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeqt/data/createComponent_lib.js
@@ -0,0 +1,7 @@
+.pragma library
+
+function loadComponent() {
+ var component = Qt.createComponent("createComponentData.qml");
+ return component.status;
+}
+
diff --git a/tests/auto/declarative/qdeclarativeqt/data/createComponent_lib.qml b/tests/auto/declarative/qdeclarativeqt/data/createComponent_lib.qml
new file mode 100644
index 0000000..aae7a91
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativeqt/data/createComponent_lib.qml
@@ -0,0 +1,10 @@
+import Qt 4.7
+import "createComponent_lib.js" as Test
+
+Item {
+ property int status: Component.Null
+
+ Component.onCompleted: {
+ status = Test.loadComponent()
+ }
+}
diff --git a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp
index 06561fa..fb100a5 100644
--- a/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp
+++ b/tests/auto/declarative/qdeclarativeqt/tst_qdeclarativeqt.cpp
@@ -76,6 +76,7 @@ private slots:
void openUrlExternally();
void md5();
void createComponent();
+ void createComponent_pragmaLibrary();
void createQmlObject();
void consoleLog();
void formatting();
@@ -361,6 +362,19 @@ void tst_qdeclarativeqt::createComponent()
delete object;
}
+void tst_qdeclarativeqt::createComponent_pragmaLibrary()
+{
+ // Currently, just loading createComponent_lib.qml causes crash on some platforms
+ /*
+ QDeclarativeComponent component(&engine, TEST_FILE("createComponent_lib.qml"));
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+
+ QEXPECT_FAIL("", "QTBUG-11507", Continue);
+ QCOMPARE(object->property("status").toInt(), int(QDeclarativeComponent::Ready));
+ */
+}
+
void tst_qdeclarativeqt::createQmlObject()
{
QDeclarativeComponent component(&engine, TEST_FILE("createQmlObject.qml"));
diff --git a/tests/auto/declarative/qdeclarativerepeater/data/repeater2.qml b/tests/auto/declarative/qdeclarativerepeater/data/repeater2.qml
index c8b863c..7f2f85a 100644
--- a/tests/auto/declarative/qdeclarativerepeater/data/repeater2.qml
+++ b/tests/auto/declarative/qdeclarativerepeater/data/repeater2.qml
@@ -9,12 +9,13 @@ Rectangle {
Item {
objectName: "myDelegate"
height: 20
+ width: 240
Text {
- y: index*20
+ objectName: "myName"
text: name
}
Text {
- y: index*20
+ objectName: "myNumber"
x: 100
text: number
}
diff --git a/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp b/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp
index 3cc68f4..7299a43 100644
--- a/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp
+++ b/tests/auto/declarative/qdeclarativerepeater/tst_qdeclarativerepeater.cpp
@@ -45,6 +45,7 @@
#include <QtDeclarative/qdeclarativeengine.h>
#include <QtDeclarative/qdeclarativeview.h>
#include <QtDeclarative/qdeclarativecontext.h>
+#include <QtDeclarative/qdeclarativeexpression.h>
#include <private/qdeclarativerepeater_p.h>
#include <private/qdeclarativetext_p.h>
@@ -75,6 +76,8 @@ private slots:
private:
QDeclarativeView *createView();
template<typename T>
+ T *findItem(QGraphicsObject *parent, const QString &objectName, int index);
+ template<typename T>
T *findItem(QGraphicsObject *parent, const QString &id);
};
@@ -312,6 +315,20 @@ void tst_QDeclarativeRepeater::dataModel()
testModel.removeItem(2);
QCOMPARE(container->childItems().count(), 4);
+ // Check that model changes are propagated
+ QDeclarativeText *text = findItem<QDeclarativeText>(canvas->rootObject(), "myName", 1);
+ QVERIFY(text);
+ QCOMPARE(text->text(), QString("two"));
+
+ testModel.modifyItem(1, "Item two", "_2");
+ text = findItem<QDeclarativeText>(canvas->rootObject(), "myName", 1);
+ QVERIFY(text);
+ QCOMPARE(text->text(), QString("Item two"));
+
+ text = findItem<QDeclarativeText>(canvas->rootObject(), "myNumber", 1);
+ QVERIFY(text);
+ QCOMPARE(text->text(), QString("_2"));
+
delete testObject;
delete canvas;
}
@@ -387,6 +404,33 @@ QDeclarativeView *tst_QDeclarativeRepeater::createView()
}
template<typename T>
+T *tst_QDeclarativeRepeater::findItem(QGraphicsObject *parent, const QString &objectName, int index)
+{
+ const QMetaObject &mo = T::staticMetaObject;
+ //qDebug() << parent->childItems().count() << "children";
+ for (int i = 0; i < parent->childItems().count(); ++i) {
+ QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(parent->childItems().at(i));
+ if(!item)
+ continue;
+ //qDebug() << "try" << item;
+ if (mo.cast(item) && (objectName.isEmpty() || item->objectName() == objectName)) {
+ if (index != -1) {
+ QDeclarativeExpression e(qmlContext(item), item, "index");
+ if (e.evaluate().toInt() == index)
+ return static_cast<T*>(item);
+ } else {
+ return static_cast<T*>(item);
+ }
+ }
+ item = findItem<T>(item, objectName, index);
+ if (item)
+ return static_cast<T*>(item);
+ }
+
+ return 0;
+}
+
+template<typename T>
T *tst_QDeclarativeRepeater::findItem(QGraphicsObject *parent, const QString &objectName)
{
const QMetaObject &mo = T::staticMetaObject;
diff --git a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
index 3143580..a55b42e 100644
--- a/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
+++ b/tests/auto/declarative/qdeclarativetextinput/tst_qdeclarativetextinput.cpp
@@ -396,7 +396,6 @@ void tst_qdeclarativetextinput::positionAt()
#endif
// Check without autoscroll...
- QEXPECT_FAIL("", "QTBUG-11127", Abort);
textinputObject->setAutoScroll(false);
pos = textinputObject->positionAt(textinputObject->width()/2);
diff = abs(fm.width(textinputObject->text().left(pos))-textinputObject->width()/2);
diff --git a/tests/auto/declarative/qdeclarativeworkerscript/data/BaseWorker.qml b/tests/auto/declarative/qdeclarativeworkerscript/data/BaseWorker.qml
index d275ca8..e06afa2 100644
--- a/tests/auto/declarative/qdeclarativeworkerscript/data/BaseWorker.qml
+++ b/tests/auto/declarative/qdeclarativeworkerscript/data/BaseWorker.qml
@@ -13,7 +13,7 @@ WorkerScript {
function compareLiteralResponse(expected) {
var e = eval('(' + expected + ')')
- return worker.response == e
+ return JSON.stringify(worker.response) == JSON.stringify(e)
}
onMessage: {
diff --git a/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp b/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp
index 52c11e9..8e98874 100644
--- a/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp
+++ b/tests/auto/declarative/qdeclarativeworkerscript/tst_qdeclarativeworkerscript.cpp
@@ -170,13 +170,15 @@ void tst_QDeclarativeWorkerScript::messaging_sendJsObject()
QDeclarativeWorkerScript *worker = qobject_cast<QDeclarativeWorkerScript*>(component.create());
QVERIFY(worker != 0);
- QString jsObject = "{'name': 'zyz', 'spell power': 3101, 'haste': 1125}";
+ // Properties are in alphabetical order to enable string-based comparison after
+ // QVariant roundtrip, since the properties will be stored in a QVariantMap.
+ QString jsObject = "{'haste': 1125, 'name': 'zyz', 'spell power': 3101}";
QScriptEngine *engine = QDeclarativeEnginePrivate::getScriptEngine(qmlEngine(worker));
QScriptValue sv = engine->newObject();
+ sv.setProperty("haste", 1125);
sv.setProperty("name", "zyz");
sv.setProperty("spell power", 3101);
- sv.setProperty("haste", 1125);
QVERIFY(QMetaObject::invokeMethod(worker, "testSend", Q_ARG(QVariant, qVariantFromValue(sv))));
waitForEchoMessage(worker);
diff --git a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/LineEdit.qml b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/LineEdit.qml
index 69f57c6..e863262 100644
--- a/tests/auto/declarative/qmlvisual/qdeclarativetextinput/LineEdit.qml
+++ b/tests/auto/declarative/qmlvisual/qdeclarativetextinput/LineEdit.qml
@@ -30,13 +30,14 @@ Item {
y: 5
//Below function implements all scrolling logic
onCursorPositionChanged: {
- if(cursorRect.x < leftMargin - textInp.x){//Cursor went off the front
- textInp.x = leftMargin - Math.max(0, cursorRect.x);
- }else if(cursorRect.x > parent.width - leftMargin - rightMargin - textInp.x){//Cusor went off the end
- textInp.x = leftMargin - Math.max(0, cursorRect.x - (parent.width - leftMargin - rightMargin));
+ if(cursorRectangle.x < leftMargin - textInp.x){//Cursor went off the front
+ textInp.x = leftMargin - Math.max(0, cursorRectangle.x);
+ }else if(cursorRectangle.x > parent.width - leftMargin - rightMargin - textInp.x){//Cusor went off the end
+ textInp.x = leftMargin - Math.max(0, cursorRectangle.x - (parent.width - leftMargin - rightMargin));
}
}
+ autoScroll: false //It is preferable to implement your own scrolling
text:""
horizontalAlignment: TextInput.AlignLeft
font.pixelSize:15
diff --git a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
index 8127f84..b9a5c66 100644
--- a/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
+++ b/tests/auto/qgraphicsgridlayout/tst_qgraphicsgridlayout.cpp
@@ -741,31 +741,73 @@ void tst_QGraphicsGridLayout::setColumnFixedWidth()
// public qreal columnSpacing(int column) const
void tst_QGraphicsGridLayout::columnSpacing()
{
- QGraphicsScene scene;
- QGraphicsView view(&scene);
- QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
- QGraphicsGridLayout *layout = new QGraphicsGridLayout();
- scene.addItem(widget);
- widget->setLayout(layout);
- populateLayout(layout, 3, 2);
- layout->setContentsMargins(0, 0, 0, 0);
- layout->setSpacing(0);
- QCOMPARE(layout->columnSpacing(0), 0.0);
+ {
+ QGraphicsScene scene;
+ QGraphicsView view(&scene);
+ QGraphicsWidget *widget = new QGraphicsWidget(0, Qt::Window);
+ QGraphicsGridLayout *layout = new QGraphicsGridLayout();
+ scene.addItem(widget);
+ widget->setLayout(layout);
+ populateLayout(layout, 3, 2);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ QCOMPARE(layout->columnSpacing(0), 0.0);
+
+ layout->setColumnSpacing(0, 20);
+ view.show();
+ widget->show();
+ widget->resize(widget->effectiveSizeHint(Qt::PreferredSize));
+ QApplication::processEvents();
- layout->setColumnSpacing(0, 20);
- view.show();
- widget->show();
- widget->resize(widget->effectiveSizeHint(Qt::PreferredSize));
- QApplication::processEvents();
+ QCOMPARE(layout->itemAt(0,0)->geometry().left(), 0.0);
+ QCOMPARE(layout->itemAt(0,0)->geometry().right(), 25.0);
+ QCOMPARE(layout->itemAt(0,1)->geometry().left(), 45.0);
+ QCOMPARE(layout->itemAt(0,1)->geometry().right(), 70.0);
+ QCOMPARE(layout->itemAt(0,2)->geometry().left(), 70.0);
+ QCOMPARE(layout->itemAt(0,2)->geometry().right(), 95.0);
- QCOMPARE(layout->itemAt(0,0)->geometry().left(), 0.0);
- QCOMPARE(layout->itemAt(0,0)->geometry().right(), 25.0);
- QCOMPARE(layout->itemAt(0,1)->geometry().left(), 45.0);
- QCOMPARE(layout->itemAt(0,1)->geometry().right(), 70.0);
- QCOMPARE(layout->itemAt(0,2)->geometry().left(), 70.0);
- QCOMPARE(layout->itemAt(0,2)->geometry().right(), 95.0);
+ delete widget;
+ }
+
+ {
+ // don't include items and spacings that was previously part of the layout
+ // (horizontal)
+ QGraphicsGridLayout *layout = new QGraphicsGridLayout;
+ populateLayout(layout, 3, 1);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ layout->setColumnSpacing(0, 10);
+ layout->setColumnSpacing(1, 10);
+ layout->setColumnSpacing(2, 10);
+ layout->setColumnSpacing(3, 10);
+ QCOMPARE(layout->preferredSize(), QSizeF(95, 25));
+ layout->removeAt(2);
+ QCOMPARE(layout->preferredSize(), QSizeF(60, 25));
+ layout->removeAt(1);
+ QCOMPARE(layout->preferredSize(), QSizeF(25, 25));
+ delete layout;
+ }
+ {
+ // don't include items and spacings that was previously part of the layout
+ // (vertical)
+ QGraphicsGridLayout *layout = new QGraphicsGridLayout;
+ populateLayout(layout, 2, 2);
+ layout->setContentsMargins(0, 0, 0, 0);
+ layout->setSpacing(0);
+ layout->setColumnSpacing(0, 10);
+ layout->setColumnSpacing(1, 10);
+ layout->setRowSpacing(0, 10);
+ layout->setRowSpacing(1, 10);
+ QCOMPARE(layout->preferredSize(), QSizeF(60, 60));
+ layout->removeAt(3);
+ QCOMPARE(layout->preferredSize(), QSizeF(60, 60));
+ layout->removeAt(2);
+ QCOMPARE(layout->preferredSize(), QSizeF(60, 25));
+ layout->removeAt(1);
+ QCOMPARE(layout->preferredSize(), QSizeF(25, 25));
+ delete layout;
+ }
- delete widget;
}
// public int columnStretchFactor(int column) const
diff --git a/tests/auto/qpixmap/loadFromData/designer_argb32.png b/tests/auto/qpixmap/loadFromData/designer_argb32.png
new file mode 100644
index 0000000..55d8247
--- /dev/null
+++ b/tests/auto/qpixmap/loadFromData/designer_argb32.png
Binary files differ
diff --git a/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.gif b/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.gif
new file mode 100644
index 0000000..26a6da3
--- /dev/null
+++ b/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.gif
Binary files differ
diff --git a/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.png b/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.png
new file mode 100644
index 0000000..28cd2f0
--- /dev/null
+++ b/tests/auto/qpixmap/loadFromData/designer_indexed8_no_alpha.png
Binary files differ
diff --git a/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.gif b/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.gif
new file mode 100644
index 0000000..49ec77b
--- /dev/null
+++ b/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.gif
Binary files differ
diff --git a/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.png b/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.png
new file mode 100644
index 0000000..09735a9
--- /dev/null
+++ b/tests/auto/qpixmap/loadFromData/designer_indexed8_with_alpha.png
Binary files differ
diff --git a/tests/auto/qpixmap/loadFromData/designer_rgb32.jpg b/tests/auto/qpixmap/loadFromData/designer_rgb32.jpg
new file mode 100644
index 0000000..70f39c2
--- /dev/null
+++ b/tests/auto/qpixmap/loadFromData/designer_rgb32.jpg
Binary files differ
diff --git a/tests/auto/qpixmap/loadFromData/designer_rgb32.png b/tests/auto/qpixmap/loadFromData/designer_rgb32.png
new file mode 100644
index 0000000..bca471d
--- /dev/null
+++ b/tests/auto/qpixmap/loadFromData/designer_rgb32.png
Binary files differ
diff --git a/tests/auto/qpixmap/tst_qpixmap.cpp b/tests/auto/qpixmap/tst_qpixmap.cpp
index 49b1e52..179f068 100644
--- a/tests/auto/qpixmap/tst_qpixmap.cpp
+++ b/tests/auto/qpixmap/tst_qpixmap.cpp
@@ -172,6 +172,9 @@ private slots:
void fromData();
void loadFromDataNullValues();
+ void loadFromDataImage_data();
+ void loadFromDataImage();
+
void preserveDepth();
void splash_crash();
@@ -1540,6 +1543,40 @@ void tst_QPixmap::loadFromDataNullValues()
}
}
+void tst_QPixmap::loadFromDataImage_data()
+{
+ QTest::addColumn<QString>("imagePath");
+#ifdef Q_OS_SYMBIAN
+ const QString prefix = QLatin1String(SRCDIR) + "loadFromData";
+#else
+ const QString prefix = QLatin1String(SRCDIR) + "/loadFromData";
+#endif
+ QTest::newRow("designer_argb32.png") << prefix + "/designer_argb32.png";
+ QTest::newRow("designer_indexed8_no_alpha.png") << prefix + "/designer_indexed8_no_alpha.png";
+ QTest::newRow("designer_indexed8_with_alpha.png") << prefix + "/designer_indexed8_with_alpha.png";
+ QTest::newRow("designer_rgb32.png") << prefix + "/designer_rgb32.png";
+ QTest::newRow("designer_indexed8_no_alpha.gif") << prefix + "/designer_indexed8_no_alpha.gif";
+ QTest::newRow("designer_indexed8_with_alpha.gif") << prefix + "/designer_indexed8_with_alpha.gif";
+ QTest::newRow("designer_rgb32.jpg") << prefix + "/designer_rgb32.jpg";
+}
+
+void tst_QPixmap::loadFromDataImage()
+{
+ QFETCH(QString, imagePath);
+
+ QImage imageRef(imagePath);
+ QPixmap pixmapWithCopy = QPixmap::fromImage(imageRef);
+
+ QFile file(imagePath);
+ file.open(QIODevice::ReadOnly);
+ QByteArray rawData = file.readAll();
+
+ QPixmap directLoadingPixmap;
+ directLoadingPixmap.loadFromData(rawData);
+
+ QVERIFY(pixmapsAreEqual(&pixmapWithCopy, &directLoadingPixmap));
+}
+
void tst_QPixmap::task_246446()
{
// This crashed without the bugfix in 246446
diff --git a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp
index 09070e6..11813d8 100644
--- a/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp
+++ b/tests/auto/qscriptextqobject/tst_qscriptextqobject.cpp
@@ -287,6 +287,8 @@ public:
{ m_qtFunctionInvoked = 15; m_actuals << v; return v; }
Q_INVOKABLE QVariantMap myInvokableWithVariantMapArg(const QVariantMap &vm)
{ m_qtFunctionInvoked = 16; m_actuals << vm; return vm; }
+ Q_INVOKABLE QVariantList myInvokableWithVariantListArg(const QVariantList &lst)
+ { m_qtFunctionInvoked = 62; m_actuals.append(QVariant(lst)); return lst; }
Q_INVOKABLE QList<int> myInvokableWithListOfIntArg(const QList<int> &lst)
{ m_qtFunctionInvoked = 17; m_actuals << qVariantFromValue(lst); return lst; }
Q_INVOKABLE QObject* myInvokableWithQObjectStarArg(QObject *obj)
@@ -535,6 +537,10 @@ private slots:
void emitAfterReceiverDeleted();
void inheritedSlots();
void enumerateMetaObject();
+ void nestedArrayAsSlotArgument_data();
+ void nestedArrayAsSlotArgument();
+ void nestedObjectAsSlotArgument_data();
+ void nestedObjectAsSlotArgument();
private:
QScriptEngine *m_engine;
@@ -3164,5 +3170,139 @@ void tst_QScriptExtQObject::enumerateMetaObject()
}
}
+void tst_QScriptExtQObject::nestedArrayAsSlotArgument_data()
+{
+ QTest::addColumn<QString>("program");
+ QTest::addColumn<QVariantList>("expected");
+
+ QTest::newRow("[[]]")
+ << QString::fromLatin1("[[]]")
+ << (QVariantList() << (QVariant(QVariantList())));
+ QTest::newRow("[[123]]")
+ << QString::fromLatin1("[[123]]")
+ << (QVariantList() << (QVariant(QVariantList() << 123)));
+ QTest::newRow("[[], 123]")
+ << QString::fromLatin1("[[], 123]")
+ << (QVariantList() << QVariant(QVariantList()) << 123);
+
+ // Cyclic
+ QTest::newRow("var a=[]; a.push(a)")
+ << QString::fromLatin1("var a=[]; a.push(a); a")
+ << (QVariantList() << QVariant(QVariantList()));
+ QTest::newRow("var a=[]; a.push(123, a)")
+ << QString::fromLatin1("var a=[]; a.push(123, a); a")
+ << (QVariantList() << 123 << QVariant(QVariantList()));
+ QTest::newRow("var a=[]; var b=[]; a.push(b); b.push(a)")
+ << QString::fromLatin1("var a=[]; var b=[]; a.push(b); b.push(a); a")
+ << (QVariantList() << QVariant(QVariantList() << QVariant(QVariantList())));
+ QTest::newRow("var a=[]; var b=[]; a.push(123, b); b.push(456, a)")
+ << QString::fromLatin1("var a=[]; var b=[]; a.push(123, b); b.push(456, a); a")
+ << (QVariantList() << 123 << QVariant(QVariantList() << 456 << QVariant(QVariantList())));
+}
+
+void tst_QScriptExtQObject::nestedArrayAsSlotArgument()
+{
+ QFETCH(QString, program);
+ QFETCH(QVariantList, expected);
+ QScriptValue a = m_engine->evaluate(program);
+ QVERIFY(!a.isError());
+ QVERIFY(a.isArray());
+ // Slot that takes QVariantList
+ {
+ QVERIFY(!m_engine->evaluate("myObject.myInvokableWithVariantListArg")
+ .call(QScriptValue(), QScriptValueList() << a).isError());
+ QCOMPARE(m_myObject->qtFunctionInvoked(), 62);
+ QCOMPARE(m_myObject->qtFunctionActuals().size(), 1);
+ QCOMPARE(m_myObject->qtFunctionActuals().at(0).type(), QVariant::List);
+ QCOMPARE(m_myObject->qtFunctionActuals().at(0).toList(), expected);
+ }
+ // Slot that takes QVariant
+ {
+ m_myObject->resetQtFunctionInvoked();
+ QVERIFY(!m_engine->evaluate("myObject.myInvokableWithVariantArg")
+ .call(QScriptValue(), QScriptValueList() << a).isError());
+ QCOMPARE(m_myObject->qtFunctionInvoked(), 15);
+ QCOMPARE(m_myObject->qtFunctionActuals().size(), 1);
+ QCOMPARE(m_myObject->qtFunctionActuals().at(0).type(), QVariant::List);
+ QCOMPARE(m_myObject->qtFunctionActuals().at(0).toList(), expected);
+ }
+}
+
+void tst_QScriptExtQObject::nestedObjectAsSlotArgument_data()
+{
+ QTest::addColumn<QString>("program");
+ QTest::addColumn<QVariantMap>("expected");
+
+ {
+ QVariantMap m;
+ m["a"] = QVariantMap();
+ QTest::newRow("{ a:{} }")
+ << QString::fromLatin1("({ a:{} })")
+ << m;
+ }
+ {
+ QVariantMap m, m2;
+ m2["b"] = 10;
+ m2["c"] = 20;
+ m["a"] = m2;
+ QTest::newRow("{ a:{b:10, c:20} }")
+ << QString::fromLatin1("({ a:{b:10, c:20} })")
+ << m;
+ }
+ {
+ QVariantMap m;
+ m["a"] = 10;
+ m["b"] = QVariantList() << 20 << 30;
+ QTest::newRow("{ a:10, b:[20, 30]}")
+ << QString::fromLatin1("({ a:10, b:[20,30]})")
+ << m;
+ }
+
+ // Cyclic
+ {
+ QVariantMap m;
+ m["p"] = QVariantMap();
+ QTest::newRow("var o={}; o.p=o")
+ << QString::fromLatin1("var o={}; o.p=o; o")
+ << m;
+ }
+ {
+ QVariantMap m;
+ m["p"] = 123;
+ m["q"] = QVariantMap();
+ QTest::newRow("var o={}; o.p=123; o.q=o")
+ << QString::fromLatin1("var o={}; o.p=123; o.q=o; o")
+ << m;
+ }
+}
+
+void tst_QScriptExtQObject::nestedObjectAsSlotArgument()
+{
+ QFETCH(QString, program);
+ QFETCH(QVariantMap, expected);
+ QScriptValue o = m_engine->evaluate(program);
+ QVERIFY(!o.isError());
+ QVERIFY(o.isObject());
+ // Slot that takes QVariantMap
+ {
+ QVERIFY(!m_engine->evaluate("myObject.myInvokableWithVariantMapArg")
+ .call(QScriptValue(), QScriptValueList() << o).isError());
+ QCOMPARE(m_myObject->qtFunctionInvoked(), 16);
+ QCOMPARE(m_myObject->qtFunctionActuals().size(), 1);
+ QCOMPARE(m_myObject->qtFunctionActuals().at(0).type(), QVariant::Map);
+ QCOMPARE(m_myObject->qtFunctionActuals().at(0).toMap(), expected);
+ }
+ // Slot that takes QVariant
+ {
+ m_myObject->resetQtFunctionInvoked();
+ QVERIFY(!m_engine->evaluate("myObject.myInvokableWithVariantArg")
+ .call(QScriptValue(), QScriptValueList() << o).isError());
+ QCOMPARE(m_myObject->qtFunctionInvoked(), 15);
+ QCOMPARE(m_myObject->qtFunctionActuals().size(), 1);
+ QCOMPARE(m_myObject->qtFunctionActuals().at(0).type(), QVariant::Map);
+ QCOMPARE(m_myObject->qtFunctionActuals().at(0).toMap(), expected);
+ }
+}
+
QTEST_MAIN(tst_QScriptExtQObject)
#include "tst_qscriptextqobject.moc"
diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
index aa9fa15..8aa4e711 100644
--- a/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
+++ b/tests/auto/qscriptvalue/tst_qscriptvalue.cpp
@@ -1270,7 +1270,7 @@ void tst_QScriptValue::toVariant_old()
QCOMPARE(opaque.toVariant(), var);
QScriptValue object = eng.newObject();
- QCOMPARE(object.toVariant(), QVariant(QString("[object Object]")));
+ QCOMPARE(object.toVariant(), QVariant(QVariantMap()));
QScriptValue qobject = eng.newQObject(this);
{
@@ -2296,7 +2296,7 @@ void tst_QScriptValue::getSetScriptClass()
QCOMPARE(obj.scriptClass(), (QScriptClass*)&testClass);
QVERIFY(obj.isObject());
QVERIFY(!obj.isVariant());
- QVERIFY(!obj.toVariant().isValid());
+ QCOMPARE(obj.toVariant(), QVariant(QVariantMap()));
}
{
QScriptValue obj = eng.newQObject(this);
@@ -3472,4 +3472,89 @@ void tst_QScriptValue::objectId()
QVERIFY(obj.strictlyEquals(eng.globalObject()));
}
+void tst_QScriptValue::nestedObjectToVariant_data()
+{
+ QTest::addColumn<QString>("program");
+ QTest::addColumn<QVariant>("expected");
+
+ // Array literals
+ QTest::newRow("[[]]")
+ << QString::fromLatin1("[[]]")
+ << QVariant(QVariantList() << (QVariant(QVariantList())));
+ QTest::newRow("[[123]]")
+ << QString::fromLatin1("[[123]]")
+ << QVariant(QVariantList() << (QVariant(QVariantList() << 123)));
+ QTest::newRow("[[], 123]")
+ << QString::fromLatin1("[[], 123]")
+ << QVariant(QVariantList() << QVariant(QVariantList()) << 123);
+
+ // Cyclic arrays
+ QTest::newRow("var a=[]; a.push(a)")
+ << QString::fromLatin1("var a=[]; a.push(a); a")
+ << QVariant(QVariantList() << QVariant(QVariantList()));
+ QTest::newRow("var a=[]; a.push(123, a)")
+ << QString::fromLatin1("var a=[]; a.push(123, a); a")
+ << QVariant(QVariantList() << 123 << QVariant(QVariantList()));
+ QTest::newRow("var a=[]; var b=[]; a.push(b); b.push(a)")
+ << QString::fromLatin1("var a=[]; var b=[]; a.push(b); b.push(a); a")
+ << QVariant(QVariantList() << QVariant(QVariantList() << QVariant(QVariantList())));
+ QTest::newRow("var a=[]; var b=[]; a.push(123, b); b.push(456, a)")
+ << QString::fromLatin1("var a=[]; var b=[]; a.push(123, b); b.push(456, a); a")
+ << QVariant(QVariantList() << 123 << QVariant(QVariantList() << 456 << QVariant(QVariantList())));
+
+ // Object literals
+ {
+ QVariantMap m;
+ m["a"] = QVariantMap();
+ QTest::newRow("{ a:{} }")
+ << QString::fromLatin1("({ a:{} })")
+ << QVariant(m);
+ }
+ {
+ QVariantMap m, m2;
+ m2["b"] = 10;
+ m2["c"] = 20;
+ m["a"] = m2;
+ QTest::newRow("{ a:{b:10, c:20} }")
+ << QString::fromLatin1("({ a:{b:10, c:20} })")
+ << QVariant(m);
+ }
+ {
+ QVariantMap m;
+ m["a"] = 10;
+ m["b"] = QVariantList() << 20 << 30;
+ QTest::newRow("{ a:10, b:[20, 30]}")
+ << QString::fromLatin1("({ a:10, b:[20,30]})")
+ << QVariant(m);
+ }
+
+ // Cyclic objects
+ {
+ QVariantMap m;
+ m["p"] = QVariantMap();
+ QTest::newRow("var o={}; o.p=o")
+ << QString::fromLatin1("var o={}; o.p=o; o")
+ << QVariant(m);
+ }
+ {
+ QVariantMap m;
+ m["p"] = 123;
+ m["q"] = QVariantMap();
+ QTest::newRow("var o={}; o.p=123; o.q=o")
+ << QString::fromLatin1("var o={}; o.p=123; o.q=o; o")
+ << QVariant(m);
+ }
+}
+
+void tst_QScriptValue::nestedObjectToVariant()
+{
+ QScriptEngine eng;
+ QFETCH(QString, program);
+ QFETCH(QVariant, expected);
+ QScriptValue o = eng.evaluate(program);
+ QVERIFY(!o.isError());
+ QVERIFY(o.isObject());
+ QCOMPARE(o.toVariant(), expected);
+}
+
QTEST_MAIN(tst_QScriptValue)
diff --git a/tests/auto/qscriptvalue/tst_qscriptvalue.h b/tests/auto/qscriptvalue/tst_qscriptvalue.h
index aae35b2..8bfaa6a 100644
--- a/tests/auto/qscriptvalue/tst_qscriptvalue.h
+++ b/tests/auto/qscriptvalue/tst_qscriptvalue.h
@@ -225,6 +225,8 @@ private slots:
void engineDeleted();
void valueOfWithClosure();
void objectId();
+ void nestedObjectToVariant_data();
+ void nestedObjectToVariant();
private:
typedef void (tst_QScriptValue::*InitDataFunction)();
diff --git a/tools/assistant/tools/assistant/helpviewer_qwv.cpp b/tools/assistant/tools/assistant/helpviewer_qwv.cpp
index 244d091..dcbbf2c 100644
--- a/tools/assistant/tools/assistant/helpviewer_qwv.cpp
+++ b/tools/assistant/tools/assistant/helpviewer_qwv.cpp
@@ -172,6 +172,7 @@ private:
bool closeNewTabIfNeeded;
friend class HelpViewer;
+ QUrl m_loadingUrl;
Qt::MouseButtons m_pressedButtons;
Qt::KeyboardModifiers m_keyboardModifiers;
};
@@ -232,6 +233,11 @@ bool HelpPage::acceptNavigationRequest(QWebFrame *,
return false;
}
+ m_loadingUrl = url; // because of async page loading, we will hit some kind
+ // of race condition while using a remote command, like a combination of
+ // SetSource; SyncContent. SetSource would be called and SyncContents shortly
+ // afterwards, but the page might not have finished loading and the old url
+ // would be returned.
return true;
}
@@ -268,6 +274,7 @@ HelpViewer::HelpViewer(CentralWidget *parent, qreal zoom)
connect(page(), SIGNAL(linkHovered(QString,QString,QString)), this,
SIGNAL(highlighted(QString)));
connect(this, SIGNAL(urlChanged(QUrl)), this, SIGNAL(sourceChanged(QUrl)));
+ connect(this, SIGNAL(loadStarted()), this, SLOT(setLoadStarted()));
connect(this, SIGNAL(loadFinished(bool)), this, SLOT(setLoadFinished(bool)));
connect(page(), SIGNAL(printRequested(QWebFrame*)), this, SIGNAL(printRequested()));
@@ -333,10 +340,19 @@ bool HelpViewer::handleForwardBackwardMouseButtons(QMouseEvent *e)
return false;
}
+QUrl HelpViewer::source() const
+{
+ HelpPage *currentPage = static_cast<HelpPage*> (page());
+ if (currentPage && !hasLoadFinished()) {
+ // see HelpPage::acceptNavigationRequest(...)
+ return currentPage->m_loadingUrl;
+ }
+ return url();
+}
+
void HelpViewer::setSource(const QUrl &url)
{
TRACE_OBJ
- loadFinished = false;
load(url.toString() == QLatin1String("help") ? LocalHelpFile : url);
}
@@ -396,6 +412,11 @@ void HelpViewer::mousePressEvent(QMouseEvent *event)
QWebView::mousePressEvent(event);
}
+void HelpViewer::setLoadStarted()
+{
+ loadFinished = false;
+}
+
void HelpViewer::setLoadFinished(bool ok)
{
TRACE_OBJ
diff --git a/tools/assistant/tools/assistant/helpviewer_qwv.h b/tools/assistant/tools/assistant/helpviewer_qwv.h
index 2577828..1897e3e 100644
--- a/tools/assistant/tools/assistant/helpviewer_qwv.h
+++ b/tools/assistant/tools/assistant/helpviewer_qwv.h
@@ -71,8 +71,8 @@ public:
bool handleForwardBackwardMouseButtons(QMouseEvent *e);
+ QUrl source() const;
void setSource(const QUrl &url);
- inline QUrl source() const { return url(); }
inline QString documentTitle() const
{ return title(); }
@@ -109,6 +109,7 @@ protected:
private Q_SLOTS:
void actionChanged();
+ void setLoadStarted();
void setLoadFinished(bool ok);
private:
diff --git a/tools/qdoc3/ditaxmlgenerator.cpp b/tools/qdoc3/ditaxmlgenerator.cpp
index 197bc13..5f10885 100644
--- a/tools/qdoc3/ditaxmlgenerator.cpp
+++ b/tools/qdoc3/ditaxmlgenerator.cpp
@@ -501,19 +501,18 @@ QString DitaXmlGenerator::format()
}
/*!
- Create a new GUID, write it to the XML stream
- as an "id" attribute, and return it.
+ Calls lookupGuid() to get a GUID for \a text, then writes
+ it to the XML stream as an "id" attribute, and returns it.
*/
QString DitaXmlGenerator::writeGuidAttribute(QString text)
{
- QString guid = QUuid::createUuid().toString();
- name2guidMap.insert(text,guid);
+ QString guid = lookupGuid(text);
writer.writeAttribute("id",guid);
return guid;
}
/*!
- Looks up \a text in the GUID map. It it finds \a text,
+ Looks up \a text in the GUID map. If it finds \a text,
it returns the associated GUID. Otherwise it inserts
\a text into the map with a new GUID, and it returns
the new GUID.
@@ -1436,6 +1435,12 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark
writer.writeStartElement(CXXCLASSACCESSSPECIFIER);
writer.writeAttribute("value",inner->accessString());
writer.writeEndElement(); // <cxxClassAccessSpecifier>
+ if (cn->isAbstract()) {
+ writer.writeStartElement(CXXCLASSABSTRACT);
+ writer.writeAttribute("name","abstract");
+ writer.writeAttribute("value","abstract");
+ writer.writeEndElement(); // </cxxClassAbstract>
+ }
writeDerivations(cn, marker);
writeLocation(cn, marker);
writer.writeEndElement(); // <cxxClassDefinition>
@@ -1452,6 +1457,26 @@ DitaXmlGenerator::generateClassLikeNode(const InnerNode* inner, CodeMarker* mark
writer.writeEndElement(); // </apiDesc>
writer.writeEndElement(); // </cxxClassDetail>
+
+ sections = marker->sections(inner, CodeMarker::Detailed, CodeMarker::Okay);
+ s = sections.begin();
+ while (s != sections.end()) {
+ if ((*s).name == "Member Function Documentation") {
+ writeFunctions((*s),cn,marker);
+ }
+ else if ((*s).name == "Member Type Documentation") {
+ writeNestedClasses((*s),cn,marker);
+ writeEnumerations((*s),cn,marker);
+ writeTypedefs((*s),cn,marker);
+ }
+ else if ((*s).name == "Member Variable Documentation") {
+ writeDataMembers((*s),cn,marker);
+ }
+ else if ((*s).name == "Property Documentation") {
+ writeProperties((*s),cn,marker);
+ }
+ ++s;
+ }
writer.writeEndElement(); // </cxxClass>
}
@@ -4475,6 +4500,31 @@ void DitaXmlGenerator::generatePageIndex(const QString& fileName, CodeMarker* ma
#endif
+/*!
+ Return the full qualification of the node \a n, but without
+ the name of \a n itself. e.g. A::B::C
+ */
+QString DitaXmlGenerator::fullQualification(const Node* n)
+{
+ QString fq;
+ InnerNode* in = n->parent();
+ while (in) {
+ if ((in->type() == Node::Class) ||
+ (in->type() == Node::Namespace)) {
+ if (in->name().isEmpty())
+ break;
+ if (fq.isEmpty())
+ fq = in->name();
+ else
+ fq = in->name() + "::" + fq;
+ }
+ else
+ break;
+ in = in->parent();
+ }
+ return fq;
+}
+
void DitaXmlGenerator::writeDerivations(const ClassNode* cn, CodeMarker* marker)
{
QList<RelatedClass>::ConstIterator r;
@@ -4502,19 +4552,168 @@ void DitaXmlGenerator::writeDerivations(const ClassNode* cn, CodeMarker* marker)
}
}
-void DitaXmlGenerator::writeLocation(const ClassNode* cn, CodeMarker* marker)
+void DitaXmlGenerator::writeLocation(const Node* n, CodeMarker* marker)
{
- writer.writeStartElement(CXXCLASSAPIITEMLOCATION);
- writer.writeStartElement(CXXCLASSDECLARATIONFILE);
+ QString s1, s2, s3;
+ if (n->type() == Node::Class) {
+ s1 = CXXCLASSAPIITEMLOCATION;
+ s2 = CXXCLASSDECLARATIONFILE;
+ s3 = CXXCLASSDECLARATIONFILELINE;
+ }
+ else if (n->type() == Node::Function) {
+ s1 = CXXFUNCTIONAPIITEMLOCATION;
+ s2 = CXXFUNCTIONDECLARATIONFILE;
+ s3 = CXXFUNCTIONDECLARATIONFILELINE;
+ }
+ writer.writeStartElement(s1);
+ writer.writeStartElement(s2);
writer.writeAttribute("name","filePath");
- writer.writeAttribute("value",cn->location().filePath());
- writer.writeEndElement(); // </cxxClassDeclarationFile>
- writer.writeStartElement(CXXCLASSDECLARATIONFILELINE);
+ writer.writeAttribute("value",n->location().filePath());
+ writer.writeEndElement(); // </cxx<s2>DeclarationFile>
+ writer.writeStartElement(s3);
writer.writeAttribute("name","lineNumber");
QString lineNr;
- writer.writeAttribute("value",lineNr.setNum(cn->location().lineNo()));
- writer.writeEndElement(); // </cxxClassDeclarationFileLine>
- writer.writeEndElement(); // </cxxClassApiItemLocation>
+ writer.writeAttribute("value",lineNr.setNum(n->location().lineNo()));
+ writer.writeEndElement(); // </cxx<s3>DeclarationFileLine>
+ writer.writeEndElement(); // </cxx<s1>ApiItemLocation>
+}
+
+void DitaXmlGenerator::writeFunctions(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker)
+{
+ NodeList::ConstIterator m = s.members.begin();
+ while (m != s.members.end()) {
+ if ((*m)->type() == Node::Function) {
+ const FunctionNode* fn = reinterpret_cast<const FunctionNode*>(*m);
+ QString name = fn->name();
+ writer.writeStartElement(CXXFUNCTION);
+ writeGuidAttribute(name);
+ writer.writeStartElement(APINAME);
+ writer.writeCharacters(name);
+ writer.writeEndElement(); // </apiName>
+ generateBrief(fn,marker);
+ writer.writeStartElement(CXXFUNCTIONDETAIL);
+ writer.writeStartElement(CXXFUNCTIONDEFINITION);
+ writer.writeStartElement(CXXFUNCTIONACCESSSPECIFIER);
+ writer.writeAttribute("value",fn->accessString());
+ writer.writeEndElement(); // <cxxFunctionAccessSpecifier>
+
+ if (fn->isStatic()) {
+ writer.writeStartElement(CXXFUNCTIONSTORAGECLASSSPECIFIERSTATIC);
+ writer.writeAttribute("name","static");
+ writer.writeAttribute("value","static");
+ writer.writeEndElement(); // <cxxFunctionStorageClassSpecifierStatic>
+ }
+
+ if (fn->isConst()) {
+ writer.writeStartElement(CXXFUNCTIONCONST);
+ writer.writeAttribute("name","const");
+ writer.writeAttribute("value","const");
+ writer.writeEndElement(); // <cxxFunctionConst>
+ }
+
+ if (fn->virtualness() != FunctionNode::NonVirtual) {
+ writer.writeStartElement(CXXFUNCTIONVIRTUAL);
+ writer.writeAttribute("name","virtual");
+ writer.writeAttribute("value","virtual");
+ writer.writeEndElement(); // <cxxFunctionVirtual>
+ if (fn->virtualness() == FunctionNode::PureVirtual) {
+ writer.writeStartElement(CXXFUNCTIONPUREVIRTUAL);
+ writer.writeAttribute("name","pure virtual");
+ writer.writeAttribute("value","pure virtual");
+ writer.writeEndElement(); // <cxxFunctionPureVirtual>
+ }
+ }
+
+ if (fn->name() == cn->name()) {
+ writer.writeStartElement(CXXFUNCTIONCONSTRUCTOR);
+ writer.writeAttribute("name","constructor");
+ writer.writeAttribute("value","constructor");
+ writer.writeEndElement(); // <cxxFunctionConstructor>
+ }
+ else if (fn->name()[0] == QChar('~')) {
+ writer.writeStartElement(CXXFUNCTIONDESTRUCTOR);
+ writer.writeAttribute("name","destructor");
+ writer.writeAttribute("value","destructor");
+ writer.writeEndElement(); // <cxxFunctionDestructor>
+ }
+ else {
+ writer.writeStartElement(CXXFUNCTIONDECLAREDTYPE);
+ writer.writeCharacters(fn->returnType());
+ writer.writeEndElement(); // <cxxFunctionDeclaredType>
+ }
+ QString fq = fullQualification(fn);
+ if (!fq.isEmpty()) {
+ writer.writeStartElement(CXXFUNCTIONSCOPEDNAME);
+ writer.writeCharacters(fq);
+ writer.writeEndElement(); // <cxxFunctionScopedName>
+ }
+ writer.writeStartElement(CXXFUNCTIONPROTOTYPE);
+ writer.writeCharacters(fn->signature(true));
+ writer.writeEndElement(); // <cxxFunctionPrototype>
+
+ QString fnl = fn->signature(false);
+ int idx = fnl.indexOf(' ');
+ if (idx < 0)
+ idx = 0;
+ else
+ ++idx;
+ fnl = fn->parent()->name() + "::" + fnl.mid(idx);
+ writer.writeStartElement(CXXFUNCTIONNAMELOOKUP);
+ writer.writeCharacters(fnl);
+ writer.writeEndElement(); // <cxxFunctionNameLookup>
+
+ writeLocation(fn, marker);
+ writer.writeEndElement(); // <cxxFunctionDefinition>
+ writer.writeStartElement(APIDESC);
+
+ if (!fn->doc().isEmpty()) {
+ generateBody(fn, marker);
+ // generateAlsoList(inner, marker);
+ }
+
+ writer.writeEndElement(); // </apiDesc>
+ writer.writeEndElement(); // </cxxFunctionDetail>
+ writer.writeEndElement(); // </cxxFunction>
+
+ if (fn->metaness() == FunctionNode::Ctor ||
+ fn->metaness() == FunctionNode::Dtor ||
+ fn->overloadNumber() != 1) {
+ }
+ }
+ ++m;
+ }
+}
+
+void DitaXmlGenerator::writeNestedClasses(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker)
+{
+}
+
+void DitaXmlGenerator::writeEnumerations(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker)
+{
+}
+
+void DitaXmlGenerator::writeTypedefs(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker)
+{
+}
+
+void DitaXmlGenerator::writeDataMembers(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker)
+{
+}
+
+void DitaXmlGenerator::writeProperties(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker)
+{
}
QT_END_NAMESPACE
diff --git a/tools/qdoc3/ditaxmlgenerator.h b/tools/qdoc3/ditaxmlgenerator.h
index 070329b..71304b3 100644
--- a/tools/qdoc3/ditaxmlgenerator.h
+++ b/tools/qdoc3/ditaxmlgenerator.h
@@ -110,8 +110,28 @@ class DitaXmlGenerator : public PageGenerator
virtual QString linkForNode(const Node *node, const Node *relative);
virtual QString refForAtom(Atom *atom, const Node *node);
+ QString fullQualification(const Node* n);
+
void writeDerivations(const ClassNode* cn, CodeMarker* marker);
- void writeLocation(const ClassNode* cn, CodeMarker* marker);
+ void writeLocation(const Node* n, CodeMarker* marker);
+ void writeFunctions(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker);
+ void writeNestedClasses(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker);
+ void writeEnumerations(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker);
+ void writeTypedefs(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker);
+ void writeDataMembers(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker);
+ void writeProperties(const Section& s,
+ const ClassNode* cn,
+ CodeMarker* marker);
private:
enum SubTitleSize { SmallSubTitle, LargeSubTitle };
diff --git a/tools/qdoc3/node.cpp b/tools/qdoc3/node.cpp
index 4664e9d..b71a43e 100644
--- a/tools/qdoc3/node.cpp
+++ b/tools/qdoc3/node.cpp
@@ -789,6 +789,7 @@ ClassNode::ClassNode(InnerNode *parent, const QString& name)
: InnerNode(Class, parent, name)
{
hidden = false;
+ abstract = false;
setPageType(ApiPage);
}
@@ -1078,6 +1079,19 @@ FunctionNode::FunctionNode(Type type, InnerNode *parent, const QString& name, bo
}
/*!
+ Sets the \a virtualness of this function. If the \a virtualness
+ is PureVirtual, and if the parent() is a ClassNode, set the parent's
+ \e abstract flag to true.
+ */
+void FunctionNode::setVirtualness(Virtualness virtualness)
+{
+ vir = virtualness;
+ if ((virtualness == PureVirtual) && parent() &&
+ (parent()->type() == Node::Class))
+ parent()->setAbstract(true);
+}
+
+/*!
*/
void FunctionNode::setOverload(bool overlode)
{
diff --git a/tools/qdoc3/node.h b/tools/qdoc3/node.h
index 523394d..ccfd9b6 100644
--- a/tools/qdoc3/node.h
+++ b/tools/qdoc3/node.h
@@ -261,6 +261,8 @@ class InnerNode : public Node
QStringList secondaryKeys();
const QStringList& pageKeywords() const { return pageKeywds; }
virtual void addPageKeywords(const QString& t) { pageKeywds << t; }
+ virtual bool isAbstract() const { return false; }
+ virtual void setAbstract(bool ) { }
protected:
InnerNode(Type type, InnerNode *parent, const QString& name);
@@ -341,11 +343,14 @@ class ClassNode : public InnerNode
void setServiceName(const QString& value) { sname = value; }
QString qmlElement() const { return qmlelement; }
void setQmlElement(const QString& value) { qmlelement = value; }
+ virtual bool isAbstract() const { return abstract; }
+ virtual void setAbstract(bool b) { abstract = b; }
private:
QList<RelatedClass> bas;
QList<RelatedClass> der;
bool hidden;
+ bool abstract;
QString sname;
QString qmlelement;
};
@@ -582,7 +587,7 @@ class FunctionNode : public LeafNode
void setReturnType(const QString& returnType) { rt = returnType; }
void setParentPath(const QStringList& parentPath) { pp = parentPath; }
void setMetaness(Metaness metaness) { met = metaness; }
- void setVirtualness(Virtualness virtualness) { vir = virtualness; }
+ void setVirtualness(Virtualness virtualness);
void setConst(bool conste) { con = conste; }
void setStatic(bool statique) { sta = statique; }
void setOverload(bool overlode);
diff --git a/tools/qml/deviceorientation_maemo.cpp b/tools/qml/deviceorientation_maemo.cpp
index 7948e2a..443edc8 100644
--- a/tools/qml/deviceorientation_maemo.cpp
+++ b/tools/qml/deviceorientation_maemo.cpp
@@ -40,100 +40,87 @@
****************************************************************************/
#include "deviceorientation.h"
-#include <stdio.h>
-#include <stdlib.h>
+#include <QtDBus>
+
+#include <mce/mode-names.h>
+#include <mce/dbus-names.h>
class MaemoOrientation : public DeviceOrientation
{
Q_OBJECT
public:
MaemoOrientation()
- : DeviceOrientation(),m_current(Portrait), m_lastSeen(Portrait), m_lastSeenCount(0)
+ : o(UnknownOrientation)
{
- m_current = get();
- if (m_current == UnknownOrientation)
- m_current = Portrait;
+ // enable the orientation sensor
+ QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH,
+ MCE_REQUEST_IF, MCE_ACCELEROMETER_ENABLE_REQ));
+
+ // query the initial orientation
+ QDBusMessage reply = QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH,
+ MCE_REQUEST_IF, MCE_DEVICE_ORIENTATION_GET));
+ if (reply.type() == QDBusMessage::ErrorMessage) {
+ qWarning("Unable to retrieve device orientation: %s", qPrintable(reply.errorMessage()));
+ } else {
+ o = toOrientation(reply.arguments().value(0).toString());
+ }
- startTimer(100);
+ // connect to the orientation change signal
+ QDBusConnection::systemBus().connect(QString(), MCE_SIGNAL_PATH, MCE_SIGNAL_IF,
+ MCE_DEVICE_ORIENTATION_SIG,
+ this,
+ SLOT(deviceOrientationChanged(QString)));
}
- Orientation orientation() const {
- return m_current;
+ ~MaemoOrientation()
+ {
+ // disable the orientation sensor
+ QDBusConnection::systemBus().call(
+ QDBusMessage::createMethodCall(MCE_SERVICE, MCE_REQUEST_PATH,
+ MCE_REQUEST_IF, MCE_ACCELEROMETER_DISABLE_REQ));
}
- void setOrientation(Orientation) { }
-
-protected:
- virtual void timerEvent(QTimerEvent *)
+ inline Orientation orientation() const
{
- Orientation c = get();
-
- if (c == m_lastSeen) {
- m_lastSeenCount++;
- } else {
- m_lastSeenCount = 0;
- m_lastSeen = c;
- }
-
- if (m_lastSeen != UnknownOrientation && m_lastSeen != m_current && m_lastSeenCount > 4) {
- m_current = m_lastSeen;
- emit orientationChanged();
- printf("%d\n", m_current);
- }
+ return o;
}
-signals:
- void changed();
-
-private:
- Orientation m_current;
- Orientation m_lastSeen;
- int m_lastSeenCount;
-
- Orientation get()
+ void setOrientation(Orientation o)
{
- Orientation o = UnknownOrientation;
-
- int ax, ay, az;
-
- read(&ax, &ay, &az);
+ }
- if (abs(az) > 850) {
- o = UnknownOrientation;
- } else if (ax < -750) {
- o = Portrait;
- } else if (ax > 750) {
- o = PortraitInverted;
- } else if (ay < -750) {
- o = Landscape;
- } else if (ay > 750) {
- o = LandscapeInverted;
- }
+private Q_SLOTS:
+ void deviceOrientationChanged(const QString &newOrientation)
+ {
+ o = toOrientation(newOrientation);
- return o;
+ emit orientationChanged();
+// printf("%d\n", o);
}
- int read(int *ax,int *ay,int *az)
+private:
+ static Orientation toOrientation(const QString &nativeOrientation)
{
- static const char *accel_filename = "/sys/class/i2c-adapter/i2c-3/3-001d/coord";
-
- FILE *fd;
- int rs;
- fd = fopen(accel_filename, "r");
- if(fd==NULL){ printf("liqaccel, cannot open for reading\n"); return -1;}
- rs=fscanf((FILE*) fd,"%i %i %i",ax,ay,az);
- fclose(fd);
- if(rs != 3){ printf("liqaccel, cannot read information\n"); return -2;}
- return 0;
+ if (nativeOrientation == MCE_ORIENTATION_LANDSCAPE)
+ return Landscape;
+ else if (nativeOrientation == MCE_ORIENTATION_LANDSCAPE_INVERTED)
+ return LandscapeInverted;
+ else if (nativeOrientation == MCE_ORIENTATION_PORTRAIT)
+ return Portrait;
+ else if (nativeOrientation == MCE_ORIENTATION_PORTRAIT_INVERTED)
+ return PortraitInverted;
+ return UnknownOrientation;
}
-};
+private:
+ Orientation o;
+};
DeviceOrientation* DeviceOrientation::instance()
{
- static MaemoOrientation *o = 0;
- if (!o)
- o = new MaemoOrientation;
+ static MaemoOrientation *o = new MaemoOrientation;
return o;
}
diff --git a/tools/qml/main.cpp b/tools/qml/main.cpp
index 0cce1cc..a75023b 100644
--- a/tools/qml/main.cpp
+++ b/tools/qml/main.cpp
@@ -347,8 +347,9 @@ int main(int argc, char ** argv)
wflags |= Qt::WindowStaysOnTopHint;
QDeclarativeViewer *viewer = new QDeclarativeViewer(0, wflags);
+ viewer->setAttribute(Qt::WA_DeleteOnClose, true);
if (!scriptopts.isEmpty()) {
- QStringList options =
+ QStringList options =
scriptopts.split(QLatin1Char(','), QString::SkipEmptyParts);
QDeclarativeViewer::ScriptOptions scriptOptions = 0;
@@ -451,7 +452,5 @@ int main(int argc, char ** argv)
viewer->setUseGL(useGL);
viewer->raise();
- int rv = app.exec();
- delete viewer;
- exit(rv);
+ return app.exec();
}
diff --git a/tools/qml/qml.pri b/tools/qml/qml.pri
index cff65be..58d8cc1 100644
--- a/tools/qml/qml.pri
+++ b/tools/qml/qml.pri
@@ -18,6 +18,7 @@ SOURCES += $$PWD/qmlruntime.cpp \
RESOURCES = $$PWD/qmlruntime.qrc
maemo5 {
+ QT += dbus
SOURCES += $$PWD/deviceorientation_maemo.cpp
} else {
SOURCES += $$PWD/deviceorientation.cpp