Track "position in set" changes via JavaScript correctly

This commit is contained in:
Martchus 2023-08-04 00:19:10 +02:00
parent 7533761d77
commit 485611141c
2 changed files with 76 additions and 45 deletions

View File

@ -154,13 +154,21 @@ QtGui::SongDescription UtilityObject::makeSongDescription(const QJSValue &obj)
return desc; return desc;
} }
PositionInSetObject::PositionInSetObject(TagParser::PositionInSet value, QJSEngine *engine, QObject *parent) PositionInSetObject::PositionInSetObject(TagParser::PositionInSet value, TagValueObject *relatedValue, QJSEngine *engine, QObject *parent)
: QObject(parent) : QObject(parent)
, m_v(value) , m_v(value)
, m_relatedValue(relatedValue)
{ {
Q_UNUSED(engine) Q_UNUSED(engine)
} }
PositionInSetObject::PositionInSetObject(const PositionInSetObject &other)
: QObject(other.parent())
, m_v(other.m_v)
, m_relatedValue(nullptr)
{
}
PositionInSetObject::~PositionInSetObject() PositionInSetObject::~PositionInSetObject()
{ {
} }
@ -172,6 +180,9 @@ qint32 PositionInSetObject::position() const
void PositionInSetObject::setPosition(qint32 position) void PositionInSetObject::setPosition(qint32 position)
{ {
if (m_relatedValue) {
m_relatedValue->flagChange();
}
m_v.setPosition(position); m_v.setPosition(position);
} }
@ -182,7 +193,10 @@ qint32 PositionInSetObject::total() const
void PositionInSetObject::setTotal(qint32 total) void PositionInSetObject::setTotal(qint32 total)
{ {
return m_v.setTotal(total); if (m_relatedValue) {
m_relatedValue->flagChange();
}
m_v.setTotal(total);
} }
QString PositionInSetObject::toString() const QString PositionInSetObject::toString() const
@ -192,46 +206,10 @@ QString PositionInSetObject::toString() const
TagValueObject::TagValueObject(const TagParser::TagValue &value, QJSEngine *engine, QObject *parent) TagValueObject::TagValueObject(const TagParser::TagValue &value, QJSEngine *engine, QObject *parent)
: QObject(parent) : QObject(parent)
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) , m_engine(engine)
, m_type(QString::fromUtf8(TagParser::tagDataTypeString(value.type())))
#endif
, m_initial(true) , m_initial(true)
{ {
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) setContentFromTagValue(value);
const auto type = TagParser::tagDataTypeString(value.type());
m_type = QString::fromUtf8(type.data(), Utility::sizeToInt(type.size()));
#endif
switch (value.type()) {
case TagParser::TagDataType::Undefined:
break;
case TagParser::TagDataType::Text:
case TagParser::TagDataType::Popularity:
case TagParser::TagDataType::DateTime:
case TagParser::TagDataType::DateTimeExpression:
case TagParser::TagDataType::TimeSpan:
m_content = Utility::tagValueToQString(value);
break;
case TagParser::TagDataType::Integer:
m_content = value.toInteger();
break;
case TagParser::TagDataType::UnsignedInteger:
if (auto v = value.toUnsignedInteger(); v < std::numeric_limits<uint>::max()) {
m_content = QJSValue(static_cast<uint>(v));
} else {
m_content = QString::number(v);
}
break;
case TagParser::TagDataType::Binary:
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;
}
} }
TagValueObject::~TagValueObject() TagValueObject::~TagValueObject()
@ -255,13 +233,47 @@ const QJSValue &TagValueObject::initialContent() const
void TagValueObject::setContent(const QJSValue &content) void TagValueObject::setContent(const QJSValue &content)
{ {
if (m_initial) { flagChange();
m_initialContent = m_content;
m_initial = false;
}
m_content = content; m_content = content;
} }
void TagValueObject::setContentFromTagValue(const TagParser::TagValue &value)
{
const auto type = TagParser::tagDataTypeString(value.type());
m_type = QString::fromUtf8(type.data(), Utility::sizeToInt(type.size()));
switch (value.type()) {
case TagParser::TagDataType::Undefined:
break;
case TagParser::TagDataType::Text:
case TagParser::TagDataType::Popularity:
case TagParser::TagDataType::DateTime:
case TagParser::TagDataType::DateTimeExpression:
case TagParser::TagDataType::TimeSpan:
m_content = Utility::tagValueToQString(value);
break;
case TagParser::TagDataType::Integer:
m_content = value.toInteger();
break;
case TagParser::TagDataType::UnsignedInteger:
if (auto v = value.toUnsignedInteger(); v < std::numeric_limits<uint>::max()) {
m_content = QJSValue(static_cast<uint>(v));
} else {
m_content = QString::number(v);
}
break;
case TagParser::TagDataType::Binary:
case TagParser::TagDataType::Picture:
m_content = m_engine->toScriptValue(QByteArray(value.dataPointer(), Utility::sizeToInt(value.dataSize())));
break;
case TagParser::TagDataType::PositionInSet:
m_content = m_engine->newQObject(new PositionInSetObject(value.toPositionInSet(), this, m_engine, this));
break;
default:
m_content = QJSValue::NullValue;
}
}
bool TagValueObject::isInitial() const bool TagValueObject::isInitial() const
{ {
return m_initial; return m_initial;
@ -277,6 +289,18 @@ TagParser::TagValue TagValueObject::toTagValue(TagParser::TagTextEncoding encodi
nativeUtf16Encoding, encoding); nativeUtf16Encoding, encoding);
} }
void TagValueObject::flagChange()
{
if (m_initial) {
if (const auto *const positionInSet = qobject_cast<const PositionInSetObject *>(m_content.toQObject())) {
m_initialContent = m_engine->newQObject(new PositionInSetObject(*positionInSet));
} else {
m_initialContent = m_content;
}
m_initial = false;
}
}
void TagValueObject::restore() void TagValueObject::restore()
{ {
if (!m_initial) { if (!m_initial) {

View File

@ -76,6 +76,8 @@ inline void UtilityObject::setDiag(const std::string *context, TagParser::Diagno
m_diag = diag; m_diag = diag;
} }
class TagValueObject;
/*! /*!
* \brief The PositionInSetObject class wraps a TagParser::PositionInSet for use within QML. * \brief The PositionInSetObject class wraps a TagParser::PositionInSet for use within QML.
*/ */
@ -85,7 +87,8 @@ class PositionInSetObject : public QObject {
Q_PROPERTY(qint32 total READ total WRITE setTotal) Q_PROPERTY(qint32 total READ total WRITE setTotal)
public: public:
explicit PositionInSetObject(TagParser::PositionInSet value, QJSEngine *engine, QObject *parent); explicit PositionInSetObject(TagParser::PositionInSet value, TagValueObject *relatedValue, QJSEngine *engine, QObject *parent);
explicit PositionInSetObject(const PositionInSetObject &other);
~PositionInSetObject() override; ~PositionInSetObject() override;
qint32 position() const; qint32 position() const;
@ -98,6 +101,7 @@ public Q_SLOTS:
private: private:
TagParser::PositionInSet m_v; TagParser::PositionInSet m_v;
TagValueObject *m_relatedValue;
}; };
/*! /*!
@ -117,6 +121,7 @@ public:
const QString &type() const; const QString &type() const;
const QJSValue &content() const; const QJSValue &content() const;
void setContent(const QJSValue &content); void setContent(const QJSValue &content);
void setContentFromTagValue(const TagParser::TagValue &value);
const QJSValue &initialContent() const; const QJSValue &initialContent() const;
bool isInitial() const; bool isInitial() const;
TagParser::TagValue toTagValue(TagParser::TagTextEncoding encoding) const; TagParser::TagValue toTagValue(TagParser::TagTextEncoding encoding) const;
@ -125,8 +130,10 @@ public Q_SLOTS:
void restore(); void restore();
void clear(); void clear();
QString toString() const; QString toString() const;
void flagChange();
private: private:
QJSEngine *m_engine;
QString m_type; QString m_type;
QJSValue m_content; QJSValue m_content;
QJSValue m_initialContent; QJSValue m_initialContent;