Skip to content

Commit

Permalink
fix #26961: update Layout panel when add / remove staff & undo
Browse files Browse the repository at this point in the history
  • Loading branch information
RomanPudashkin authored and Jojo-Schmitz committed Mar 11, 2025
1 parent 5355e68 commit 24224ce
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 28 deletions.
43 changes: 35 additions & 8 deletions src/instrumentsscene/view/layoutpaneltreemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,12 @@ void LayoutPanelTreeModel::setupPartsConnections()
});
}

void LayoutPanelTreeModel::setupStavesConnections(const muse::ID& stavesPartId)
void LayoutPanelTreeModel::setupStavesConnections(const muse::ID& partId)
{
async::NotifyList<const Staff*> notationStaves = m_notation->parts()->staffList(stavesPartId);
async::NotifyList<const Staff*> notationStaves = m_notation->parts()->staffList(partId);

notationStaves.onItemChanged(m_partsNotifyReceiver.get(), [this, stavesPartId](const Staff* staff) {
auto partItem = m_rootItem->childAtId(stavesPartId, LayoutPanelItemType::PART);
notationStaves.onItemChanged(m_partsNotifyReceiver.get(), [this, partId](const Staff* staff) {
auto partItem = m_rootItem->childAtId(partId, LayoutPanelItemType::PART);
if (!partItem) {
return;
}
Expand All @@ -252,17 +252,44 @@ void LayoutPanelTreeModel::setupStavesConnections(const muse::ID& stavesPartId)
staffItem->init(m_masterNotation->parts()->staff(staff->id()));
});

notationStaves.onItemAdded(m_partsNotifyReceiver.get(), [this, stavesPartId](const Staff* staff) {
auto partItem = m_rootItem->childAtId(stavesPartId, LayoutPanelItemType::PART);
notationStaves.onItemRemoved(m_partsNotifyReceiver.get(), [this, partId](const Staff* staff) {
auto partItem = m_rootItem->childAtId(partId, LayoutPanelItemType::PART);
if (!partItem) {
return;
}

auto staffItem = partItem->childAtId(staff->id(), LayoutPanelItemType::STAFF);
if (!staffItem) {
return;
}

QModelIndex partIndex = index(partItem->row(), 0, QModelIndex());
int staffRow = staffItem->row();

beginRemoveRows(partIndex, staffRow, staffRow);
partItem->removeChildren(staffRow, 1, false);
endRemoveRows();
});

notationStaves.onItemAdded(m_partsNotifyReceiver.get(), [this, partId](const Staff* staff) {
auto partItem = m_rootItem->childAtId(partId, LayoutPanelItemType::PART);
if (!partItem) {
return;
}

if (partItem->childAtId(staff->id(), LayoutPanelItemType::STAFF)) {
return; // this staff item already exists in the part
}

const Staff* masterStaff = m_masterNotation->parts()->staff(staff->id());
auto staffItem = buildMasterStaffItem(masterStaff, partItem);
size_t staffIdx = muse::indexOf(masterStaff->part()->staves(), const_cast<Staff*>(masterStaff));
if (staffIdx == muse::nidx) {
return;
}

auto staffItem = buildMasterStaffItem(masterStaff, partItem);
QModelIndex partIndex = index(partItem->row(), 0, QModelIndex());
int dstRow = partItem->childCount() - 1;
int dstRow = static_cast<int>(staffIdx);

beginInsertRows(partIndex, dstRow, dstRow);
partItem->insertChild(staffItem, dstRow);
Expand Down
2 changes: 1 addition & 1 deletion src/instrumentsscene/view/layoutpaneltreemodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ private slots:
void sortParts(notation::PartList& parts);

void setupPartsConnections();
void setupStavesConnections(const muse::ID& stavesPartId);
void setupStavesConnections(const muse::ID& partId);
void setupNotationConnections();

void updateSelectedRows();
Expand Down
6 changes: 4 additions & 2 deletions src/instrumentsscene/view/parttreeitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,13 @@ void PartTreeItem::removeChildren(int row, int count, bool deleteChild)
stavesIds.push_back(childAtRow(i)->id());
}

// Remove the children first, then remove the staves
// so we don't try to remove them twice when notified by removeStaves()
AbstractLayoutPanelTreeItem::removeChildren(row, count, deleteChild);

if (deleteChild) {
masterNotation()->parts()->removeStaves(stavesIds);
}

AbstractLayoutPanelTreeItem::removeChildren(row, count, deleteChild);
}

bool PartTreeItem::canAcceptDrop(const QVariant& obj) const
Expand Down
34 changes: 20 additions & 14 deletions src/notation/internal/notationparts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,14 +344,14 @@ void NotationParts::listenUndoStackChanges()

for (ElementType type : TYPES_TO_CHECK) {
if (muse::contains(range.changedTypes, type)) {
updatePartsAndSystemObjectStaves();
updatePartsAndSystemObjectStaves(range);
return;
}
}
});
}

void NotationParts::updatePartsAndSystemObjectStaves()
void NotationParts::updatePartsAndSystemObjectStaves(const mu::engraving::ScoreChangesRange& range)
{
const auto systemObjectStavesWithTopStaff = [this]() {
std::vector<Staff*> result;
Expand All @@ -378,6 +378,20 @@ void NotationParts::updatePartsAndSystemObjectStaves()
if (systemObjectStavesChanged) {
m_systemObjectStavesChanged.notify();
}

for (auto& pair : range.changedItems) {
if (!pair.first || !pair.first->isStaff()) {
continue;
}

Staff* staff = toStaff(pair.first);

if (muse::contains(pair.second, CommandType::RemoveStaff)) {
notifyAboutStaffRemoved(staff);
} else if (muse::contains(pair.second, CommandType::InsertStaff)) {
notifyAboutStaffAdded(staff);
}
}
}

void NotationParts::doSetScoreOrder(const ScoreOrder& order)
Expand Down Expand Up @@ -566,8 +580,6 @@ bool NotationParts::appendStaff(Staff* staff, const ID& destinationPartId)
doAppendStaff(staff, destinationPart);
apply();

notifyAboutStaffAdded(staff, destinationPartId);

return true;
}

Expand Down Expand Up @@ -595,8 +607,6 @@ bool NotationParts::appendLinkedStaff(Staff* staff, const muse::ID& sourceStaffI

apply();

notifyAboutStaffAdded(staff, destinationPartId);

return true;
}

Expand Down Expand Up @@ -1005,10 +1015,6 @@ void NotationParts::removeStaves(const IDList& stavesIds)
setBracketsAndBarlines();

apply();

for (const Staff* staff : stavesToRemove) {
notifyAboutStaffRemoved(staff);
}
}

void NotationParts::moveParts(const IDList& sourcePartsIds, const ID& destinationPartId, InsertMode mode)
Expand Down Expand Up @@ -1358,19 +1364,19 @@ void NotationParts::notifyAboutStaffChanged(const Staff* staff) const
notifier.itemChanged(staff);
}

