fixed conversion PropertyValue <-> QVariant

This commit is contained in:
Igor Korsukov 2021-11-18 17:25:56 +02:00 committed by pereverzev+v
parent 1334d739fd
commit f93004843c
26 changed files with 419 additions and 322 deletions

View file

@ -85,6 +85,9 @@ set(MODULE_SRC
${COMPAT_MIDI_SRC}
${CMAKE_CURRENT_LIST_DIR}/types/types.h
${CMAKE_CURRENT_LIST_DIR}/types/spatium.h
${CMAKE_CURRENT_LIST_DIR}/property/propertyvalue.cpp
${CMAKE_CURRENT_LIST_DIR}/property/propertyvalue.h

View file

@ -465,11 +465,7 @@ void XmlWriter::tag(const QString& name, QVariant data)
break;
default: {
const char* type = data.typeName();
if (strcmp(type, "Ms::Spatium") == 0) {
*this << "<" << name << ">";
*this << data.value<Spatium>().val();
*this << "</" << ename << ">\n";
} else if (strcmp(type, "mu::PointF") == 0) {
if (strcmp(type, "mu::PointF") == 0) {
PointF p = PointF::fromVariant(data);
*this << QString("<%1 x=\"%2\" y=\"%3\"/>\n").arg(name).arg(p.x()).arg(p.y());
} else if (strcmp(type, "mu::SizeF") == 0) {

View file

@ -25,7 +25,6 @@
#include "engravingobject.h"
#include "elementgroup.h"
#include "spatium.h"
#include "fraction.h"
#include "mscore.h"
#include "shape.h"
@ -39,6 +38,8 @@
#include "modularity/ioc.h"
#include "iengravingconfiguration.h"
#include "types/spatium.h"
namespace mu::engraving {
class Factory;
class AccessibleItem;

View file

@ -265,7 +265,6 @@ set(LIBMSCORE_SRC
${CMAKE_CURRENT_LIST_DIR}/spanner.h
${CMAKE_CURRENT_LIST_DIR}/spannermap.cpp
${CMAKE_CURRENT_LIST_DIR}/spannermap.h
${CMAKE_CURRENT_LIST_DIR}/spatium.h
${CMAKE_CURRENT_LIST_DIR}/splitMeasure.cpp
${CMAKE_CURRENT_LIST_DIR}/staff.cpp
${CMAKE_CURRENT_LIST_DIR}/staff.h

View file

@ -65,7 +65,6 @@
#include "stemslash.h"
#include "fraction.h"
#include "excerpt.h"
#include "spatium.h"
#include "barline.h"
#include "skyline.h"
#include "scorefont.h"
@ -233,15 +232,6 @@ QString toUserString(Direction val)
#endif
}
//---------------------------------------------------------
// doubleToSpatium
//---------------------------------------------------------
static Spatium doubleToSpatium(double d)
{
return Spatium(d);
}
//---------------------------------------------------------
// init
//---------------------------------------------------------
@ -301,15 +291,6 @@ void MScore::init()
void MScore::registerUiTypes()
{
if (!QMetaType::registerConverter<Spatium, double>(&Spatium::toDoubleStatic)) {
qFatal("registerConverter Spatium::toDouble failed");
}
if (!QMetaType::registerConverter<double, Spatium>(&doubleToSpatium)) {
qFatal("registerConverter doubleToSpatium failed");
}
// if (!QMetaType::registerComparators<Spatium>())
// qFatal("registerComparators for Spatium failed");
#ifdef SCRIPT_INTERFACE
qRegisterMetaType<Note::ValueType>("ValueType");

View file

@ -395,7 +395,7 @@ enum class Pid {
extern mu::engraving::PropertyValue readProperty(Pid type, XmlReader& e);
extern mu::engraving::PropertyValue propertyFromString(Pid type, QString value);
extern QString propertyToString(Pid, const mu::engraving::PropertyValue& value, bool mscx);
extern P_TYPE propertyType(Pid);
extern mu::engraving::P_TYPE propertyType(Pid);
extern const char* propertyName(Pid);
extern bool propertyLink(Pid id);
extern Pid propertyId(const QString& name);

View file

@ -25,7 +25,6 @@
#include "infrastructure/draw/color.h"
#include "engravingitem.h"
#include "spatium.h"
#include "mscore.h"
#include "durationtype.h"
#include "note.h"

View file

@ -29,7 +29,6 @@
*/
#include "engravingitem.h"
#include "spatium.h"
#include "symbol.h"
#include "skyline.h"

View file

@ -31,7 +31,6 @@
#include "style/style.h"
#include "compat/midi/midipatch.h"
#include "spatium.h"
#include "mscore.h"
#include "sig.h"
#include "tempo.h"

View file

@ -34,92 +34,92 @@ PropertyValue::PropertyValue()
}
PropertyValue::PropertyValue(bool v)
: m_type(Ms::P_TYPE::BOOL), m_val(v)
: m_type(P_TYPE::BOOL), m_val(v)
{
}
PropertyValue::PropertyValue(int v)
: m_type(Ms::P_TYPE::INT), m_val(v)
: m_type(P_TYPE::INT), m_val(v)
{
}
PropertyValue::PropertyValue(qreal v)
: m_type(Ms::P_TYPE::REAL), m_val(v)
: m_type(P_TYPE::REAL), m_val(v)
{
}
PropertyValue::PropertyValue(const char* v)
: m_type(Ms::P_TYPE::STRING), m_val(QString(v))
: m_type(P_TYPE::STRING), m_val(QString(v))
{
}
PropertyValue::PropertyValue(const QString& v)
: m_type(Ms::P_TYPE::STRING), m_val(v)
: m_type(P_TYPE::STRING), m_val(v)
{
}
PropertyValue::PropertyValue(const Ms::Spatium& v)
: m_type(Ms::P_TYPE::SPATIUM), m_val(v)
PropertyValue::PropertyValue(const Spatium& v)
: m_type(P_TYPE::SPATIUM), m_val(v)
{
}
PropertyValue::PropertyValue(const PointF& v)
: m_type(Ms::P_TYPE::POINT), m_val(v)
: m_type(P_TYPE::POINT), m_val(v)
{
}
PropertyValue::PropertyValue(const SizeF& v)
: m_type(Ms::P_TYPE::SIZE), m_val(v)
: m_type(P_TYPE::SIZE), m_val(v)
{
}
PropertyValue::PropertyValue(const PainterPath& v)
: m_type(Ms::P_TYPE::PATH), m_val(v)
: m_type(P_TYPE::PATH), m_val(v)
{
}
PropertyValue::PropertyValue(const draw::Color& v)
: m_type(Ms::P_TYPE::COLOR), m_val(v)
: m_type(P_TYPE::COLOR), m_val(v)
{
}
PropertyValue::PropertyValue(Ms::Align v)
: m_type(Ms::P_TYPE::ALIGN), m_val(v)
: m_type(P_TYPE::ALIGN), m_val(v)
{
}
PropertyValue::PropertyValue(Ms::Direction v)
: m_type(Ms::P_TYPE::DIRECTION), m_val(v)
: m_type(P_TYPE::DIRECTION), m_val(v)
{
}
PropertyValue::PropertyValue(Ms::SymId v)
: m_type(Ms::P_TYPE::SYMID), m_val(v)
: m_type(P_TYPE::SYMID), m_val(v)
{
}
PropertyValue::PropertyValue(Ms::BarLineType v)
: m_type(Ms::P_TYPE::BARLINE_TYPE), m_val(v)
: m_type(P_TYPE::BARLINE_TYPE), m_val(v)
{
}
PropertyValue::PropertyValue(Ms::HookType v)
: m_type(Ms::P_TYPE::HOOK_TYPE), m_val(v)
: m_type(P_TYPE::HOOK_TYPE), m_val(v)
{
}
PropertyValue::PropertyValue(Ms::HPlacement v)
: m_type(Ms::P_TYPE::HPLACEMENT), m_val(v)
: m_type(P_TYPE::HPLACEMENT), m_val(v)
{
}
PropertyValue::PropertyValue(const Ms::PitchValues& v)
: m_type(Ms::P_TYPE::PITCH_VALUES), m_val(v)
: m_type(P_TYPE::PITCH_VALUES), m_val(v)
{
}
PropertyValue::PropertyValue(const Ms::Groups& v)
: m_type(Ms::P_TYPE::GROUPS), m_any(v)
: m_type(P_TYPE::GROUPS), m_any(v)
{
}
@ -129,7 +129,7 @@ const Ms::Groups& PropertyValue::toGroups() const
}
PropertyValue::PropertyValue(const Ms::TDuration& v)
: m_type(Ms::P_TYPE::TDURATION), m_any(v)
: m_type(P_TYPE::TDURATION), m_any(v)
{
}
@ -139,21 +139,21 @@ const Ms::TDuration& PropertyValue::toTDuration() const
}
PropertyValue::PropertyValue(const Ms::Fraction& v)
: m_type(Ms::P_TYPE::FRACTION), m_val(v)
: m_type(P_TYPE::FRACTION), m_val(v)
{
}
PropertyValue::PropertyValue(const QList<int>& v)
: m_type(Ms::P_TYPE::INT_LIST), m_val(v)
: m_type(P_TYPE::INT_LIST), m_val(v)
{
}
bool PropertyValue::isValid() const
{
return m_type != Ms::P_TYPE::UNDEFINED;
return m_type != P_TYPE::UNDEFINED;
}
Ms::P_TYPE PropertyValue::type() const
P_TYPE PropertyValue::type() const
{
return m_type;
}
@ -161,35 +161,35 @@ Ms::P_TYPE PropertyValue::type() const
bool PropertyValue::operator ==(const PropertyValue& v) const
{
//! HACK Temporary hack for bool comparisons (maybe one type is bool and another type is int)
if (v.m_type == Ms::P_TYPE::BOOL || m_type == Ms::P_TYPE::BOOL) {
if (v.m_type == P_TYPE::BOOL || m_type == P_TYPE::BOOL) {
return v.value<bool>() == value<bool>();
}
//! HACK Temporary hack for Spatium comparisons (maybe one type is Spatium and another type is real)
if (v.m_type == Ms::P_TYPE::SPATIUM || m_type == Ms::P_TYPE::SPATIUM) {
if (v.m_type == P_TYPE::SPATIUM || m_type == P_TYPE::SPATIUM) {
return RealIsEqual(v.value<qreal>(), value<qreal>());
}
//! HACK Temporary hack for Fraction comparisons
if (v.m_type == Ms::P_TYPE::FRACTION) {
assert(m_type == Ms::P_TYPE::FRACTION);
if (v.m_type == P_TYPE::FRACTION) {
assert(m_type == P_TYPE::FRACTION);
return v.value<Ms::Fraction>().identical(value<Ms::Fraction>());
}
//! HACK Temporary hack for TDURATION comparisons
if (v.m_type == Ms::P_TYPE::TDURATION) {
assert(m_type == Ms::P_TYPE::TDURATION);
if (v.m_type == P_TYPE::TDURATION) {
assert(m_type == P_TYPE::TDURATION);
return v.toTDuration() == toTDuration();
}
//! HACK Temporary hack for GROUPS comparisons
if (v.m_type == Ms::P_TYPE::GROUPS) {
assert(m_type == Ms::P_TYPE::GROUPS);
if (v.m_type == P_TYPE::GROUPS) {
assert(m_type == P_TYPE::GROUPS);
return v.toGroups() == toGroups();
}
if (v.m_type == Ms::P_TYPE::REAL) {
assert(m_type == Ms::P_TYPE::REAL);
if (v.m_type == P_TYPE::REAL) {
assert(m_type == P_TYPE::REAL);
return RealIsEqual(v.value<qreal>(), value<qreal>());
}
@ -199,59 +199,59 @@ bool PropertyValue::operator ==(const PropertyValue& v) const
QVariant PropertyValue::toQVariant() const
{
switch (m_type) {
case Ms::P_TYPE::UNDEFINED: return QVariant();
case P_TYPE::UNDEFINED: return QVariant();
// base
case Ms::P_TYPE::BOOL: return value<bool>();
case Ms::P_TYPE::INT: return value<int>();
case Ms::P_TYPE::REAL: return value<qreal>();
case Ms::P_TYPE::STRING: return value<QString>();
case P_TYPE::BOOL: return value<bool>();
case P_TYPE::INT: return value<int>();
case P_TYPE::REAL: return value<qreal>();
case P_TYPE::STRING: return value<QString>();
// geometry
case Ms::P_TYPE::POINT: return value<PointF>().toQPointF();
case Ms::P_TYPE::SIZE: return value<SizeF>().toQSizeF();
case Ms::P_TYPE::PATH: {
case P_TYPE::POINT: return value<PointF>().toQPointF();
case P_TYPE::SIZE: return value<SizeF>().toQSizeF();
case P_TYPE::PATH: {
UNREACHABLE; //! TODO
}
break;
case Ms::P_TYPE::SCALE: {
case P_TYPE::SCALE: {
UNREACHABLE; //! TODO
}
break;
case Ms::P_TYPE::SPATIUM: return value<Ms::Spatium>().val();
case Ms::P_TYPE::POINT_SP: {
case P_TYPE::SPATIUM: return value<Spatium>().val();
case P_TYPE::POINT_SP: {
UNREACHABLE; //! TODO
}
break;
case Ms::P_TYPE::POINT_SP_MM: {
case P_TYPE::POINT_SP_MM: {
UNREACHABLE; //! TODO
}
break;
case Ms::P_TYPE::SP_REAL: {
case P_TYPE::SP_REAL: {
UNREACHABLE; //! TODO
}
break;
// draw
case Ms::P_TYPE::COLOR: return value<draw::Color>().toQColor();
case Ms::P_TYPE::FONT_FACE: {
case P_TYPE::COLOR: return value<draw::Color>().toQColor();
case P_TYPE::FONT_FACE: {
UNREACHABLE; //! TODO
}
break;
case Ms::P_TYPE::ALIGN: return QVariant::fromValue(value<Ms::Align>());
case Ms::P_TYPE::PLACEMENT: return static_cast<int>(value<Ms::Placement>());
case Ms::P_TYPE::HPLACEMENT: return static_cast<int>(value<Ms::HPlacement>());
case Ms::P_TYPE::DIRECTION: return QVariant::fromValue(value<Ms::Direction>());
case Ms::P_TYPE::DIRECTION_H: {
case P_TYPE::ALIGN: return QVariant::fromValue(value<Ms::Align>());
case P_TYPE::PLACEMENT: return static_cast<int>(value<Ms::Placement>());
case P_TYPE::HPLACEMENT: return static_cast<int>(value<Ms::HPlacement>());
case P_TYPE::DIRECTION: return QVariant::fromValue(value<Ms::Direction>());
case P_TYPE::DIRECTION_H: {
UNREACHABLE; //! TODO
}
break;
// time
case Ms::P_TYPE::FRACTION: return QVariant::fromValue(value<Ms::Fraction>());
case Ms::P_TYPE::TDURATION: return QVariant::fromValue(toTDuration());
case P_TYPE::FRACTION: return QVariant::fromValue(value<Ms::Fraction>());
case P_TYPE::TDURATION: return QVariant::fromValue(toTDuration());
// other
case Ms::P_TYPE::BARLINE_TYPE: return static_cast<int>(value<Ms::BarLineType>());
case Ms::P_TYPE::SYMID: return static_cast<int>(value<Ms::SymId>());
case Ms::P_TYPE::HOOK_TYPE: return static_cast<int>(value<Ms::HookType>());
case Ms::P_TYPE::DYNAMIC_TYPE: return static_cast<int>(value<Ms::DynamicType>());
case Ms::P_TYPE::ACCIDENTAL_ROLE: return static_cast<int>(value<Ms::AccidentalRole>());
case P_TYPE::BARLINE_TYPE: return static_cast<int>(value<Ms::BarLineType>());
case P_TYPE::SYMID: return static_cast<int>(value<Ms::SymId>());
case P_TYPE::HOOK_TYPE: return static_cast<int>(value<Ms::HookType>());
case P_TYPE::DYNAMIC_TYPE: return static_cast<int>(value<Ms::DynamicType>());
case P_TYPE::ACCIDENTAL_ROLE: return static_cast<int>(value<Ms::AccidentalRole>());
default:
UNREACHABLE; //! TODO
}
@ -259,8 +259,73 @@ QVariant PropertyValue::toQVariant() const
return QVariant();
}
PropertyValue PropertyValue::fromQVariant(const QVariant& v)
PropertyValue PropertyValue::fromQVariant(const QVariant& v, P_TYPE type)
{
switch (type) {
case P_TYPE::UNDEFINED: // try by QVariant type
break;
// base
case P_TYPE::BOOL: return PropertyValue(v.toBool());
case P_TYPE::INT: return PropertyValue(v.toInt());
case P_TYPE::REAL: return PropertyValue(v.toReal());
case P_TYPE::STRING: return PropertyValue(v.toString());
// geometry
case P_TYPE::POINT: return PropertyValue(PointF::fromQPointF(v.value<QPointF>()));
case P_TYPE::SIZE: return PropertyValue(SizeF::fromQSizeF(v.value<QSizeF>()));
case P_TYPE::PATH: {
UNREACHABLE; //! TODO
}
break;
case P_TYPE::SCALE: {
UNREACHABLE; //! TODO
}
break;
case P_TYPE::SPATIUM: return PropertyValue(Spatium(v.toReal()));
case P_TYPE::POINT_SP: {
UNREACHABLE; //! TODO
}
break;
case P_TYPE::POINT_SP_MM: {
UNREACHABLE; //! TODO
}
break;
case P_TYPE::SP_REAL: {
UNREACHABLE; //! TODO
}
break;
// draw
case P_TYPE::COLOR: return PropertyValue(Color::fromQColor(v.value<QColor>()));
case P_TYPE::FONT_FACE: {
UNREACHABLE; //! TODO
}
break;
case P_TYPE::ALIGN: return PropertyValue(Ms::Align(v.toInt()));
case P_TYPE::PLACEMENT: return PropertyValue(Ms::Placement(v.toInt()));
case P_TYPE::HPLACEMENT: return PropertyValue(Ms::HPlacement(v.toInt()));
case P_TYPE::DIRECTION: return PropertyValue(Ms::Direction(v.toInt()));
case P_TYPE::DIRECTION_H: {
UNREACHABLE; //! TODO
}
break;
// time
case P_TYPE::FRACTION: return PropertyValue(v.value<Ms::Fraction>());
case P_TYPE::TDURATION: {
UNREACHABLE; //! TODO
}
break;
// other
case P_TYPE::BARLINE_TYPE: return PropertyValue(Ms::BarLineType(v.toInt()));
case P_TYPE::SYMID: return PropertyValue(Ms::SymId(v.toInt()));
case P_TYPE::HOOK_TYPE: return PropertyValue(Ms::HookType(v.toInt()));
case P_TYPE::DYNAMIC_TYPE: return PropertyValue(Ms::DynamicType(v.toInt()));
case P_TYPE::ACCIDENTAL_ROLE: return PropertyValue(Ms::AccidentalRole(v.toInt()));
default:
break;
}
//! NOTE Try determinate type by QVariant type
switch (v.type()) {
case QVariant::Invalid: return PropertyValue();
case QVariant::Bool: return PropertyValue(v.toBool());
@ -278,9 +343,6 @@ PropertyValue PropertyValue::fromQVariant(const QVariant& v)
case QVariant::Color: return PropertyValue(draw::Color::fromQColor(v.value<QColor>()));
case QVariant::UserType: {
const char* type = v.typeName();
if (strcmp(type, "Ms::Spatium") == 0) {
return PropertyValue(v.value<Ms::Spatium>());
}
if (strcmp(type, "Ms::Direction") == 0) {
return PropertyValue(v.value<Ms::Direction>());
}

View file

@ -29,7 +29,7 @@
#include <QVariant>
#include "libmscore/spatium.h"
#include "types/types.h"
#include "libmscore/types.h"
#include "libmscore/symid.h"
#include "libmscore/pitchvalue.h"
@ -44,16 +44,19 @@
namespace Ms {
class Groups;
class TDuration;
}
namespace mu::engraving {
enum class P_TYPE {
UNDEFINED = 0,
// base
BOOL,
INT,
REAL,
STRING,
// geometry
BOOL, // bool
INT, // int
REAL, // qreal
STRING, // QString
// geometry
POINT,
SIZE,
PATH, // mu::PainterPath
SCALE,
@ -61,11 +64,11 @@ enum class P_TYPE {
POINT_SP, // point units, value saved in (score) spatium units
POINT_SP_MM, // point units, value saved as mm or spatium depending on EngravingItem->sizeIsSpatiumDependent()
POINT,
SP_REAL, // real (point) value saved in (score) spatium units
// draw
COLOR,
COLOR, // Color
FONT_FACE,
ALIGN,
PLACEMENT, // ABOVE or BELOW
@ -108,9 +111,7 @@ enum class P_TYPE {
HOOK_TYPE,
ACCIDENTAL_ROLE
};
}
namespace mu::engraving {
class PropertyValue
{
public:
@ -127,14 +128,14 @@ public:
PropertyValue(const PointF& v);
PropertyValue(const SizeF& v);
PropertyValue(const PainterPath& v);
PropertyValue(const Ms::Spatium& v);
PropertyValue(const Spatium& v);
// draw
PropertyValue(const draw::Color& v);
PropertyValue(Ms::Align v);
PropertyValue(Ms::HPlacement v);
PropertyValue(Ms::Placement v)
: m_type(Ms::P_TYPE::PLACEMENT), m_val(v) {}
: m_type(P_TYPE::PLACEMENT), m_val(v) {}
PropertyValue(Ms::Direction v);
PropertyValue(Ms::SymId v);
@ -142,25 +143,25 @@ public:
PropertyValue(Ms::HookType v);
PropertyValue(Ms::DynamicType v)
: m_type(Ms::P_TYPE::DYNAMIC_TYPE), m_val(v) {}
: m_type(P_TYPE::DYNAMIC_TYPE), m_val(v) {}
PropertyValue(const Ms::PitchValues& v);
PropertyValue(const Ms::Fraction& v);
PropertyValue(const QList<int>& v); //endings
PropertyValue(const Ms::AccidentalRole& v)
: m_type(Ms::P_TYPE::ACCIDENTAL_ROLE), m_val(v) {}
: m_type(P_TYPE::ACCIDENTAL_ROLE), m_val(v) {}
PropertyValue(const Ms::Groups& v);
PropertyValue(const Ms::TDuration& v);
bool isValid() const;
Ms::P_TYPE type() const;
P_TYPE type() const;
template<typename T>
T value() const
{
if (Ms::P_TYPE::UNDEFINED == m_type) {
if (P_TYPE::UNDEFINED == m_type) {
return T();
}
@ -171,7 +172,7 @@ public:
//! HACK Temporary hack for int to enum
if constexpr (std::is_enum<T>::value) {
if (Ms::P_TYPE::INT == m_type) {
if (P_TYPE::INT == m_type) {
const int* pi = std::get_if<int>(&m_val);
assert(pi);
return pi ? static_cast<T>(*pi) : T();
@ -181,15 +182,15 @@ public:
//! HACK Temporary hack for enum to int
if constexpr (std::is_same<T, int>::value) {
switch (m_type) {
case Ms::P_TYPE::ALIGN: return static_cast<int>(value<Ms::Align>());
case Ms::P_TYPE::HPLACEMENT: return static_cast<int>(value<Ms::HPlacement>());
case Ms::P_TYPE::PLACEMENT: return static_cast<int>(value<Ms::Placement>());
case Ms::P_TYPE::DIRECTION: return static_cast<int>(value<Ms::Direction>());
case Ms::P_TYPE::SYMID: return static_cast<int>(value<Ms::SymId>());
case Ms::P_TYPE::BARLINE_TYPE: return static_cast<int>(value<Ms::BarLineType>());
case Ms::P_TYPE::HOOK_TYPE: return static_cast<int>(value<Ms::HookType>());
case Ms::P_TYPE::DYNAMIC_TYPE: return static_cast<int>(value<Ms::DynamicType>());
case Ms::P_TYPE::ACCIDENTAL_ROLE: return static_cast<int>(value<Ms::AccidentalRole>());
case P_TYPE::ALIGN: return static_cast<int>(value<Ms::Align>());
case P_TYPE::HPLACEMENT: return static_cast<int>(value<Ms::HPlacement>());
case P_TYPE::PLACEMENT: return static_cast<int>(value<Ms::Placement>());
case P_TYPE::DIRECTION: return static_cast<int>(value<Ms::Direction>());
case P_TYPE::SYMID: return static_cast<int>(value<Ms::SymId>());
case P_TYPE::BARLINE_TYPE: return static_cast<int>(value<Ms::BarLineType>());
case P_TYPE::HOOK_TYPE: return static_cast<int>(value<Ms::HookType>());
case P_TYPE::DYNAMIC_TYPE: return static_cast<int>(value<Ms::DynamicType>());
case P_TYPE::ACCIDENTAL_ROLE: return static_cast<int>(value<Ms::AccidentalRole>());
default:
break;
}
@ -197,7 +198,7 @@ public:
//! HACK Temporary hack for bool to int
if constexpr (std::is_same<T, int>::value) {
if (Ms::P_TYPE::BOOL == m_type) {
if (P_TYPE::BOOL == m_type) {
const bool* pb = std::get_if<bool>(&m_val);
assert(pb);
return pb ? static_cast<T>(*pb) : T();
@ -212,18 +213,18 @@ public:
}
//! HACK Temporary hack for real to Spatium
if constexpr (std::is_same<T, Ms::Spatium>::value) {
if (Ms::P_TYPE::SP_REAL == m_type || Ms::P_TYPE::REAL == m_type) {
if constexpr (std::is_same<T, Spatium>::value) {
if (P_TYPE::SP_REAL == m_type || P_TYPE::REAL == m_type) {
const qreal* pr = std::get_if<qreal>(&m_val);
assert(pr);
return pr ? Ms::Spatium(*pr) : Ms::Spatium();
return pr ? Spatium(*pr) : Spatium();
}
}
//! HACK Temporary hack for Spatium to real
if constexpr (std::is_same<T, qreal>::value) {
if (Ms::P_TYPE::SPATIUM == m_type) {
const Ms::Spatium* ps = std::get_if<Ms::Spatium>(&m_val);
if (P_TYPE::SPATIUM == m_type) {
const Spatium* ps = std::get_if<Spatium>(&m_val);
assert(ps);
return ps ? ps->val() : T();
}
@ -231,7 +232,7 @@ public:
//! HACK Temporary hack for Fraction to String
if constexpr (std::is_same<T, QString>::value) {
if (Ms::P_TYPE::FRACTION == m_type) {
if (P_TYPE::FRACTION == m_type) {
const Ms::Fraction* pf = std::get_if<Ms::Fraction>(&m_val);
assert(pf);
return pf ? pf->toString() : T();
@ -247,7 +248,6 @@ public:
qreal toReal() const { return value<qreal>(); }
double toDouble() const { return value<qreal>(); }
QString toString() const { return value<QString>(); }
Ms::Spatium toSpatium() const { return value<Ms::Spatium>(); }
Ms::Align toAlign() const { return value<Ms::Align>(); }
Ms::Direction toDirection() const { return value<Ms::Direction>(); }
@ -262,15 +262,15 @@ public:
//! NOTE compat
QVariant toQVariant() const;
static PropertyValue fromQVariant(const QVariant& v);
static PropertyValue fromQVariant(const QVariant& v, P_TYPE type);
private:
Ms::P_TYPE m_type = Ms::P_TYPE::UNDEFINED;
P_TYPE m_type = P_TYPE::UNDEFINED;
std::variant<
//base
bool, int, qreal, QString,
// geometry
PointF, SizeF, PainterPath, Ms::Spatium,
PointF, SizeF, PainterPath, Spatium,
// draw
draw::Color, Ms::Align, Ms::HPlacement, Ms::Placement, Ms::Direction,

View file

@ -60,7 +60,7 @@ void MStyle::set(const Sid t, const PropertyValue& val)
} else {
if (StyleDef::styleValues[idx].valueType() == P_TYPE::SPATIUM) {
qreal _spatium = value(Sid::spatium).toReal();
m_precomputedValues[idx] = m_values[idx].toSpatium().val() * _spatium;
m_precomputedValues[idx] = m_values[idx].value<Spatium>().val() * _spatium;
}
}
}
@ -70,7 +70,7 @@ void MStyle::precomputeValues()
qreal _spatium = value(Sid::spatium).toReal();
for (const StyleDef::StyleValue& t : StyleDef::styleValues) {
if (t.valueType() == P_TYPE::SPATIUM) {
m_precomputedValues[t.idx()] = value(t.styleIdx()).toSpatium().val() * _spatium;
m_precomputedValues[t.idx()] = value(t.styleIdx()).value<Spatium>().val() * _spatium;
}
}
}
@ -346,7 +346,7 @@ void MStyle::save(XmlWriter& xml, bool optimize)
}
P_TYPE type = st.valueType();
if (P_TYPE::SPATIUM == type) {
xml.tag(st.name(), value(idx).toSpatium().val());
xml.tag(st.name(), value(idx).value<Spatium>().val());
} else if (P_TYPE::DIRECTION == type) {
xml.tag(st.name(), int(value(idx).toDirection()));
} else if (P_TYPE::ALIGN == type) {

View file

@ -30,7 +30,7 @@
#include <QSet>
#include "libmscore/types.h"
#include "libmscore/spatium.h"
#include "types/spatium.h"
#include "property/propertyvalue.h"
#include "infrastructure/draw/geometry.h"
@ -52,12 +52,17 @@ public:
MStyle() = default;
const mu::engraving::PropertyValue& styleV(Sid idx) const { return value(idx); }
Spatium styleS(Sid idx) const { Q_ASSERT(MStyle::valueType(idx) == P_TYPE::SPATIUM); return value(idx).toSpatium(); }
qreal styleP(Sid idx) const { Q_ASSERT(MStyle::valueType(idx) == P_TYPE::SPATIUM); return pvalue(idx); }
QString styleSt(Sid idx) const { Q_ASSERT(MStyle::valueType(idx) == P_TYPE::STRING); return value(idx).toString(); }
bool styleB(Sid idx) const { Q_ASSERT(MStyle::valueType(idx) == P_TYPE::BOOL); return value(idx).toBool(); }
qreal styleD(Sid idx) const { Q_ASSERT(MStyle::valueType(idx) == P_TYPE::REAL); return value(idx).toReal(); }
int styleI(Sid idx) const { Q_ASSERT(MStyle::valueType(idx) == P_TYPE::INT); return value(idx).toInt(); }
Spatium styleS(Sid idx) const
{
Q_ASSERT(MStyle::valueType(idx) == mu::engraving::P_TYPE::SPATIUM);
return value(idx).value<Spatium>();
}
qreal styleP(Sid idx) const { Q_ASSERT(MStyle::valueType(idx) == mu::engraving::P_TYPE::SPATIUM); return pvalue(idx); }
QString styleSt(Sid idx) const { Q_ASSERT(MStyle::valueType(idx) == mu::engraving::P_TYPE::STRING); return value(idx).toString(); }
bool styleB(Sid idx) const { Q_ASSERT(MStyle::valueType(idx) == mu::engraving::P_TYPE::BOOL); return value(idx).toBool(); }
qreal styleD(Sid idx) const { Q_ASSERT(MStyle::valueType(idx) == mu::engraving::P_TYPE::REAL); return value(idx).toReal(); }
int styleI(Sid idx) const { Q_ASSERT(MStyle::valueType(idx) == mu::engraving::P_TYPE::INT); return value(idx).toInt(); }
const mu::engraving::PropertyValue& value(Sid idx) const;
qreal pvalue(Sid idx) const;
@ -75,7 +80,7 @@ public:
void precomputeValues();
static P_TYPE valueType(const Sid);
static mu::engraving::P_TYPE valueType(const Sid);
static const char* valueName(const Sid);
static Sid styleIdx(const QString& name);

View file

@ -33,7 +33,6 @@
#include "libmscore/mscore.h"
#include "libmscore/page.h"
#include "libmscore/property.h"
#include "libmscore/spatium.h"
#include "libmscore/textlinebase.h"
#include "libmscore/tuplet.h"
#include "libmscore/types.h"

View file

@ -1503,7 +1503,7 @@ private:
Sid styleIdx() const { return _idx; }
int idx() const { return int(_idx); }
const char* name() const { return _name; }
P_TYPE valueType() const { return _defaultValue.type(); }
mu::engraving::P_TYPE valueType() const { return _defaultValue.type(); }
const mu::engraving::PropertyValue& defaultValue() const { return _defaultValue; }
};

View file

@ -20,12 +20,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __SPATIUM_H__
#define __SPATIUM_H__
#ifndef MU_ENGRAVING_SPATIUM_H
#define MU_ENGRAVING_SPATIUM_H
#include <QVariant>
#include "realfn.h"
namespace Ms {
namespace mu::engraving {
//---------------------------------------------------------
// Spatium
// - a unit of measure
@ -35,63 +35,58 @@ namespace Ms {
class Spatium
{
qreal _val;
public:
constexpr Spatium()
: _val(0.0) {}
explicit Spatium(qreal v) { _val = v; }
Spatium() = default;
explicit Spatium(qreal v)
: m_val(v) {}
constexpr qreal val() const { return _val; }
constexpr qreal val() const { return m_val; }
bool operator>(const Spatium& a) const { return _val > a._val; }
bool operator<(const Spatium& a) const { return _val < a._val; }
bool operator==(const Spatium& a) const { return _val == a._val; }
bool operator!=(const Spatium& a) const { return _val != a._val; }
bool isZero() const { return _val == 0.0; }
bool operator>(const Spatium& a) const { return m_val > a.m_val; }
bool operator<(const Spatium& a) const { return m_val < a.m_val; }
bool operator==(const Spatium& a) const { return RealIsEqual(m_val, a.m_val); }
bool operator!=(const Spatium& a) const { return m_val != a.m_val; }
bool isZero() const { return RealIsNull(m_val); }
Spatium& operator+=(const Spatium& a)
{
_val += a._val;
m_val += a.m_val;
return *this;
}
Spatium& operator-=(const Spatium& a)
{
_val -= a._val;
m_val -= a.m_val;
return *this;
}
Spatium& operator/=(qreal d)
{
_val /= d;
m_val /= d;
return *this;
}
qreal operator/(const Spatium& b)
{
return _val / b._val;
return m_val / b.m_val;
}
Spatium& operator*=(int d)
{
_val *= d;
m_val *= d;
return *this;
}
Spatium& operator*=(qreal d)
{
_val *= d;
m_val *= d;
return *this;
}
Spatium operator-() const { return Spatium(-_val); }
operator QVariant() const {
return QVariant::fromValue(*this);
}
Spatium operator-() const { return Spatium(-m_val); }
double toDouble() { return _val; }
static double toDoubleStatic(const Spatium& v) { return v._val; }
private:
qreal m_val = 0.0;
};
inline Spatium operator+(const Spatium& a, const Spatium& b)
@ -142,8 +137,11 @@ inline Spatium operator*(qreal a, const Spatium& b)
r *= a;
return r;
}
} // namespace Ms
}
Q_DECLARE_METATYPE(Ms::Spatium);
//! NOTE compat
namespace Ms {
using Spatium = mu::engraving::Spatium;
}
#endif
#endif //MU_ENGRAVING_SPATIUM_H

View file

@ -0,0 +1,34 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "infrastructure/draw/color.h"
#include "spatium.h"
#ifndef MU_ENGRAVING_TYPES_H
#define MU_ENGRAVING_TYPES_H
namespace mu::engraving {
using Color = draw::Color;
}
#endif // MU_ENGRAVING_TYPES_H

View file

@ -214,8 +214,6 @@ void AbstractInspectorModel::onPropertyValueChanged(const Ms::Pid pid, const QVa
beginCommand();
QVariant convertedValue;
for (Ms::EngravingItem* element : m_elementList) {
IF_ASSERT_FAILED(element) {
continue;
@ -227,9 +225,8 @@ void AbstractInspectorModel::onPropertyValueChanged(const Ms::Pid pid, const QVa
ps = Ms::PropertyFlags::UNSTYLED;
}
convertedValue = valueToElementUnits(pid, newValue, element);
element->undoChangeProperty(pid, PropertyValue::fromQVariant(convertedValue), ps);
PropertyValue propValue = valueToElementUnits(pid, newValue, element);
element->undoChangeProperty(pid, propValue, ps);
}
updateNotation();
@ -273,7 +270,7 @@ Ms::Sid AbstractInspectorModel::styleIdByPropertyId(const Ms::Pid pid) const
void AbstractInspectorModel::updateStyleValue(const Ms::Sid& sid, const QVariant& newValue)
{
PropertyValue newVal = PropertyValue::fromQVariant(newValue);
PropertyValue newVal = PropertyValue::fromQVariant(newValue, Ms::MStyle::valueType(sid));
if (style() && style()->styleValue(sid) != newVal) {
beginCommand();
style()->setStyleValue(sid, newVal);
@ -286,51 +283,51 @@ QVariant AbstractInspectorModel::styleValue(const Ms::Sid& sid) const
return style() ? style()->styleValue(sid).toQVariant() : QVariant();
}
QVariant AbstractInspectorModel::valueToElementUnits(const Ms::Pid& pid, const QVariant& value,
const Ms::EngravingItem* element) const
PropertyValue AbstractInspectorModel::valueToElementUnits(const Ms::Pid& pid, const QVariant& value, const Ms::EngravingItem* element) const
{
switch (Ms::propertyType(pid)) {
case Ms::P_TYPE::POINT_SP:
return value.value<PointF>() * element->spatium();
auto toPoint = [](const QVariant& v) {
if (v.type() == QVariant::PointF) {
return PointF::fromQPointF(v.value<QPointF>());
}
return v.value<PointF>();
};
case Ms::P_TYPE::POINT_SP_MM: {
P_TYPE type = Ms::propertyType(pid);
switch (type) {
case P_TYPE::POINT_SP:
return toPoint(value) * element->spatium();
case P_TYPE::POINT_SP_MM: {
if (element->sizeIsSpatiumDependent()) {
return value.value<PointF>() * element->spatium();
return toPoint(value) * element->spatium();
} else {
return value.value<PointF>() * Ms::DPMM;
return toPoint(value) * Ms::DPMM;
}
}
case Ms::P_TYPE::SP_REAL:
return value.toDouble() * element->spatium();
case P_TYPE::SP_REAL:
return value.toReal() * element->spatium();
case Ms::P_TYPE::SPATIUM:
return value.value<Ms::Spatium>().val();
case P_TYPE::SPATIUM:
return Spatium(value.toReal());
case Ms::P_TYPE::TEMPO:
return value.toDouble() / 60.0;
case P_TYPE::TEMPO:
return value.toReal() / 60.0;
case Ms::P_TYPE::ZERO_INT:
case P_TYPE::ZERO_INT:
return value.toInt() - 1;
case Ms::P_TYPE::DIRECTION:
return static_cast<int>(value.value<Ms::Direction>());
case P_TYPE::DIRECTION:
return value.value<Ms::Direction>();
case Ms::P_TYPE::INT_LIST: {
QStringList strList;
case P_TYPE::INT_LIST:
return value.value<QList<int> >();
for (const int i : value.value<QList<int> >()) {
strList << QString("%1").arg(i);
}
return strList.join(",");
}
case P_TYPE::COLOR:
return Color::fromQColor(value.value<QColor>());
default:
if (value.type() == QVariant::Type::Color) {
return QVariant::fromValue(mu::draw::Color(value.value<QColor>()));
}
return value;
return PropertyValue::fromQVariant(value, type);
}
}
@ -340,10 +337,10 @@ QVariant AbstractInspectorModel::valueFromElementUnits(const Ms::Pid& pid, const
UNUSED(pid);
switch (value.type()) {
case Ms::P_TYPE::POINT_SP:
case P_TYPE::POINT_SP:
return value.value<PointF>().toQPointF() / element->spatium();
case Ms::P_TYPE::POINT_SP_MM: {
case P_TYPE::POINT_SP_MM: {
if (element->sizeIsSpatiumDependent()) {
return value.value<PointF>().toQPointF() / element->spatium();
} else {
@ -351,22 +348,22 @@ QVariant AbstractInspectorModel::valueFromElementUnits(const Ms::Pid& pid, const
}
}
case Ms::P_TYPE::SP_REAL:
case P_TYPE::SP_REAL:
return value.toReal() / element->spatium();
case Ms::P_TYPE::SPATIUM:
case P_TYPE::SPATIUM:
return value.value<Ms::Spatium>().val();
case Ms::P_TYPE::TEMPO:
case P_TYPE::TEMPO:
return value.toReal() * 60.0;
case Ms::P_TYPE::ZERO_INT:
case P_TYPE::ZERO_INT:
return value.toInt() + 1;
case Ms::P_TYPE::DIRECTION:
case P_TYPE::DIRECTION:
return static_cast<int>(value.value<Ms::Direction>());
case Ms::P_TYPE::INT_LIST: {
case P_TYPE::INT_LIST: {
QStringList strList;
for (const int i : value.value<QList<int> >()) {
@ -375,7 +372,7 @@ QVariant AbstractInspectorModel::valueFromElementUnits(const Ms::Pid& pid, const
return strList.join(",");
}
case Ms::P_TYPE::COLOR:
case P_TYPE::COLOR:
return value.value<mu::draw::Color>().toQColor();
default:
return value.toQVariant();

View file

@ -162,7 +162,7 @@ protected:
bool isNotationExisting() const;
QVariant valueToElementUnits(const Ms::Pid& pid, const QVariant& value, const Ms::EngravingItem* element) const;
engraving::PropertyValue valueToElementUnits(const Ms::Pid& pid, const QVariant& value, const Ms::EngravingItem* element) const;
QVariant valueFromElementUnits(const Ms::Pid& pid, const engraving::PropertyValue& value, const Ms::EngravingItem* element) const;
notation::INotationStylePtr style() const;

View file

@ -123,6 +123,11 @@ void BarlineSettingsModel::setSpanIntervalAsStaffDefault()
std::vector<Ms::EngravingItem*> staves;
auto undoChangeProperty = [](Ms::EngravingObject* o, Ms::Pid pid, const QVariant& val)
{
o->undoChangeProperty(pid, PropertyValue::fromQVariant(val, Ms::propertyType(pid)));
};
for (Ms::EngravingItem* item : m_elementList) {
if (!item->isBarLine()) {
continue;
@ -132,9 +137,9 @@ void BarlineSettingsModel::setSpanIntervalAsStaffDefault()
Ms::Staff* staff = barline->staff();
if (std::find(staves.cbegin(), staves.cend(), staff) == staves.cend()) {
staff->undoChangeProperty(Ms::Pid::STAFF_BARLINE_SPAN, PropertyValue::fromQVariant(m_isSpanToNextStaff->value()));
staff->undoChangeProperty(Ms::Pid::STAFF_BARLINE_SPAN_FROM, PropertyValue::fromQVariant(m_spanFrom->value()));
staff->undoChangeProperty(Ms::Pid::STAFF_BARLINE_SPAN_TO, PropertyValue::fromQVariant(m_spanTo->value()));
undoChangeProperty(staff, Ms::Pid::STAFF_BARLINE_SPAN, m_isSpanToNextStaff->value());
undoChangeProperty(staff, Ms::Pid::STAFF_BARLINE_SPAN_FROM, m_spanFrom->value());
undoChangeProperty(staff, Ms::Pid::STAFF_BARLINE_SPAN_TO, m_spanTo->value());
staves.push_back(staff);
}

View file

@ -24,15 +24,16 @@
#include "property.h"
using namespace mu::inspector;
using namespace mu::engraving;
PropertyItem::PropertyItem(const Ms::Pid propertyId, QObject* parent)
: QObject(parent), m_isVisible(true)
{
m_propertyId = propertyId;
Ms::P_TYPE propertyType = Ms::propertyType(propertyId);
P_TYPE propertyType = Ms::propertyType(propertyId);
if (propertyType != Ms::P_TYPE::COLOR) {
if (propertyType != P_TYPE::COLOR) {
m_currentValue = 0;
m_defaultValue = 0;
}

View file

@ -24,6 +24,7 @@
#include "engraving/style/style.h"
using namespace mu::notation;
using namespace mu::engraving;
AbstractStyleDialogModel::AbstractStyleDialogModel(QObject* parent, std::set<StyleId> ids)
: QObject(parent)
@ -65,8 +66,8 @@ StyleItem* AbstractStyleDialogModel::buildStyleItem(StyleId id)
QVariant AbstractStyleDialogModel::toUiValue(StyleId id, const PropertyValue& logicalValue) const
{
if (Ms::MStyle::valueType(id) == Ms::P_TYPE::SPATIUM) {
return logicalValue.value<Ms::Spatium>().toDouble();
if (Ms::MStyle::valueType(id) == P_TYPE::SPATIUM) {
return logicalValue.value<Ms::Spatium>().val();
}
return logicalValue.toQVariant();
@ -74,9 +75,9 @@ QVariant AbstractStyleDialogModel::toUiValue(StyleId id, const PropertyValue& lo
PropertyValue AbstractStyleDialogModel::fromUiValue(StyleId id, const QVariant& uiValue) const
{
if (Ms::MStyle::valueType(id) == Ms::P_TYPE::SPATIUM) {
if (Ms::MStyle::valueType(id) == P_TYPE::SPATIUM) {
return Ms::Spatium(uiValue.toDouble());
}
return PropertyValue::fromQVariant(uiValue);
return PropertyValue::fromQVariant(uiValue, Ms::MStyle::valueType(id));
}

View file

@ -46,6 +46,7 @@
#include "translation.h"
using namespace mu::notation;
using namespace mu::engraving;
using namespace mu::ui;
using namespace mu::framework;
@ -629,9 +630,9 @@ EditStyle::EditStyle(QWidget* parent)
const auto mapFunction = QOverload<>::of(&QSignalMapper::map);
for (const StyleWidget& sw : styleWidgets) {
const char* type = styleValue(sw.idx).typeName();
P_TYPE type = Ms::MStyle::valueType(sw.idx);
if (!strcmp("Direction", type)) {
if (P_TYPE::DIRECTION == type) {
QComboBox* cb = qobject_cast<QComboBox*>(sw.widget);
fillDirectionComboBox(cb);
}
@ -1351,7 +1352,7 @@ void EditStyle::on_resetStylesButton_clicked()
void EditStyle::unhandledType(const StyleWidget sw)
{
Ms::P_TYPE type = Ms::MStyle::valueType(sw.idx);
P_TYPE type = Ms::MStyle::valueType(sw.idx);
qFatal("%d <%s>: widget: %s\n", int(type), Ms::MStyle::valueName(sw.idx), sw.widget->metaObject()->className());
}
@ -1360,24 +1361,28 @@ void EditStyle::unhandledType(const StyleWidget sw)
// return current gui value
//---------------------------------------------------------
QVariant EditStyle::getValue(StyleId idx)
PropertyValue EditStyle::getValue(StyleId idx)
{
const StyleWidget& sw = styleWidget(idx);
const char* type = styleValue(sw.idx).typeName();
if (!strcmp("Ms::Spatium", type)) {
P_TYPE type = Ms::MStyle::valueType(idx);
switch (type) {
case P_TYPE::SPATIUM: {
QDoubleSpinBox* sb = qobject_cast<QDoubleSpinBox*>(sw.widget);
return QVariant(Ms::Spatium(sb->value() * (sw.showPercent ? 0.01 : 1.0)));
} else if (!strcmp("double", type)) {
return Ms::Spatium(sb->value() * (sw.showPercent ? 0.01 : 1.0));
} break;
case P_TYPE::REAL: {
QVariant v = sw.widget->property("value");
if (!v.isValid()) {
unhandledType(sw);
return PropertyValue();
}
qreal value = v.toReal();
if (sw.showPercent) {
v = v.toDouble() * 0.01;
value = value * 0.01;
}
return v;
} else if (!strcmp("bool", type)) {
return value;
} break;
case P_TYPE::BOOL: {
QVariant v;
if (sw.idx == StyleId::harmonyVoiceLiteral) { // special case for bool represented by a two-item combobox
QComboBox* cb = qobject_cast<QComboBox*>(sw.widget);
@ -1386,10 +1391,12 @@ QVariant EditStyle::getValue(StyleId idx)
v = sw.widget->property("checked");
if (!v.isValid()) {
unhandledType(sw);
return PropertyValue();
}
}
return v;
} else if (!strcmp("int", type)) {
return v.toBool();
} break;
case P_TYPE::INT: {
if (qobject_cast<QComboBox*>(sw.widget)) {
QComboBox* cb = qobject_cast<QComboBox*>(sw.widget);
return cb->currentData().toInt();
@ -1403,7 +1410,8 @@ QVariant EditStyle::getValue(StyleId idx)
} else {
qFatal("unhandled int");
}
} else if (!strcmp("QString", type)) {
} break;
case P_TYPE::STRING: {
if (qobject_cast<QFontComboBox*>(sw.widget)) {
return static_cast<QFontComboBox*>(sw.widget)->currentFont().family();
}
@ -1415,27 +1423,33 @@ QVariant EditStyle::getValue(StyleId idx)
QTextEdit* te = qobject_cast<QTextEdit*>(sw.widget);
return te->toPlainText();
}
} else if (!strcmp("mu::PointF", type)) {
} break;
case P_TYPE::POINT: {
OffsetSelect* cb = qobject_cast<OffsetSelect*>(sw.widget);
if (cb) {
return mu::PointF::fromQPointF(cb->offset());
return PointF::fromQPointF(cb->offset());
} else {
qFatal("unhandled mu::PointF");
}
} else if (!strcmp("Ms::Direction", type)) {
} break;
case P_TYPE::DIRECTION: {
QComboBox* cb = qobject_cast<QComboBox*>(sw.widget);
if (cb) {
return cb->currentIndex();
return Ms::Direction(cb->currentIndex());
} else {
qFatal("unhandled Direction");
}
} else if (!strcmp("Ms::Align", type)) {
} break;
case P_TYPE::ALIGN: {
AlignSelect* as = qobject_cast<AlignSelect*>(sw.widget);
return QVariant::fromValue(as->align());
} else {
return as->align();
} break;
default: {
qFatal("EditStyle::getValue: unhandled type <%s>", type);
} break;
}
return QVariant();
return PropertyValue();
}
//---------------------------------------------------------
@ -1448,43 +1462,49 @@ void EditStyle::setValues()
if (sw.widget) {
sw.widget->blockSignals(true);
}
QVariant val = styleValue(sw.idx);
const char* type = styleValue(sw.idx).typeName();
PropertyValue val = styleValue(sw.idx);
if (sw.reset) {
sw.reset->setEnabled(hasDefaultStyleValue(sw.idx));
}
if (!strcmp("Ms::Spatium", type)) {
switch (val.type()) {
case P_TYPE::SPATIUM: {
qreal value = val.value<Spatium>().val();
if (sw.showPercent) {
qobject_cast<QSpinBox*>(sw.widget)->setValue(int(val.value<Ms::Spatium>().val() * 100.0));
qobject_cast<QSpinBox*>(sw.widget)->setValue(int(value * 100.0));
} else {
sw.widget->setProperty("value", val);
sw.widget->setProperty("value", value);
}
} else if (!strcmp("double", type)) {
} break;
case P_TYPE::REAL: {
qreal value = val.toReal();
if (sw.showPercent) {
val = QVariant(val.toDouble() * 100);
value = value * 100;
}
if (!sw.widget->setProperty("value", val)) {
if (!sw.widget->setProperty("value", value)) {
unhandledType(sw);
}
} else if (!strcmp("bool", type)) {
} break;
case P_TYPE::BOOL: {
bool value = val.toBool();
if (sw.idx == StyleId::harmonyVoiceLiteral) { // special case for bool represented by a two-item combobox
voicingSelectWidget->interpretBox->setCurrentIndex(val.toBool());
voicingSelectWidget->interpretBox->setCurrentIndex(value);
} else {
if (!sw.widget->setProperty("checked", val)) {
if (!sw.widget->setProperty("checked", value)) {
unhandledType(sw);
}
if (sw.idx == StyleId::measureNumberSystem && !val.toBool()) {
if (sw.idx == StyleId::measureNumberSystem && !value) {
showIntervalMeasureNumber->setChecked(true);
}
}
} else if (!strcmp("int", type)) {
} break;
case P_TYPE::INT: {
int value = val.toInt();
if (qobject_cast<QComboBox*>(sw.widget)) {
QComboBox* cb = qobject_cast<QComboBox*>(sw.widget);
cb->setCurrentIndex(cb->findData(val));
cb->setCurrentIndex(cb->findData(value));
} else if (qobject_cast<QSpinBox*>(sw.widget)) {
qobject_cast<QSpinBox*>(sw.widget)->setValue(val.toInt()
* (sw.showPercent ? 100 : 1));
qobject_cast<QSpinBox*>(sw.widget)->setValue(value * (sw.showPercent ? 100 : 1));
} else if (qobject_cast<QButtonGroup*>(sw.widget)) {
QButtonGroup* bg = qobject_cast<QButtonGroup*>(sw.widget);
for (auto a : bg->buttons()) {
@ -1494,43 +1514,50 @@ void EditStyle::setValues()
}
}
} else if (FontStyleSelect* fontStyle = qobject_cast<FontStyleSelect*>(sw.widget)) {
fontStyle->setFontStyle(Ms::FontStyle(val.toInt()));
fontStyle->setFontStyle(Ms::FontStyle(value));
} else {
unhandledType(sw);
}
} else if (!strcmp("QString", type)) {
} break;
case P_TYPE::STRING: {
QString value = val.toString();
if (qobject_cast<QFontComboBox*>(sw.widget)) {
static_cast<QFontComboBox*>(sw.widget)->setCurrentFont(QFont(val.toString()));
static_cast<QFontComboBox*>(sw.widget)->setCurrentFont(QFont(value));
} else if (qobject_cast<QComboBox*>(sw.widget)) {
QComboBox* cb = qobject_cast<QComboBox*>(sw.widget);
for (int i = 0; i < cb->count(); ++i) {
if (cb->itemData(i) == val.toString()) {
if (cb->itemData(i) == value) {
cb->setCurrentIndex(i);
break;
}
}
} else if (qobject_cast<QTextEdit*>(sw.widget)) {
static_cast<QTextEdit*>(sw.widget)->setPlainText(val.toString());
static_cast<QTextEdit*>(sw.widget)->setPlainText(value);
} else {
unhandledType(sw);
}
} else if (!strcmp("Ms::Direction", type)) {
} break;
case P_TYPE::DIRECTION: {
QComboBox* cb = qobject_cast<QComboBox*>(sw.widget);
if (cb) {
cb->setCurrentIndex(int(val.value<Ms::Direction>()));
} else {
unhandledType(sw);
}
} else if (!strcmp("Ms::Align", type)) {
} break;
case P_TYPE::ALIGN: {
AlignSelect* as = qobject_cast<AlignSelect*>(sw.widget);
as->setAlign(val.value<Ms::Align>());
} else if (!strcmp("mu::PointF", type)) {
} break;
case P_TYPE::POINT: {
OffsetSelect* as = qobject_cast<OffsetSelect*>(sw.widget);
if (as) {
as->setOffset(val.value<mu::PointF>().toQPointF());
}
} else {
} break;
default: {
unhandledType(sw);
} break;
}
if (sw.widget) {
@ -1648,17 +1675,17 @@ void EditStyle::setSwingParams(bool checked)
swingBox->setEnabled(true);
}
setStyleValue(StyleId::swingUnit, val);
setStyleQVariantValue(StyleId::swingUnit, val);
}
QVariant EditStyle::styleValue(StyleId id) const
PropertyValue EditStyle::styleValue(StyleId id) const
{
return globalContext()->currentNotation()->style()->styleValue(id).toQVariant();
return globalContext()->currentNotation()->style()->styleValue(id);
}
QVariant EditStyle::defaultStyleValue(StyleId id) const
PropertyValue EditStyle::defaultStyleValue(StyleId id) const
{
return globalContext()->currentNotation()->style()->defaultStyleValue(id).toQVariant();
return globalContext()->currentNotation()->style()->defaultStyleValue(id);
}
bool EditStyle::hasDefaultStyleValue(StyleId id) const
@ -1666,9 +1693,14 @@ bool EditStyle::hasDefaultStyleValue(StyleId id) const
return defaultStyleValue(id) == styleValue(id);
}
void EditStyle::setStyleValue(StyleId id, const QVariant& value)
void EditStyle::setStyleQVariantValue(StyleId id, const QVariant& value)
{
globalContext()->currentNotation()->style()->setStyleValue(id, PropertyValue::fromQVariant(value));
setStyleValue(id, PropertyValue::fromQVariant(value, Ms::MStyle::valueType(id)));
}
void EditStyle::setStyleValue(StyleId id, const PropertyValue& value)
{
globalContext()->currentNotation()->style()->setStyleValue(id, value);
}
//---------------------------------------------------------
@ -1713,7 +1745,7 @@ void EditStyle::setChordStyle(bool checked)
}
setStyleValue(StyleId::chordsXmlFile, chordsXml);
setStyleValue(StyleId::chordStyle, val);
setStyleQVariantValue(StyleId::chordStyle, val);
if (!file.isEmpty()) {
setStyleValue(StyleId::chordDescriptionFile, file);
@ -1851,12 +1883,7 @@ const EditStyle::StyleWidget& EditStyle::styleWidget(StyleId idx) const
return sw;
}
}
#if (!defined (_MSCVER) && !defined (_MSC_VER))
__builtin_unreachable();
#else
// The MSVC __assume() optimizer hint is similar, though not identical, to __builtin_unreachable()
__assume(0);
#endif
UNREACHABLE;
}
//---------------------------------------------------------
@ -1866,13 +1893,13 @@ const EditStyle::StyleWidget& EditStyle::styleWidget(StyleId idx) const
void EditStyle::valueChanged(int i)
{
StyleId idx = (StyleId)i;
QVariant val = getValue(idx);
PropertyValue val = getValue(idx);
bool setValue = false;
if (idx == StyleId::MusicalSymbolFont && optimizeStyleCheckbox->isChecked()) {
Ms::ScoreFont* scoreFont = Ms::ScoreFont::fontByName(val.toString());
if (scoreFont) {
for (auto j : scoreFont->engravingDefaults()) {
setStyleValue(j.first, j.second);
setStyleQVariantValue(j.first, j.second);
}
// fix values, the distances are defined different in MuseScore
@ -1936,7 +1963,7 @@ void EditStyle::textStyleChanged(int row)
for (const Ms::StyledProperty& a : *ts) {
switch (a.pid) {
case Ms::Pid::FONT_FACE: {
QVariant val = styleValue(a.sid);
PropertyValue val = styleValue(a.sid);
textStyleFontFace->setCurrentFont(QFont(val.toString()));
resetTextStyleFontFace->setEnabled(val != defaultStyleValue(a.sid));
}
@ -1963,12 +1990,12 @@ void EditStyle::textStyleChanged(int row)
break;
case Ms::Pid::OFFSET:
textStyleOffset->setOffset(styleValue(a.sid).toPointF());
textStyleOffset->setOffset(styleValue(a.sid).value<PointF>().toQPointF());
resetTextStyleOffset->setEnabled(styleValue(a.sid) != defaultStyleValue(a.sid));
break;
case Ms::Pid::SIZE_SPATIUM_DEPENDENT: {
QVariant val = styleValue(a.sid);
PropertyValue val = styleValue(a.sid);
textStyleSpatiumDependent->setChecked(val.toBool());
resetTextStyleSpatiumDependent->setEnabled(val != defaultStyleValue(a.sid));
textStyleOffset->setSuffix(val.toBool() ? tr("sp") : tr("mm"));
@ -1997,17 +2024,17 @@ void EditStyle::textStyleChanged(int row)
break;
case Ms::Pid::FRAME_FG_COLOR:
textStyleFrameForeground->setColor(styleValue(a.sid).value<QColor>());
textStyleFrameForeground->setColor(styleValue(a.sid).value<Color>().toQColor());
resetTextStyleFrameForeground->setEnabled(styleValue(a.sid) != defaultStyleValue(a.sid));
break;
case Ms::Pid::FRAME_BG_COLOR:
textStyleFrameBackground->setColor(styleValue(a.sid).value<QColor>());
textStyleFrameBackground->setColor(styleValue(a.sid).value<Color>().toQColor());
resetTextStyleFrameBackground->setEnabled(styleValue(a.sid) != defaultStyleValue(a.sid));
break;
case Ms::Pid::COLOR:
textStyleColor->setColor(styleValue(a.sid).value<QColor>());
textStyleColor->setColor(styleValue(a.sid).value<Color>().toQColor());
resetTextStyleColor->setEnabled(styleValue(a.sid) != defaultStyleValue(a.sid));
break;
@ -2032,7 +2059,7 @@ void EditStyle::textStyleValueChanged(Ms::Pid pid, QVariant value)
for (const Ms::StyledProperty& a : *ts) {
if (a.pid == pid) {
setStyleValue(a.sid, value);
setStyleQVariantValue(a.sid, value);
break;
}
}

View file

@ -84,13 +84,14 @@ private:
QPushButton* buttonApplyToAllParts = nullptr;
void unhandledType(const StyleWidget);
QVariant getValue(StyleId idx);
PropertyValue getValue(StyleId idx);
void setValues();
QVariant styleValue(StyleId id) const;
QVariant defaultStyleValue(StyleId id) const;
PropertyValue styleValue(StyleId id) const;
PropertyValue defaultStyleValue(StyleId id) const;
bool hasDefaultStyleValue(StyleId id) const;
void setStyleValue(StyleId id, const QVariant& value);
void setStyleQVariantValue(StyleId id, const QVariant& value);
void setStyleValue(StyleId id, const PropertyValue& value);
int numberOfPage;
int pageListMap[50];

View file

@ -129,9 +129,6 @@ void ScoreElement::set(Ms::Pid pid, QVariant val)
case P_TYPE::SP_REAL:
val = val.toReal() * spatium();
break;
case P_TYPE::SPATIUM:
val = QVariant::fromValue(Spatium(val.toReal()));
break;
default:
break;
}
@ -140,9 +137,9 @@ void ScoreElement::set(Ms::Pid pid, QVariant val)
const PropertyFlags newFlags = (f == PropertyFlags::NOSTYLE) ? f : PropertyFlags::UNSTYLED;
if (_ownership == Ownership::SCORE) {
e->undoChangeProperty(pid, PropertyValue::fromQVariant(val), newFlags);
e->undoChangeProperty(pid, PropertyValue::fromQVariant(val, propertyType(pid)), newFlags);
} else { // not added to a score so no need (and dangerous) to deal with undo stack
e->setProperty(pid, PropertyValue::fromQVariant(val));
e->setProperty(pid, PropertyValue::fromQVariant(val, propertyType(pid)));
e->setPropertyFlags(pid, newFlags);
}
}

View file

@ -27,6 +27,8 @@
#include "libmscore/masterscore.h"
using namespace mu::engraving;
namespace Ms {
namespace PluginAPI {
//---------------------------------------------------------
@ -76,13 +78,8 @@ QVariant MStyle::value(const QString& key) const
return QVariant();
}
const QVariant val = _style->value(sid).toQVariant();
if (Ms::MStyle::valueType(sid) == P_TYPE::SPATIUM) {
return val.value<Ms::Spatium>().val();
}
return val;
const PropertyValue val = _style->value(sid);
return val.toQVariant();
}
//---------------------------------------------------------
@ -99,16 +96,12 @@ void MStyle::setValue(const QString& key, QVariant value)
return;
}
if (Ms::MStyle::valueType(sid) == P_TYPE::SPATIUM) {
value = QVariant::fromValue(Ms::Spatium(value.toReal()));
}
if (_score) {
// Style belongs to actual score: change style value in undoable way
_score->undoChangeStyleVal(sid, mu::engraving::PropertyValue::fromQVariant(value));
_score->undoChangeStyleVal(sid, PropertyValue::fromQVariant(value, Ms::MStyle::valueType(sid)));
} else {
// Style is not bound to a score: change the value directly
_style->set(sid, mu::engraving::PropertyValue::fromQVariant(value));
_style->set(sid, PropertyValue::fromQVariant(value, Ms::MStyle::valueType(sid)));
}
}
} // namespace PluginAPI