Skip to content

Commit

Permalink
Remove partial ties on repeat structure change
Browse files Browse the repository at this point in the history
  • Loading branch information
miiizen committed Dec 30, 2024
1 parent cc454db commit ea6001f
Show file tree
Hide file tree
Showing 17 changed files with 94 additions and 101 deletions.
14 changes: 0 additions & 14 deletions src/engraving/dom/barline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,20 +271,6 @@ static void undoChangeBarLineType(BarLine* bl, BarLineType barType, bool allStav
}
break;
}

if ((prevBarType == BarLineType::END_REPEAT || prevBarType == BarLineType::END_START_REPEAT)
&& !(barType == BarLineType::END_REPEAT || prevBarType == BarLineType::END_START_REPEAT)) {
// Remove outgoing partial tie & endpoints
m->removePartialTiesOnRepeatChange(true);
}
if ((prevBarType == BarLineType::START_REPEAT || prevBarType == BarLineType::END_START_REPEAT)
&& !(barType == BarLineType::START_REPEAT || prevBarType == BarLineType::END_START_REPEAT)) {
// Remove incoming partial tie
Measure* nextMeasure = m->nextMeasure();
if (nextMeasure) {
nextMeasure->removePartialTiesOnRepeatChange(false);
}
}
}

//---------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/engraving/dom/cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1694,7 +1694,7 @@ void Score::changeCRlen(ChordRest* cr, const Fraction& dstF, bool fillWithRest)
for (Note* n : c->notes()) {
if (Tie* tie = n->tieFor()) {
if (tie->tieJumpPoints()) {
tie->removeTiesFromJumpPoints();
tie->undoRemoveTiesFromJumpPoints();
}
undoRemoveElement(tie);
}
Expand Down
64 changes: 57 additions & 7 deletions src/engraving/dom/edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2764,7 +2764,6 @@ void Score::deleteItem(EngravingItem* el)
Measure* lmeasure = lscore->tick2measure(m2->tick());
if (lmeasure) {
lmeasure->undoChangeProperty(Pid::REPEAT_START, false);
lmeasure->removePartialTiesOnRepeatChange(false);
}
}
} else if (bl->barLineType() == BarLineType::END_REPEAT) {
Expand All @@ -2773,7 +2772,6 @@ void Score::deleteItem(EngravingItem* el)
Measure* lmeasure = lscore->tick2measure(m2->tick());
if (lmeasure) {
lmeasure->undoChangeProperty(Pid::REPEAT_END, false);
lmeasure->removePartialTiesOnRepeatChange(true);
}
}
} else {
Expand Down Expand Up @@ -2922,17 +2920,13 @@ void Score::deleteItem(EngravingItem* el)
if (el->isTie()) {
Tie* tie = toTie(el);
if (tie->tieJumpPoints()) {
tie->removeTiesFromJumpPoints();
tie->undoRemoveTiesFromJumpPoints();
}
if (tie->jumpPoint()) {
tie->updateStartTieOnRemoval();
}
}

if (el->isVolta()) {
toVolta(el)->startMeasure()->removePartialTiesOnRepeatChange(false);
}

undoRemoveElement(el);
}
break;
Expand Down Expand Up @@ -7175,4 +7169,60 @@ void Score::undoChangeMeasureRepeatCount(Measure* m, int newCount, staff_idx_t s
}
}
}

void Score::doUndoRemoveStaleTieJumpPoints(Tie* tie)
{
std::vector<Tie*> oldTies;
for (TieJumpPoint* jumpPoint : *tie->tieJumpPoints()) {
if (jumpPoint->followingNote()) {
continue;
}
oldTies.push_back(jumpPoint->endTie());
}

tie->updatePossibleJumpPoints();

for (Tie* oldTie : oldTies) {
auto findEndTie = [&oldTie](const TieJumpPoint* jumpPoint) {
return jumpPoint->endTie() == oldTie;
};

if (std::find_if((*tie->tieJumpPoints()).begin(), (*tie->tieJumpPoints()).end(),
findEndTie) != (*tie->tieJumpPoints()).end()) {
continue;
}
startCmd(TranslatableString("engraving", "Remove stale partial tie"));
undoRemoveElement(oldTie);
endCmd();
// These changes should be merged with the change in repeat structure which caused the ties to become invalid
undoStack()->mergeCommands(undoStack()->currentIndex() - 2);
}
}

