aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorQt Forward Merge Bot <qt_forward_merge_bot@qt-project.org>2019-03-13 01:01:04 +0100
committerUlf Hermann <ulf.hermann@qt.io>2019-03-13 10:10:09 +0100
commit76be4abbbcfb2fbb14ce532413e0895198e7f0f1 (patch)
tree5d6ca9c4425df15a93b6f74dc8e4dbb38db74d91 /src/qml
parent587d789fa5929f462b5744ba33a25db6c77b36fc (diff)
parent70d726e91e4ef27002b2271805de19077e25809c (diff)
Merge remote-tracking branch 'origin/5.12' into 5.13
Conflicts: src/qml/compiler/qv4codegen.cpp src/qml/animations/qsequentialanimationgroupjob.cpp Change-Id: I8b76e509fd7c8599d4cef25181d790ee28edab54
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/animations/qanimationgroupjob.cpp10
-rw-r--r--src/qml/animations/qsequentialanimationgroupjob.cpp4
-rw-r--r--src/qml/compiler/qv4codegen.cpp31
-rw-r--r--src/qml/doc/src/cppintegration/definetypes.qdoc2
-rw-r--r--src/qml/doc/src/qmllanguageref/syntax/signals.qdoc32
-rw-r--r--src/qml/jsruntime/qv4numberobject.cpp38
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp21
-rw-r--r--src/qml/qml/qqmlapplicationengine.cpp8
-rw-r--r--src/qml/types/qqmldelegatemodel.cpp21
9 files changed, 68 insertions, 99 deletions
diff --git a/src/qml/animations/qanimationgroupjob.cpp b/src/qml/animations/qanimationgroupjob.cpp
index 344791fd83..66599561fc 100644
--- a/src/qml/animations/qanimationgroupjob.cpp
+++ b/src/qml/animations/qanimationgroupjob.cpp
@@ -120,13 +120,9 @@ void QAnimationGroupJob::removeAnimation(QAbstractAnimationJob *animation)
void QAnimationGroupJob::clear()
{
- QAbstractAnimationJob *child = firstChild();
- QAbstractAnimationJob *nextSibling = nullptr;
- while (child != nullptr) {
- child->m_group = nullptr;
- nextSibling = child->nextSibling();
- delete child;
- child = nextSibling;
+ while (QAbstractAnimationJob *child = firstChild()) {
+ removeAnimation(child);
+ delete child;
}
m_firstChild = nullptr;
m_lastChild = nullptr;
diff --git a/src/qml/animations/qsequentialanimationgroupjob.cpp b/src/qml/animations/qsequentialanimationgroupjob.cpp
index 0595141d60..d98546122f 100644
--- a/src/qml/animations/qsequentialanimationgroupjob.cpp
+++ b/src/qml/animations/qsequentialanimationgroupjob.cpp
@@ -206,9 +206,11 @@ int QSequentialAnimationGroupJob::duration() const
void QSequentialAnimationGroupJob::clear()
{
- m_currentAnimation = nullptr;
m_previousLoop = 0;
QAnimationGroupJob::clear();
+
+ // clear() should call removeAnimation(), which will clear m_currentAnimation, eventually.
+ Q_ASSERT(m_currentAnimation == nullptr);
}
void QSequentialAnimationGroupJob::updateCurrentTime(int currentTime)
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 17869bcc84..ac763e592f 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -727,9 +727,6 @@ void Codegen::destructureElementList(const Codegen::Reference &array, PatternEle
bytecodeGenerator->addInstruction(iteratorObjInstr);
iterator.storeConsumeAccumulator();
- bool hasRest = false;
-
- BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
{
auto cleanup = [this, iterator, iteratorDone]() {
iterator.loadInAccumulator();
@@ -760,27 +757,17 @@ void Codegen::destructureElementList(const Codegen::Reference &array, PatternEle
Reference::fromConst(this, Encode(true)).storeOnStack(iteratorDone.stackSlot());
bytecodeGenerator->addInstruction(Instruction::DestructureRestElement());
initializeAndDestructureBindingElement(e, Reference::fromAccumulator(this), isDefinition);
- hasRest = true;
} else {
Instruction::IteratorNext next;
next.value = iteratorValue.stackSlot();
next.done = iteratorDone.stackSlot();
bytecodeGenerator->addInstruction(next);
initializeAndDestructureBindingElement(e, iteratorValue, isDefinition);
- if (hasError) {
- end.link();
+ if (hasError)
return;
- }
}
}
-
- if (hasRest)
- // no need to close the iterator
- bytecodeGenerator->jump().link(end);
}
-
-
- end.link();
}
void Codegen::destructurePattern(Pattern *p, const Reference &rhs)
@@ -1220,7 +1207,6 @@ bool Codegen::visit(ArrayPattern *ast)
BytecodeGenerator::Label in = bytecodeGenerator->newLabel();
BytecodeGenerator::Label end = bytecodeGenerator->newLabel();
- BytecodeGenerator::Label done = bytecodeGenerator->newLabel();
{
auto cleanup = [this, iterator, iteratorDone]() {
@@ -1230,12 +1216,6 @@ bool Codegen::visit(ArrayPattern *ast)
bytecodeGenerator->addInstruction(close);
};
ControlFlowLoop flow(this, &end, &in, cleanup);
- bytecodeGenerator->jump().link(in);
-
- BytecodeGenerator::Label body = bytecodeGenerator->label();
-
- lhsValue.loadInAccumulator();
- pushAccumulator();
in.link();
iterator.loadInAccumulator();
@@ -1243,13 +1223,14 @@ bool Codegen::visit(ArrayPattern *ast)
next.value = lhsValue.stackSlot();
next.done = iteratorDone.stackSlot();
bytecodeGenerator->addInstruction(next);
- bytecodeGenerator->addTracingJumpInstruction(Instruction::JumpFalse()).link(body);
- bytecodeGenerator->jump().link(done);
+ bytecodeGenerator->addTracingJumpInstruction(Instruction::JumpTrue()).link(end);
+ lhsValue.loadInAccumulator();
+ pushAccumulator();
+
+ bytecodeGenerator->jump().link(in);
end.link();
}
-
- done.link();
} else {
RegisterScope innerScope(this);
Reference expr = expression(it->element->initializer);
diff --git a/src/qml/doc/src/cppintegration/definetypes.qdoc b/src/qml/doc/src/cppintegration/definetypes.qdoc
index 0cce1895cb..f6f630c749 100644
--- a/src/qml/doc/src/cppintegration/definetypes.qdoc
+++ b/src/qml/doc/src/cppintegration/definetypes.qdoc
@@ -66,6 +66,8 @@ this manner, but the type cannot be used instantiated as a QML object type
from QML. This is useful, for example, if a type has enums that should be
exposed to QML but the type itself should not be instantiable.
+For a quick guide to choosing the correct approach to expose C++ types to QML,
+see \l {Choosing the Correct Integration Method Between C++ and QML}.
\section2 Registering an Instantiable Object Type
diff --git a/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc b/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc
index b643f18154..cd73ccc025 100644
--- a/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc
+++ b/src/qml/doc/src/qmllanguageref/syntax/signals.qdoc
@@ -59,9 +59,9 @@ receiving this signal should be \c onClicked. In the example below, whenever
the button is clicked, the \c onClicked handler is invoked, applying a random
color to the parent \l Rectangle:
-\qml
-import QtQuick 2.\QtMinorVersion
-import QtQuick.Controls 2.\QtMinorVersion
+\qml \QtMinorVersion
+import QtQuick 2.\1
+import QtQuick.Controls 2.\1
Rectangle {
id: rect
@@ -87,8 +87,8 @@ these signals are written in the form \e on<Property>Changed, where
For example, the \l MouseArea type has a \l {MouseArea::pressed}{pressed} property. To receive a notification whenever this property changes, write a signal handler named \c onPressedChanged:
-\qml
-import QtQuick 2.\QtMinorVersion
+\qml \QtMinorVersion
+import QtQuick 2.\1
Rectangle {
id: rect
@@ -116,9 +116,9 @@ received by the root \l Rectangle instead, by placing the \c onClicked handler
in a \l Connections object that has its \l {Connections::target}{target} set to
the \c button:
-\qml
-import QtQuick 2.\QtMinorVersion
-import QtQuick.Controls 2.\QtMinorVersion
+\qml \QtMinorVersion
+import QtQuick 2.\1
+import QtQuick.Controls 2.\1
Rectangle {
id: rect
@@ -151,8 +151,8 @@ For example, \l{Component::completed}{Component.onCompleted} is an attached
signal handler. It is often used to execute some JavaScript code when its
creation process is complete. Here is an example:
-\qml
-import QtQuick 2.\QtMinorVersion
+\qml \QtMinorVersion
+import QtQuick 2.\1
Rectangle {
width: 200; height: 200
@@ -195,9 +195,9 @@ root \l Rectangle object has an \c activated signal, which is emitted whenever t
child \l TapHandler is \c tapped. In this particular example the activated signal
is emitted with the x and y coordinates of the mouse click:
-\qml
+\qml \QtMinorVersion
// SquareButton.qml
-import QtQuick 2.\QtMinorVersion
+import QtQuick 2.\1
Rectangle {
id: root
@@ -237,8 +237,8 @@ signal to be received by a method instead of a signal handler.
Below, the \c messageReceived signal is connected to three methods using the \c connect() method:
-\qml
-import QtQuick 2.\QtMinorVersion
+\qml \QtMinorVersion
+import QtQuick 2.\1
Rectangle {
id: relay
@@ -289,8 +289,8 @@ Rectangle {
By connecting signals to other signals, the \c connect() method can form different
signal chains.
-\qml
-import QtQuick 2.\QtMinorVersion
+\qml \QtMinorVersion
+import QtQuick 2.\1
Rectangle {
id: forwarder
diff --git a/src/qml/jsruntime/qv4numberobject.cpp b/src/qml/jsruntime/qv4numberobject.cpp
index d26e888069..13f6912371 100644
--- a/src/qml/jsruntime/qv4numberobject.cpp
+++ b/src/qml/jsruntime/qv4numberobject.cpp
@@ -223,41 +223,9 @@ ReturnedValue NumberPrototype::method_toString(const FunctionObject *b, const Va
return v4->throwError(QStringLiteral("Number.prototype.toString: %0 is not a valid radix").arg(radix));
}
- if (std::isnan(num)) {
- return Encode(v4->newString(QStringLiteral("NaN")));
- } else if (qt_is_inf(num)) {
- return Encode(v4->newString(QLatin1String(num < 0 ? "-Infinity" : "Infinity")));
- }
-
- if (radix != 10) {
- QString str;
- bool negative = false;
- if (num < 0) {
- negative = true;
- num = -num;
- }
- double frac = num - std::floor(num);
- num = Value::toInteger(num);
- do {
- char c = (char)std::fmod(num, radix);
- c = (c < 10) ? (c + '0') : (c - 10 + 'a');
- str.prepend(QLatin1Char(c));
- num = std::floor(num / radix);
- } while (num != 0);
- if (frac != 0) {
- str.append(QLatin1Char('.'));
- do {
- frac = frac * radix;
- char c = (char)std::floor(frac);
- c = (c < 10) ? (c + '0') : (c - 10 + 'a');
- str.append(QLatin1Char(c));
- frac = frac - std::floor(frac);
- } while (frac != 0);
- }
- if (negative)
- str.prepend(QLatin1Char('-'));
- return Encode(v4->newString(str));
- }
+ QString str;
+ RuntimeHelpers::numberToString(&str, num, radix);
+ return Encode(v4->newString(str));
}
return Encode(Value::fromDouble(num).toString(v4));
diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp
index abf48b1034..afa4632e07 100644
--- a/src/qml/jsruntime/qv4runtime.cpp
+++ b/src/qml/jsruntime/qv4runtime.cpp
@@ -298,13 +298,22 @@ void RuntimeHelpers::numberToString(QString *result, double num, int radix)
if (frac != 0) {
result->append(QLatin1Char('.'));
+ double magnitude = 1;
+ double next = frac;
do {
- frac = frac * radix;
- char c = (char)::floor(frac);
+ next *= radix;
+ const int floored = ::floor(next);
+ char c = char(floored);
c = (c < 10) ? (c + '0') : (c - 10 + 'a');
result->append(QLatin1Char(c));
- frac = frac - ::floor(frac);
- } while (frac != 0);
+ magnitude /= radix;
+ frac -= double(floored) * magnitude;
+ next -= double(floored);
+
+ // The next digit still makes a difference
+ // if a value of "radix" for it would change frac.
+ // Otherwise we've reached the limit of numerical precision.
+ } while (frac > 0 && frac - magnitude != frac);
}
if (negative)
@@ -1600,12 +1609,14 @@ ReturnedValue Runtime::method_tailCall(CppStackFrame *frame, ExecutionEngine *en
const Value &thisObject = tos[StackOffsets::tailCall_thisObject];
Value *argv = reinterpret_cast<Value *>(frame->jsFrame) + tos[StackOffsets::tailCall_argv].int_32();
int argc = tos[StackOffsets::tailCall_argc].int_32();
+ Q_ASSERT(argc >= 0);
if (!function.isFunctionObject())
return engine->throwTypeError();
const FunctionObject &fo = static_cast<const FunctionObject &>(function);
- if (!frame->callerCanHandleTailCall || !fo.canBeTailCalled() || engine->debugger()) {
+ if (!frame->callerCanHandleTailCall || !fo.canBeTailCalled() || engine->debugger()
+ || unsigned(argc) > fo.formalParameterCount()) {
// Cannot tailcall, do a normal call:
return fo.call(&thisObject, argv, argc);
}
diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp
index c519429d48..1b7a433a84 100644
--- a/src/qml/qml/qqmlapplicationengine.cpp
+++ b/src/qml/qml/qqmlapplicationengine.cpp
@@ -250,10 +250,12 @@ QQmlApplicationEngine::~QQmlApplicationEngine()
/*!
Loads the root QML file located at \a url. The object tree defined by the file
is created immediately for local file urls. Remote urls are loaded asynchronously,
- listen to the objectCreated signal to determine when the object
- tree is ready.
+ listen to the \l {QQmlApplicationEngine::objectCreated()}{objectCreated} signal to
+ determine when the object tree is ready.
- If an error occurs, error messages are printed with qWarning.
+ If an error occurs, the \l {QQmlApplicationEngine::objectCreated()}{objectCreated}
+ signal is emitted with a null pointer as parameter and error messages are printed
+ with qWarning.
*/
void QQmlApplicationEngine::load(const QUrl &url)
{
diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp
index 53e3f65553..572f58339f 100644
--- a/src/qml/types/qqmldelegatemodel.cpp
+++ b/src/qml/types/qqmldelegatemodel.cpp
@@ -353,6 +353,7 @@ void QQmlDelegateModel::componentComplete()
\l{QtQuick.XmlListModel::XmlListModel}{XmlListModel}.
\sa {qml-data-models}{Data Models}
+ \keyword dm-model-property
*/
QVariant QQmlDelegateModel::model() const
{
@@ -493,11 +494,10 @@ void QQmlDelegateModel::setDelegate(QQmlComponent *delegate)
\c view.qml:
\snippet delegatemodel/delegatemodel_rootindex/view.qml 0
- If the \l model is a QAbstractItemModel subclass, the delegate can also
- reference a \c hasModelChildren property (optionally qualified by a
- \e model. prefix) that indicates whether the delegate's model item has
- any child nodes.
-
+ If the \l {dm-model-property}{model} is a QAbstractItemModel subclass,
+ the delegate can also reference a \c hasModelChildren property (optionally
+ qualified by a \e model. prefix) that indicates whether the delegate's
+ model item has any child nodes.
\sa modelIndex(), parentModelIndex()
*/
@@ -699,6 +699,7 @@ QQmlDelegateModelGroup *QQmlDelegateModelPrivate::group_at(
The following example illustrates using groups to select items in a model.
\snippet delegatemodel/delegatemodelgroup.qml 0
+ \keyword dm-groups-property
*/
QQmlListProperty<QQmlDelegateModelGroup> QQmlDelegateModel::groups()
@@ -2274,7 +2275,7 @@ void QQmlDelegateModelAttached::resetCurrentIndex()
}
/*!
- \qmlattachedproperty int QtQml.Models::DelegateModel::model
+ \qmlattachedproperty model QtQml.Models::DelegateModel::model
This attached property holds the data model this delegate instance belongs to.
@@ -2482,7 +2483,8 @@ void QQmlDelegateModelGroupPrivate::destroyingPackage(QQuickPackage *package)
information about group membership and indexes as well as model data. In combination
with the move() function this can be used to implement view sorting, with remove() to filter
items out of a view, or with setGroups() and \l Package delegates to categorize items into
- different views.
+ different views. Different groups can only be sorted independently if they are disjunct. Moving
+ an item in one group will also move it in all other groups it is a part of.
Data from models can be supplemented by inserting data directly into a DelegateModelGroup
with the insert() function. This can be used to introduce mock items into a view, or
@@ -3094,6 +3096,11 @@ void QQmlDelegateModelGroup::setGroups(QQmlV4Function *args)
\qmlmethod QtQml.Models::DelegateModelGroup::move(var from, var to, int count)
Moves \a count at \a from in a group \a to a new position.
+
+ \note The DelegateModel acts as a proxy model: it holds the delegates in a
+ different order than the \l{dm-model-property}{underlying model} has them.
+ Any subsequent changes to the underlying model will not undo whatever
+ reordering you have done via this function.
*/
void QQmlDelegateModelGroup::move(QQmlV4Function *args)