diff --git a/src/app/configs/data/shortcuts.xml b/src/app/configs/data/shortcuts.xml
index 7107e705508ac..184dfd0ff2061 100644
--- a/src/app/configs/data/shortcuts.xml
+++ b/src/app/configs/data/shortcuts.xml
@@ -797,6 +797,11 @@
Ctrl+Return
Ctrl+Enter
+
+ apply-system-lock
+ Alt+Return
+ Alt+Enter
+
move-measure-to-prev-system
Alt+Up
diff --git a/src/app/configs/data/shortcuts_azerty.xml b/src/app/configs/data/shortcuts_azerty.xml
index 7dc7ccc57fcb7..eaf65a8fbc06b 100644
--- a/src/app/configs/data/shortcuts_azerty.xml
+++ b/src/app/configs/data/shortcuts_azerty.xml
@@ -823,6 +823,11 @@
Ctrl+Return
Ctrl+Enter
+
+ apply-system-lock
+ Alt+Return
+ Alt+Enter
+
move-measure-to-prev-system
Alt+Up
diff --git a/src/app/configs/data/shortcuts_mac.xml b/src/app/configs/data/shortcuts_mac.xml
index 1cf9ae5fbbd7f..a0cf1bc90ae79 100644
--- a/src/app/configs/data/shortcuts_mac.xml
+++ b/src/app/configs/data/shortcuts_mac.xml
@@ -797,6 +797,11 @@
Ctrl+Return
Ctrl+Enter
+
+ apply-system-lock
+ Alt+Return
+ Alt+Enter
+
move-measure-to-prev-system
Alt+Up
diff --git a/src/engraving/dom/cmd.cpp b/src/engraving/dom/cmd.cpp
index eb2b30b16a695..b06124d5dcd3a 100644
--- a/src/engraving/dom/cmd.cpp
+++ b/src/engraving/dom/cmd.cpp
@@ -4777,6 +4777,40 @@ void Score::cmdToggleSystemLock()
toggleSystemLock(m_selection.selectedSystems());
}
+void Score::cmdApplyLockToSelection()
+{
+ MeasureBase* first = nullptr;
+ MeasureBase* last = nullptr;
+
+ if (selection().isRange()) {
+ first = selection().startMeasureBase();
+ last = selection().endMeasureBase();
+ } else {
+ for (EngravingItem* el : selection().elements()) {
+ MeasureBase* mb = el->findMeasureBase();
+ if (!mb) {
+ continue;
+ }
+ if (!first || mb->isBefore(first)) {
+ first = mb;
+ }
+ if (!last || mb->isAfter(last)) {
+ last = mb;
+ }
+ }
+ }
+
+ if (!first || !last) {
+ return;
+ }
+
+ if (first != last) {
+ makeIntoSystem(first, last);
+ } else {
+ makeIntoSystem(first->system()->first(), last);
+ }
+}
+
void Score::cmdToggleScoreLock()
{
bool unlockAll = true;
@@ -4815,40 +4849,7 @@ void Score::cmdMakeIntoSystem()
return;
}
- bool mmrests = style().styleB(Sid::createMultiMeasureRests);
-
- const SystemLock* lockContainingFirstSelected = m_systemLocks.lockContaining(firstSelected);
- const SystemLock* lockContainingLastSelected = m_systemLocks.lockContaining(lastSelected);
-
- if (lockContainingFirstSelected) {
- undoRemoveSystemLock(lockContainingFirstSelected);
- if (lockContainingFirstSelected->startMB()->isBefore(firstSelected)) {
- MeasureBase* oneBeforeFirst = mmrests ? firstSelected->prevMM() : firstSelected->prev();
- SystemLock* newLockBefore = new SystemLock(lockContainingFirstSelected->startMB(), oneBeforeFirst);
- undoAddSystemLock(newLockBefore);
- }
- }
-
- if (lockContainingLastSelected) {
- if (lockContainingLastSelected != lockContainingFirstSelected) {
- undoRemoveSystemLock(lockContainingLastSelected);
- }
- if (lastSelected->isBefore(lockContainingLastSelected->endMB())) {
- MeasureBase* oneAfterLast = mmrests ? lastSelected->nextMM() : lastSelected->next();
- SystemLock* newLockAfter = new SystemLock(oneAfterLast, lockContainingLastSelected->endMB());
- undoAddSystemLock(newLockAfter);
- }
- }
-
- std::vector locksContainedInRange = m_systemLocks.locksContainedInRange(firstSelected, lastSelected);
- for (const SystemLock* lock : locksContainedInRange) {
- if (lock != lockContainingFirstSelected && lock != lockContainingLastSelected) {
- undoRemoveSystemLock(lock);
- }
- }
-
- SystemLock* newLock = new SystemLock(firstSelected, lastSelected);
- undoAddSystemLock(newLock);
+ makeIntoSystem(firstSelected, lastSelected);
}
void Score::cmdAddStaffTypeChange(Measure* measure, staff_idx_t staffIdx, StaffTypeChange* stc)
diff --git a/src/engraving/dom/edit.cpp b/src/engraving/dom/edit.cpp
index b57e1b00aca48..3cd5cdc45c0c1 100644
--- a/src/engraving/dom/edit.cpp
+++ b/src/engraving/dom/edit.cpp
@@ -6555,6 +6555,44 @@ void Score::toggleSystemLock(const std::vector& systems)
}
}
+void Score::makeIntoSystem(MeasureBase* first, MeasureBase* last)
+{
+ bool mmrests = style().styleB(Sid::createMultiMeasureRests);
+
+ const SystemLock* lockContainingfirst = m_systemLocks.lockContaining(first);
+ const SystemLock* lockContaininglast = m_systemLocks.lockContaining(last);
+
+ if (lockContainingfirst) {
+ undoRemoveSystemLock(lockContainingfirst);
+ if (lockContainingfirst->startMB()->isBefore(first)) {
+ MeasureBase* oneBeforeFirst = mmrests ? first->prevMM() : first->prev();
+ SystemLock* newLockBefore = new SystemLock(lockContainingfirst->startMB(), oneBeforeFirst);
+ undoAddSystemLock(newLockBefore);
+ }
+ }
+
+ if (lockContaininglast) {
+ if (lockContaininglast != lockContainingfirst) {
+ undoRemoveSystemLock(lockContaininglast);
+ }
+ if (last->isBefore(lockContaininglast->endMB())) {
+ MeasureBase* oneAfterLast = mmrests ? last->nextMM() : last->next();
+ SystemLock* newLockAfter = new SystemLock(oneAfterLast, lockContaininglast->endMB());
+ undoAddSystemLock(newLockAfter);
+ }
+ }
+
+ std::vector locksContainedInRange = m_systemLocks.locksContainedInRange(first, last);
+ for (const SystemLock* lock : locksContainedInRange) {
+ if (lock != lockContainingfirst && lock != lockContaininglast) {
+ undoRemoveSystemLock(lock);
+ }
+ }
+
+ SystemLock* newLock = new SystemLock(first, last);
+ undoAddSystemLock(newLock);
+}
+
void Score::removeSystemLocksOnAddLayoutBreak(LayoutBreakType breakType, const MeasureBase* measure)
{
IF_ASSERT_FAILED(breakType != LayoutBreakType::NOBREAK) {
diff --git a/src/engraving/dom/measure.cpp b/src/engraving/dom/measure.cpp
index 106a360200612..a6eafb70a9de3 100644
--- a/src/engraving/dom/measure.cpp
+++ b/src/engraving/dom/measure.cpp
@@ -1383,8 +1383,7 @@ bool Measure::acceptDrop(EditData& data) const
{
LayoutMode layoutMode = score()->layoutMode();
if (layoutMode == LayoutMode::PAGE || layoutMode == LayoutMode::SYSTEM) {
- const System* sys = system();
- viewer->setDropRectangle(sys->canvasBoundingRect().adjusted(sys->leftMargin(), 0.0, 0.0, 0.0));
+ viewer->setDropRectangle(canvasBoundingRect().adjusted(-x(), 0.0, 0.0, 0.0));
return true;
}
return false;
@@ -1726,7 +1725,7 @@ EngravingItem* Measure::drop(EditData& data)
break;
}
case ActionIconType::SYSTEM_LOCK:
- score()->toggleSystemLock({ system() });
+ score()->makeIntoSystem(system()->first(), this);
break;
default:
break;
diff --git a/src/engraving/dom/score.h b/src/engraving/dom/score.h
index c62160725ddf9..695289dbe3259 100644
--- a/src/engraving/dom/score.h
+++ b/src/engraving/dom/score.h
@@ -361,6 +361,7 @@ class Score : public EngravingObject, public muse::Injectable
void cmdMoveMeasureToPrevSystem();
void cmdMoveMeasureToNextSystem();
void cmdToggleSystemLock();
+ void cmdApplyLockToSelection();
void cmdToggleScoreLock();
void cmdMakeIntoSystem();
void cmdAddStaffTypeChange(Measure* measure, staff_idx_t staffIdx, StaffTypeChange* stc);
@@ -1018,6 +1019,7 @@ class Score : public EngravingObject, public muse::Injectable
void undoRemoveSystemLock(const SystemLock* lock);
void undoRemoveAllLocks();
void toggleSystemLock(const std::vector& systems);
+ void makeIntoSystem(MeasureBase* first, MeasureBase* last);
void removeSystemLocksOnAddLayoutBreak(LayoutBreakType breakType, const MeasureBase* measure);
void removeLayoutBreaksOnAddSystemLock(const SystemLock* lock);
diff --git a/src/notation/inotationinteraction.h b/src/notation/inotationinteraction.h
index a3295246f6a4a..77407c1a3f38f 100644
--- a/src/notation/inotationinteraction.h
+++ b/src/notation/inotationinteraction.h
@@ -205,6 +205,7 @@ class INotationInteraction
virtual void toggleSystemLock() = 0;
virtual void toggleScoreLock() = 0;
virtual void makeIntoSystem() = 0;
+ virtual void applySystemLock() = 0;
virtual void addRemoveSystemLocks(AddRemoveSystemLockType intervalType, int interval = 0) = 0;
virtual bool transpose(const TransposeOptions& options) = 0;
diff --git a/src/notation/internal/notationactioncontroller.cpp b/src/notation/internal/notationactioncontroller.cpp
index 1c6ccc6cd3d76..3475f7fee77fa 100644
--- a/src/notation/internal/notationactioncontroller.cpp
+++ b/src/notation/internal/notationactioncontroller.cpp
@@ -256,6 +256,7 @@ void NotationActionController::init()
registerAction("section-break", &Interaction::toggleLayoutBreak, LayoutBreakType::SECTION, PlayMode::NoPlay,
&Controller::toggleLayoutBreakAvailable);
+ registerAction("apply-system-lock", &Interaction::applySystemLock);
registerAction("move-measure-to-prev-system", &Interaction::moveMeasureToPrevSystem);
registerAction("move-measure-to-next-system", &Interaction::moveMeasureToNextSystem);
registerAction("toggle-system-lock", &Interaction::toggleSystemLock);
diff --git a/src/notation/internal/notationinteraction.cpp b/src/notation/internal/notationinteraction.cpp
index 095735af6108f..e6b68d77f0471 100644
--- a/src/notation/internal/notationinteraction.cpp
+++ b/src/notation/internal/notationinteraction.cpp
@@ -1763,7 +1763,7 @@ bool NotationInteraction::applyPaletteElement(mu::engraving::EngravingItem* elem
mu::engraving::LayoutBreak* breakElement = toLayoutBreak(element);
score->cmdToggleLayoutBreak(breakElement->layoutBreakType());
} else if (element->isActionIcon() && toActionIcon(element)->actionType() == ActionIconType::SYSTEM_LOCK) {
- score->cmdToggleSystemLock();
+ score->cmdApplyLockToSelection();
} else if (element->isSlur() && addSingle) {
doAddSlur(toSlur(element));
} else if (element->isSLine() && !element->isGlissando() && !element->isGuitarBend() && addSingle) {
@@ -2022,9 +2022,7 @@ bool NotationInteraction::applyPaletteElement(mu::engraving::EngravingItem* elem
}
}
} else if (element->isActionIcon() && toActionIcon(element)->actionType() == ActionIconType::SYSTEM_LOCK) {
- if (sel.isRange()) {
- score->toggleSystemLock(sel.selectedSystems());
- }
+ score->cmdApplyLockToSelection();
} else {
track_idx_t track1 = sel.staffStart() * mu::engraving::VOICES;
track_idx_t track2 = sel.staffEnd() * mu::engraving::VOICES;
@@ -4529,6 +4527,13 @@ void NotationInteraction::makeIntoSystem()
apply();
}
+void NotationInteraction::applySystemLock()
+{
+ startEdit(TranslatableString("undoableAction", "Apply system lock to selection"));
+ score()->cmdApplyLockToSelection();
+ apply();
+}
+
void NotationInteraction::addRemoveSystemLocks(AddRemoveSystemLockType intervalType, int interval)
{
interval = intervalType == AddRemoveSystemLockType::MeasuresInterval ? interval : 0;
diff --git a/src/notation/internal/notationinteraction.h b/src/notation/internal/notationinteraction.h
index 688e5f95aeee9..8d88caeb014b6 100644
--- a/src/notation/internal/notationinteraction.h
+++ b/src/notation/internal/notationinteraction.h
@@ -208,6 +208,7 @@ class NotationInteraction : public INotationInteraction, public muse::Injectable
void toggleSystemLock() override;
void toggleScoreLock() override;
void makeIntoSystem() override;
+ void applySystemLock() override;
void addRemoveSystemLocks(AddRemoveSystemLockType intervalType, int interval = 0) override;
bool transpose(const TransposeOptions& options) override;
diff --git a/src/notation/internal/notationuiactions.cpp b/src/notation/internal/notationuiactions.cpp
index 083c97e70d587..400eef56ca81a 100644
--- a/src/notation/internal/notationuiactions.cpp
+++ b/src/notation/internal/notationuiactions.cpp
@@ -631,6 +631,12 @@ const UiActionList NotationUiActions::m_actions = {
TranslatableString("action", "Add/remove page break"),
TranslatableString("action", "Add/remove page break")
),
+ UiAction("apply-system-lock",
+ mu::context::UiCtxProjectOpened,
+ mu::context::CTX_NOTATION_FOCUSED,
+ TranslatableString("action", "Add/remove system lock"),
+ TranslatableString("action", "Add/remove system lock")
+ ),
UiAction("move-measure-to-prev-system",
mu::context::UiCtxProjectOpened,
mu::context::CTX_NOTATION_FOCUSED,
diff --git a/src/notation/tests/mocks/notationinteractionmock.h b/src/notation/tests/mocks/notationinteractionmock.h
index 91f37f276d721..1b61735efa7b6 100644
--- a/src/notation/tests/mocks/notationinteractionmock.h
+++ b/src/notation/tests/mocks/notationinteractionmock.h
@@ -167,6 +167,7 @@ class NotationInteractionMock : public INotationInteraction
MOCK_METHOD(void, toggleSystemLock, (), (override));
MOCK_METHOD(void, toggleScoreLock, (), (override));
MOCK_METHOD(void, makeIntoSystem, (), (override));
+ MOCK_METHOD(void, applySystemLock, (), (override));
MOCK_METHOD(void, addRemoveSystemLocks, (AddRemoveSystemLockType, int), (override));
MOCK_METHOD(bool, transpose, (const TransposeOptions&), (override));