void Score::undoRemoveStaleTieJumpPoints()
{
size_t tracks = nstaves() * VOICES;
Measure* m = firstMeasure();
if (!m) {
return;
}

SegmentType st = SegmentType::ChordRest;
for (Segment* s = m->first(st); s; s = s->next1(st)) {
for (track_idx_t i = 0; i < tracks; ++i) {
EngravingItem* e = s->element(i);
if (e == 0 || !e->isChord()) {
continue;
}
Chord* c = toChord(e);
for (Note* n : c->notes()) {
if (!n->tieFor()) {
continue;
}

doUndoRemoveStaleTieJumpPoints(n->tieFor());
}
}
}
}
}
2 changes: 1 addition & 1 deletion src/engraving/dom/excerpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ static void collectTieEndPoints(TieMap& tieMap)
for (auto& tie : tieMap) {
Tie* newTie = toTie(tie.second);
if (newTie->type() == ElementType::TIE || (newTie->type() == ElementType::PARTIAL_TIE && toPartialTie(newTie)->isOutgoing())) {
newTie->collectPossibleJumpPoints();
newTie->updatePossibleJumpPoints();
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/engraving/dom/masterscore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,14 @@ const RepeatList& MasterScore::repeatList() const
return *m_nonExpandedRepeatList;
}

const RepeatList& MasterScore::repeatList(bool expandRepeats) const
const RepeatList& MasterScore::repeatList(bool expandRepeats, bool updateTies) const
{
if (expandRepeats) {
m_expandedRepeatList->update(true);
m_expandedRepeatList->update(true, updateTies);
return *m_expandedRepeatList;
}

m_nonExpandedRepeatList->update(false);
m_nonExpandedRepeatList->update(false, updateTies);
return *m_nonExpandedRepeatList;
}

Expand Down
3 changes: 2 additions & 1 deletion src/engraving/dom/masterscore.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,9 @@ class MasterScore : public Score

void updateRepeatListTempo();
void updateRepeatList();

const RepeatList& repeatList() const override;
const RepeatList& repeatList(bool expandRepeats) const override;
const RepeatList& repeatList(bool expandRepeats, bool updateTies = true) const override;

std::vector<Excerpt*>& excerpts() { return m_excerpts; }
const std::vector<Excerpt*>& excerpts() const { return m_excerpts; }
Expand Down
38 changes: 2 additions & 36 deletions src/engraving/dom/measure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -940,16 +940,10 @@ void Measure::remove(EngravingItem* e)
}
break;

case ElementType::MARKER:
removePartialTiesOnRepeatChange(muse::contains(Marker::RIGHT_MARKERS, toMarker(e)->markerType()));

