From 57b6d38e4353c47d4bcc3d54ddcc9e561e885d87 Mon Sep 17 00:00:00 2001 From: Martchus Date: Tue, 1 Aug 2023 00:50:21 +0200 Subject: [PATCH] Simplify dealing with fields in JavaScript * Expose PositionInSet as Object (that is still convertable to String) * Allow assigning field values directly without having to have a TagValueObject and without having to have an Array --- cli/mediafileinfoobject.cpp | 79 +++++++++++++++++++++++++++++++------ cli/mediafileinfoobject.h | 27 +++++++++++++ testfiles/set-tags.js | 2 +- 3 files changed, 94 insertions(+), 14 deletions(-) diff --git a/cli/mediafileinfoobject.cpp b/cli/mediafileinfoobject.cpp index 8df91a2..da26837 100644 --- a/cli/mediafileinfoobject.cpp +++ b/cli/mediafileinfoobject.cpp @@ -103,6 +103,42 @@ QString UtilityObject::fixUmlauts(const QString &str) const return Utility::fixUmlauts(str); } +PositionInSetObject::PositionInSetObject(TagParser::PositionInSet value, QJSEngine *engine, QObject *parent) + : QObject(parent) + , m_v(value) +{ + Q_UNUSED(engine) +} + +PositionInSetObject::~PositionInSetObject() +{ +} + +qint32 PositionInSetObject::position() const +{ + return m_v.position(); +} + +void PositionInSetObject::setPosition(qint32 position) +{ + m_v.setPosition(position); +} + +qint32 PositionInSetObject::total() const +{ + return m_v.total(); +} + +void PositionInSetObject::setTotal(qint32 total) +{ + return m_v.setTotal(total); +} + +QString PositionInSetObject::toString() const +{ + return QString::fromStdString(m_v.toString()); +} + TagValueObject::TagValueObject(const TagParser::TagValue &value, QJSEngine *engine, QObject *parent) : QObject(parent) #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) @@ -119,7 +155,6 @@ TagValueObject::TagValueObject(const TagParser::TagValue &value, QJSEngine *engi case TagParser::TagDataType::Undefined: break; case TagParser::TagDataType::Text: - case TagParser::TagDataType::PositionInSet: case TagParser::TagDataType::Popularity: case TagParser::TagDataType::DateTime: case TagParser::TagDataType::DateTimeExpression: @@ -140,6 +175,9 @@ TagValueObject::TagValueObject(const TagParser::TagValue &value, QJSEngine *engi case TagParser::TagDataType::Picture: m_content = engine->toScriptValue(QByteArray(value.dataPointer(), Utility::sizeToInt(value.dataSize()))); break; + case TagParser::TagDataType::PositionInSet: + m_content = engine->newQObject(new PositionInSetObject(value.toPositionInSet(), engine, this)); + break; default: m_content = QJSValue::NullValue; } @@ -201,6 +239,11 @@ void TagValueObject::clear() setContent(QJSValue()); } +QString TagValueObject::toString() const +{ + return m_content.toString(); +} + TagObject::TagObject(TagParser::Tag &tag, TagParser::Diagnostics &diag, QJSEngine *engine, QObject *parent) : QObject(parent) , m_tag(tag) @@ -280,34 +323,44 @@ void TagObject::applyChanges() } auto propertyValue = m_fields.property(propertyName); if (!propertyValue.isArray()) { - m_engine->throwError(QJSValue::TypeError, QStringLiteral("non-array assigned to field ") + propertyName); - goto end; + auto array = m_engine->newArray(1); + array.setProperty(0, propertyValue); + propertyValue = std::move(array); } const auto size = propertyValue.property(QStringLiteral("length")).toUInt(); + const auto initialValues = m_tag.values(field); auto values = std::vector(); values.reserve(size); for (auto i = quint32(); i != size; ++i) { - const auto *const tagValueObj = qobject_cast(propertyValue.property(i).toQObject()); + const auto arrayElement = propertyValue.property(i); + if (arrayElement.isUndefined() || arrayElement.isNull()) { + continue; + } + auto *tagValueObj = qobject_cast(arrayElement.toQObject()); if (!tagValueObj) { - m_engine->throwError(QJSValue::TypeError, QStringLiteral("invalid value present in value-array of field ") + propertyName); - goto end; + tagValueObj = new TagValueObject(i < initialValues.size() ? *initialValues[i] : TagParser::TagValue(), m_engine, this); + tagValueObj->setContent(arrayElement); + propertyValue.setProperty(i, m_engine->newQObject(tagValueObj)); } if (tagValueObj->isInitial()) { + if (i < initialValues.size()) { + values.emplace_back(*initialValues[i]); + } continue; } const auto &value = values.emplace_back(tagValueObj->toTagValue(encoding)); m_diag.emplace_back(TagParser::DiagLevel::Debug, - value.isNull() ? CppUtilities::argsToString(" - delete ", propertyName.toStdString(), '[', i, ']') - : (tagValueObj->initialContent().isNull() ? CppUtilities::argsToString( - " - set ", propertyName.toStdString(), '[', i, "] to '", tagValueObj->content().toString().toStdString(), '\'') - : CppUtilities::argsToString(" - change ", propertyName.toStdString(), '[', - i, "] from '", tagValueObj->initialContent().toString().toStdString(), - "' to '", tagValueObj->content().toString().toStdString(), '\'')), + value.isNull() + ? CppUtilities::argsToString(" - delete ", propertyName.toStdString(), '[', i, ']') + : (tagValueObj->initialContent().isUndefined() ? CppUtilities::argsToString( + " - set ", propertyName.toStdString(), '[', i, "] to '", tagValueObj->content().toString().toStdString(), '\'') + : CppUtilities::argsToString(" - change ", propertyName.toStdString(), '[', i, + "] from '", tagValueObj->initialContent().toString().toStdString(), "' to '", + tagValueObj->content().toString().toStdString(), '\'')), std::string()); } m_tag.setValues(field, values); } -end:; } MediaFileInfoObject::MediaFileInfoObject(TagParser::MediaFileInfo &mediaFileInfo, TagParser::Diagnostics &diag, QJSEngine *engine, QObject *parent) diff --git a/cli/mediafileinfoobject.h b/cli/mediafileinfoobject.h index 8111845..bb998c2 100644 --- a/cli/mediafileinfoobject.h +++ b/cli/mediafileinfoobject.h @@ -1,6 +1,8 @@ #ifndef CLI_MEDIA_FILE_INFO_OBJECT_H #define CLI_MEDIA_FILE_INFO_OBJECT_H +#include + #include #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) namespace TagParser { @@ -58,6 +60,30 @@ inline void UtilityObject::setDiag(const std::string *context, TagParser::Diagno m_diag = diag; } +/*! + * \brief The PositionInSetObject class wraps a TagParser::PositionInSet for use within QML. + */ +class PositionInSetObject : public QObject { + Q_OBJECT + Q_PROPERTY(qint32 position READ position WRITE setPosition) + Q_PROPERTY(qint32 total READ total WRITE setTotal) + +public: + explicit PositionInSetObject(TagParser::PositionInSet value, QJSEngine *engine, QObject *parent); + ~PositionInSetObject() override; + + qint32 position() const; + void setPosition(qint32 position); + qint32 total() const; + void setTotal(qint32 total); + +public Q_SLOTS: + QString toString() const; + +private: + TagParser::PositionInSet m_v; +}; + /*! * \brief The TagValueObject class wraps a TagParser::TagValue for use within QML. */ @@ -82,6 +108,7 @@ public: public Q_SLOTS: void restore(); void clear(); + QString toString() const; private: QString m_type; diff --git a/testfiles/set-tags.js b/testfiles/set-tags.js index ac8560b..600064e 100644 --- a/testfiles/set-tags.js +++ b/testfiles/set-tags.js @@ -52,5 +52,5 @@ function changeTagFields(tag) { } // set some other fields - fields.track.content = "4/17"; + fields.track = "4/17"; }