Skip to content
Permalink
Browse files

fix #287852, fix #287839, fix #287885, fix #287807: issues with staff…

…type
  • Loading branch information...
MarcSabatella committed Apr 17, 2019
1 parent 98b0d26 commit dee866205c50b999706fe1caf0be5ad0f3399908
Showing with 106 additions and 36 deletions.
  1. +43 −13 libmscore/measure.cpp
  2. +43 −12 libmscore/staff.cpp
  3. +2 −1 libmscore/staff.h
  4. +17 −9 libmscore/stafftypechange.cpp
  5. +1 −1 libmscore/stafftypelist.h
@@ -884,6 +884,34 @@ void Measure::add(Element* e)
_mmRest = toMeasure(e);
break;

case ElementType::STAFFTYPE_CHANGE:
{
StaffTypeChange* stc = toStaffTypeChange(e);
Staff* staff = stc->staff();
const StaffType* st = stc->staffType();
StaffType* nst;
// st needs to point to the stafftype element within the stafftypelist for the staff
if (st) {
// executed on read, undo/redo, clone
// setStaffType adds a copy to list and returns a pointer to that element within list
// we won't need the original after that
// this requires that st was allocated via new to begin with!
nst = staff->setStaffType(tick(), *st);
delete st;
}
else {
// executed on add from palette
// staffType returns a pointer to the current stafftype element in the list
// setStaffType will make a copy and return a pointer to that element within list
st = staff->staffType(tick());
nst = staff->setStaffType(tick(), *st);
}
staff->staffTypeListChanged(tick());
stc->setStaffType(nst);
MeasureBase::add(e);
}
break;

default:
MeasureBase::add(e);
break;
@@ -964,6 +992,21 @@ void Measure::remove(Element* e)
_mmRest = 0;
break;

case ElementType::STAFFTYPE_CHANGE:
{
StaffTypeChange* stc = toStaffTypeChange(e);
Staff* staff = stc->staff();
if (staff) {
// st currently points to an list element that is about to be removed
// make a copy now to use on undo/redo
StaffType* st = new StaffType(*stc->staffType());
staff->removeStaffType(tick());
stc->setStaffType(st);
}
MeasureBase::remove(e);
}
break;

default:
MeasureBase::remove(e);
break;
@@ -1611,21 +1654,8 @@ Element* Measure::drop(EditData& data)

case ElementType::STAFFTYPE_CHANGE:
{
StaffTypeChange* stc = toStaffTypeChange(e);
e->setParent(this);
e->setTrack(staffIdx * VOICES);
const StaffType* st = stc->staffType();
StaffType* nst;
if (st) {
nst = staff->setStaffType(tick(), *st);
delete st;
}
else {
// dragged from palette
st = staff->staffType(tick());
nst = staff->setStaffType(tick(), *st);
}
stc->setStaffType(nst);
score()->undoAddElement(e);
}
break;
@@ -992,11 +992,16 @@ void Staff::staffTypeListChanged(const Fraction& tick)
{
score()->setLayout(tick);
auto i = _staffTypeList.find(tick.ticks());
++i;
if (i != _staffTypeList.end())
score()->setLayout(Fraction::fromTicks(i->first));
else
score()->setLayout(score()->lastMeasure()->endTick());
if (i == _staffTypeList.end()) {
score()->setLayoutAll();
}
else {
++i;
if (i != _staffTypeList.end())
score()->setLayout(Fraction::fromTicks(i->first));
else
score()->setLayout(score()->lastMeasure()->endTick());
}
}

//---------------------------------------------------------
@@ -1008,6 +1013,21 @@ StaffType* Staff::setStaffType(const Fraction& tick, const StaffType& nst)
return _staffTypeList.setStaffType(tick, nst);
}

//---------------------------------------------------------
// setStaffType
//---------------------------------------------------------

void Staff::removeStaffType(const Fraction& tick)
{
auto i = _staffTypeList.find(tick.ticks());
if (i == _staffTypeList.end())
return;
qreal old = spatium(tick);
_staffTypeList.erase(i);
localSpatiumChanged(old, spatium(tick), tick);
staffTypeListChanged(tick);
}

