Implemented insert/append measures

This commit is contained in:
Eism 2020-11-06 14:40:25 +02:00 committed by Igor Korsukov
parent f7bfa2decd
commit 985be90184
11 changed files with 270 additions and 4 deletions

View file

@ -60,7 +60,7 @@ public:
virtual async::Notification selectionChanged() const = 0;
// Drag
using IsDraggable = std::function<bool(const Element*)>;
using IsDraggable = std::function<bool (const Element*)>;
virtual bool isDragStarted() const = 0;
virtual void startDrag(const std::vector<Element*>& elems, const QPointF& eoffset, const IsDraggable& isDrag) = 0;
virtual void drag(const QPointF& fromPos, const QPointF& toPos, DragMode mode) = 0;
@ -94,6 +94,8 @@ public:
// Measure
virtual void splitSelectedMeasure() = 0;
virtual void joinSelectedMeasures() = 0;
virtual void insertMeasures(int afterMeasureIndex, int count) = 0;
virtual void appendMeasures(int count) = 0;
virtual void copySelection() = 0;
virtual void pasteSelection(const Fraction& scale = Fraction(1, 1)) = 0;

View file

@ -21,6 +21,7 @@
#include <QPoint>
#include "log.h"
#include "notationtypes.h"
using namespace mu::notation;
using namespace mu::actions;
@ -78,6 +79,10 @@ void NotationActionController::init()
dispatcher()->reg(this, "split-measure", this, &NotationActionController::splitMeasure);
dispatcher()->reg(this, "join-measures", this, &NotationActionController::joinSelectedMeasures);
dispatcher()->reg(this, "insert-measure", this, &NotationActionController::insertMeasure);
dispatcher()->reg(this, "insert-measures", this, &NotationActionController::insertMeasures);
dispatcher()->reg(this, "append-measure", this, &NotationActionController::appendMeasure);
dispatcher()->reg(this, "append-measures", this, &NotationActionController::appendMeasures);
dispatcher()->reg(this, "edit-style", this, &NotationActionController::openPageStyle);
dispatcher()->reg(this, "staff-properties", this, &NotationActionController::openStaffProperties);
@ -375,6 +380,68 @@ void NotationActionController::joinSelectedMeasures()
interaction->joinSelectedMeasures();
}
void NotationActionController::insertMeasure()
{
auto interaction = currentNotationInteraction();
if (!interaction) {
return;
}
int lastSelectedMeasureIndex = this->lastSelectedMeasureIndex();
if (lastSelectedMeasureIndex == -1) {
return;
}
interaction->insertMeasures(lastSelectedMeasureIndex, 1);
}
void NotationActionController::insertMeasures()
{
auto interaction = currentNotationInteraction();
if (!interaction) {
return;
}
int lastSelectedMeasureIndex = this->lastSelectedMeasureIndex();
if (lastSelectedMeasureIndex == -1) {
return;
}
RetVal<Val> measureCount = interactive()->open("musescore://notation/selectmeasurescount?operation=insert");
if (!measureCount.ret) {
return;
}
interaction->insertMeasures(lastSelectedMeasureIndex, measureCount.val.toInt());
}
void NotationActionController::appendMeasure()
{
auto interaction = currentNotationInteraction();
if (!interaction) {
return;
}
interaction->appendMeasures(1);
}
void NotationActionController::appendMeasures()
{
auto interaction = currentNotationInteraction();
if (!interaction) {
return;
}
RetVal<Val> measureCount = interactive()->open("musescore://notation/selectcountmeasures?operation=append");
if (!measureCount.ret) {
return;
}
interaction->appendMeasures(measureCount.val.toInt());
}
void NotationActionController::openPageStyle()
{
interactive()->open("musescore://notation/style");
@ -410,3 +477,21 @@ void NotationActionController::openPartsDialog()
{
interactive()->open("musescore://notation/parts");
}
int NotationActionController::lastSelectedMeasureIndex() const
{
int result = -1;
auto interaction = currentNotationInteraction();
if (!interaction) {
return result;
}
if (interaction->selection()->isRange()) {
result = interaction->selection()->range()->endMeasureIndex();
} else {
result = interaction->selection()->element()->findMeasure()->index();
}
return result;
}

View file

@ -60,9 +60,12 @@ private:
void redo();
void selectAll();
void splitMeasure();
void joinSelectedMeasures();
void insertMeasure();
void insertMeasures();
void appendMeasure();
void appendMeasures();
void openPageStyle();
void openStaffProperties();
@ -80,6 +83,8 @@ private:
void pasteSelection(PastingType type = PastingType::Default);
Fraction resolvePastingScale(const INotationInteractionPtr& interaction, PastingType type) const;
int lastSelectedMeasureIndex() const;
};
}

View file

@ -219,6 +219,22 @@ const ActionList NotationActions::m_actions = {
Action("join-measures",
QT_TRANSLATE_NOOP("action", "Join Selected Measures"),
ShortcutContext::NotationActive
),
Action("insert-measure",
QT_TRANSLATE_NOOP("action", "Insert Measure"),
ShortcutContext::NotationActive
),
Action("insert-measures",
QT_TRANSLATE_NOOP("action", "Insert Measures"),
ShortcutContext::NotationActive
),
Action("append-measure",
QT_TRANSLATE_NOOP("action", "Append Measure"),
ShortcutContext::NotationActive
),
Action("append-measures",
QT_TRANSLATE_NOOP("action", "Append Measures"),
ShortcutContext::NotationActive
)
};