void NotationParts::notifyAboutStaffAdded(const Staff* staff, const ID& partId) const
void NotationParts::notifyAboutStaffAdded(const Staff* staff) const
{
IF_ASSERT_FAILED(staff) {
IF_ASSERT_FAILED(staff && staff->part()) {
return;
}

ChangedNotifier<const Staff*>& notifier = m_staffChangedNotifierMap[partId];
ChangedNotifier<const Staff*>& notifier = m_staffChangedNotifierMap[staff->part()->id()];
notifier.itemAdded(staff);
}

void NotationParts::notifyAboutStaffRemoved(const Staff* staff) const
{
IF_ASSERT_FAILED(staff) {
IF_ASSERT_FAILED(staff && staff->part()) {
return;
}

Expand Down
5 changes: 2 additions & 3 deletions src/notation/internal/notationparts.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ class NotationParts : public INotationParts, public muse::async::Asyncable
friend class MasterNotationParts;

void listenUndoStackChanges();
void updatePartsAndSystemObjectStaves();
void updatePartsAndSystemObjectStaves(const mu::engraving::ScoreChangesRange& range = {});

void doSetScoreOrder(const ScoreOrder& order);
void doRemoveParts(const std::vector<Part*>& parts);
Expand Down Expand Up @@ -137,7 +137,7 @@ class NotationParts : public INotationParts, public muse::async::Asyncable
void notifyAboutPartRemoved(const Part* part) const;
void notifyAboutPartReplaced(const Part* oldPart, const Part* newPart) const;
void notifyAboutStaffChanged(const Staff* staff) const;
void notifyAboutStaffAdded(const Staff* staff, const muse::ID& partId) const;
void notifyAboutStaffAdded(const Staff* staff) const;
void notifyAboutStaffRemoved(const Staff* staff) const;

IGetScore* m_getScore = nullptr;
Expand All @@ -147,7 +147,6 @@ class NotationParts : public INotationParts, public muse::async::Asyncable
muse::async::Notification m_scoreOrderChanged;

std::vector<Part*> m_parts;

std::vector<Staff*> m_systemObjectStaves;
muse::async::Notification m_systemObjectStavesChanged;

Expand Down

0 comments on commit 24224ce

Please sign in to comment.