diff options
author | Liang Qi <liang.qi@qt.io> | 2019-10-10 13:59:00 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2019-10-10 16:18:19 +0200 |
commit | 45f95e74297ab3778965319c175a6d726f9c8afe (patch) | |
tree | 24a9b79eeaf62ffb6a5936cb0ef2673d426df1ec | |
parent | 6fceeab1d15e1d6c1fa3d8e067f2acdeccb78e64 (diff) | |
parent | aa057451b35953018c4f94d0a4bd5e813767cbc9 (diff) |
Merge "Merge remote-tracking branch 'origin/5.13' into 5.14"
30 files changed, 363 insertions, 31 deletions
diff --git a/examples/quick/views/doc/src/views.qdoc b/examples/quick/views/doc/src/views.qdoc index 294b88542b..16237a68e0 100644 --- a/examples/quick/views/doc/src/views.qdoc +++ b/examples/quick/views/doc/src/views.qdoc @@ -87,7 +87,7 @@ \section1 Packages - \e Packages uses the \l Package type to transition delegates between + \e Packages use the \l [QML]{Package} type to transition delegates between two views. It has a Package object which defines delegate items for each view and an 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/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/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; diff --git a/tests/auto/qml/qqmlecmascript/data/checkDate-October.qml b/tests/auto/qml/qqmlecmascript/data/checkDate-October.qml new file mode 100644 index 0000000000..6686831e1c --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/checkDate-October.qml @@ -0,0 +1,12 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +MyTypeObject { + Component.onCompleted: { + // QTBUG-78996 + dateProperty = new Date(2019, 9, 3) + boolProperty = (dateProperty.getFullYear() == 2019 + && dateProperty.getMonth() == 9 + && dateProperty.getDate() == 3) + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-Feb.qml b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-Feb.qml new file mode 100644 index 0000000000..29ec40ffbd --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-Feb.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +MyTypeObject { + Component.onCompleted: { + dateProperty = new Date(2019, 2, 0) // Feb 28th + boolProperty = (dateProperty.getFullYear() == 2019 + && dateProperty.getMonth() == 1 + && dateProperty.getDate() == 28) + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-March.qml b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-March.qml new file mode 100644 index 0000000000..7fc8bf43bd --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-March.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +MyTypeObject { + Component.onCompleted: { + dateProperty = new Date(2019, 1, 29) // March 1st + boolProperty = (dateProperty.getFullYear() == 2019 + && dateProperty.getMonth() == 2 + && dateProperty.getDate() == 1) + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-leap.qml b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-leap.qml new file mode 100644 index 0000000000..6dd84810e6 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-leap.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +MyTypeObject { + Component.onCompleted: { + dateProperty = new Date(2020, 2, 0) // Feb 29th + boolProperty = (dateProperty.getFullYear() == 2020 + && dateProperty.getMonth() == 1 + && dateProperty.getDate() == 29) + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-wrap.qml b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-wrap.qml new file mode 100644 index 0000000000..ddb79727ef --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-wrap.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +MyTypeObject { + Component.onCompleted: { + dateProperty = new Date(2017, 40, -61) // 2020, Feb 29th + boolProperty = (dateProperty.getFullYear() == 2020 + && dateProperty.getMonth() == 1 + && dateProperty.getDate() == 29) + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-year.qml b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-year.qml new file mode 100644 index 0000000000..90514c39c8 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/checkDate-denormal-year.qml @@ -0,0 +1,11 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +MyTypeObject { + Component.onCompleted: { + dateProperty = new Date(2019, 12, 0) // Dec 31 + boolProperty = (dateProperty.getFullYear() == 2019 + && dateProperty.getMonth() == 11 + && dateProperty.getDate() == 31) + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/checkDateTime-October.qml b/tests/auto/qml/qqmlecmascript/data/checkDateTime-October.qml new file mode 100644 index 0000000000..c97076f887 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/checkDateTime-October.qml @@ -0,0 +1,16 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +MyTypeObject { + Component.onCompleted: { + // QTBUG-78996 + dateTimeProperty = new Date(2019, 9, 3, 12) + boolProperty = (dateTimeProperty.getFullYear() == 2019 + && dateTimeProperty.getMonth() == 9 + && dateTimeProperty.getDate() == 3 + && dateTimeProperty.getHours() == 12 + && dateTimeProperty.getMinutes() == 0 + && dateTimeProperty.getSeconds() == 0 + && dateTimeProperty.getMilliseconds() == 0) + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-March.qml b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-March.qml new file mode 100644 index 0000000000..2b6b9af3e1 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-March.qml @@ -0,0 +1,15 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +MyTypeObject { + Component.onCompleted: { + dateTimeProperty = new Date(2019, 1, 28, 23, 59, 59, 1001) // 2019-3-1 0:0:0.001 + boolProperty = (dateTimeProperty.getFullYear() == 2019 + && dateTimeProperty.getMonth() == 2 + && dateTimeProperty.getDate() == 1 + && dateTimeProperty.getHours() == 0 + && dateTimeProperty.getMinutes() == 0 + && dateTimeProperty.getSeconds() == 0 + && dateTimeProperty.getMilliseconds() == 1) + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-hours.qml b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-hours.qml new file mode 100644 index 0000000000..7d018e2904 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-hours.qml @@ -0,0 +1,15 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +MyTypeObject { + Component.onCompleted: { + dateTimeProperty = new Date(2019, 11, 31, 1440) // 2020-2-29 0:0:0 + boolProperty = (dateTimeProperty.getFullYear() == 2020 + && dateTimeProperty.getMonth() == 1 + && dateTimeProperty.getDate() == 29 + && dateTimeProperty.getHours() == 0 + && dateTimeProperty.getMinutes() == 0 + && dateTimeProperty.getSeconds() == 0 + && dateTimeProperty.getMilliseconds() == 0) + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-leap.qml b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-leap.qml new file mode 100644 index 0000000000..0a7687c669 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-leap.qml @@ -0,0 +1,15 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +MyTypeObject { + Component.onCompleted: { + dateTimeProperty = new Date(2020, 2, 1, 0, 0, 0, -1) // 2020-2-29 23:59:59.999 + boolProperty = (dateTimeProperty.getFullYear() == 2020 + && dateTimeProperty.getMonth() == 1 + && dateTimeProperty.getDate() == 29 + && dateTimeProperty.getHours() == 23 + && dateTimeProperty.getMinutes() == 59 + && dateTimeProperty.getSeconds() == 59 + && dateTimeProperty.getMilliseconds() == 999) + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-minutes.qml b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-minutes.qml new file mode 100644 index 0000000000..738d603b4b --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-minutes.qml @@ -0,0 +1,15 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +MyTypeObject { + Component.onCompleted: { + dateTimeProperty = new Date(2020, 1, 28, 0, 1440) // 2020-2-29 0:0:0 + boolProperty = (dateTimeProperty.getFullYear() == 2020 + && dateTimeProperty.getMonth() == 1 + && dateTimeProperty.getDate() == 29 + && dateTimeProperty.getHours() == 0 + && dateTimeProperty.getMinutes() == 0 + && dateTimeProperty.getSeconds() == 0 + && dateTimeProperty.getMilliseconds() == 0) + } +} diff --git a/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-seconds.qml b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-seconds.qml new file mode 100644 index 0000000000..d48534f0d0 --- /dev/null +++ b/tests/auto/qml/qqmlecmascript/data/checkDateTime-denormal-seconds.qml @@ -0,0 +1,15 @@ +import Qt.test 1.0 +import QtQuick 2.0 + +MyTypeObject { + Component.onCompleted: { + dateTimeProperty = new Date(2020, 1, 28, 23, 0, 3600) // 2020-2-29 0:0:0 + boolProperty = (dateTimeProperty.getFullYear() == 2020 + && dateTimeProperty.getMonth() == 1 + && dateTimeProperty.getDate() == 29 + && dateTimeProperty.getHours() == 0 + && dateTimeProperty.getMinutes() == 0 + && dateTimeProperty.getSeconds() == 0 + && dateTimeProperty.getMilliseconds() == 0) + } +} diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp index 05ad5e2f22..8824dfd019 100644 --- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp +++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp @@ -79,6 +79,10 @@ private slots: void assignDate(); void exportDate_data(); void exportDate(); + void checkDate_data(); + void checkDate(); + void checkDateTime_data(); + void checkDateTime(); void idShortcutInvalidates(); void boolPropertiesEvaluateAsBool(); void methods(); @@ -568,6 +572,82 @@ void tst_qqmlecmascript::exportDate() QCOMPARE(object->boolProperty(), true); } +void tst_qqmlecmascript::checkDate_data() +{ + QTest::addColumn<QUrl>("source"); + QTest::addColumn<QDate>("date"); + // NB: JavaScript month-indices are Jan = 0 to Dec = 11; QDate's are Jan = 1 to Dec = 12. + QTest::newRow("denormal-March") + << testFileUrl("checkDate-denormal-March.qml") + << QDate(2019, 3, 1); + QTest::newRow("denormal-leap") + << testFileUrl("checkDate-denormal-leap.qml") + << QDate(2020, 2, 29); + QTest::newRow("denormal-Feb") + << testFileUrl("checkDate-denormal-Feb.qml") + << QDate(2019, 2, 28); + QTest::newRow("denormal-year") + << testFileUrl("checkDate-denormal-year.qml") + << QDate(2019, 12, 31); + QTest::newRow("denormal-wrap") + << testFileUrl("checkDate-denormal-wrap.qml") + << QDate(2020, 2, 29); + QTest::newRow("October") + << testFileUrl("checkDate-October.qml") + << QDate(2019, 10, 3); +} + +void tst_qqmlecmascript::checkDate() +{ + QFETCH(const QUrl, source); + QFETCH(const QDate, date); + QQmlEngine e; + QQmlComponent component(&e, source); + QScopedPointer<QObject> obj(component.create()); + MyTypeObject *object = qobject_cast<MyTypeObject *>(obj.data()); + QVERIFY(object != nullptr); + QCOMPARE(object->dateProperty(), date); + QVERIFY(object->boolProperty()); +} + +void tst_qqmlecmascript::checkDateTime_data() +{ + QTest::addColumn<QUrl>("source"); + QTest::addColumn<QDateTime>("when"); + // NB: JavaScript month-indices are Jan = 0 to Dec = 11; QDate's are Jan = 1 to Dec = 12. + QTest::newRow("denormal-March") + << testFileUrl("checkDateTime-denormal-March.qml") + << QDateTime(QDate(2019, 3, 1), QTime(0, 0, 0, 1), Qt::LocalTime); + QTest::newRow("denormal-leap") + << testFileUrl("checkDateTime-denormal-leap.qml") + << QDateTime(QDate(2020, 2, 29), QTime(23, 59, 59, 999), Qt::LocalTime); + QTest::newRow("denormal-hours") + << testFileUrl("checkDateTime-denormal-hours.qml") + << QDateTime(QDate(2020, 2, 29), QTime(0, 0), Qt::LocalTime); + QTest::newRow("denormal-minutes") + << testFileUrl("checkDateTime-denormal-minutes.qml") + << QDateTime(QDate(2020, 2, 29), QTime(0, 0), Qt::LocalTime); + QTest::newRow("denormal-seconds") + << testFileUrl("checkDateTime-denormal-seconds.qml") + << QDateTime(QDate(2020, 2, 29), QTime(0, 0), Qt::LocalTime); + QTest::newRow("October") + << testFileUrl("checkDateTime-October.qml") + << QDateTime(QDate(2019, 10, 3), QTime(12, 0), Qt::LocalTime); +} + +void tst_qqmlecmascript::checkDateTime() +{ + QFETCH(const QUrl, source); + QFETCH(const QDateTime, when); + QQmlEngine e; + QQmlComponent component(&e, source); + QScopedPointer<QObject> obj(component.create()); + MyTypeObject *object = qobject_cast<MyTypeObject *>(obj.data()); + QVERIFY(object != nullptr); + QCOMPARE(object->dateTimeProperty(), when); + QVERIFY(object->boolProperty()); +} + void tst_qqmlecmascript::idShortcutInvalidates() { QQmlEngine engine; diff --git a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp index 08149a1786..ca438a9cd5 100644 --- a/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp +++ b/tests/auto/quick/qquicklistview/tst_qquicklistview.cpp @@ -1943,6 +1943,31 @@ void tst_QQuickListView::enforceRange() QTRY_COMPARE(listview->currentIndex(), 6); + // Test for [QTBUG-77418] { + // explicit set current index + listview->setCurrentIndex(5); + QTRY_COMPARE(listview->contentY(), 0); + + // then check if contentY changes if the highlight range is changed + listview->setPreferredHighlightBegin(80); + listview->setPreferredHighlightEnd(80); + QTRY_COMPARE(listview->contentY(), 20); + + // verify that current index does not change with no highlight + listview->setHighlightRangeMode(QQuickListView::NoHighlightRange); + listview->setContentY(100); + QTRY_COMPARE(listview->currentIndex(), 5); + + // explicit set current index, contentY should not change now + listview->setCurrentIndex(6); + QTRY_COMPARE(listview->contentY(), 100); + QTest::qWait(50); // This was needed in order to reproduce a failure for the following test + + // verify that contentY changes if we turn on highlight again + listview->setHighlightRangeMode(QQuickListView::StrictlyEnforceRange); + QTRY_COMPARE(listview->contentY(), 40); + // } Test for [QTBUG-77418] + // change model QaimModel model2; for (int i = 0; i < 5; i++) diff --git a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp index 8a1ab40475..4498548d45 100644 --- a/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp +++ b/tests/auto/quick/qquickpathview/tst_qquickpathview.cpp @@ -1614,16 +1614,55 @@ void tst_QQuickPathView::flickNClick() // QTBUG-77173 QQuickPathView *pathview = qobject_cast<QQuickPathView*>(window->rootObject()); QVERIFY(pathview != nullptr); + QSignalSpy movingChangedSpy(pathview, SIGNAL(movingChanged())); + QSignalSpy draggingSpy(pathview, SIGNAL(draggingChanged())); + QSignalSpy dragStartedSpy(pathview, SIGNAL(dragStarted())); + QSignalSpy dragEndedSpy(pathview, SIGNAL(dragEnded())); + QSignalSpy currentIndexSpy(pathview, SIGNAL(currentIndexChanged())); + QSignalSpy moveStartedSpy(pathview, SIGNAL(movementStarted())); + QSignalSpy moveEndedSpy(pathview, SIGNAL(movementEnded())); + QSignalSpy flickingSpy(pathview, SIGNAL(flickingChanged())); + QSignalSpy flickStartedSpy(pathview, SIGNAL(flickStarted())); + QSignalSpy flickEndedSpy(pathview, SIGNAL(flickEnded())); for (int duration = 100; duration > 0; duration -= 20) { + movingChangedSpy.clear(); + draggingSpy.clear(); + dragStartedSpy.clear(); + dragEndedSpy.clear(); + currentIndexSpy.clear(); + moveStartedSpy.clear(); + moveEndedSpy.clear(); + flickingSpy.clear(); + flickStartedSpy.clear(); + flickEndedSpy.clear(); // Dragging the child mouse area should animate the PathView (MA has no drag target) flick(window.data(), QPoint(200,200), QPoint(400,200), duration); QVERIFY(pathview->isMoving()); + QCOMPARE(movingChangedSpy.count(), 1); + QCOMPARE(draggingSpy.count(), 2); + QCOMPARE(dragStartedSpy.count(), 1); + QCOMPARE(dragEndedSpy.count(), 1); + QVERIFY(currentIndexSpy.count() > 0); + QCOMPARE(moveStartedSpy.count(), 1); + QCOMPARE(moveEndedSpy.count(), 0); + QCOMPARE(flickingSpy.count(), 1); + QCOMPARE(flickStartedSpy.count(), 1); + QCOMPARE(flickEndedSpy.count(), 0); // Now while it's still moving, click it. // The PathView should stop at a position such that offset is a whole number. QTest::mouseClick(window.data(), Qt::LeftButton, Qt::NoModifier, QPoint(200, 200)); QTRY_VERIFY(!pathview->isMoving()); + QCOMPARE(movingChangedSpy.count(), 2); // QTBUG-78926 + QCOMPARE(draggingSpy.count(), 2); + QCOMPARE(dragStartedSpy.count(), 1); + QCOMPARE(dragEndedSpy.count(), 1); + QCOMPARE(moveStartedSpy.count(), 1); + QCOMPARE(moveEndedSpy.count(), 1); + QCOMPARE(flickingSpy.count(), 2); + QCOMPARE(flickStartedSpy.count(), 1); + QCOMPARE(flickEndedSpy.count(), 1); QVERIFY(qFuzzyIsNull(pathview->offset() - int(pathview->offset()))); } } |