Skip to content

Commit

Permalink
Refactoring of EngravingObject::findLinkedInScore
Browse files Browse the repository at this point in the history
The function did not take into account that an item can have multiple links within the same score (e.g. linked TABs).

Now EngravingItem::findLinkedInScore(Score*) returns (if exists) the item linked in the required score AND in a staff with same id.

Additionally, EngravingItem::findLinkedInStaff(Staff*) returns if (exists) the linked item in the required staff.
  • Loading branch information
mike-spa committed Sep 19, 2023
1 parent 795b535 commit 4e6d03b
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 19 deletions.
4 changes: 2 additions & 2 deletions src/engraving/dom/edit.cpp
Expand Up @@ -6438,11 +6438,11 @@ void Score::undoAddCR(ChordRest* cr, Measure* measure, const Fraction& tick)
DurationElement* elementBelow = cr;
Tuplet* tupletAbove = elementBelow->tuplet();
while (tupletAbove) {
DurationElement* linkedElementBelow = (DurationElement*)elementBelow->findLinkedInScore(score);
DurationElement* linkedElementBelow = (DurationElement*)elementBelow->findLinkedInStaff(staff);
if (!linkedElementBelow) { // shouldn't happen
break;
}
Tuplet* linkedTuplet = (Tuplet*)tupletAbove->findLinkedInScore(score);
Tuplet* linkedTuplet = (Tuplet*)tupletAbove->findLinkedInStaff(staff);
if (!linkedTuplet) {
linkedTuplet = toTuplet(tupletAbove->linkedClone());
linkedTuplet->setScore(score);
Expand Down
30 changes: 30 additions & 0 deletions src/engraving/dom/engravingitem.cpp
Expand Up @@ -2109,6 +2109,36 @@ std::pair<int, float> EngravingItem::barbeat() const
return std::pair<int, float>(bar + 1, beat + 1 + ticks / static_cast<float>(ticksB));
}

EngravingItem* EngravingItem::findLinkedInScore(const Score* score) const
{
if (!score || !staff() || !links() || links()->empty()) {
return nullptr;
}

Staff* linkedStaffInScore = staff()->findLinkedInScore(score);

if (!linkedStaffInScore) {
return nullptr;
}

return findLinkedInStaff(linkedStaffInScore);
}

EngravingItem* EngravingItem::findLinkedInStaff(const Staff* staff) const
{
if (!links() || links()->empty()) {
return nullptr;
}

for (EngravingObject* linked : *links()) {
if (toEngravingItem(linked)->staff() == staff) {
return toEngravingItem(linked);
}
}

return nullptr;
}

bool EngravingItem::selected() const
{
return flag(ElementFlag::SELECTED);
Expand Down
3 changes: 3 additions & 0 deletions src/engraving/dom/engravingitem.h
Expand Up @@ -480,6 +480,9 @@ class EngravingItem : public EngravingObject

std::pair<int, float> barbeat() const;

virtual EngravingItem* findLinkedInScore(const Score* score) const;
EngravingItem* findLinkedInStaff(const Staff* staff) const;

struct Autoplace {
OffsetChange offsetChanged = OffsetChange::NONE; // set by user actions that change offset, used by autoplace
PointF changedPos; // position set when changing offset
Expand Down
16 changes: 0 additions & 16 deletions src/engraving/dom/engravingobject.cpp
Expand Up @@ -541,22 +541,6 @@ bool EngravingObject::isLinked(EngravingObject* se) const
return m_links->contains(se);
}

//---------------------------------------------------------
// findLinkedInScore
/// if exists, returns the linked object in the required
/// score, else returns null
//---------------------------------------------------------

EngravingObject* EngravingObject::findLinkedInScore(Score* score) const
{
if (score == this || !m_links || m_links->empty()) {
return nullptr;
}
auto findElem = std::find_if(m_links->begin(), m_links->end(),
[this, score](EngravingObject* engObj) { return engObj && engObj != this && engObj->score() == score; });
return findElem != m_links->end() ? *findElem : nullptr;
}

//---------------------------------------------------------
// undoUnlink
//---------------------------------------------------------
Expand Down
1 change: 0 additions & 1 deletion src/engraving/dom/engravingobject.h
Expand Up @@ -267,7 +267,6 @@ class EngravingObject
void linkTo(EngravingObject*);
void unlink();
bool isLinked(EngravingObject* se = nullptr) const;
EngravingObject* findLinkedInScore(Score* score) const;

virtual void undoUnlink();
LinkedObjects* links() const { return m_links; }
Expand Down
11 changes: 11 additions & 0 deletions src/engraving/dom/staff.cpp
Expand Up @@ -112,6 +112,17 @@ void Staff::triggerLayout(const Fraction& tick)
score()->setLayout(tick, idx());
}

Staff* Staff::findLinkedInScore(const Score* score) const
{
for (Staff* staff : score->staves()) {
if (staff->id() == id()) {
return staff;
}
}

return nullptr;
}

//---------------------------------------------------------
// fillBrackets
// make sure index idx is valid
Expand Down
2 changes: 2 additions & 0 deletions src/engraving/dom/staff.h
Expand Up @@ -304,6 +304,8 @@ class Staff final : public EngravingItem

void triggerLayout() const override;
void triggerLayout(const Fraction& tick);

Staff* findLinkedInScore(const Score* score) const override;
};
} // namespace mu::engraving
#endif

0 comments on commit 4e6d03b

Please sign in to comment.