aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/quick/demos/calqlatr/doc/src/calqlatr.qdoc13
-rw-r--r--examples/quick/demos/clocks/clocks.pro14
-rw-r--r--examples/quick/demos/clocks/clocks.qml6
-rw-r--r--examples/quick/demos/clocks/clocks.qrc15
-rw-r--r--examples/quick/demos/clocks/doc/src/clocks.qdoc12
-rw-r--r--examples/quick/demos/clocks/main.cpp41
-rw-r--r--examples/quick/demos/demos.pro2
-rw-r--r--examples/quick/demos/maroon/doc/src/maroon.qdoc10
-rw-r--r--examples/quick/demos/photosurface/doc/src/photosurface.qdoc10
-rw-r--r--examples/quick/demos/photoviewer/doc/src/photoviewer.qdoc12
-rw-r--r--examples/quick/demos/rssnews/doc/src/rssnews.qdoc12
-rw-r--r--examples/quick/demos/samegame/doc/src/samegame.qdoc12
-rw-r--r--examples/quick/demos/stocqt/doc/src/stocqt.qdoc10
-rw-r--r--examples/quick/demos/tweetsearch/doc/src/tweetsearch.qdoc18
-rw-r--r--src/3rdparty/masm/assembler/MacroAssemblerARMv7.h2
-rw-r--r--src/qml/compiler/qv4codegen.cpp6
-rw-r--r--src/qml/compiler/qv4compileddata_p.h2
-rw-r--r--src/qml/jit/qv4assembler_p.h6
-rw-r--r--src/qml/jit/qv4isel_masm.cpp6
-rw-r--r--src/qml/jsruntime/qv4qobjectwrapper.cpp2
-rw-r--r--src/qml/qml/qqmlproperty.cpp6
-rw-r--r--src/qml/types/qqmldelegatemodel_p_p.h2
-rw-r--r--src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp2
-rw-r--r--src/quick/items/qquickitem.cpp14
-rw-r--r--src/quick/items/qquickitemview.cpp2
-rw-r--r--src/quick/items/qquickpathview.cpp2
-rw-r--r--src/quick/items/qquicktextcontrol.cpp46
-rw-r--r--src/quick/items/qquicktextcontrol_p.h1
-rw-r--r--src/quick/scenegraph/util/qsgtexture.cpp1
-rw-r--r--src/quick/scenegraph/util/qsgtexturematerial.cpp2
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp34
-rw-r--r--tests/auto/qml/qqmllanguage/data/assignNullStrings.qml9
-rw-r--r--tests/auto/qml/qqmllanguage/testtypes.h11
-rw-r--r--tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp14
-rw-r--r--tests/auto/qml/qqmlxmlhttprequest/data/stateChangeCallingContext.qml2
-rw-r--r--tests/auto/qmltest/listview/tst_listview.qml23
-rw-r--r--tests/auto/qmltest/pathview/tst_pathview.qml35
-rw-r--r--tests/auto/quick/qquickitem2/data/keysforward.qml84
-rw-r--r--tests/auto/quick/qquickitem2/tst_qquickitem.cpp73
-rw-r--r--tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp2
-rw-r--r--tests/auto/quick/qquicktextinput/qquicktextinput.pro2
-rw-r--r--tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp3
-rw-r--r--tools/qmlplugindump/main.cpp125
43 files changed, 595 insertions, 111 deletions
diff --git a/examples/quick/demos/calqlatr/doc/src/calqlatr.qdoc b/examples/quick/demos/calqlatr/doc/src/calqlatr.qdoc
index 533ba99f7a..ff8061e2ea 100644
--- a/examples/quick/demos/calqlatr/doc/src/calqlatr.qdoc
+++ b/examples/quick/demos/calqlatr/doc/src/calqlatr.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -29,9 +29,14 @@
\title Qt Quick Demo - Calqlatr
\ingroup qtquickdemos
\example demos/calqlatr
- \brief A simple calculator app, designed for portrait devices.
+ \brief A simple QML calculator app, designed for portrait devices.
\image qtquick-demo-calqlatr.png
- This app has the logic implemented in JavaScript and the appearance implemented in QML.
-*/
+ \e{Calqlatr} demonstrates various QML and \l{Qt Quick} features such as
+ displaying custom components. The logic is implemented in JavaScript and the
+ appearance implemented in QML.
+
+ \include examples-run.qdocinc
+ \sa {QML Applications}
+*/
diff --git a/examples/quick/demos/clocks/clocks.pro b/examples/quick/demos/clocks/clocks.pro
new file mode 100644
index 0000000000..21d3f7f971
--- /dev/null
+++ b/examples/quick/demos/clocks/clocks.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+
+QT += qml quick
+
+SOURCES += main.cpp
+RESOURCES += clocks.qrc
+
+target.path = $$[QT_INSTALL_EXAMPLES]/quick/demos/clocks
+INSTALLS += target
+
+OTHER_FILES += \
+ clocks.qml \
+ content/Clock.qml \
+ content/*.png
diff --git a/examples/quick/demos/clocks/clocks.qml b/examples/quick/demos/clocks/clocks.qml
index ddf9e42ea2..d16e3c5442 100644
--- a/examples/quick/demos/clocks/clocks.qml
+++ b/examples/quick/demos/clocks/clocks.qml
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
@@ -39,7 +39,7 @@
****************************************************************************/
import QtQuick 2.0
-import "content"
+import "content" as Content
Rectangle {
id: root
@@ -54,7 +54,7 @@ Rectangle {
snapMode: ListView.SnapOneItem
highlightRangeMode: ListView.ApplyRange
- delegate: Clock { city: cityName; shift: timeShift }
+ delegate: Content.Clock { city: cityName; shift: timeShift }
model: ListModel {
ListElement { cityName: "New York"; timeShift: -4 }
ListElement { cityName: "London"; timeShift: 0 }
diff --git a/examples/quick/demos/clocks/clocks.qrc b/examples/quick/demos/clocks/clocks.qrc
new file mode 100644
index 0000000000..eaff4729ae
--- /dev/null
+++ b/examples/quick/demos/clocks/clocks.qrc
@@ -0,0 +1,15 @@
+<RCC>
+ <qresource prefix="/demos/clocks">
+ <file>clocks.qml</file>
+ <file>content/arrow.png</file>
+ <file>content/background.png</file>
+ <file>content/center.png</file>
+ <file>content/clock-night.png</file>
+ <file>content/clock.png</file>
+ <file>content/Clock.qml</file>
+ <file>content/hour.png</file>
+ <file>content/minute.png</file>
+ <file>content/quit.png</file>
+ <file>content/second.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/quick/demos/clocks/doc/src/clocks.qdoc b/examples/quick/demos/clocks/doc/src/clocks.qdoc
index b34f844cc6..b57894c5d3 100644
--- a/examples/quick/demos/clocks/doc/src/clocks.qdoc
+++ b/examples/quick/demos/clocks/doc/src/clocks.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -29,7 +29,13 @@
\title Qt Quick Demo - Clocks
\ingroup qtquickdemos
\example demos/clocks
- \brief An app that shows the current time in different cities.
+ \brief A QML application that shows the current time in different cities.
\image qtquick-demo-clocks-small.png
-*/
+ \e Clocks demonstrates various QML and \l{Qt Quick} features such as
+ displaying custom components.
+
+ \include examples-run.qdocinc
+
+ \sa {QML Applications}
+*/
diff --git a/examples/quick/demos/clocks/main.cpp b/examples/quick/demos/clocks/main.cpp
new file mode 100644
index 0000000000..f6b7f87d38
--- /dev/null
+++ b/examples/quick/demos/clocks/main.cpp
@@ -0,0 +1,41 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
+** of its contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include "../../shared/shared.h"
+DECLARATIVE_EXAMPLE_MAIN(demos/clocks/clocks)
diff --git a/examples/quick/demos/demos.pro b/examples/quick/demos/demos.pro
index 867dfa5a07..ac15cc3c1f 100644
--- a/examples/quick/demos/demos.pro
+++ b/examples/quick/demos/demos.pro
@@ -1,12 +1,12 @@
TEMPLATE = subdirs
SUBDIRS = samegame \
calqlatr \
+ clocks \
tweetsearch \
maroon \
photosurface \
stocqt
EXAMPLE_FILES = \
- clocks \
photoviewer \
rssnews
diff --git a/examples/quick/demos/maroon/doc/src/maroon.qdoc b/examples/quick/demos/maroon/doc/src/maroon.qdoc
index c18b6bc874..59f6397dcf 100644
--- a/examples/quick/demos/maroon/doc/src/maroon.qdoc
+++ b/examples/quick/demos/maroon/doc/src/maroon.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -32,5 +32,11 @@
\brief A cute game designed for touchscreens.
\image qtquick-demo-maroon-med-1.png
\image qtquick-demo-maroon-med-2.png
-*/
+ \e{Maroon in Trouble} demonstrates various QML and \l{Qt Quick} features
+ such as displaying custom components and playing sound effects.
+
+ \include examples-run.qdocinc
+
+ \sa {QML Applications}
+*/
diff --git a/examples/quick/demos/photosurface/doc/src/photosurface.qdoc b/examples/quick/demos/photosurface/doc/src/photosurface.qdoc
index 48f8e8a14b..d56b34365d 100644
--- a/examples/quick/demos/photosurface/doc/src/photosurface.qdoc
+++ b/examples/quick/demos/photosurface/doc/src/photosurface.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -32,6 +32,10 @@
\brief A touch-based app for shuffling photos around a virtual surface.
\image qtquick-demo-photosurface-small.png
- This example demonstrates how to handle dragging, rotation and
- pinch zooming within the same item using a PinchArea containing a MouseArea.
+ \e{Photo Surface} demonstrates how to handle dragging, rotation and pinch
+ zooming within the same item using a \l PinchArea containing a \l MouseArea.
+
+ \include examples-run.qdocinc
+
+ \sa {QML Applications}
*/
diff --git a/examples/quick/demos/photoviewer/doc/src/photoviewer.qdoc b/examples/quick/demos/photoviewer/doc/src/photoviewer.qdoc
index b0f1368a1c..29c432be3c 100644
--- a/examples/quick/demos/photoviewer/doc/src/photoviewer.qdoc
+++ b/examples/quick/demos/photoviewer/doc/src/photoviewer.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -29,7 +29,13 @@
\title Qt Quick Demo - Photo Viewer
\ingroup qtquickdemos
\example demos/photoviewer
- \brief An online photo viewer that displays Flickr feeds.
+ \brief A photo viewer that displays Flickr feeds.
\image qtquick-demo-photoviewer-small.png
-*/
+ \e{Photo Viewer} demonstrates various QML and \l{Qt Quick} features such as
+ displaying custom components.
+
+ \include examples-run.qdocinc
+
+ \sa {QML Applications}
+*/
diff --git a/examples/quick/demos/rssnews/doc/src/rssnews.qdoc b/examples/quick/demos/rssnews/doc/src/rssnews.qdoc
index 019b54d609..12c7c0d19b 100644
--- a/examples/quick/demos/rssnews/doc/src/rssnews.qdoc
+++ b/examples/quick/demos/rssnews/doc/src/rssnews.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -29,7 +29,13 @@
\title Qt Quick Demo - RSS News
\ingroup qtquickdemos
\example demos/rssnews
- \brief An RSS news reader.
+ \brief A QML RSS news reader.
\image qtquick-demo-rssnews-small.png
-*/
+ \e{RSS News} demonstrates various QML and \l{Qt Quick} features such as
+ loading XML data and displaying custom components.
+
+ \include examples-run.qdocinc
+
+ \sa {QML Applications}
+*/
diff --git a/examples/quick/demos/samegame/doc/src/samegame.qdoc b/examples/quick/demos/samegame/doc/src/samegame.qdoc
index 70042d73f0..acae8d728f 100644
--- a/examples/quick/demos/samegame/doc/src/samegame.qdoc
+++ b/examples/quick/demos/samegame/doc/src/samegame.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -30,7 +30,15 @@
\ingroup qtquickdemos
\example demos/samegame
\brief A QML implementation of the popular puzzle game by Kuniaki Moribe.
+
+ \e{Same Game} demonstrates a QML game with custom types and logic written in
+ JavaScript. The game uses various \l{Qt Quick} features such as
+ particles, animation, and loading images.
+
\image qtquick-demo-samegame-med-1.png
\image qtquick-demo-samegame-med-2.png
-*/
+ \include examples-run.qdocinc
+
+ \sa {QML Applications}
+*/
diff --git a/examples/quick/demos/stocqt/doc/src/stocqt.qdoc b/examples/quick/demos/stocqt/doc/src/stocqt.qdoc
index 7001bfb395..5f090e84f9 100644
--- a/examples/quick/demos/stocqt/doc/src/stocqt.qdoc
+++ b/examples/quick/demos/stocqt/doc/src/stocqt.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -31,5 +31,11 @@
\example demos/stocqt
\brief A configurable stock chart for the NASDAQ-100.
\image qtquick-demo-stocqt.png
-*/
+ \e{StocQt} demonstrates various QML and \l{Qt Quick} features such as
+ displaying custom components and downloading data from the internet.
+
+ \include examples-run.qdocinc
+
+ \sa {QML Applications}
+*/
diff --git a/examples/quick/demos/tweetsearch/doc/src/tweetsearch.qdoc b/examples/quick/demos/tweetsearch/doc/src/tweetsearch.qdoc
index a56ed0d7e9..41c6c09dea 100644
--- a/examples/quick/demos/tweetsearch/doc/src/tweetsearch.qdoc
+++ b/examples/quick/demos/tweetsearch/doc/src/tweetsearch.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -33,22 +33,20 @@
\image qtquick-demo-tweetsearch-med-1.png
\image qtquick-demo-tweetsearch-med-2.png
- \section1 Demo Introduction
-
- The Tweet Search demo searches items posted to Twitter service
- using a number of query parameters. Search can be done for tweets
- from a specified user, a hashtag or a search phrase.
+ \e{Tweet Search} is a QML application that searches items posted to Twitter
+ service using a number of query parameters. Search can be done for tweets
+ from a specified user, a hashtag, or a search phrase.
The search result is a list of items showing the contents of the
tweet as well as the name and image of the user who posted it.
Hashtags, names and links in the content are clickable. Clicking
on the image will flip the item to reveal more information.
- \section1 Running the Demo
+ \include examples-run.qdocinc
Tweet Search uses Twitter API v1.1 for running seaches.
- \section2 Authentication
+ \section1 Request Authentication
Each request must be authenticated on behalf of the application.
For demonstration purposes, the application uses a hard-coded
@@ -67,7 +65,7 @@
Rebuild and run the demo.
- \section2 JSON Parsing
+ \section1 JSON Parsing
Search results are returned in JSON (JavaScript Object Notation)
format. \c TweetsModel uses an \l XMLHTTPRequest object to send
@@ -76,4 +74,6 @@
representing a tweet is then added to a \l ListModel:
\snippet demos/tweetsearch/content/TweetsModel.qml requesting
+
+ \sa {QML Applications}
*/
diff --git a/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h b/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h
index 9a8dc1f358..f492cc8c94 100644
--- a/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h
+++ b/src/3rdparty/masm/assembler/MacroAssemblerARMv7.h
@@ -39,7 +39,7 @@ class MacroAssemblerARMv7 : public AbstractMacroAssembler<ARMv7Assembler> {
// - dTR is likely used more than aTR, and we'll get better instruction
// encoding if it's in the low 8 registers.
static const RegisterID dataTempRegister = ARMRegisters::ip;
- static const RegisterID addressTempRegister = ARMRegisters::r3;
+ static const RegisterID addressTempRegister = ARMRegisters::r10;
static const ARMRegisters::FPDoubleRegisterID fpTempRegister = ARMRegisters::d7;
inline ARMRegisters::FPSingleRegisterID fpTempRegisterAsSingle() { return ARMRegisters::asSingle(fpTempRegister); }
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index d1450f051c..1e067c8a1e 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -2212,8 +2212,6 @@ bool Codegen::visit(ForEachStatement *ast)
IR::BasicBlock *foreachbody = _function->newBasicBlock(foreachin, exceptionHandler());
IR::BasicBlock *foreachend = _function->newBasicBlock(groupStartBlock(), exceptionHandler());
- enterLoop(ast, foreachin, foreachend, foreachin);
-
int objectToIterateOn = _block->newTemp();
move(_block->TEMP(objectToIterateOn), *expression(ast->expression));
IR::ExprList *args = _function->New<IR::ExprList>();
@@ -2222,6 +2220,7 @@ bool Codegen::visit(ForEachStatement *ast)
int iterator = _block->newTemp();
move(_block->TEMP(iterator), _block->CALL(_block->NAME(IR::Name::builtin_foreach_iterator_object, 0, 0), args));
+ enterLoop(ast, foreachin, foreachend, foreachin);
_block->JUMP(foreachin);
_block = foreachbody;
@@ -2352,8 +2351,6 @@ bool Codegen::visit(LocalForEachStatement *ast)
IR::BasicBlock *foreachbody = _function->newBasicBlock(foreachin, exceptionHandler());
IR::BasicBlock *foreachend = _function->newBasicBlock(groupStartBlock(), exceptionHandler());
- enterLoop(ast, foreachin, foreachend, foreachin);
-
variableDeclaration(ast->declaration);
int iterator = _block->newTemp();
@@ -2363,6 +2360,7 @@ bool Codegen::visit(LocalForEachStatement *ast)
move(_block->TEMP(iterator), _block->CALL(_block->NAME(IR::Name::builtin_foreach_iterator_object, 0, 0), args));
_block->JUMP(foreachin);
+ enterLoop(ast, foreachin, foreachend, foreachin);
_block = foreachbody;
int temp = _block->newTemp();
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index afcf2c6a24..a4dcfd9209 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -196,6 +196,8 @@ struct Unit
const uint *offsetTable = reinterpret_cast<const uint*>((reinterpret_cast<const char *>(this)) + offsetToStringTable);
const uint offset = offsetTable[idx];
const String *str = reinterpret_cast<const String*>(reinterpret_cast<const char *>(this) + offset);
+ if (str->str.size == 0)
+ return QString();
QStringDataPtr holder = { const_cast<QStringData *>(static_cast<const QStringData*>(&str->str)) };
QString qstr(holder);
if (flags & StaticData)
diff --git a/src/qml/jit/qv4assembler_p.h b/src/qml/jit/qv4assembler_p.h
index 19804e7293..6fde517e1f 100644
--- a/src/qml/jit/qv4assembler_p.h
+++ b/src/qml/jit/qv4assembler_p.h
@@ -219,12 +219,12 @@ public:
#define ARGUMENTS_IN_REGISTERS
#undef HAVE_ALU_OPS_WITH_MEM_OPERAND
- static const RegisterID StackFrameRegister = JSC::ARMRegisters::r4;
- static const RegisterID StackPointerRegister = JSC::ARMRegisters::sp;
+ static const RegisterID StackPointerRegister = JSC::ARMRegisters::sp; // r13
+ static const RegisterID StackFrameRegister = JSC::ARMRegisters::fp; // r11
static const RegisterID LocalsRegister = JSC::ARMRegisters::r7;
+ static const RegisterID ScratchRegister = JSC::ARMRegisters::r6;
static const RegisterID ContextRegister = JSC::ARMRegisters::r5;
static const RegisterID ReturnValueRegister = JSC::ARMRegisters::r0;
- static const RegisterID ScratchRegister = JSC::ARMRegisters::r6;
static const FPRegisterID FPGpr0 = JSC::ARMRegisters::d0;
static const FPRegisterID FPGpr1 = JSC::ARMRegisters::d1;
diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp
index 74b404a793..3307fcc0d1 100644
--- a/src/qml/jit/qv4isel_masm.cpp
+++ b/src/qml/jit/qv4isel_masm.cpp
@@ -258,10 +258,10 @@ static QVector<int> getIntRegisters()
static const QVector<int> intRegisters = QVector<int>()
<< JSC::ARMRegisters::r1
<< JSC::ARMRegisters::r2
+ << JSC::ARMRegisters::r3
+ << JSC::ARMRegisters::r4
<< JSC::ARMRegisters::r8
- << JSC::ARMRegisters::r9
- << JSC::ARMRegisters::r10
- << JSC::ARMRegisters::r11;
+ << JSC::ARMRegisters::r9;
return intRegisters;
}
diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp
index de556dc9ed..b61be913a6 100644
--- a/src/qml/jsruntime/qv4qobjectwrapper.cpp
+++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp
@@ -685,7 +685,7 @@ void QObjectWrapper::put(Managed *m, const StringRef name, const ValueRef value)
QQmlData *ddata = QQmlData::get(that->m_object);
// Types created by QML are not extensible at run-time, but for other QObjects we can store them
// as regular JavaScript properties, like on JavaScript objects.
- if (ddata && ddata->compiledData) {
+ if (ddata && ddata->context) {
QString error = QLatin1String("Cannot assign to non-existent property \"") +
name->toQString() + QLatin1Char('\"');
v4->currentContext()->throwError(error);
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index 0bbcafda54..1075b53c5e 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -1403,6 +1403,12 @@ bool QQmlPropertyPrivate::write(QObject *object,
v = value;
if (v.convert(propertyType)) {
ok = true;
+ } else if (v.isValid() && value.isNull()) {
+ // For historical reasons converting a null QVariant to another type will do the trick
+ // but return false anyway. This is caught with the above condition and considered a
+ // successful conversion.
+ Q_ASSERT(v.userType() == propertyType);
+ ok = true;
} else if ((uint)propertyType >= QVariant::UserType && variantType == QVariant::String) {
QQmlMetaType::StringConverter con = QQmlMetaType::customStringConverter(propertyType);
if (con) {
diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h
index 32b1154d30..7da089c9b8 100644
--- a/src/qml/types/qqmldelegatemodel_p_p.h
+++ b/src/qml/types/qqmldelegatemodel_p_p.h
@@ -144,7 +144,7 @@ public:
QQmlDelegateModelItemMetaType * const metaType;
QQmlContextData *contextData;
QObject *object;
- QQmlDelegateModelAttached *attached;
+ QPointer<QQmlDelegateModelAttached> attached;
QQDMIncubationTask *incubationTask;
int objectRef;
int scriptRef;
diff --git a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
index 06a0713365..5697c25ff0 100644
--- a/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
+++ b/src/quick/items/context2d/qquickcontext2dcommandbuffer.cpp
@@ -214,6 +214,8 @@ void QQuickContext2DCommandBuffer::setPainterState(QPainter* p, const QQuickCont
if (state.globalCompositeOperation != p->compositionMode())
p->setCompositionMode(state.globalCompositeOperation);
+
+ p->setClipPath(state.clipPath);
}
static void qt_drawImage(QPainter *p, QQuickContext2D::State& state, QImage image, const QRectF& sr, const QRectF& dr, bool shadow = false)
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index 691fea21e1..3f0dae8070 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -1333,7 +1333,7 @@ void QQuickKeysAttached::keyPressed(QKeyEvent *event, bool post)
for (int ii = 0; ii < d->targets.count(); ++ii) {
QQuickItem *i = d->targets.at(ii);
if (i && i->isVisible()) {
- d->item->window()->sendEvent(i, event);
+ QCoreApplication::sendEvent(i, event);
if (event->isAccepted()) {
d->inPress = false;
return;
@@ -1375,7 +1375,7 @@ void QQuickKeysAttached::keyReleased(QKeyEvent *event, bool post)
for (int ii = 0; ii < d->targets.count(); ++ii) {
QQuickItem *i = d->targets.at(ii);
if (i && i->isVisible()) {
- d->item->window()->sendEvent(i, event);
+ QCoreApplication::sendEvent(i, event);
if (event->isAccepted()) {
d->inRelease = false;
return;
@@ -6391,10 +6391,12 @@ void QQuickItem::setFocus(bool focus, Qt::FocusReason reason)
while (scope && !scope->isFocusScope() && scope->parentItem())
scope = scope->parentItem();
if (d->window) {
- if (focus)
- QQuickWindowPrivate::get(d->window)->setFocusInScope(scope, this, reason);
- else
- QQuickWindowPrivate::get(d->window)->clearFocusInScope(scope, this, reason);
+ if (reason != Qt::PopupFocusReason) {
+ if (focus)
+ QQuickWindowPrivate::get(d->window)->setFocusInScope(scope, this, reason);
+ else
+ QQuickWindowPrivate::get(d->window)->clearFocusInScope(scope, this, reason);
+ }
} else {
// do the focus changes from setFocusInScope/clearFocusInScope that are
// unrelated to a window
diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp
index 46eec643fd..b4f6c34c6a 100644
--- a/src/quick/items/qquickitemview.cpp
+++ b/src/quick/items/qquickitemview.cpp
@@ -364,6 +364,8 @@ void QQuickItemView::setDelegate(QQmlComponent *delegate)
if (!d->ownModel) {
d->model = new QQmlDelegateModel(qmlContext(this));
d->ownModel = true;
+ if (isComponentComplete())
+ static_cast<QQmlDelegateModel *>(d->model.data())->componentComplete();
}
if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) {
int oldCount = dataModel->count();
diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp
index ec789670ab..45cd8e184c 100644
--- a/src/quick/items/qquickpathview.cpp
+++ b/src/quick/items/qquickpathview.cpp
@@ -1242,6 +1242,8 @@ void QQuickPathView::setDelegate(QQmlComponent *delegate)
if (!d->ownModel) {
d->model = new QQmlDelegateModel(qmlContext(this));
d->ownModel = true;
+ if (isComponentComplete())
+ static_cast<QQmlDelegateModel *>(d->model.data())->componentComplete();
}
if (QQmlDelegateModel *dataModel = qobject_cast<QQmlDelegateModel*>(d->model)) {
int oldCount = dataModel->count();
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 0a9677bd4e..53d736fb36 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -1365,6 +1365,11 @@ void QQuickTextControlPrivate::inputMethodEvent(QInputMethodEvent *e)
QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property) const
{
+ return inputMethodQuery(property, QVariant());
+}
+
+QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const
+{
Q_D(const QQuickTextControl);
QTextBlock block = d->cursor.block();
switch (property) {
@@ -1382,6 +1387,47 @@ QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property) cons
return QVariant(); // No limit.
case Qt::ImAnchorPosition:
return QVariant(d->cursor.anchor() - block.position());
+ case Qt::ImAbsolutePosition:
+ return QVariant(d->cursor.anchor());
+ case Qt::ImTextAfterCursor:
+ {
+ int maxLength = argument.isValid() ? argument.toInt() : 1024;
+ QTextCursor tmpCursor = d->cursor;
+ int localPos = d->cursor.position() - block.position();
+ QString result = block.text().mid(localPos);
+ while (result.length() < maxLength) {
+ int currentBlock = tmpCursor.blockNumber();
+ tmpCursor.movePosition(QTextCursor::NextBlock);
+ if (tmpCursor.blockNumber() == currentBlock)
+ break;
+ result += QLatin1Char('\n') + tmpCursor.block().text();
+ }
+ return QVariant(result);
+ }
+ case Qt::ImTextBeforeCursor:
+ {
+ int maxLength = argument.isValid() ? argument.toInt() : 1024;
+ QTextCursor tmpCursor = d->cursor;
+ int localPos = d->cursor.position() - block.position();
+ int numBlocks = 0;
+ int resultLen = localPos;
+ while (resultLen < maxLength) {
+ int currentBlock = tmpCursor.blockNumber();
+ tmpCursor.movePosition(QTextCursor::PreviousBlock);
+ if (tmpCursor.blockNumber() == currentBlock)
+ break;
+ numBlocks++;
+ resultLen += tmpCursor.block().length();
+ }
+ QString result;
+ while (numBlocks) {
+ result += tmpCursor.block().text() + QLatin1Char('\n');
+ tmpCursor.movePosition(QTextCursor::NextBlock);
+ --numBlocks;
+ }
+ result += block.text().mid(0,localPos);
+ return QVariant(result);
+ }
default:
return QVariant();
}
diff --git a/src/quick/items/qquicktextcontrol_p.h b/src/quick/items/qquicktextcontrol_p.h
index bc5371b0c3..39221ced11 100644
--- a/src/quick/items/qquicktextcontrol_p.h
+++ b/src/quick/items/qquicktextcontrol_p.h
@@ -160,6 +160,7 @@ public:
#ifndef QT_NO_IM
virtual QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
+ Q_INVOKABLE QVariant inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const;
#endif
virtual QMimeData *createMimeDataFromSelection() const;
diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp
index ec563273a1..c6e5f7ac7b 100644
--- a/src/quick/scenegraph/util/qsgtexture.cpp
+++ b/src/quick/scenegraph/util/qsgtexture.cpp
@@ -567,6 +567,7 @@ void QSGPlainTexture::setImage(const QImage &image)
m_has_alpha = image.hasAlphaChannel();
m_dirty_texture = true;
m_dirty_bind_options = true;
+ m_mipmaps_generated = false;
}
int QSGPlainTexture::textureId() const
diff --git a/src/quick/scenegraph/util/qsgtexturematerial.cpp b/src/quick/scenegraph/util/qsgtexturematerial.cpp
index fcdb4fcdfe..afa535d322 100644
--- a/src/quick/scenegraph/util/qsgtexturematerial.cpp
+++ b/src/quick/scenegraph/util/qsgtexturematerial.cpp
@@ -152,7 +152,7 @@ void QSGOpaqueTextureMaterialShader::updateState(const RenderState &state, QSGMa
QSGOpaqueTextureMaterial::QSGOpaqueTextureMaterial()
: m_texture(0)
, m_filtering(QSGTexture::Nearest)
- , m_mipmap_filtering(QSGTexture::Nearest)
+ , m_mipmap_filtering(QSGTexture::None)
, m_horizontal_wrap(QSGTexture::ClampToEdge)
, m_vertical_wrap(QSGTexture::ClampToEdge)
{
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 0a56c2f6d0..64c6754aa7 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -48,6 +48,7 @@
#include <qstandarditemmodel.h>
#include <QtCore/qnumeric.h>
#include <qqmlengine.h>
+#include <qqmlcomponent.h>
#include <stdlib.h>
#include <private/qv4alloca_p.h>
@@ -2964,11 +2965,34 @@ void tst_QJSEngine::prototypeChainGc()
void tst_QJSEngine::dynamicProperties()
{
- QJSEngine engine;
- QObject *obj = new QObject;
- QJSValue wrapper = engine.newQObject(obj);
- wrapper.setProperty("someRandomProperty", 42);
- QCOMPARE(wrapper.property("someRandomProperty").toInt(), 42);
+ {
+ QJSEngine engine;
+ QObject *obj = new QObject;
+ QJSValue wrapper = engine.newQObject(obj);
+ wrapper.setProperty("someRandomProperty", 42);
+ QCOMPARE(wrapper.property("someRandomProperty").toInt(), 42);
+ QVERIFY(!qmlContext(obj));
+ }
+ {
+ QQmlEngine qmlEngine;
+ QQmlComponent component(&qmlEngine);
+ component.setData("import QtQml 2.0; QtObject { property QtObject subObject: QtObject {} }", QUrl());
+ QObject *root = component.create(0);
+ QVERIFY(root);
+ QVERIFY(qmlContext(root));
+
+ QJSValue wrapper = qmlEngine.newQObject(root);
+ wrapper.setProperty("someRandomProperty", 42);
+ QVERIFY(!wrapper.hasProperty("someRandomProperty"));
+
+ QObject *subObject = qvariant_cast<QObject*>(root->property("subObject"));
+ QVERIFY(subObject);
+ QVERIFY(qmlContext(subObject));
+
+ wrapper = qmlEngine.newQObject(subObject);
+ wrapper.setProperty("someRandomProperty", 42);
+ QVERIFY(!wrapper.hasProperty("someRandomProperty"));
+ }
}
QTEST_MAIN(tst_QJSEngine)
diff --git a/tests/auto/qml/qqmllanguage/data/assignNullStrings.qml b/tests/auto/qml/qqmllanguage/data/assignNullStrings.qml
new file mode 100644
index 0000000000..5e1c3a9b03
--- /dev/null
+++ b/tests/auto/qml/qqmllanguage/data/assignNullStrings.qml
@@ -0,0 +1,9 @@
+import Test 1.0
+MyTypeObject {
+ stringProperty: ""
+ byteArrayProperty: ""
+ function assignNullStringsFromJs() {
+ stringProperty = ""
+ byteArrayProperty = ""
+ }
+}
diff --git a/tests/auto/qml/qqmllanguage/testtypes.h b/tests/auto/qml/qqmllanguage/testtypes.h
index 6a6b2eba45..1c13a2e21c 100644
--- a/tests/auto/qml/qqmllanguage/testtypes.h
+++ b/tests/auto/qml/qqmllanguage/testtypes.h
@@ -236,6 +236,7 @@ class MyTypeObject : public QObject
Q_PROPERTY(MyMirroredEnum mirroredEnumProperty READ mirroredEnumProperty WRITE setMirroredEnumProperty NOTIFY mirroredEnumPropertyChanged)
Q_PROPERTY(MyEnumContainer::RelatedEnum relatedEnumProperty READ relatedEnumProperty WRITE setRelatedEnumProperty)
Q_PROPERTY(QString stringProperty READ stringProperty WRITE setStringProperty NOTIFY stringPropertyChanged)
+ Q_PROPERTY(QByteArray byteArrayProperty READ byteArrayProperty WRITE setByteArrayProperty NOTIFY byteArrayPropertyChanged)
Q_PROPERTY(uint uintProperty READ uintProperty WRITE setUintProperty NOTIFY uintPropertyChanged)
Q_PROPERTY(int intProperty READ intProperty WRITE setIntProperty NOTIFY intPropertyChanged)
Q_PROPERTY(qreal realProperty READ realProperty WRITE setRealProperty NOTIFY realPropertyChanged)
@@ -357,6 +358,15 @@ public:
emit stringPropertyChanged();
}
+ QByteArray byteArrayPropertyValue;
+ QByteArray byteArrayProperty() const {
+ return byteArrayPropertyValue;
+ }
+ void setByteArrayProperty(const QByteArray &v) {
+ byteArrayPropertyValue = v;
+ emit byteArrayPropertyChanged();
+ }
+
uint uintPropertyValue;
uint uintProperty() const {
return uintPropertyValue;
@@ -570,6 +580,7 @@ signals:
void qtEnumPropertyChanged();
void mirroredEnumPropertyChanged();
void stringPropertyChanged();
+ void byteArrayPropertyChanged();
void uintPropertyChanged();
void intPropertyChanged();
void realPropertyChanged();
diff --git a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
index 55d07e78da..87f811cbbc 100644
--- a/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
+++ b/tests/auto/qml/qqmllanguage/tst_qqmllanguage.cpp
@@ -110,6 +110,7 @@ private slots:
void assignLiteralToVariant();
void assignLiteralToVar();
void assignLiteralToJSValue();
+ void assignNullStrings();
void bindJSValueToVar();
void bindJSValueToVariant();
void bindJSValueToType();
@@ -873,6 +874,19 @@ void tst_qqmllanguage::assignLiteralToJSValue()
}
}
+void tst_qqmllanguage::assignNullStrings()
+{
+ QQmlComponent component(&engine, testFileUrl("assignNullStrings.qml"));
+ VERIFY_ERRORS(0);
+ MyTypeObject *object = qobject_cast<MyTypeObject *>(component.create());
+ QVERIFY(object != 0);
+ QVERIFY(object->stringProperty().isNull());
+ QVERIFY(object->byteArrayProperty().isNull());
+ QMetaObject::invokeMethod(object, "assignNullStringsFromJs", Qt::DirectConnection);
+ QVERIFY(object->stringProperty().isNull());
+ QVERIFY(object->byteArrayProperty().isNull());
+}
+
void tst_qqmllanguage::bindJSValueToVar()
{
QQmlComponent component(&engine, testFileUrl("assignLiteralToJSValue.qml"));
diff --git a/tests/auto/qml/qqmlxmlhttprequest/data/stateChangeCallingContext.qml b/tests/auto/qml/qqmlxmlhttprequest/data/stateChangeCallingContext.qml
index f44f4f926c..b35c31d513 100644
--- a/tests/auto/qml/qqmlxmlhttprequest/data/stateChangeCallingContext.qml
+++ b/tests/auto/qml/qqmlxmlhttprequest/data/stateChangeCallingContext.qml
@@ -8,7 +8,7 @@ Item {
SequentialAnimation {
id: anim
- PauseAnimation { duration: 525 } // delay mode is 500 msec.
+ PauseAnimation { duration: 1000 } // delay mode is 500 msec.
ScriptAction { script: loadcomponent(0) }
PauseAnimation { duration: 525 } // delay mode is 500 msec.
ScriptAction { script: loadcomponent(1) }
diff --git a/tests/auto/qmltest/listview/tst_listview.qml b/tests/auto/qmltest/listview/tst_listview.qml
index 0589e7c46b..03be57909f 100644
--- a/tests/auto/qmltest/listview/tst_listview.qml
+++ b/tests/auto/qmltest/listview/tst_listview.qml
@@ -102,6 +102,23 @@ Item {
}
}
+ ListView {
+ id: listViewDelegateModelAfterCreate
+ anchors.fill: parent
+ property int createdDelegates: 0
+ }
+
+ Component {
+ id: delegateModelAfterCreateComponent
+ Rectangle {
+ width: 140
+ height: 140
+ border.color: "black"
+ color: "red"
+ Component.onCompleted: listViewDelegateModelAfterCreate.createdDelegates++;
+ }
+ }
+
ListModel { id: emptymodel }
ListModel { id: manyitems }
ListModel { id: firstmodel; ListElement { name: "FirstModelElement0" } }
@@ -249,5 +266,11 @@ Item {
asyncListViewLoaderView.currentIndex = 4;
}
}
+
+ function test_set_delegate_model_after_list_creation() {
+ listViewDelegateModelAfterCreate.delegate = delegateModelAfterCreateComponent;
+ listViewDelegateModelAfterCreate.model = 40;
+ verify(listViewDelegateModelAfterCreate.createdDelegates > 0);
+ }
}
}
diff --git a/tests/auto/qmltest/pathview/tst_pathview.qml b/tests/auto/qmltest/pathview/tst_pathview.qml
new file mode 100644
index 0000000000..820034c960
--- /dev/null
+++ b/tests/auto/qmltest/pathview/tst_pathview.qml
@@ -0,0 +1,35 @@
+import QtQuick 2.1
+import QtTest 1.0
+
+Item {
+ id: top
+
+ PathView {
+ id: pathViewDelegateModelAfterCreate
+ anchors.fill: parent
+ property int createdDelegates: 0
+ path: Path { startX: 120; startY: 100 }
+ }
+
+ Component {
+ id: delegateModelAfterCreateComponent
+ Rectangle {
+ width: 140
+ height: 140
+ border.color: "black"
+ color: "red"
+ Component.onCompleted: pathViewDelegateModelAfterCreate.createdDelegates++;
+ }
+ }
+
+ TestCase {
+ name: "PathView"
+ when: windowShown
+
+ function test_set_delegate_model_after_path_creation() {
+ pathViewDelegateModelAfterCreate.delegate = delegateModelAfterCreateComponent;
+ pathViewDelegateModelAfterCreate.model = 40;
+ verify(pathViewDelegateModelAfterCreate.createdDelegates > 0);
+ }
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/data/keysforward.qml b/tests/auto/quick/qquickitem2/data/keysforward.qml
new file mode 100644
index 0000000000..f0cb4d9508
--- /dev/null
+++ b/tests/auto/quick/qquickitem2/data/keysforward.qml
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite 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$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+
+Item {
+ id: root
+
+ property alias source: source
+ property alias primaryTarget: primaryTarget
+ property alias secondaryTarget: secondaryTarget
+
+ property var pressedKeys: []
+ property var releasedKeys: []
+ Keys.onPressed: { var keys = pressedKeys; keys.push(event.key); pressedKeys = keys }
+ Keys.onReleased: { var keys = releasedKeys; keys.push(event.key); releasedKeys = keys }
+
+ Item {
+ id: primaryTarget
+ objectName: "primary"
+ property var pressedKeys: []
+ property var releasedKeys: []
+ Keys.forwardTo: secondaryTarget
+ Keys.onPressed: { event.accepted = event.key === Qt.Key_P; var keys = pressedKeys; keys.push(event.key); pressedKeys = keys }
+ Keys.onReleased: { event.accepted = event.key === Qt.Key_P; var keys = releasedKeys; keys.push(event.key); releasedKeys = keys }
+
+ Item {
+ id: source
+ objectName: "source"
+ property var pressedKeys: []
+ property var releasedKeys: []
+ Keys.forwardTo: primaryTarget
+ Keys.onPressed: { var keys = pressedKeys; keys.push(event.key); pressedKeys = keys }
+ Keys.onReleased: { var keys = releasedKeys; keys.push(event.key); releasedKeys = keys }
+ }
+ }
+
+ Item {
+ id: secondaryTarget
+ objectName: "secondary"
+ property var pressedKeys: []
+ property var releasedKeys: []
+ Keys.onPressed: { event.accepted = event.key === Qt.Key_S; var keys = pressedKeys; keys.push(event.key); pressedKeys = keys }
+ Keys.onReleased: { event.accepted = event.key === Qt.Key_S; var keys = releasedKeys; keys.push(event.key); releasedKeys = keys }
+ }
+}
diff --git a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
index e6fd98ac35..6778d6a8b6 100644
--- a/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
+++ b/tests/auto/quick/qquickitem2/tst_qquickitem.cpp
@@ -85,6 +85,7 @@ private slots:
void standardKeys();
void keysProcessingOrder();
void keysim();
+ void keysForward();
void keyNavigation_data();
void keyNavigation();
void keyNavigation_RightToLeft();
@@ -1386,6 +1387,78 @@ void tst_QQuickItem::keysim()
delete window;
}
+void tst_QQuickItem::keysForward()
+{
+ QQuickView window;
+ window.setBaseSize(QSize(240,320));
+
+ window.setSource(testFileUrl("keysforward.qml"));
+ window.show();
+ window.requestActivate();
+ QVERIFY(QTest::qWaitForWindowActive(&window));
+ QVERIFY(QGuiApplication::focusWindow() == &window);
+
+ QQuickItem *rootItem = qobject_cast<QQuickItem *>(window.rootObject());
+ QVERIFY(rootItem);
+ QQuickItem *sourceItem = rootItem->property("source").value<QQuickItem *>();
+ QVERIFY(sourceItem);
+ QQuickItem *primaryTarget = rootItem->property("primaryTarget").value<QQuickItem *>();
+ QVERIFY(primaryTarget);
+ QQuickItem *secondaryTarget = rootItem->property("secondaryTarget").value<QQuickItem *>();
+ QVERIFY(secondaryTarget);
+
+ // primary target accepts/consumes Key_P
+ QKeyEvent pressKeyP(QEvent::KeyPress, Qt::Key_P, Qt::NoModifier, "P");
+ QCoreApplication::sendEvent(sourceItem, &pressKeyP);
+ QCOMPARE(rootItem->property("pressedKeys").toList(), QVariantList());
+ QCOMPARE(sourceItem->property("pressedKeys").toList(), QVariantList());
+ QCOMPARE(primaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P);
+ QCOMPARE(secondaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P);
+ QVERIFY(pressKeyP.isAccepted());
+
+ QKeyEvent releaseKeyP(QEvent::KeyRelease, Qt::Key_P, Qt::NoModifier, "P");
+ QCoreApplication::sendEvent(sourceItem, &releaseKeyP);
+ QCOMPARE(rootItem->property("releasedKeys").toList(), QVariantList());
+ QCOMPARE(sourceItem->property("releasedKeys").toList(), QVariantList());
+ QCOMPARE(primaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P);
+ QCOMPARE(secondaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P);
+ QVERIFY(releaseKeyP.isAccepted());
+
+ // secondary target accepts/consumes Key_S
+ QKeyEvent pressKeyS(QEvent::KeyPress, Qt::Key_S, Qt::NoModifier, "S");
+ QCoreApplication::sendEvent(sourceItem, &pressKeyS);
+ QCOMPARE(rootItem->property("pressedKeys").toList(), QVariantList());
+ QCOMPARE(sourceItem->property("pressedKeys").toList(), QVariantList());
+ QCOMPARE(primaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P);
+ QCOMPARE(secondaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_S);
+ QVERIFY(pressKeyS.isAccepted());
+
+ QKeyEvent releaseKeyS(QEvent::KeyRelease, Qt::Key_S, Qt::NoModifier, "S");
+ QCoreApplication::sendEvent(sourceItem, &releaseKeyS);
+ QCOMPARE(rootItem->property("releasedKeys").toList(), QVariantList());
+ QCOMPARE(sourceItem->property("releasedKeys").toList(), QVariantList());
+ QCOMPARE(primaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P);
+ QCOMPARE(secondaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_S);
+ QVERIFY(releaseKeyS.isAccepted());
+
+ // neither target accepts/consumes Key_Q
+ QKeyEvent pressKeyQ(QEvent::KeyPress, Qt::Key_Q, Qt::NoModifier, "Q");
+ QCoreApplication::sendEvent(sourceItem, &pressKeyQ);
+ QCOMPARE(rootItem->property("pressedKeys").toList(), QVariantList());
+ QCOMPARE(sourceItem->property("pressedKeys").toList(), QVariantList() << Qt::Key_Q);
+ QCOMPARE(primaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_Q);
+ QCOMPARE(secondaryTarget->property("pressedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_S << Qt::Key_Q);
+ QVERIFY(!pressKeyQ.isAccepted());
+
+ QKeyEvent releaseKeyQ(QEvent::KeyRelease, Qt::Key_Q, Qt::NoModifier, "Q");
+ QCoreApplication::sendEvent(sourceItem, &releaseKeyQ);
+ QCOMPARE(rootItem->property("releasedKeys").toList(), QVariantList());
+ QCOMPARE(sourceItem->property("releasedKeys").toList(), QVariantList() << Qt::Key_Q);
+ QCOMPARE(primaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_Q);
+ QCOMPARE(secondaryTarget->property("releasedKeys").toList(), QVariantList() << Qt::Key_P << Qt::Key_S << Qt::Key_Q);
+ QVERIFY(!releaseKeyQ.isAccepted());
+}
+
QQuickItemPrivate *childPrivate(QQuickItem *rootItem, const char * itemString)
{
QQuickItem *item = findItem<QQuickItem>(rootItem, QString(QLatin1String(itemString)));
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
index 91a6886bf0..45d23abbf6 100644
--- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
@@ -1296,7 +1296,7 @@ void tst_qquicktextedit::selectionOnFocusOut()
QVERIFY(edit2->hasActiveFocus());
edit2->setFocus(false, Qt::PopupFocusReason);
- QVERIFY(!edit2->hasActiveFocus());
+ QVERIFY(edit2->hasActiveFocus());
QCOMPARE(edit2->selectedText(), QLatin1String("text 2"));
}
diff --git a/tests/auto/quick/qquicktextinput/qquicktextinput.pro b/tests/auto/quick/qquicktextinput/qquicktextinput.pro
index c14b09c545..521f41df43 100644
--- a/tests/auto/quick/qquicktextinput/qquicktextinput.pro
+++ b/tests/auto/quick/qquicktextinput/qquicktextinput.pro
@@ -14,3 +14,5 @@ TESTDATA = data/*
QT += core-private gui-private qml-private quick-private testlib
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
+
+macx: CONFIG+=insignificant_test # QTBUG-38363
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index 273c0de660..e125c33a56 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -3605,7 +3605,8 @@ void tst_qquicktextinput::focusOutNotClearSelection()
input.setFocus(false, Qt::PopupFocusReason);
QGuiApplication::processEvents();
QTRY_COMPARE(input.selectedText(), QLatin1String("llo"));
- QTRY_COMPARE(input.hasActiveFocus(), false);
+ // QTBUG-36332 and 36292: a popup window does not take focus
+ QTRY_COMPARE(input.hasActiveFocus(), true);
input.setFocus(true);
QTRY_COMPARE(input.hasActiveFocus(), true);
diff --git a/tools/qmlplugindump/main.cpp b/tools/qmlplugindump/main.cpp
index 8babaecc8b..bc55c40434 100644
--- a/tools/qmlplugindump/main.cpp
+++ b/tools/qmlplugindump/main.cpp
@@ -317,6 +317,29 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine,
return metas;
}
+class KnownAttributes {
+ QHash<QByteArray, int> m_properties;
+ QHash<QByteArray, QHash<int, int> > m_methods;
+public:
+ bool knownMethod(const QByteArray &name, int nArgs, int revision)
+ {
+ if (m_methods.contains(name)) {
+ QHash<int, int> overloads = m_methods.value(name);
+ if (overloads.contains(nArgs) && overloads.value(nArgs) <= revision)
+ return true;
+ }
+ m_methods[name][nArgs] = revision;
+ return false;
+ }
+
+ bool knownProperty(const QByteArray &name, int revision)
+ {
+ if (m_properties.contains(name) && m_properties.value(name) <= revision)
+ return true;
+ m_properties[name] = revision;
+ return false;
+ }
+};
class Dumper
{
@@ -350,12 +373,15 @@ public:
return exportString;
}
- void writeMetaContent(const QMetaObject *meta)
+ void writeMetaContent(const QMetaObject *meta, KnownAttributes *knownAttributes = 0)
{
QSet<QString> implicitSignals;
for (int index = meta->propertyOffset(); index < meta->propertyCount(); ++index) {
const QMetaProperty &property = meta->property(index);
- dump(property);
+ dump(property, knownAttributes);
+ if (knownAttributes)
+ knownAttributes->knownMethod(QByteArray(property.name()).append("Changed"),
+ 0, property.revision());
implicitSignals.insert(QString("%1Changed").arg(QString::fromUtf8(property.name())));
}
@@ -368,38 +394,52 @@ public:
|| signature == QByteArrayLiteral("destroyed()")
|| signature == QByteArrayLiteral("deleteLater()"))
continue;
- dump(method, implicitSignals);
+ dump(method, implicitSignals, knownAttributes);
}
// and add toString(), destroy() and destroy(int)
- qml->writeStartObject(QLatin1String("Method"));
- qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("toString")));
- qml->writeEndObject();
- qml->writeStartObject(QLatin1String("Method"));
- qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy")));
- qml->writeEndObject();
- qml->writeStartObject(QLatin1String("Method"));
- qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy")));
- qml->writeStartObject(QLatin1String("Parameter"));
- qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("delay")));
- qml->writeScriptBinding(QLatin1String("type"), enquote(QLatin1String("int")));
- qml->writeEndObject();
- qml->writeEndObject();
+ if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("toString"), 0, 0)) {
+ qml->writeStartObject(QLatin1String("Method"));
+ qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("toString")));
+ qml->writeEndObject();
+ }
+ if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 0, 0)) {
+ qml->writeStartObject(QLatin1String("Method"));
+ qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy")));
+ qml->writeEndObject();
+ }
+ if (!knownAttributes || !knownAttributes->knownMethod(QByteArray("destroy"), 1, 0)) {
+ qml->writeStartObject(QLatin1String("Method"));
+ qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("destroy")));
+ qml->writeStartObject(QLatin1String("Parameter"));
+ qml->writeScriptBinding(QLatin1String("name"), enquote(QLatin1String("delay")));
+ qml->writeScriptBinding(QLatin1String("type"), enquote(QLatin1String("int")));
+ qml->writeEndObject();
+ qml->writeEndObject();
+ }
} else {
for (int index = meta->methodOffset(); index < meta->methodCount(); ++index)
- dump(meta->method(index), implicitSignals);
+ dump(meta->method(index), implicitSignals, knownAttributes);
}
}
- QString getPrototypeNameForCompositeType(const QMetaObject *metaObject, QSet<QByteArray> &defaultReachableNames)
+ QString getPrototypeNameForCompositeType(const QMetaObject *metaObject, QSet<QByteArray> &defaultReachableNames,
+ QList<const QMetaObject *> *objectsToMerge)
{
QString prototypeName;
if (!defaultReachableNames.contains(metaObject->className())) {
+ // dynamic meta objects can break things badly
+ // but extended types are usually fine
+ const QMetaObjectPrivate *mop = reinterpret_cast<const QMetaObjectPrivate *>(metaObject->d.data);
+ if (!(mop->flags & DynamicMetaObject) && objectsToMerge
+ && !objectsToMerge->contains(metaObject))
+ objectsToMerge->append(metaObject);
const QMetaObject *superMetaObject = metaObject->superClass();
if (!superMetaObject)
prototypeName = "QObject";
else
- prototypeName = getPrototypeNameForCompositeType(superMetaObject, defaultReachableNames);
+ prototypeName = getPrototypeNameForCompositeType(
+ superMetaObject, defaultReachableNames, objectsToMerge);
} else {
prototypeName = convertToId(metaObject->className());
}
@@ -418,8 +458,11 @@ public:
const QMetaObject *mainMeta = object->metaObject();
+ QList<const QMetaObject *> objectsToMerge;
+ KnownAttributes knownAttributes;
// Get C++ base class name for the composite type
- QString prototypeName = getPrototypeNameForCompositeType(mainMeta, defaultReachableNames);
+ QString prototypeName = getPrototypeNameForCompositeType(mainMeta, defaultReachableNames,
+ &objectsToMerge);
qml->writeScriptBinding(QLatin1String("prototype"), enquote(prototypeName));
QString qmlTyName = compositeType->qmlTypeName();
@@ -443,25 +486,8 @@ public:
}
}
- QSet<const QMetaObject *> metas;
- QSet<const QMetaObject *> candidatesComposite;
- collectReachableMetaObjects(mainMeta, &candidatesComposite);
-
- // Also eliminate meta objects with the same classname.
- // This is required because extended objects seem not to share
- // a single meta object instance.
- foreach (const QMetaObject *mo, candidatesComposite) {
- if (!defaultReachableNames.contains(mo->className()))
- metas.insert(mo);
- }
-
- // put the metaobjects into a map so they are always dumped in the same order
- QMap<QString, const QMetaObject *> nameToMeta;
- foreach (const QMetaObject *meta, metas)
- nameToMeta.insert(convertToId(meta), meta);
-
- foreach (const QMetaObject *meta, nameToMeta)
- writeMetaContent(meta);
+ foreach (const QMetaObject *meta, objectsToMerge)
+ writeMetaContent(meta, &knownAttributes);
qml->writeEndObject();
}
@@ -579,21 +605,23 @@ private:
qml->writeScriptBinding(QLatin1String("isPointer"), QLatin1String("true"));
}
- void dump(const QMetaProperty &prop)
+ void dump(const QMetaProperty &prop, KnownAttributes *knownAttributes = 0)
{
+ int revision = prop.revision();
+ QByteArray propName = prop.name();
+ if (knownAttributes && knownAttributes->knownProperty(propName, revision))
+ return;
qml->writeStartObject("Property");
-
qml->writeScriptBinding(QLatin1String("name"), enquote(QString::fromUtf8(prop.name())));
-#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 4))
- if (int revision = prop.revision())
+ if (revision)
qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision));
-#endif
writeTypeProperties(prop.typeName(), prop.isWritable());
qml->writeEndObject();
}
- void dump(const QMetaMethod &meth, const QSet<QString> &implicitSignals)
+ void dump(const QMetaMethod &meth, const QSet<QString> &implicitSignals,
+ KnownAttributes *knownAttributes = 0)
{
if (meth.methodType() == QMetaMethod::Signal) {
if (meth.access() != QMetaMethod::Public)
@@ -614,6 +642,9 @@ private:
return;
}
+ int revision = meth.revision();
+ if (knownAttributes && knownAttributes->knownMethod(name, meth.parameterNames().size(), revision))
+ return;
if (meth.methodType() == QMetaMethod::Signal)
qml->writeStartObject(QLatin1String("Signal"));
else
@@ -621,10 +652,8 @@ private:
qml->writeScriptBinding(QLatin1String("name"), enquote(name));
-#if (QT_VERSION >= QT_VERSION_CHECK(4, 7, 4))
- if (int revision = meth.revision())
+ if (revision)
qml->writeScriptBinding(QLatin1String("revision"), QString::number(revision));
-#endif
if (typeName != QLatin1String("void"))
qml->writeScriptBinding(QLatin1String("type"), enquote(typeName));