diff options
Diffstat (limited to 'src')
18 files changed, 129 insertions, 77 deletions
diff --git a/src/imports/layouts/qquickstacklayout.cpp b/src/imports/layouts/qquickstacklayout.cpp index 116e162aa9..4c1d611409 100644 --- a/src/imports/layouts/qquickstacklayout.cpp +++ b/src/imports/layouts/qquickstacklayout.cpp @@ -94,7 +94,7 @@ \sa ColumnLayout \sa GridLayout \sa RowLayout - \sa StackView + \sa {QtQuick.Controls::StackView}{StackView} */ QT_BEGIN_NAMESPACE diff --git a/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp index 1736a2098e..a5231e15d1 100644 --- a/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp +++ b/src/plugins/scenegraph/openvg/qsgopenvgcontext.cpp @@ -76,6 +76,7 @@ void QSGOpenVGRenderContext::initialize(const QSGRenderContext::InitParams *para m_vgContext = vgparams->context; QSGRenderContext::initialize(params); + emit initialized(); } void QSGOpenVGRenderContext::invalidate() @@ -84,6 +85,7 @@ void QSGOpenVGRenderContext::invalidate() delete m_glyphCacheManager; m_glyphCacheManager = nullptr; QSGRenderContext::invalidate(); + emit invalidated(); } void QSGOpenVGRenderContext::renderNextFrame(QSGRenderer *renderer, uint fboId) diff --git a/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp b/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp index d728686248..2c71c1610a 100644 --- a/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp +++ b/src/plugins/scenegraph/openvg/qsgopenvginternalrectanglenode.cpp @@ -211,21 +211,14 @@ void QSGOpenVGInternalRectangleNode::render() } else { vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); vgLoadIdentity(); - if (m_radius > 0) { - // Fallback to rendering to an image for rounded rects with perspective transforms - if (m_offscreenSurface == nullptr || m_offscreenSurface->size() != QSize(std::ceil(m_rect.width()), std::ceil(m_rect.height()))) { - delete m_offscreenSurface; - m_offscreenSurface = new QOpenVGOffscreenSurface(QSize(std::ceil(m_rect.width()), std::ceil(m_rect.height()))); - } - - m_offscreenSurface->makeCurrent(); - } else if (m_offscreenSurface) { + // Fallback to rendering to an image for rounded rects with perspective transforms + if (m_offscreenSurface == nullptr || m_offscreenSurface->size() != QSize(std::ceil(m_rect.width()), std::ceil(m_rect.height()))) { delete m_offscreenSurface; - m_offscreenSurface = nullptr; + m_offscreenSurface = new QOpenVGOffscreenSurface(QSize(std::ceil(m_rect.width()), std::ceil(m_rect.height()))); } + m_offscreenSurface->makeCurrent(); } - // If path is dirty if (m_pathDirty) { vgClearPath(m_rectanglePath, VG_PATH_CAPABILITY_APPEND_TO); @@ -291,7 +284,7 @@ void QSGOpenVGInternalRectangleNode::render() vgDrawPath(m_rectanglePath, VG_FILL_PATH); } - if (!transform().isAffine() && m_radius > 0) { + if (!transform().isAffine()) { m_offscreenSurface->doneCurrent(); // Render offscreen surface vgSeti(VG_MATRIX_MODE, VG_MATRIX_IMAGE_USER_TO_SURFACE); diff --git a/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp index 69b10fcdee..85651ece9d 100644 --- a/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp +++ b/src/plugins/scenegraph/openvg/qsgopenvgrenderloop.cpp @@ -187,6 +187,7 @@ void QSGOpenVGRenderLoop::renderWindow(QQuickWindow *window) data.updatePending = false; if (!data.grabOnly) { + cd->flushFrameSynchronousEvents(); // Event delivery/processing triggered the window to be deleted or stop rendering. if (!m_windows.contains(window)) return; diff --git a/src/plugins/scenegraph/openvg/qsgopenvgspritenode.cpp b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.cpp index fb24df7471..1b75d450aa 100644 --- a/src/plugins/scenegraph/openvg/qsgopenvgspritenode.cpp +++ b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.cpp @@ -52,7 +52,7 @@ QSGOpenVGSpriteNode::QSGOpenVGSpriteNode() QSGOpenVGSpriteNode::~QSGOpenVGSpriteNode() { - + delete m_texture; } void QSGOpenVGSpriteNode::setTexture(QSGTexture *texture) diff --git a/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h index d47b389a0b..dba4e663be 100644 --- a/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h +++ b/src/plugins/scenegraph/openvg/qsgopenvgspritenode.h @@ -66,7 +66,7 @@ public: void render() override; private: - QSGOpenVGTexture *m_texture; + QSGOpenVGTexture *m_texture = nullptr; float m_time; QPoint m_sourceA; QPoint m_sourceB; diff --git a/src/qml/doc/src/javascript/imports.qdoc b/src/qml/doc/src/javascript/imports.qdoc index 974f2e154f..8e26c4aadd 100644 --- a/src/qml/doc/src/javascript/imports.qdoc +++ b/src/qml/doc/src/javascript/imports.qdoc @@ -144,14 +144,17 @@ A JavaScript resource may import a QML module in the following fashion: .import TypeNamespace MajorVersion.MinorVersion as Qualifier \endcode -For example: +Below you can see an example that also shows how to use the QML types from a +module imported in javascript: + \code .import Qt.test 1.0 as JsQtTest + +var importedEnumValue = JsQtTest.MyQmlObject.EnumValue3 \endcode In particular, this may be useful in order to access functionality provided via a singleton type; see qmlRegisterSingletonType() for more information. \note The .import syntax doesn't work for scripts used in the \l {WorkerScript} - */ diff --git a/src/qml/jsruntime/qv4dateobject.cpp b/src/qml/jsruntime/qv4dateobject.cpp index 520b715189..cc89947cec 100644 --- a/src/qml/jsruntime/qv4dateobject.cpp +++ b/src/qml/jsruntime/qv4dateobject.cpp @@ -294,13 +294,28 @@ static double MakeDay(double year, double month, double day) if (month < 0) month += 12.0; - double d = DayFromYear(year); - bool leap = InLeapYear(d*msPerDay); + /* Quoting the spec: - d += DayFromMonth(month, leap); - d += day - 1; + Find a value t such that YearFromTime(t) is ym and MonthFromTime(t) is mn + and DateFromTime(t) is 1; but if this is not possible (because some + argument is out of range), return NaN. + */ + double first = DayFromYear(year); + /* Beware floating-point glitches: don't test the first millisecond of a + * year, month or day when we could test a moment firmly in the interior of + * the interval. A rounding glitch might give the first millisecond to the + * preceding interval. + */ + bool leap = InLeapYear((first + 60) * msPerDay); - return d; + first += DayFromMonth(month, leap); + const double t = first * msPerDay + msPerDay / 2; // Noon on the first of the month + Q_ASSERT(Day(t) == first); + if (YearFromTime(t) != year || MonthFromTime(t) != month || DateFromTime(t) != 1) { + qWarning("Apparently out-of-range date %.0f-%02.0f-%02.0f", year, month, day); + return qt_qnan(); + } + return first + day - 1; } static inline double MakeDate(double day, double time) diff --git a/src/qmlmodels/qqmllistmodel.cpp b/src/qmlmodels/qqmllistmodel.cpp index d68815cbc1..e0a66e7170 100644 --- a/src/qmlmodels/qqmllistmodel.cpp +++ b/src/qmlmodels/qqmllistmodel.cpp @@ -634,7 +634,7 @@ void ListModel::set(int elementIndex, QV4::Object *object, QVector<int> *roles) mo->updateValues(*roles); } -void ListModel::set(int elementIndex, QV4::Object *object) +void ListModel::set(int elementIndex, QV4::Object *object, ListModel::SetElement reason) { if (!object) return; @@ -684,7 +684,7 @@ void ListModel::set(int elementIndex, QV4::Object *object) } else if (QV4::DateObject *date = propertyValue->as<QV4::DateObject>()) { const ListLayout::Role &r = m_layout->getRoleOrCreate(propertyName, ListLayout::Role::DateTime); if (r.type == ListLayout::Role::DateTime) { - QDateTime dt = date->toQDateTime();; + QDateTime dt = date->toQDateTime(); e->setDateTimePropertyFast(r, dt); } } else if (QV4::Object *o = propertyValue->as<QV4::Object>()) { @@ -699,9 +699,16 @@ void ListModel::set(int elementIndex, QV4::Object *object) e->setVariantMapFast(role, o); } } else if (propertyValue->isNullOrUndefined()) { - const ListLayout::Role *r = m_layout->getExistingRole(propertyName); - if (r) - e->clearProperty(*r); + if (reason == SetElement::WasJustInserted) { + QQmlError err; + auto memberName = propertyName->toString(m_modelCache->engine())->toQString(); + err.setDescription(QString::fromLatin1("%1 is %2. Adding an object with a %2 member does not create a role for it.").arg(memberName, propertyValue->isNull() ? QLatin1String("null") : QLatin1String("undefined"))); + qmlWarning(nullptr, err); + } else { + const ListLayout::Role *r = m_layout->getExistingRole(propertyName); + if (r) + e->clearProperty(*r); + } } } } @@ -725,13 +732,13 @@ QVector<std::function<void()>> ListModel::remove(int index, int count) void ListModel::insert(int elementIndex, QV4::Object *object) { insertElement(elementIndex); - set(elementIndex, object); + set(elementIndex, object, SetElement::WasJustInserted); } int ListModel::append(QV4::Object *object) { int elementIndex = appendElement(); - set(elementIndex, object); + set(elementIndex, object, SetElement::WasJustInserted); return elementIndex; } diff --git a/src/qmlmodels/qqmllistmodel_p_p.h b/src/qmlmodels/qqmllistmodel_p_p.h index a0d0e9ad89..2ad5158050 100644 --- a/src/qmlmodels/qqmllistmodel_p_p.h +++ b/src/qmlmodels/qqmllistmodel_p_p.h @@ -381,8 +381,10 @@ public: return elements.count(); } + enum class SetElement {WasJustInserted, IsCurrentlyUpdated}; + void set(int elementIndex, QV4::Object *object, QVector<int> *roles); - void set(int elementIndex, QV4::Object *object); + void set(int elementIndex, QV4::Object *object, SetElement reason = SetElement::IsCurrentlyUpdated); int append(QV4::Object *object); void insert(int elementIndex, QV4::Object *object); diff --git a/src/qmltest/quicktestutil.cpp b/src/qmltest/quicktestutil.cpp index 682c56400e..d9e6a2fba5 100644 --- a/src/qmltest/quicktestutil.cpp +++ b/src/qmltest/quicktestutil.cpp @@ -63,7 +63,7 @@ int QuickTestUtil::dragThreshold() const QJSValue QuickTestUtil::typeName(const QVariant &v) const { - QString name(v.typeName()); + QString name = QString::fromUtf8(v.typeName()); if (v.canConvert<QObject*>()) { QQmlType type; const QMetaObject *mo = v.value<QObject*>()->metaObject(); diff --git a/src/quick/doc/qtquick.qdocconf b/src/quick/doc/qtquick.qdocconf index 6a4300c1bd..91458527dd 100644 --- a/src/quick/doc/qtquick.qdocconf +++ b/src/quick/doc/qtquick.qdocconf @@ -38,7 +38,7 @@ qhp.QtQuick.subprojects.examples.selectors = fake:example tagfile = ../../../doc/qtquick/qtquick.tags -depends += qtcore qtqml qtqmltest qtgui qtlinguist qtquickcontrols1 qtquickcontrols qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects qtsql qtxmlpatterns +depends += qtcore qtqml qtqmltest qtgui qtlinguist qtquickcontrols qtquickcontrols1 qtdoc qtquickdialogs qtsensors qtwidgets qmake qtmultimedia qtgraphicaleffects qtsql qtxmlpatterns headerdirs += ..\ ../../quick \ diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp index c7e7ccea55..840cfe15da 100644 --- a/src/quick/items/qquickimage.cpp +++ b/src/quick/items/qquickimage.cpp @@ -676,13 +676,13 @@ QSGNode *QQuickImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) int xOffset = 0; if (d->hAlign == QQuickImage::AlignHCenter) - xOffset = qCeil((width() - pixWidth) / 2.); + xOffset = (width() - pixWidth) / 2; else if (d->hAlign == QQuickImage::AlignRight) xOffset = qCeil(width() - pixWidth); int yOffset = 0; if (d->vAlign == QQuickImage::AlignVCenter) - yOffset = qCeil((height() - pixHeight) / 2.); + yOffset = (height() - pixHeight) / 2; else if (d->vAlign == QQuickImage::AlignBottom) yOffset = qCeil(height() - pixHeight); diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index e1af65c986..fccd467274 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -587,6 +587,7 @@ void QQuickItemView::setHighlightRangeMode(HighlightRangeMode mode) d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd; if (isComponentComplete()) { d->updateViewport(); + d->moveReason = QQuickItemViewPrivate::Other; d->fixupPosition(); } emit highlightRangeModeChanged(); @@ -609,8 +610,10 @@ void QQuickItemView::setPreferredHighlightBegin(qreal start) d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd; if (isComponentComplete()) { d->updateViewport(); - if (!isMoving() && !isFlicking()) + if (!isMoving() && !isFlicking()) { + d->moveReason = QQuickItemViewPrivate::Other; d->fixupPosition(); + } } emit preferredHighlightBeginChanged(); } @@ -624,8 +627,10 @@ void QQuickItemView::resetPreferredHighlightBegin() d->highlightRangeStart = 0; if (isComponentComplete()) { d->updateViewport(); - if (!isMoving() && !isFlicking()) + if (!isMoving() && !isFlicking()) { + d->moveReason = QQuickItemViewPrivate::Other; d->fixupPosition(); + } } emit preferredHighlightBeginChanged(); } @@ -646,8 +651,10 @@ void QQuickItemView::setPreferredHighlightEnd(qreal end) d->haveHighlightRange = d->highlightRange != NoHighlightRange && d->highlightRangeStart <= d->highlightRangeEnd; if (isComponentComplete()) { d->updateViewport(); - if (!isMoving() && !isFlicking()) + if (!isMoving() && !isFlicking()) { + d->moveReason = QQuickItemViewPrivate::Other; d->fixupPosition(); + } } emit preferredHighlightEndChanged(); } @@ -661,8 +668,10 @@ void QQuickItemView::resetPreferredHighlightEnd() d->highlightRangeEnd = 0; if (isComponentComplete()) { d->updateViewport(); - if (!isMoving() && !isFlicking()) + if (!isMoving() && !isFlicking()) { + d->moveReason = QQuickItemViewPrivate::Other; d->fixupPosition(); + } } emit preferredHighlightEndChanged(); } diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp index addd52cb1d..9f9777f199 100644 --- a/src/quick/items/qquickrendercontrol.cpp +++ b/src/quick/items/qquickrendercontrol.cpp @@ -275,6 +275,7 @@ void QQuickRenderControl::polishItems() if (!d->window) return; cd->polishItems(); + emit d->window->afterAnimating(); } /*! diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp index 31d1c91649..07767d377d 100644 --- a/src/quick/items/qquickstateoperations.cpp +++ b/src/quick/items/qquickstateoperations.cpp @@ -44,6 +44,7 @@ #include <QtQml/qqmlinfo.h> #include <QtCore/qmath.h> +#include <memory> QT_BEGIN_NAMESPACE @@ -51,15 +52,17 @@ class QQuickParentChangePrivate : public QQuickStateOperationPrivate { Q_DECLARE_PUBLIC(QQuickParentChange) public: - QQuickParentChangePrivate() : target(nullptr), parent(nullptr), origParent(nullptr), origStackBefore(nullptr), - rewindParent(nullptr), rewindStackBefore(nullptr) {} - - QQuickItem *target; + QQuickItem *target = nullptr; QPointer<QQuickItem> parent; - QPointer<QQuickItem> origParent; - QPointer<QQuickItem> origStackBefore; - QQuickItem *rewindParent; - QQuickItem *rewindStackBefore; + + struct StateSnapshot { + QPointer<QQuickItem> parent; + QPointer<QQuickItem> stackBefore; + qreal x = 0, y = 0, width = 0, height = 0, scale = 0, rotation = 0; + }; + + std::unique_ptr<StateSnapshot> orig; + std::unique_ptr<StateSnapshot> rewind; QQmlNullableValue<QQmlScriptString> xString; QQmlNullableValue<QQmlScriptString> yString; @@ -68,10 +71,11 @@ public: QQmlNullableValue<QQmlScriptString> scaleString; QQmlNullableValue<QQmlScriptString> rotationString; - void doChange(QQuickItem *targetParent, QQuickItem *stackBefore = nullptr); + void doChange(QQuickItem *targetParent); + void reverseRewindHelper(const std::unique_ptr<StateSnapshot> &snapshot); }; -void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *stackBefore) +void QQuickParentChangePrivate::doChange(QQuickItem *targetParent) { if (targetParent && target && target->parentItem()) { Q_Q(QQuickParentChange); @@ -137,11 +141,6 @@ void QQuickParentChangePrivate::doChange(QQuickItem *targetParent, QQuickItem *s } else if (target) { target->setParentItem(targetParent); } - - //restore the original stack position. - //### if stackBefore has also been reparented this won't work - if (target && stackBefore) - target->stackBefore(stackBefore); } /*! @@ -305,7 +304,7 @@ bool QQuickParentChange::rotationIsSet() const QQuickItem *QQuickParentChange::originalParent() const { Q_D(const QQuickParentChange); - return d->origParent; + return d->orig ? d->orig->parent : nullptr; } /*! @@ -473,21 +472,11 @@ void QQuickParentChange::saveOriginals() { Q_D(QQuickParentChange); saveCurrentValues(); - d->origParent = d->rewindParent; - d->origStackBefore = d->rewindStackBefore; + if (!d->orig) + d->orig.reset(new QQuickParentChangePrivate::StateSnapshot); + *d->orig = *d->rewind; } -/*void QQuickParentChange::copyOriginals(QQuickStateActionEvent *other) -{ - Q_D(QQuickParentChange); - QQuickParentChange *pc = static_cast<QQuickParentChange*>(other); - - d->origParent = pc->d_func()->rewindParent; - d->origStackBefore = pc->d_func()->rewindStackBefore; - - saveCurrentValues(); -}*/ - void QQuickParentChange::execute() { Q_D(QQuickParentChange); @@ -499,10 +488,26 @@ bool QQuickParentChange::isReversable() return true; } +void QQuickParentChangePrivate::reverseRewindHelper(const std::unique_ptr<QQuickParentChangePrivate::StateSnapshot> &snapshot) +{ + if (!target || !snapshot) + return; + target->setX(snapshot->x); + target->setY(snapshot->y); + target->setScale(snapshot->scale); + target->setWidth(snapshot->width); + target->setHeight(snapshot->height); + target->setRotation(snapshot->rotation); + target->setParentItem(snapshot->parent); + if (snapshot->stackBefore) + target->stackBefore(snapshot->stackBefore); +} + + void QQuickParentChange::reverse() { Q_D(QQuickParentChange); - d->doChange(d->origParent, d->origStackBefore); + d->reverseRewindHelper(d->orig); } QQuickStateActionEvent::EventType QQuickParentChange::type() const @@ -524,21 +529,28 @@ void QQuickParentChange::saveCurrentValues() { Q_D(QQuickParentChange); if (!d->target) { - d->rewindParent = nullptr; - d->rewindStackBefore = nullptr; + d->rewind = nullptr; return; } - d->rewindParent = d->target->parentItem(); - d->rewindStackBefore = nullptr; + d->rewind.reset(new QQuickParentChangePrivate::StateSnapshot); + d->rewind->x = d->target->x(); + d->rewind->y = d->target->y(); + d->rewind->scale = d->target->scale(); + d->rewind->width = d->target->width(); + d->rewind->height = d->target->height(); + d->rewind->rotation = d->target->rotation(); + + d->rewind->parent = d->target->parentItem(); + d->rewind->stackBefore = nullptr; - if (!d->rewindParent) + if (!d->rewind->parent) return; - QList<QQuickItem *> children = d->rewindParent->childItems(); + QList<QQuickItem *> children = d->rewind->parent->childItems(); for (int ii = 0; ii < children.count() - 1; ++ii) { if (children.at(ii) == d->target) { - d->rewindStackBefore = children.at(ii + 1); + d->rewind->stackBefore = children.at(ii + 1); break; } } @@ -547,7 +559,8 @@ void QQuickParentChange::saveCurrentValues() void QQuickParentChange::rewind() { Q_D(QQuickParentChange); - d->doChange(d->rewindParent, d->rewindStackBefore); + d->reverseRewindHelper(d->rewind); + d->rewind.reset(); } /*! diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode.cpp index d4e5e98d68..17e8bdc2f9 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode.cpp @@ -49,6 +49,11 @@ QSGSoftwareSpriteNode::QSGSoftwareSpriteNode() setGeometry((QSGGeometry*)1); } +QSGSoftwareSpriteNode::~QSGSoftwareSpriteNode() +{ + delete m_texture; +} + void QSGSoftwareSpriteNode::setTexture(QSGTexture *texture) { m_texture = qobject_cast<QSGSoftwarePixmapTexture*>(texture); diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode_p.h b/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode_p.h index 577a30c051..4015537395 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode_p.h +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarespritenode_p.h @@ -64,6 +64,7 @@ class QSGSoftwareSpriteNode : public QSGSpriteNode { public: QSGSoftwareSpriteNode(); + ~QSGSoftwareSpriteNode() override; void setTexture(QSGTexture *texture) override; void setTime(float time) override; @@ -81,7 +82,7 @@ public: private: - QSGSoftwarePixmapTexture *m_texture; + QSGSoftwarePixmapTexture *m_texture = nullptr; float m_time; QPoint m_sourceA; QPoint m_sourceB; |