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
This commit is contained in:
Martchus 2023-08-01 00:50:21 +02:00
parent c3af3d43e6
commit 57b6d38e43
3 changed files with 94 additions and 14 deletions

View File

@ -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<TagParser::TagValue>();
values.reserve(size);
for (auto i = quint32(); i != size; ++i) {
const auto *const tagValueObj = qobject_cast<const TagValueObject *>(propertyValue.property(i).toQObject());
const auto arrayElement = propertyValue.property(i);
if (arrayElement.isUndefined() || arrayElement.isNull()) {
continue;
}
auto *tagValueObj = qobject_cast<TagValueObject *>(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)

View File

@ -1,6 +1,8 @@
#ifndef CLI_MEDIA_FILE_INFO_OBJECT_H
#define CLI_MEDIA_FILE_INFO_OBJECT_H
#include <tagparser/positioninset.h>
#include <QtGlobal>
#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;

View File

@ -52,5 +52,5 @@ function changeTagFields(tag) {
}
// set some other fields
fields.track.content = "4/17";
fields.track = "4/17";
}