View file

@ -1978,6 +1978,46 @@ void NotationInteraction::joinSelectedMeasures()
m_selectionChanged.notify();
}
void NotationInteraction::insertMeasures(int afterMeasureIndex, int count)
{
Measure* measure = score()->crMeasure(afterMeasureIndex);
if (!measure) {
return;
}
score()->startCmd();
for (int i = 0; i < count; i++) {
score()->insertMeasure(ElementType::MEASURE, measure);
}
score()->endCmd();
clearSelection();
for (int i = afterMeasureIndex + 1; i <= afterMeasureIndex + count; i++) {
Measure* measure = score()->crMeasure(i - 1);
select(measure, SelectType::RANGE);
}
}
void NotationInteraction::appendMeasures(int count)
{
int measureCount = score()->measures()->size();
score()->startCmd();
for (int i = 0; i < count; i++) {
score()->insertMeasure(ElementType::MEASURE, nullptr);
}
score()->endCmd();
clearSelection();
for (int i = measureCount; i < measureCount + count; i++) {
Measure* measure = score()->crMeasure(i - 1);
select(measure, SelectType::RANGE);
}
}
void NotationInteraction::copySelection()
{
if (!selection()->canCopy()) {

View file

@ -111,6 +111,8 @@ public:
// Measure
void splitSelectedMeasure() override;
void joinSelectedMeasures() override;
void insertMeasures(int afterMeasureIndex, int count) override;
void appendMeasures(int count) override;
void copySelection() override;
void pasteSelection(const Fraction& scale = Fraction(1, 1)) override;

View file

@ -272,8 +272,8 @@ int NotationSelectionRange::sectionElementsMinY(const NotationSelectionRange::Ra
NotationSelectionRange::MeasureRange NotationSelectionRange::measureRange() const
{
const Ms::Selection& selection = score()->selection();
Measure* startMeasure;
Measure* endMeasure;
Measure* startMeasure = nullptr;
Measure* endMeasure = nullptr;
selection.measureRange(&startMeasure, &endMeasure);
MeasureRange range;

View file

@ -123,6 +123,9 @@ void NotationModule::resolveImports()
ir->registerUri(Uri("musescore://notation/noteinputbar/customise"),
ContainerMeta(ContainerType::QmlDialog, "MuseScore/NotationScene/NoteInputBarCustomiseDialog.qml"));
ir->registerUri(Uri("musescore://notation/selectmeasurescount"),
ContainerMeta(ContainerType::QmlDialog, "MuseScore/NotationScene/SelectMeasuresCountDialog.qml"));
}
}

View file

@ -21,5 +21,6 @@
<file>qml/MuseScore/NotationScene/NoteInputBarCustomiseDialog.qml</file>
<file>qml/MuseScore/NotationScene/internal/NoteInputBarActionDelegate.qml</file>
<file>qml/MuseScore/NotationScene/internal/NoteInputBarSeparatorDelegate.qml</file>
<file>qml/MuseScore/NotationScene/SelectMeasuresCountDialog.qml</file>
</qresource>
</RCC>

View file

@ -33,6 +33,7 @@
#include "libmscore/staff.h"
#include "libmscore/stafftype.h"
#include "libmscore/score.h"
#include "libmscore/measure.h"
#include "instruments/instrumentstypes.h"

View file

@ -0,0 +1,111 @@
import QtQuick 2.12
import QtQuick.Layouts 1.12
import MuseScore.Ui 1.0
import MuseScore.UiComponents 1.0
QmlDialog {
id: root
width: 534
height: 146
modal: true
property string operation: ""
Rectangle {
id: content
anchors.fill: parent
color: ui.theme.popupBackgroundColor
property int measuresCount: 1
QtObject {
id: privateProperties
readonly property int sideMargin: 16
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
}
ColumnLayout {
anchors.fill: parent
anchors.margins: privateProperties.sideMargin
spacing: 20
Column {
Layout.fillWidth: true
spacing: 12
StyledTextLabel {
text: privateProperties.capitalizeFirstLetter(operation) + " " + qsTrc("notation", "empty measures")
font.bold: true
}
RowLayout {
Layout.fillWidth: true
spacing: 12
StyledTextLabel {
Layout.fillWidth: true
text: qsTrc("notation", "Number of measures to ") + operation.toLowerCase() + ":"
}
IncrementalPropertyControl {
id: countMeasuresInputField
Layout.alignment: Qt.AlignRight
Layout.preferredWidth: 100
iconMode: iconModeEnum.hidden
currentValue: content.measuresCount
step: 1
maxValue: 1000
minValue: 1
validator: IntInputValidator {
top: countMeasuresInputField.maxValue
bottom: countMeasuresInputField.minValue
}
onValueEdited: {
content.measuresCount = newValue
}
}
}
}
Row {
Layout.preferredHeight: childrenRect.height
Layout.alignment: Qt.AlignRight | Qt.AlignBottom
spacing: 12
FlatButton {
text: qsTrc("global", "Cancel")
onClicked: {
root.reject()
}
}
FlatButton {
text: qsTrc("global", "Ok")
onClicked: {
root.ret = {errcode: 0, value: content.measuresCount}
root.hide()
}
}
}
}
}
}