Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package qt6-quicktimeline for openSUSE:Factory checked in at 2025-06-05 20:32:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/qt6-quicktimeline (Old) and /work/SRC/openSUSE:Factory/.qt6-quicktimeline.new.19631 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "qt6-quicktimeline" Thu Jun 5 20:32:22 2025 rev:37 rq:1282574 version:6.9.1 Changes: -------- --- /work/SRC/openSUSE:Factory/qt6-quicktimeline/qt6-quicktimeline.changes 2025-04-07 17:35:38.030355839 +0200 +++ /work/SRC/openSUSE:Factory/.qt6-quicktimeline.new.19631/qt6-quicktimeline.changes 2025-06-05 20:32:46.317383378 +0200 @@ -1,0 +2,6 @@ +Tue Jun 3 07:49:31 UTC 2025 - Christophe Marin <christo...@krop.fr> + +- Update to 6.9.1: + * https://www.qt.io/blog/qt-6.9.1-released + +------------------------------------------------------------------- Old: ---- qtquicktimeline-everywhere-src-6.9.0.tar.xz New: ---- qtquicktimeline-everywhere-src-6.9.1.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ qt6-quicktimeline.spec ++++++ --- /var/tmp/diff_new_pack.sU5Qxq/_old 2025-06-05 20:32:48.069456229 +0200 +++ /var/tmp/diff_new_pack.sU5Qxq/_new 2025-06-05 20:32:48.081456729 +0200 @@ -16,7 +16,7 @@ # -%define real_version 6.9.0 +%define real_version 6.9.1 %define short_version 6.9 %define tar_name qtquicktimeline-everywhere-src %define tar_suffix %{nil} @@ -27,7 +27,7 @@ %endif # Name: qt6-quicktimeline%{?pkg_suffix} -Version: 6.9.0 +Version: 6.9.1 Release: 0 Summary: Qt 6 module for creating keyframe-based animations License: GPL-3.0-only ++++++ qtquicktimeline-everywhere-src-6.9.0.tar.xz -> qtquicktimeline-everywhere-src-6.9.1.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtquicktimeline-everywhere-src-6.9.0/.cmake.conf new/qtquicktimeline-everywhere-src-6.9.1/.cmake.conf --- old/qtquicktimeline-everywhere-src-6.9.0/.cmake.conf 2025-03-29 00:18:58.000000000 +0100 +++ new/qtquicktimeline-everywhere-src-6.9.1/.cmake.conf 2025-05-29 02:19:44.000000000 +0200 @@ -1,4 +1,4 @@ -set(QT_REPO_MODULE_VERSION "6.9.0") +set(QT_REPO_MODULE_VERSION "6.9.1") set(QT_REPO_MODULE_PRERELEASE_VERSION_SEGMENT "alpha1") set(QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_AS_CONST=1") list(APPEND QT_EXTRA_INTERNAL_TARGET_DEFINES "QT_NO_FOREACH=1") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtquicktimeline-everywhere-src-6.9.0/.tag new/qtquicktimeline-everywhere-src-6.9.1/.tag --- old/qtquicktimeline-everywhere-src-6.9.0/.tag 2025-03-29 00:18:58.000000000 +0100 +++ new/qtquicktimeline-everywhere-src-6.9.1/.tag 2025-05-29 02:19:44.000000000 +0200 @@ -1 +1 @@ -6c2a7848571c3ecf20b9c8c673c6e73c7a11ea29 +410381aa0b4d3f810a4c3d737c15315010ad9831 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtquicktimeline-everywhere-src-6.9.0/REUSE.toml new/qtquicktimeline-everywhere-src-6.9.1/REUSE.toml --- old/qtquicktimeline-everywhere-src-6.9.0/REUSE.toml 2025-03-29 00:18:58.000000000 +0100 +++ new/qtquicktimeline-everywhere-src-6.9.1/REUSE.toml 2025-05-29 02:19:44.000000000 +0200 @@ -7,17 +7,18 @@ SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GPL-3.0-only" [[annotations]] -path = ["**.pro", "**.qrc", ".cmake.conf", "**.yaml", "coin/axivion/ci_config_linux.json"] +path = ["**.pro", "**.qrc", ".cmake.conf", "**.yaml", "coin/axivion/ci_config_linux.json", + ".tag"] precedence = "closest" comment = "build system" SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd." SPDX-License-Identifier = "BSD-3-Clause" [[annotations]] -path = [".tag", "**/.gitattributes", "**.gitignore", "**/.gitreview"] +path = ["**/.gitattributes", "**.gitignore", "**.gitreview"] precedence = "closest" SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd." -SPDX-License-Identifier = "BSD-3-Clause" +SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause" [[annotations]] path = ["**/doc/images/**", "**.qdocconf", "src/timeline/doc/style/style.css"] @@ -30,7 +31,7 @@ path = ["**.toml", "licenseRule.json"] precedence = "override" SPDX-FileCopyrightText = "Copyright (C) 2024 The Qt Company Ltd." -SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only" +SPDX-License-Identifier = "LicenseRef-Qt-Commercial OR BSD-3-Clause" [[annotations]] path = ["**/qt_attribution.json"] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtquicktimeline-everywhere-src-6.9.0/dependencies.yaml new/qtquicktimeline-everywhere-src-6.9.1/dependencies.yaml --- old/qtquicktimeline-everywhere-src-6.9.0/dependencies.yaml 2025-03-29 00:18:58.000000000 +0100 +++ new/qtquicktimeline-everywhere-src-6.9.1/dependencies.yaml 2025-05-29 02:19:44.000000000 +0200 @@ -1,7 +1,7 @@ dependencies: ../qtbase: - ref: 25986746947798e1a22d0830d3bcb11a55fcd3ae + ref: 2ad23cd72d5f122f88ce95792a4323d639c27d25 required: true ../qtdeclarative: - ref: 47ecb4fa226253c1ac85be8130ba905f95318f36 + ref: 1e6adc3d5f1f4cbbb77b41911395782dff43cccd required: true diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtquicktimeline-everywhere-src-6.9.0/licenseRule.json new/qtquicktimeline-everywhere-src-6.9.1/licenseRule.json --- old/qtquicktimeline-everywhere-src-6.9.0/licenseRule.json 2025-03-29 00:18:58.000000000 +0100 +++ new/qtquicktimeline-everywhere-src-6.9.1/licenseRule.json 2025-05-29 02:19:44.000000000 +0200 @@ -1,6 +1,6 @@ [ { - "comment" : ["file_pattern_ending: strings matched against the end of a file name.", + "comment": ["file_pattern_ending: strings matched against the end of a file name.", "location keys: regular expression matched against the beginning of", "the file path (relative to the git submodule root).", "spdx: list of SPDX-License-Expression's allowed in the matching files.", @@ -9,88 +9,100 @@ "unless they are examples", "Files with other endings can also be build system files" ], - "file_pattern_ending" : ["CMakeLists.txt", ".cmake", ".pro", ".pri", ".prf", + "file_pattern_ending": ["CMakeLists.txt", ".cmake", ".pro", ".pri", ".prf", "configure", "configure.bat", "cmake.in", "plist.in", "CMakeLists.txt.in", - ".cmake.conf", ".gitattributes", ".gitignore", ".tag", ".yaml", "ci_config_linux.json", - "configure.json", ".qrc", ".gitreview"], - "location" : { - "" : { - "comment" : "Default", - "file type" : "build system", - "spdx" : ["BSD-3-Clause"] - }, - "(.*)(examples/|snippets/)" : { - "comment" : "Example takes precedence", - "file type" : "examples and snippets", - "spdx" : ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] + ".cmake.conf", ".tag", ".yaml", "ci_config_linux.json", + "configure.json", ".qrc"], + "location": { + "": { + "comment": "Default", + "file type": "build system", + "spdx": ["BSD-3-Clause"] + }, + "(.*)(examples/|snippets/)": { + "comment": "Example takes precedence", + "file type": "examples and snippets", + "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] } } }, { - "comments" : ["Files with the following endings are Tool licensed,", + "comments": ["Files with the following endings are infrastructure licensed"], + "file_pattern_ending": [".gitattributes", ".gitignore", ".gitmodules", ".gitreview", + "_clang-format", "licenseRule.json", "REUSE.toml"], + "location":{ + "": { + "comment": "Default", + "file type": "infrastructure", + "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] + } + } + }, + { + "comments": ["Files with the following endings are Tool licensed,", "unless they are examples.", "Files with other endings can also be tool files."], - "file_pattern_ending" : [".sh", ".py", ".pl", ".bat", ".ps1"], - "location" :{ - "" : { - "comment" : "Default", - "file type" : "tools and utils", - "spdx" : ["LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0"] - }, - "(.*)(examples/|snippets/)" : { - "comment" : "Example takes precedence", - "file type" : "examples and snippets", - "spdx" : ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] + "file_pattern_ending": [".sh", ".py", ".pl", ".bat", ".ps1"], + "location":{ + "": { + "comment": "Default", + "file type": "tools and utils", + "spdx": ["LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0"] + }, + "(.*)(examples/|snippets/)": { + "comment": "Example takes precedence", + "file type": "examples and snippets", + "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] } } }, { - "comment" : "Files with the following endings are Documentation licensed.", - "file_pattern_ending" : [".qdoc", ".qdocinc" , ".qdocconf", "README", "qt_attribution.json", - "REUSE.toml", "licenseRule.json", ".css"], - "location" :{ - "" : { - "comment" : "", - "file type" : "documentation", - "spdx" : ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"] + "comment": "Files with the following endings are Documentation licensed.", + "file_pattern_ending": [".qdoc", ".qdocinc" , ".qdocconf", "README", "qt_attribution.json", + ".css"], + "location":{ + "": { + "comment": "", + "file type": "documentation", + "spdx": ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"] } } }, { - "comment" : ["All other files", + "comment": ["All other files", "The licensing is defined only by the file location in the Qt module repository.", "NO <file_pattern_ending> key for this case!", "This needs to be the last entry of the file."], - "location" : { - "" : { - "comment" : "Default", - "file type" : "module and plugin", - "spdx" : ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] - }, - "dist/" : { - "comment" : "Default", - "file type" : "documentation", - "spdx" : ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"] - }, - "src/" : { - "comment" : "Default", - "file type" : "module and plugin", - "spdx" : ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] - }, - "tests/" : { - "comment" : "Default", - "file type" : "test", - "spdx" : ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] - }, - "(.*)(examples/|snippets/)" : { - "comment" : "Default", - "file type" : "examples and snippets", - "spdx" : ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] - }, - ".*doc/images/" : { - "comment" : "Default", - "file type" : "documentation", - "spdx" : ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"] + "location": { + "": { + "comment": "Default", + "file type": "module and plugin", + "spdx": ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] + }, + "dist/": { + "comment": "Default", + "file type": "documentation", + "spdx": ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"] + }, + "src/": { + "comment": "Default", + "file type": "module and plugin", + "spdx": ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] + }, + "tests/": { + "comment": "Default", + "file type": "test", + "spdx": ["LicenseRef-Qt-Commercial OR GPL-3.0-only"] + }, + "(.*)(examples/|snippets/)": { + "comment": "Default", + "file type": "examples and snippets", + "spdx": ["LicenseRef-Qt-Commercial OR BSD-3-Clause"] + }, + ".*doc/images/": { + "comment": "Default", + "file type": "documentation", + "spdx": ["LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only"] } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtquicktimeline-everywhere-src-6.9.0/src/timeline/doc/src/qtquicktimeline-overview.qdoc new/qtquicktimeline-everywhere-src-6.9.1/src/timeline/doc/src/qtquicktimeline-overview.qdoc --- old/qtquicktimeline-everywhere-src-6.9.0/src/timeline/doc/src/qtquicktimeline-overview.qdoc 2025-03-29 00:18:58.000000000 +0100 +++ new/qtquicktimeline-everywhere-src-6.9.1/src/timeline/doc/src/qtquicktimeline-overview.qdoc 2025-05-29 02:19:44.000000000 +0200 @@ -18,8 +18,7 @@ the color and scale properties of the item at keyframes to make it appear to move closer or farther away. - Qt Design Studio and Qt Quick Designer contain a timeline editor for - creating keyframe based animations. + \QDS contains a timeline editor for creating keyframe based animations. \image timeline-editor.png @@ -28,7 +27,7 @@ can be a useful way of organizing your UI logic. Transitions are objects you can associate with an item to define how its properties will animate when they change due to a state change. You can bind timeline animations - to states in Qt Design Studio and Qt Quick Designer. + to states in \QDS. \image timeline-settings.png */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtquicktimeline-everywhere-src-6.9.0/src/timeline/qquickkeyframe.cpp new/qtquicktimeline-everywhere-src-6.9.1/src/timeline/qquickkeyframe.cpp --- old/qtquicktimeline-everywhere-src-6.9.0/src/timeline/qquickkeyframe.cpp 2025-03-29 00:18:58.000000000 +0100 +++ new/qtquicktimeline-everywhere-src-6.9.1/src/timeline/qquickkeyframe.cpp 2025-05-29 02:19:44.000000000 +0200 @@ -4,7 +4,6 @@ #include "qquickkeyframe_p.h" #include "qquicktimeline_p.h" -#include "qquickkeyframedatautils_p.h" #include <QtCore/qdebug.h> #include <QtCore/QVariantAnimation> @@ -16,6 +15,13 @@ #include <QtQml/QQmlEngine> #include <QtCore/QFile> #include <QtCore/QCborStreamReader> +#include <QCborArray> +#include <QRect> +#include <QVector2D> +#include <QVector3D> +#include <QVector4D> +#include <QQuaternion> +#include <QColor> #include <private/qvariantanimation_p.h> #include <private/qqmlproperty_p.h> @@ -39,7 +45,8 @@ protected: void setupKeyframes(); - void loadKeyframes(bool fromBinary = false); + bool loadKeyframes(bool fromBinary = false); + void resetKeyframes(); static void append_keyframe(QQmlListProperty<QQuickKeyframe> *list, QQuickKeyframe *a); static qsizetype keyframe_count(QQmlListProperty<QQuickKeyframe> *list); @@ -62,7 +69,154 @@ }); } -void QQuickKeyframeGroupPrivate::loadKeyframes(bool fromBinary) +// time, easingType, data +static int validFrameSize(QMetaType::Type type) +{ + switch (type) { + case QMetaType::Bool: + case QMetaType::Int: + case QMetaType::Float: + case QMetaType::Double: + return 3; + case QMetaType::QVector2D: + case QMetaType::QPoint: + case QMetaType::QPointF: + case QMetaType::QSize: + case QMetaType::QSizeF: + return 4; + case QMetaType::QVector3D: + return 5; + case QMetaType::QVector4D: + case QMetaType::QQuaternion: + case QMetaType::QColor: + case QMetaType::QRect: + case QMetaType::QRectF: + return 6; + default: + qWarning() << "Keyframe property type not handled:" << type; + return -1; + } +} + +// Read property 'type' value from CborArray from index 'id' and return it as QVariant. +static QVariant qQuickKeyframeReadProperty(const QCborArray &array, qsizetype id, QMetaType::Type type) +{ + switch (type) { + case QMetaType::QVector2D: + { + QVector2D v; + v.setX(array.at(id).toDouble()); + v.setY(array.at(id + 1).toDouble()); + return QVariant(v); + } + break; + case QMetaType::QVector3D: + { + QVector3D v; + v.setX(array.at(id).toDouble()); + v.setY(array.at(id + 1).toDouble()); + v.setZ(array.at(id + 2).toDouble()); + return QVariant(v); + } + break; + case QMetaType::QVector4D: + { + QVector4D v; + v.setX(array.at(id).toDouble()); + v.setY(array.at(id + 1).toDouble()); + v.setZ(array.at(id + 2).toDouble()); + v.setW(array.at(id + 3).toDouble()); + return QVariant(v); + } + break; + case QMetaType::QQuaternion: + { + QQuaternion q; + q.setScalar(array.at(id).toDouble()); + q.setX(array.at(id + 1).toDouble()); + q.setY(array.at(id + 2).toDouble()); + q.setZ(array.at(id + 3).toDouble()); + return QVariant(q); + } + break; + case QMetaType::QColor: + { + QColor c; + c.setRed(array.at(id).toInteger()); + c.setGreen(array.at(id + 1).toInteger()); + c.setBlue(array.at(id + 2).toInteger()); + c.setAlpha(array.at(id + 3).toInteger()); + return QVariant(c); + } + break; + case QMetaType::QRectF: + { + QRectF r; + r.setX(array.at(id).toDouble()); + r.setY(array.at(id + 1).toDouble()); + r.setWidth(array.at(id + 2).toDouble()); + r.setHeight(array.at(id + 3).toDouble()); + return QVariant(r); + } + break; + case QMetaType::QRect: + { + QRect r; + r.setX(array.at(id).toInteger()); + r.setY(array.at(id + 1).toInteger()); + r.setWidth(array.at(id + 2).toInteger()); + r.setHeight(array.at(id + 3).toInteger()); + return QVariant(r); + } + break; + case QMetaType::QPointF: + { + QPointF p; + p.setX(array.at(id).toDouble()); + p.setY(array.at(id + 1).toDouble()); + return QVariant(p); + } + break; + case QMetaType::QPoint: + { + QPoint p; + p.setX(array.at(id).toInteger()); + p.setY(array.at(id + 1).toInteger()); + return QVariant(p); + } + break; + case QMetaType::QSizeF: + { + QSizeF s; + s.setWidth(array.at(id).toDouble()); + s.setHeight(array.at(id + 1).toDouble()); + return QVariant(s); + } + break; + case QMetaType::QSize: + { + QSize s; + s.setWidth(array.at(id).toInteger()); + s.setHeight(array.at(id + 1).toInteger()); + return QVariant(s); + } + break; + case QMetaType::Bool: + case QMetaType::Int: + case QMetaType::Float: + case QMetaType::Double: + { + return array.at(id).toVariant(); + } + + default: + qWarning() << "Keyframe property type not handled:" << type; + } + + return QVariant(); +} + +bool QQuickKeyframeGroupPrivate::loadKeyframes(bool fromBinary) { Q_Q(QQuickKeyframeGroup); @@ -80,48 +234,81 @@ if (!dataFile.open(QIODevice::ReadOnly)) { // Invalid file qWarning() << "Unable to open keyframeSource:" << dataFilePath; - qDeleteAll(keyframes); - keyframes.clear(); - return; + return false; } reader.setDevice(&dataFile); } else { reader.addData(keyframeData); } - auto cleanup = qScopeGuard([&dataFile] { dataFile.close(); }); + auto error = [&reader](const QString &msg = QString()) { + if (!msg.isEmpty()) + qWarning() << "Corrupt keyframeSource" << msg; + else + qWarning() << "Corrupt keyframeSource" << reader.lastError().toString(); + return false; + }; + + QCborValue kfSrcCborValue = QCborValue::fromCbor(reader); + if (reader.lastError() != QCborError::NoError || !kfSrcCborValue.isArray()) + return error(QStringLiteral("invalid format.(array expected)")); + + QCborArray kfSrcCborArray = kfSrcCborValue.toArray(); + // [ "QTimelineKeyframes", version(int), property type(int), [...]] + if (kfSrcCborArray.size() != 4) + return error(QStringLiteral("invalid data size")); + + if (kfSrcCborArray.at(0).toString() != QStringLiteral("QTimelineKeyframes")) + return error(QStringLiteral("invalid keyframeSource header string")); + + if (kfSrcCborArray.at(1).toInteger() != 1) + return error(QStringLiteral("invalid keyframeSource version %1").arg(kfSrcCborArray.at(1).toInteger())); + + // QMetaType::UnknownType = 0; + QMetaType::Type propertyType = static_cast<QMetaType::Type>(kfSrcCborArray.at(2).toInteger(0)); + const int frameSize = validFrameSize(propertyType); + if (frameSize < 0) + return error(QStringLiteral("unsupported property type")); - // Check that file is standard keyframes CBOR and get the version - int version = readKeyframesHeader(reader); + // Start keyframes array + QCborArray kfArray = kfSrcCborArray.at(3).toArray(); + const auto arraySize = kfArray.size(); + bool validKeyframeData = true; + for (qsizetype i = 0; i < arraySize - frameSize; i += frameSize) { + auto keyframe = std::make_unique<QQuickKeyframe>(q); + + keyframe->setFrame(kfArray.at(i).toDouble()); + + QCborValue easingTypeValue = kfArray.at(i + 1); + if (!easingTypeValue.isInteger()) { + validKeyframeData = false; + break; + } + keyframe->setEasing(static_cast<QEasingCurve::Type>(easingTypeValue.toInteger())); - if (version == -1) { - // Invalid file - qWarning() << "Invalid keyframeSource version:" << version; - return; + QVariant value = qQuickKeyframeReadProperty(kfArray, i + 2, propertyType); + if (value.isValid()) { + keyframe->setValue(value); + keyframes.append(keyframe.release()); + } else { + validKeyframeData = false; + break; + } } - QMetaType::Type propertyType = QMetaType::UnknownType; - if (reader.isInteger()) { - propertyType = static_cast<QMetaType::Type>(reader.toInteger()); - reader.next(); + if (!validKeyframeData) { + qWarning() << "Invalid keyframe data"; + resetKeyframes(); + return false; } - // Start keyframes array - reader.enterContainer(); - - while (reader.lastError() == QCborError::NoError && reader.hasNext()) { - auto keyframe = new QQuickKeyframe(q); - keyframe->setFrame(readReal(reader)); - keyframe->setEasing(QEasingCurve(static_cast<QEasingCurve::Type>(reader.toInteger()))); - reader.next(); - keyframe->setValue(readValue(reader, propertyType)); - keyframes.append(keyframe); - } - // Leave keyframes array - reader.leaveContainer(); + return true; +} - // Leave root array - reader.leaveContainer(); +void QQuickKeyframeGroupPrivate::resetKeyframes() +{ + qDeleteAll(keyframes); + keyframes.clear(); } void QQuickKeyframeGroupPrivate::append_keyframe(QQmlListProperty<QQuickKeyframe> *list, QQuickKeyframe *a) @@ -347,14 +534,13 @@ if (d->keyframes.size() > 0) { // Remove possible previously loaded keyframes - qDeleteAll(d->keyframes); - d->keyframes.clear(); + d->resetKeyframes(); d->keyframeData.clear(); } d->keyframeSource = source; - d->loadKeyframes(); - d->setupKeyframes(); + if (d->loadKeyframes()) + d->setupKeyframes(); reset(); emit keyframeSourceChanged(); @@ -374,14 +560,13 @@ if (d->keyframes.size() > 0) { // Remove possible previously loaded keyframes - qDeleteAll(d->keyframes); - d->keyframes.clear(); + d->resetKeyframes(); d->keyframeSource.clear(); } d->keyframeData = data; - d->loadKeyframes(true); - d->setupKeyframes(); + if (d->loadKeyframes(true)) + d->setupKeyframes(); reset(); emit keyframeSourceChanged(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/qtquicktimeline-everywhere-src-6.9.0/src/timeline/qquickkeyframedatautils_p.h new/qtquicktimeline-everywhere-src-6.9.1/src/timeline/qquickkeyframedatautils_p.h --- old/qtquicktimeline-everywhere-src-6.9.0/src/timeline/qquickkeyframedatautils_p.h 2025-03-29 00:18:58.000000000 +0100 +++ new/qtquicktimeline-everywhere-src-6.9.1/src/timeline/qquickkeyframedatautils_p.h 2025-05-29 02:19:44.000000000 +0200 @@ -15,7 +15,6 @@ // We mean it. // -#include <QtCore/QCborStreamReader> #include <QtCore/QCborStreamWriter> #include <QtCore/QVariant> #include <QtCore/QMetaType> @@ -28,180 +27,9 @@ #include <QtGui/QColor> #include <QtCore/private/qglobal_p.h> -// This file contains useful methods to read & write keyframes +// This file contains useful methods to write keyframes // CBOR binary files and understand the format. -// Read property 'type' value from CBOR and return it as QVariant. -QVariant readValue(QCborStreamReader &reader, QMetaType::Type type) -{ - switch (type) { - case QMetaType::Bool: { - bool b = reader.toBool(); - reader.next(); - return QVariant(b); - break; - } - case QMetaType::Int: { - int i = reader.toInteger(); - reader.next(); - return QVariant(i); - break; - } - case QMetaType::Float: { - float f = reader.toFloat(); - reader.next(); - return QVariant(f); - break; - } - case QMetaType::Double: { - double d = reader.toDouble(); - reader.next(); - return QVariant(d); - break; - } - case QMetaType::QString: { - QString s = reader.readString().data; - return QVariant(s); - break; - } - case QMetaType::QVector2D: { - QVector2D v; - v.setX(reader.toFloat()); - reader.next(); - v.setY(reader.toFloat()); - reader.next(); - return QVariant(v); - break; - } - case QMetaType::QVector3D: { - QVector3D v; - v.setX(reader.toFloat()); - reader.next(); - v.setY(reader.toFloat()); - reader.next(); - v.setZ(reader.toFloat()); - reader.next(); - return QVariant(v); - break; - } - case QMetaType::QVector4D: { - QVector4D v; - v.setX(reader.toFloat()); - reader.next(); - v.setY(reader.toFloat()); - reader.next(); - v.setZ(reader.toFloat()); - reader.next(); - v.setW(reader.toFloat()); - reader.next(); - return QVariant(v); - break; - } - case QMetaType::QQuaternion: { - QQuaternion q; - q.setScalar(reader.toFloat()); - reader.next(); - q.setX(reader.toFloat()); - reader.next(); - q.setY(reader.toFloat()); - reader.next(); - q.setZ(reader.toFloat()); - reader.next(); - return QVariant(q); - break; - } - case QMetaType::QColor: { - QColor c; - c.setRed(reader.toInteger()); - reader.next(); - c.setGreen(reader.toInteger()); - reader.next(); - c.setBlue(reader.toInteger()); - reader.next(); - c.setAlpha(reader.toInteger()); - reader.next(); - return QVariant(c); - break; - } - case QMetaType::QRect: { - QRect r; - r.setX(reader.toInteger()); - reader.next(); - r.setY(reader.toInteger()); - reader.next(); - r.setWidth(reader.toInteger()); - reader.next(); - r.setHeight(reader.toInteger()); - reader.next(); - return QVariant(r); - break; - } - default: { - qWarning() << "Keyframe property type not handled:" << type; - } - } - - return QVariant(); -} - -// Read a string from COB. -QString readString(QCborStreamReader &reader) -{ - QString result; - auto r = reader.readString(); - while (r.status == QCborStreamReader::Ok) { - result += r.data; - r = reader.readString(); - } - - if (r.status == QCborStreamReader::Error) { - // handle error condition - result.clear(); - } - return result; -} - -// Read a real (double or float) from CBOR. -double readReal(QCborStreamReader &reader) -{ - double result = 0.0; - if (reader.isDouble()) { - result = reader.toDouble(); - reader.next(); - } else if (reader.isFloat()) { - result = reader.toFloat(); - reader.next(); - } - return result; -} - -// Read keyframes file header and return version. -// If header is not valid, -1 is returned. -int readKeyframesHeader(QCborStreamReader &reader) -{ - int version = -1; - if (reader.lastError() == QCborError::NoError && reader.isArray()) { - // Start root array - reader.enterContainer(); - if (reader.isString()) { - QString header = readString(reader); - if (header == QStringLiteral("QTimelineKeyframes")) { - if (reader.isInteger()) { - version = reader.toInteger(); - reader.next(); - } else { - qWarning() << "Invalid keyframeSource version"; - } - } else { - qWarning() << "Invalid keyframeSource header"; - } - } else { - qWarning() << "Invalid keyframeSource container"; - } - } - return version; -} - void writeKeyframesHeader(QCborStreamWriter &writer, QMetaType::Type type, int version = 1) { // Root array