//---------------------------------------------------------
// init
//---------------------------------------------------------
@@ -1280,13 +1300,16 @@ QVariant Staff::getProperty(Pid id) const
bool Staff::setProperty(Pid id, const QVariant& v)
{
switch (id) {
case Pid::SMALL:
case Pid::SMALL: {
qreal _spatium = spatium(Fraction(0,1));
setSmall(Fraction(0,1), v.toBool());
localSpatiumChanged(_spatium, spatium(Fraction(0,1)), Fraction(0, 1));
break;
}
case Pid::MAG: {
qreal _spatium = spatium(Fraction(0,1));
setUserMag(Fraction(0,1), v.toReal());
score()->spatiumChanged(_spatium, spatium(Fraction(0,1)));
localSpatiumChanged(_spatium, spatium(Fraction(0,1)), Fraction(0, 1));
}
break;
case Pid::COLOR:
@@ -1374,24 +1397,32 @@ QVariant Staff::propertyDefault(Pid id) const
}

//---------------------------------------------------------
// scaleChanged
// localSpatiumChanged
//---------------------------------------------------------

void Staff::scaleChanged(double oldVal, double newVal)
void Staff::localSpatiumChanged(double oldVal, double newVal, Fraction tick)
{
Fraction etick;
auto i = _staffTypeList.find(tick.ticks());
++i;
if (i == _staffTypeList.end())
etick = score()->lastSegment()->tick();
else
etick = Fraction::fromTicks(i->first);
int staffIdx = idx();
int startTrack = staffIdx * VOICES;
int endTrack = startTrack + VOICES;
for (Segment* s = score()->firstSegment(SegmentType::All); s; s = s->next1()) {
for (Segment* s = score()->tick2rightSegment(tick); s && s->tick() < etick; s = s->next1()) {
for (Element* e : s->annotations())
e->localSpatiumChanged(oldVal, newVal);
for (int track = startTrack; track < endTrack; ++track) {
if (s->element(track))
s->element(track)->localSpatiumChanged(oldVal, newVal);
}
}
for (auto i : score()->spanner()) {
Spanner* spanner = i.second;
auto spanners = score()->spannerMap().findContained(tick.ticks(), etick.ticks());
for (auto interval : spanners) {
Spanner* spanner = interval.value;
if (spanner->staffIdx() == staffIdx) {
for (auto k : spanner->spannerSegments())
k->localSpatiumChanged(oldVal, newVal);
@@ -96,7 +96,6 @@ class Staff final : public ScoreElement {
VeloList _velocities; ///< cached value
PitchList _pitchOffsets; ///< cached value

void scaleChanged(double oldValue, double newValue);
void fillBrackets(int);
void cleanBrackets();

@@ -201,6 +200,7 @@ class Staff final : public ScoreElement {
const StaffType* constStaffType(const Fraction&) const;
StaffType* staffType(const Fraction&);
StaffType* setStaffType(const Fraction&, const StaffType&);
void removeStaffType(const Fraction&);
void staffTypeListChanged(const Fraction&);

bool isPitchedStaff(const Fraction&) const;
@@ -236,6 +236,7 @@ class Staff final : public ScoreElement {
void setUserDist(qreal val) { _userDist = val; }

void spatiumChanged(qreal /*oldValue*/, qreal /*newValue*/);
void localSpatiumChanged(double oldVal, double newVal, Fraction tick);
bool genKeySig();
bool showLedgerLines(const Fraction&) const;

@@ -58,12 +58,10 @@ void StaffTypeChange::read(XmlReader& e)
while (e.readNextStartElement()) {
const QStringRef& tag(e.name());
if (tag == "StaffType") {
StaffType st;
st.read(e);
if (staff())
_staffType = staff()->setStaffType(measure()->tick(), st);
else
_staffType = new StaffType(st); // drag&drop operation
StaffType* st = new StaffType();
st->read(e);
// Measure::add() will replace this with a pointer to a copy in the staff
_staffType = st;
}
else if (!Element::readProperties(e))
e.unknown();
@@ -85,7 +83,7 @@ void StaffTypeChange::spatiumChanged(qreal, qreal)

void StaffTypeChange::layout()
{
qreal _spatium = spatium();
qreal _spatium = score()->spatium();
setbbox(QRectF(-lw*.5, -lw*.5, _spatium * 2.5 + lw, _spatium*2.5 + lw));
if (measure()) {
qreal y = -1.5 * _spatium - height() + measure()->system()->staff(staffIdx())->y();
@@ -190,11 +188,21 @@ bool StaffTypeChange::setProperty(Pid propertyId, const QVariant& v)
case Pid::STAFF_GEN_KEYSIG:
_staffType->setGenKeysig(v.toBool());
break;
case Pid::MAG:
case Pid::MAG: {
qreal _spatium = spatium();
_staffType->setUserMag(v.toDouble());
Staff* _staff = staff();
if (_staff)
_staff->localSpatiumChanged(_spatium, spatium(), tick());
}
break;
case Pid::SMALL:
case Pid::SMALL: {
qreal _spatium = spatium();
_staffType->setSmall(v.toBool());
Staff* _staff = staff();
if (_staff)
_staff->localSpatiumChanged(_spatium, spatium(), tick());
}
break;
case Pid::STAFF_YOFFSET:
_staffType->setYoffset(v.value<Spatium>());
@@ -22,7 +22,7 @@ class XmlReader;
//---------------------------------------------------------
// StaffTypeList
// this list is instantiated for every staff
// to keep track of key signature changes
// to keep track of staff type changes
//---------------------------------------------------------

class StaffTypeList : public std::map<int, StaffType> {

0 comments on commit dee8662

Please sign in to comment.
You can’t perform that action at this time.