From f475849fc5e7b2936bad26a9e422bde428cafb8a Mon Sep 17 00:00:00 2001 From: Michele Spagnolo Date: Fri, 21 Feb 2025 10:22:29 +0100 Subject: [PATCH 1/6] Allow drop on system object layers --- src/instrumentsscene/view/systemobjectslayertreeitem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/instrumentsscene/view/systemobjectslayertreeitem.cpp b/src/instrumentsscene/view/systemobjectslayertreeitem.cpp index 78979da7ff34b..174a94be3706c 100644 --- a/src/instrumentsscene/view/systemobjectslayertreeitem.cpp +++ b/src/instrumentsscene/view/systemobjectslayertreeitem.cpp @@ -134,7 +134,7 @@ QString SystemObjectsLayerTreeItem::staffId() const bool SystemObjectsLayerTreeItem::canAcceptDrop(const QVariant&) const { - return false; + return m_staffIdx != 0; // all except the first } void SystemObjectsLayerTreeItem::onScoreChanged(const mu::engraving::ScoreChangesRange& changes) From 1e3eeb0759176ecb3d87c7173ef01399bc019c2e Mon Sep 17 00:00:00 2001 From: Michele Spagnolo Date: Fri, 21 Feb 2025 12:04:06 +0100 Subject: [PATCH 2/6] If system object layer ends up last, remove it from list --- src/instrumentsscene/view/layoutpaneltreemodel.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/instrumentsscene/view/layoutpaneltreemodel.cpp b/src/instrumentsscene/view/layoutpaneltreemodel.cpp index e6e8c2d67e12f..ab10a4cf066ce 100644 --- a/src/instrumentsscene/view/layoutpaneltreemodel.cpp +++ b/src/instrumentsscene/view/layoutpaneltreemodel.cpp @@ -553,6 +553,17 @@ bool LayoutPanelTreeModel::moveRows(const QModelIndex& sourceParent, int sourceR sourceParentItem->moveChildren(sourceFirstRow, count, destinationParentItem, destinationRow, !m_dragInProgress); endMoveRows(); + int lastRow = m_rootItem->childCount() - 1; + AbstractLayoutPanelTreeItem* lastItem = m_rootItem->childAtRow(m_rootItem->childCount() - 1); + if (lastItem->type() == LayoutPanelItemType::SYSTEM_OBJECTS_LAYER) { + bool restore = m_isRemovingAvailable; + m_isRemovingAvailable = true; + + removeRow(lastRow); + + m_isRemovingAvailable = restore; + } + updateRearrangementAvailability(); updateSystemObjectLayers(); From d9988ed80959a3d79045c5e57bd9459517fe1136 Mon Sep 17 00:00:00 2001 From: Michele Spagnolo Date: Fri, 21 Feb 2025 13:06:33 +0100 Subject: [PATCH 3/6] Ensure top system object can't get selected/moved Fix #26601 --- src/instrumentsscene/view/layoutpaneltreemodel.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/instrumentsscene/view/layoutpaneltreemodel.cpp b/src/instrumentsscene/view/layoutpaneltreemodel.cpp index ab10a4cf066ce..78f71387a913e 100644 --- a/src/instrumentsscene/view/layoutpaneltreemodel.cpp +++ b/src/instrumentsscene/view/layoutpaneltreemodel.cpp @@ -839,6 +839,13 @@ void LayoutPanelTreeModel::updateMovingDownAvailability(bool isSelectionMovable, bool hasControlItem = parentItem->type() != LayoutPanelItemType::ROOT; const AbstractLayoutPanelTreeItem* curItem = modelIndexToItem(lastSelectedRowIndex); bool lastSelectedIsSystemObjectLayer = curItem && curItem->type() == LayoutPanelItemType::ItemType::SYSTEM_OBJECTS_LAYER; + + IF_ASSERT_FAILED(!(lastSelectedIsSystemObjectLayer && lastSelectedRowIndex.row() == 0)) { + // Selecting/moving the top system object layer not allowed + setIsMovingDownAvailable(false); + return; + } + int lastItemRowIndex = parentItem->childCount() - 1 - (hasControlItem ? 1 : 0) - (lastSelectedIsSystemObjectLayer ? 1 : 0); bool isRowInBoundaries = lastSelectedRowIndex.isValid() && lastSelectedRowIndex.row() < lastItemRowIndex; @@ -1063,7 +1070,10 @@ void LayoutPanelTreeModel::updateSystemObjectLayers() m_rootItem->insertChild(newItem, row); endInsertRows(); - m_selectionModel->select(createIndex(row, 0, newItem)); + if (row != 0) { + m_selectionModel->select(createIndex(row, 0, newItem)); + } + break; } } From d7931787269c8f42a44036e8764a08e161a1e3ce Mon Sep 17 00:00:00 2001 From: Michele Spagnolo Date: Fri, 21 Feb 2025 17:23:41 +0100 Subject: [PATCH 4/6] Don't allow adding more system object layer if full --- .../view/layoutpaneltreemodel.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/instrumentsscene/view/layoutpaneltreemodel.cpp b/src/instrumentsscene/view/layoutpaneltreemodel.cpp index 78f71387a913e..afeb2ad7054ce 100644 --- a/src/instrumentsscene/view/layoutpaneltreemodel.cpp +++ b/src/instrumentsscene/view/layoutpaneltreemodel.cpp @@ -69,6 +69,7 @@ LayoutPanelTreeModel::LayoutPanelTreeModel(QObject* parent) updateRearrangementAvailability(); updateRemovingAvailability(); updateSelectedItemsType(); + emit isAddingSystemMarkingsAvailableChanged(isAddingSystemMarkingsAvailable()); }); connect(this, &LayoutPanelTreeModel::rowsInserted, this, [this]() { @@ -453,6 +454,8 @@ void LayoutPanelTreeModel::addSystemMarkings() if (const Staff* staff = resolveNewSystemObjectStaff()) { m_masterNotation->parts()->addSystemObjects({ staff->id() }); } + + emit isAddingSystemMarkingsAvailableChanged(isAddingSystemMarkingsAvailable()); } void LayoutPanelTreeModel::moveSelectedRowsUp() @@ -730,7 +733,18 @@ bool LayoutPanelTreeModel::isAddingAvailable() const bool LayoutPanelTreeModel::isAddingSystemMarkingsAvailable() const { - return isAddingAvailable() && m_notation->isMaster(); + if (!isAddingAvailable() || !m_notation->isMaster()) { + return false; + } + + int systemLayerCount = 0; + for (const AbstractLayoutPanelTreeItem* item : m_rootItem->childItems()) { + if (item->type() == LayoutPanelItemType::SYSTEM_OBJECTS_LAYER) { + ++systemLayerCount; + } + } + + return systemLayerCount < 0.5 * m_rootItem->childCount(); } bool LayoutPanelTreeModel::isEmpty() const From f607f858679d36f746854fbbebb41035f91ebdc4 Mon Sep 17 00:00:00 2001 From: Michele Spagnolo Date: Mon, 24 Feb 2025 09:33:34 +0100 Subject: [PATCH 5/6] Don't add/remove system object staves in parts They are currently disabled, and anyway will be managed separately between score and parts --- src/notation/internal/masternotationparts.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/notation/internal/masternotationparts.cpp b/src/notation/internal/masternotationparts.cpp index 308d8d6bc3210..1c9c744ff69d0 100644 --- a/src/notation/internal/masternotationparts.cpp +++ b/src/notation/internal/masternotationparts.cpp @@ -265,10 +265,6 @@ void MasterNotationParts::addSystemObjects(const muse::IDList& stavesIds) NotationParts::addSystemObjects(stavesIds); - for (INotationPartsPtr parts : excerptsParts()) { - parts->addSystemObjects(stavesIds); - } - endGlobalEdit(); } @@ -282,10 +278,6 @@ void MasterNotationParts::removeSystemObjects(const muse::IDList& stavesIds) NotationParts::removeSystemObjects(stavesIds); - for (INotationPartsPtr parts : excerptsParts()) { - parts->removeSystemObjects(stavesIds); - } - endGlobalEdit(); } From 82f06aae36b8c59a687b7c3f90e8c29c3f856baa Mon Sep 17 00:00:00 2001 From: Michele Spagnolo Date: Mon, 24 Feb 2025 09:54:56 +0100 Subject: [PATCH 6/6] Don't add system object staff at staffIdx = 0 The first staff already gets system objects by default --- src/notation/internal/notationparts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/notation/internal/notationparts.cpp b/src/notation/internal/notationparts.cpp index 7f2aaa3f954ca..c305f92359923 100644 --- a/src/notation/internal/notationparts.cpp +++ b/src/notation/internal/notationparts.cpp @@ -799,7 +799,7 @@ void NotationParts::moveSystemObjects(const ID& sourceStaffId, const ID& destina startEdit(TranslatableString("undoableAction", "Move system markings")); score()->undo(new mu::engraving::RemoveSystemObjectStaff(srcStaff)); - if (!score()->isSystemObjectStaff(dstStaff)) { + if (!score()->isSystemObjectStaff(dstStaff) && !dstStaffIdx == 0) { score()->undo(new mu::engraving::AddSystemObjectStaff(dstStaff)); }