aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--examples/quick/particles/affectors/content/attractor.qml6
-rw-r--r--examples/quick/particles/affectors/content/groupgoal.qml4
-rw-r--r--examples/quick/particles/affectors/content/move.qml6
-rw-r--r--examples/quick/particles/affectors/content/spritegoal.qml4
-rw-r--r--examples/quick/particles/affectors/content/turbulence.qml4
-rw-r--r--examples/quick/particles/customparticle/content/imagecolors.qml2
-rw-r--r--examples/quick/particles/emitters/content/burstandpulse.qml2
-rw-r--r--examples/quick/particles/emitters/content/customemitter.qml2
-rw-r--r--examples/quick/particles/emitters/content/emitmask.qml2
-rw-r--r--examples/quick/particles/emitters/content/maximumemitted.qml2
-rw-r--r--examples/quick/particles/emitters/content/shapeanddirection.qml2
-rw-r--r--examples/quick/particles/emitters/content/trailemitter.qml4
-rw-r--r--examples/quick/particles/emitters/content/velocityfrommotion.qml8
-rw-r--r--examples/quick/particles/imageparticle/content/colored.qml4
-rw-r--r--examples/quick/particles/imageparticle/content/colortable.qml2
-rw-r--r--examples/quick/particles/images.qrc3
-rw-r--r--examples/quick/particles/system/content/dynamiccomparison.qml4
-rw-r--r--examples/quick/particles/system/content/dynamicemitters.qml2
-rw-r--r--examples/quick/particles/system/content/multiplepainters.qml2
-rw-r--r--examples/quick/particles/system/content/startstop.qml2
-rw-r--r--examples/quick/particles/system/content/timedgroupchanges.qml2
-rw-r--r--src/imports/folderlistmodel/fileinfothread.cpp13
-rw-r--r--src/imports/folderlistmodel/fileinfothread_p.h4
-rw-r--r--src/imports/folderlistmodel/qquickfolderlistmodel.cpp10
-rw-r--r--src/particles/particleresources/fuzzydot.png (renamed from examples/quick/particles/images/particle4.png)bin1799 -> 1799 bytes
-rw-r--r--src/particles/particleresources/glowdot.png (renamed from examples/quick/particles/images/particle.png)bin861 -> 861 bytes
-rw-r--r--src/particles/particleresources/star.png (renamed from examples/quick/particles/images/star.png)bin1550 -> 1550 bytes
-rw-r--r--src/particles/particles.qrc3
-rw-r--r--src/particles/qquickimageparticle.cpp16
-rw-r--r--src/qml/qml/qqmlengine.cpp2
-rw-r--r--src/qml/qml/qqmlerror.cpp25
-rw-r--r--src/qml/qml/qqmlerror.h2
-rw-r--r--src/qml/qml/qqmlimport.cpp2
-rw-r--r--src/qml/qml/qqmljavascriptexpression.cpp9
-rw-r--r--src/qml/qml/qqmljavascriptexpression_p.h1
-rw-r--r--src/qml/qml/qqmlproperty.cpp5
-rw-r--r--src/qml/qml/qqmlxmlhttprequest.cpp5
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp1
-rw-r--r--src/qml/qml/v8/qv8bindings.cpp1
-rw-r--r--src/quick/doc/images/particles/fuzzydot.pngbin0 -> 1799 bytes
-rw-r--r--src/quick/doc/images/particles/glowdot.pngbin0 -> 861 bytes
-rw-r--r--src/quick/doc/images/particles/star.pngbin0 -> 1550 bytes
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp214
-rw-r--r--src/quick/items/context2d/qquickcontext2d_p.h3
-rw-r--r--src/quick/items/qquickitemsmodule.cpp3
-rw-r--r--src/quick/items/qquicktext.cpp80
-rw-r--r--src/quick/items/qquicktext_p.h8
-rw-r--r--src/quick/items/qquicktext_p_p.h4
-rw-r--r--src/quick/items/qquicktextcontrol.cpp26
-rw-r--r--src/quick/items/qquicktextcontrol_p.h2
-rw-r--r--src/quick/items/qquicktextcontrol_p_p.h2
-rw-r--r--src/quick/items/qquicktextedit.cpp107
-rw-r--r--src/quick/items/qquicktextedit_p.h9
-rw-r--r--src/quick/items/qquicktextedit_p_p.h1
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.cpp46
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode.h11
-rw-r--r--src/quick/scenegraph/coreapi/qsgnode_p.h76
-rw-r--r--src/quick/scenegraph/scenegraph.pri1
-rw-r--r--src/quick/scenegraph/util/qsgsimpletexturenode.cpp81
-rw-r--r--src/quick/scenegraph/util/qsgsimpletexturenode.h16
-rw-r--r--src/quick/util/qquickimageprovider.cpp2
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp2
-rw-r--r--tests/auto/qml/qquickfolderlistmodel/data/showDotAndDotDot.qml5
-rw-r--r--tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp49
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_context.qml91
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp168
-rw-r--r--tests/auto/quick/qquicktextedit/data/linkInteraction.qml (renamed from tests/auto/quick/qquicktextedit/data/linkActivated.qml)0
-rw-r--r--tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp179
-rw-r--r--tests/auto/shared/testhttpserver.cpp53
-rw-r--r--tests/auto/shared/testhttpserver.h5
-rw-r--r--tests/benchmarks/qml/animation/animation.pro5
-rw-r--r--tests/benchmarks/qml/compilation/tst_compilation.cpp6
-rw-r--r--tests/benchmarks/qml/creation/creation.pro3
-rw-r--r--tests/benchmarks/qml/creation/tst_creation.cpp8
-rw-r--r--tests/benchmarks/qml/holistic/testtypes.cpp14
-rw-r--r--tests/benchmarks/qml/painting/paintbenchmark.cpp5
-rw-r--r--tests/benchmarks/qml/pointers/pointers.pro2
-rw-r--r--tests/benchmarks/qml/pointers/tst_pointers.cpp2
-rw-r--r--tests/benchmarks/qml/qquickwindow/tst_qquickwindow.cpp4
-rw-r--r--tests/benchmarks/qml/typeimports/tst_typeimports.cpp2
81 files changed, 1247 insertions, 218 deletions
diff --git a/.qmake.conf b/.qmake.conf
index a7e09bffc3..4baafa83df 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,4 +1,4 @@
load(qt_build_config)
CONFIG += qt_example_installs
-MODULE_VERSION = 5.1.1
+MODULE_VERSION = 5.2.0
diff --git a/examples/quick/particles/affectors/content/attractor.qml b/examples/quick/particles/affectors/content/attractor.qml
index fd7fd65b9c..349132e61a 100644
--- a/examples/quick/particles/affectors/content/attractor.qml
+++ b/examples/quick/particles/affectors/content/attractor.qml
@@ -77,7 +77,7 @@ Rectangle {
ImageParticle {
id: stars
groups: ["stars"]
- source: "../../images/star.png"
+ source: "qrc:///particleresources/star.png"
color: "white"
colorVariation: 0.1
alpha: 0
@@ -96,7 +96,7 @@ Rectangle {
ImageParticle {
id: shot
groups: ["shot"]
- source: "../../images/star.png"
+ source: "qrc:///particleresources/star.png"
color: "#0FF06600"
colorVariation: 0.3
@@ -104,7 +104,7 @@ Rectangle {
ImageParticle {
id: engine
groups: ["engine"]
- source: "../../images/particle4.png"
+ source: "qrc:///particleresources/fuzzydot.png"
color: "orange"
SequentialAnimation on color {
diff --git a/examples/quick/particles/affectors/content/groupgoal.qml b/examples/quick/particles/affectors/content/groupgoal.qml
index 19fa041288..cf4361eb94 100644
--- a/examples/quick/particles/affectors/content/groupgoal.qml
+++ b/examples/quick/particles/affectors/content/groupgoal.qml
@@ -124,7 +124,7 @@ Rectangle {
id: smoke
anchors.fill: parent
groups: ["smoke"]
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
colorVariation: 0
color: "#00111111"
}
@@ -132,7 +132,7 @@ Rectangle {
id: pilot
anchors.fill: parent
groups: ["pilot"]
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
redVariation: 0.01
blueVariation: 0.4
color: "#0010004f"
diff --git a/examples/quick/particles/affectors/content/move.qml b/examples/quick/particles/affectors/content/move.qml
index b4d83318b0..e90f8c685c 100644
--- a/examples/quick/particles/affectors/content/move.qml
+++ b/examples/quick/particles/affectors/content/move.qml
@@ -50,7 +50,7 @@ Rectangle {
ImageParticle {
groups: ["A"]
anchors.fill: parent
- source: "../../images/star.png"
+ source: "qrc:///particleresources/star.png"
color:"#FF1010"
redVariation: 0.8
}
@@ -80,7 +80,7 @@ Rectangle {
ImageParticle {
groups: ["B"]
anchors.fill: parent
- source: "../../images/star.png"
+ source: "qrc:///particleresources/star.png"
color:"#10FF10"
greenVariation: 0.8
}
@@ -112,7 +112,7 @@ Rectangle {
ImageParticle {
groups: ["C"]
anchors.fill: parent
- source: "../../images/star.png"
+ source: "qrc:///particleresources/star.png"
color:"#1010FF"
blueVariation: 0.8
}
diff --git a/examples/quick/particles/affectors/content/spritegoal.qml b/examples/quick/particles/affectors/content/spritegoal.qml
index 78b161f25b..ab108bb065 100644
--- a/examples/quick/particles/affectors/content/spritegoal.qml
+++ b/examples/quick/particles/affectors/content/spritegoal.qml
@@ -66,7 +66,7 @@ Item {
ImageParticle {
system: sys
groups: ["starfield"]
- source: "../../images/star.png"
+ source: "qrc:///particleresources/star.png"
colorVariation: 0.3
color: "white"
}
@@ -170,7 +170,7 @@ Item {
z:0
system: sys
groups: ["exhaust"]
- source: "../../images/particle4.png"
+ source: "qrc:///particleresources/fuzzydot.png"
color: "orange"
SequentialAnimation on color {
diff --git a/examples/quick/particles/affectors/content/turbulence.qml b/examples/quick/particles/affectors/content/turbulence.qml
index d7a86039b4..eacedbe153 100644
--- a/examples/quick/particles/affectors/content/turbulence.qml
+++ b/examples/quick/particles/affectors/content/turbulence.qml
@@ -75,13 +75,13 @@ Rectangle {
ImageParticle {
groups: ["smoke"]
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
color: "#11111111"
colorVariation: 0
}
ImageParticle {
groups: ["flame"]
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
color: "#11ff400f"
colorVariation: 0.1
}
diff --git a/examples/quick/particles/customparticle/content/imagecolors.qml b/examples/quick/particles/customparticle/content/imagecolors.qml
index 130518a6f9..3fb4c9f378 100644
--- a/examples/quick/particles/customparticle/content/imagecolors.qml
+++ b/examples/quick/particles/customparticle/content/imagecolors.qml
@@ -71,7 +71,7 @@ Rectangle {
}
Image {
id: particle
- source: "../../images/particle4.png"
+ source: "qrc:///particleresources/fuzzydot.png"
}
//! [vertex]
vertexShader:"
diff --git a/examples/quick/particles/emitters/content/burstandpulse.qml b/examples/quick/particles/emitters/content/burstandpulse.qml
index 18d1c43933..28c56b326d 100644
--- a/examples/quick/particles/emitters/content/burstandpulse.qml
+++ b/examples/quick/particles/emitters/content/burstandpulse.qml
@@ -67,7 +67,7 @@ Rectangle {
id: particles
anchors.fill: parent
ImageParticle {
- source: "../../images/star.png"
+ source: "qrc:///particleresources/star.png"
alpha: 0
colorVariation: 0.6
}
diff --git a/examples/quick/particles/emitters/content/customemitter.qml b/examples/quick/particles/emitters/content/customemitter.qml
index 966c78e70f..9ad504ebc8 100644
--- a/examples/quick/particles/emitters/content/customemitter.qml
+++ b/examples/quick/particles/emitters/content/customemitter.qml
@@ -90,7 +90,7 @@ ParticleSystem {
}
ImageParticle {
- source: "../../images/particle4.png"
+ source: "qrc:///particleresources/fuzzydot.png"
alpha: 0.0
}
}
diff --git a/examples/quick/particles/emitters/content/emitmask.qml b/examples/quick/particles/emitters/content/emitmask.qml
index 08c04f6e5f..1c2e7b458f 100644
--- a/examples/quick/particles/emitters/content/emitmask.qml
+++ b/examples/quick/particles/emitters/content/emitmask.qml
@@ -51,7 +51,7 @@ Rectangle {
anchors.centerIn: parent
ImageParticle {
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
z: 2
anchors.fill: parent
color: "#336666CC"
diff --git a/examples/quick/particles/emitters/content/maximumemitted.qml b/examples/quick/particles/emitters/content/maximumemitted.qml
index df92f05f4b..4bd9079770 100644
--- a/examples/quick/particles/emitters/content/maximumemitted.qml
+++ b/examples/quick/particles/emitters/content/maximumemitted.qml
@@ -53,7 +53,7 @@ Rectangle {
ImageParticle {
system: sys
id: cp
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
colorVariation: 0.4
color: "#000000FF"
}
diff --git a/examples/quick/particles/emitters/content/shapeanddirection.qml b/examples/quick/particles/emitters/content/shapeanddirection.qml
index 1dec5b2fa7..0ca433cfba 100644
--- a/examples/quick/particles/emitters/content/shapeanddirection.qml
+++ b/examples/quick/particles/emitters/content/shapeanddirection.qml
@@ -58,7 +58,7 @@ Rectangle {
ImageParticle {
groups: ["center","edge"]
anchors.fill: parent
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
colorVariation: 0.1
color: "#009999FF"
}
diff --git a/examples/quick/particles/emitters/content/trailemitter.qml b/examples/quick/particles/emitters/content/trailemitter.qml
index a4972b7b73..3186b511ef 100644
--- a/examples/quick/particles/emitters/content/trailemitter.qml
+++ b/examples/quick/particles/emitters/content/trailemitter.qml
@@ -56,7 +56,7 @@ Rectangle {
system: particles
anchors.fill: parent
groups: ["A", "B"]
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
colorVariation: 0
color: "#00111111"
}
@@ -65,7 +65,7 @@ Rectangle {
anchors.fill: parent
system: particles
groups: ["C", "D"]
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
colorVariation: 0.1
color: "#00ff400f"
}
diff --git a/examples/quick/particles/emitters/content/velocityfrommotion.qml b/examples/quick/particles/emitters/content/velocityfrommotion.qml
index 1f1d6607d0..d325f9b7e1 100644
--- a/examples/quick/particles/emitters/content/velocityfrommotion.qml
+++ b/examples/quick/particles/emitters/content/velocityfrommotion.qml
@@ -61,7 +61,7 @@ Rectangle {
ParticleSystem { id: sys1 }
ImageParticle {
system: sys1
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
color: "cyan"
alpha: 0
SequentialAnimation on color {
@@ -127,7 +127,7 @@ Rectangle {
}
}
colorVariation: 0.5
- source: "../../images/star.png"
+ source: "qrc:///particleresources/star.png"
}
Emitter {
id: trailsStars
@@ -149,7 +149,7 @@ Rectangle {
}
ParticleSystem { id: sys3; }
ImageParticle {
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
system: sys3
color: "orange"
alpha: 0
@@ -191,7 +191,7 @@ Rectangle {
ParticleSystem { id: sys4; }
ImageParticle {
system: sys4
- source: "../../images/star.png"
+ source: "qrc:///particleresources/star.png"
color: "green"
alpha: 0
SequentialAnimation on color {
diff --git a/examples/quick/particles/imageparticle/content/colored.qml b/examples/quick/particles/imageparticle/content/colored.qml
index 939ec7e437..236cc0f372 100644
--- a/examples/quick/particles/imageparticle/content/colored.qml
+++ b/examples/quick/particles/imageparticle/content/colored.qml
@@ -50,7 +50,7 @@ Rectangle {
ImageParticle {
groups: ["stars"]
anchors.fill: parent
- source: "../../images/star.png"
+ source: "qrc:///particleresources/star.png"
}
Emitter {
group: "stars"
@@ -64,7 +64,7 @@ Rectangle {
// ![0]
ImageParticle {
anchors.fill: parent
- source: "../../images/star.png"
+ source: "qrc:///particleresources/star.png"
alpha: 0
alphaVariation: 0.2
colorVariation: 1.0
diff --git a/examples/quick/particles/imageparticle/content/colortable.qml b/examples/quick/particles/imageparticle/content/colortable.qml
index 4090163872..87b5ae2678 100644
--- a/examples/quick/particles/imageparticle/content/colortable.qml
+++ b/examples/quick/particles/imageparticle/content/colortable.qml
@@ -55,7 +55,7 @@ Rectangle {
alpha: 0
//! [0]
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
colorTable: "../../images/colortable.png"
sizeTable: "../../images/colortable.png"
//! [0]
diff --git a/examples/quick/particles/images.qrc b/examples/quick/particles/images.qrc
index 9f284a087d..1f754838a8 100644
--- a/examples/quick/particles/images.qrc
+++ b/examples/quick/particles/images.qrc
@@ -12,10 +12,8 @@
<file>images/meteor.png</file>
<file>images/meteors.png</file>
<file>images/nullRock.png</file>
- <file>images/particle.png</file>
<file>images/particle2.png</file>
<file>images/particle3.png</file>
- <file>images/particle4.png</file>
<file>images/particleA.png</file>
<file>images/portal_bg.png</file>
<file>images/realLeaf1.png</file>
@@ -27,7 +25,6 @@
<file>images/sizeInOut.png</file>
<file>images/snowflake.png</file>
<file>images/sparkleSize.png</file>
- <file>images/star.png</file>
<file>images/starfish_0.png</file>
<file>images/starfish_1.png</file>
<file>images/starfish_2.png</file>
diff --git a/examples/quick/particles/system/content/dynamiccomparison.qml b/examples/quick/particles/system/content/dynamiccomparison.qml
index 247a25a17d..9db7c0a1ec 100644
--- a/examples/quick/particles/system/content/dynamiccomparison.qml
+++ b/examples/quick/particles/system/content/dynamiccomparison.qml
@@ -52,7 +52,7 @@ Rectangle {
ImageParticle {
system: sys
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
color: "white"
colorVariation: 1.0
alpha: 0.1
@@ -90,7 +90,7 @@ Rectangle {
property int lifeSpan: 10000
width: 32
height: 32
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
y: 0
PropertyAnimation on y {from: -16; to: root.height-16; duration: container.lifeSpan; running: true}
SequentialAnimation on opacity {
diff --git a/examples/quick/particles/system/content/dynamicemitters.qml b/examples/quick/particles/system/content/dynamicemitters.qml
index 10ac33bd76..72ec1ffc23 100644
--- a/examples/quick/particles/system/content/dynamicemitters.qml
+++ b/examples/quick/particles/system/content/dynamicemitters.qml
@@ -51,7 +51,7 @@ Rectangle {
}
ImageParticle {
system: sys
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
color: "white"
colorVariation: 1.0
alpha: 0.1
diff --git a/examples/quick/particles/system/content/multiplepainters.qml b/examples/quick/particles/system/content/multiplepainters.qml
index 8a38874533..e0a1288588 100644
--- a/examples/quick/particles/system/content/multiplepainters.qml
+++ b/examples/quick/particles/system/content/multiplepainters.qml
@@ -91,6 +91,6 @@ Rectangle {
height: 240
width: root.width
z: 1
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
}
}
diff --git a/examples/quick/particles/system/content/startstop.qml b/examples/quick/particles/system/content/startstop.qml
index 5ce8729a43..e787919b05 100644
--- a/examples/quick/particles/system/content/startstop.qml
+++ b/examples/quick/particles/system/content/startstop.qml
@@ -69,7 +69,7 @@ Rectangle {
ImageParticle {
anchors.fill: parent
system: particles
- source: "../../images/star.png"
+ source: "qrc:///particleresources/star.png"
sizeTable: "../../images/sparkleSize.png"
alpha: 0
colorVariation: 0.6
diff --git a/examples/quick/particles/system/content/timedgroupchanges.qml b/examples/quick/particles/system/content/timedgroupchanges.qml
index 6443878a36..7131633769 100644
--- a/examples/quick/particles/system/content/timedgroupchanges.qml
+++ b/examples/quick/particles/system/content/timedgroupchanges.qml
@@ -119,7 +119,7 @@ Rectangle {
ImageParticle {
groups: ["works", "fire", "splode"]
- source: "../../images/particle.png"
+ source: "qrc:///particleresources/glowdot.png"
entryEffect: ImageParticle.Scale
}
}
diff --git a/src/imports/folderlistmodel/fileinfothread.cpp b/src/imports/folderlistmodel/fileinfothread.cpp
index 64a4b02e91..ad09f54381 100644
--- a/src/imports/folderlistmodel/fileinfothread.cpp
+++ b/src/imports/folderlistmodel/fileinfothread.cpp
@@ -57,7 +57,7 @@ FileInfoThread::FileInfoThread(QObject *parent)
sortUpdate(false),
showDirs(true),
showDirsFirst(false),
- showDotDot(false),
+ showDotAndDotDot(false),
showOnlyReadable(false)
{
#ifndef QT_NO_FILESYSTEMWATCHER
@@ -158,11 +158,12 @@ void FileInfoThread::setShowDirsFirst(bool show)
condition.wakeAll();
}
-void FileInfoThread::setShowDotDot(bool on)
+void FileInfoThread::setShowDotAndDotDot(bool on)
{
QMutexLocker locker(&mutex);
- showDotDot = on;
+ showDotAndDotDot = on;
folderUpdate = true;
+ needUpdate = true;
condition.wakeAll();
}
@@ -212,10 +213,12 @@ void FileInfoThread::run()
void FileInfoThread::getFileInfos(const QString &path)
{
QDir::Filters filter;
- filter = QDir::Files | QDir::NoDot | QDir::CaseSensitive;
+ filter = QDir::Files | QDir::CaseSensitive;
if (showDirs)
filter = filter | QDir::AllDirs | QDir::Drives;
- if ((path == rootPath) || !showDotDot)
+ if (!showDotAndDotDot)
+ filter = filter | QDir::NoDot | QDir::NoDotDot;
+ else if (path == rootPath)
filter = filter | QDir::NoDotDot;
if (showOnlyReadable)
filter = filter | QDir::Readable;
diff --git a/src/imports/folderlistmodel/fileinfothread_p.h b/src/imports/folderlistmodel/fileinfothread_p.h
index f9340ca75d..cf6572a279 100644
--- a/src/imports/folderlistmodel/fileinfothread_p.h
+++ b/src/imports/folderlistmodel/fileinfothread_p.h
@@ -72,7 +72,7 @@ public:
void setNameFilters(const QStringList & nameFilters);
void setShowDirs(bool showFolders);
void setShowDirsFirst(bool show);
- void setShowDotDot(bool on);
+ void setShowDotAndDotDot(bool on);
void setShowOnlyReadable(bool on);
public Q_SLOTS:
@@ -104,7 +104,7 @@ private:
bool sortUpdate;
bool showDirs;
bool showDirsFirst;
- bool showDotDot;
+ bool showDotAndDotDot;
bool showOnlyReadable;
};
diff --git a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
index 7ba2981a4e..85b59e9c73 100644
--- a/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
+++ b/src/imports/folderlistmodel/qquickfolderlistmodel.cpp
@@ -55,7 +55,7 @@ class QQuickFolderListModelPrivate
public:
QQuickFolderListModelPrivate(QQuickFolderListModel *q)
: q_ptr(q),
- sortField(QQuickFolderListModel::Name), sortReversed(false), showDirs(true), showDirsFirst(false), showDots(false), showOnlyReadable(false)
+ sortField(QQuickFolderListModel::Name), sortReversed(false), showDirs(true), showDirsFirst(false), showDotAndDotDot(false), showOnlyReadable(false)
{
nameFilters << QLatin1String("*");
}
@@ -72,7 +72,7 @@ public:
bool sortReversed;
bool showDirs;
bool showDirsFirst;
- bool showDots;
+ bool showDotAndDotDot;
bool showOnlyReadable;
~QQuickFolderListModelPrivate() {}
@@ -681,15 +681,15 @@ void QQuickFolderListModel::setShowDirsFirst(bool on)
bool QQuickFolderListModel::showDotAndDotDot() const
{
Q_D(const QQuickFolderListModel);
- return d->showDots;
+ return d->showDotAndDotDot;
}
void QQuickFolderListModel::setShowDotAndDotDot(bool on)
{
Q_D(QQuickFolderListModel);
- if (on != d->showDots) {
- d->fileInfoThread.setShowDotDot(on);
+ if (on != d->showDotAndDotDot) {
+ d->fileInfoThread.setShowDotAndDotDot(on);
}
}
diff --git a/examples/quick/particles/images/particle4.png b/src/particles/particleresources/fuzzydot.png
index bc95b703c1..bc95b703c1 100644
--- a/examples/quick/particles/images/particle4.png
+++ b/src/particles/particleresources/fuzzydot.png
Binary files differ
diff --git a/examples/quick/particles/images/particle.png b/src/particles/particleresources/glowdot.png
index 5c83896d22..5c83896d22 100644
--- a/examples/quick/particles/images/particle.png
+++ b/src/particles/particleresources/glowdot.png
Binary files differ
diff --git a/examples/quick/particles/images/star.png b/src/particles/particleresources/star.png
index 0d592cfa87..0d592cfa87 100644
--- a/examples/quick/particles/images/star.png
+++ b/src/particles/particleresources/star.png
Binary files differ
diff --git a/src/particles/particles.qrc b/src/particles/particles.qrc
index 344f9489a4..582520405f 100644
--- a/src/particles/particles.qrc
+++ b/src/particles/particles.qrc
@@ -1,5 +1,8 @@
<RCC>
<qresource prefix="/">
<file>particleresources/noise.png</file>
+ <file>particleresources/fuzzydot.png</file>
+ <file>particleresources/glowdot.png</file>
+ <file>particleresources/star.png</file>
</qresource>
</RCC>
diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp
index d571641bad..0145ce4edb 100644
--- a/src/particles/qquickimageparticle.cpp
+++ b/src/particles/qquickimageparticle.cpp
@@ -623,6 +623,22 @@ void fillUniformArrayFromImage(float* array, const QImage& img, int size)
The source image to be used.
If the image is a sprite animation, use the sprite property instead.
+
+ Since Qt 5.2, some default images are provided as resources to aid prototyping:
+ \table
+ \row
+ \li qrc:///particleresources/star.png
+ \li \inlineimage particles/star.png
+ \row
+ \li qrc:///particleresources/glowdot.png
+ \li \inlineimage particles/glowdot.png
+ \row
+ \li qrc:///particleresources/fuzzydot.png
+ \li \inlineimage particles/fuzzydot.png
+ \endtable
+
+ Note that the images are white and semi-transparent, to allow colorization
+ and alpha levels to have maximum effect.
*/
/*!
\qmlproperty list<Sprite> QtQuick.Particles2::ImageParticle::sprites
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index b36f35f3eb..673fbfefbb 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -2230,7 +2230,7 @@ bool QQml_isFileCaseCorrect(const QString &fileName, int lengthIn /* = -1 */)
QFileInfo info(fileName);
const QString absolute = info.absoluteFilePath();
-#if defined(Q_OS_MAC) || defined(Q_OS_WINCE)
+#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
const QString canonical = info.canonicalFilePath();
#elif defined(Q_OS_WIN)
wchar_t buffer[1024];
diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp
index 98d8259dda..0c8e46bd8d 100644
--- a/src/qml/qml/qqmlerror.cpp
+++ b/src/qml/qml/qqmlerror.cpp
@@ -84,10 +84,11 @@ public:
QString description;
quint16 line;
quint16 column;
+ QObject *object;
};
QQmlErrorPrivate::QQmlErrorPrivate()
-: line(0), column(0)
+: line(0), column(0), object()
{
}
@@ -122,6 +123,7 @@ QQmlError &QQmlError::operator=(const QQmlError &other)
d->description = other.d->description;
d->line = other.d->line;
d->column = other.d->column;
+ d->object = other.d->object;
}
return *this;
}
@@ -215,6 +217,27 @@ void QQmlError::setColumn(int column)
}
/*!
+ Returns the nearest object where this error occurred.
+ Exceptions in bound property expressions set this to the object
+ to which the property belongs. It will be 0 for all
+ other exceptions.
+ */
+QObject *QQmlError::object() const
+{
+ if (d) return d->object;
+ else return 0;
+}
+
+/*!
+ Sets the nearest \a object where this error occurred.
+ */
+void QQmlError::setObject(QObject *object)
+{
+ if (!d) d = new QQmlErrorPrivate;
+ d->object = object;
+}
+
+/*!
Returns the error as a human readable string.
*/
QString QQmlError::toString() const
diff --git a/src/qml/qml/qqmlerror.h b/src/qml/qml/qqmlerror.h
index cea9ee4cc0..cfa0dfcdbf 100644
--- a/src/qml/qml/qqmlerror.h
+++ b/src/qml/qml/qqmlerror.h
@@ -70,6 +70,8 @@ public:
void setLine(int);
int column() const;
void setColumn(int);
+ QObject *object() const;
+ void setObject(QObject *);
QString toString() const;
private:
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index 2fbb614605..50b2c8af0d 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -1463,7 +1463,7 @@ QString QQmlImportDatabase::resolvePlugin(QQmlTypeLoader *typeLoader,
const QString &qmldirPath, const QString &qmldirPluginPath,
const QString &baseName)
{
-#if defined(Q_OS_WIN32) || defined(Q_OS_WINCE)
+#if defined(Q_OS_WIN)
return resolvePlugin(typeLoader, qmldirPath, qmldirPluginPath, baseName,
QStringList()
# ifdef QT_DEBUG
diff --git a/src/qml/qml/qqmljavascriptexpression.cpp b/src/qml/qml/qqmljavascriptexpression.cpp
index 4568307d5b..2a1ed1406a 100644
--- a/src/qml/qml/qqmljavascriptexpression.cpp
+++ b/src/qml/qml/qqmljavascriptexpression.cpp
@@ -79,6 +79,11 @@ void QQmlDelayedError::setErrorDescription(const QString &description)
m_error.setDescription(description);
}
+void QQmlDelayedError::setErrorObject(QObject *object)
+{
+ m_error.setObject(object);
+}
+
/*
Converting from a message to an error is relatively expensive.
@@ -348,6 +353,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
error.setDescription(QLatin1String("Exception occurred during function compilation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
+ error.setObject(scope);
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
@@ -360,6 +366,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
error.setDescription(QLatin1String("Exception occurred during function evaluation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
+ error.setObject(scope);
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
@@ -390,6 +397,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
error.setDescription(QLatin1String("Exception occurred during function compilation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
+ error.setObject(scope);
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
@@ -402,6 +410,7 @@ QQmlJavaScriptExpression::evalFunction(QQmlContextData *ctxt, QObject *scope,
error.setDescription(QLatin1String("Exception occurred during function evaluation"));
error.setLine(line);
error.setUrl(QUrl::fromLocalFile(filename));
+ error.setObject(scope);
v8::Local<v8::Message> message = tc.Message();
if (!message.IsEmpty())
QQmlExpressionPrivate::exceptionToError(message, error);
diff --git a/src/qml/qml/qqmljavascriptexpression_p.h b/src/qml/qml/qqmljavascriptexpression_p.h
index c48972e6a1..b521ea3bee 100644
--- a/src/qml/qml/qqmljavascriptexpression_p.h
+++ b/src/qml/qml/qqmljavascriptexpression_p.h
@@ -84,6 +84,7 @@ public:
void setMessage(v8::Handle<v8::Message> message);
void setErrorLocation(const QUrl &url, quint16 line, quint16 column);
void setErrorDescription(const QString &description);
+ void setErrorObject(QObject *object);
private:
void convertMessageToError(QQmlEngine *engine) const;
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 0baf450cbf..0936df59c4 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -1555,6 +1555,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
// we explicitly disallow this case to avoid confusion. Users can still store one
// in an array in a var property if they need to, but the common case is user error.
expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration."));
+ expression->delayedError()->setErrorObject(object);
return false;
}
@@ -1570,6 +1571,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
if (!result.IsEmpty() && result->IsFunction()
&& !result->ToObject()->GetHiddenValue(v8engine->bindingFlagKey()).IsEmpty()) {
expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration."));
+ expression->delayedError()->setErrorObject(object);
return false;
}
writeValueProperty(object, core, QVariant::fromValue(v8engine->scriptValueFromInternal(result)), context, flags);
@@ -1580,12 +1582,14 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
else
errorStr += QLatin1String(QMetaType::typeName(type));
expression->delayedError()->setErrorDescription(errorStr);
+ expression->delayedError()->setErrorObject(object);
return false;
} else if (result->IsFunction()) {
if (!result->ToObject()->GetHiddenValue(v8engine->bindingFlagKey()).IsEmpty())
expression->delayedError()->setErrorDescription(QLatin1String("Invalid use of Qt.binding() in a binding declaration."));
else
expression->delayedError()->setErrorDescription(QLatin1String("Unable to assign a function to a property of any type other than var."));
+ expression->delayedError()->setErrorObject(object);
return false;
} else if (!writeValueProperty(object, core, value, context, flags)) {
@@ -1618,6 +1622,7 @@ bool QQmlPropertyPrivate::writeBinding(QObject *object,
QLatin1String(valueType) +
QLatin1String(" to ") +
QLatin1String(propertyType));
+ expression->delayedError()->setErrorObject(object);
return false;
}
diff --git a/src/qml/qml/qqmlxmlhttprequest.cpp b/src/qml/qml/qqmlxmlhttprequest.cpp
index 4fa9869564..be0c70c80a 100644
--- a/src/qml/qml/qqmlxmlhttprequest.cpp
+++ b/src/qml/qml/qqmlxmlhttprequest.cpp
@@ -1030,6 +1030,7 @@ private:
int m_status;
QString m_statusText;
QNetworkRequest m_request;
+ QStringList m_addedHeaders;
QQmlGuard<QNetworkReply> m_network;
void destroyNetwork();
@@ -1083,6 +1084,7 @@ v8::Handle<v8::Value> QQmlXMLHttpRequest::open(v8::Handle<v8::Object> me, const
m_method = method;
m_url = url;
m_state = Opened;
+ m_addedHeaders.clear();
v8::TryCatch tc;
dispatchCallback(me);
if (tc.HasCaught()) printError(tc.Message());
@@ -1093,10 +1095,11 @@ void QQmlXMLHttpRequest::addHeader(const QString &name, const QString &value)
{
QByteArray utfname = name.toUtf8();
- if (m_request.hasRawHeader(utfname)) {
+ if (m_addedHeaders.contains(name, Qt::CaseInsensitive)) {
m_request.setRawHeader(utfname, m_request.rawHeader(utfname) + ',' + value.toUtf8());
} else {
m_request.setRawHeader(utfname, value.toUtf8());
+ m_addedHeaders.append(name);
}
}
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp
index b680bf798b..668f7b4d05 100644
--- a/src/qml/qml/v4/qv4bindings.cpp
+++ b/src/qml/qml/v4/qv4bindings.cpp
@@ -793,6 +793,7 @@ static void throwException(int id, QQmlDelayedError *error,
error->setErrorDescription(QLatin1String("TypeError: Result of expression is not an object"));
else
error->setErrorDescription(description);
+ error->setErrorObject(context->contextObject);
if (id != 0xFF) {
quint32 e = *((quint32 *)(program->data() + program->exceptionDataOffset) + id);
error->setErrorLocation(context->url, (e >> 16), (e & 0xFFFF));
diff --git a/src/qml/qml/v8/qv8bindings.cpp b/src/qml/qml/v8/qv8bindings.cpp
index 8d133e728a..757d9d9cf6 100644
--- a/src/qml/qml/v8/qv8bindings.cpp
+++ b/src/qml/qml/v8/qv8bindings.cpp
@@ -191,6 +191,7 @@ void QV8Bindings::Binding::update(QQmlPropertyPrivate::WriteFlags flags)
delayedError()->setErrorLocation(parent->url(), instruction->line, 0);
if (hasError()) {
+ delayedError()->setErrorObject(object());
if (!delayedError()->addError(ep)) ep->warning(this->error(context->engine));
} else {
clearError();
diff --git a/src/quick/doc/images/particles/fuzzydot.png b/src/quick/doc/images/particles/fuzzydot.png
new file mode 100644
index 0000000000..bc95b703c1
--- /dev/null
+++ b/src/quick/doc/images/particles/fuzzydot.png
Binary files differ
diff --git a/src/quick/doc/images/particles/glowdot.png b/src/quick/doc/images/particles/glowdot.png
new file mode 100644
index 0000000000..5c83896d22
--- /dev/null
+++ b/src/quick/doc/images/particles/glowdot.png
Binary files differ
diff --git a/src/quick/doc/images/particles/star.png b/src/quick/doc/images/particles/star.png
new file mode 100644
index 0000000000..0d592cfa87
--- /dev/null
+++ b/src/quick/doc/images/particles/star.png
Binary files differ
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index be72de996c..8434c0fe0c 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -192,29 +192,153 @@ QColor qt_color_from_string(v8::Local<v8::Value> name)
return QColor();
}
-QFont qt_font_from_string(const QString& fontString) {
- QFont font;
- // ### this is simplified and incomplete
- // ### TODO:get code from Qt webkit
- const QStringList tokens = fontString.split(QLatin1Char(' '));
- foreach (const QString &token, tokens) {
- if (token == QLatin1String("italic"))
- font.setItalic(true);
- else if (token == QLatin1String("bold"))
- font.setBold(true);
- else if (token.endsWith(QLatin1String("px"))) {
- QString number = token;
- number.remove(QLatin1String("px"));
- //font.setPointSizeF(number.trimmed().toFloat());
- font.setPixelSize(number.trimmed().toInt());
- } else
- font.setFamily(token);
- }
-
- return font;
+static bool qSetFontSizeFromToken(QFont &font, const QString &fontSizeToken)
+{
+ const QString trimmedToken = fontSizeToken.trimmed();
+ QString unit = trimmedToken.right(2);
+ QString value = trimmedToken.left(fontSizeToken.size() - 2);
+ bool ok = false;
+ float size = value.trimmed().toFloat(&ok);
+ if (ok) {
+ int intSize = int(size);
+ if (unit.compare(QLatin1String("px")) == 0) {
+ font.setPixelSize(intSize);
+ return true;
+ } else if (unit.compare(QLatin1String("pt")) == 0) {
+ font.setPointSize(intSize);
+ return true;
+ }
+ }
+ qWarning().nospace() << "Context2D: A font size of " << fontSizeToken << " is invalid.";
+ return false;
}
+static bool qSetFontFamilyFromToken(QFont &font, const QString &fontFamilyToken)
+{
+ const QString trimmedToken = fontFamilyToken.trimmed();
+ QFontDatabase fontDatabase;
+ if (fontDatabase.hasFamily(trimmedToken)) {
+ font.setFamily(trimmedToken);
+ return true;
+ } else {
+ // Can't find a family matching this name; if it's a generic family,
+ // try searching for the default family for it by using style hints.
+ QFont tmp;
+ int styleHint = -1;
+ if (fontFamilyToken.compare(QLatin1String("serif")) == 0) {
+ styleHint = QFont::Serif;
+ } else if (fontFamilyToken.compare(QLatin1String("sans-serif")) == 0) {
+ styleHint = QFont::SansSerif;
+ } else if (fontFamilyToken.compare(QLatin1String("cursive")) == 0) {
+ styleHint = QFont::Cursive;
+ } else if (fontFamilyToken.compare(QLatin1String("monospace")) == 0) {
+ styleHint = QFont::Monospace;
+ } else if (fontFamilyToken.compare(QLatin1String("fantasy")) == 0) {
+ styleHint = QFont::Fantasy;
+ }
+ if (styleHint != -1) {
+ tmp.setStyleHint(static_cast<QFont::StyleHint>(styleHint));
+ font.setFamily(tmp.defaultFamily());
+ return true;
+ }
+ }
+ qWarning().nospace() << "Context2D: The font family " << fontFamilyToken << " is invalid.";
+ return false;
+}
+enum FontToken
+{
+ NoTokens = 0x00,
+ FontStyle = 0x01,
+ FontVariant = 0x02,
+ FontWeight = 0x04
+};
+
+#define Q_TRY_SET_TOKEN(token, value, setStatement) \
+if (!(usedTokens & token)) { \
+ usedTokens |= token; \
+ setStatement; \
+} else { \
+ qWarning().nospace() << "Context2D: Duplicate token " << QLatin1String(value) << " found in font string."; \
+ return currentFont; \
+}
+
+/*!
+ Parses a font string based on the CSS shorthand font property.
+
+ See: http://www.w3.org/TR/css3-fonts/#font-prop
+*/
+static QFont qt_font_from_string(const QString& fontString, const QFont &currentFont) {
+ const QStringList tokens = fontString.split(QLatin1Char(' '));
+ if (tokens.size() < 2) {
+ qWarning().nospace() << "Context2D: Insufficent amount of tokens in font string.";
+ return currentFont;
+ }
+
+ QFont newFont;
+ QStringList remainingTokens = tokens;
+ int usedTokens = NoTokens;
+ // Optional properties can be in any order, but font-size and font-family must be last.
+ while (remainingTokens.size() > 2) {
+ const QString token = remainingTokens.takeFirst();
+ if (token.compare(QLatin1String("normal")) == 0) {
+ if (!(usedTokens & FontStyle) || !(usedTokens & FontVariant) || !(usedTokens & FontWeight)) {
+ // Could be font-style, font-variant or font-weight.
+ if (!(usedTokens & FontStyle)) {
+ // QFont::StyleNormal is the default for QFont::style.
+ usedTokens = usedTokens | FontStyle;
+ } else if (!(usedTokens & FontVariant)) {
+ // QFont::MixedCase is the default for QFont::capitalization.
+ usedTokens |= FontVariant;
+ } else if (!(usedTokens & FontWeight)) {
+ // QFont::Normal is the default for QFont::weight.
+ usedTokens |= FontWeight;
+ }
+ } else {
+ qWarning().nospace() << "Context2D: Duplicate token \"normal\" found in font string.";
+ return currentFont;
+ }
+ } else if (token.compare(QLatin1String("bold")) == 0) {
+ Q_TRY_SET_TOKEN(FontWeight, "bold", newFont.setBold(true))
+ } else if (token.compare(QLatin1String("italic")) == 0) {
+ Q_TRY_SET_TOKEN(FontStyle, "italic", newFont.setStyle(QFont::StyleItalic))
+ } else if (token.compare(QLatin1String("oblique")) == 0) {
+ Q_TRY_SET_TOKEN(FontStyle, "oblique", newFont.setStyle(QFont::StyleOblique))
+ } else if (token.compare(QLatin1String("small-caps")) == 0) {
+ Q_TRY_SET_TOKEN(FontVariant, "small-caps", newFont.setCapitalization(QFont::SmallCaps))
+ } else {
+ bool conversionOk = false;
+ int weight = token.toInt(&conversionOk);
+ if (conversionOk) {
+ if (weight >= 0 && weight <= 99) {
+ Q_TRY_SET_TOKEN(FontWeight, "<font-weight>", newFont.setWeight(weight))
+ continue;
+ } else {
+ qWarning().nospace() << "Context2D: Invalid font weight " << weight << " found in font string; "
+ << "must be between 0 and 99, inclusive.";
+ return currentFont;
+ }
+ }
+ // The token is invalid or in the wrong place/order in the font string.
+ qWarning().nospace() << "Context2D: Invalid or misplaced token " << token << " found in font string.";
+ return currentFont;
+ }
+ }
+ if (remainingTokens.size() == 2) {
+ // Order must be: font-size font-family.
+ if (!qSetFontSizeFromToken(newFont, remainingTokens.first())) {
+ return currentFont;
+ }
+ if (!qSetFontFamilyFromToken(newFont, remainingTokens.last())) {
+ return currentFont;
+ }
+ return newFont;
+ } else {
+ qWarning().nospace() << "Context2D: Missing font-size and/or font-family tokens in font string.";
+ return currentFont;
+ }
+ return newFont;
+}
class QQuickContext2DEngineData : public QV8Engine::Deletable
{
@@ -2052,13 +2176,28 @@ static v8::Handle<v8::Value> ctx2d_caretBlinkRate(const v8::Arguments &args)
V8THROW_DOM(DOMEXCEPTION_NOT_SUPPORTED_ERR, "Context2D::caretBlinkRate is not supported");
}
-// text
+
/*!
- \qmlproperty string QtQuick2::Context2D::font
- Holds the current font settings.
+ \qmlproperty string QtQuick2::Context2D::font
+ Holds the current font settings.
- The default font value is "10px sans-serif".
- See \l {http://www.w3.org/TR/2dcontext/#dom-context-2d-font}{w3C 2d context standard for font}
+ A subset of the
+ \l {http://www.w3.org/TR/2dcontext/#dom-context-2d-font}{w3C 2d context standard for font}
+ is supported:
+
+ \list
+ \li font-style (optional):
+ normal | italic | oblique
+ \li font-variant (optional): normal | small-caps
+ \li font-weight (optional): normal | bold | 0 ... 99
+ \li font-size: Npx | Npt (where N is a positive number)
+ \li font-family: See \l {http://www.w3.org/TR/CSS2/fonts.html#propdef-font-family}
+ \endlist
+
+ Note that font-size and font-family are mandatory and must be in the order
+ they are shown in above.
+
+ The default font value is "10px sans-serif".
*/
v8::Handle<v8::Value> ctx2d_font(v8::Local<v8::String>, const v8::AccessorInfo &info)
{
@@ -2077,7 +2216,7 @@ static void ctx2d_font_set(v8::Local<v8::String>, v8::Local<v8::Value> value, co
QV8Engine *engine = V8ENGINE_ACCESSOR();
QString fs = engine->toString(value);
- QFont font = qt_font_from_string(fs);
+ QFont font = qt_font_from_string(fs, r->context->state.font);
if (font != r->context->state.font) {
r->context->state.font = font;
}
@@ -3695,7 +3834,6 @@ void QQuickContext2D::pushState()
void QQuickContext2D::reset()
{
QQuickContext2D::State newState;
- newState.matrix = QTransform();
m_path = QPainterPath();
@@ -3707,28 +3845,6 @@ void QQuickContext2D::reset()
newState.clipPath = defaultClipPath;
newState.clipPath.setFillRule(Qt::WindingFill);
- newState.strokeStyle = QColor("#000000");
- newState.fillStyle = QColor("#000000");
- newState.fillPatternRepeatX = false;
- newState.fillPatternRepeatY = false;
- newState.strokePatternRepeatX = false;
- newState.strokePatternRepeatY = false;
- newState.invertibleCTM = true;
- newState.fillRule = Qt::WindingFill;
- newState.globalAlpha = 1.0;
- newState.lineWidth = 1;
- newState.lineCap = Qt::FlatCap;
- newState.lineJoin = Qt::MiterJoin;
- newState.miterLimit = 10;
- newState.shadowOffsetX = 0;
- newState.shadowOffsetY = 0;
- newState.shadowBlur = 0;
- newState.shadowColor = qRgba(0, 0, 0, 0);
- newState.globalCompositeOperation = QPainter::CompositionMode_SourceOver;
- newState.font = QFont(QLatin1String("sans-serif"), 10);
- newState.textAlign = QQuickContext2D::Start;
- newState.textBaseline = QQuickContext2D::Alphabetic;
-
m_stateStack.clear();
m_stateStack.push(newState);
popState();
diff --git a/src/quick/items/context2d/qquickcontext2d_p.h b/src/quick/items/context2d/qquickcontext2d_p.h
index 24f5c44f18..6256249327 100644
--- a/src/quick/items/context2d/qquickcontext2d_p.h
+++ b/src/quick/items/context2d/qquickcontext2d_p.h
@@ -130,10 +130,11 @@ public:
, shadowBlur(0)
, shadowColor(qRgba(0, 0, 0, 0))
, globalCompositeOperation(QPainter::CompositionMode_SourceOver)
- , font(QFont(QLatin1String("sans-serif"), 10))
+ , font(QFont(QLatin1String("sans-serif")))
, textAlign(QQuickContext2D::Start)
, textBaseline(QQuickContext2D::Alphabetic)
{
+ font.setPixelSize(10);
}
QTransform matrix;
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 7f80697f3c..6f1edc718a 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -235,6 +235,9 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickListView, 1>(uri, 2, 1, "ListView");
qmlRegisterType<QQuickGridView, 1>(uri, 2, 1, "GridView");
qmlRegisterType<QQuickTextEdit, 1>(uri, 2, 1, "TextEdit");
+
+ qmlRegisterType<QQuickText, 2>(uri, 2, 2, "Text");
+ qmlRegisterType<QQuickTextEdit, 2>(uri, 2, 2, "TextEdit");
}
void QQuickItemsModule::defineModule()
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index b46f2e5ab9..cc2cbb3cb3 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -107,6 +107,7 @@ void QQuickTextPrivate::init()
Q_Q(QQuickText);
q->setAcceptedMouseButtons(Qt::LeftButton);
q->setFlag(QQuickItem::ItemHasContents);
+ q->setAcceptHoverEvents(true);
}
QQuickTextDocumentWithImageResources::QQuickTextDocumentWithImageResources(QQuickItem *parent)
@@ -2581,4 +2582,83 @@ void QQuickText::mouseReleaseEvent(QMouseEvent *event)
QQuickItem::mouseReleaseEvent(event);
}
+bool QQuickTextPrivate::isLinkHoveredConnected()
+{
+ Q_Q(QQuickText);
+ IS_SIGNAL_CONNECTED(q, QQuickText, linkHovered, (const QString &));
+}
+
+/*!
+ \qmlsignal QtQuick2::Text::onLinkHovered(string link)
+ \since QtQuick 2.2
+
+ This handler is called when the user hovers a link embedded in the
+ text. The link must be in rich text or HTML format and the \a link
+ string provides access to the particular link.
+
+ \sa hoveredLink
+*/
+
+/*!
+ \qmlproperty string QtQuick2::Text::hoveredLink
+ \since QtQuick 2.2
+
+ This property contains the link string when user hovers a link
+ embedded in the text. The link must be in rich text or HTML format
+ and the \a hoveredLink string provides access to the particular link.
+
+ \sa onLinkHovered
+*/
+
+QString QQuickText::hoveredLink() const
+{
+ Q_D(const QQuickText);
+ if (const_cast<QQuickTextPrivate *>(d)->isLinkHoveredConnected()) {
+ if (d->extra.isAllocated())
+ return d->extra->hoveredLink;
+ } else {
+#ifndef QT_NO_CURSOR
+ if (QQuickWindow *wnd = window()) {
+ QPointF pos = QCursor::pos(wnd->screen()) - wnd->position() - mapToScene(QPointF(0, 0));
+ return d->anchorAt(pos);
+ }
+#endif // QT_NO_CURSOR
+ }
+ return QString();
+}
+
+void QQuickTextPrivate::processHoverEvent(QHoverEvent *event)
+{
+ Q_Q(QQuickText);
+ QString link;
+ if (event->type() != QEvent::HoverLeave)
+ link = anchorAt(event->posF());
+
+ if ((!extra.isAllocated() && !link.isEmpty()) || (extra.isAllocated() && extra->hoveredLink != link)) {
+ extra.value().hoveredLink = link;
+ emit q->linkHovered(extra->hoveredLink);
+ }
+}
+
+void QQuickText::hoverEnterEvent(QHoverEvent *event)
+{
+ Q_D(QQuickText);
+ if (d->isLinkHoveredConnected())
+ d->processHoverEvent(event);
+}
+
+void QQuickText::hoverMoveEvent(QHoverEvent *event)
+{
+ Q_D(QQuickText);
+ if (d->isLinkHoveredConnected())
+ d->processHoverEvent(event);
+}
+
+void QQuickText::hoverLeaveEvent(QHoverEvent *event)
+{
+ Q_D(QQuickText);
+ if (d->isLinkHoveredConnected())
+ d->processHoverEvent(event);
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktext_p.h b/src/quick/items/qquicktext_p.h
index 03b436b3fb..f34cf17e5d 100644
--- a/src/quick/items/qquicktext_p.h
+++ b/src/quick/items/qquicktext_p.h
@@ -90,6 +90,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickText : public QQuickImplicitSizeItem
Q_PROPERTY(int minimumPointSize READ minimumPointSize WRITE setMinimumPointSize NOTIFY minimumPointSizeChanged)
Q_PROPERTY(FontSizeMode fontSizeMode READ fontSizeMode WRITE setFontSizeMode NOTIFY fontSizeModeChanged)
Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
+ Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION 2)
public:
QQuickText(QQuickItem *parent=0);
@@ -207,9 +208,12 @@ public:
RenderType renderType() const;
void setRenderType(RenderType renderType);
+ QString hoveredLink() const;
+
Q_SIGNALS:
void textChanged(const QString &text);
void linkActivated(const QString &link);
+ Q_REVISION(2) void linkHovered(const QString &link);
void fontChanged(const QFont &font);
void colorChanged();
void linkColorChanged();
@@ -243,6 +247,10 @@ protected:
void updatePolish();
+ void hoverEnterEvent(QHoverEvent *event);
+ void hoverMoveEvent(QHoverEvent *event);
+ void hoverLeaveEvent(QHoverEvent *event);
+
private Q_SLOTS:
void q_imagesLoaded();
void triggerPreprocess();
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index ff6b0f20be..7a31e77ae4 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -87,6 +87,8 @@ public:
QString elidedText(qreal lineWidth, const QTextLine &line, QTextLine *nextLine = 0) const;
void elideFormats(int start, int length, int offset, QList<QTextLayout::FormatRange> *elidedFormats);
+ void processHoverEvent(QHoverEvent *event);
+
QRectF layedOutTextRect;
struct ExtraData {
@@ -95,6 +97,7 @@ public:
qreal lineHeight;
QQuickTextDocumentWithImageResources *doc;
QString activeLink;
+ QString hoveredLink;
int minimumPixelSize;
int minimumPointSize;
int nbActiveDownloads;
@@ -167,6 +170,7 @@ public:
QRectF setupTextLayout(qreal * const baseline);
void setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset = 0);
bool isLinkActivatedConnected();
+ bool isLinkHoveredConnected();
static QString anchorAt(const QTextLayout *layout, const QPointF &mousePos);
QString anchorAt(const QPointF &pos) const;
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index e22c84879b..fce5e02b4d 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -720,6 +720,12 @@ void QQuickTextControl::processEvent(QEvent *e, const QMatrix &matrix)
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
d->mouseDoubleClickEvent(ev, matrix.map(ev->localPos()));
break; }
+ case QEvent::HoverEnter:
+ case QEvent::HoverMove:
+ case QEvent::HoverLeave: {
+ QHoverEvent *ev = static_cast<QHoverEvent *>(e);
+ d->hoverEvent(ev, matrix.map(ev->posF()));
+ break; }
#ifndef QT_NO_IM
case QEvent::InputMethod:
d->inputMethodEvent(static_cast<QInputMethodEvent *>(e));
@@ -1403,6 +1409,20 @@ void QQuickTextControlPrivate::focusEvent(QFocusEvent *e)
}
}
+void QQuickTextControlPrivate::hoverEvent(QHoverEvent *e, const QPointF &pos)
+{
+ Q_Q(QQuickTextControl);
+
+ QString link;
+ if (e->type() != QEvent::HoverLeave)
+ link = q->anchorAt(pos);
+
+ if (hoveredLink != link) {
+ hoveredLink = link;
+ emit q->linkHovered(link);
+ }
+}
+
bool QQuickTextControl::hasImState() const
{
Q_D(const QQuickTextControl);
@@ -1438,6 +1458,12 @@ QRectF QQuickTextControl::cursorRect() const
return cursorRect(d->cursor);
}
+QString QQuickTextControl::hoveredLink() const
+{
+ Q_D(const QQuickTextControl);
+ return d->hoveredLink;
+}
+
QString QQuickTextControl::anchorAt(const QPointF &pos) const
{
Q_D(const QQuickTextControl);
diff --git a/src/quick/items/qquicktextcontrol_p.h b/src/quick/items/qquicktextcontrol_p.h
index 7ec8a68b4c..bc5371b0c3 100644
--- a/src/quick/items/qquicktextcontrol_p.h
+++ b/src/quick/items/qquicktextcontrol_p.h
@@ -103,6 +103,7 @@ public:
QRectF selectionRect(const QTextCursor &cursor) const;
QRectF selectionRect() const;
+ QString hoveredLink() const;
QString anchorAt(const QPointF &pos) const;
void setCursorWidth(int width);
@@ -151,6 +152,7 @@ Q_SIGNALS:
void updateRequest();
void cursorRectangleChanged();
void linkActivated(const QString &link);
+ void linkHovered(const QString &link);
public:
virtual void processEvent(QEvent *e, const QMatrix &matrix);
diff --git a/src/quick/items/qquicktextcontrol_p_p.h b/src/quick/items/qquicktextcontrol_p_p.h
index da76de8ffe..e0bcbc2191 100644
--- a/src/quick/items/qquicktextcontrol_p_p.h
+++ b/src/quick/items/qquicktextcontrol_p_p.h
@@ -118,6 +118,7 @@ public:
#ifndef QT_NO_IM
void inputMethodEvent(QInputMethodEvent *);
#endif
+ void hoverEvent(QHoverEvent *e, const QPointF &pos);
void activateLinkUnderCursor(QString href = QString());
@@ -138,6 +139,7 @@ public:
QTextCursor selectedBlockOnTripleClick;
QString anchorOnMousePress;
QString linkToCopy;
+ QString hoveredLink;
QBasicTimer cursorBlinkTimer;
QBasicTimer tripleClickTimer;
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 327b0867e6..6e2262831d 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -272,6 +272,12 @@ QString QQuickTextEdit::text() const
The text to display. If the text format is AutoText the text edit will
automatically determine whether the text should be treated as
rich text. This determination is made using Qt::mightBeRichText().
+
+ The text-property is mostly suitable for setting the initial content and
+ handling modifications to relatively small text content. The append(),
+ insert() and remove() methods provide more fine-grained control and
+ remarkably better performance for modifying especially large rich text
+ content.
*/
void QQuickTextEdit::setText(const QString &text)
{
@@ -1953,6 +1959,8 @@ void QQuickTextEditPrivate::init()
#endif
q->setFlag(QQuickItem::ItemHasContents);
+ q->setAcceptHoverEvents(true);
+
document = new QQuickTextDocumentWithImageResources(q);
control = new QQuickTextControl(document, q);
@@ -1967,6 +1975,7 @@ void QQuickTextEditPrivate::init()
qmlobject_connect(control, QQuickTextControl, SIGNAL(cursorPositionChanged()), q, QQuickTextEdit, SIGNAL(cursorPositionChanged()));
qmlobject_connect(control, QQuickTextControl, SIGNAL(cursorRectangleChanged()), q, QQuickTextEdit, SLOT(moveCursorDelegate()));
qmlobject_connect(control, QQuickTextControl, SIGNAL(linkActivated(QString)), q, QQuickTextEdit, SIGNAL(linkActivated(QString)));
+ qmlobject_connect(control, QQuickTextControl, SIGNAL(linkHovered(QString)), q, QQuickTextEdit, SIGNAL(linkHovered(QString)));
qmlobject_connect(control, QQuickTextControl, SIGNAL(textChanged()), q, QQuickTextEdit, SLOT(q_textChanged()));
#ifndef QT_NO_CLIPBOARD
qmlobject_connect(QGuiApplication::clipboard(), QClipboard, SIGNAL(dataChanged()), q, QQuickTextEdit, SLOT(q_canPasteChanged()));
@@ -2468,4 +2477,102 @@ QQuickTextDocument *QQuickTextEdit::textDocument()
return d->quickDocument;
}
+bool QQuickTextEditPrivate::isLinkHoveredConnected()
+{
+ Q_Q(QQuickTextEdit);
+ IS_SIGNAL_CONNECTED(q, QQuickTextEdit, linkHovered, (const QString &));
+}
+
+/*!
+ \qmlsignal QtQuick2::TextEdit::onLinkHovered(string link)
+ \since QtQuick 2.2
+
+ This handler is called when the user hovers a link embedded in the text.
+ The link must be in rich text or HTML format and the
+ \a link string provides access to the particular link.
+
+ \sa hoveredLink
+*/
+
+/*!
+ \qmlproperty string QtQuick2::TextEdit::hoveredLink
+ \since QtQuick 2.2
+
+ This property contains the link string when user hovers a link
+ embedded in the text. The link must be in rich text or HTML format
+ and the link string provides access to the particular link.
+
+ \sa onLinkHovered
+*/
+
+QString QQuickTextEdit::hoveredLink() const
+{
+ Q_D(const QQuickTextEdit);
+ if (const_cast<QQuickTextEditPrivate *>(d)->isLinkHoveredConnected()) {
+ return d->control->hoveredLink();
+ } else {
+#ifndef QT_NO_CURSOR
+ if (QQuickWindow *wnd = window()) {
+ QPointF pos = QCursor::pos(wnd->screen()) - wnd->position() - mapToScene(QPointF(0, 0));
+ return d->control->anchorAt(pos);
+ }
+#endif // QT_NO_CURSOR
+ }
+ return QString();
+}
+
+void QQuickTextEdit::hoverEnterEvent(QHoverEvent *event)
+{
+ Q_D(QQuickTextEdit);
+ if (d->isLinkHoveredConnected())
+ d->control->processEvent(event, QPointF(-d->xoff, -d->yoff));
+}
+
+void QQuickTextEdit::hoverMoveEvent(QHoverEvent *event)
+{
+ Q_D(QQuickTextEdit);
+ if (d->isLinkHoveredConnected())
+ d->control->processEvent(event, QPointF(-d->xoff, -d->yoff));
+}
+
+void QQuickTextEdit::hoverLeaveEvent(QHoverEvent *event)
+{
+ Q_D(QQuickTextEdit);
+ if (d->isLinkHoveredConnected())
+ d->control->processEvent(event, QPointF(-d->xoff, -d->yoff));
+}
+
+/*!
+ \qmlmethod void QtQuick2::TextEdit::append(string text)
+ \since QtQuick 2.2
+
+ Appends a new paragraph with \a text to the end of the TextEdit.
+
+ In order to append without inserting a new paragraph,
+ call \c myTextEdit.insert(myTextEdit.length, text) instead.
+*/
+void QQuickTextEdit::append(const QString &text)
+{
+ Q_D(QQuickTextEdit);
+ QTextCursor cursor(d->document);
+ cursor.beginEditBlock();
+ cursor.movePosition(QTextCursor::End);
+
+ if (!d->document->isEmpty())
+ cursor.insertBlock();
+
+#ifndef QT_NO_TEXTHTMLPARSER
+ if (d->format == RichText || (d->format == AutoText && Qt::mightBeRichText(text))) {
+ cursor.insertHtml(text);
+ } else {
+ cursor.insertText(text);
+ }
+#else
+ cursor.insertText(text);
+#endif // QT_NO_TEXTHTMLPARSER
+
+ cursor.endEditBlock();
+ d->control->updateCursorRectangle(false);
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h
index 4e09eafcac..69ffad7e70 100644
--- a/src/quick/items/qquicktextedit_p.h
+++ b/src/quick/items/qquicktextedit_p.h
@@ -102,6 +102,7 @@ class Q_QUICK_PRIVATE_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem
Q_PROPERTY(QUrl baseUrl READ baseUrl WRITE setBaseUrl RESET resetBaseUrl NOTIFY baseUrlChanged)
Q_PROPERTY(RenderType renderType READ renderType WRITE setRenderType NOTIFY renderTypeChanged)
Q_PROPERTY(QQuickTextDocument *textDocument READ textDocument FINAL REVISION 1)
+ Q_PROPERTY(QString hoveredLink READ hoveredLink NOTIFY linkHovered REVISION 2)
public:
QQuickTextEdit(QQuickItem *parent=0);
@@ -255,6 +256,8 @@ public:
QQuickTextDocument *textDocument();
+ QString hoveredLink() const;
+
Q_SIGNALS:
void textChanged();
void contentSizeChanged();
@@ -282,6 +285,7 @@ Q_SIGNALS:
void selectByMouseChanged(bool selectByMouse);
void mouseSelectionModeChanged(SelectionMode mode);
void linkActivated(const QString &link);
+ Q_REVISION(2) void linkHovered(const QString &link);
void canPasteChanged();
void canUndoChanged();
void canRedoChanged();
@@ -310,6 +314,7 @@ public Q_SLOTS:
void redo();
void insert(int position, const QString &text);
void remove(int start, int end);
+ Q_REVISION(2) void append(const QString &text);
private Q_SLOTS:
void q_textChanged();
@@ -338,6 +343,10 @@ protected:
void focusInEvent(QFocusEvent *event);
void focusOutEvent(QFocusEvent *event);
+ void hoverEnterEvent(QHoverEvent *event);
+ void hoverMoveEvent(QHoverEvent *event);
+ void hoverLeaveEvent(QHoverEvent *event);
+
// mouse filter?
void mousePressEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index 4f0ab939f6..ec3cf1cec5 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -124,6 +124,7 @@ public:
void mirrorChange();
qreal getImplicitWidth() const;
Qt::LayoutDirection textDirection(const QString &text) const;
+ bool isLinkHoveredConnected();
void setNativeCursorEnabled(bool enabled) { control->setCursorWidth(enabled ? 1 : 0); }
void handleFocusEvent(QFocusEvent *event);
diff --git a/src/quick/scenegraph/coreapi/qsgnode.cpp b/src/quick/scenegraph/coreapi/qsgnode.cpp
index f30e95deb7..25f8f342c9 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.cpp
+++ b/src/quick/scenegraph/coreapi/qsgnode.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qsgnode.h"
+#include "qsgnode_p.h"
#include "qsgrenderer_p.h"
#include "qsgnodeupdater_p.h"
#include "qsgmaterial.h"
@@ -267,6 +268,26 @@ QSGNode::QSGNode(NodeType type)
}
/*!
+ * Constructs a new node with the given node type.
+ *
+ * \internal
+ */
+QSGNode::QSGNode(QSGNodePrivate &dd, NodeType type)
+ : m_parent(0)
+ , m_type(type)
+ , m_firstChild(0)
+ , m_lastChild(0)
+ , m_nextSibling(0)
+ , m_previousSibling(0)
+ , m_subtreeRenderableCount(type == GeometryNodeType || type == RenderNodeType ? 1 : 0)
+ , m_nodeFlags(OwnedByParent)
+ , m_dirtyState(0)
+ , d_ptr(&dd)
+{
+ init();
+}
+
+/*!
* \internal
*/
void QSGNode::init()
@@ -678,6 +699,18 @@ QSGBasicGeometryNode::QSGBasicGeometryNode(NodeType type)
/*!
+ \internal
+ */
+QSGBasicGeometryNode::QSGBasicGeometryNode(QSGBasicGeometryNodePrivate &dd, NodeType type)
+ : QSGNode(dd, type)
+ , m_geometry(0)
+ , m_matrix(0)
+ , m_clip_list(0)
+{
+}
+
+
+/*!
Deletes this QSGBasicGeometryNode.
If the node has the flag QSGNode::OwnsGeometry set, it will also delete the
@@ -808,6 +841,19 @@ QSGGeometryNode::QSGGeometryNode()
/*!
+ \internal
+ */
+QSGGeometryNode::QSGGeometryNode(QSGGeometryNodePrivate &dd)
+ : QSGBasicGeometryNode(dd, GeometryNodeType)
+ , m_render_order(0)
+ , m_material(0)
+ , m_opaque_material(0)
+ , m_opacity(1)
+{
+}
+
+
+/*!
Deletes this geometry node.
The flags QSGNode::OwnsMaterial, QSGNode::OwnsOpaqueMaterial and
diff --git a/src/quick/scenegraph/coreapi/qsgnode.h b/src/quick/scenegraph/coreapi/qsgnode.h
index 3fa2f7fc04..d83e6bcc81 100644
--- a/src/quick/scenegraph/coreapi/qsgnode.h
+++ b/src/quick/scenegraph/coreapi/qsgnode.h
@@ -58,6 +58,9 @@ class QSGRootNode;
class QSGGeometryNode;
class QSGTransformNode;
class QSGClipNode;
+class QSGNodePrivate;
+class QSGBasicGeometryNodePrivate;
+class QSGGeometryNodePrivate;
class Q_QUICK_EXPORT QSGNode
{
@@ -149,6 +152,7 @@ public:
protected:
QSGNode(NodeType type);
+ QSGNode(QSGNodePrivate &dd, NodeType type);
private:
friend class QSGRootNode;
@@ -167,7 +171,8 @@ private:
Flags m_nodeFlags;
DirtyState m_dirtyState;
- void *m_reserved;
+protected:
+ QScopedPointer<QSGNodePrivate> d_ptr;
};
class Q_QUICK_EXPORT QSGBasicGeometryNode : public QSGNode
@@ -184,6 +189,7 @@ public:
protected:
QSGBasicGeometryNode(NodeType type);
+ QSGBasicGeometryNode(QSGBasicGeometryNodePrivate &dd, NodeType type);
private:
friend class QSGNodeUpdater;
@@ -218,6 +224,9 @@ public:
void setInheritedOpacity(qreal opacity);
qreal inheritedOpacity() const { return m_opacity; }
+protected:
+ QSGGeometryNode(QSGGeometryNodePrivate &dd);
+
private:
friend class QSGNodeUpdater;
diff --git a/src/quick/scenegraph/coreapi/qsgnode_p.h b/src/quick/scenegraph/coreapi/qsgnode_p.h
new file mode 100644
index 0000000000..b0d8088af2
--- /dev/null
+++ b/src/quick/scenegraph/coreapi/qsgnode_p.h
@@ -0,0 +1,76 @@
+/****************************************************************************
+**
+** Copyright (C) 2013 Klaralvdalens Datakonsult AB (KDAB)
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtQml module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSGNODE_P_H
+#define QSGNODE_P_H
+
+#include <qglobal.h>
+
+QT_BEGIN_NAMESPACE
+
+class QSGNodePrivate
+{
+public:
+ QSGNodePrivate() {}
+ virtual ~QSGNodePrivate() {}
+};
+
+
+class QSGBasicGeometryNodePrivate : public QSGNodePrivate
+{
+public:
+ QSGBasicGeometryNodePrivate()
+ : QSGNodePrivate()
+ {}
+};
+
+
+class QSGGeometryNodePrivate: public QSGBasicGeometryNodePrivate
+{
+public:
+ QSGGeometryNodePrivate()
+ : QSGBasicGeometryNodePrivate()
+ {}
+};
+
+QT_END_NAMESPACE
+
+#endif // QSGNODE_P_H
diff --git a/src/quick/scenegraph/scenegraph.pri b/src/quick/scenegraph/scenegraph.pri
index c002a81451..34432ffd9c 100644
--- a/src/quick/scenegraph/scenegraph.pri
+++ b/src/quick/scenegraph/scenegraph.pri
@@ -6,6 +6,7 @@ HEADERS += \
$$PWD/coreapi/qsggeometry.h \
$$PWD/coreapi/qsgmaterial.h \
$$PWD/coreapi/qsgnode.h \
+ $$PWD/coreapi/qsgnode_p.h \
$$PWD/coreapi/qsgnodeupdater_p.h \
$$PWD/coreapi/qsgrenderer_p.h \
$$PWD/coreapi/qsgrendernode_p.h \
diff --git a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp
index 318120e4bf..86e0d36f6c 100644
--- a/src/quick/scenegraph/util/qsgsimpletexturenode.cpp
+++ b/src/quick/scenegraph/util/qsgsimpletexturenode.cpp
@@ -41,18 +41,44 @@
#include "qsgsimpletexturenode.h"
+#include <private/qsgnode_p.h>
QT_BEGIN_NAMESPACE
+class QSGSimpleTextureNodePrivate : public QSGGeometryNodePrivate
+{
+public:
+ QSGSimpleTextureNodePrivate()
+ : QSGGeometryNodePrivate()
+ , m_texCoordMode(QSGSimpleTextureNode::NoTransform)
+ {}
+
+ QSGSimpleTextureNode::TextureCoordinatesTransformMode m_texCoordMode;
+};
+
static void qsgsimpletexturenode_update(QSGGeometry *g,
QSGTexture *texture,
- const QRectF &rect)
+ const QRectF &rect,
+ QSGSimpleTextureNode::TextureCoordinatesTransformMode texCoordMode)
{
if (!texture)
return;
QSize ts = texture->textureSize();
QRectF sourceRect(0, 0, ts.width(), ts.height());
+
+ // Maybe transform the texture coordinates
+ if (texCoordMode.testFlag(QSGSimpleTextureNode::MirrorHorizontally)) {
+ float tmp = sourceRect.left();
+ sourceRect.setLeft(sourceRect.right());
+ sourceRect.setRight(tmp);
+ }
+ if (texCoordMode.testFlag(QSGSimpleTextureNode::MirrorVertically)) {
+ float tmp = sourceRect.top();
+ sourceRect.setTop(sourceRect.bottom());
+ sourceRect.setBottom(tmp);
+ }
+
QSGGeometry::updateTexturedRectGeometry(g, rect, texture->convertToNormalizedSourceRect(sourceRect));
}
@@ -71,7 +97,8 @@ static void qsgsimpletexturenode_update(QSGGeometry *g,
Constructs a new simple texture node
*/
QSGSimpleTextureNode::QSGSimpleTextureNode()
- : m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
+ : QSGGeometryNode(*new QSGSimpleTextureNodePrivate)
+ , m_geometry(QSGGeometry::defaultAttributes_TexturedPoint2D(), 4)
{
setGeometry(&m_geometry);
setMaterial(&m_material);
@@ -112,7 +139,8 @@ void QSGSimpleTextureNode::setRect(const QRectF &r)
if (m_rect == r)
return;
m_rect = r;
- qsgsimpletexturenode_update(&m_geometry, texture(), m_rect);
+ Q_D(QSGSimpleTextureNode);
+ qsgsimpletexturenode_update(&m_geometry, texture(), m_rect, d->m_texCoordMode);
markDirty(DirtyGeometry);
}
@@ -144,7 +172,8 @@ void QSGSimpleTextureNode::setTexture(QSGTexture *texture)
return;
m_material.setTexture(texture);
m_opaque_material.setTexture(texture);
- qsgsimpletexturenode_update(&m_geometry, texture, m_rect);
+ Q_D(QSGSimpleTextureNode);
+ qsgsimpletexturenode_update(&m_geometry, texture, m_rect, d->m_texCoordMode);
markDirty(DirtyMaterial);
}
@@ -158,4 +187,48 @@ QSGTexture *QSGSimpleTextureNode::texture() const
return m_material.texture();
}
+/*!
+ \enum QSGSimpleTextureNode::TextureCoordinatesTransformFlag
+
+ The TextureCoordinatesTransformFlag enum is used to specify the
+ mode used to generate texture coordinates for a textured quad.
+
+ \value NoTransform Texture coordinates are oriented with window coordinates
+ i.e. with origin at top-left.
+
+ \value MirrorHorizontally Texture coordinates are inverted in the horizontal axis with
+ respect to window coordinates
+
+ \value MirrorVertically Texture coordinates are inverted in the vertical axis with
+ respect to window coordinates
+ */
+
+/*!
+ Sets the method used to generate texture coordinates to \a mode. This can be used to obtain
+ correct orientation of the texture. This is commonly needed when using a third party OpenGL
+ library to render to texture as OpenGL has an inverted y-axis relative to Qt Quick.
+
+ \sa textureCoordinatesTransform()
+ */
+void QSGSimpleTextureNode::setTextureCoordinatesTransform(QSGSimpleTextureNode::TextureCoordinatesTransformMode mode)
+{
+ Q_D(QSGSimpleTextureNode);
+ if (d->m_texCoordMode == mode)
+ return;
+ d->m_texCoordMode = mode;
+ qsgsimpletexturenode_update(&m_geometry, texture(), m_rect, d->m_texCoordMode);
+ markDirty(DirtyMaterial);
+}
+
+/*!
+ Returns the mode used to generate texture coordinates for this node.
+
+ \sa setTextureCoordinatesTransform()
+ */
+QSGSimpleTextureNode::TextureCoordinatesTransformMode QSGSimpleTextureNode::textureCoordinatesTransform() const
+{
+ Q_D(const QSGSimpleTextureNode);
+ return d->m_texCoordMode;
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/scenegraph/util/qsgsimpletexturenode.h b/src/quick/scenegraph/util/qsgsimpletexturenode.h
index ffd10210ae..f5ab7fb3bb 100644
--- a/src/quick/scenegraph/util/qsgsimpletexturenode.h
+++ b/src/quick/scenegraph/util/qsgsimpletexturenode.h
@@ -48,6 +48,8 @@
QT_BEGIN_NAMESPACE
+class QSGSimpleTextureNodePrivate;
+
class Q_QUICK_EXPORT QSGSimpleTextureNode : public QSGGeometryNode
{
public:
@@ -63,14 +65,28 @@ public:
void setFiltering(QSGTexture::Filtering filtering);
QSGTexture::Filtering filtering() const;
+ enum TextureCoordinatesTransformFlag {
+ NoTransform = 0x00,
+ MirrorHorizontally = 0x01,
+ MirrorVertically = 0x02
+ };
+ Q_DECLARE_FLAGS(TextureCoordinatesTransformMode, TextureCoordinatesTransformFlag)
+
+ void setTextureCoordinatesTransform(TextureCoordinatesTransformMode mode);
+ TextureCoordinatesTransformMode textureCoordinatesTransform() const;
+
private:
QSGGeometry m_geometry;
QSGOpaqueTextureMaterial m_opaque_material;
QSGTextureMaterial m_material;
QRectF m_rect;
+
+ Q_DECLARE_PRIVATE(QSGSimpleTextureNode)
};
+Q_DECLARE_OPERATORS_FOR_FLAGS(QSGSimpleTextureNode::TextureCoordinatesTransformMode)
+
QT_END_NAMESPACE
#endif // QSGSIMPLETEXTURENODE_H
diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp
index 354c95bc2d..6fbba8ca2f 100644
--- a/src/quick/util/qquickimageprovider.cpp
+++ b/src/quick/util/qquickimageprovider.cpp
@@ -204,7 +204,7 @@ QImage QQuickTextureFactory::image() const
\image imageprovider.png
A complete example is available in Qt's
- \l {qml/imageprovider}{examples/qml/imageprovider}
+ \l {qml/imageprovider}{examples/quick/imageprovider}
directory. Note the example registers the provider via a \l{QQmlExtensionPlugin}{plugin}
instead of registering it in the application \c main() function as shown above.
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 23c32c163f..5e36a8a32d 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -2664,7 +2664,6 @@ void tst_QJSEngine::dateConversionJSQt()
QDateTime qtDate = jsDate.toDateTime();
QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate);
QString jsUTCDateStr = jsDate.property("toISOString").callWithInstance(jsDate).toString();
- jsUTCDateStr.remove(jsUTCDateStr.length() - 5, 4); // get rid of milliseconds (".000")
if (qtUTCDateStr != jsUTCDateStr)
QFAIL(qPrintable(jsDate.toString()));
secs += 2*60*60;
@@ -2678,7 +2677,6 @@ void tst_QJSEngine::dateConversionQtJS()
for (int i = 0; i < 8000; ++i) {
QJSValue jsDate = eng.toScriptValue(qtDate);
QString jsUTCDateStr = jsDate.property("toISOString").callWithInstance(jsDate).toString();
- jsUTCDateStr.remove(jsUTCDateStr.length() - 5, 4); // get rid of milliseconds (".000")
QString qtUTCDateStr = qtDate.toUTC().toString(Qt::ISODate);
if (jsUTCDateStr != qtUTCDateStr)
QFAIL(qPrintable(qtDate.toString()));
diff --git a/tests/auto/qml/qquickfolderlistmodel/data/showDotAndDotDot.qml b/tests/auto/qml/qquickfolderlistmodel/data/showDotAndDotDot.qml
new file mode 100644
index 0000000000..b65ace2f78
--- /dev/null
+++ b/tests/auto/qml/qquickfolderlistmodel/data/showDotAndDotDot.qml
@@ -0,0 +1,5 @@
+import Qt.labs.folderlistmodel 1.0
+
+FolderListModel {
+ showDotAndDotDot: false
+}
diff --git a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
index 9230608622..b845faca7d 100644
--- a/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
+++ b/tests/auto/qml/qquickfolderlistmodel/tst_qquickfolderlistmodel.cpp
@@ -77,6 +77,8 @@ private slots:
// WinCE does not have drive concept, so lets execute this test only on desktop Windows.
void changeDrive();
#endif
+ void showDotAndDotDot();
+ void showDotAndDotDot_data();
private:
void checkNoErrors(const QQmlComponent& component);
@@ -113,7 +115,7 @@ void tst_qquickfolderlistmodel::basicProperties()
QVERIFY(flm != 0);
flm->setProperty("folder", dataDirectoryUrl());
- QTRY_COMPARE(flm->property("count").toInt(),4); // wait for refresh
+ QTRY_COMPARE(flm->property("count").toInt(),5); // wait for refresh
QCOMPARE(flm->property("folder").toUrl(), dataDirectoryUrl());
QCOMPARE(flm->property("parentFolder").toUrl(), QUrl::fromLocalFile(QDir(directory()).canonicalPath()));
QCOMPARE(flm->property("sortField").toInt(), int(Name));
@@ -169,7 +171,7 @@ void tst_qquickfolderlistmodel::refresh()
QVERIFY(flm != 0);
flm->setProperty("folder", dataDirectoryUrl());
- QTRY_COMPARE(flm->property("count").toInt(),4); // wait for refresh
+ QTRY_COMPARE(flm->property("count").toInt(),5); // wait for refresh
int count = flm->rowCount();
@@ -228,6 +230,49 @@ void tst_qquickfolderlistmodel::changeDrive()
}
#endif
+void tst_qquickfolderlistmodel::showDotAndDotDot()
+{
+ QFETCH(QUrl, folder);
+ QFETCH(QUrl, rootFolder);
+ QFETCH(bool, showDotAndDotDot);
+ QFETCH(bool, showDot);
+ QFETCH(bool, showDotDot);
+
+ QQmlComponent component(&engine, testFileUrl("showDotAndDotDot.qml"));
+ checkNoErrors(component);
+
+ QAbstractListModel *flm = qobject_cast<QAbstractListModel*>(component.create());
+ QVERIFY(flm != 0);
+
+ flm->setProperty("folder", folder);
+ flm->setProperty("rootFolder", rootFolder);
+ flm->setProperty("showDotAndDotDot", showDotAndDotDot);
+
+ int count = 5;
+ if (showDot) count++;
+ if (showDotDot) count++;
+ QTRY_COMPARE(flm->property("count").toInt(), count); // wait for refresh
+
+ if (showDot)
+ QCOMPARE(flm->data(flm->index(0),FileNameRole).toString(), QLatin1String("."));
+ if (showDotDot)
+ QCOMPARE(flm->data(flm->index(1),FileNameRole).toString(), QLatin1String(".."));
+}
+
+void tst_qquickfolderlistmodel::showDotAndDotDot_data()
+{
+ QTest::addColumn<QUrl>("folder");
+ QTest::addColumn<QUrl>("rootFolder");
+ QTest::addColumn<bool>("showDotAndDotDot");
+ QTest::addColumn<bool>("showDot");
+ QTest::addColumn<bool>("showDotDot");
+
+ QTest::newRow("false") << dataDirectoryUrl() << QUrl() << false << false << false;
+ QTest::newRow("true") << dataDirectoryUrl() << QUrl() << true << true << true;
+ QTest::newRow("true but root") << dataDirectoryUrl() << dataDirectoryUrl() << true << true << false;
+
+}
+
QTEST_MAIN(tst_qquickfolderlistmodel)
#include "tst_qquickfolderlistmodel.moc"
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_context.qml b/tests/auto/quick/qquickcanvasitem/data/tst_context.qml
index b72e755ed9..ab351f0de8 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_context.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_context.qml
@@ -70,4 +70,95 @@ Canvas {
compare(canvas.contextInPaint, canvas.getContext("2d"));
}
}
+
+ // See: http://www.w3.org/TR/css3-fonts/#font-prop
+ TestCase {
+ name: "ContextFontValidation"
+ when: canvas.available
+
+ function test_pixelSize() {
+ wait(100);
+ compare(contextSpy.count, 1);
+
+ var ctx = canvas.getContext("2d");
+ compare(ctx.font, "sans-serif,-1,10,5,50,0,0,0,0,0");
+
+ ctx.font = "80.1px cursive";
+ // Can't verify the chosen font family since it's different for each platform.
+ compare(ctx.font.substr(ctx.font.indexOf(",") + 1), "-1,80,5,50,0,0,0,0,0");
+ }
+
+ function test_valid() {
+ wait(100);
+ compare(contextSpy.count, 1);
+
+ var ctx = canvas.getContext("2d");
+
+ var validFonts = [
+ { string: "12px sans-serif", expected: "sans-serif,-1,12,5,50,0,0,0,0,0" },
+ { string: "12px serif", expected: "serif,-1,12,5,50,0,0,0,0,0" },
+ { string: "12pt sans-serif", expected: "sans-serif,12,-1,5,50,0,0,0,0,0" },
+ { string: "12pt serif", expected: "serif,12,-1,5,50,0,0,0,0,0" },
+ { string: "normal 12px sans-serif", expected: "sans-serif,-1,12,5,50,0,0,0,0,0" },
+ { string: "normal normal 12px sans-serif", expected: "sans-serif,-1,12,5,50,0,0,0,0,0" },
+ { string: "normal normal normal 12px sans-serif", expected: "sans-serif,-1,12,5,50,0,0,0,0,0" },
+ { string: "italic 12px sans-serif", expected: "sans-serif,-1,12,5,50,1,0,0,0,0" },
+ { string: "italic normal 12px sans-serif", expected: "sans-serif,-1,12,5,50,1,0,0,0,0" },
+ { string: "italic normal normal 12px sans-serif", expected: "sans-serif,-1,12,5,50,1,0,0,0,0" },
+ { string: "oblique 12px sans-serif", expected: "sans-serif,-1,12,5,50,2,0,0,0,0" },
+ { string: "oblique normal 12px sans-serif", expected: "sans-serif,-1,12,5,50,2,0,0,0,0" },
+ { string: "oblique normal normal 12px sans-serif", expected: "sans-serif,-1,12,5,50,2,0,0,0,0" },
+ { string: "bold 12px sans-serif", expected: "sans-serif,-1,12,5,75,0,0,0,0,0" },
+ { string: "0 12px sans-serif", expected: "sans-serif,-1,12,5,0,0,0,0,0,0" },
+ { string: "small-caps 12px sans-serif", expected: "sans-serif,-1,12,5,50,0,0,0,0,0" },
+ ];
+ for (var i = 0; i < validFonts.length; ++i) {
+ ctx.font = validFonts[i].string;
+ compare(ctx.font.substr(ctx.font.indexOf(",") + 1),
+ validFonts[i].expected.substr(validFonts[i].expected.indexOf(",") + 1));
+ }
+ }
+
+ function test_invalid() {
+ wait(100);
+ compare(contextSpy.count, 1);
+
+ var ctx = canvas.getContext("2d");
+ var originalFont = ctx.font;
+ var i = 0;
+
+ var insufficientQtyTokens = ["", "12px", "sans-serif"];
+ for (i = 0; i < insufficientQtyTokens.length; ++i) {
+ ignoreWarning("Context2D: Insufficent amount of tokens in font string.");
+ ctx.font = insufficientQtyTokens[i];
+ compare(ctx.font, originalFont);
+ }
+
+ var invalidFontSizes = ["z12px sans-serif", "1z2px sans-serif", "12zpx sans-serif",
+ "12pzx sans-serif", "12pxz sans-serif", "sans-serif 12px"];
+ for (i = 0; i < invalidFontSizes.length; ++i) {
+ ignoreWarning("Context2D: A font size of \"" + invalidFontSizes[i].split(" ")[0] + "\" is invalid.");
+ ctx.font = invalidFontSizes[i];
+ compare(ctx.font, originalFont);
+ }
+
+ var invalidFontFamilies = ["12px !@weeeeeeee!@!@Don'tNameYourFontThis", "12px )(&*^^^%#$@*!!@#$JSPOR)"];
+ for (i = 0; i < invalidFontFamilies.length; ++i) {
+ ignoreWarning("Context2D: The font family \"" + invalidFontFamilies[i].split(" ")[1] + "\" is invalid.");
+ ctx.font = invalidFontFamilies[i];
+ compare(ctx.font, originalFont);
+ }
+
+ var duplicates = [
+ { duplicate: "normal", string: "normal normal normal normal 12px sans-serif" },
+ { duplicate: "bold", string: "normal normal bold bold 12px sans-serif" },
+ { duplicate: "bold", string: "bold bold 12px sans-serif" }
+ ];
+ for (i = 0; i < duplicates.length; ++i) {
+ ignoreWarning("Context2D: Duplicate token \"" + duplicates[i].duplicate + "\" found in font string.");
+ ctx.font = duplicates[i].string;
+ compare(ctx.font, originalFont);
+ }
+ }
+ }
}
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index fb3b62b8d2..fdaa1d6617 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -110,8 +110,8 @@ private slots:
void letterSpacing();
void wordSpacing();
- void clickLink_data();
- void clickLink();
+ void linkInteraction_data();
+ void linkInteraction();
void implicitSize_data();
void implicitSize();
@@ -1482,15 +1482,30 @@ void tst_qquicktext::wordSpacing()
class EventSender : public QQuickItem
{
public:
- void sendEvent(QMouseEvent *event) {
- if (event->type() == QEvent::MouseButtonPress)
- mousePressEvent(event);
- else if (event->type() == QEvent::MouseButtonRelease)
- mouseReleaseEvent(event);
- else if (event->type() == QEvent::MouseMove)
- mouseMoveEvent(event);
- else
+ void sendEvent(QEvent *event) {
+ switch (event->type()) {
+ case QEvent::MouseButtonPress:
+ mousePressEvent(static_cast<QMouseEvent *>(event));
+ break;
+ case QEvent::MouseButtonRelease:
+ mouseReleaseEvent(static_cast<QMouseEvent *>(event));
+ break;
+ case QEvent::MouseMove:
+ mouseMoveEvent(static_cast<QMouseEvent *>(event));
+ break;
+ case QEvent::HoverEnter:
+ hoverEnterEvent(static_cast<QHoverEvent *>(event));
+ break;
+ case QEvent::HoverLeave:
+ hoverLeaveEvent(static_cast<QHoverEvent *>(event));
+ break;
+ case QEvent::HoverMove:
+ hoverMoveEvent(static_cast<QHoverEvent *>(event));
+ break;
+ default:
qWarning() << "Trying to send unsupported event type";
+ break;
+ }
}
};
@@ -1500,10 +1515,12 @@ class LinkTest : public QObject
public:
LinkTest() {}
- QString link;
+ QString clickedLink;
+ QString hoveredLink;
public slots:
- void linkClicked(QString l) { link = l; }
+ void linkClicked(QString l) { clickedLink = l; }
+ void linkHovered(QString l) { hoveredLink = l; }
};
class TextMetrics
@@ -1589,13 +1606,15 @@ public:
typedef QVector<QPointF> PointVector;
Q_DECLARE_METATYPE(PointVector);
-void tst_qquicktext::clickLink_data()
+void tst_qquicktext::linkInteraction_data()
{
QTest::addColumn<QString>("text");
QTest::addColumn<qreal>("width");
QTest::addColumn<QString>("bindings");
QTest::addColumn<PointVector>("mousePositions");
- QTest::addColumn<QString>("link");
+ QTest::addColumn<QString>("clickedLink");
+ QTest::addColumn<QString>("hoverEnterLink");
+ QTest::addColumn<QString>("hoverMoveLink");
const QString singleLineText = "this text has a <a href=\\\"http://qt-project.org/single\\\">link</a> in it";
const QString singleLineLink = "http://qt-project.org/single";
@@ -1612,196 +1631,229 @@ void tst_qquicktext::clickLink_data()
<< singleLineText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(18).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
QTest::newRow("click on text")
<< singleLineText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(13).center())
- << QString();
+ << QString()
+ << QString() << QString();
QTest::newRow("drag within link")
<< singleLineText << 240.
<< ""
<< (PointVector()
<< metrics.characterRectangle(17).center()
<< metrics.characterRectangle(19).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
QTest::newRow("drag away from link")
<< singleLineText << 240.
<< ""
<< (PointVector()
<< metrics.characterRectangle(18).center()
<< metrics.characterRectangle(13).center())
- << QString();
+ << QString()
+ << singleLineLink << QString();
QTest::newRow("drag on to link")
<< singleLineText << 240.
<< ""
<< (PointVector()
<< metrics.characterRectangle(13).center()
<< metrics.characterRectangle(18).center())
- << QString();
+ << QString()
+ << QString() << singleLineLink;
QTest::newRow("click on bottom right aligned link")
<< singleLineText << 240.
<< "horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignBottom"
<< (PointVector() << metrics.characterRectangle(18, Qt::AlignRight, Qt::AlignBottom).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
QTest::newRow("click on center aligned link")
<< singleLineText << 240.
<< "horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter"
<< (PointVector() << metrics.characterRectangle(18, Qt::AlignHCenter, Qt::AlignVCenter).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
QTest::newRow("click on rich text link")
<< singleLineText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(18).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
QTest::newRow("click on rich text")
<< singleLineText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(13).center())
- << QString();
+ << QString()
+ << QString() << QString();
QTest::newRow("click on bottom right aligned rich text link")
<< singleLineText << 240.
<< "textFormat: Text.RichText; horizontalAlignment: Text.AlignRight; verticalAlignment: Text.AlignBottom"
<< (PointVector() << metrics.characterRectangle(18, Qt::AlignRight, Qt::AlignBottom).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
QTest::newRow("click on center aligned rich text link")
<< singleLineText << 240.
<< "textFormat: Text.RichText; horizontalAlignment: Text.AlignHCenter; verticalAlignment: Text.AlignVCenter"
<< (PointVector() << metrics.characterRectangle(18, Qt::AlignHCenter, Qt::AlignVCenter).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
} {
const TextMetrics metrics("this text has a li", Qt::ElideRight);
QTest::newRow("click on right elided link")
<< singleLineText << metrics.width() + 2
<< "elide: Text.ElideRight"
<< (PointVector() << metrics.characterRectangle(17).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
} {
const TextMetrics metrics("ink in it", Qt::ElideLeft);
QTest::newRow("click on left elided link")
<< singleLineText << metrics.width() + 2
<< "elide: Text.ElideLeft"
<< (PointVector() << metrics.characterRectangle(2).center())
- << singleLineLink;
+ << singleLineLink
+ << singleLineLink << singleLineLink;
} {
const TextMetrics metrics("this text\nhas multiple\nlines in it");
QTest::newRow("click on second line")
<< multipleLineText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(18).center())
- << multipleLineLink;
+ << multipleLineLink
+ << multipleLineLink << multipleLineLink;
QTest::newRow("click on third line")
<< multipleLineText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(25).center())
- << multipleLineLink;
+ << multipleLineLink
+ << multipleLineLink << multipleLineLink;
QTest::newRow("drag from second line to third")
<< multipleLineText << 240.
<< ""
<< (PointVector()
<< metrics.characterRectangle(18).center()
<< metrics.characterRectangle(25).center())
- << multipleLineLink;
+ << multipleLineLink
+ << multipleLineLink << multipleLineLink;
QTest::newRow("click on rich text second line")
<< multipleLineText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(18).center())
- << multipleLineLink;
+ << multipleLineLink
+ << multipleLineLink << multipleLineLink;
QTest::newRow("click on rich text third line")
<< multipleLineText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(25).center())
- << multipleLineLink;
+ << multipleLineLink
+ << multipleLineLink << multipleLineLink;
QTest::newRow("drag rich text from second line to third")
<< multipleLineText << 240.
<< "textFormat: Text.RichText"
<< (PointVector()
<< metrics.characterRectangle(18).center()
<< metrics.characterRectangle(25).center())
- << multipleLineLink;
+ << multipleLineLink
+ << multipleLineLink << multipleLineLink;
} {
const TextMetrics metrics("this text has a nested link in it");
QTest::newRow("click on left outer link")
<< nestedText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(22).center())
- << outerLink;
+ << outerLink
+ << outerLink << outerLink;
QTest::newRow("click on right outer link")
<< nestedText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(27).center())
- << outerLink;
+ << outerLink
+ << outerLink << outerLink;
QTest::newRow("click on inner link left")
<< nestedText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(23).center())
- << innerLink;
+ << innerLink
+ << innerLink << innerLink;
QTest::newRow("click on inner link right")
<< nestedText << 240.
<< ""
<< (PointVector() << metrics.characterRectangle(26).center())
- << innerLink;
+ << innerLink
+ << innerLink << innerLink;
QTest::newRow("drag from inner to outer link")
<< nestedText << 240.
<< ""
<< (PointVector()
<< metrics.characterRectangle(25).center()
<< metrics.characterRectangle(30).center())
- << QString();
+ << QString()
+ << innerLink << outerLink;
QTest::newRow("drag from outer to inner link")
<< nestedText << 240.
<< ""
<< (PointVector()
<< metrics.characterRectangle(30).center()
<< metrics.characterRectangle(25).center())
- << QString();
+ << QString()
+ << outerLink << innerLink;
QTest::newRow("click on left outer rich text link")
<< nestedText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(22).center())
- << outerLink;
+ << outerLink
+ << outerLink << outerLink;
QTest::newRow("click on right outer rich text link")
<< nestedText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(27).center())
- << outerLink;
+ << outerLink
+ << outerLink << outerLink;
QTest::newRow("click on inner rich text link left")
<< nestedText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(23).center())
- << innerLink;
+ << innerLink
+ << innerLink << innerLink;
QTest::newRow("click on inner rich text link right")
<< nestedText << 240.
<< "textFormat: Text.RichText"
<< (PointVector() << metrics.characterRectangle(26).center())
- << innerLink;
+ << innerLink
+ << innerLink << innerLink;
QTest::newRow("drag from inner to outer rich text link")
<< nestedText << 240.
<< "textFormat: Text.RichText"
<< (PointVector()
<< metrics.characterRectangle(25).center()
<< metrics.characterRectangle(30).center())
- << QString();
+ << QString()
+ << innerLink << outerLink;
QTest::newRow("drag from outer to inner rich text link")
<< nestedText << 240.
<< "textFormat: Text.RichText"
<< (PointVector()
<< metrics.characterRectangle(30).center()
<< metrics.characterRectangle(25).center())
- << QString();
+ << QString()
+ << outerLink << innerLink;
}
}
-void tst_qquicktext::clickLink()
+void tst_qquicktext::linkInteraction()
{
QFETCH(QString, text);
QFETCH(qreal, width);
QFETCH(QString, bindings);
QFETCH(PointVector, mousePositions);
- QFETCH(QString, link);
+ QFETCH(QString, clickedLink);
+ QFETCH(QString, hoverEnterLink);
+ QFETCH(QString, hoverMoveLink);
QString componentStr =
- "import QtQuick 2.0\nText {\n"
+ "import QtQuick 2.2\nText {\n"
"width: " + QString::number(width) + "\n"
"height: 320\n"
"text: \"" + text + "\"\n"
@@ -1815,28 +1867,46 @@ void tst_qquicktext::clickLink()
LinkTest test;
QObject::connect(textObject, SIGNAL(linkActivated(QString)), &test, SLOT(linkClicked(QString)));
+ QObject::connect(textObject, SIGNAL(linkHovered(QString)), &test, SLOT(linkHovered(QString)));
QVERIFY(mousePositions.count() > 0);
QPointF mousePosition = mousePositions.first();
{
+ QHoverEvent he(QEvent::HoverEnter, mousePosition, QPointF());
+ static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&he);
+
QMouseEvent me(QEvent::MouseButtonPress, mousePosition, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
}
+ QCOMPARE(test.hoveredLink, hoverEnterLink);
+ QCOMPARE(textObject->hoveredLink(), hoverEnterLink);
+
for (int i = 1; i < mousePositions.count(); ++i) {
mousePosition = mousePositions.at(i);
+ QHoverEvent he(QEvent::HoverMove, mousePosition, QPointF());
+ static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&he);
+
QMouseEvent me(QEvent::MouseMove, mousePosition, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
}
+ QCOMPARE(test.hoveredLink, hoverMoveLink);
+ QCOMPARE(textObject->hoveredLink(), hoverMoveLink);
+
{
+ QHoverEvent he(QEvent::HoverLeave, mousePosition, QPointF());
+ static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&he);
+
QMouseEvent me(QEvent::MouseButtonRelease, mousePosition, Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
}
- QCOMPARE(test.link, link);
+ QCOMPARE(test.clickedLink, clickedLink);
+ QCOMPARE(test.hoveredLink, QString());
+ QCOMPARE(textObject->hoveredLink(), QString());
delete textObject;
}
diff --git a/tests/auto/quick/qquicktextedit/data/linkActivated.qml b/tests/auto/quick/qquicktextedit/data/linkInteraction.qml
index d3bba82b59..d3bba82b59 100644
--- a/tests/auto/quick/qquicktextedit/data/linkActivated.qml
+++ b/tests/auto/quick/qquicktextedit/data/linkInteraction.qml
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
index bce1f9e4a2..798db9fe23 100644
--- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
@@ -143,7 +143,7 @@ private slots:
void positionAt_data();
void positionAt();
- void linkActivated();
+ void linkInteraction();
void cursorDelegate_data();
void cursorDelegate();
@@ -182,6 +182,8 @@ private slots:
void getText();
void getFormattedText_data();
void getFormattedText();
+ void append_data();
+ void append();
void insert_data();
void insert();
void remove_data();
@@ -2341,9 +2343,9 @@ void tst_qquicktextedit::positionAt()
QVERIFY(texteditObject->positionAt(x0 / 2, y1) > 0);
}
-void tst_qquicktextedit::linkActivated()
+void tst_qquicktextedit::linkInteraction()
{
- QQuickView window(testFileUrl("linkActivated.qml"));
+ QQuickView window(testFileUrl("linkInteraction.qml"));
QVERIFY(window.rootObject() != 0);
window.show();
window.requestActivate();
@@ -2353,6 +2355,7 @@ void tst_qquicktextedit::linkActivated()
QVERIFY(texteditObject != 0);
QSignalSpy spy(texteditObject, SIGNAL(linkActivated(QString)));
+ QSignalSpy hover(texteditObject, SIGNAL(linkHovered(QString)));
const QString link("http://example.com/");
@@ -2361,21 +2364,31 @@ void tst_qquicktextedit::linkActivated()
QTest::mouseClick(&window, Qt::LeftButton, 0, linkPos.toPoint());
QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(hover.count(), 1);
QCOMPARE(spy.last()[0].toString(), link);
+ QCOMPARE(hover.last()[0].toString(), link);
+ QCOMPARE(texteditObject->hoveredLink(), link);
QTest::mouseClick(&window, Qt::LeftButton, 0, textPos.toPoint());
- QTest::qWait(50);
- QCOMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(hover.count(), 2);
+ QCOMPARE(hover.last()[0].toString(), QString());
+ QCOMPARE(texteditObject->hoveredLink(), QString());
texteditObject->setReadOnly(true);
QTest::mouseClick(&window, Qt::LeftButton, 0, linkPos.toPoint());
QTRY_COMPARE(spy.count(), 2);
+ QTRY_COMPARE(hover.count(), 3);
QCOMPARE(spy.last()[0].toString(), link);
+ QCOMPARE(hover.last()[0].toString(), link);
+ QCOMPARE(texteditObject->hoveredLink(), link);
QTest::mouseClick(&window, Qt::LeftButton, 0, textPos.toPoint());
- QTest::qWait(50);
- QCOMPARE(spy.count(), 2);
+ QTRY_COMPARE(spy.count(), 2);
+ QTRY_COMPARE(hover.count(), 4);
+ QCOMPARE(hover.last()[0].toString(), QString());
+ QCOMPARE(texteditObject->hoveredLink(), QString());
}
void tst_qquicktextedit::cursorDelegate_data()
@@ -3816,6 +3829,158 @@ void tst_qquicktextedit::getFormattedText()
}
}
+void tst_qquicktextedit::append_data()
+{
+ QTest::addColumn<QString>("text");
+ QTest::addColumn<QQuickTextEdit::TextFormat>("textFormat");
+ QTest::addColumn<int>("selectionStart");
+ QTest::addColumn<int>("selectionEnd");
+ QTest::addColumn<QString>("appendText");
+ QTest::addColumn<QString>("expectedText");
+ QTest::addColumn<int>("expectedSelectionStart");
+ QTest::addColumn<int>("expectedSelectionEnd");
+ QTest::addColumn<int>("expectedCursorPosition");
+ QTest::addColumn<bool>("selectionChanged");
+ QTest::addColumn<bool>("cursorPositionChanged");
+
+ QTest::newRow("cursor kept intact (beginning)")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 0 << 0
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << 0 << 0 << 0
+ << false << false;
+
+ QTest::newRow("cursor kept intact (middle)")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 18 << 18
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << 18 << 18 << 18
+ << false << false;
+
+ QTest::newRow("cursor follows (end)")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << standard.at(0).length() << standard.at(0).length()
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << standard.at(0).length() + 6 << standard.at(0).length() + 6 << standard.at(0).length() + 6
+ << false << true;
+
+ QTest::newRow("selection kept intact (beginning)")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 0 << 18
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << 0 << 18 << 18
+ << false << false;
+
+ QTest::newRow("selection kept intact (middle)")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 14 << 18
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << 14 << 18 << 18
+ << false << false;
+
+ QTest::newRow("selection kept intact, cursor follows (end)")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 18 << standard.at(0).length()
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << 18 << standard.at(0).length() + 6 << standard.at(0).length() + 6
+ << false << true;
+
+ QTest::newRow("reversed selection kept intact")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 18 << 14
+ << QString("Hello")
+ << standard.at(0) + QString("\nHello")
+ << 14 << 18 << 14
+ << false << false;
+
+ QTest::newRow("rich text into plain text")
+ << standard.at(0) << QQuickTextEdit::PlainText
+ << 0 << 0
+ << QString("<b>Hello</b>")
+ << standard.at(0) + QString("\n<b>Hello</b>")
+ << 0 << 0 << 0
+ << false << false;
+
+ QTest::newRow("rich text into rich text")
+ << standard.at(0) << QQuickTextEdit::RichText
+ << 0 << 0
+ << QString("<b>Hello</b>")
+ << standard.at(0) + QChar(QChar::ParagraphSeparator) + QString("Hello")
+ << 0 << 0 << 0
+ << false << false;
+
+ QTest::newRow("rich text into auto text")
+ << standard.at(0) << QQuickTextEdit::AutoText
+ << 0 << 0
+ << QString("<b>Hello</b>")
+ << standard.at(0) + QString("\nHello")
+ << 0 << 0 << 0
+ << false << false;
+}
+
+void tst_qquicktextedit::append()
+{
+ QFETCH(QString, text);
+ QFETCH(QQuickTextEdit::TextFormat, textFormat);
+ QFETCH(int, selectionStart);
+ QFETCH(int, selectionEnd);
+ QFETCH(QString, appendText);
+ QFETCH(QString, expectedText);
+ QFETCH(int, expectedSelectionStart);
+ QFETCH(int, expectedSelectionEnd);
+ QFETCH(int, expectedCursorPosition);
+ QFETCH(bool, selectionChanged);
+ QFETCH(bool, cursorPositionChanged);
+
+ QString componentStr = "import QtQuick 2.2\nTextEdit { text: \"" + text + "\" }";
+ QQmlComponent textEditComponent(&engine);
+ textEditComponent.setData(componentStr.toLatin1(), QUrl());
+ QQuickTextEdit *textEdit = qobject_cast<QQuickTextEdit*>(textEditComponent.create());
+ QVERIFY(textEdit != 0);
+
+ textEdit->setTextFormat(textFormat);
+ textEdit->select(selectionStart, selectionEnd);
+
+ QSignalSpy selectionSpy(textEdit, SIGNAL(selectedTextChanged()));
+ QSignalSpy selectionStartSpy(textEdit, SIGNAL(selectionStartChanged()));
+ QSignalSpy selectionEndSpy(textEdit, SIGNAL(selectionEndChanged()));
+ QSignalSpy textSpy(textEdit, SIGNAL(textChanged()));
+ QSignalSpy cursorPositionSpy(textEdit, SIGNAL(cursorPositionChanged()));
+
+ textEdit->append(appendText);
+
+ if (textFormat == QQuickTextEdit::RichText || (textFormat == QQuickTextEdit::AutoText && (
+ Qt::mightBeRichText(text) || Qt::mightBeRichText(appendText)))) {
+ QCOMPARE(textEdit->getText(0, expectedText.length()), expectedText);
+ } else {
+ QCOMPARE(textEdit->text(), expectedText);
+
+ }
+ QCOMPARE(textEdit->length(), expectedText.length());
+
+ QCOMPARE(textEdit->selectionStart(), expectedSelectionStart);
+ QCOMPARE(textEdit->selectionEnd(), expectedSelectionEnd);
+ QCOMPARE(textEdit->cursorPosition(), expectedCursorPosition);
+
+ if (selectionStart > selectionEnd)
+ qSwap(selectionStart, selectionEnd);
+
+ QEXPECT_FAIL("into selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue);
+ QEXPECT_FAIL("into reversed selection", "selectedTextChanged signal isn't emitted on edits within selection", Continue);
+ QCOMPARE(selectionSpy.count() > 0, selectionChanged);
+ QCOMPARE(selectionStartSpy.count() > 0, selectionStart != expectedSelectionStart);
+ QEXPECT_FAIL("into reversed selection", "selectionEndChanged signal not emitted", Continue);
+ QCOMPARE(selectionEndSpy.count() > 0, selectionEnd != expectedSelectionEnd);
+ QCOMPARE(textSpy.count() > 0, text != expectedText);
+ QCOMPARE(cursorPositionSpy.count() > 0, cursorPositionChanged);
+}
+
void tst_qquicktextedit::insert_data()
{
QTest::addColumn<QString>("text");
diff --git a/tests/auto/shared/testhttpserver.cpp b/tests/auto/shared/testhttpserver.cpp
index 205d5cec5d..fd681710de 100644
--- a/tests/auto/shared/testhttpserver.cpp
+++ b/tests/auto/shared/testhttpserver.cpp
@@ -137,7 +137,19 @@ bool TestHTTPServer::wait(const QUrl &expect, const QUrl &reply, const QUrl &bod
bodyData = bodyFile.readAll();
}
- waitData = expectFile.readAll();
+ QByteArray line;
+ bool headers_done = false;
+ while (!(line = expectFile.readLine()).isEmpty()) {
+ line.replace('\r', "");
+ if (line.at(0) == '\n') {
+ headers_done = true;
+ continue;
+ }
+ if (headers_done)
+ waitData.body.append(line);
+ else
+ waitData.headers.append(line);
+ }
/*
while (waitData.endsWith('\n'))
waitData = waitData.left(waitData.count() - 1);
@@ -199,39 +211,38 @@ void TestHTTPServer::readyRead()
QTcpSocket *socket = qobject_cast<QTcpSocket *>(sender());
if (!socket || socket->state() == QTcpSocket::ClosingState) return;
- QByteArray ba = socket->readAll();
-
if (!dirs.isEmpty()) {
- serveGET(socket, ba);
+ serveGET(socket, socket->readAll());
return;
}
- if (m_hasFailed || waitData.isEmpty()) {
- qWarning() << "TestHTTPServer: Unexpected data" << ba;
+ if (m_hasFailed || (waitData.body.isEmpty() && waitData.headers.count() == 0)) {
+ qWarning() << "TestHTTPServer: Unexpected data" << socket->readAll();
return;
}
- for (int ii = 0; ii < ba.count(); ++ii) {
- const char c = ba.at(ii);
- if (c == '\r' && waitData.isEmpty())
- continue;
- else if (!waitData.isEmpty() && c == waitData.at(0))
- waitData = waitData.mid(1);
- else if (c == '\r')
- continue;
- else {
- QByteArray data = ba.mid(ii);
- qWarning() << "TestHTTPServer: Unexpected data" << data << "\nExpected: " << waitData;
+ QByteArray line;
+ while (!(line = socket->readLine()).isEmpty()) {
+ line.replace('\r', "");
+ if (line.at(0) == '\n') {
+ QByteArray data = socket->readAll();
+ if (waitData.body != data) {
+ qWarning() << "TestHTTPServer: Unexpected data" << data << "\nExpected: " << waitData.body;
+ m_hasFailed = true;
+ socket->disconnectFromHost();
+ return;
+ }
+ }
+ else if (!waitData.headers.contains(line)) {
+ qWarning() << "TestHTTPServer: Unexpected header:" << line << "\nExpected headers: " << waitData.headers;
m_hasFailed = true;
socket->disconnectFromHost();
return;
}
}
- if (waitData.isEmpty()) {
- socket->write(replyData);
- socket->disconnectFromHost();
- }
+ socket->write(replyData);
+ socket->disconnectFromHost();
}
bool TestHTTPServer::reply(QTcpSocket *socket, const QByteArray &fileName)
diff --git a/tests/auto/shared/testhttpserver.h b/tests/auto/shared/testhttpserver.h
index 15e08afd0c..ce0501f170 100644
--- a/tests/auto/shared/testhttpserver.h
+++ b/tests/auto/shared/testhttpserver.h
@@ -81,7 +81,10 @@ private:
QHash<QTcpSocket *, QByteArray> dataCache;
QList<QPair<QTcpSocket *, QByteArray> > toSend;
- QByteArray waitData;
+ struct WaitData {
+ QList <QByteArray>headers;
+ QByteArray body;
+ } waitData;
QByteArray replyData;
QByteArray bodyData;
bool m_hasFailed;
diff --git a/tests/benchmarks/qml/animation/animation.pro b/tests/benchmarks/qml/animation/animation.pro
index 7490c5fe39..adf83828fa 100644
--- a/tests/benchmarks/qml/animation/animation.pro
+++ b/tests/benchmarks/qml/animation/animation.pro
@@ -1,11 +1,10 @@
+CONFIG += testcase
TEMPLATE = app
TARGET = tst_animation
-QT += qml
+QT += qml testlib core-private gui-private qml-private quick-private v8-private
macx:CONFIG -= app_bundle
SOURCES += tst_animation.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
-
-QT += testlib core-private gui-private qml-private quick-private v8-private
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/compilation/tst_compilation.cpp b/tests/benchmarks/qml/compilation/tst_compilation.cpp
index 148396622b..eac3dcc2dd 100644
--- a/tests/benchmarks/qml/compilation/tst_compilation.cpp
+++ b/tests/benchmarks/qml/compilation/tst_compilation.cpp
@@ -120,7 +120,6 @@ void tst_compilation::jsparser()
QBENCHMARK {
QQmlJS::Engine engine;
- QQmlJS::NodePool nodePool(file, &engine);
QQmlJS::Lexer lexer(&engine);
lexer.setCode(code, -1);
@@ -146,11 +145,14 @@ void tst_compilation::scriptparser()
QVERIFY(f.open(QIODevice::ReadOnly));
QByteArray data = f.readAll();
+ //TODO(pvarga): check preparseData
+ QByteArray preparseData;
QUrl url = QUrl::fromLocalFile(file);
+ QString urlString = url.toString();
QBENCHMARK {
QQmlScript::Parser parser;
- parser.parse(data, url);
+ parser.parse(data, preparseData, url, urlString);
parser.tree();
}
}
diff --git a/tests/benchmarks/qml/creation/creation.pro b/tests/benchmarks/qml/creation/creation.pro
index 8d26ef88df..0cfac64d5f 100644
--- a/tests/benchmarks/qml/creation/creation.pro
+++ b/tests/benchmarks/qml/creation/creation.pro
@@ -1,11 +1,10 @@
CONFIG += testcase
TEMPLATE = app
TARGET = tst_creation
+QT += core-private gui-private qml-private quick-private widgets testlib
macx:CONFIG -= app_bundle
SOURCES += tst_creation.cpp
DEFINES += SRCDIR=\\\"$$PWD\\\"
-
-QT += core-private gui-private qml-private qtquick1-private widgets testlib
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/benchmarks/qml/creation/tst_creation.cpp b/tests/benchmarks/qml/creation/tst_creation.cpp
index 4b5c1d1950..b6b402a6c0 100644
--- a/tests/benchmarks/qml/creation/tst_creation.cpp
+++ b/tests/benchmarks/qml/creation/tst_creation.cpp
@@ -48,7 +48,6 @@
#include <QGraphicsItem>
#include <QQuickItem>
#include <QQmlContext>
-#include <QtQuick1/private/qdeclarativetextinput_p.h>
#include <private/qobject_p.h>
class tst_creation : public QObject
@@ -96,7 +95,7 @@ public:
: QObject(parent) {}
QQmlListProperty<QObject> resources() {
- return QQmlListProperty<QObject>(this, 0, resources_append);
+ return QQmlListProperty<QObject>(this, 0, resources_append, 0, 0, 0);
}
static void resources_append(QQmlListProperty<QObject> *p, QObject *o) {
@@ -107,9 +106,6 @@ public:
tst_creation::tst_creation()
{
qmlRegisterType<TestType>("Qt.test", 1, 0, "TestType");
-
- //get rid of initialization effects
- QDeclarative1TextInput te;
}
inline QUrl TEST_FILE(const QString &filename)
@@ -321,9 +317,7 @@ void tst_creation::itemtree_qml()
void tst_creation::itemtree_scene_cpp()
{
- QGraphicsScene scene;
QQuickItem *root = new QQuickItem;
- scene.addItem(root);
QBENCHMARK {
QQuickItem *item = new QQuickItem;
for (int i = 0; i < 30; ++i) {
diff --git a/tests/benchmarks/qml/holistic/testtypes.cpp b/tests/benchmarks/qml/holistic/testtypes.cpp
index 0a9e36dc3a..9b1bb86850 100644
--- a/tests/benchmarks/qml/holistic/testtypes.cpp
+++ b/tests/benchmarks/qml/holistic/testtypes.cpp
@@ -82,13 +82,13 @@ void registerTypes()
qmlRegisterType<ScarceResourceProvider>("Qt.test", 1,0, "MyScarceResourceProvider");
qmlRegisterType<ArbitraryVariantProvider>("Qt.test", 1,0, "MyArbitraryVariantProvider");
- qmlRegisterSingletonType("Qt.test",1,0,script_api); // register (script) singleton Type for an existing uri which contains elements
- qmlRegisterSingletonType<testQObjectApi>("Qt.test",1,0,qobject_api); // register (qobject) for an existing uri for which another singleton Type was previously regd. Should replace!
- qmlRegisterSingletonType("Qt.test.scriptApi",1,0,script_api); // register (script) singleton Type for a uri which doesn't contain elements
- qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApi",1,0,qobject_api); // register (qobject) singleton Type for a uri which doesn't contain elements
- qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApi",1,3,qobject_api); // register (qobject) singleton Type for a uri which doesn't contain elements, minor version set
- qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApi",2,0,qobject_api); // register (qobject) singleton Type for a uri which doesn't contain elements, major version set
- qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApiParented",1,0,qobject_api_engine_parent); // register (parented qobject) singleton Type for a uri which doesn't contain elements
+ qmlRegisterSingletonType("Qt.test",1,0,"Script",script_api); // register (script) singleton Type for an existing uri which contains elements
+ qmlRegisterSingletonType<testQObjectApi>("Qt.test",1,0,"QObject",qobject_api); // register (qobject) for an existing uri for which another singleton Type was previously regd. Should replace!
+ qmlRegisterSingletonType("Qt.test.scriptApi",1,0,"Script",script_api); // register (script) singleton Type for a uri which doesn't contain elements
+ qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApi",1,0,"QObject",qobject_api); // register (qobject) singleton Type for a uri which doesn't contain elements
+ qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApi",1,3,"QObject",qobject_api); // register (qobject) singleton Type for a uri which doesn't contain elements, minor version set
+ qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApi",2,0,"QObject",qobject_api); // register (qobject) singleton Type for a uri which doesn't contain elements, major version set
+ qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApiParented",1,0,"QObject",qobject_api_engine_parent); // register (parented qobject) singleton Type for a uri which doesn't contain elements
}
//#include "testtypes.moc"
diff --git a/tests/benchmarks/qml/painting/paintbenchmark.cpp b/tests/benchmarks/qml/painting/paintbenchmark.cpp
index b99161749d..1fc7813c04 100644
--- a/tests/benchmarks/qml/painting/paintbenchmark.cpp
+++ b/tests/benchmarks/qml/painting/paintbenchmark.cpp
@@ -180,6 +180,8 @@ void paint_RoundedRect(QPainter &p)
}
}
+// Disable this test case since this cannot be compiled with Qt5.
+#if 0
void paint_QPixmapCachedRoundedRect(QPainter &p)
{
static bool first = true;
@@ -218,6 +220,7 @@ void paint_QPixmapCachedRoundedRect(QPainter &p)
}
}
}
+#endif
void paint_pathCacheRoundedRect(QPainter &p)
{
@@ -312,7 +315,7 @@ struct {
{ "QStaticTextWithBackendOptimizations", &paint_QStaticText_optimizations },
{ "CachedText", &paint_QPixmapCachedText },
{ "RoundedRect", &paint_RoundedRect },
- { "CachedRoundedRect", &paint_QPixmapCachedRoundedRect },
+ // { "CachedRoundedRect", &paint_QPixmapCachedRoundedRect },
{ "PathCacheRoundedRect", &paint_pathCacheRoundedRect },
{ "QPixmap63x63_opaque", &paint_QPixmap63x63_opaque },
{ "QPixmap64x64_opaque", &paint_QPixmap64x64_opaque },
diff --git a/tests/benchmarks/qml/pointers/pointers.pro b/tests/benchmarks/qml/pointers/pointers.pro
index 1db474428d..b9b44abb0f 100644
--- a/tests/benchmarks/qml/pointers/pointers.pro
+++ b/tests/benchmarks/qml/pointers/pointers.pro
@@ -1,5 +1,5 @@
CONFIG += testcase
-QT += qml testlib
+QT += core-private v8-private qml-private testlib
TEMPLATE = app
TARGET = tst_pointers
macx:CONFIG -= app_bundle
diff --git a/tests/benchmarks/qml/pointers/tst_pointers.cpp b/tests/benchmarks/qml/pointers/tst_pointers.cpp
index 65dda28fe7..0c25030c7f 100644
--- a/tests/benchmarks/qml/pointers/tst_pointers.cpp
+++ b/tests/benchmarks/qml/pointers/tst_pointers.cpp
@@ -40,7 +40,7 @@
****************************************************************************/
#include <qtest.h>
-#include "private/qqmlguard_p.h"
+#include <QtQml/private/qqmlguard_p.h>
#include <QWeakPointer>
class tst_pointers : public QObject
diff --git a/tests/benchmarks/qml/qquickwindow/tst_qquickwindow.cpp b/tests/benchmarks/qml/qquickwindow/tst_qquickwindow.cpp
index 01ddd70838..20e5fb6c64 100644
--- a/tests/benchmarks/qml/qquickwindow/tst_qquickwindow.cpp
+++ b/tests/benchmarks/qml/qquickwindow/tst_qquickwindow.cpp
@@ -63,9 +63,9 @@ tst_qquickwindow::tst_qquickwindow()
{
window = new QQuickWindow;
window->resize(250, 250);
- window->setPos(100, 100);
+ window->setPosition(100, 100);
for ( int i=0; i<8000; i++ ) {
- QQuickRectangle *r =new QQuickRectangle(window->rootItem());
+ QQuickRectangle *r =new QQuickRectangle(window->contentItem());
for ( int j=0; j<10; ++j ) {
new QQuickRectangle(r);
}
diff --git a/tests/benchmarks/qml/typeimports/tst_typeimports.cpp b/tests/benchmarks/qml/typeimports/tst_typeimports.cpp
index c24e344a6b..5871565ace 100644
--- a/tests/benchmarks/qml/typeimports/tst_typeimports.cpp
+++ b/tests/benchmarks/qml/typeimports/tst_typeimports.cpp
@@ -67,7 +67,7 @@ public:
TestType1(QObject *parent = 0) : QObject(parent) {}
QQmlListProperty<QObject> resources() {
- return QQmlListProperty<QObject>(this, 0, resources_append);
+ return QQmlListProperty<QObject>(this, 0, resources_append, 0, 0, 0);
}
static void resources_append(QQmlListProperty<QObject> *p, QObject *o) {