if (!el().remove(e)) {
LOGD("Measure(%p)::remove(%s,%p) not found", this, e->typeName(), e);
}
break;
case ElementType::JUMP:
removePartialTiesOnRepeatChange(true);
setRepeatJump(false);
// fall through
case ElementType::MARKER:
case ElementType::HBOX:
if (!el().remove(e)) {
LOGD("Measure(%p)::remove(%s,%p) not found", this, e->typeName(), e);
Expand Down Expand Up @@ -1030,34 +1024,6 @@ void Measure::spatiumChanged(double /*oldValue*/, double /*newValue*/)
{
}

void Measure::removePartialTiesOnRepeatChange(bool outgoing)
{
Segment* seg = first(SegmentType::ChordRest);
while (seg) {
for (EngravingItem* item : seg->elist()) {
if (!item || !item->isChord()) {
continue;
}

Chord* chord = toChord(item);

for (Note* note : chord->notes()) {
Tie* tie = outgoing ? note->tieFor() : note->tieBack();
if (!tie) {
continue;
}

if (outgoing) {
tie->removeTiesFromJumpPoints();
} else if (tie->isPartialTie()) {
score()->doUndoRemoveElement(tie);
}
}
}
seg = seg->next(SegmentType::ChordRest);
}
}

//-------------------------------------------------------------------
// moveTicks
// Also adjust endBarLine if measure len has changed. For this
Expand Down
2 changes: 0 additions & 2 deletions src/engraving/dom/measure.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,6 @@ class Measure final : public MeasureBase
void change(EngravingItem* o, EngravingItem* n) override;
void spatiumChanged(double oldValue, double newValue) override;

void removePartialTiesOnRepeatChange(bool outgoing);

System* system() const { return toSystem(explicitParent()); }
bool hasVoices(staff_idx_t staffIdx, Fraction stick, Fraction len, bool considerInvisible = false) const;
bool hasVoices(staff_idx_t staffIdx) const;
Expand Down
6 changes: 5 additions & 1 deletion src/engraving/dom/repeatlist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ int RepeatList::ticks() const
// update
//---------------------------------------------------------

void RepeatList::update(bool expand)
void RepeatList::update(bool expand, bool updateTies)
{
if (!m_scoreChanged && expand == m_expanded) {
return;
Expand All @@ -171,6 +171,10 @@ void RepeatList::update(bool expand)
}

m_scoreChanged = false;

if (updateTies) {
m_score->undoRemoveStaleTieJumpPoints();
}
}

//---------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/engraving/dom/repeatlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ class RepeatList : public std::vector<RepeatSegment*>
RepeatList& operator=(const RepeatList&) = delete;
~RepeatList();

void update(bool expand);
void update(bool expand, bool updateTies = true);
void setScoreChanged() { m_scoreChanged = true; }
const Score* score() const { return m_score; }

Expand Down
8 changes: 6 additions & 2 deletions src/engraving/dom/score.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5742,7 +5742,7 @@ void Score::connectTies(bool silent)
// connect a tie without end note
Tie* tie = n->tieFor();
if (tie) {
tie->collectPossibleJumpPoints();
tie->updatePossibleJumpPoints();
}
if (tie && !tie->isPartialTie() && !tie->endNote()) {
Note* nnote;
Expand Down Expand Up @@ -6076,7 +6076,11 @@ void Score::updateChannel()

UndoStack* Score::undoStack() const { return m_masterScore->undoStack(); }
const RepeatList& Score::repeatList() const { return m_masterScore->repeatList(); }
const RepeatList& Score::repeatList(bool expandRepeats) const { return m_masterScore->repeatList(expandRepeats); }
const RepeatList& Score::repeatList(bool expandRepeats, bool updateTies) const
{
return m_masterScore->repeatList(expandRepeats, updateTies);
}

TempoMap* Score::tempomap() const { return m_masterScore->tempomap(); }
TimeSigMap* Score::sigmap() const { return m_masterScore->sigmap(); }
//QQueue<MidiInputEvent>* Score::midiInputQueue() { return _masterScore->midiInputQueue(); }
Expand Down
4 changes: 3 additions & 1 deletion src/engraving/dom/score.h
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,7 @@ class Score : public EngravingObject, public muse::Injectable
/// where those need to have the same value for expandRepeats.
virtual const RepeatList& repeatList() const;
/// For small, one-step operations, where you need to get the relevant repeatList just once
virtual const RepeatList& repeatList(bool expandRepeats) const;
virtual const RepeatList& repeatList(bool expandRepeats, bool updateTies = true) const;

double utick2utime(int tick) const;
int utime2utick(double utime) const;
Expand Down Expand Up @@ -803,6 +803,8 @@ class Score : public EngravingObject, public muse::Injectable
Segment* lastSegmentMM() const;

void connectTies(bool silent = false);
void undoRemoveStaleTieJumpPoints();
void doUndoRemoveStaleTieJumpPoints(Tie* tie);

void scanElementsInRange(void* data, void (* func)(void*, EngravingItem*), bool all = true);
int fileDivision() const { return m_fileDivision; } ///< division of current loading *.msc file
Expand Down
31 changes: 8 additions & 23 deletions src/engraving/dom/tie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,9 @@ Tie::Tie(const ElementType& type, EngravingItem* parent)
setAnchor(Anchor::NOTE);
}

void Tie::collectPossibleJumpPoints()
void Tie::updatePossibleJumpPoints()
{
const MasterScore* master = masterScore();
MasterScore* master = masterScore();
const Note* note = toNote(parentItem());
const Chord* chord = note->chord();
const Measure* measure = chord->measure();
Expand All @@ -227,11 +227,6 @@ void Tie::collectPossibleJumpPoints()
return;
}

std::vector<Tie*> oldTies;
for (TieJumpPoint* jumpPoint : *tieJumpPoints()) {
oldTies.push_back(jumpPoint->endTie());
}

tieJumpPoints()->clear();

if (!startNote()->hasFollowingJumpItem()) {
Expand All @@ -251,7 +246,7 @@ void Tie::collectPossibleJumpPoints()
}

// Get following notes by taking repeats
const RepeatList& repeatList = master->repeatList();
const RepeatList& repeatList = master->repeatList(true, false);

for (auto it = repeatList.begin(); it != repeatList.end(); it++) {
const RepeatSegment* rs = *it;
Expand Down Expand Up @@ -279,16 +274,6 @@ void Tie::collectPossibleJumpPoints()
jumpPointIdx++;
}
}
for (Tie* tie : oldTies) {
auto findEndTie = [&tie](const TieJumpPoint* jumpPoint){
return jumpPoint->endTie() == tie;
};

if (std::find_if((*tieJumpPoints()).begin(), (*tieJumpPoints()).end(), findEndTie) != (*tieJumpPoints()).end()) {
continue;
}
score()->undoRemoveElement(tie);
}

if (jumpPointIdx < 2 && !isPartialTie()) {
tieJumpPoints()->clear();
Expand All @@ -297,7 +282,7 @@ void Tie::collectPossibleJumpPoints()

void Tie::addTiesToJumpPoints()
{
collectPossibleJumpPoints();
updatePossibleJumpPoints();
TieJumpPointList* jumpPoints = tieJumpPoints();
if (!jumpPoints) {
return;
Expand All @@ -312,7 +297,7 @@ void Tie::addTiesToJumpPoints()
}
}

void Tie::removeTiesFromJumpPoints()
void Tie::undoRemoveTiesFromJumpPoints()
{
TieJumpPointList* jumpPoints = tieJumpPoints();
if (!jumpPoints) {
Expand All @@ -324,7 +309,7 @@ void Tie::removeTiesFromJumpPoints()
continue;
}

jumpPoints->removeTieFromScore(jumpPoint);
jumpPoints->undoRemoveTieFromScore(jumpPoint);
}
}

Expand Down Expand Up @@ -643,7 +628,7 @@ void TieJumpPointList::toggleJumpPoint(const String& id)
score->startCmd(TranslatableString("engraving", "Toggle partial tie"));
const bool checked = end->active();
if (checked) {
removeTieFromScore(end);
undoRemoveTieFromScore(end);
} else {
addTieToScore(end);
}
Expand Down Expand Up @@ -684,7 +669,7 @@ void TieJumpPointList::addTieToScore(TieJumpPoint* jumpPoint)
score->undoAddElement(pt);
}

void TieJumpPointList::removeTieFromScore(TieJumpPoint* jumpPoint)
void TieJumpPointList::undoRemoveTieFromScore(TieJumpPoint* jumpPoint)
{
Note* note = jumpPoint->note();
Score* score = note ? note->score() : nullptr;
Expand Down
Loading

0 comments on commit ea6001f

Please sign in to comment.