From 8bba2d2823f8a6b155b16fb78f40f1f31bcf3aee Mon Sep 17 00:00:00 2001 From: Michele Spagnolo Date: Thu, 5 Mar 2026 17:46:10 +0100 Subject: [PATCH 1/5] Group naming --- src/engraving/api/tests/score_tests.cpp | 6 +- src/engraving/dom/dom.cmake | 2 +- src/engraving/dom/excerpt.cpp | 1 - src/engraving/dom/instrtemplate.h | 2 +- src/engraving/dom/instrument.cpp | 50 +- src/engraving/dom/instrument.h | 27 +- src/engraving/dom/instrumentname.cpp | 8 +- src/engraving/dom/instrumentname.h | 16 +- src/engraving/dom/part.cpp | 39 +- src/engraving/dom/part.h | 11 +- src/engraving/dom/stafflabel.h | 148 ++ src/engraving/dom/staffname.h | 47 - src/engraving/dom/stafftype.cpp | 2 +- src/engraving/dom/stafftype.h | 15 +- src/engraving/dom/system.cpp | 74 +- src/engraving/dom/system.h | 24 +- src/engraving/editing/editpart.cpp | 25 +- src/engraving/editing/editpart.h | 24 +- src/engraving/editing/undo.h | 1 + .../rendering/score/systemheaderlayout.cpp | 764 +++++-- .../rendering/score/systemheaderlayout.h | 9 +- src/engraving/rw/read114/read114.cpp | 5 - src/engraving/rw/read206/read206.cpp | 6 - src/engraving/rw/read400/tread.cpp | 10 +- src/engraving/rw/read410/tread.cpp | 10 +- src/engraving/rw/read460/tread.cpp | 107 +- src/engraving/rw/read460/tread.h | 13 +- src/engraving/rw/write/twrite.cpp | 107 +- src/engraving/rw/write/twrite.h | 11 +- src/engraving/style/style.cpp | 10 + src/engraving/style/styledef.cpp | 12 + src/engraving/style/styledef.h | 11 + src/engraving/types/propertyvalue.cpp | 2 + src/engraving/types/propertyvalue.h | 4 + src/engraving/types/types.h | 7 + src/engraving/types/typesconv.cpp | 17 + src/engraving/types/typesconv.h | 3 + .../bww/internal/bww/importbww.cpp | 1 - src/importexport/capella/internal/capella.cpp | 1 - .../guitarpro/internal/gtp/gpconverter.cpp | 1 - .../guitarpro/internal/importgtp-gp4.cpp | 1 - .../guitarpro/internal/importgtp-gp5.cpp | 1 - .../guitarpro/internal/importgtp.cpp | 2 - .../guitarpro/internal/importptb.cpp | 1 - .../midi/internal/midiimport/importmidi.cpp | 1 - .../mnx/internal/import/mnximporter.cpp | 1 - .../internal/import/importmusicxmlpass2.cpp | 8 +- .../tabledit/internal/importtef.cpp | 1 - .../instrumentname/InstrumentNameSettings.qml | 2 +- .../internal/InstrumentSettingsPopup.qml | 28 + .../internal/instrumentsettingsmodel.cpp | 17 + .../internal/instrumentsettingsmodel.h | 4 + .../internal/parttreeitem.cpp | 4 +- .../internal/stafftreeitem.cpp | 5 +- src/notation/inotationparts.h | 1 + src/notation/internal/notationparts.cpp | 67 +- src/notation/internal/notationparts.h | 1 + src/notation/notationtypes.h | 3 +- .../internal/notationuiactions.cpp | 4 +- .../styledialog/InstrumentNamesPage.qml | 170 +- .../styledialog/instrumentnamespagemodel.cpp | 76 +- .../styledialog/instrumentnamespagemodel.h | 22 + src/notationscene/widgets/editstaff.cpp | 34 + src/notationscene/widgets/editstaff.ui | 2032 +++++++++-------- 64 files changed, 2779 insertions(+), 1340 deletions(-) create mode 100644 src/engraving/dom/stafflabel.h delete mode 100644 src/engraving/dom/staffname.h diff --git a/src/engraving/api/tests/score_tests.cpp b/src/engraving/api/tests/score_tests.cpp index c34cb04e3f83f..e947f68ab5a62 100644 --- a/src/engraving/api/tests/score_tests.cpp +++ b/src/engraving/api/tests/score_tests.cpp @@ -78,7 +78,7 @@ TEST_F(Engraving_ApiScoreTests, replaceInstrumentAtDomLevel) newInstrument.setTrackName(u"Replaced Instrument"); score->startCmd(TranslatableString::untranslatable("Replace instrument test")); - score->undo(new ChangePart(part, new Instrument(newInstrument), u"Replaced Part")); + score->undo(new ChangePart(part, new Instrument(newInstrument))); score->endCmd(); // [THEN] The part's instrument should be changed @@ -116,7 +116,7 @@ TEST_F(Engraving_ApiScoreTests, replaceInstrumentUndo) newInstrument.setTrackName(u"New Instrument"); score->startCmd(TranslatableString::untranslatable("Replace instrument test")); - score->undo(new ChangePart(part, new Instrument(newInstrument), u"New Part")); + score->undo(new ChangePart(part, new Instrument(newInstrument))); score->endCmd(); // Verify it changed @@ -155,7 +155,7 @@ TEST_F(Engraving_ApiScoreTests, replaceInstrumentRedo) newInstrument.setId(u"test.replaced"); score->startCmd(TranslatableString::untranslatable("Replace instrument test")); - score->undo(new ChangePart(part, new Instrument(newInstrument), u"Replaced")); + score->undo(new ChangePart(part, new Instrument(newInstrument))); score->endCmd(); EXPECT_EQ(part->instrumentId(), u"test.replaced"); diff --git a/src/engraving/dom/dom.cmake b/src/engraving/dom/dom.cmake index 05c04af4b2659..e9e002a0716ba 100644 --- a/src/engraving/dom/dom.cmake +++ b/src/engraving/dom/dom.cmake @@ -286,7 +286,7 @@ set(DOM_SRC ${CMAKE_CURRENT_LIST_DIR}/staff.h ${CMAKE_CURRENT_LIST_DIR}/stafflines.cpp ${CMAKE_CURRENT_LIST_DIR}/stafflines.h - ${CMAKE_CURRENT_LIST_DIR}/staffname.h + ${CMAKE_CURRENT_LIST_DIR}/stafflabel.h ${CMAKE_CURRENT_LIST_DIR}/staffstate.cpp ${CMAKE_CURRENT_LIST_DIR}/staffstate.h ${CMAKE_CURRENT_LIST_DIR}/stafftext.cpp diff --git a/src/engraving/dom/excerpt.cpp b/src/engraving/dom/excerpt.cpp index 221782bac1a74..748f61e1abf91 100644 --- a/src/engraving/dom/excerpt.cpp +++ b/src/engraving/dom/excerpt.cpp @@ -361,7 +361,6 @@ void Excerpt::createExcerpt(Excerpt* excerpt) Part* p = new Part(score); p->setId(part->id()); p->setInstrument(*part->instrument()); - p->setPartName(part->partName()); p->setPreferSharpFlat(part->preferSharpFlat()); for (Staff* staff : part->staves()) { diff --git a/src/engraving/dom/instrtemplate.h b/src/engraving/dom/instrtemplate.h index fa5f57627e79f..ec1a2d8820728 100644 --- a/src/engraving/dom/instrtemplate.h +++ b/src/engraving/dom/instrtemplate.h @@ -84,7 +84,7 @@ class InstrumentTemplate String id; String soundId; String trackName; - StaffName instrumentName; + InstrumentLabel instrumentName; String musicXmlId; ///< used in MusicXML 3.0 String description; ///< a longer description of the instrument diff --git a/src/engraving/dom/instrument.cpp b/src/engraving/dom/instrument.cpp index 04175035b4b12..36df940fd7d5c 100644 --- a/src/engraving/dom/instrument.cpp +++ b/src/engraving/dom/instrument.cpp @@ -74,7 +74,7 @@ Instrument::Instrument(const Instrument& i) { m_id = i.m_id; m_soundId = i.m_soundId; - m_instrumentName = i.m_instrumentName; + m_instrumentLabel = i.m_instrumentLabel; m_trackName = i.m_trackName; m_minPitchA = i.m_minPitchA; m_maxPitchA = i.m_maxPitchA; @@ -106,7 +106,7 @@ void Instrument::operator=(const Instrument& i) m_id = i.m_id; m_soundId = i.m_soundId; - m_instrumentName = i.m_instrumentName; + m_instrumentLabel = i.m_instrumentLabel; m_trackName = i.m_trackName; m_minPitchA = i.m_minPitchA; m_maxPitchA = i.m_maxPitchA; @@ -152,8 +152,8 @@ String Instrument::recognizeMusicXmlId() const nameList.reserve(3); nameList.push_back(m_trackName); - nameList.push_back(m_instrumentName.longName()); - nameList.push_back(m_instrumentName.shortName()); + nameList.push_back(m_instrumentLabel.longName()); + nameList.push_back(m_instrumentLabel.shortName()); const InstrumentTemplate* tmplByName = mu::engraving::searchTemplateForInstrNameList(nameList, m_useDrumset); @@ -805,7 +805,7 @@ void Instrument::setGlissandoStyle(GlissandoStyle style) bool Instrument::operator==(const Instrument& i) const { - bool equal = i.m_instrumentName == m_instrumentName; + bool equal = i.m_instrumentLabel == m_instrumentLabel; equal &= i.m_trackName == m_trackName; equal &= i.m_id == m_id; equal &= i.m_soundId == m_soundId; @@ -864,14 +864,36 @@ bool Instrument::isDifferentInstrument(const Instrument& i) const String Instrument::family() const { - auto search = searchTemplateIndexForId(m_id); + static const String NO_FAMILY = u"-"; - if (!search.instrTemplate) { - static String empty; - return empty; + if (m_familyCache.empty()) { + auto search = searchTemplateIndexForId(m_id); + + if (search.instrTemplate) { + m_familyCache = search.instrTemplate->familyId(); + } else { + m_familyCache = NO_FAMILY; + } + } + + return m_familyCache == NO_FAMILY ? String() : m_familyCache; +} + +String Instrument::group() const +{ + static const String NO_GROUP = u"-"; + + if (m_groupCache.empty()) { + auto search = searchTemplateIndexForId(m_id); + + if (search.instrTemplate) { + m_groupCache = search.instrTemplate->groupId; + } else { + m_groupCache = NO_GROUP; + } } - return search.instrTemplate->familyId(); + return m_groupCache == NO_GROUP ? String() : m_groupCache; } //--------------------------------------------------------- @@ -1051,22 +1073,22 @@ void Instrument::setTrackName(const String& s) String Instrument::nameAsXmlText() const { - return m_instrumentName.longName(); + return m_instrumentLabel.longName(); } String Instrument::nameAsPlainText() const { - return TextBase::unEscape(m_instrumentName.longName()); + return TextBase::unEscape(m_instrumentLabel.longName()); } String Instrument::abbreviatureAsXmlText() const { - return m_instrumentName.shortName(); + return m_instrumentLabel.shortName(); } String Instrument::abbreviatureAsPlainText() const { - return TextBase::unEscape(m_instrumentName.shortName()); + return TextBase::unEscape(m_instrumentLabel.shortName()); } Instrument Instrument::fromTemplate(const InstrumentTemplate* templ) diff --git a/src/engraving/dom/instrument.h b/src/engraving/dom/instrument.h index 2c71994a08f84..95a01285bdcbf 100644 --- a/src/engraving/dom/instrument.h +++ b/src/engraving/dom/instrument.h @@ -29,7 +29,7 @@ #include "clef.h" #include "interval.h" #include "notifier.h" -#include "staffname.h" +#include "stafflabel.h" #include "stringdata.h" #include "../compat/midi/midicoreevent.h" @@ -285,6 +285,7 @@ class Instrument const String& soundId() const { return m_soundId; } void setSoundId(const String& id) { m_soundId = id; } String family() const; + String group() const; void setId(const String& id) { m_id = id; } void setMinPitchP(int v) { m_minPitchP = v; } void setMaxPitchP(int v) { m_maxPitchP = v; } @@ -326,12 +327,19 @@ class Instrument void setStringData(const StringData& d) { m_stringData.set(d); } bool hasStrings() const { return m_stringData.strings() > 0; } - void setLongName(const String& f) { m_instrumentName.setLongName(f); } - void setShortName(const String& f) { m_instrumentName.setShortName(f); } - void setInstrumentName(const StaffName& n) { m_instrumentName = n; } - const String& longName() const { return m_instrumentName.longName(); } - const String& shortName() const { return m_instrumentName.shortName(); } - const StaffName& instrumentName() const { return m_instrumentName; } + void setLongName(const String& f) { m_instrumentLabel.setLongName(f); } + void setShortName(const String& f) { m_instrumentLabel.setShortName(f); } + void setInstrumentName(const InstrumentLabel& n) { m_instrumentLabel = n; } + const String& longName() const { return m_instrumentLabel.longName(); } + const String& shortName() const { return m_instrumentLabel.shortName(); } + const InstrumentLabel& instrumentLabel() const { return m_instrumentLabel; } + InstrumentLabel& instrumentLabel() { return m_instrumentLabel; } + + int number() const { return m_instrumentLabel.number(); } + void setNumber(int v) { return m_instrumentLabel.setNumber(v); } + + const String& transposition() const { return m_instrumentLabel.transposition(); } + void setTransposition(const String& s) { m_instrumentLabel.setTransposition(s); } int minPitchP() const; int maxPitchP() const; @@ -369,7 +377,7 @@ class Instrument private: - StaffName m_instrumentName; + InstrumentLabel m_instrumentLabel; String m_trackName; String m_id; @@ -396,6 +404,9 @@ class Instrument Trait m_trait; bool m_isPrimary = false; + mutable String m_familyCache; + mutable String m_groupCache; + GlissandoStyle m_glissandoStyle = GlissandoStyle::CHROMATIC; }; diff --git a/src/engraving/dom/instrumentname.cpp b/src/engraving/dom/instrumentname.cpp index 825826dbca0f3..877d8d949a696 100644 --- a/src/engraving/dom/instrumentname.cpp +++ b/src/engraving/dom/instrumentname.cpp @@ -116,8 +116,12 @@ mu::engraving::staff_idx_t mu::engraving::InstrumentName::effectiveStaffIdx() co { if (m_sysStaff->show() || m_instrumentNameRole == InstrumentNameRole::STAFF) { return staffIdx(); + } else if (m_instrumentNameRole == InstrumentNameRole::PART) { + return system()->firstVisibleSysStaffOfPart(score()->staff(staffIdx())->part()); + } else { + staff_idx_t curIdx = staffIdx(); + Instrument* instr = score()->staff(curIdx)->part()->instrument(system()->first()->tick()); + return system()->firstVisibleSysStaffWithInstrument(instr->id(), curIdx); } - - return system()->firstVisibleSysStaffOfPart(score()->staff(staffIdx())->part()); } } diff --git a/src/engraving/dom/instrumentname.h b/src/engraving/dom/instrumentname.h index 96072a5d58f1d..bed988de03cc6 100644 --- a/src/engraving/dom/instrumentname.h +++ b/src/engraving/dom/instrumentname.h @@ -30,7 +30,7 @@ enum class InstrumentNameType : char { LONG, SHORT }; enum class InstrumentNameRole : char { - STAFF, PART + STAFF, PART, GROUP }; class System; @@ -71,11 +71,25 @@ class InstrumentName final : public TextBase staff_idx_t effectiveStaffIdx() const override; + staff_idx_t endIdxOfGroup() const { return m_endIdxOfGroup; } + void setEndIdxOfGroup(staff_idx_t v) { m_endIdxOfGroup = v; } + + struct LayoutData : public TextBase::LayoutData { + public: + int column() const { return m_column; } + void setColumn(int v) { m_column = v; } + + private: + int m_column = 0; + }; + DECLARE_LAYOUTDATA_METHODS(InstrumentName) + private: InstrumentNameType m_instrumentNameType = InstrumentNameType::LONG; InstrumentNameRole m_instrumentNameRole = InstrumentNameRole::PART; SysStaff* m_sysStaff = nullptr; + staff_idx_t m_endIdxOfGroup = muse::nidx; // one-after last spanned staff (for GROUP types) }; } // namespace mu::engraving #endif diff --git a/src/engraving/dom/part.cpp b/src/engraving/dom/part.cpp index 8bfb37a16e760..307c50a16d55d 100644 --- a/src/engraving/dom/part.cpp +++ b/src/engraving/dom/part.cpp @@ -67,7 +67,6 @@ Part::Part(Score* s) void Part::initFromInstrTemplate(const InstrumentTemplate* t) { - m_partName = t->instrumentName.longName(); setInstrument(Instrument::fromTemplate(t)); } @@ -557,6 +556,26 @@ void Part::setShortNameAll(const String& s) } } +int Part::number(const Fraction& tick) const +{ + return instrument(tick)->number(); +} + +void Part::setNumber(int v, const Fraction& tick) +{ + instrument(tick)->setNumber(v); +} + +String Part::transposition(const Fraction& tick) const +{ + return instrument(tick)->transposition(); +} + +void Part::setTransposition(const String& s, const Fraction& tick) +{ + instrument(tick)->setTransposition(s); +} + //--------------------------------------------------------- // setPlainLongName //--------------------------------------------------------- @@ -832,6 +851,24 @@ Fraction Part::currentHarpDiagramTick(const Fraction& tick) const return Fraction::fromTicks(i->first); } +String Part::partName() const +{ + const Instrument* i = instrument(); + String fullName = i->longName(); + + const String& transp = i->transposition(); + if (!transp.empty()) { + fullName += u" " + muse::mtrc("notation", "in") + u" " + transp; + } + + int n = number(); + if (n != 0) { + fullName += u" " + String::number(n); + } + + return fullName; +} + bool Part::isVisible() const { return m_show; diff --git a/src/engraving/dom/part.h b/src/engraving/dom/part.h index c40de9303933a..c87d7de45b020 100644 --- a/src/engraving/dom/part.h +++ b/src/engraving/dom/part.h @@ -103,6 +103,12 @@ class Part final : public EngravingObject void setLongNameAll(const String& s); // For all instruments in _instruments void setShortNameAll(const String& s); // For all instruments in _instruments + int number(const Fraction& tick = { -1, 1 }) const; + void setNumber(int v, const Fraction& tick = { -1, 1 }); + + String transposition(const Fraction& tick = { -1, 1 }) const; + void setTransposition(const String& s, const Fraction& tick = { -1, 1 }); + void setPlainLongName(const String& s); void setPlainShortName(const String& s); void setPlainLongNameAll(const String& s); @@ -153,8 +159,8 @@ class Part final : public EngravingObject HarpPedalDiagram* prevHarpDiagram(const Fraction&) const; Fraction currentHarpDiagramTick(const Fraction&) const; - String partName() const { return m_partName; } - void setPartName(const String& s) { m_partName = s; } + String partName() const; + int color() const { return m_color; } void setColor(int value) { m_color = value; } @@ -196,7 +202,6 @@ class Part final : public EngravingObject private: friend class read206::Read206; - String m_partName; ///< used in tracklist (mixer) InstrumentList m_instruments; std::vector m_staves; muse::ID m_id = INVALID_ID; ///< used for MusicXML import diff --git a/src/engraving/dom/stafflabel.h b/src/engraving/dom/stafflabel.h new file mode 100644 index 0000000000000..9250e22d5bf0e --- /dev/null +++ b/src/engraving/dom/stafflabel.h @@ -0,0 +1,148 @@ +/* + * SPDX-License-Identifier: GPL-3.0-only + * MuseScore-Studio-CLA-applies + * + * MuseScore Studio + * Music Composition & Notation + * + * Copyright (C) 2021 MuseScore Limited + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include "global/types/string.h" + +namespace mu::engraving { +class StaffLabel +{ +public: + StaffLabel() = default; + StaffLabel(const muse::String& longName, const muse::String& shortName) + : m_longName(longName), m_shortName(shortName) {} + + bool operator==(const StaffLabel& i) const { return m_longName == i.m_longName && m_shortName == i.m_shortName; } + + const muse::String& longName() const { return m_longName; } + const muse::String& shortName() const { return m_shortName; } + void setLongName(const muse::String& s) { m_longName = s; } + void setShortName(const muse::String& s) { m_shortName = s; } + + bool empty() const { return m_longName.empty() && m_shortName.empty(); } + +private: + muse::String m_longName; + muse::String m_shortName; +}; + +class InstrumentLabel : public StaffLabel +{ +public: + bool operator==(const InstrumentLabel& i) const; + + int number() const { return m_number; } + void setNumber(int v) { m_number = v; } + + const muse::String& transposition() const { return m_transposition; } + void setTransposition(const muse::String& s) { m_transposition = s; } + + bool showNumberLong() const { return m_showNumberLong; } + void setShowNumberLong(bool v) { m_showNumberLong = v; } + + bool showNumberShort() const { return m_showNumberShort; } + void setShowNumberShort(bool v) { m_showNumberShort = v; } + + bool showTranspositionLong() const { return m_showTranspositionLong; } + void setShowTranspositionLong(bool v) { m_showTranspositionLong = v; } + + bool showTranspositionShort() const { return m_showTranspositionShort; } + void setShowTranspositionShort(bool v) { m_showTranspositionShort = v; } + + bool allowGroupName() const { return m_allowGroupName; } + void setAllowGroupName(bool v) { m_allowGroupName = v; } + + muse::String customNameLong() const { return m_customNameLong; } + void setCustomNameLong(const muse::String& v) { m_customNameLong = v; } + + muse::String customNameShort() const { return m_customNameShort; } + void setCustomNameShort(const muse::String& v) { m_customNameShort = v; } + + bool useCustomNameLong() const { return m_useCustomNameLong; } + void setUseCustomNameLong(bool v) { m_useCustomNameLong = v; } + + bool useCustomNameShort() const { return m_useCustomNameShort; } + void setUseCustomNameShort(bool v) { m_useCustomNameShort = v; } + + muse::String customNameLongGroup() const { return m_customNameLongGroup; } + void setCustomNameLongGroup(const muse::String& v) { m_customNameLongGroup = v; } + + muse::String customNameShortGroup() const { return m_customNameShortGroup; } + void setCustomNameShortGroup(const muse::String& v) { m_customNameShortGroup = v; } + + bool useCustomNameLongGroup() const { return m_useCustomNameLongGroup; } + void setUseCustomNameLongGroup(bool v) { m_useCustomNameLongGroup = v; } + + bool useCustomNameShortGroup() const { return m_useCustomNameShortGroup; } + void setUseCustomNameShortGroup(bool v) { m_useCustomNameShortGroup = v; } + + bool empty() const; + +private: + int m_number = 0; + bool m_showNumberLong = true; + bool m_showNumberShort = true; + + muse::String m_transposition; + bool m_showTranspositionLong = true; + bool m_showTranspositionShort = true; + + muse::String m_customNameLong; + muse::String m_customNameShort; + bool m_useCustomNameLong = false; + bool m_useCustomNameShort = false; + + bool m_allowGroupName = true; + + muse::String m_customNameLongGroup; + muse::String m_customNameShortGroup; + bool m_useCustomNameLongGroup = false; + bool m_useCustomNameShortGroup = false; +}; + +inline bool InstrumentLabel::operator==(const InstrumentLabel& i) const +{ + return StaffLabel::operator==(i) + && m_number == i.m_number + && m_transposition == i.m_transposition + && m_showNumberLong == i.m_showNumberLong + && m_showNumberShort == i.m_showNumberShort + && m_showTranspositionLong == i.m_showTranspositionLong + && m_showTranspositionShort == i.m_showTranspositionShort + && m_allowGroupName == i.m_allowGroupName + && m_customNameLong == i.m_customNameLong + && m_customNameShort == i.m_customNameShort + && m_useCustomNameLong == i.m_useCustomNameLong + && m_useCustomNameShort == i.m_useCustomNameShort + && m_customNameLongGroup == i.m_customNameLongGroup + && m_customNameShortGroup == i.m_customNameShortGroup + && m_useCustomNameLongGroup == i.m_useCustomNameLongGroup + && m_useCustomNameShortGroup == i.m_useCustomNameShortGroup; +} + +inline bool InstrumentLabel::empty() const +{ + static const InstrumentLabel EMPTY_LABEL = InstrumentLabel(); + + return *this == EMPTY_LABEL; +} +} diff --git a/src/engraving/dom/staffname.h b/src/engraving/dom/staffname.h deleted file mode 100644 index 93c8c7c8e38c5..0000000000000 --- a/src/engraving/dom/staffname.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-3.0-only - * MuseScore-Studio-CLA-applies - * - * MuseScore Studio - * Music Composition & Notation - * - * Copyright (C) 2021 MuseScore Limited - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 3 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#pragma once - -#include "global/types/string.h" - -namespace mu::engraving { -class StaffName -{ -public: - StaffName() = default; - StaffName(const muse::String& longName, const muse::String& shortName) - : m_longName(longName), m_shortName(shortName) {} - - bool operator==(const StaffName& i) const { return m_longName == i.m_longName && m_shortName == i.m_shortName; } - - const muse::String& longName() const { return m_longName; } - const muse::String& shortName() const { return m_shortName; } - void setLongName(const muse::String& s) { m_longName = s; } - void setShortName(const muse::String& s) { m_shortName = s; } - - bool empty() const { return m_longName.empty() && m_shortName.empty(); } - -private: - muse::String m_longName; - muse::String m_shortName; -}; -} diff --git a/src/engraving/dom/stafftype.cpp b/src/engraving/dom/stafftype.cpp index c2167e861d798..72d81444e02d5 100644 --- a/src/engraving/dom/stafftype.cpp +++ b/src/engraving/dom/stafftype.cpp @@ -177,7 +177,7 @@ bool StaffType::operator==(const StaffType& st) const equal &= (m_group == st.m_group); equal &= (m_xmlName == st.m_xmlName); equal &= (m_staffTypeName == st.m_staffTypeName); - equal &= (m_staffName == st.m_staffName); + equal &= (m_staffLabel == st.m_staffLabel); equal &= (m_userMag == st.m_userMag); equal &= (m_yoffset == st.m_yoffset); equal &= (m_small == st.m_small); diff --git a/src/engraving/dom/stafftype.h b/src/engraving/dom/stafftype.h index 6bf6c86632ae7..36e09f5946da7 100644 --- a/src/engraving/dom/stafftype.h +++ b/src/engraving/dom/stafftype.h @@ -27,7 +27,7 @@ #include "draw/types/font.h" #include "engravingitem.h" -#include "staffname.h" +#include "stafflabel.h" #include "../types/types.h" @@ -180,11 +180,12 @@ class StaffType void setXmlName(const String& val) { m_xmlName = val; } String translatedGroupName() const; - const StaffName& staffName() const { return m_staffName; } - const String& longName() const { return m_staffName.longName(); } - const String& shortName() const { return m_staffName.shortName(); } - void setLongName(const String& s) { m_staffName.setLongName(s); } - void setShortName(const String& s) { m_staffName.setShortName(s); } + const StaffLabel& staffLabel() const { return m_staffLabel; } + StaffLabel& staffLabel() { return m_staffLabel; } + const String& longName() const { return m_staffLabel.longName(); } + const String& shortName() const { return m_staffLabel.shortName(); } + void setLongName(const String& s) { m_staffLabel.setLongName(s); } + void setShortName(const String& s) { m_staffLabel.setShortName(s); } void setLines(int val) { m_lines = val; } int lines() const { return m_lines; } @@ -335,7 +336,7 @@ class StaffType String m_xmlName; // the name used to reference this preset in instruments.xml String m_staffTypeName; // user visible name - StaffName m_staffName; + StaffLabel m_staffLabel; double m_userMag = 1.0; // allowed 0.1 - 10.0 Spatium m_yoffset; diff --git a/src/engraving/dom/system.cpp b/src/engraving/dom/system.cpp index 41139edfd04a1..6df67115edb56 100644 --- a/src/engraving/dom/system.cpp +++ b/src/engraving/dom/system.cpp @@ -70,6 +70,7 @@ namespace mu::engraving { SysStaff::~SysStaff() { + delete groupName; delete instrumentName; delete individualStaffName; } @@ -476,15 +477,19 @@ void System::add(EngravingItem* el) switch (el->type()) { case ElementType::INSTRUMENT_NAME: -// LOGD(" staffIdx %d, staves %d", el->staffIdx(), _staves.size()); - if (toInstrumentName(el)->instrumentNameRole() == InstrumentNameRole::PART) { - m_staves[el->staffIdx()]->instrumentName = toInstrumentName(el); + { + InstrumentName* n = toInstrumentName(el); + SysStaff* sysStaff = m_staves[n->staffIdx()]; + if (n->instrumentNameRole() == InstrumentNameRole::GROUP) { + sysStaff->groupName = n; + } else if (n->instrumentNameRole() == InstrumentNameRole::PART) { + sysStaff->instrumentName = n; } else { - m_staves[el->staffIdx()]->individualStaffName = toInstrumentName(el); + sysStaff->individualStaffName = n; } - toInstrumentName(el)->setSysStaff(m_staves[el->staffIdx()]); + n->setSysStaff(sysStaff); break; - + } case ElementType::BEAM: score()->addElement(el); break; @@ -566,14 +571,20 @@ void System::remove(EngravingItem* el) { switch (el->type()) { case ElementType::INSTRUMENT_NAME: + { // TODO: I'm pretty sure that this gets leadked. Needs fixing. - if (toInstrumentName(el)->instrumentNameRole() == InstrumentNameRole::PART) { - m_staves[el->staffIdx()]->instrumentName = nullptr; + InstrumentName* n = toInstrumentName(el); + SysStaff* sysStaff = m_staves[n->staffIdx()]; + if (n->instrumentNameRole() == InstrumentNameRole::GROUP) { + sysStaff->groupName = nullptr; + } else if (n->instrumentNameRole() == InstrumentNameRole::PART) { + sysStaff->instrumentName = nullptr; } else { - m_staves[el->staffIdx()]->individualStaffName = nullptr; + sysStaff->individualStaffName = nullptr; } - toInstrumentName(el)->setSysStaff(0); + n->setSysStaff(0); break; + } case ElementType::BEAM: score()->removeElement(el); break; @@ -736,14 +747,22 @@ void System::scanElements(std::function func) for (const SysStaff* st : m_staves) { if (st->show()) { + if (InstrumentName* n = st->groupName) { + func(n); + } if (InstrumentName* t = st->instrumentName) { func(t); } if (InstrumentName* n = st->individualStaffName) { func(n); } - } else if (InstrumentName* n = st->instrumentName; n && n->effectiveStaffIdx() != muse::nidx) { - func(n); + } else { + if (InstrumentName* n = st->groupName; n && n->effectiveStaffIdx() != muse::nidx) { + func(n); + } + if (InstrumentName* n = st->instrumentName; n && n->effectiveStaffIdx() != muse::nidx) { + func(n); + } } } @@ -1169,6 +1188,22 @@ staff_idx_t System::firstVisibleSysStaffOfPart(const Part* part) const return muse::nidx; // No visible staves on this part. } +staff_idx_t System::firstVisibleSysStaffWithInstrument(const String& instrumentId, staff_idx_t startFrom) +{ + Fraction tick = first()->tick(); + for (staff_idx_t idx = startFrom; idx < m_staves.size(); ++idx) { + Part* part = score()->staff(idx)->part(); + if (part->instrument(tick)->id() == instrumentId) { + staff_idx_t firstVisOfPart = firstVisibleSysStaffOfPart(part); + if (firstVisOfPart != muse::nidx) { + return firstVisOfPart; + } + } + } + + return muse::nidx; +} + //--------------------------------------------------------- // lastSysStaffOfPart //--------------------------------------------------------- @@ -1215,4 +1250,19 @@ std::vector System::visibleStavesOfPart(const Part* part) const return result; } + +std::vector mu::engraving::System::visiblePartsOfGroup(staff_idx_t start, staff_idx_t end) const +{ + std::vector result; + + for (staff_idx_t idx = start; idx < end;) { + Part* part = score()->staff(idx)->part(); + if (visibleStavesOfPart(part).size() > 0) { + result.push_back(part); + } + idx += part->nstaves(); + } + + return result; +} } diff --git a/src/engraving/dom/system.h b/src/engraving/dom/system.h index e1adaf34bd351..5f4007c6f136b 100644 --- a/src/engraving/dom/system.h +++ b/src/engraving/dom/system.h @@ -28,6 +28,7 @@ */ #include "engravingitem.h" +#include "stafflabel.h" namespace mu::engraving { class Box; @@ -50,6 +51,7 @@ class SysStaff SysStaff() {} ~SysStaff(); + InstrumentName* groupName = nullptr; InstrumentName* instrumentName = nullptr; InstrumentName* individualStaffName = nullptr; @@ -191,9 +193,11 @@ class System final : public EngravingItem staff_idx_t firstSysStaffOfPart(const Part* part) const; staff_idx_t firstVisibleSysStaffOfPart(const Part* part) const; + staff_idx_t firstVisibleSysStaffWithInstrument(const String& instrumentId, staff_idx_t startFrom); staff_idx_t lastSysStaffOfPart(const Part* part) const; staff_idx_t lastVisibleSysStaffOfPart(const Part* part) const; std::vector visibleStavesOfPart(const Part* part) const; + std::vector visiblePartsOfGroup(staff_idx_t start, staff_idx_t end) const; #ifndef ENGRAVING_NO_ACCESSIBILITY AccessibleItemPtr createAccessible() override; @@ -220,19 +224,27 @@ class System final : public EngravingItem void setUseLongNames(bool v) { m_useLongNames = v; } double instrumentNameOffset() const { return m_instrumentNameOffset; } void setInstrumentNameOffset(double v) { m_instrumentNameOffset = v; } - double staffNamesWidth() const { return m_staffNamesWidth; } - void setStaffNamesWidth(double v) { m_staffNamesWidth = v; } - double instrumentNamesWidth() const { return m_instrumentNamesWidth; } - void setInstrumentNamesWidth(double v) { m_instrumentNamesWidth = v; } + + double firstColumnWidth() const { return m_firstColumnWidth; } + void setFirstColumnWidth(double v) { m_firstColumnWidth = v; } + double secondColumnWidth() const { return m_secondColumnWidth; } + void setSecondColumnWidth(double v) { m_secondColumnWidth = v; } double totalNamesWidth() const { return m_totalNamesWidth; } void setTotalNamesWidth(double v) { m_totalNamesWidth = v; } + const std::unordered_map& partsWithGroupName() const { return m_partsWithGroupName; } + void addPartWithGroupNames(Part* p, InstrumentName* n) { m_partsWithGroupName.emplace(p, n); } + void clearPartsWithGroupNames() { m_partsWithGroupName.clear(); } + private: bool m_useLongNames = false; double m_instrumentNameOffset = 0.0; - double m_staffNamesWidth = 0.0; - double m_instrumentNamesWidth = 0.0; + + double m_firstColumnWidth = 0.0; + double m_secondColumnWidth = 0.0; double m_totalNamesWidth = 0.0; + + std::unordered_map m_partsWithGroupName; }; DECLARE_LAYOUTDATA_METHODS(System) diff --git a/src/engraving/editing/editpart.cpp b/src/engraving/editing/editpart.cpp index 8dc41985abf53..bcd127aebfff9 100644 --- a/src/engraving/editing/editpart.cpp +++ b/src/engraving/editing/editpart.cpp @@ -122,19 +122,16 @@ void SetSoloist::redo(EditData*) // ChangePart //--------------------------------------------------------- -ChangePart::ChangePart(Part* _part, Instrument* i, const String& s) +ChangePart::ChangePart(Part* _part, Instrument* i) { instrument = i; part = _part; - partName = s; } void ChangePart::flip(EditData*) { Instrument* oi = part->instrument(); //tick? - String s = part->partName(); part->setInstrument(instrument); - part->setPartName(partName); part->updateHarmonyChannels(false); @@ -148,7 +145,6 @@ void ChangePart::flip(EditData*) score->setLayoutAll(); - partName = s; instrument = oi; } @@ -192,6 +188,19 @@ void ChangeInstrumentShort::flip(EditData*) part->score()->setLayoutAll(); } +ChangeInstrumentNumber::ChangeInstrumentNumber(const Fraction& _tick, Part* p, int v) + : part(p), tick(_tick), number(v) +{ +} + +void ChangeInstrumentNumber::flip(EditData*) +{ + int v = part->number(tick); + part->setNumber(number, tick); + number = v; + part->score()->setLayoutAll(); +} + //--------------------------------------------------------- // ChangeDrumset //--------------------------------------------------------- @@ -300,15 +309,13 @@ static InstrumentChange* findInstrumentChange(Score* score, const Part* part, co } void EditPart::replacePartInstrument(Score* score, Part* part, const Instrument& newInstrument, - const StaffType* newStaffType, const String& partName) + const StaffType* newStaffType) { if (!score || !part) { return; } - // Change the part's instrument and name - String newPartName = partName.isEmpty() ? newInstrument.trackName() : partName; - score->undo(new ChangePart(part, new Instrument(newInstrument), newPartName)); + score->undo(new ChangePart(part, new Instrument(newInstrument))); // Update clefs and staff type for all staves in the part for (staff_idx_t staffIdx = 0; staffIdx < part->nstaves(); ++staffIdx) { diff --git a/src/engraving/editing/editpart.h b/src/engraving/editing/editpart.h index 98b94ab0c9cd9..747291f1e8a1d 100644 --- a/src/engraving/editing/editpart.h +++ b/src/engraving/editing/editpart.h @@ -90,12 +90,11 @@ class ChangePart : public UndoCommand Part* part = nullptr; Instrument* instrument = nullptr; - String partName; void flip(EditData*) override; public: - ChangePart(Part*, Instrument*, const String& name); + ChangePart(Part*, Instrument*); void cleanup(bool) override; UNDO_TYPE(CommandType::ChangePart) @@ -139,6 +138,24 @@ class ChangeInstrumentShort : public UndoCommand UNDO_CHANGED_OBJECTS({ part }) }; +class ChangeInstrumentNumber : public UndoCommand +{ + OBJECT_ALLOCATOR(engraving, ChangeInstrumentNumber) + + Part* part = nullptr; + Fraction tick; + int number; + + void flip(EditData*) override; + +public: + ChangeInstrumentNumber(const Fraction&, Part*, int v); + + UNDO_TYPE(CommandType::ChangeInstrumentNumber) + UNDO_NAME("ChangeInstrumentNumber") + UNDO_CHANGED_OBJECTS({ part }) +}; + class ChangeDrumset : public UndoCommand { OBJECT_ALLOCATOR(engraving, ChangeDrumset) @@ -213,8 +230,7 @@ enum class StaffTypes : signed char; class EditPart { public: - static void replacePartInstrument(Score* score, Part* part, const Instrument& newInstrument, const StaffType* newStaffType = nullptr, - const String& partName = String()); + static void replacePartInstrument(Score* score, Part* part, const Instrument& newInstrument, const StaffType* newStaffType = nullptr); static bool replaceInstrumentAtTick(Score* score, Part* part, const Fraction& tick, const Instrument& newInstrument); diff --git a/src/engraving/editing/undo.h b/src/engraving/editing/undo.h index 3d9543a16484d..bcd349011a01c 100644 --- a/src/engraving/editing/undo.h +++ b/src/engraving/editing/undo.h @@ -65,6 +65,7 @@ enum class CommandType : signed char { // Instruments ChangeInstrumentShort, ChangeInstrumentLong, + ChangeInstrumentNumber, ChangeInstrument, ChangeDrumset, diff --git a/src/engraving/rendering/score/systemheaderlayout.cpp b/src/engraving/rendering/score/systemheaderlayout.cpp index b4bb720298b28..1505bd86eef55 100644 --- a/src/engraving/rendering/score/systemheaderlayout.cpp +++ b/src/engraving/rendering/score/systemheaderlayout.cpp @@ -309,84 +309,138 @@ void SystemHeaderLayout::computeInstrumentNameOffset(System* system, LayoutConte void SystemHeaderLayout::computeInstrumentNamesWidth(System* system, LayoutContext& ctx) { System::LayoutData* ldata = system->mutldata(); - ldata->setStaffNamesWidth(0.0); - ldata->setInstrumentNamesWidth(0.0); + ldata->setFirstColumnWidth(0.0); + ldata->setSecondColumnWidth(0.0); ldata->setTotalNamesWidth(0.0); - std::set partsWithIndividualStaffNames; + std::unordered_set partsWithIndividualStaffNames; + std::unordered_set partsWithGroupNames; - for (staff_idx_t staffIdx = 0; staffIdx < ctx.dom().nstaves(); ++staffIdx) { - if (!ctx.dom().staff(staffIdx)->show()) { - // We know that the staff is hidden in the entire score so safe to skip - continue; + std::vector groupNames; + std::vector instrumentNames; + + for (staff_idx_t staffIdx = 0; staffIdx < system->staves().size(); ++staffIdx) { + const SysStaff* sysStaff = system->staff(staffIdx); + const Staff* staff = ctx.dom().staff(staffIdx); + + if (InstrumentName* groupName = sysStaff->groupName) { + if (ldata->useLongNames() && groupName->effectiveStaffIdx() == muse::nidx) { + // NOTE: We can only do this for long-name systems because they don't need to have + // the left barline aligned with the other systems across the page. + groupName->mutldata()->setIsSkipDraw(true); + continue; + } + groupName->mutldata()->setIsSkipDraw(false); + + groupNames.push_back(groupName); + groupName->mutldata()->setColumn(1); + for (staff_idx_t groupIdx = groupName->staffIdx(); groupIdx < groupName->endIdxOfGroup(); ++groupIdx) { + partsWithGroupNames.insert(ctx.dom().staff(groupIdx)->part()); + } + ldata->setSecondColumnWidth(std::max(ldata->secondColumnWidth(), groupName->width())); + ldata->setTotalNamesWidth(std::max(ldata->totalNamesWidth(), groupName->width())); } - const SysStaff* staff = system->staff(staffIdx); - if (ldata->useLongNames() && !staff->show()) { - // NOTE: We can only do this for long-name systems because they don't need to have - // the left barline aligned with the other systems across the page. + if (!staff->show()) { + // We know that the staff is hidden in the entire score so safe to skip continue; } - if (InstrumentName* name = staff->individualStaffName) { - TLayout::layoutInstrumentName(name, name->mutldata()); - ldata->setStaffNamesWidth(std::max(ldata->staffNamesWidth(), name->width())); - ldata->setTotalNamesWidth(std::max(ldata->totalNamesWidth(), name->width())); + if (InstrumentName* name = sysStaff->individualStaffName) { + if (ldata->useLongNames() && !sysStaff->show()) { + // NOTE: We can only do this for long-name systems because they don't need to have + // the left barline aligned with the other systems across the page. + name->mutldata()->setIsSkipDraw(true); + continue; + } + name->mutldata()->setIsSkipDraw(false); + + name->mutldata()->setColumn(0); partsWithIndividualStaffNames.insert(ctx.dom().staff(staffIdx)->part()); + ldata->setFirstColumnWidth(std::max(ldata->firstColumnWidth(), name->width())); + ldata->setTotalNamesWidth(std::max(ldata->totalNamesWidth(), name->width())); } } - bool stackVertically = stackLabelsVertically(system); + for (staff_idx_t staffIdx = 0; staffIdx < system->staves().size(); ++staffIdx) { + const SysStaff* sysStaff = system->staff(staffIdx); + const Staff* staff = ctx.dom().staff(staffIdx); + Part* part = staff->part(); - for (staff_idx_t staffIdx = 0; staffIdx < ctx.dom().nstaves(); ++staffIdx) { - Part* part = ctx.dom().staff(staffIdx)->part(); if (!part->show() || part->visibleStavesCount() == 0) { // We know that the part is hidden in the entire score so safe to skip continue; } - const SysStaff* staff = system->staff(staffIdx); - - InstrumentName* name = staff->instrumentName; - if (!name) { + InstrumentName* instrName = sysStaff->instrumentName; + if (!instrName) { continue; } - if (ldata->useLongNames() && name->effectiveStaffIdx() == muse::nidx) { + if (ldata->useLongNames() && instrName->effectiveStaffIdx() == muse::nidx) { + // NOTE: We can only do this for long-name systems because they don't need to have + // the left barline aligned with the other systems across the page. + instrName->mutldata()->setIsSkipDraw(true); continue; } + instrName->mutldata()->setIsSkipDraw(false); - TLayout::layoutInstrumentName(name, name->mutldata()); - ldata->setInstrumentNamesWidth(std::max(ldata->instrumentNamesWidth(), name->width())); - ldata->setTotalNamesWidth(std::max(ldata->totalNamesWidth(), name->width())); + instrumentNames.push_back(instrName); + ldata->setTotalNamesWidth(std::max(ldata->totalNamesWidth(), instrName->width())); - if (stackVertically) { - continue; + if (partsWithGroupNames.count(part)) { + instrName->mutldata()->setColumn(0); + ldata->setFirstColumnWidth(std::max(ldata->firstColumnWidth(), instrName->width())); + } else { + instrName->mutldata()->setColumn(1); + ldata->setSecondColumnWidth(std::max(ldata->secondColumnWidth(), instrName->width())); } + } - size_t visibleStaveCount = system->visibleStavesOfPart(part).size(); - if (ldata->useLongNames() && visibleStaveCount % 2 == 0) { + if (stackLabelsVertically(system)) { + return; + } + + auto sumWidth = [&](InstrumentName* outerName, InstrumentName* innerName) { + AlignH staffNameAlign = innerName->position(); + if (staffNameAlign == AlignH::LEFT || staffNameAlign == AlignH::JUSTIFY) { + return ldata->firstColumnWidth() + outerName->width() + ldata->instrumentNameOffset(); + } else if (staffNameAlign == AlignH::HCENTER) { + double sumWidth = innerName->width() + outerName->width() + ldata->instrumentNameOffset(); + double move = 0.5 * (ldata->firstColumnWidth() - innerName->width()); + return sumWidth + move; + } else { + return innerName->width() + outerName->width() + ldata->instrumentNameOffset(); + } + }; + + for (InstrumentName* groupName : groupNames) { + staff_idx_t startStaff = groupName->staffIdx(); + staff_idx_t endStaff = groupName->endIdxOfGroup(); + if (ldata->useLongNames() && system->visiblePartsOfGroup(startStaff, endStaff).size() % 2 == 0) { continue; } + for (staff_idx_t idx = startStaff; idx < endStaff; ++idx) { + if (InstrumentName* n = system->staff(idx)->individualStaffName; n && !n->ldata()->isSkipDraw()) { + ldata->setTotalNamesWidth(std::max(ldata->totalNamesWidth(), sumWidth(groupName, n))); + } + if (InstrumentName* n = system->staff(idx)->instrumentName; n && !n->ldata()->isSkipDraw()) { + ldata->setTotalNamesWidth(std::max(ldata->totalNamesWidth(), sumWidth(groupName, n))); + } + } + } - if (muse::contains(partsWithIndividualStaffNames, part)) { - staff_idx_t startStaff = system->firstSysStaffOfPart(part); - staff_idx_t endStaff = startStaff + part->nstaves(); - for (staff_idx_t idx = startStaff; idx < endStaff; ++idx) { - if (InstrumentName* staffName = system->staff(idx)->individualStaffName) { - double sumWidth = 0.0; - AlignH staffNameAlign = staffName->position(); - if (staffNameAlign == AlignH::LEFT || staffNameAlign == AlignH::JUSTIFY) { - sumWidth = ldata->staffNamesWidth() + name->width() + ldata->instrumentNameOffset(); - } else if (staffNameAlign == AlignH::HCENTER) { - sumWidth = staffName->width() + name->width() + ldata->instrumentNameOffset(); - double move = 0.5 * (ldata->staffNamesWidth() - staffName->width()); - sumWidth += move; - } else { - sumWidth = staffName->width() + name->width() + ldata->instrumentNameOffset(); - } - ldata->setTotalNamesWidth(std::max(ldata->totalNamesWidth(), sumWidth)); - } + for (InstrumentName* instrName : instrumentNames) { + if (instrName->ldata()->column() == 0) { + continue; + } + Part* part = ctx.dom().staff(instrName->staffIdx())->part(); + if (ldata->useLongNames() && system->visibleStavesOfPart(part).size() % 2 == 0) { + continue; + } + for (staff_idx_t idx : part->staveIdxList()) { + if (InstrumentName* n = system->staff(idx)->individualStaffName; n && !n->ldata()->isSkipDraw()) { + ldata->setTotalNamesWidth(std::max(ldata->totalNamesWidth(), sumWidth(instrName, n))); } } } @@ -413,6 +467,7 @@ void SystemHeaderLayout::setInstrumentNamesVerticalPos(System* system, LayoutCon size_t nstaves = p->nstaves(); SysStaff* s = system->staff(staffIdx); + InstrumentName* t = s->instrumentName; if (!t || t->effectiveStaffIdx() == muse::nidx) { staffIdx += nstaves; @@ -435,37 +490,138 @@ void SystemHeaderLayout::setInstrumentNamesVerticalPos(System* system, LayoutCon y1 = topSt->bbox().top(); y2 = bottomSt->bbox().bottom(); t->mutldata()->setPosY(0.5 * (y1 + y2) - yCenter); + + staffIdx += nstaves; + continue; + } + + if (visibleStavesCount % 2 == 0) { + SysStaff* staffAboveMid = system->staff(visibleStavesOfPart[visibleStavesCount / 2 - 1]); + SysStaff* staffBelowMid = system->staff(visibleStavesOfPart[visibleStavesCount / 2]); + y1 = staffAboveMid->bbox().top(); + y2 = staffBelowMid->bbox().bottom(); + t->mutldata()->setPosY(0.5 * (y1 + y2) - yCenter); + + staffIdx += nstaves; + continue; + } + + SysStaff* midStaff = system->staff(visibleStavesOfPart[visibleStavesCount / 2]); + y1 = midStaff->bbox().top(); + y2 = midStaff->bbox().bottom(); + if (InstrumentName* staffName = midStaff->individualStaffName) { + if (stackVertically || t->ldata()->column() == 0) { + double lineSpacing = t->lineSpacing(); + double instrNameBottom = t->ldata()->blocks.back().y(); + double centerY = 0.5 * (midStaff->bbox().top() + midStaff->bbox().bottom()); + t->mutldata()->setPosY(centerY - instrNameBottom - 0.25 * lineSpacing); + double staffNameTop = staffName->ldata()->blocks.front().y(); + staffName->mutldata()->setPosY(centerY - staffNameTop + 0.75 * lineSpacing); + } else if (staffName->ldata()->rows() == 1 && t->ldata()->rows() == 1) { + t->mutldata()->setPosY(staffName->y()); + } else { + t->mutldata()->setPosY(0.5 * (y1 + y2) - yCenter); + } + } + + staffIdx += nstaves; + } + + for (staff_idx_t staffIdx = 0; staffIdx < system->staves().size(); ++staffIdx) { + InstrumentName* groupName = system->staff(staffIdx)->groupName; + if (!groupName || groupName->effectiveStaffIdx() == muse::nidx) { + continue; + } + + const RectF& bbox = groupName->ldata()->bbox(); + double yCenter = 0.5 * (bbox.bottom() + bbox.top()); + + std::vector visibleParts = system->visiblePartsOfGroup(staffIdx, groupName->endIdxOfGroup()); + size_t visiblePartsCount = visibleParts.size(); + DO_ASSERT(visiblePartsCount > 0); + + double y1 = 0; + double y2 = 0; + + if (visiblePartsCount % 2 == 0) { + Part* partAboveMid = visibleParts[visiblePartsCount / 2 - 1]; + staff_idx_t staffIdxAboveMid = system->lastVisibleSysStaffOfPart(partAboveMid); + DO_ASSERT(staffIdxAboveMid != muse::nidx); + SysStaff* staffAboveMid = system->staff(staffIdxAboveMid); + + Part* partBelowMid = visibleParts[visiblePartsCount / 2]; + staff_idx_t staffIdxBelowMid = system->firstVisibleSysStaffOfPart(partBelowMid); + DO_ASSERT(staffIdxBelowMid != muse::nidx); + SysStaff* staffBelowMid = system->staff(staffIdxBelowMid); + + y1 = staffAboveMid->bbox().top(); + y2 = staffBelowMid->bbox().bottom(); + groupName->mutldata()->setPosY(0.5 * (y1 + y2) - yCenter); + + continue; + } + + Part* midPart = visibleParts[visiblePartsCount / 2]; + InstrumentName* instrName = system->staff(*midPart->staveIdxList().begin())->instrumentName; + std::vector visibleStaves = system->visibleStavesOfPart(midPart); + size_t visibleStavesCount = visibleStaves.size(); + + if (visibleStavesCount % 2) { + SysStaff* midStaff = system->staff(visibleStaves[visibleStavesCount / 2]); + y1 = midStaff->bbox().top(); + y2 = midStaff->bbox().bottom(); } else { - if (visibleStavesCount % 2) { - SysStaff* midStaff = system->staff(visibleStavesOfPart[visibleStavesCount / 2]); - y1 = midStaff->bbox().top(); - y2 = midStaff->bbox().bottom(); - if (InstrumentName* staffName = midStaff->individualStaffName) { - if (stackVertically) { - double lineSpacing = t->fontMetrics().lineSpacing(); - double instrNameBottom = t->ldata()->blocks.back().y(); - double centerY = 0.5 * (midStaff->bbox().top() + midStaff->bbox().bottom()); - t->mutldata()->setPosY(centerY - instrNameBottom - 0.25 * lineSpacing); - double staffNameTop = staffName->ldata()->blocks.front().y(); - staffName->mutldata()->setPosY(centerY - staffNameTop + 0.75 * lineSpacing); - } else if (staffName->ldata()->rows() == 1 && t->ldata()->rows() == 1) { - t->mutldata()->setPosY(staffName->y()); - } else { - t->mutldata()->setPosY(0.5 * (y1 + y2) - yCenter); - } + SysStaff* staffAboveMid = system->staff(visibleStaves[visibleStavesCount / 2 - 1]); + SysStaff* staffBelowMid = system->staff(visibleStaves[visibleStavesCount / 2]); + y1 = staffAboveMid->bbox().top(); + y2 = staffBelowMid->bbox().bottom(); + } + + if (instrName) { + if (stackVertically) { + double lineSpacing = groupName->lineSpacing(); + double groupNameBottom = groupName->ldata()->blocks.back().y(); + if (visibleStavesCount % 2 && system->staff(visibleStaves[visibleStavesCount / 2])->individualStaffName) { + groupName->mutldata()->setPosY(instrName->y() - groupNameBottom - lineSpacing); } else { - t->mutldata()->setPosY(0.5 * (y1 + y2) - yCenter); + double centerY = 0.5 * (y1 + y2); + groupName->mutldata()->setPosY(centerY - groupNameBottom - 0.25 * lineSpacing); + double instrNameTop = instrName->ldata()->blocks.front().y(); + instrName->mutldata()->setPosY(centerY - instrNameTop + 0.75 * lineSpacing); } + } else if (instrName->ldata()->rows() == 1 && groupName->ldata()->rows() == 1) { + groupName->mutldata()->setPosY(instrName->y()); } else { - SysStaff* staffAboveMid = system->staff(visibleStavesOfPart[visibleStavesCount / 2 - 1]); - SysStaff* staffBelowMid = system->staff(visibleStavesOfPart[visibleStavesCount / 2]); - y1 = staffAboveMid->bbox().top(); - y2 = staffBelowMid->bbox().bottom(); - t->mutldata()->setPosY(0.5 * (y1 + y2) - yCenter); + groupName->mutldata()->setPosY(0.5 * (y1 + y2) - yCenter); } + + continue; } - staffIdx += nstaves; + if (visibleStavesCount % 2 == 0) { + groupName->mutldata()->setPosY(0.5 * (y1 + y2) - yCenter); + continue; + } + + SysStaff* midStaff = system->staff(visibleStaves[visibleStavesCount / 2]); + InstrumentName* staffName = midStaff->individualStaffName; + if (!staffName) { + groupName->mutldata()->setPosY(0.5 * (y1 + y2) - yCenter); + continue; + } + + if (stackVertically) { + double lineSpacing = groupName->lineSpacing(); + double groupNameBottom = groupName->ldata()->blocks.back().y(); + double centerY = 0.5 * (y1 + y2); + groupName->mutldata()->setPosY(centerY - groupNameBottom - 0.25 * lineSpacing); + double staffNameTop = staffName->ldata()->blocks.front().y(); + staffName->mutldata()->setPosY(centerY - staffNameTop + 0.75 * lineSpacing); + } else if (staffName->ldata()->rows() == 1 && groupName->ldata()->rows() == 1) { + groupName->mutldata()->setPosY(staffName->y()); + } else { + groupName->mutldata()->setPosY(0.5 * (y1 + y2) - yCenter); + } } } @@ -479,78 +635,141 @@ void SystemHeaderLayout::setInstrumentNamesHorizontalPos(System* system) System::LayoutData* ldata = system->mutldata(); double totalNamesWidth = ldata->totalNamesWidth(); - double staffNamesWidth = ldata->staffNamesWidth(); + double firstColumnWidth = ldata->firstColumnWidth(); + InstrumentNamesAlign align = system->style().styleV( + ldata->useLongNames() ? Sid::instrumentNamesAlignLong : Sid::instrumentNamesAlignShort).value(); + + auto placeFirstColumnName = [&](InstrumentName* name) { + const RectF& bbox = name->ldata()->bbox(); + if (align == InstrumentNamesAlign::CENTER_CENTER) { + name->mutldata()->setPosX(totalNamesWidth * .5 - (bbox.right() + bbox.left()) * .5); + } else { + switch (name->position()) { + case AlignH::JUSTIFY: + case AlignH::LEFT: + name->mutldata()->setPosX(totalNamesWidth - firstColumnWidth - bbox.left()); + break; + case AlignH::HCENTER: + name->mutldata()->setPosX(totalNamesWidth - 0.5 * firstColumnWidth - 0.5 * (bbox.right() + bbox.left())); + break; + case AlignH::RIGHT: + name->mutldata()->setPosX(totalNamesWidth - bbox.right()); + } + } + }; for (const SysStaff* s : system->staves()) { - if (InstrumentName* t = s->individualStaffName) { - bool longName = t->instrumentNameType() == InstrumentNameType::LONG; - InstrumentNamesAlign align - = t->style().styleV(longName ? Sid::instrumentNamesAlignLong : Sid::instrumentNamesAlignShort).value(); - const RectF& bbox = t->ldata()->bbox(); - if (align == InstrumentNamesAlign::CENTER_CENTER) { - t->mutldata()->setPosX(totalNamesWidth * .5 - (bbox.right() + bbox.left()) * .5); - } else { - switch (t->position()) { - case AlignH::JUSTIFY: - case AlignH::LEFT: - t->mutldata()->setPosX(totalNamesWidth - staffNamesWidth - bbox.left()); - break; - case AlignH::HCENTER: - t->mutldata()->setPosX(totalNamesWidth - 0.5 * staffNamesWidth - 0.5 * (bbox.right() + bbox.left())); - break; - case AlignH::RIGHT: - t->mutldata()->setPosX(totalNamesWidth - bbox.right()); - } - } + if (InstrumentName* n = s->individualStaffName) { + placeFirstColumnName(n); + } + if (InstrumentName* n = s->instrumentName; n && n->ldata()->column() == 0 && n->effectiveStaffIdx() != muse::nidx) { + placeFirstColumnName(n); } } bool stackVertically = stackLabelsVertically(system); - for (staff_idx_t staffIdx = 0; staffIdx < system->staves().size(); ++staffIdx) { - const SysStaff* s = system->staff(staffIdx); - const Part* p = system->score()->staff(staffIdx)->part(); - if (InstrumentName* t = s->instrumentName; t && t->effectiveStaffIdx() != muse::nidx) { - const RectF& bbox = t->ldata()->bbox(); - bool longName = t->instrumentNameType() == InstrumentNameType::LONG; - InstrumentNamesAlign align - = t->style().styleV(longName ? Sid::instrumentNamesAlignLong : Sid::instrumentNamesAlignShort).value(); - - if (align == InstrumentNamesAlign::LEFT_RIGHT) { - t->mutldata()->setPosX(0 - bbox.left()); - } else if (align == InstrumentNamesAlign::CENTER_CENTER) { - t->mutldata()->setPosX(0.5 * totalNamesWidth - 0.5 * (bbox.right() + bbox.left())); - } else if (align == InstrumentNamesAlign::CENTER_RIGHT) { - t->mutldata()->moveX(0.5 * ldata->instrumentNamesWidth() - 0.5 * (bbox.right() + bbox.left())); + auto placeSecondColumnName = [&](InstrumentName* name, staff_idx_t staffIdx) { + const RectF& bbox = name->ldata()->bbox(); + + if (align == InstrumentNamesAlign::LEFT_RIGHT) { + name->mutldata()->setPosX(0 - bbox.left()); + return; + } + + if (align == InstrumentNamesAlign::CENTER_CENTER) { + name->mutldata()->setPosX(0.5 * totalNamesWidth - 0.5 * (bbox.right() + bbox.left())); + return; + } + + if (align == InstrumentNamesAlign::CENTER_RIGHT) { + name->mutldata()->setPosX(0.5 * ldata->secondColumnWidth() - 0.5 * (bbox.right() + bbox.left())); + return; + } + + if (stackVertically) { + name->mutldata()->setPosX(totalNamesWidth - bbox.right()); + return; + } + + if (name->instrumentNameRole() == InstrumentNameRole::PART) { + const Part* p = system->score()->staff(staffIdx)->part(); + std::vector visibleStavesForPart = system->visibleStavesOfPart(p); + size_t visibleStaveCount = visibleStavesForPart.size(); + if (visibleStaveCount % 2 == 0) { + name->mutldata()->setPosX(totalNamesWidth - bbox.right()); + return; + } + + staff_idx_t centerStaff = visibleStavesForPart[visibleStaveCount / 2]; + if (InstrumentName* staffName = system->staff(centerStaff)->individualStaffName) { + name->mutldata()->setPosX( + staffName->x() + staffName->ldata()->bbox().left() - bbox.right() - ldata->instrumentNameOffset()); } else { - std::vector visibleStavesForPart = system->visibleStavesOfPart(p); - size_t visibleStaveCount = visibleStavesForPart.size(); - if (visibleStaveCount % 2 && !stackVertically) { - staff_idx_t centerStaff = visibleStavesForPart[visibleStaveCount / 2]; - if (InstrumentName* staffName = system->staff(centerStaff)->individualStaffName) { - t->mutldata()->setPosX( - staffName->x() + staffName->ldata()->bbox().left() - bbox.right() - ldata->instrumentNameOffset()); - } else { - t->mutldata()->setPosX(totalNamesWidth - bbox.right()); - } - } else { - t->mutldata()->setPosX(totalNamesWidth - bbox.right()); - } + name->mutldata()->setPosX(totalNamesWidth - bbox.right()); } + + return; + } + + std::vector visiblePartsOfGroup = system->visiblePartsOfGroup(staffIdx, name->endIdxOfGroup()); + size_t visiblePartsCount = visiblePartsOfGroup.size(); + if (visiblePartsCount % 2 == 0) { + name->mutldata()->setPosX(totalNamesWidth - bbox.right()); + return; + } + + Part* centerPart = visiblePartsOfGroup[visiblePartsCount / 2]; + if (InstrumentName* instrName = system->staff(*centerPart->staveIdxList().begin())->instrumentName) { + name->mutldata()->setPosX( + instrName->x() + instrName->ldata()->bbox().left() - bbox.right() - ldata->instrumentNameOffset()); + return; + } + + std::vector visibleStavesOfPart = system->visibleStavesOfPart(centerPart); + size_t visibleStavesCount = visibleStavesOfPart.size(); + if (visibleStavesCount % 2 == 0) { + name->mutldata()->setPosX(totalNamesWidth - bbox.right()); + return; + } + + staff_idx_t centerStaff = visibleStavesOfPart[visibleStavesCount / 2]; + if (InstrumentName* staffName = system->staff(centerStaff)->individualStaffName) { + name->mutldata()->setPosX( + staffName->x() + staffName->ldata()->bbox().left() - bbox.right() - ldata->instrumentNameOffset()); + } else { + name->mutldata()->setPosX(totalNamesWidth - bbox.right()); + } + }; + + for (staff_idx_t staffIdx = 0; staffIdx < system->staves().size(); ++staffIdx) { + const SysStaff* s = system->staff(staffIdx); + InstrumentName* instrName = s->instrumentName; + if (instrName && instrName->effectiveStaffIdx() != muse::nidx && instrName->ldata()->column() > 0) { + placeSecondColumnName(instrName, staffIdx); + } + } + + for (staff_idx_t staffIdx = 0; staffIdx < system->staves().size(); ++staffIdx) { + const SysStaff* s = system->staff(staffIdx); + InstrumentName* groupName = s->groupName; + if (groupName && groupName->effectiveStaffIdx() != muse::nidx) { + placeSecondColumnName(groupName, staffIdx); } } } -void SystemHeaderLayout::updateName(System* system, staff_idx_t staffIdx, LayoutContext& ctx, const String& name, - InstrumentNameType type, InstrumentNameRole role) +InstrumentName* SystemHeaderLayout::updateName(System* system, staff_idx_t staffIdx, LayoutContext& ctx, const String& name, + InstrumentNameType type, InstrumentNameRole role) { SysStaff* sysStaff = system->staff(staffIdx); - InstrumentName* iname = role == InstrumentNameRole::PART ? sysStaff->instrumentName : sysStaff->individualStaffName; + InstrumentName* iname = role == InstrumentNameRole::GROUP ? sysStaff->groupName + : role == InstrumentNameRole::PART ? sysStaff->instrumentName : sysStaff->individualStaffName; if (name.empty()) { if (iname) { ctx.mutDom().removeElement(iname); } - return; + return nullptr; } if (!iname) { @@ -566,6 +785,161 @@ void SystemHeaderLayout::updateName(System* system, staff_idx_t staffIdx, Layout iname->setAlign(Align(iname->align().horizontal, AlignV::BASELINE)); iname->setXmlText(name); + + iname->mutldata()->setColumn(0); // Reset here, will be computed later + TLayout::layoutInstrumentName(iname, iname->mutldata()); + + return iname; +} + +String SystemHeaderLayout::formattedInstrumentName(System* system, Part* part, const Fraction& tick) +{ + if (muse::contains(system->ldata()->partsWithGroupName(), part)) { + int number = part->number(tick); + return number > 0 ? String::number(number) : String(); + } + + const MStyle& style = system->style(); + + bool longNames = system->ldata()->useLongNames(); + Instrument* instr = part->instrument(tick); + const InstrumentLabel& label = instr->instrumentLabel(); + + if (longNames && label.useCustomNameLong()) { + return label.customNameLong(); + } + + if (!longNames && label.useCustomNameShort()) { + return label.customNameShort(); + } + + String instrName = longNames ? instr->longName() : instr->shortName(); + + bool showNumber = longNames ? label.showNumberLong() : label.showNumberShort(); + String number = instr->number() > 0 && showNumber ? String::number(instr->number()) : String(); + + bool showTranspo = longNames ? label.showTranspositionLong() : label.showTranspositionShort(); + showTranspo &= style.styleB(longNames ? Sid::instrumentNamesShowTranspositionLong : Sid::instrumentNamesShowTranspositionShort); + String transposition = showTranspo ? instr->transposition() : String(); + + if (transposition.empty()) { + String result = instrName; + if (!number.empty()) { + result += u" " + number; + } + return result; + } + + InstrumentNamesFormat nameFormat + = style.styleV(longNames ? Sid::instrumentNamesFormatLong : Sid::instrumentNamesFormatShort).value(); + + String in = TranslatableString("notation", "in").translated(); + + switch (nameFormat) { + case InstrumentNamesFormat::NAME_IN_TRANSP_NUM: + return instrName + u" " + in + u" " + transposition + (number.empty() ? String() : u" " + number); + case InstrumentNamesFormat::NAME_NUM_IN_TRANSP: + return instrName + (number.empty() ? String() : u" " + number) + u" " + in + u" " + transposition; + case InstrumentNamesFormat::TRANSP_NAME_NUM: + return transposition + u" " + instrName + (number.empty() ? String() : u" " + number); + default: + { + String result = style.styleSt(longNames ? Sid::instrumentNamesCustomFormatLong : Sid::instrumentNamesCustomFormatShort); + result.replace(u"$name", instrName); + result.replace(u"$transposition", transposition); + if (!number.empty()) { + result.replace(u"$number", number); + } else { + if (result.contains(u" $number")) { + result.remove(u" $number"); + } else if (result.contains(u"$number ")) { + result.remove(u"$number "); + } else if (result.contains(u"$number")) { + result.remove(u"$number"); + } + } + return result; + } + } +} + +String SystemHeaderLayout::formattedGroupName(System* system, Part* part, const Fraction& tick) +{ + const MStyle& style = system->style(); + + bool longNames = system->ldata()->useLongNames(); + Instrument* instr = part->instrument(tick); + const InstrumentLabel& label = instr->instrumentLabel(); + + if (longNames && label.useCustomNameLongGroup()) { + return label.customNameLongGroup(); + } + + if (!longNames && label.useCustomNameShortGroup()) { + return label.customNameShortGroup(); + } + + String instrName = longNames ? instr->longName() : instr->shortName(); + + bool showTranspo = longNames ? label.showTranspositionLong() : label.showTranspositionShort(); + showTranspo &= style.styleB(longNames ? Sid::instrumentNamesShowTranspositionLong : Sid::instrumentNamesShowTranspositionShort); + + String transposition = showTranspo ? instr->transposition() : String(); + + if (transposition.empty()) { + return instrName; + } + + InstrumentNamesFormat nameFormat + = style.styleV(longNames ? Sid::instrumentNamesFormatLong : Sid::instrumentNamesFormatShort).value(); + + String in = TranslatableString("notation", "in").translated(); + + switch (nameFormat) { + case InstrumentNamesFormat::NAME_IN_TRANSP_NUM: + return instrName + u" " + in + u" " + transposition; + case InstrumentNamesFormat::NAME_NUM_IN_TRANSP: + return instrName + u" " + in + u" " + transposition; + case InstrumentNamesFormat::TRANSP_NAME_NUM: + return transposition + u" " + instrName; + default: + { + String result = style.styleSt(longNames ? Sid::instrumentNamesCustomFormatLong : Sid::instrumentNamesCustomFormatShort); + result.replace(u"$name", instrName); + result.replace(u"$transposition", transposition); + if (result.contains(u" $number")) { + result.remove(u" $number"); + } else if (result.contains(u"$number ")) { + result.remove(u"$number "); + } else if (result.contains(u"$number")) { + result.remove(u"$number"); + } + return result; + } + } +} + +bool SystemHeaderLayout::showNames(LayoutContext& ctx) +{ + if (!ctx.conf().isShowInstrumentNames()) { + return false; + } + + if (ctx.conf().styleB(Sid::hideInstrumentNameIfOneInstrument) && ctx.dom().visiblePartCount() <= 1) { + return false; + } + + if (ctx.state().firstSystem() + && ctx.conf().styleV(Sid::firstSystemInstNameVisibility).value() == InstrumentLabelVisibility::HIDE) { + return false; + } + + if (!ctx.state().firstSystem() + && ctx.conf().styleV(Sid::subsSystemInstNameVisibility).value() == InstrumentLabelVisibility::HIDE) { + return false; + } + + return true; } void SystemHeaderLayout::setInstrumentNames(System* system, LayoutContext& ctx, bool longName, Fraction tick) @@ -574,63 +948,123 @@ void SystemHeaderLayout::setInstrumentNames(System* system, LayoutContext& ctx, return; } - system->mutldata()->setUseLongNames(longName); + System::LayoutData* ldata = system->mutldata(); + ldata->setUseLongNames(longName); - if (!ctx.conf().isShowInstrumentNames() - || (ctx.conf().styleB(Sid::hideInstrumentNameIfOneInstrument) && ctx.dom().visiblePartCount() <= 1) - || (ctx.state().firstSystem() - && ctx.conf().styleV(Sid::firstSystemInstNameVisibility).value() == InstrumentLabelVisibility::HIDE) - || (!ctx.state().firstSystem() - && ctx.conf().styleV(Sid::subsSystemInstNameVisibility).value() - == InstrumentLabelVisibility::HIDE)) { - for (SysStaff* staff : system->staves()) { - if (InstrumentName* iName = staff->instrumentName) { - ctx.mutDom().removeElement(iName); - } - if (InstrumentName* sName = staff->individualStaffName) { - ctx.mutDom().removeElement(sName); - } + InstrumentNameType type = longName ? InstrumentNameType::LONG : InstrumentNameType::SHORT; + + if (!showNames(ctx)) { + for (staff_idx_t idx = 0; idx < system->staves().size(); ++idx) { + updateName(system, idx, ctx, String(), type, InstrumentNameRole::STAFF); + updateName(system, idx, ctx, String(), type, InstrumentNameRole::PART); + updateName(system, idx, ctx, String(), type, InstrumentNameRole::GROUP); } return; } - InstrumentNameType type = longName ? InstrumentNameType::LONG : InstrumentNameType::SHORT; + updateGroupNames(system, ctx, tick); for (size_t staffIdx = 0; staffIdx < system->staves().size(); /*empty*/) { Part* part = ctx.dom().staff(staffIdx)->part(); + size_t partNstaves = part->nstaves(); + size_t visibleStavesCount = part->visibleStavesCount(); - if (!part->show() || part->visibleStavesCount() == 0) { - for (size_t i = 0; i < part->nstaves(); ++i) { - SysStaff* sysStaff = system->staff(staffIdx + i); - if (InstrumentName* iName = sysStaff->instrumentName) { - ctx.mutDom().removeElement(iName); - } - if (InstrumentName* sName = sysStaff->individualStaffName) { - ctx.mutDom().removeElement(sName); - } + for (size_t idxInPart = 0; idxInPart < partNstaves; ++idxInPart) { + staff_idx_t globalIdx = staffIdx + idxInPart; + + String instrumentName; + if (idxInPart == 0 && part->show() && visibleStavesCount > 0) { + instrumentName = formattedInstrumentName(system, part, tick); + } + updateName(system, globalIdx, ctx, instrumentName, type, InstrumentNameRole::PART); + + const Staff* staff = ctx.dom().staff(globalIdx); + String staffName; + if (staff->show()) { + staffName = longName ? staff->individualStaffNameLong(tick) : staff->individualStaffNameShort(tick); } - staffIdx += part->nstaves(); + updateName(system, globalIdx, ctx, staffName, type, InstrumentNameRole::STAFF); + } + + staffIdx += partNstaves; + } +} + +void SystemHeaderLayout::updateGroupNames(System* system, LayoutContext& ctx, const Fraction& tick) +{ + const MStyle& style = ctx.conf().style(); + InstrumentNameType type = system->ldata()->useLongNames() ? InstrumentNameType::LONG : InstrumentNameType::SHORT; + + System::LayoutData* ldata = system->mutldata(); + ldata->clearPartsWithGroupNames(); + + auto useGroupNames = [&](String instrumentGroup) { + if (instrumentGroup == "woodwinds" || instrumentGroup == "brass") { + return style.styleB(Sid::windsNameByGroup); + } + if (instrumentGroup == "vocals") { + return style.styleB(Sid::vocalsNameByGroup); + } + if (instrumentGroup == "strings") { + return style.styleB(Sid::stringsNameByGroup); + } + return style.styleB(Sid::othersNameByGroup); + }; + + for (staff_idx_t startOfGroup = 0; startOfGroup < system->staves().size();) { + Part* curPart = ctx.dom().staff(startOfGroup)->part(); + const Instrument* curInstrument = curPart->instrument(tick); + if (!curInstrument->instrumentLabel().allowGroupName()) { + ++startOfGroup; continue; } - for (size_t i = 0; i < part->nstaves(); ++i) { - staff_idx_t idx = staffIdx + i; - SysStaff* sysStaff = system->staff(idx); - if (i == 0) { - const String& instrName = longName ? part->longName(tick) : part->shortName(tick); - updateName(system, idx, ctx, instrName, type, InstrumentNameRole::PART); - } else { - if (sysStaff->instrumentName) { - ctx.mutDom().removeElement(sysStaff->instrumentName); + std::vector partsInThisGroup; + + staff_idx_t endOfGroup = startOfGroup; + while (endOfGroup < system->staves().size()) { + Part* nextPart = ctx.dom().staff(endOfGroup)->part(); + Instrument* nextInstrument = nextPart->instrument(tick); + if (nextPart != curPart + && (nextInstrument->id() != curInstrument->id() || !nextInstrument->instrumentLabel().allowGroupName())) { + break; + } + + if (type == InstrumentNameType::LONG && system->visibleStavesOfPart(nextPart).size() == 0) { + // NOTE: We can only do this for long-name systems because they don't need to have + // the left barline aligned with the other systems across the page. + endOfGroup += nextPart->nstaves(); + continue; + } + + if (nextPart->show() && nextPart->visibleStavesCount() > 0) { + partsInThisGroup.push_back(nextPart); + } + + endOfGroup += nextPart->nstaves(); + } + + if (partsInThisGroup.size() > 1 && useGroupNames(curInstrument->group())) { + String name = formattedGroupName(system, curPart, tick); + InstrumentName* groupName = updateName(system, startOfGroup, ctx, name, type, InstrumentNameRole::GROUP); + + if (groupName) { + groupName->setEndIdxOfGroup(endOfGroup); + + for (Part* p : partsInThisGroup) { + ldata->addPartWithGroupNames(p, groupName); } } - const Staff* staff = ctx.dom().staff(idx); - if (staff->show()) { - const String& staffName = longName ? staff->individualStaffNameLong(tick) : staff->individualStaffNameShort(tick); - updateName(system, idx, ctx, staffName, type, InstrumentNameRole::STAFF); + + for (staff_idx_t idx = startOfGroup + 1; idx < endOfGroup; ++idx) { + updateName(system, idx, ctx, String(), type, InstrumentNameRole::GROUP); + } + } else { + for (staff_idx_t idx = startOfGroup; idx < endOfGroup; ++idx) { + updateName(system, idx, ctx, String(), type, InstrumentNameRole::GROUP); } } - staffIdx += part->nstaves(); + startOfGroup = endOfGroup; } } diff --git a/src/engraving/rendering/score/systemheaderlayout.h b/src/engraving/rendering/score/systemheaderlayout.h index 951baa67694bb..01f4cc974ce8c 100644 --- a/src/engraving/rendering/score/systemheaderlayout.h +++ b/src/engraving/rendering/score/systemheaderlayout.h @@ -51,8 +51,13 @@ class SystemHeaderLayout static Bracket* createBracket(System* system, LayoutContext& ctx, BracketItem* bi, size_t column, staff_idx_t staffIdx, std::vector& bl, Measure* measure); - static void updateName(System* system, staff_idx_t staffIdx, LayoutContext& ctx, const String& name, InstrumentNameType type, - InstrumentNameRole role); + static void updateGroupNames(System* system, LayoutContext& ctx, const Fraction& tick); + static InstrumentName* updateName(System* system, staff_idx_t staffIdx, LayoutContext& ctx, const String& name, InstrumentNameType type, + InstrumentNameRole role); + static String formattedInstrumentName(System* system, Part* part, const Fraction& tick); + static String formattedGroupName(System* system, Part* part, const Fraction& tick); + static bool showNames(LayoutContext& ctx); + static bool stackLabelsVertically(System* system); }; } diff --git a/src/engraving/rw/read114/read114.cpp b/src/engraving/rw/read114/read114.cpp index 976445e8491a6..bddb01582d0e2 100644 --- a/src/engraving/rw/read114/read114.cpp +++ b/src/engraving/rw/read114/read114.cpp @@ -2584,17 +2584,12 @@ static void readPart(Part* part, XmlReader& e, ReadContext& ctx) readText114(e, ctx, t, t); part->instrument()->setShortName(t->xmlText()); delete t; - } else if (tag == "trackName") { - part->setPartName(e.readText()); } else if (tag == "show") { part->setShow(e.readInt()); } else { e.unknown(); } } - if (part->partName().isEmpty()) { - part->setPartName(part->instrument()->trackName()); - } if (part->instrument()->useDrumset()) { for (Staff* staff : part->staves()) { diff --git a/src/engraving/rw/read206/read206.cpp b/src/engraving/rw/read206/read206.cpp index 5cbcbcca8a188..39807afcf1283 100644 --- a/src/engraving/rw/read206/read206.cpp +++ b/src/engraving/rw/read206/read206.cpp @@ -922,18 +922,12 @@ void Read206::readPart206(Part* part, XmlReader& e, ReadContext& ctx) part->instrument()->setLongName(e.readText()); } else if (tag == "shortName") { part->instrument()->setShortName(e.readText()); - } else if (tag == "trackName") { - part->setPartName(e.readText()); } else if (tag == "show") { part->setShow(e.readInt()); } else { e.unknown(); } } - - if (part->partName().isEmpty()) { - part->setPartName(part->instrument()->trackName()); - } } //--------------------------------------------------------- diff --git a/src/engraving/rw/read400/tread.cpp b/src/engraving/rw/read400/tread.cpp index 21bbba67fafc6..84d0e0966f8ce 100644 --- a/src/engraving/rw/read400/tread.cpp +++ b/src/engraving/rw/read400/tread.cpp @@ -803,9 +803,9 @@ bool TRead::readProperties(Instrument* item, XmlReader& e, ReadContext& ctx, Par const AsciiStringView tag(e.name()); if (tag == "longName") { - item->setLongName(read460::TRead::readStaffName(e)); + item->setLongName(read460::TRead::readLegacyStaffName(e)); } else if (tag == "shortName") { - item->setShortName(read460::TRead::readStaffName(e)); + item->setShortName(read460::TRead::readLegacyStaffName(e)); } else if (tag == "trackName") { item->setTrackName(e.readText()); } else if (tag == "minPitch") { // obsolete @@ -3296,10 +3296,6 @@ void TRead::read(Part* p, XmlReader& e, ReadContext& ctx) } } - if (p->partName().isEmpty()) { - p->setPartName(p->instrument()->trackName()); - } - read(p, staffHideModes, ctx.style().styleB(Sid::hideEmptyStaves)); } @@ -3396,8 +3392,6 @@ bool TRead::readProperties(Part* p, XmlReader& e, ReadContext& ctx, StaffHideMod p->setColor(e.readInt()); } else if (tag == "shortName") { p->instrument()->setShortName(e.readText()); - } else if (tag == "trackName") { - p->setPartName(e.readText()); } else if (tag == "show") { p->setShow(e.readInt()); } else if (tag == "soloist") { diff --git a/src/engraving/rw/read410/tread.cpp b/src/engraving/rw/read410/tread.cpp index 0425d8e093ccf..a4fd7c4a968d5 100644 --- a/src/engraving/rw/read410/tread.cpp +++ b/src/engraving/rw/read410/tread.cpp @@ -998,9 +998,9 @@ bool TRead::readProperties(Instrument* item, XmlReader& e, ReadContext& ctx, Par if (tag == "soundId") { item->setSoundId(e.readText()); } else if (tag == "longName") { - item->setLongName(read460::TRead::readStaffName(e)); + item->setLongName(read460::TRead::readLegacyStaffName(e)); } else if (tag == "shortName") { - item->setShortName(read460::TRead::readStaffName(e)); + item->setShortName(read460::TRead::readLegacyStaffName(e)); } else if (tag == "trackName") { item->setTrackName(e.readText()); } else if (tag == "minPitchA") { @@ -3494,10 +3494,6 @@ void TRead::read(Part* p, XmlReader& e, ReadContext& ctx) } } - if (p->partName().isEmpty()) { - p->setPartName(p->instrument()->trackName()); - } - read400::TRead::read(p, staffHideModes, ctx.style().styleB(Sid::hideEmptyStaves)); } @@ -3545,8 +3541,6 @@ bool TRead::readProperties(Part* p, XmlReader& e, ReadContext& ctx, StaffHideMod p->setColor(e.readInt()); } else if (tag == "shortName") { p->instrument()->setShortName(e.readText()); - } else if (tag == "trackName") { - p->setPartName(e.readText()); } else if (tag == "show") { p->setShow(e.readInt()); } else if (tag == "soloist") { diff --git a/src/engraving/rw/read460/tread.cpp b/src/engraving/rw/read460/tread.cpp index addd77a273c31..e36faefe6b28d 100644 --- a/src/engraving/rw/read460/tread.cpp +++ b/src/engraving/rw/read460/tread.cpp @@ -975,9 +975,11 @@ bool TRead::readProperties(Instrument* item, XmlReader& e, ReadContext& ctx, Par if (tag == "soundId") { item->setSoundId(e.readText()); } else if (tag == "longName") { - item->setLongName(readStaffName(e)); + item->setLongName(readLegacyStaffName(e)); // Old implementation } else if (tag == "shortName") { - item->setShortName(readStaffName(e)); + item->setShortName(readLegacyStaffName(e)); // Old implementation + } else if (tag == "InstrumentLabel") { + readInstrumentLabel(item->instrumentLabel(), e); // New implementation } else if (tag == "trackName") { item->setTrackName(e.readText()); } else if (tag == "minPitchA") { @@ -3543,10 +3545,6 @@ void TRead::read(Part* p, XmlReader& e, ReadContext& ctx) e.unknown(); } } - - if (p->partName().isEmpty()) { - p->setPartName(p->instrument()->trackName()); - } } void TRead::read(PartialLyricsLine* p, XmlReader& xml, ReadContext& ctx) @@ -3593,8 +3591,6 @@ bool TRead::readProperties(Part* p, XmlReader& e, ReadContext& ctx) p->setColor(e.readInt()); } else if (tag == "shortName") { p->instrument()->setShortName(e.readText()); - } else if (tag == "trackName") { - p->setPartName(e.readText()); } else if (tag == "show") { p->setShow(e.readInt()); } else if (tag == "soloist") { @@ -3819,10 +3815,11 @@ void TRead::readHopoText(HammerOnPullOffSegment* hopoSeg, XmlReader& xml, ReadCo hopoSeg->addHopoText(hopoText); } -void TRead::lineBreakFromTag(String& str) +String TRead::lineBreakFromTag(const String& str) { // Raw newlines appearing next to tags (", u"\n"); + String s = str; + return s.replace(u"
", u"\n"); } void TRead::readNoteParenGroup(Chord* ch, XmlReader& e, ReadContext& ctx) @@ -3937,10 +3934,9 @@ void TRead::read(StaffType* t, XmlReader& e, ReadContext& ctx) const AsciiStringView tag(e.name()); if (tag == "name") { t->setXmlName(e.readText()); - } else if (tag == "longName") { - t->setLongName(readStaffName(e)); - } else if (tag == "shortName") { - t->setShortName(readStaffName(e)); + } else if (tag == "StaffLabel") { + StaffLabel& staffLabel = t->staffLabel(); + readStaffLabel(staffLabel, e); } else if (tag == "lines") { t->setLines(e.readInt()); } else if (tag == "lineDistance") { @@ -4133,10 +4129,9 @@ bool TRead::readProperties(Staff* s, XmlReader& e, ReadContext& ctx) return true; } -String TRead::readStaffName(XmlReader& xml) +String TRead::readLegacyStaffName(XmlReader& xml) { - String name = xml.readXml(); - lineBreakFromTag(name); + String name = lineBreakFromTag(xml.readXml()); if (name.startsWith(u"")) { // compatibility to old html implementation: name = HtmlParser::parse(name); @@ -4144,6 +4139,81 @@ String TRead::readStaffName(XmlReader& xml) return name; } +void TRead::readStaffLabel(StaffLabel& item, XmlReader& xml) +{ + while (xml.readNextStartElement()) { + if (!readProperties(item, xml)) { + xml.unknown(); + } + } +} + +bool TRead::readProperties(StaffLabel& item, XmlReader& xml) +{ + AsciiStringView tag = xml.name(); + + if (tag == "longName") { + item.setLongName(lineBreakFromTag(xml.readXml())); + } else if (tag == "shortName") { + item.setShortName(lineBreakFromTag(xml.readXml())); + } else { + return false; + } + + return true; +} + +void TRead::readInstrumentLabel(InstrumentLabel& item, XmlReader& xml) +{ + while (xml.readNextStartElement()) { + if (!readProperties(item, xml)) { + xml.unknown(); + } + } +} + +bool TRead::readProperties(InstrumentLabel& item, XmlReader& xml) +{ + AsciiStringView tag = xml.name(); + + if (readProperties(static_cast(item), xml)) { + } else if (tag == "transposition") { + item.setTransposition(lineBreakFromTag(xml.readXml())); + } else if (tag == "showTranspositionLong") { + item.setShowTranspositionLong(xml.readBool()); + } else if (tag == "showTranspositionShort") { + item.setShowTranspositionShort(xml.readBool()); + } else if (tag == "number") { + item.setNumber(xml.readInt()); + } else if (tag == "showNumberLong") { + item.setShowNumberLong(xml.readBool()); + } else if (tag == "showNumberShort") { + item.setShowNumberLong(xml.readBool()); + } else if (tag == "allowGroupName") { + item.setAllowGroupName(xml.readBool()); + } else if (tag == "customNameLong") { + item.setCustomNameLong(lineBreakFromTag(xml.readXml())); + } else if (tag == "customNameShort") { + item.setCustomNameShort(lineBreakFromTag(xml.readXml())); + } else if (tag == "useCustomNameLong") { + item.setUseCustomNameLong(xml.readBool()); + } else if (tag == "useCustomNameShort") { + item.setUseCustomNameShort(xml.readBool()); + } else if (tag == "customNameLongGroup") { + item.setCustomNameLongGroup(lineBreakFromTag(xml.readXml())); + } else if (tag == "customNameShortGroup") { + item.setCustomNameShortGroup(lineBreakFromTag(xml.readXml())); + } else if (tag == "useCustomNameLongGroup") { + item.setUseCustomNameLongGroup(xml.readBool()); + } else if (tag == "useCustomNameShortGroup") { + item.setUseCustomNameShortGroup(xml.readBool()); + } else { + return false; + } + + return true; +} + void TRead::read(Stem* s, XmlReader& e, ReadContext& ctx) { while (e.readNextStartElement()) { @@ -4477,8 +4547,7 @@ bool TRead::readProperties(TextBase* t, XmlReader& e, ReadContext& ctx) } if (tag == "text") { - String str = e.readXml(); - lineBreakFromTag(str); + String str = lineBreakFromTag(e.readXml()); t->setXmlText(str); t->checkCustomFormatting(str); } else if (tag == "bold") { diff --git a/src/engraving/rw/read460/tread.h b/src/engraving/rw/read460/tread.h index 5db0f5097fc59..16b7812490b63 100644 --- a/src/engraving/rw/read460/tread.h +++ b/src/engraving/rw/read460/tread.h @@ -91,6 +91,7 @@ class Hook; class Instrument; class InstrChannel; class InstrumentChange; +class InstrumentLabel; class Jump; @@ -145,7 +146,7 @@ class SlurTieSegment; class Spanner; class Spacer; class Staff; -class StaffName; +class StaffLabel; class StaffState; class StaffText; class StaffTextBase; @@ -393,7 +394,10 @@ class TRead static void readItemEID(EngravingObject* item, XmlReader& xml); static void readItemLink(EngravingItem* item, XmlReader& xml, ReadContext& ctx); - static String readStaffName(XmlReader& xml); + static String readLegacyStaffName(XmlReader& xml); + + static void readStaffLabel(StaffLabel& item, XmlReader& xml); + static void readInstrumentLabel(InstrumentLabel& item, XmlReader& xml); private: static bool readProperties(Box* b, XmlReader& xml, ReadContext& ctx); @@ -406,8 +410,11 @@ class TRead static void readHopoText(HammerOnPullOffSegment* hopoSeg, XmlReader& xml, ReadContext& ctx, int idx); - static void lineBreakFromTag(String& str); + static String lineBreakFromTag(const String& str); static void readNoteParenGroup(Chord* ch, XmlReader& e, ReadContext& ctx); + + static bool readProperties(StaffLabel& item, XmlReader& xml); + static bool readProperties(InstrumentLabel& item, XmlReader& xml); }; } diff --git a/src/engraving/rw/write/twrite.cpp b/src/engraving/rw/write/twrite.cpp index 0f94f266d02fc..d1cec0f4267ae 100644 --- a/src/engraving/rw/write/twrite.cpp +++ b/src/engraving/rw/write/twrite.cpp @@ -534,10 +534,11 @@ void TWrite::writeSystemLock(const SystemLock* systemLock, XmlWriter& xml) xml.endElement(); } -void TWrite::lineBreakToTag(String& str) +String TWrite::lineBreakToTag(const String& str) { // Raw newlines appearing next to tags ("); + String s = str; + return s.replace(u"\n", u"
"); } void TWrite::writeStyledProperties(const EngravingItem* item, XmlWriter& xml) @@ -1342,9 +1343,7 @@ void TWrite::writeProperties(const TextBase* item, XmlWriter& xml, WriteContext& writeProperty(item, xml, spp.pid); } if (writeText) { - String xmlStr = item->xmlText(); - lineBreakToTag(xmlStr); - xml.writeXml(u"text", xmlStr); + xml.writeXml(u"text", lineBreakToTag(item->xmlText())); } writeProperty(item, xml, Pid::TEXT_LINKED_TO_MASTER); @@ -1915,7 +1914,9 @@ void TWrite::write(const Instrument* item, XmlWriter& xml, WriteContext&, const xml.tag("soundId", item->soundId()); } - write(item->instrumentName(), xml); + if (!item->instrumentLabel().empty()) { + write(item->instrumentLabel(), xml); + } // if (!_trackName.empty()) xml.tag("trackName", item->trackName()); @@ -2093,18 +2094,96 @@ void TWrite::write(const MidiArticulation* item, XmlWriter& xml) xml.endElement(); } -void TWrite::write(const StaffName& item, XmlWriter& xml) +void TWrite::write(const StaffLabel& item, XmlWriter& xml) +{ + xml.startElement("StaffLabel"); + writeProperties(item, xml); + xml.endElement(); +} + +void TWrite::writeProperties(const StaffLabel& item, XmlWriter& xml) { String longName = item.longName(); if (!longName.empty()) { - lineBreakToTag(longName); - xml.writeXml(u"longName", longName); + xml.writeXml(u"longName", lineBreakToTag(longName)); } String shortName = item.shortName(); if (!shortName.empty()) { - lineBreakToTag(shortName); - xml.writeXml(u"shortName", shortName); + xml.writeXml(u"shortName", lineBreakToTag(shortName)); + } +} + +void TWrite::write(const InstrumentLabel& item, XmlWriter& xml) +{ + xml.startElement("InstrumentLabel"); + writeProperties(item, xml); + xml.endElement(); +} + +void TWrite::writeProperties(const InstrumentLabel& item, XmlWriter& xml) +{ + writeProperties(static_cast(item), xml); + + String transposition = item.transposition(); + if (!transposition.empty()) { + xml.writeXml(u"transposition", lineBreakToTag(transposition)); + } + + if (!item.showTranspositionLong()) { + xml.tag("showTranspositionLong", item.showTranspositionLong()); + } + + if (!item.showTranspositionShort()) { + xml.tag("showTranspositionShort", item.showTranspositionShort()); + } + + if (item.number() != 0) { + xml.tag("number", item.number()); + } + + if (!item.showNumberLong()) { + xml.tag("showNumberLong", item.showNumberLong()); + } + + if (!item.showNumberShort()) { + xml.tag("showNumberShort", item.showNumberShort()); + } + + if (!item.allowGroupName()) { + xml.tag("allowGroupName", item.allowGroupName()); + } + + if (!item.customNameLong().empty()) { + xml.writeXml(u"customNameLong", lineBreakToTag(item.customNameLong())); + } + + if (!item.customNameShort().empty()) { + xml.writeXml(u"customNameShort", lineBreakToTag(item.customNameShort())); + } + + if (item.useCustomNameLong()) { + xml.tag("useCustomNameLong", item.useCustomNameLong()); + } + + if (item.useCustomNameShort()) { + xml.tag("useCustomNameShort", item.useCustomNameShort()); + } + + if (!item.customNameLongGroup().empty()) { + xml.writeXml(u"customNameLongGroup", item.customNameLongGroup()); + } + + if (!item.customNameShortGroup().empty()) { + xml.writeXml(u"customNameShortGroup", item.customNameShortGroup()); + } + + if (item.useCustomNameLongGroup()) { + xml.tag("useCustomNameLongGroup", item.useCustomNameLongGroup()); + } + + if (item.useCustomNameShortGroup()) { + xml.tag("useCustomNameShortGroup", item.useCustomNameShortGroup()); } } @@ -2504,8 +2583,6 @@ void TWrite::write(const Part* item, XmlWriter& xml, WriteContext& ctx) xml.tag("soloist", item->soloist()); } - xml.tag("trackName", item->partName()); - if (item->color() != Part::DEFAULT_COLOR) { xml.tag("color", item->color()); } @@ -2901,8 +2978,8 @@ void TWrite::write(const StaffType* item, XmlWriter& xml, WriteContext& ctx) if (!item->xmlName().isEmpty()) { xml.tag("name", item->xmlName()); } - if (!item->staffName().empty()) { - write(item->staffName(), xml); + if (!item->staffLabel().empty()) { + write(item->staffLabel(), xml); } if (item->lines() != 5) { xml.tag("lines", item->lines()); diff --git a/src/engraving/rw/write/twrite.h b/src/engraving/rw/write/twrite.h index 05a2eb528be14..7086b97b17520 100644 --- a/src/engraving/rw/write/twrite.h +++ b/src/engraving/rw/write/twrite.h @@ -83,6 +83,7 @@ class Image; class Instrument; class InstrChannel; class InstrumentChange; +class InstrumentLabel; class Jump; @@ -129,7 +130,7 @@ class SLine; class Spanner; class Spacer; class Staff; -class StaffName; +class StaffLabel; class StaffState; class StaffText; class StaffTextBase; @@ -275,7 +276,6 @@ class TWrite static void write(const Slur* item, XmlWriter& xml, WriteContext& ctx); static void write(const Spacer* item, XmlWriter& xml, WriteContext& ctx); static void write(const Staff* item, XmlWriter& xml, WriteContext& ctx); - static void write(const StaffName& item, XmlWriter& xml); static void write(const StaffState* item, XmlWriter& xml, WriteContext& ctx); static void write(const StaffText* item, XmlWriter& xml, WriteContext& ctx); static void write(const StaffType* item, XmlWriter& xml, WriteContext& ctx); @@ -320,6 +320,9 @@ class TWrite static void writeItemEid(const EngravingObject* item, XmlWriter& xml, WriteContext& ctx); static void writeItemLink(const EngravingObject* item, XmlWriter& xml, WriteContext& ctx); + static void write(const StaffLabel& item, XmlWriter& xml); + static void write(const InstrumentLabel& item, XmlWriter& xml); + private: static void writeStyledProperties(const EngravingItem* item, XmlWriter& xml); @@ -362,6 +365,8 @@ class TWrite static void writeSystemLock(const SystemLock* systemLock, XmlWriter& xml); - static void lineBreakToTag(String& str); + static muse::String lineBreakToTag(const String& str); + static void writeProperties(const StaffLabel& item, XmlWriter& xml); + static void writeProperties(const InstrumentLabel& item, XmlWriter& xml); }; } diff --git a/src/engraving/style/style.cpp b/src/engraving/style/style.cpp index 159f56e1e9204..b7d61574cd671 100644 --- a/src/engraving/style/style.cpp +++ b/src/engraving/style/style.cpp @@ -238,6 +238,9 @@ bool MStyle::readProperties(XmlReader& e) case P_TYPE::INSTRUMENT_NAMES_ALIGN: set(idx, TConv::fromXml(e.readAsciiText(), InstrumentNamesAlign::RIGHT_RIGHT)); break; + case P_TYPE::INSTRUMENT_NAMES_FORMAT: + set(idx, TConv::fromXml(e.readAsciiText(), InstrumentNamesFormat::NAME_IN_TRANSP_NUM)); + break; default: ASSERT_X(u"unhandled type " + String::number(int(type))); } @@ -636,6 +639,11 @@ void MStyle::read(XmlReader& e, compat::ReadChordListHook* readChordListHook, in } } + if (mscVersion < 500) { + set(Sid::windsNameByGroup, false); + set(Sid::vocalsNameByGroup, false); + } + if (mscVersion < 470) { set(Sid::dividerLeftAlignToSystemBarline, false); set(Sid::dividerRightAlignToSystemBarline, false); @@ -772,6 +780,8 @@ void MStyle::save(XmlWriter& xml, bool optimize) xml.tag(st.xmlName, TConv::toXml(value(idx).value())); } else if (P_TYPE::INSTRUMENT_NAMES_ALIGN == type) { xml.tag(st.xmlName, TConv::toXml(value(idx).value())); + } else if (P_TYPE::INSTRUMENT_NAMES_FORMAT == type) { + xml.tag(st.xmlName, TConv::toXml(value(idx).value())); } else { PropertyValue val = value(idx); //! NOTE for compatibility diff --git a/src/engraving/style/styledef.cpp b/src/engraving/style/styledef.cpp index 65f69f73018e2..ec3773b1bdc9e 100644 --- a/src/engraving/style/styledef.cpp +++ b/src/engraving/style/styledef.cpp @@ -58,9 +58,21 @@ const std::array StyleDef::styleValue styleDef(minSystemDistance, 8.5_sp), styleDef(maxSystemDistance, 15.0_sp), styleDef(alignSystemToMargin, true), + + styleDef(instrumentNamesShowTranspositionLong, true), + styleDef(instrumentNamesShowTranspositionShort, true), + styleDef(instrumentNamesFormatLong, InstrumentNamesFormat::NAME_IN_TRANSP_NUM), + styleDef(instrumentNamesCustomFormatLong, String(u"$name in $transposition $number")), + styleDef(instrumentNamesFormatShort, InstrumentNamesFormat::NAME_IN_TRANSP_NUM), + styleDef(instrumentNamesCustomFormatShort, String(u"$name in $transposition $number")), + styleDef(instrumentNamesAlignLong, InstrumentNamesAlign::RIGHT_RIGHT), styleDef(instrumentNamesAlignShort, InstrumentNamesAlign::RIGHT_RIGHT), styleDef(instrumentNamesStackVertically, false), + styleDef(windsNameByGroup, true), + styleDef(vocalsNameByGroup, true), + styleDef(stringsNameByGroup, false), + styleDef(othersNameByGroup, false), styleDef(enableVerticalSpread, true), styleDef(spreadSystem, 2.5), diff --git a/src/engraving/style/styledef.h b/src/engraving/style/styledef.h index 0fa61681626d2..f1b4fd31ff77d 100644 --- a/src/engraving/style/styledef.h +++ b/src/engraving/style/styledef.h @@ -69,9 +69,20 @@ enum class Sid : short { minSystemDistance, maxSystemDistance, alignSystemToMargin, + + instrumentNamesShowTranspositionLong, + instrumentNamesShowTranspositionShort, + instrumentNamesFormatLong, + instrumentNamesCustomFormatLong, + instrumentNamesFormatShort, + instrumentNamesCustomFormatShort, instrumentNamesAlignLong, instrumentNamesAlignShort, instrumentNamesStackVertically, + windsNameByGroup, + vocalsNameByGroup, + stringsNameByGroup, + othersNameByGroup, enableVerticalSpread, spreadSystem, diff --git a/src/engraving/types/propertyvalue.cpp b/src/engraving/types/propertyvalue.cpp index 0d340b07c4185..4868e2d43c102 100644 --- a/src/engraving/types/propertyvalue.cpp +++ b/src/engraving/types/propertyvalue.cpp @@ -188,6 +188,7 @@ QVariant PropertyValue::toQVariant() const case P_TYPE::MEASURE_NUMBER_PLACEMENT: return static_cast(value()); case P_TYPE::CAPO_TRANSPOSE_MODE: return static_cast(value()); case P_TYPE::INSTRUMENT_NAMES_ALIGN: return static_cast(value()); + case P_TYPE::INSTRUMENT_NAMES_FORMAT: return static_cast(value()); // Other case P_TYPE::GROUPS: { @@ -311,6 +312,7 @@ PropertyValue PropertyValue::fromQVariant(const QVariant& v, P_TYPE type) case P_TYPE::MEASURE_NUMBER_PLACEMENT: return PropertyValue(MeasureNumberPlacement(v.toInt())); case P_TYPE::CAPO_TRANSPOSE_MODE: return PropertyValue(CapoParams::TransposeMode(v.toInt())); case P_TYPE::INSTRUMENT_NAMES_ALIGN: return PropertyValue(InstrumentNamesAlign(v.toInt())); + case P_TYPE::INSTRUMENT_NAMES_FORMAT: return PropertyValue(InstrumentNamesFormat(v.toInt())); // Other case P_TYPE::GROUPS: { diff --git a/src/engraving/types/propertyvalue.h b/src/engraving/types/propertyvalue.h index 1ebd1c7cc031e..cdfd18d8b0d59 100644 --- a/src/engraving/types/propertyvalue.h +++ b/src/engraving/types/propertyvalue.h @@ -131,6 +131,7 @@ enum class P_TYPE : unsigned char { CAPO_TRANSPOSE_MODE, INSTRUMENT_NAMES_ALIGN, + INSTRUMENT_NAMES_FORMAT, // Other GROUPS, @@ -367,6 +368,9 @@ class PropertyValue PropertyValue(const InstrumentNamesAlign& v) : m_type(P_TYPE::INSTRUMENT_NAMES_ALIGN), m_data(make_data(v)) {} + PropertyValue(const InstrumentNamesFormat& v) + : m_type(P_TYPE::INSTRUMENT_NAMES_FORMAT), m_data(make_data(v)) {} + bool isValid() const; P_TYPE type() const; diff --git a/src/engraving/types/types.h b/src/engraving/types/types.h index be0621ed2a728..c57ad2deab8ec 100644 --- a/src/engraving/types/types.h +++ b/src/engraving/types/types.h @@ -286,6 +286,13 @@ enum class InstrumentNamesAlign : unsigned char { LEFT_RIGHT, }; +enum class InstrumentNamesFormat : unsigned char { + NAME_IN_TRANSP_NUM, + NAME_NUM_IN_TRANSP, + TRANSP_NAME_NUM, + CUSTOM, +}; + struct Align { AlignH horizontal = AlignH::LEFT; AlignV vertical = AlignV::TOP; diff --git a/src/engraving/types/typesconv.cpp b/src/engraving/types/typesconv.cpp index 91b3f7b5e495e..ea0dbe088dab1 100644 --- a/src/engraving/types/typesconv.cpp +++ b/src/engraving/types/typesconv.cpp @@ -3412,3 +3412,20 @@ InstrumentNamesAlign TConv::fromXml(const AsciiStringView& str, InstrumentNamesA { return findTypeByXmlTag(INSTR_LABELS_ALIGN, str, def); } + +const std::array, 4> INSTR_NAMES_FORMAT = { { + { InstrumentNamesFormat::NAME_IN_TRANSP_NUM, "name-in-transp-num" }, + { InstrumentNamesFormat::NAME_NUM_IN_TRANSP, "name-num-in-transp" }, + { InstrumentNamesFormat::TRANSP_NAME_NUM, "transp-name-num" }, + { InstrumentNamesFormat::CUSTOM, "custom" } +} }; + +mu::engraving::AsciiStringView mu::engraving::TConv::toXml(InstrumentNamesFormat v) +{ + return findXmlTagByType(INSTR_NAMES_FORMAT, v); +} + +InstrumentNamesFormat TConv::fromXml(const AsciiStringView& str, InstrumentNamesFormat def) +{ + return findTypeByXmlTag(INSTR_NAMES_FORMAT, str, def); +} diff --git a/src/engraving/types/typesconv.h b/src/engraving/types/typesconv.h index 3483e1d8eda70..b903e52f4fef1 100644 --- a/src/engraving/types/typesconv.h +++ b/src/engraving/types/typesconv.h @@ -297,5 +297,8 @@ class TConv static AsciiStringView toXml(InstrumentNamesAlign v); static InstrumentNamesAlign fromXml(const AsciiStringView& str, InstrumentNamesAlign def); + + static AsciiStringView toXml(InstrumentNamesFormat v); + static InstrumentNamesFormat fromXml(const AsciiStringView& str, InstrumentNamesFormat def); }; } diff --git a/src/importexport/bww/internal/bww/importbww.cpp b/src/importexport/bww/internal/bww/importbww.cpp index 92186e2f46ae2..a4c942d371e91 100644 --- a/src/importexport/bww/internal/bww/importbww.cpp +++ b/src/importexport/bww/internal/bww/importbww.cpp @@ -457,7 +457,6 @@ void MsScWriter::header(const QString title, const QString type, mu::engraving::Part* part = score->staff(0)->part(); part->setPlainLongName(instrumentName()); - part->setPartName(instrumentName()); part->instrument()->setTrackName(instrumentName()); part->setMidiProgram(midiProgram() - 1); } diff --git a/src/importexport/capella/internal/capella.cpp b/src/importexport/capella/internal/capella.cpp index 01d927f17c7ba..7f4f8aa9a14c3 100644 --- a/src/importexport/capella/internal/capella.cpp +++ b/src/importexport/capella/internal/capella.cpp @@ -1249,7 +1249,6 @@ void convertCapella(Score* score, Capella* cap, bool capxMode) } else { part->setMidiProgram(cl->sound, 0); } - part->setPartName(cl->descr); part->setPlainLongName(cl->name); part->setPlainShortName(cl->abbrev); diff --git a/src/importexport/guitarpro/internal/gtp/gpconverter.cpp b/src/importexport/guitarpro/internal/gtp/gpconverter.cpp index 8bc70e4f6c04d..a1ad7124e40f3 100644 --- a/src/importexport/guitarpro/internal/gtp/gpconverter.cpp +++ b/src/importexport/guitarpro/internal/gtp/gpconverter.cpp @@ -1077,7 +1077,6 @@ void GPConverter::setUpTrack(const std::unique_ptr& tR) Part* part = new Part(_score); part->setPlainLongName(tR->name()); part->setPlainShortName(tR->shortName()); - part->setPartName(tR->name()); part->setId(idx); _score->appendPart(part); diff --git a/src/importexport/guitarpro/internal/importgtp-gp4.cpp b/src/importexport/guitarpro/internal/importgtp-gp4.cpp index b4565e7b05b69..3df472ad8b602 100644 --- a/src/importexport/guitarpro/internal/importgtp-gp4.cpp +++ b/src/importexport/guitarpro/internal/importgtp-gp4.cpp @@ -742,7 +742,6 @@ bool GuitarPro4::read(IODevice* io) Instrument* instr = part->instrument(); instr->setStringData(stringData); instr->setSingleNoteDynamics(false); - part->setPartName(name); part->setPlainLongName(name); int patch = channelDefaults[midiChannel].patch; diff --git a/src/importexport/guitarpro/internal/importgtp-gp5.cpp b/src/importexport/guitarpro/internal/importgtp-gp5.cpp index 4dade8fdf14e1..a199b5ea43a7a 100644 --- a/src/importexport/guitarpro/internal/importgtp-gp5.cpp +++ b/src/importexport/guitarpro/internal/importgtp-gp5.cpp @@ -592,7 +592,6 @@ bool GuitarPro5::readTracks() Instrument* instr = part->instrument(); instr->setStringData(stringData); instr->setSingleNoteDynamics(false); - part->setPartName(name); part->setPlainLongName(name); stringDatas.insert_or_assign(part->id().toUint64(), stringData); diff --git a/src/importexport/guitarpro/internal/importgtp.cpp b/src/importexport/guitarpro/internal/importgtp.cpp index a7b79b4b43bca..9aa3ab40561f8 100644 --- a/src/importexport/guitarpro/internal/importgtp.cpp +++ b/src/importexport/guitarpro/internal/importgtp.cpp @@ -1517,7 +1517,6 @@ bool GuitarPro2::read(IODevice* io) Instrument* instr = part->instrument(); instr->setStringData(stringData); instr->setSingleNoteDynamics(false); - part->setPartName(name); part->setPlainLongName(name); // @@ -2266,7 +2265,6 @@ bool GuitarPro3::read(IODevice* io) Instrument* instr = part->instrument(); instr->setStringData(stringData); instr->setSingleNoteDynamics(false); - part->setPartName(name); part->setPlainLongName(name); // // determine clef diff --git a/src/importexport/guitarpro/internal/importptb.cpp b/src/importexport/guitarpro/internal/importptb.cpp index abc8ea1ba4845..4a64ba13d3670 100644 --- a/src/importexport/guitarpro/internal/importptb.cpp +++ b/src/importexport/guitarpro/internal/importptb.cpp @@ -790,7 +790,6 @@ void PowerTab::addToScore(ptSection& sec) std::string n = "part " + std::to_string(i + 1); staffName = muse::String::fromStdString(n); } - part->setPartName(staffName); part->setPlainLongName(staffName); std::vector reverseStr; diff --git a/src/importexport/midi/internal/midiimport/importmidi.cpp b/src/importexport/midi/internal/midiimport/importmidi.cpp index daeab1cf1e397..6b83575b45f21 100644 --- a/src/importexport/midi/internal/midiimport/importmidi.cpp +++ b/src/importexport/midi/internal/midiimport/importmidi.cpp @@ -924,7 +924,6 @@ void setTrackInfo(MTrack& mt) if (mt.staff->isTop()) { Part* part = mt.staff->part(); part->setLongName(XmlWriter::xmlString(MidiInstr::concatenateWithComma(trackInstrName, mt.name))); - part->setPartName(part->longName()); part->setMidiChannel(mt.mtrack->outChannel()); int bank = 0; if (mt.mtrack->drumTrack()) { diff --git a/src/importexport/mnx/internal/import/mnximporter.cpp b/src/importexport/mnx/internal/import/mnximporter.cpp index 8836b1edfcdeb..71f33aac07235 100644 --- a/src/importexport/mnx/internal/import/mnximporter.cpp +++ b/src/importexport/mnx/internal/import/mnximporter.cpp @@ -404,7 +404,6 @@ void MnxImporter::importParts() if (it) { part->initFromInstrTemplate(it); } - part->setPartName(String::fromStdString(mnxPart.name_or("Part " + mnxPart.id_or(std::to_string((partNum)))))); part->setLongName(String::fromStdString(mnxPart.name_or(""))); part->setShortName(String::fromStdString(mnxPart.shortName_or(""))); loadInstrument(mnxDocument(), part, mnxPart, part->instrument(), m_mnxKitComponentToMidi); diff --git a/src/importexport/musicxml/internal/import/importmusicxmlpass2.cpp b/src/importexport/musicxml/internal/import/importmusicxmlpass2.cpp index 89874f6b3c974..23cb58bf9c25c 100644 --- a/src/importexport/musicxml/internal/import/importmusicxmlpass2.cpp +++ b/src/importexport/musicxml/internal/import/importmusicxmlpass2.cpp @@ -2236,7 +2236,6 @@ void MusicXmlParserPass2::part() String partName = mxmlPart.getName(); setPartInstruments(m_logger, &m_e, part, id, m_score, m_pass1.getInstrList(id), m_pass1.getIntervals(id), instruments, partName); partName = replacePartNameAccidentals(partName); - part->setPartName(partName); const bool inconsistentVisibility = mxmlPart.getPrintName() != mxmlPart.getPrintAbbr(); if (!isLikelyIncorrectPartName(partName)) { part->setLongNameAll(partName); @@ -2252,12 +2251,7 @@ void MusicXmlParserPass2::part() } else { part->setPlainShortNameAll(u""); } - // set the parts first instrument - // try to prevent an empty track name - if (part->partName() == "") { - String instrId = m_pass1.getInstrList(id).instrument(Fraction(0, 1)); - part->setPartName(muse::value(instruments, instrId).name); - } + if (m_pass1.nparts() == 1 && mxmlPart.getPrintName() && mxmlPart.getPrintAbbr()) { m_score->style().set(Sid::hideInstrumentNameIfOneInstrument, false); } diff --git a/src/importexport/tabledit/internal/importtef.cpp b/src/importexport/tabledit/internal/importtef.cpp index 91817c9afeda3..5bc9f668b3963 100644 --- a/src/importexport/tabledit/internal/importtef.cpp +++ b/src/importexport/tabledit/internal/importtef.cpp @@ -580,7 +580,6 @@ void TablEdit::createParts() Part* part = new Part(score); score->appendPart(part); muse::String staffName { muse::String::fromStdString(instrument.name) }; - part->setPartName(staffName); part->setPlainLongName(staffName); StringData stringData; diff --git a/src/inspector/qml/MuseScore/Inspector/notation/instrumentname/InstrumentNameSettings.qml b/src/inspector/qml/MuseScore/Inspector/notation/instrumentname/InstrumentNameSettings.qml index 0d2a030e96010..b8e623f8bec04 100644 --- a/src/inspector/qml/MuseScore/Inspector/notation/instrumentname/InstrumentNameSettings.qml +++ b/src/inspector/qml/MuseScore/Inspector/notation/instrumentname/InstrumentNameSettings.qml @@ -63,7 +63,7 @@ Column { FlatButton { width: parent.width - text: qsTrc("inspector", "Staff/Part properties") + text: qsTrc("inspector", "Instrument / Staff properties") navigation.panel: root.navigationPanel navigation.row: root.navigationRowStart + 2 diff --git a/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/InstrumentSettingsPopup.qml b/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/InstrumentSettingsPopup.qml index 0eaf1d77cfda6..30a19d10a247f 100644 --- a/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/InstrumentSettingsPopup.qml +++ b/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/InstrumentSettingsPopup.qml @@ -119,6 +119,34 @@ StyledPopupView { } } + Column { + width: parent.width + spacing: 8 + + StyledTextLabel { + id: numberLabel + width: parent.width + text: qsTrc("layoutpanel/instrumentsettingspopup", "Number") + horizontalAlignment: Text.AlignLeft + } + + IncrementalPropertyControl { + step: 1 + decimals: 0 + maxValue: 100 + minValue: 0 + + navigation.panel: root.navigationPanel + navigation.row: 3 + navigation.accessible.name: numberLabel.text + " " + currentText + + currentValue: settingsModel.number + onValueEdited: function(newValue) { + settingsModel.number = newValue + } + } + } + SeparatorLine {} Column { diff --git a/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/instrumentsettingsmodel.cpp b/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/instrumentsettingsmodel.cpp index 98693bb61957a..cb2c895f09f1e 100644 --- a/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/instrumentsettingsmodel.cpp +++ b/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/instrumentsettingsmodel.cpp @@ -51,6 +51,7 @@ void InstrumentSettingsModel::load(const QVariant& instrument) m_instrumentName = part->instrument()->nameAsPlainText(); m_instrumentAbbreviature = part->instrument()->abbreviatureAsPlainText(); + m_number = part->instrument()->number(); m_hideWhenEmpty = static_cast(part->hideWhenEmpty()); m_hideStavesWhenIndividuallyEmpty = part->hideStavesWhenIndividuallyEmpty(); m_hasMultipleStaves = part->nstaves() > 1; @@ -75,6 +76,11 @@ QString InstrumentSettingsModel::abbreviature() const return m_instrumentAbbreviature; } +int InstrumentSettingsModel::number() const +{ + return m_number; +} + int InstrumentSettingsModel::hideWhenEmpty() const { return m_hideWhenEmpty; @@ -115,6 +121,17 @@ void InstrumentSettingsModel::setAbbreviature(const QString& abbreviature) notationParts()->setInstrumentAbbreviature(m_instrumentKey, abbreviature); } +void InstrumentSettingsModel::setNumber(int v) +{ + if (m_number == v || !notationParts()) { + return; + } + + m_number = v; + notationParts()->setInstrumentNumber(m_instrumentKey, v); + emit dataChanged(); +} + void InstrumentSettingsModel::setHideWhenEmpty(int value) { if (m_hideWhenEmpty == value || !notationParts()) { diff --git a/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/instrumentsettingsmodel.h b/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/instrumentsettingsmodel.h index 438ba8e5d290b..f33f3c0af8295 100644 --- a/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/instrumentsettingsmodel.h +++ b/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/instrumentsettingsmodel.h @@ -39,6 +39,7 @@ class InstrumentSettingsModel : public QObject, public muse::async::Asyncable, p Q_PROPERTY(QString instrumentName READ instrumentName WRITE setInstrumentName NOTIFY dataChanged) Q_PROPERTY(QString abbreviature READ abbreviature WRITE setAbbreviature NOTIFY dataChanged) + Q_PROPERTY(int number READ number WRITE setNumber NOTIFY dataChanged) Q_PROPERTY(int hideWhenEmpty READ hideWhenEmpty WRITE setHideWhenEmpty NOTIFY hideWhenEmptyChanged) Q_PROPERTY( bool hideStavesWhenIndividuallyEmpty READ hideStavesWhenIndividuallyEmpty WRITE setHideStavesWhenIndividuallyEmpty NOTIFY hideStavesWhenIndividuallyEmptyChanged) @@ -57,6 +58,7 @@ class InstrumentSettingsModel : public QObject, public muse::async::Asyncable, p QString instrumentName() const; QString abbreviature() const; + int number() const; int hideWhenEmpty() const; bool hideStavesWhenIndividuallyEmpty() const; bool hasMultipleStaves() const; @@ -66,6 +68,7 @@ class InstrumentSettingsModel : public QObject, public muse::async::Asyncable, p public slots: void setInstrumentName(const QString& name); void setAbbreviature(const QString& abbreviature); + void setNumber(int v); void setHideWhenEmpty(int value); void setHideStavesWhenIndividuallyEmpty(bool value); @@ -84,6 +87,7 @@ public slots: notation::InstrumentKey m_instrumentKey; QString m_instrumentName; QString m_instrumentAbbreviature; + int m_number = 0; int m_hideWhenEmpty = 0; // AutoOnOff::AUTO bool m_hideStavesWhenIndividuallyEmpty = false; bool m_hasMultipleStaves = false; diff --git a/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/parttreeitem.cpp b/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/parttreeitem.cpp index ce8a7e7a9d560..be77ae0f47f64 100644 --- a/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/parttreeitem.cpp +++ b/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/parttreeitem.cpp @@ -53,7 +53,7 @@ void PartTreeItem::init(const notation::Part* masterPart) setId(part->id()); - const String instName = part->instrument()->nameAsPlainText(); + const String instName = part->partName(); setTitle(instName.simplified()); // Collapse whitespace... setIsVisible(visible); @@ -77,7 +77,7 @@ void PartTreeItem::onScoreChanged(const mu::engraving::ScoreChanges&) return; } - const String instName = m_part->instrument()->nameAsPlainText(); + const String instName = m_part->partName(); setTitle(instName.simplified()); // Collapse whitespace... m_ignoreVisibilityChange = true; diff --git a/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/stafftreeitem.cpp b/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/stafftreeitem.cpp index ab078023e304d..d570b871b7300 100644 --- a/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/stafftreeitem.cpp +++ b/src/instrumentsscene/qml/MuseScore/InstrumentsScene/internal/stafftreeitem.cpp @@ -59,7 +59,10 @@ void StaffTreeItem::init(const Staff* masterStaff) staff = masterStaff; } - QString staffName = staff->staffName(); + QString staffName = staff->staffType()->longName(); + if (staffName.isEmpty()) { + staffName = staff->staffName(); + } //: Prefix for the display name for a linked staff. Preferably, keep this short. QString title = masterStaff->isLinked() ? muse::qtrc("layoutpanel", "[LINK] %1").arg(staffName) : staffName; diff --git a/src/notation/inotationparts.h b/src/notation/inotationparts.h index 6b3186a56e627..465672fa9dbc1 100644 --- a/src/notation/inotationparts.h +++ b/src/notation/inotationparts.h @@ -59,6 +59,7 @@ class INotationParts virtual void setPartSharpFlat(const muse::ID& partId, const SharpFlat& sharpFlat) = 0; virtual void setInstrumentName(const InstrumentKey& instrumentKey, const QString& name) = 0; virtual void setInstrumentAbbreviature(const InstrumentKey& instrumentKey, const QString& abbreviature) = 0; + virtual void setInstrumentNumber(const InstrumentKey& instrumentKey, int v) = 0; virtual void setStaffType(const muse::ID& staffId, StaffTypeId type) = 0; virtual void setStaffConfig(const muse::ID& staffId, const StaffConfig& config, Fraction tick = Fraction(0, 1)) = 0; diff --git a/src/notation/internal/notationparts.cpp b/src/notation/internal/notationparts.cpp index ed085776e3218..5e8927a367ec3 100644 --- a/src/notation/internal/notationparts.cpp +++ b/src/notation/internal/notationparts.cpp @@ -61,28 +61,6 @@ static String formatInstrumentTitleOnScore(const String& instrumentName, const T return instrumentName; // Example: "Flute" } -static String formatInstrumentTitleOnScore(const String& instrumentName, const Trait& trait, int instrumentNumber) -{ - if (instrumentNumber == 0) { - // Only one instance of this instrument in the score - return formatInstrumentTitleOnScore(instrumentName, trait); - } - - String number = String::number(instrumentNumber); - - // Comments for translators start with //: - - if (trait.type == TraitType::Transposition && !trait.isHiddenOnScore) { - //: %1=name ("Horn"), %2=transposition ("C alto"), %3=number ("2"). Example: "Horn in C alto 2" - return muse::mtrc("notation", "%1 in %2 %3", "One of several transposing instruments displayed in the score") - .arg(instrumentName, trait.name, number); - } - - //: %1=name ("Flute"), %2=number ("2"). Example: "Flute 2" - return muse::mtrc("notation", "%1 %2", "One of several instruments displayed in the score") - .arg(instrumentName, number); -} - NotationParts::NotationParts(IGetScore* getScore, INotationInteractionPtr interaction, INotationUndoStackPtr undoStack) : m_getScore(getScore), m_undoStack(undoStack), m_interaction(interaction) { @@ -464,6 +442,33 @@ void NotationParts::setInstrumentAbbreviature(const InstrumentKey& instrumentKey notifyAboutPartChanged(part); } +void NotationParts::setInstrumentNumber(const InstrumentKey& instrumentKey, int v) +{ + TRACEFUNC; + + Part* part = partModifiable(instrumentKey.partId); + if (!part) { + return; + } + + const mu::engraving::Instrument* instrument = part->instrument(instrumentKey.tick); + if (!instrument) { + return; + } + + if (instrument->number() == v) { + return; + } + + startEdit(TranslatableString("undoableAction", "Set instrument number")); + + score()->undo(new mu::engraving::ChangeInstrumentNumber(instrumentKey.tick, part, v)); + + apply(); + + notifyAboutPartChanged(part); +} + bool NotationParts::setVoiceVisible(const ID& staffId, int voiceIndex, bool visible) { TRACEFUNC; @@ -701,8 +706,7 @@ void NotationParts::replaceInstrument(const InstrumentKey& instrumentKey, const startEdit(TranslatableString("undoableAction", "Replace instrument")); if (isMainInstrumentForPart(instrumentKey, part)) { - String newInstrumentPartName = formatInstrumentTitle(newInstrument.trackName(), newInstrument.trait()); - mu::engraving::EditPart::replacePartInstrument(score(), part, newInstrument, newStaffType, newInstrumentPartName); + mu::engraving::EditPart::replacePartInstrument(score(), part, newInstrument, newStaffType); } else { if (!mu::engraving::EditPart::replaceInstrumentAtTick(score(), part, instrumentKey.tick, newInstrument)) { rollback(); @@ -1142,18 +1146,19 @@ void NotationParts::insertNewParts(const PartInstrumentList& parts, const mu::en const String& longN = instrument.longName(); const String& shortN = instrument.shortName(); + InstrumentTrait trait = instrument.trait(); + const String& transp = trait.type == TraitType::Transposition && !trait.isHiddenOnScore ? trait.name : String(); + Part* part = new Part(score()); part->setSoloist(pi.isSoloist); part->setInstrument(instrument); - int instrumentNumber = resolveNewInstrumentNumber(pi.instrumentTemplate, parts); - - String formattedLongName = formatInstrumentTitleOnScore(longN, instrument.trait(), instrumentNumber); - String formattedShortName = formatInstrumentTitleOnScore(shortN, instrument.trait(), instrumentNumber); + part->setLongName(muse::qtrc("notation", longN)); + part->setShortName(muse::qtrc("notation", shortN)); + part->setTransposition(muse::qtrc("notation", transp)); - part->setPartName(formattedLongName); - part->setLongName(formattedLongName); - part->setShortName(formattedShortName); + int instrumentNumber = resolveNewInstrumentNumber(pi.instrumentTemplate, parts); + part->setNumber(instrumentNumber); if (Excerpt* excerpt = score()->excerpt()) { score()->undo(new AddPartToExcerpt(excerpt, part, partIdx)); diff --git a/src/notation/internal/notationparts.h b/src/notation/internal/notationparts.h index d936d857b2bb7..2806108e2f44e 100644 --- a/src/notation/internal/notationparts.h +++ b/src/notation/internal/notationparts.h @@ -58,6 +58,7 @@ class NotationParts : public INotationParts, public muse::async::Asyncable void setPartSharpFlat(const muse::ID& partId, const SharpFlat& sharpFlat) override; void setInstrumentName(const InstrumentKey& instrumentKey, const QString& name) override; void setInstrumentAbbreviature(const InstrumentKey& instrumentKey, const QString& abbreviature) override; + void setInstrumentNumber(const InstrumentKey& instrumentKey, int v) override; void setStaffType(const muse::ID& staffId, StaffTypeId type) override; void setStaffConfig(const muse::ID& staffId, const StaffConfig& config, Fraction tick = Fraction(0, 1)) override; diff --git a/src/notation/notationtypes.h b/src/notation/notationtypes.h index 6ea32d0faa04c..b1342f451ff42 100644 --- a/src/notation/notationtypes.h +++ b/src/notation/notationtypes.h @@ -122,7 +122,8 @@ using BracketType = mu::engraving::BracketType; using StaffGroup = mu::engraving::StaffGroup; using StaffType = mu::engraving::StaffType; using StaffTypeId = mu::engraving::StaffTypes; -using StaffName = mu::engraving::StaffName; +using StaffLabel = mu::engraving::StaffLabel; +using InstrumentLabel = mu::engraving::InstrumentLabel; using Segment = mu::engraving::Segment; using TextStyleType = mu::engraving::TextStyleType; using TraitType = mu::engraving::TraitType; diff --git a/src/notationscene/internal/notationuiactions.cpp b/src/notationscene/internal/notationuiactions.cpp index 514803dcc6f43..95dee806c0916 100644 --- a/src/notationscene/internal/notationuiactions.cpp +++ b/src/notationscene/internal/notationuiactions.cpp @@ -569,8 +569,8 @@ const UiActionList NotationUiActions::s_actions = { UiAction("staff-properties", mu::context::UiCtxProjectOpened, mu::context::CTX_NOTATION_OPENED, - TranslatableString("action", "Staff/Part properties…"), - TranslatableString("action", "Staff/Part properties") + TranslatableString("action", "Instrument / Staff properties…"), + TranslatableString("action", "Instrument / Staff properties") ), UiAction("staff-text-properties", mu::context::UiCtxProjectOpened, diff --git a/src/notationscene/qml/MuseScore/NotationScene/styledialog/InstrumentNamesPage.qml b/src/notationscene/qml/MuseScore/NotationScene/styledialog/InstrumentNamesPage.qml index e51640488835e..d0c551ea69ec8 100644 --- a/src/notationscene/qml/MuseScore/NotationScene/styledialog/InstrumentNamesPage.qml +++ b/src/notationscene/qml/MuseScore/NotationScene/styledialog/InstrumentNamesPage.qml @@ -50,7 +50,175 @@ StyledFlickable { StyledGroupBox { Layout.fillWidth: true Layout.minimumWidth: 500 - title: qsTrc("notation/editstyle/instrumentnames", "Instrument & staff names alignment") + title: qsTrc("notation/editstyle/instrumentnames", "Transposition") + + ColumnLayout { + spacing: 12 + + ColumnLayout { + spacing: 8 + + StyledTextLabel { + text: qsTrc("notation/editstyle/instrumentnames", "Show transposition") + } + + StyleToggle { + text: qsTrc("notation/editstyle/instrumentnames", "On long names") + styleItem: instrumentNamesModel.instrumentNamesShowTranspositionLong + } + + StyleToggle { + text: qsTrc("notation/editstyle/instrumentnames", "On abbreviated names") + styleItem: instrumentNamesModel.instrumentNamesShowTranspositionShort + } + } + + ColumnLayout { + spacing: 8 + + enabled: instrumentNamesModel.instrumentNamesShowTranspositionLong.value === true + + StyledTextLabel { + text: qsTrc("notation/editstyle/instrumentnames", "Long name format:") + } + + ColumnLayout { + spacing : 8 + Layout.alignment: Qt.AlignTop + + Repeater { + model: [ + { text: qsTrc("notation/editstyle/instrumentnames", "Horn in F 1"), value: 0 }, + { text: qsTrc("notation/editstyle/instrumentnames", "Horn 1 in F"), value: 1 }, + { text: qsTrc("notation/editstyle/instrumentnames", "F Horn 1"), value: 2 }, + { text: qsTrc("notation/editstyle/instrumentnames", "Custom:"), value: 3 }, + ] + + RoundedRadioButton { + required property var modelData + text: modelData.text + checked: instrumentNamesModel.instrumentNamesFormatLong.value === modelData.value + onClicked: instrumentNamesModel.instrumentNamesFormatLong.value = modelData.value + } + } + } + + RowLayout { + id: customFormatLong + spacing: 8 + + enabled: instrumentNamesModel.instrumentNamesFormatLong.value === 3 + + TextInputField { + Layout.preferredWidth: 220 + currentText: instrumentNamesModel.instrumentNamesCustomFormatLong.value + onTextEditingFinished: function(newValue) { + instrumentNamesModel.instrumentNamesCustomFormatLong.value = newValue + } + } + + StyleResetButton { + styleItem: instrumentNamesModel.instrumentNamesCustomFormatLong + enabled: !styleItem.isDefault && customFormatLong.enabled + } + } + } + + ColumnLayout { + spacing: 8 + + enabled: instrumentNamesModel.instrumentNamesShowTranspositionShort.value === true + + StyledTextLabel { + text: qsTrc("notation/editstyle/instrumentnames", "Short name format:") + } + + ColumnLayout { + spacing : 8 + Layout.alignment: Qt.AlignTop + + Repeater { + model: [ + { text: qsTrc("notation/editstyle/instrumentnames", "Hn. in F 1"), value: 0 }, + { text: qsTrc("notation/editstyle/instrumentnames", "Hn. 1 in F"), value: 1 }, + { text: qsTrc("notation/editstyle/instrumentnames", "F Hn. 1"), value: 2 }, + { text: qsTrc("notation/editstyle/instrumentnames", "Custom:"), value: 3 }, + ] + + RoundedRadioButton { + required property var modelData + text: modelData.text + checked: instrumentNamesModel.instrumentNamesFormatShort.value === modelData.value + onClicked: instrumentNamesModel.instrumentNamesFormatShort.value = modelData.value + } + } + } + + RowLayout { + id: customFormatShort + spacing: 8 + + enabled: instrumentNamesModel.instrumentNamesFormatShort.value === 3 + + TextInputField { + Layout.preferredWidth: 220 + currentText: instrumentNamesModel.instrumentNamesCustomFormatShort.value + onTextEditingFinished: function(newValue) { + instrumentNamesModel.instrumentNamesCustomFormatShort.value = newValue + } + } + + StyleResetButton { + styleItem: instrumentNamesModel.instrumentNamesCustomFormatShort + enabled: !styleItem.isDefault && customFormatShort.enabled + } + } + } + } + } + + StyledGroupBox { + Layout.fillWidth: true + Layout.minimumWidth: 500 + title: qsTrc("notation/editstyle/instrumentnames", "Group names") + + ColumnLayout { + spacing: 12 + + ColumnLayout { + spacing: 8 + + StyledTextLabel { + text: qsTrc("notation/editstyle/instrumentnames", "Enable group names for") + } + + StyleToggle { + text: qsTrc("notation/editstyle/instrumentnames", "Winds") + styleItem: instrumentNamesModel.windsNameByGroup + } + + StyleToggle { + text: qsTrc("notation/editstyle/instrumentnames", "Vocals") + styleItem: instrumentNamesModel.vocalsNameByGroup + } + + StyleToggle { + text: qsTrc("notation/editstyle/instrumentnames", "Strings") + styleItem: instrumentNamesModel.stringsNameByGroup + } + + StyleToggle { + text: qsTrc("notation/editstyle/instrumentnames", "Others") + styleItem: instrumentNamesModel.othersNameByGroup + } + } + } + } + + StyledGroupBox { + Layout.fillWidth: true + Layout.minimumWidth: 500 + title: qsTrc("notation/editstyle/instrumentnames", "Alignment") ColumnLayout { width: parent.width diff --git a/src/notationscene/qml/MuseScore/NotationScene/styledialog/instrumentnamespagemodel.cpp b/src/notationscene/qml/MuseScore/NotationScene/styledialog/instrumentnamespagemodel.cpp index 044f5f2a839f8..f9f01203676b1 100644 --- a/src/notationscene/qml/MuseScore/NotationScene/styledialog/instrumentnamespagemodel.cpp +++ b/src/notationscene/qml/MuseScore/NotationScene/styledialog/instrumentnamespagemodel.cpp @@ -29,12 +29,82 @@ InstrumentNamesPageModel::InstrumentNamesPageModel(QObject* parent) StyleId::instrumentNamesAlignLong, StyleId::instrumentNamesAlignShort, StyleId::instrumentNamesStackVertically, + StyleId::windsNameByGroup, + StyleId::vocalsNameByGroup, + StyleId::stringsNameByGroup, + StyleId::othersNameByGroup, + + StyleId::instrumentNamesShowTranspositionLong, + StyleId::instrumentNamesShowTranspositionShort, + StyleId::instrumentNamesFormatLong, + StyleId::instrumentNamesCustomFormatLong, + StyleId::instrumentNamesFormatShort, + StyleId::instrumentNamesCustomFormatShort, }) { } -StyleItem* InstrumentNamesPageModel::instrumentNamesAlignLong() const { return styleItem(StyleId::instrumentNamesAlignLong); } +StyleItem* InstrumentNamesPageModel::instrumentNamesAlignLong() const +{ + return styleItem(StyleId::instrumentNamesAlignLong); +} + +StyleItem* InstrumentNamesPageModel::instrumentNamesAlignShort() const +{ + return styleItem(StyleId::instrumentNamesAlignShort); +} -StyleItem* InstrumentNamesPageModel::instrumentNamesAlignShort() const { return styleItem(StyleId::instrumentNamesAlignShort); } +StyleItem* InstrumentNamesPageModel::instrumentNamesStackVertically() const +{ + return styleItem(StyleId::instrumentNamesStackVertically); +} -StyleItem* InstrumentNamesPageModel::instrumentNamesStackVertically() const { return styleItem(StyleId::instrumentNamesStackVertically); } +StyleItem* InstrumentNamesPageModel::windsNameByGroup() const +{ + return styleItem(StyleId::windsNameByGroup); +} + +StyleItem* InstrumentNamesPageModel::vocalsNameByGroup() const +{ + return styleItem(StyleId::vocalsNameByGroup); +} + +StyleItem* InstrumentNamesPageModel::stringsNameByGroup() const +{ + return styleItem(StyleId::stringsNameByGroup); +} + +StyleItem* InstrumentNamesPageModel::othersNameByGroup() const +{ + return styleItem(StyleId::othersNameByGroup); +} + +StyleItem* InstrumentNamesPageModel::instrumentNamesShowTranspositionLong() const +{ + return styleItem(StyleId::instrumentNamesShowTranspositionLong); +} + +StyleItem* InstrumentNamesPageModel::instrumentNamesShowTranspositionShort() const +{ + return styleItem(StyleId::instrumentNamesShowTranspositionShort); +} + +StyleItem* InstrumentNamesPageModel::instrumentNamesFormatLong() const +{ + return styleItem(StyleId::instrumentNamesFormatLong); +} + +StyleItem* InstrumentNamesPageModel::instrumentNamesCustomFormatLong() const +{ + return styleItem(StyleId::instrumentNamesCustomFormatLong); +} + +StyleItem* InstrumentNamesPageModel::instrumentNamesFormatShort() const +{ + return styleItem(StyleId::instrumentNamesFormatShort); +} + +StyleItem* InstrumentNamesPageModel::instrumentNamesCustomFormatShort() const +{ + return styleItem(StyleId::instrumentNamesCustomFormatShort); +} diff --git a/src/notationscene/qml/MuseScore/NotationScene/styledialog/instrumentnamespagemodel.h b/src/notationscene/qml/MuseScore/NotationScene/styledialog/instrumentnamespagemodel.h index bfb624d72692e..06ff726323a1e 100644 --- a/src/notationscene/qml/MuseScore/NotationScene/styledialog/instrumentnamespagemodel.h +++ b/src/notationscene/qml/MuseScore/NotationScene/styledialog/instrumentnamespagemodel.h @@ -32,6 +32,17 @@ class InstrumentNamesPageModel : public AbstractStyleDialogModel Q_PROPERTY(mu::notation::StyleItem * instrumentNamesAlignLong READ instrumentNamesAlignLong CONSTANT) Q_PROPERTY(mu::notation::StyleItem * instrumentNamesAlignShort READ instrumentNamesAlignShort CONSTANT) Q_PROPERTY(mu::notation::StyleItem * instrumentNamesStackVertically READ instrumentNamesStackVertically CONSTANT) + Q_PROPERTY(mu::notation::StyleItem * windsNameByGroup READ windsNameByGroup CONSTANT) + Q_PROPERTY(mu::notation::StyleItem * vocalsNameByGroup READ vocalsNameByGroup CONSTANT) + Q_PROPERTY(mu::notation::StyleItem * stringsNameByGroup READ stringsNameByGroup CONSTANT) + Q_PROPERTY(mu::notation::StyleItem * othersNameByGroup READ othersNameByGroup CONSTANT) + + Q_PROPERTY(mu::notation::StyleItem * instrumentNamesShowTranspositionLong READ instrumentNamesShowTranspositionLong CONSTANT) + Q_PROPERTY(mu::notation::StyleItem * instrumentNamesShowTranspositionShort READ instrumentNamesShowTranspositionShort CONSTANT) + Q_PROPERTY(mu::notation::StyleItem * instrumentNamesFormatLong READ instrumentNamesFormatLong CONSTANT) + Q_PROPERTY(mu::notation::StyleItem * instrumentNamesCustomFormatLong READ instrumentNamesCustomFormatLong CONSTANT) + Q_PROPERTY(mu::notation::StyleItem * instrumentNamesFormatShort READ instrumentNamesFormatShort CONSTANT) + Q_PROPERTY(mu::notation::StyleItem * instrumentNamesCustomFormatShort READ instrumentNamesCustomFormatShort CONSTANT) QML_ELEMENT @@ -41,5 +52,16 @@ class InstrumentNamesPageModel : public AbstractStyleDialogModel StyleItem* instrumentNamesAlignLong() const; StyleItem* instrumentNamesAlignShort() const; StyleItem* instrumentNamesStackVertically() const; + StyleItem* windsNameByGroup() const; + StyleItem* vocalsNameByGroup() const; + StyleItem* stringsNameByGroup() const; + StyleItem* othersNameByGroup() const; + + StyleItem* instrumentNamesShowTranspositionLong() const; + StyleItem* instrumentNamesShowTranspositionShort() const; + StyleItem* instrumentNamesFormatLong() const; + StyleItem* instrumentNamesCustomFormatLong() const; + StyleItem* instrumentNamesFormatShort() const; + StyleItem* instrumentNamesCustomFormatShort() const; }; } diff --git a/src/notationscene/widgets/editstaff.cpp b/src/notationscene/widgets/editstaff.cpp index f5db540a7bf02..5c10eb7e92e17 100644 --- a/src/notationscene/widgets/editstaff.cpp +++ b/src/notationscene/widgets/editstaff.cpp @@ -196,6 +196,23 @@ void EditStaff::updateInstrument() longName->setPlainText(m_instrument.nameAsPlainText()); shortName->setPlainText(m_instrument.abbreviatureAsPlainText()); + instrumentNumber->setValue(m_instrument.number()); + + const InstrumentLabel& instrLabel = m_instrument.instrumentLabel(); + showNumberLong->setChecked(instrLabel.showNumberLong()); + showNumberShort->setChecked(instrLabel.showNumberShort()); + showTranspositionLong->setChecked(instrLabel.showTranspositionLong()); + showTranspositionShort->setChecked(instrLabel.showTranspositionShort()); + transpositionLabel->setText(TextBase::unEscape(instrLabel.transposition())); + allowGroupName->setChecked(instrLabel.allowGroupName()); + useCustomLong->setChecked(instrLabel.useCustomNameLong()); + useCustomShort->setChecked(instrLabel.useCustomNameShort()); + customLongName->setPlainText(TextBase::unEscape(instrLabel.customNameLong())); + customShortName->setPlainText(TextBase::unEscape(instrLabel.customNameShort())); + useCustomGroupLong->setChecked(instrLabel.useCustomNameLongGroup()); + useCustomGroupShort->setChecked(instrLabel.useCustomNameShortGroup()); + customLongNameGroup->setPlainText(TextBase::unEscape(instrLabel.customNameLongGroup())); + customShortNameGroup->setPlainText(TextBase::unEscape(instrLabel.customNameShortGroup())); const InstrumentTemplate* templ = mu::engraving::searchTemplate(m_instrument.id()); if (templ) { @@ -554,6 +571,23 @@ void EditStaff::applyPartProperties() m_instrument.setShortName(String::fromQString(sn)); m_instrument.setLongName(String::fromQString(ln)); + m_instrument.setNumber(instrumentNumber->value()); + + InstrumentLabel& name = m_instrument.instrumentLabel(); + name.setShowNumberLong(showNumberLong->isChecked()); + name.setShowNumberShort(showNumberShort->isChecked()); + name.setShowTranspositionLong(showTranspositionLong->isChecked()); + name.setShowTranspositionShort(showTranspositionShort->isChecked()); + name.setTransposition(transpositionLabel->text()); + name.setAllowGroupName(allowGroupName->isChecked()); + name.setUseCustomNameLong(useCustomLong->isChecked()); + name.setUseCustomNameShort(useCustomShort->isChecked()); + name.setCustomNameLong(customLongName->toPlainText()); + name.setCustomNameShort(customShortName->toPlainText()); + name.setUseCustomNameLongGroup(useCustomGroupLong->isChecked()); + name.setUseCustomNameShortGroup(useCustomGroupShort->isChecked()); + name.setCustomNameLongGroup(customLongNameGroup->toPlainText()); + name.setCustomNameShortGroup(customShortNameGroup->toPlainText()); size_t staffIdxInPart = muse::indexOf(part->staves(), m_orgStaff); DO_ASSERT(staffIdxInPart != muse::nidx); diff --git a/src/notationscene/widgets/editstaff.ui b/src/notationscene/widgets/editstaff.ui index fa9cd3e61d079..dff758f4fdedc 100644 --- a/src/notationscene/widgets/editstaff.ui +++ b/src/notationscene/widgets/editstaff.ui @@ -6,8 +6,8 @@ 0 0 - 788 - 712 + 869 + 1091 @@ -23,704 +23,1187 @@ - Staff/Part properties + Instrument & Staff properties - - - - - - - - 29 - 29 - - - - Apply and go to previous staff - - - Apply and go to previous staff - - - - - - - - - - - 29 - 29 - - - - Apply and go to next staff - - - Apply and go to next staff - - - - - - - - - - Qt::Orientation::Horizontal - - - - 40 - 20 - - - - - - - - - - - 0 - 0 - - - - Part properties + + + + + true - - - - - 0 - - - - - 6 - + + + + 0 + 0 + 835 + 1143 + + + + + + + + 0 + 0 + + + + Instrument properties + + - - - changeInstrument + + + 0 + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + 6 + + + + + changeInstrument + + + + + + + + + Instrument: + + + instrumentName + + + + + + + Replace instrument… + + + + + + + + + Instrument name properties + + + + + 0 + + + + + On abbreviated name + + + + + + + Number: + + + + + + + + 0 + 0 + + + + + + + + Show number: + + + + + + + Transposition: + + + + + + + On long name + + + + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + On long name + + + + + + + On abbreviated name + + + + + + + Show transposition: + + + + + + + + + + + + 0 + 0 + + + + Abbreviated instrument name: + + + shortName + + + + + + + Use custom abbreviated name: + + + + + + + + 0 + 0 + + + + true + + + + + + + + 0 + 0 + + + + Instrument name: + + + longName + + + + + + + + 0 + 0 + + + + true + + + + + + + + + + Use custom name: + + + + + + + + + + + + Allow group name + + + true + + + + + + Use custom group name: + + + + + + + Use custom abbreviated group name: + + + + + + + + + + + + + - - - Replace instrument… + + + + + + + + Usable pitch range: + + + + + + + + + Amateur: + + + minPitchA + + + + + + + 4 + + + true + + + + + + + Edit + + + + + + + + + + - + + + maxPitchA + + + + + + + 4 + + + true + + + + + + + Edit + + + + + + + + + + Qt::Orientation::Horizontal + + + + 0 + 0 + + + + + + + + Professional: + + + minPitchP + + + + + + + 4 + + + true + + + + + + + Edit + + + + + + + + + + - + + + maxPitchP + + + + + + + 4 + + + true + + + + + + + Edit + + + + + + + + + + Qt::Orientation::Horizontal + + + + 0 + 0 + + + + + + + + + + Qt::Orientation::Horizontal + + + + + + + + + + + Interval from written to sounding pitch + + + Transposition: + + + iList + + + + + + + Octave + + + 10 + + + + + + + Octave(s) + + + + octave + + + + + + + + 0 + 0 + + + + Interval + + + + 0 - Perfect unison + + + + + 1 - Augmented unison + + + + + 0 - Diminished second + + + + + 1 - Minor second + + + + + 2 - Major second + + + + + 3 - Augmented second + + + + + 2 - Diminished third + + + + + 3 - Minor third + + + + + 4 - Major third + + + + + 5 - Augmented third + + + + + 4 - Diminished fourth + + + + + 5 - Perfect fourth + + + + + 6 - Augmented fourth + + + + + 6 - Diminished fifth + + + + + 7 - Perfect fifth + + + + + 8 - Augmented fifth + + + + + 7 - Diminished sixth + + + + + 8 - Minor sixth + + + + + 9 - Major sixth + + + + + 10 - Augmented sixth + + + + + 9 - Diminished seventh + + + + + 10 - Minor seventh + + + + + 11 - Major seventh + + + + + 12 - Augmented seventh + + + + + 11 - Diminished octave + + + + + 12 - Perfect octave + + + + + + + + Up + + + + + + + Down + + + + + + + Qt::Orientation::Horizontal + + + + 17 + 18 + + + + + + + + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Prefer sharps or flats for transposed key signatures: + + + preferSharpFlat + + + + + + + + None + + + + + Sharps + + + + + Flats + + + + + Auto + + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + Number of strings: + + + numOfStrings + + + + + + + 0 + + + + + editStringData + + + + + + + Edit string data… + + + + + + + Don’t reflect transposition in linked tablature staves + + + true + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + - + + + + 6 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Staff properties + + + + Qt::Orientation::Horizontal - 40 - 20 + 13 + 13 - - - - - - Instrument: - - - instrumentName - - - - - - - - - - - - 0 - 0 - - - - Instrument name: - - - longName - - - - - - - - 0 - 0 - - - - Abbreviated instrument name: - - - shortName - - - - - - - - 0 - 40 - - - - true - - - - - - - - 0 - 40 - - - - true - - - - - - - - - Usable pitch range: - - - - - - - - - Amateur: - - - minPitchA - - - - - - - 4 - - - true - - - - - - - Edit - - - - - - - - - - - - - - maxPitchA - - - - - - - 4 - - - true - - - - - - - Edit - - - - - - - - - - Qt::Orientation::Horizontal - - - - 0 - 0 - - - - - - - - Professional: - - - minPitchP - - - - - - - 4 - - - true - - - - - - - Edit - - - - - - - - - - - - - - maxPitchP - - - - - - - 4 - - - true - - - - - - - Edit - - - - - - - - - - Qt::Orientation::Horizontal - - - - 0 - 0 - - - - - - - - - - Qt::Orientation::Horizontal - - - - - - - - - - - Interval from written to sounding pitch + + + + Advanced style properties… + + + + - Transposition: + Staff line color: - iList + color - - - - Octave + + + + Qt::Orientation::Horizontal - - 10 + + + 13 + 13 + + + + + + + + Extra distance above staff: + + + spinExtraDistance - - + + + + Qt::FocusPolicy::TabFocus + + + + + - Octave(s) + + Lines: + + + Qt::TextFormat::PlainText - octave + lines - - - - - 0 - 0 - + + + + Show barlines - - Interval + + + + + + Invisible staff lines + + + + + + Style group: + + + staffGroupName + + + + + + + % + + + 1 + + + 10.000000000000000 + + + 1000.000000000000000 + + + 100.000000000000000 + + + + + + + sp + + + -50.000000000000000 + + + 50.000000000000000 + + + 0.250000000000000 + + + + + + + + + + Show time signature + + + + + - 0 - Perfect unison - - - - - 1 - Augmented unison - - - - - 0 - Diminished second - - - - - 1 - Minor second - - - - - 2 - Major second - - - - - 3 - Augmented second - - - - - 2 - Diminished third - - - - - 3 - Minor third - - - - - 4 - Major third - - - - - 5 - Augmented third - - - - - 4 - Diminished fourth - - - - - 5 - Perfect fourth - - - - - 6 - Augmented fourth - - - - - 6 - Diminished fifth - - - - - 7 - Perfect fifth - - - - - 8 - Augmented fifth - - - - - 7 - Diminished sixth - - - - - 8 - Minor sixth - - - - - 9 - Major sixth - - - - - 10 - Augmented sixth - - - - - 9 - Diminished seventh - - - - - 10 - Minor seventh - - - - - 11 - Major seventh - - - - - 12 - Augmented seventh + Auto - 11 - Diminished octave + On - 12 - Perfect octave + Off - - + + - Up + Line distance: + + + lineDistance - - + + - Down + Show clef - - + + + + Hide system barline + + + + + + + + 0 + 0 + + + + sp + + + 0.250000000000000 + + + + + Qt::Orientation::Horizontal - 17 - 18 + 13 + 29 - - - - - - - 6 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Prefer sharps or flats for transposed key signatures: - - - preferSharpFlat - - - - - - - - None - - - - - Sharps - - - + + + + 1 + + + 14 + + + 5 + + + + + + + + 0 + 0 + + + + Merge matching rests: + + + + + + + Scale: + + + mag + + + + + + + 0 + + + - Flats + Staff label: - - + + + + - Auto + Abbreviated staff label - - - - - - - Qt::Orientation::Horizontal - - - - 40 - 20 - - - - - - - - - - - - - - 6 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - Number of strings: - - - numOfStrings - - - - - - - editStringData - - - - - - - Edit string data… - - - - - - - Don’t reflect transposition in linked tablature staves - - - true - - - - - - - Qt::Orientation::Horizontal - - - - 40 - 20 - - - - - - - - + + + + + + + + + + + + + + + - + + + + + + + 29 + 29 + + + + Apply and go to previous staff + + + Apply and go to previous staff + + + + + + + + + + + 29 + 29 + + + + Apply and go to next staff + + + Apply and go to next staff + + + + + + + + + + Qt::Orientation::Horizontal + + + + 40 + 20 + + + + + + + Qt::Orientation::Horizontal @@ -730,304 +1213,6 @@ - - - - - 0 - 0 - - - - - 0 - 0 - - - - Staff properties - - - - - - Qt::Orientation::Horizontal - - - - 13 - 13 - - - - - - - - Advanced style properties… - - - - - - - Staff line color: - - - color - - - - - - - Qt::Orientation::Horizontal - - - - 13 - 13 - - - - - - - - Extra distance above staff: - - - spinExtraDistance - - - - - - - Qt::FocusPolicy::TabFocus - - - - - - - Lines: - - - Qt::TextFormat::PlainText - - - lines - - - - - - - Show barlines - - - - - - - Invisible staff lines - - - - - - - Style group: - - - staffGroupName - - - - - - - % - - - 1 - - - 10.000000000000000 - - - 1000.000000000000000 - - - 100.000000000000000 - - - - - - - sp - - - -50.000000000000000 - - - 50.000000000000000 - - - 0.250000000000000 - - - - - - - - - - Show time signature - - - - - - - - Auto - - - - - On - - - - - Off - - - - - - - - Line distance: - - - lineDistance - - - - - - - Show clef - - - - - - - Hide system barline - - - - - - - - 0 - 0 - - - - sp - - - 0.250000000000000 - - - - - - - Qt::Orientation::Horizontal - - - - 13 - 29 - - - - - - - - 1 - - - 14 - - - 5 - - - - - - - - 0 - 0 - - - - Merge matching rests: - - - - - - - Scale: - - - mag - - - - - - - 0 - - - - - Staff label: - - - - - - - Abbreviated staff label - - - - - - - - - - - - - - @@ -1039,7 +1224,6 @@ - changeInstrument longName shortName minPitchA @@ -1055,8 +1239,6 @@ up down preferSharpFlat - editStringData - noReflectTranspositionInLinkedTab showClef invisible lines From 11f6a84ef157898f34599e135908f27b02a335e4 Mon Sep 17 00:00:00 2001 From: Michele Spagnolo Date: Tue, 10 Mar 2026 17:20:24 +0100 Subject: [PATCH 2/5] update utests --- .../tests/barline_data/barlinedelete-ref.mscx | 7 +- src/engraving/tests/beam_data/Beam-A.mscx | 3 +- src/engraving/tests/beam_data/Beam-B.mscx | 3 +- src/engraving/tests/beam_data/Beam-C.mscx | 3 +- src/engraving/tests/beam_data/Beam-D.mscx | 3 +- src/engraving/tests/beam_data/Beam-E.mscx | 3 +- src/engraving/tests/beam_data/Beam-F.mscx | 3 +- src/engraving/tests/beam_data/Beam-G.mscx | 3 +- .../tests/beam_data/beamNoSlope.mscx | 9 +- .../tests/beam_data/beamPositions.mscx | 9 +- .../tests/beam_data/beamStemDir-01-ref.mscx | 9 +- .../tests/beam_data/flatBeams-ref.mscx | 9 +- .../beam_data/flipBeamStemDir-01-ref.mscx | 9 +- .../tests/beam_data/flippedDirection.mscx | 9 +- src/engraving/tests/beam_data/wideBeams.mscx | 9 +- .../tests/box_data/undoRemoveVBox1-ref.mscx | 7 +- .../tests/box_data/undoRemoveVBox2-ref.mscx | 7 +- .../tests/breath_data/breath01-ref.mscx | 14 +- .../tests/breath_data/breath02-ref.mscx | 14 +- .../tests/chordsymbol_data/add-link-ref.mscx | 1 - .../tests/chordsymbol_data/add-part-ref.mscx | 2 - .../tests/chordsymbol_data/clear-ref.mscx | 1 - .../tests/chordsymbol_data/extend-ref.mscx | 1 - .../tests/chordsymbol_data/no-system-ref.mscx | 28 ++-- .../chordsymbol_data/realize-3note-ref.mscx | 7 +- .../chordsymbol_data/realize-4note-ref.mscx | 7 +- .../chordsymbol_data/realize-6note-ref.mscx | 7 +- .../chordsymbol_data/realize-close-ref.mscx | 7 +- .../realize-concert-pitch-ref.mscx | 7 +- .../chordsymbol_data/realize-drop2-ref.mscx | 7 +- .../realize-duration-ref.mscx | 7 +- .../chordsymbol_data/realize-jazz-ref.mscx | 7 +- .../realize-override-ref.mscx | 7 +- .../realize-transpose-ref.mscx | 7 +- .../chordsymbol_data/realize-triplet-ref.mscx | 7 +- .../chordsymbol_data/transpose-part-ref.mscx | 14 +- .../tests/chordsymbol_data/transpose-ref.mscx | 7 +- .../clef_courtesy01-ref.mscx | 1 - .../clef_courtesy02-ref.mscx | 1 - .../clef_courtesy03-ref.mscx | 1 - .../clef_courtesy04-ref.mscx | 2 - src/engraving/tests/clef_data/clef-1-ref.mscx | 1 - src/engraving/tests/clef_data/clef-2-ref.mscx | 7 +- src/engraving/tests/clef_data/clef-3-ref.mscx | 7 +- .../tests/compat114_data/accidentals-ref.mscx | 1 - .../compat114_data/articulations-ref.mscx | 1 - .../clef_missing_first-ref.mscx | 7 +- .../tests/compat114_data/clefs-ref.mscx | 1 - .../tests/compat114_data/drumset-ref.mscx | 7 +- .../tests/compat114_data/fingering-ref.mscx | 7 +- .../tests/compat114_data/hairpin-ref.mscx | 7 +- .../hor_frame_and_mmrest-ref.mscx | 1 - .../tests/compat114_data/keysig-ref.mscx | 7 +- .../tests/compat114_data/markers-ref.mscx | 1 - .../tests/compat114_data/noteheads-ref.mscx | 1 - .../tests/compat114_data/notes-ref.mscx | 7 +- .../compat114_data/notes_useroffset-ref.mscx | 1 - .../tests/compat114_data/ottava-ref.mscx | 7 +- .../tests/compat114_data/pedal-ref.mscx | 7 +- .../tests/compat114_data/slurs-ref.mscx | 1 - .../tests/compat114_data/style-ref.mscx | 7 +- .../tests/compat114_data/tamtam-ref.mscx | 7 +- .../tests/compat114_data/textline-ref.mscx | 7 +- .../tests/compat114_data/textstyles-ref.mscx | 1 - .../tests/compat114_data/title-ref.mscx | 7 +- .../compat114_data/tremolo2notes-ref.mscx | 1 - .../tests/compat114_data/tuplets-ref.mscx | 1 - .../tests/compat114_data/tuplets_1-ref.mscx | 1 - .../tests/compat114_data/tuplets_2-ref.mscx | 1 - .../tests/compat206_data/accidentals-ref.mscx | 7 +- .../tests/compat206_data/ambitus-ref.mscx | 7 +- .../articulations-double-ref.mscx | 14 +- .../compat206_data/articulations-ref.mscx | 7 +- .../tests/compat206_data/barlines-ref.mscx | 56 ++++--- .../tests/compat206_data/breath-ref.mscx | 7 +- .../tests/compat206_data/clefs-ref.mscx | 7 +- .../tests/compat206_data/drumset-ref.mscx | 28 ++-- .../tests/compat206_data/fermata-ref.mscx | 7 +- .../tests/compat206_data/frame_text2-ref.mscx | 5 +- .../tests/compat206_data/hairpin-ref.mscx | 14 +- .../instrumentNameAlign-ref.mscx | 28 ++-- .../compat206_data/lidemptytext-ref.mscx | 4 +- .../tests/compat206_data/markers-ref.mscx | 7 +- .../tests/compat206_data/noteheads-ref.mscx | 7 +- .../tests/compat206_data/textstyles-ref.mscx | 13 +- .../tests/compat206_data/tuplets-ref.mscx | 7 +- .../compat206_data/userstylesparts-ref.mscx | 42 +++--- .../tests/copypaste_data/copypaste01-ref.mscx | 1 - .../tests/copypaste_data/copypaste02-ref.mscx | 1 - .../tests/copypaste_data/copypaste03-ref.mscx | 1 - .../tests/copypaste_data/copypaste04-ref.mscx | 1 - .../tests/copypaste_data/copypaste05-ref.mscx | 1 - .../tests/copypaste_data/copypaste06-ref.mscx | 1 - .../tests/copypaste_data/copypaste07-ref.mscx | 1 - .../tests/copypaste_data/copypaste08-ref.mscx | 1 - .../tests/copypaste_data/copypaste09-ref.mscx | 1 - .../tests/copypaste_data/copypaste10-ref.mscx | 1 - .../tests/copypaste_data/copypaste11-ref.mscx | 1 - .../tests/copypaste_data/copypaste12-ref.mscx | 1 - .../tests/copypaste_data/copypaste13-ref.mscx | 7 +- .../tests/copypaste_data/copypaste17-ref.mscx | 7 +- .../tests/copypaste_data/copypaste18-ref.mscx | 7 +- .../tests/copypaste_data/copypaste19-ref.mscx | 1 - .../tests/copypaste_data/copypaste20-ref.mscx | 7 +- .../tests/copypaste_data/copypaste22-ref.mscx | 1 - .../tests/copypaste_data/copypaste23-ref.mscx | 7 +- .../tests/copypaste_data/copypaste24-ref.mscx | 7 +- .../tests/copypaste_data/copypaste25-ref.mscx | 7 +- .../tests/copypaste_data/copypaste26-ref.mscx | 7 +- .../tests/copypaste_data/copypaste27-ref.mscx | 7 +- .../tests/copypaste_data/copypaste50-ref.mscx | 2 - .../copypaste_data/copypasteNote01-ref.mscx | 3 +- .../copypaste_data/copypasteNote02-ref.mscx | 3 +- .../copypaste_data/copypasteNote03-ref.mscx | 3 +- .../copypaste_data/copypasteNote04-ref.mscx | 3 +- .../copypaste_data/copypasteNote05-ref.mscx | 3 +- .../copypaste_data/copypasteNote06-ref.mscx | 3 +- .../copypaste_data/copypasteNote07-ref.mscx | 3 +- .../copypaste_data/copypasteNote08-ref.mscx | 3 +- .../copypaste_data/copypasteNote09-ref.mscx | 3 +- .../copypaste_data/copypasteNote10-ref.mscx | 3 +- .../copypaste_data/copypasteNote11-ref.mscx | 3 +- .../copypaste_data/copypasteNote12-ref.mscx | 7 +- .../copypaste_data/copypasteSplit01-ref.mscx | 7 +- .../copypaste_data/copypasteSplit02-ref.mscx | 7 +- .../copypaste_data/copypasteSplit03-ref.mscx | 7 +- .../copypaste_data/copypasteSplit04-ref.mscx | 7 +- .../copypaste_partial_01-ref.mscx | 1 - .../copypaste_data/copypaste_parts-ref.mscx | 14 +- .../copypaste_repeatListSelection-ref.mscx | 7 +- .../copypaste_tuplet_01-ref.mscx | 7 +- .../copypaste_tuplet_02-ref.mscx | 7 +- .../copypastesymbollist-articulation-ref.mscx | 1 - ...pastesymbollist-articulation-rest-ref.mscx | 7 +- ...copypastesymbollist-chordnames-01-ref.mscx | 1 - .../copypastesymbollist-chordnames-ref.mscx | 1 - .../copypastesymbollist-lyrics-ref.mscx | 1 - .../copypastesymbollist-ornament-ref.mscx | 1 - .../copypastesymbollist-range-01-ref.mscx | 14 +- .../copypastesymbollist-range-ref.mscx | 14 +- .../copypastesymbollist-stafftext-ref.mscx | 1 - .../copypastesymbollist-sticking-ref.mscx | 1 - ...tesymbollist-tremolo-single-chord-ref.mscx | 7 +- .../earlymusic_data/mensurstrich01-ref.mscx | 16 +- .../tests/earlymusic_data/mensurstrich01.mscx | 16 +- .../exchangevoices-gliss-ref.mscx | 7 +- .../exchangevoices-range-ref.mscx | 9 +- .../exchangevoices-range.mscx | 9 +- .../exchangevoices-slurs-ref.mscx | 7 +- .../undoChangeVoice01-ref.mscx | 14 +- .../undoChangeVoice02-ref.mscx | 14 +- .../expression_data/expression-1-ref.mscx | 7 +- .../expression_data/expression-2-ref.mscx | 7 +- .../harpdiagrams_data/textdiagram01-ref.mscx | 9 +- .../harpdiagrams_data/textdiagram02.mscx | 9 +- .../explodeDynamics01-ref.mscx | 28 ++-- .../explodeDynamics02-ref.mscx | 28 ++-- .../implodeDynamics01-ref.mscx | 21 +-- .../implodeDynamics02-ref.mscx | 21 +-- .../implodeScore01-ref.mscx | 30 ++-- .../implodeScore02-ref.mscx | 30 ++-- .../undoExplode01-ref.mscx | 28 ++-- .../undoExplode02-ref.mscx | 28 ++-- .../undoImplode01-ref.mscx | 21 +-- .../undoImplode02-ref.mscx | 21 +-- .../undoImplodeVoice01-ref.mscx | 7 +- .../undoImplodeVoice02-ref.mscx | 7 +- .../tests/instrumentchange_data/add-ref.mscx | 20 ++- .../instrumentchange_data/change-ref.mscx | 20 ++- .../tests/instrumentchange_data/copy-ref.mscx | 26 ++-- .../instrumentchange_data/delete-ref.mscx | 14 +- .../instrumentchange_data/mixer-ref.mscx | 20 ++- src/engraving/tests/join_data/join01-ref.mscx | 1 - src/engraving/tests/join_data/join02-ref.mscx | 1 - src/engraving/tests/join_data/join03-ref.mscx | 1 - src/engraving/tests/join_data/join04-ref.mscx | 1 - src/engraving/tests/join_data/join05-ref.mscx | 1 - src/engraving/tests/join_data/join06-ref.mscx | 1 - src/engraving/tests/join_data/join07-ref.mscx | 1 - src/engraving/tests/join_data/join09-ref.mscx | 7 +- src/engraving/tests/join_data/join10-ref.mscx | 7 +- .../keysig_data/concert-pitch-01-ref.mscx | 14 +- .../keysig_data/concert-pitch-02-ref.mscx | 14 +- src/engraving/tests/keysig_data/keysig.mscx | 3 +- .../tests/keysig_data/keysig01-ref.mscx | 3 +- .../tests/keysig_data/keysig02-ref.mscx | 3 +- .../tests/keysig_data/keysig03-ref.mscx | 9 +- .../tests/keysig_data/keysig03bis-ref.mscx | 3 +- .../keysig_data/preferSharpFlat-1-ref.mscx | 7 +- .../keysig_data/preferSharpFlat-2-ref.mscx | 7 +- .../links_data/testPickupLinkedStaff-ref.mscx | 7 +- .../measure_data/changeMeasureLen-ref.mscx | 7 +- .../tests/measure_data/measure-1-ref.mscx | 28 ++-- .../tests/measure_data/measure-10-ref.mscx | 5 +- .../tests/measure_data/measure-2-ref.mscx | 28 ++-- .../tests/measure_data/measure-3-ref.mscx | 28 ++-- .../tests/measure_data/measure-4-ref.mscx | 5 +- .../tests/measure_data/measure-5-ref.mscx | 5 +- .../tests/measure_data/measure-6-ref.mscx | 5 +- .../tests/measure_data/measure-7-ref.mscx | 5 +- .../tests/measure_data/measure-8-ref.mscx | 5 +- .../tests/measure_data/measure-9-ref.mscx | 5 +- .../measure-insert_beginning-ref.mscx | 9 +- .../measure-insert_bf_clef-2-ref.mscx | 3 +- .../measure-insert_bf_clef-ref.mscx | 3 +- .../measure_data/measure-insert_bf_clef.mscx | 3 +- .../measure-insert_bf_key-2-ref.mscx | 3 +- .../measure-insert_bf_key-ref.mscx | 3 +- .../measure-insert_bf_key_undo-ref.mscx | 3 +- .../tests/measure_data/measureSplit-ref.mscx | 28 ++-- .../measure_data/measurenumber-1-ref.mscx | 7 +- .../measure_data/measurenumber-2-ref.mscx | 7 +- .../measure_data/measurenumber-3-ref.mscx | 7 +- .../measure_data/measurenumber-4-ref.mscx | 7 +- .../measure_data/measurenumber-5-ref.mscx | 7 +- .../measure_data/measurenumber-6-ref.mscx | 7 +- .../measure_data/measurenumber-7-ref.mscx | 7 +- .../tests/measure_data/mmrest-ref.mscx | 9 +- .../undoDelInitialVBox_269919-ref.mscx | 9 +- src/engraving/tests/note_data/grace-ref.mscx | 7 +- .../note_data/graceAfterSlashSave-ref.mscx | 7 +- .../tests/note_data/notelimits-ref.mscx | 7 +- src/engraving/tests/note_data/tpc-ref.mscx | 7 +- .../tests/note_data/tpc-transpose-ref.mscx | 7 +- .../tests/note_data/tpc-transpose2-ref.mscx | 7 +- .../tests/partialtie_data/coda-ref.mscx | 7 +- .../copyPastePartials01-ref.mscx | 10 +- .../copyPastePartials02-ref.mscx | 10 +- .../copyPastePartials03-ref.mscx | 10 +- .../copyPastePartials04-ref.mscx | 10 +- .../partialtie_data/partialTieList-ref.mscx | 7 +- .../partialtie_data/repeat_barlines-ref.mscx | 7 +- .../tests/partialtie_data/volta_coda-ref.mscx | 7 +- .../tests/parts_data/linked-ties-1.mscx | 7 +- .../tests/parts_data/linked-ties-parts.mscx | 14 +- .../tests/parts_data/part-54346-parts.mscx | 30 ++-- .../tests/parts_data/part-54346.mscx | 16 +- .../parts_data/part-all-appendmeasures.mscx | 30 ++-- .../parts_data/part-all-insertmeasures.mscx | 30 ++-- .../tests/parts_data/part-all-parts.mscx | 30 ++-- .../parts_data/part-all-uappendmeasures.mscx | 30 ++-- .../parts_data/part-all-uinsertmeasures.mscx | 30 ++-- src/engraving/tests/parts_data/part-all.mscx | 16 +- .../tests/parts_data/part-breath-add.mscx | 30 ++-- .../tests/parts_data/part-breath-del.mscx | 30 ++-- .../tests/parts_data/part-breath-parts.mscx | 30 ++-- .../tests/parts_data/part-breath-uadd.mscx | 30 ++-- .../tests/parts_data/part-breath-udel.mscx | 30 ++-- .../tests/parts_data/part-breath-uradd.mscx | 30 ++-- .../tests/parts_data/part-breath-urdel.mscx | 30 ++-- .../tests/parts_data/part-breath.mscx | 16 +- .../tests/parts_data/part-chordline-add.mscx | 30 ++-- .../tests/parts_data/part-chordline-del.mscx | 30 ++-- .../parts_data/part-chordline-parts.mscx | 30 ++-- .../tests/parts_data/part-chordline-uadd.mscx | 30 ++-- .../tests/parts_data/part-chordline-udel.mscx | 30 ++-- .../parts_data/part-chordline-uradd.mscx | 30 ++-- .../parts_data/part-chordline-urdel.mscx | 30 ++-- .../tests/parts_data/part-chordline.mscx | 16 +- .../tests/parts_data/part-empty-parts.mscx | 30 ++-- .../tests/parts_data/part-empty.mscx | 16 +- .../tests/parts_data/part-fingering-add.mscx | 30 ++-- .../tests/parts_data/part-fingering-del.mscx | 30 ++-- .../parts_data/part-fingering-parts.mscx | 30 ++-- .../tests/parts_data/part-fingering-uadd.mscx | 30 ++-- .../tests/parts_data/part-fingering-udel.mscx | 30 ++-- .../parts_data/part-fingering-uradd.mscx | 30 ++-- .../parts_data/part-fingering-urdel.mscx | 30 ++-- .../tests/parts_data/part-fingering.mscx | 16 +- .../tests/parts_data/part-image-add.mscx | 30 ++-- .../tests/parts_data/part-image-del.mscx | 34 +++-- .../parts_data/part-image-parts-ref.mscx | 30 ++-- .../tests/parts_data/part-image-ref.mscx | 16 +- .../tests/parts_data/part-image-uadd.mscx | 30 ++-- .../tests/parts_data/part-image-udel.mscx | 34 +++-- .../tests/parts_data/part-image-uradd.mscx | 30 ++-- .../tests/parts_data/part-image-urdel.mscx | 34 +++-- .../parts_data/part-measure-repeat-add.mscx | 30 ++-- .../parts_data/part-measure-repeat-del.mscx | 30 ++-- .../parts_data/part-measure-repeat-parts.mscx | 30 ++-- .../parts_data/part-measure-repeat-uadd.mscx | 30 ++-- .../parts_data/part-measure-repeat-udel.mscx | 30 ++-- .../parts_data/part-measure-repeat-uradd.mscx | 30 ++-- .../parts_data/part-measure-repeat-urdel.mscx | 30 ++-- .../tests/parts_data/part-measure-repeat.mscx | 16 +- .../tests/parts_data/part-spanners-parts.mscx | 30 ++-- .../tests/parts_data/part-spanners.mscx | 16 +- .../tests/parts_data/part-stemless-parts.mscx | 30 ++-- .../tests/parts_data/part-stemless.mscx | 16 +- .../tests/parts_data/part-symbol-add.mscx | 30 ++-- .../tests/parts_data/part-symbol-del.mscx | 30 ++-- .../tests/parts_data/part-symbol-parts.mscx | 30 ++-- .../tests/parts_data/part-symbol-uadd.mscx | 30 ++-- .../tests/parts_data/part-symbol-udel.mscx | 30 ++-- .../tests/parts_data/part-symbol-uradd.mscx | 30 ++-- .../tests/parts_data/part-symbol-urdel.mscx | 30 ++-- .../tests/parts_data/part-symbol.mscx | 16 +- .../part-visible-tracks-part-ref.mscx | 9 +- .../part-visible-tracks-score-ref.mscx | 16 +- .../parts_data/partExclusion-part-0.mscx | 7 +- .../parts_data/partExclusion-part-1.mscx | 7 +- .../partPropertyLinking-part-0.mscx | 7 +- .../partPropertyLinking-part-1.mscx | 7 +- .../tests/parts_data/partStyle-score-ref.mscx | 122 +++++++-------- .../partStyle-score-reload-ref.mscx | 12 +- .../tests/parts_data/voices-ref.mscx | 35 +++-- .../readwriteundoreset_data/barlines.mscx | 9 +- ...stBarlineTextLinks-disable-mmrest-ref.mscx | 9 +- ...tBarlineTextLinks-recreate-mmrest-ref.mscx | 9 +- .../mmrestBarlineTextLinks.mscx | 9 +- .../tests/readwriteundoreset_data/slurs.mscx | 9 +- .../group8ths4-4-ref.mscx | 2 - .../group8thsCompound-ref.mscx | 2 - .../group8thsSimple-ref.mscx | 2 - .../groupArticulationsTies-ref.mscx | 7 +- .../groupConflicts-ref.mscx | 14 +- .../groupShortenNotes-ref.mscx | 7 +- .../groupSubbeats-ref.mscx | 7 +- .../groupVoices-ref.mscx | 7 +- .../selectionfilter_gracesandslurs-ref.mscx | 9 +- ...ionfilter_notesinchords_copypaste-ref.mscx | 7 +- ...nfilter_notesinchords_deleterange-ref.mscx | 7 +- .../selectionrangedelete03-ref.mscx | 7 +- .../selectionrangedelete04-ref.mscx | 7 +- .../selectionrangedelete05-ref.mscx | 7 +- ...angedelete06_partialnestedtuplets-ref.mscx | 9 +- .../glissando-cloning01-ref.mscx | 7 +- .../glissando-cloning03-ref.mscx | 7 +- .../glissando-cloning04-ref.mscx | 14 +- .../glissando-crossstaff01-ref.mscx | 7 +- .../spanners_data/glissando-graces01-ref.mscx | 7 +- .../tests/spanners_data/glissando01-ref.mscx | 7 +- .../tests/spanners_data/linecolor01-ref.mscx | 7 +- .../tests/spanners_data/lyricsline02-ref.mscx | 9 +- .../tests/spanners_data/lyricsline02.mscx | 9 +- .../tests/spanners_data/lyricsline03-ref.mscx | 9 +- .../tests/spanners_data/lyricsline03.mscx | 9 +- .../tests/spanners_data/lyricsline04-ref.mscx | 9 +- .../tests/spanners_data/lyricsline04.mscx | 9 +- .../tests/spanners_data/lyricsline05-ref.mscx | 9 +- .../tests/spanners_data/lyricsline05.mscx | 9 +- .../tests/spanners_data/smallstaff01-ref.mscx | 7 +- .../tests/split_data/split01-ref.mscx | 1 - .../tests/split_data/split02-ref.mscx | 1 - .../tests/split_data/split03-ref.mscx | 1 - .../tests/split_data/split04-ref.mscx | 1 - .../tests/split_data/split05-ref.mscx | 1 - .../tests/split_data/split06-ref.mscx | 1 - .../tests/split_data/split07-ref.mscx | 1 - .../tests/split_data/split08-ref.mscx | 1 - ...83846-irregular-hn-hn-qn-qn-hn-hn-ref.mscx | 7 +- .../split183846-irregular-qn-qn-wn-ref.mscx | 7 +- .../split183846-irregular-verylong-ref.mscx | 7 +- .../split183846-irregular-wn-wn-ref.mscx | 7 +- ...it183846-irregular-wn-wr-wn-hr-qr-ref.mscx | 7 +- ...it183846-irregular-wr-wn-wr-hn-qn-ref.mscx | 7 +- ...061-keep-tie-before-break-voice-4-ref.mscx | 7 +- .../split_data/split184061-keep-tie-ref.mscx | 7 +- .../split_data/split184061-no-tie-ref.mscx | 7 +- ...lit184061-other-inst-only-one-tie-ref.mscx | 14 +- .../tests/split_data/split295207-ref.mscx | 1 - .../splitstaff_data/splitstaff01-ref.mscx | 1 - .../splitstaff_data/splitstaff02-ref.mscx | 1 - .../splitstaff_data/splitstaff03-ref.mscx | 21 +-- .../splitstaff_data/splitstaff04-ref.mscx | 7 +- .../splitstaff_data/splitstaff05-ref.mscx | 7 +- .../splitstaff_data/splitstaff06-ref.mscx | 1 - .../tests/staffmove_data/hiddenStaff-ref.mscx | 9 +- .../tests/staffmove_data/hiddenStaff.mscx | 9 +- .../tests/staffmove_data/linkedStaff-ref.mscx | 9 +- .../tests/staffmove_data/linkedStaff.mscx | 9 +- .../textbase_data/createDynamic-ref.mscx | 8 +- .../dynamicAddTextAfter-ref.mscx | 8 +- .../dynamicAddTextBefore-ref.mscx | 8 +- .../dynamicAddTextNoItalic-ref.mscx | 8 +- .../tests/textbase_data/lineBreak-ref.mscx | 7 +- .../tests/timesig_data/timesig-02-ref.mscx | 1 - .../tests/timesig_data/timesig-03-ref.mscx | 1 - .../tests/timesig_data/timesig-04-ref.mscx | 7 +- .../tests/timesig_data/timesig-05-ref.mscx | 1 - .../tests/timesig_data/timesig-06-ref.mscx | 5 +- .../tests/timesig_data/timesig-07-ref.mscx | 5 +- .../tests/timesig_data/timesig-10-ref.mscx | 7 +- .../tests/timesig_data/timesig01-ref.mscx | 5 +- .../change-enharmonic-both-01-ref.mscx | 7 +- .../change-enharmonic-both-02-ref.mscx | 7 +- .../change-enharmonic-both-03-ref.mscx | 7 +- .../change-enharmonic-both-04-ref.mscx | 7 +- .../change-enharmonic-both-05-ref.mscx | 7 +- .../change-enharmonic-current-01-ref.mscx | 7 +- .../change-enharmonic-current-02-ref.mscx | 7 +- .../change-enharmonic-current-03-ref.mscx | 7 +- .../change-enharmonic-current-04-ref.mscx | 7 +- .../change-enharmonic-current-05-ref.mscx | 7 +- .../tools_data/undoResequenceAlpha01-ref.mscx | 7 +- .../tools_data/undoResequenceAlpha02-ref.mscx | 7 +- .../undoResequenceMeasure01-ref.mscx | 7 +- .../undoResequenceMeasure02-ref.mscx | 7 +- .../undoResequenceNumeric01-ref.mscx | 7 +- .../undoResequenceNumeric02-ref.mscx | 7 +- .../tools_data/undoResequencePart01-ref.mscx | 14 +- .../tools_data/undoResequencePart02-ref.mscx | 14 +- .../tests/tools_data/undoSlashFill01-ref.mscx | 14 +- .../tests/tools_data/undoSlashFill02-ref.mscx | 14 +- .../tools_data/undoSlashRhythm01-ref.mscx | 14 +- .../tools_data/undoSlashRhythm02-ref.mscx | 14 +- .../undoDiatonicTranspose01-ref.mscx | 1 - .../undoDiatonicTranspose02-ref.mscx | 1 - ...doDiatonicTransposeChordSymbols01-ref.mscx | 7 +- ...doDiatonicTransposeChordSymbols02-ref.mscx | 7 +- ...doDiatonicTransposeFretDiagrams01-ref.mscx | 7 +- ...doDiatonicTransposeFretDiagrams02-ref.mscx | 7 +- ...ansposeFretDiagramsChordSymbols01-ref.mscx | 7 +- ...ansposeFretDiagramsChordSymbols02-ref.mscx | 7 +- .../transpose_data/undoTranspose01-ref.mscx | 7 +- .../transpose_data/undoTranspose02-ref.mscx | 7 +- .../undoTransposeChordSymbols01-ref.mscx | 7 +- .../undoTransposeChordSymbols02-ref.mscx | 7 +- .../undoTransposeFretDiagrams01-ref.mscx | 7 +- .../undoTransposeFretDiagrams02-ref.mscx | 7 +- ...ansposeFretDiagramsChordSymbols01-ref.mscx | 7 +- ...ansposeFretDiagramsChordSymbols02-ref.mscx | 7 +- .../nestedTuplets_addStaff-ref.mscx | 7 +- .../tests/tuplet_data/save-load.mscx | 9 +- .../tests/tuplet_data/split1-ref.mscx | 7 +- .../tests/tuplet_data/split2-ref.mscx | 7 +- .../tests/tuplet_data/split3-ref.mscx | 7 +- .../tests/tuplet_data/split4-ref.mscx | 7 +- .../tests/tuplet_data/tuplet1-ref.mscx | 1 - .../capella/tests/data/test1.cap-ref.mscx | 1 - .../capella/tests/data/test1.capx-ref.mscx | 1 - .../capella/tests/data/test2.cap-ref.mscx | 1 - .../capella/tests/data/test2.capx-ref.mscx | 1 - .../capella/tests/data/test3.cap-ref.mscx | 1 - .../capella/tests/data/test3.capx-ref.mscx | 1 - .../capella/tests/data/test4.cap-ref.mscx | 1 - .../capella/tests/data/test4.capx-ref.mscx | 1 - .../capella/tests/data/test5.cap-ref.mscx | 1 - .../capella/tests/data/test5.capx-ref.mscx | 1 - .../capella/tests/data/test6.cap-ref.mscx | 1 - .../capella/tests/data/test6.capx-ref.mscx | 1 - .../capella/tests/data/test7.cap-ref.mscx | 1 - .../capella/tests/data/test7.capx-ref.mscx | 1 - .../capella/tests/data/test8.cap-ref.mscx | 1 - .../tests/data/testBarline.capx-ref.mscx | 1 - .../tests/data/testEmptyStaff1.capx-ref.mscx | 2 - .../tests/data/testEmptyStaff2.capx-ref.mscx | 2 - .../tests/data/testPianoG4G5.capx-ref.mscx | 2 - .../tests/data/testScaleC4C5.capx-ref.mscx | 1 - .../tests/data/testSlurTie.capx-ref.mscx | 1 - .../tests/data/testText1.capx-ref.mscx | 1 - .../tests/data/testTuplet1.capx-ref.mscx | 1 - .../tests/data/testTuplet2.cap-ref.mscx | 1 - .../tests/data/testTuplet2.capx-ref.mscx | 1 - .../tests/data/testTuplet3.capx-ref.mscx | 1 - .../tests/data/testVolta1.capx-ref.mscx | 7 +- .../data/UncompletedMeasure.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/accent.gp-ref.mscx | 7 +- .../guitarpro/tests/data/accent.gpx-ref.mscx | 7 +- .../tests/data/all-percussion.gp-ref.mscx | 7 +- .../tests/data/all-percussion.gp5-ref.mscx | 5 +- .../guitarpro/tests/data/arpeggio.gp-ref.mscx | 7 +- .../tests/data/arpeggio.gpx-ref.mscx | 7 +- .../data/artificial-harmonic.gp-ref.mscx | 7 +- .../data/artificial-harmonic.gpx-ref.mscx | 7 +- .../data/barline-last-measure.gp-ref.mscx | 14 +- .../guitarpro/tests/data/barre.gp-ref.mscx | 7 +- .../guitarpro/tests/data/barre.gpx-ref.mscx | 7 +- .../tests/data/basic-bend.gp-ref.mscx | 7 +- .../tests/data/basic-bend.gp5-ref.mscx | 5 +- .../tests/data/basic-bend.gpx-ref.mscx | 7 +- .../tests/data/beam-modes.gp-ref.mscx | 7 +- .../data/beams-stems-ledger-lines.gp-ref.mscx | 7 +- .../beams-stems-ledger-lines.gp5-ref.mscx | 5 +- .../beams-stems-ledger-lines.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/bend.gp-ref.mscx | 7 +- .../guitarpro/tests/data/bend.gp3-ref.mscx | 5 +- .../guitarpro/tests/data/bend.gp4-ref.mscx | 5 +- .../guitarpro/tests/data/bend.gp5-ref.mscx | 5 +- .../guitarpro/tests/data/bend.gpx-ref.mscx | 7 +- .../tests/data/bend_and_glissando.gp-ref.mscx | 7 +- .../data/bend_and_glissando.gp5-ref.mscx | 5 +- .../tests/data/bend_and_harmonic.gp-ref.mscx | 7 +- .../tests/data/bend_and_harmonic.gp5-ref.mscx | 5 +- .../guitarpro/tests/data/brush.gp-ref.mscx | 7 +- .../guitarpro/tests/data/brush.gp4-ref.mscx | 5 +- .../guitarpro/tests/data/brush.gp5-ref.mscx | 5 +- .../guitarpro/tests/data/brush.gpx-ref.mscx | 7 +- .../tests/data/capo-fret.gp3-ref.mscx | 5 +- .../tests/data/capo-fret.gp4-ref.mscx | 5 +- .../tests/data/capo-fret.gp5-ref.mscx | 5 +- .../chord_with_tied_harmonics.gp-ref.mscx | 7 +- .../chord_with_tied_harmonics.gp5-ref.mscx | 5 +- .../data/chordnames_keyboard.gp-ref.mscx | 7 +- .../data/chordnames_keyboard.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/clefs.gp-ref.mscx | 7 +- .../guitarpro/tests/data/clefs.gpx-ref.mscx | 7 +- .../tests/data/copyright.gp-ref.mscx | 7 +- .../tests/data/copyright.gp3-ref.mscx | 5 +- .../tests/data/copyright.gp4-ref.mscx | 5 +- .../tests/data/copyright.gp5-ref.mscx | 5 +- .../tests/data/copyright.gpx-ref.mscx | 7 +- .../data/crescendo-diminuendo.gp-ref.mscx | 7 +- .../data/crescendo-diminuendo.gpx-ref.mscx | 7 +- .../tests/data/dead-note.gp-ref.mscx | 7 +- .../tests/data/dead-note.gpx-ref.mscx | 7 +- .../tests/data/directions.gp-ref.mscx | 7 +- .../tests/data/directions.gpx-ref.mscx | 7 +- .../tests/data/dotted-gliss.gp-ref.mscx | 7 +- .../tests/data/dotted-gliss.gp3-ref.mscx | 5 +- .../tests/data/dotted-gliss.gpx-ref.mscx | 7 +- .../tests/data/dotted-tuplets.gp-ref.mscx | 7 +- .../tests/data/dotted-tuplets.gp5-ref.mscx | 5 +- .../tests/data/dotted-tuplets.gpx-ref.mscx | 7 +- .../tests/data/double-bar.gp-ref.mscx | 7 +- .../tests/data/double-bar.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/dynamic.gp-ref.mscx | 14 +- .../guitarpro/tests/data/dynamic.gp5-ref.mscx | 10 +- .../guitarpro/tests/data/dynamic.gpx-ref.mscx | 14 +- .../guitarpro/tests/data/fade-in.gp-ref.mscx | 7 +- .../guitarpro/tests/data/fade-in.gp4-ref.mscx | 5 +- .../guitarpro/tests/data/fade-in.gp5-ref.mscx | 5 +- .../guitarpro/tests/data/fade-in.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/fermata.gp-ref.mscx | 7 +- .../guitarpro/tests/data/fermata.gpx-ref.mscx | 7 +- .../tests/data/fingering.gp-ref.mscx | 7 +- .../tests/data/fingering.gp4-ref.mscx | 5 +- .../tests/data/fingering.gp5-ref.mscx | 5 +- .../tests/data/fingering.gpx-ref.mscx | 7 +- .../tests/data/free-time.gp-ref.mscx | 7 +- .../tests/data/free-time.gpx-ref.mscx | 7 +- .../tests/data/fret-diagram.gp-ref.mscx | 7 +- .../tests/data/fret-diagram.gp4-ref.mscx | 5 +- .../tests/data/fret-diagram.gp5-ref.mscx | 5 +- .../tests/data/fret-diagram.gpx-ref.mscx | 7 +- .../fret-diagram_2instruments.gp-ref.mscx | 14 +- .../fret-diagram_2instruments.gpx-ref.mscx | 14 +- .../tests/data/ghost-note.gp-ref.mscx | 7 +- .../tests/data/ghost-note.gpx-ref.mscx | 7 +- .../tests/data/ghost_note.gp3-ref.mscx | 5 +- .../tests/data/grace-before-beat.gp-ref.mscx | 7 +- .../tests/data/grace-before-beat.gpx-ref.mscx | 7 +- .../tests/data/grace-durations.gp-ref.mscx | 7 +- .../tests/data/grace-on-beat.gp-ref.mscx | 7 +- .../tests/data/grace-on-beat.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/grace.gp-ref.mscx | 7 +- .../guitarpro/tests/data/grace.gp5-ref.mscx | 5 +- .../guitarpro/tests/data/grace.gpx-ref.mscx | 7 +- .../tests/data/heavy-accent.gp-ref.mscx | 7 +- .../tests/data/heavy-accent.gp5-ref.mscx | 5 +- .../tests/data/heavy-accent.gpx-ref.mscx | 7 +- .../tests/data/hide-rests.gp-ref.mscx | 14 +- .../data/instr-change-1-beat.gp-ref.mscx | 7 +- .../data/instr-change-1-beat.gpx-ref.mscx | 7 +- .../tests/data/instr-change.gp-ref.mscx | 7 +- .../tests/data/instr-change.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/keysig.gp-ref.mscx | 7 +- .../guitarpro/tests/data/keysig.gp4-ref.mscx | 5 +- .../guitarpro/tests/data/keysig.gp5-ref.mscx | 5 +- .../guitarpro/tests/data/keysig.gpx-ref.mscx | 7 +- .../tests/data/legato-slide.gp-ref.mscx | 7 +- .../tests/data/legato-slide.gp4-ref.mscx | 5 +- .../tests/data/legato-slide.gp5-ref.mscx | 5 +- .../tests/data/legato-slide.gpx-ref.mscx | 7 +- .../tests/data/let-ring-tied.gp5-ref.mscx | 5 +- .../guitarpro/tests/data/let-ring.gp-ref.mscx | 7 +- .../tests/data/let-ring.gp4-ref.mscx | 5 +- .../tests/data/let-ring.gp5-ref.mscx | 5 +- .../tests/data/let-ring.gpx-ref.mscx | 7 +- .../tests/data/line_elements.gp-ref.mscx | 28 ++-- .../tests/data/line_elements.gp5-ref.mscx | 25 ++-- .../guitarpro/tests/data/mmrest.gp-ref.mscx | 7 +- .../guitarpro/tests/data/mordents.gp-ref.mscx | 7 +- .../tests/data/mordents.gpx-ref.mscx | 7 +- .../tests/data/multivoices.gp-ref.mscx | 7 +- .../tests/data/multivoices.gpx-ref.mscx | 7 +- .../tests/data/ottava-simile.gp-ref.mscx | 7 +- .../guitarpro/tests/data/ottava1.gp-ref.mscx | 7 +- .../guitarpro/tests/data/ottava1.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/ottava2.gp-ref.mscx | 14 +- .../guitarpro/tests/data/ottava2.gpx-ref.mscx | 14 +- .../guitarpro/tests/data/ottava3.gp-ref.mscx | 14 +- .../guitarpro/tests/data/ottava3.gpx-ref.mscx | 14 +- .../guitarpro/tests/data/ottava4.gp-ref.mscx | 14 +- .../guitarpro/tests/data/ottava4.gpx-ref.mscx | 14 +- .../guitarpro/tests/data/ottava5.gp-ref.mscx | 14 +- .../guitarpro/tests/data/ottava5.gpx-ref.mscx | 14 +- .../tests/data/palm-mute.gp-ref.mscx | 7 +- .../tests/data/palm-mute.gp4-ref.mscx | 5 +- .../tests/data/palm-mute.gp5-ref.mscx | 5 +- .../tests/data/palm-mute.gpx-ref.mscx | 7 +- .../tests/data/percussion-beams.gp-ref.mscx | 7 +- .../tests/data/pick-up-down.gp-ref.mscx | 7 +- .../tests/data/pick-up-down.gp4-ref.mscx | 5 +- .../tests/data/pick-up-down.gp5-ref.mscx | 5 +- .../tests/data/pick-up-down.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/rasg.gp-ref.mscx | 7 +- .../guitarpro/tests/data/rasg.gpx-ref.mscx | 7 +- .../tests/data/repeated-bars.gp-ref.mscx | 7 +- .../tests/data/repeated-bars.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/repeats.gp-ref.mscx | 7 +- .../guitarpro/tests/data/repeats.gpx-ref.mscx | 7 +- .../tests/data/rest-centered.gp-ref.mscx | 7 +- .../tests/data/rest-centered.gp4-ref.mscx | 5 +- .../tests/data/rest-centered.gp5-ref.mscx | 5 +- .../tests/data/rest-centered.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/sforzato.gp-ref.mscx | 7 +- .../tests/data/sforzato.gp4-ref.mscx | 5 +- .../tests/data/sforzato.gpx-ref.mscx | 7 +- .../tests/data/shift-slide.gp-ref.mscx | 7 +- .../tests/data/shift-slide.gp4-ref.mscx | 5 +- .../tests/data/shift-slide.gp5-ref.mscx | 5 +- .../tests/data/shift-slide.gpx-ref.mscx | 7 +- .../data/skipped_tied_notes.gp5-ref.mscx | 5 +- .../tests/data/slide-in-above.gp-ref.mscx | 7 +- .../tests/data/slide-in-above.gp4-ref.mscx | 5 +- .../tests/data/slide-in-above.gp5-ref.mscx | 5 +- .../tests/data/slide-in-above.gpx-ref.mscx | 7 +- .../tests/data/slide-in-below.gp-ref.mscx | 7 +- .../tests/data/slide-in-below.gp4-ref.mscx | 5 +- .../tests/data/slide-in-below.gp5-ref.mscx | 5 +- .../tests/data/slide-in-below.gpx-ref.mscx | 7 +- .../tests/data/slide-out-down.gp-ref.mscx | 7 +- .../tests/data/slide-out-down.gp4-ref.mscx | 5 +- .../tests/data/slide-out-down.gp5-ref.mscx | 5 +- .../tests/data/slide-out-down.gpx-ref.mscx | 7 +- .../tests/data/slide-out-up.gp-ref.mscx | 7 +- .../tests/data/slide-out-up.gp4-ref.mscx | 5 +- .../tests/data/slide-out-up.gp5-ref.mscx | 5 +- .../tests/data/slide-out-up.gpx-ref.mscx | 7 +- .../data/slur-notes-effect-mask.gp-ref.mscx | 7 +- .../data/slur-notes-effect-mask.gp5-ref.mscx | 5 +- .../data/slur-notes-effect-mask.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/slur.gp-ref.mscx | 7 +- .../guitarpro/tests/data/slur.gp4-ref.mscx | 5 +- .../guitarpro/tests/data/slur.gpx-ref.mscx | 7 +- .../tests/data/slur_hammer_slur.gp-ref.mscx | 7 +- .../tests/data/slur_hammer_slur.gpx-ref.mscx | 7 +- .../data/slur_over_3_measures.gp-ref.mscx | 7 +- .../data/slur_over_3_measures.gpx-ref.mscx | 7 +- .../tests/data/slur_slur_hammer.gp-ref.mscx | 7 +- .../tests/data/slur_slur_hammer.gpx-ref.mscx | 7 +- .../tests/data/slur_voices.gp-ref.mscx | 7 +- .../tests/data/slur_voices.gpx-ref.mscx | 7 +- .../spanner-in-uncomplete-measure.gp-ref.mscx | 7 +- ...spanner-in-uncomplete-measure.gp5-ref.mscx | 5 +- .../tests/data/tap-slap-pop.gp-ref.mscx | 7 +- .../tests/data/tap-slap-pop.gp5-ref.mscx | 5 +- .../tests/data/tap-slap-pop.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/tempo.gp-ref.mscx | 7 +- .../guitarpro/tests/data/tempo.gp3-ref.mscx | 5 +- .../guitarpro/tests/data/tempo.gp4-ref.mscx | 5 +- .../guitarpro/tests/data/tempo.gp5-ref.mscx | 5 +- .../guitarpro/tests/data/tempo.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/text.gp-ref.mscx | 7 +- .../guitarpro/tests/data/text.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/timer.gp-ref.mscx | 7 +- .../guitarpro/tests/data/timer.gpx-ref.mscx | 7 +- .../tests/data/tremolo-bar.gp-ref.mscx | 7 +- .../tests/data/tremolo-bar.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/tremolos.gp-ref.mscx | 7 +- .../tests/data/tremolos.gp5-ref.mscx | 5 +- .../tests/data/tremolos.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/trill.gp-ref.mscx | 7 +- .../guitarpro/tests/data/trill.gp4-ref.mscx | 5 +- .../guitarpro/tests/data/trill.gpx-ref.mscx | 7 +- .../data/tuplet-empty-measure.gp-ref.mscx | 7 +- .../tests/data/tuplet-with-slur.gp-ref.mscx | 7 +- .../tests/data/tuplet-with-slur.gp4-ref.mscx | 5 +- .../tests/data/tuplet-with-slur.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/tuplets.gpx-ref.mscx | 7 +- .../tests/data/tuplets2.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/turn.gp-ref.mscx | 7 +- .../guitarpro/tests/data/turn.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/vibrato.gp-ref.mscx | 7 +- .../guitarpro/tests/data/vibrato.gp5-ref.mscx | 5 +- .../guitarpro/tests/data/vibrato.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/volta.gp-ref.mscx | 7 +- .../guitarpro/tests/data/volta.gp3-ref.mscx | 5 +- .../guitarpro/tests/data/volta.gp4-ref.mscx | 5 +- .../guitarpro/tests/data/volta.gp5-ref.mscx | 5 +- .../guitarpro/tests/data/volta.gpx-ref.mscx | 7 +- .../tests/data/volume-swell.gp-ref.mscx | 7 +- .../tests/data/volume-swell.gpx-ref.mscx | 7 +- .../guitarpro/tests/data/wah.gp-ref.mscx | 7 +- .../guitarpro/tests/data/wah.gpx-ref.mscx | 7 +- .../guitarbendimporter_data/bend_hold-gp.mscx | 7 +- .../bend_on_tuplet-gp.mscx | 7 +- .../bend_on_unequal_chords-gp.mscx | 7 +- .../bend_release-gp.mscx | 7 +- .../bends_release_grace_after-gp.mscx | 7 +- .../bends_tied_1-gp.mscx | 7 +- .../bends_tied_2-gp.mscx | 7 +- .../bends_tied_3-gp.mscx | 7 +- .../grace_chord_diff_bends-gp.mscx | 7 +- .../guitarbendimporter_data/prebend-gp.mscx | 7 +- .../guitarbendimporter_data/prebend-gp5.mscx | 5 +- .../prebend_bend-gp.mscx | 7 +- .../prebend_release_bend-gp.mscx | 7 +- .../simple_bend-gp.mscx | 7 +- .../simple_bend_chord-gp.mscx | 7 +- .../slight_bend-gp.mscx | 7 +- .../slight_bend-gp5.mscx | 5 +- .../slight_bend_chord-gp.mscx | 7 +- .../slight_bend_tied-gp.mscx | 7 +- .../tied_bends_release_or_hold-gp.mscx | 7 +- src/importexport/mei/tests/data/accid-01.mscx | 7 +- src/importexport/mei/tests/data/accid-02.mscx | 7 +- src/importexport/mei/tests/data/arpeg-01.mscx | 7 +- src/importexport/mei/tests/data/artic-01.mscx | 7 +- src/importexport/mei/tests/data/artic-02.mscx | 7 +- src/importexport/mei/tests/data/beam-01.mscx | 7 +- src/importexport/mei/tests/data/beam-02.mscx | 7 +- src/importexport/mei/tests/data/beam-03.mscx | 7 +- .../mei/tests/data/breaks-01.mscx | 7 +- .../mei/tests/data/breath-01.mscx | 14 +- src/importexport/mei/tests/data/btrem-01.mscx | 7 +- .../mei/tests/data/chord-label-01.mscx | 7 +- src/importexport/mei/tests/data/clef-01.mscx | 7 +- src/importexport/mei/tests/data/color-01.mscx | 7 +- .../mei/tests/data/cross-staff-01.mscx | 7 +- src/importexport/mei/tests/data/dir-01.mscx | 14 +- .../mei/tests/data/dynamic-01.mscx | 7 +- .../mei/tests/data/ending-01.mscx | 14 +- .../mei/tests/data/fermata-01.mscx | 14 +- .../mei/tests/data/fig-bass-01.mscx | 7 +- .../mei/tests/data/fingering-01.mscx | 7 +- src/importexport/mei/tests/data/gliss-01.mscx | 7 +- .../mei/tests/data/gracenote-01.mscx | 7 +- .../mei/tests/data/gracenote-02.mscx | 7 +- .../mei/tests/data/hairpin-01.mscx | 7 +- src/importexport/mei/tests/data/harp-01.mscx | 7 +- src/importexport/mei/tests/data/jump-01.mscx | 7 +- src/importexport/mei/tests/data/jump-02.mscx | 7 +- .../mei/tests/data/key-signature-01.mscx | 14 +- src/importexport/mei/tests/data/label-01.mscx | 7 +- .../mei/tests/data/laissez-vibrer-01.mscx | 7 +- src/importexport/mei/tests/data/lyric-01.mscx | 7 +- src/importexport/mei/tests/data/lyric-02.mscx | 21 +-- src/importexport/mei/tests/data/lyric-03.mscx | 14 +- src/importexport/mei/tests/data/lyric-04.mscx | 1 - .../mei/tests/data/measure-01.mscx | 7 +- .../mei/tests/data/measure-02.mscx | 28 ++-- .../mei/tests/data/measure-repeat-01.mscx | 7 +- .../mei/tests/data/metadata-01.mscx | 7 +- src/importexport/mei/tests/data/midi-01.mscx | 21 +-- .../mei/tests/data/mordent-01.mscx | 7 +- .../mei/tests/data/octave-01.mscx | 7 +- src/importexport/mei/tests/data/ornam-01.mscx | 7 +- .../mei/tests/data/page-head-01.mscx | 7 +- .../mei/tests/data/page-head-02.mscx | 7 +- src/importexport/mei/tests/data/pedal-01.mscx | 7 +- src/importexport/mei/tests/data/reh-01.mscx | 1 - .../mei/tests/data/roman-numeral-01.mscx | 7 +- src/importexport/mei/tests/data/score-01.mscx | 98 ++++++------ src/importexport/mei/tests/data/score-02.mscx | 49 +++--- src/importexport/mei/tests/data/score-03.mscx | 14 +- src/importexport/mei/tests/data/slur-01.mscx | 7 +- src/importexport/mei/tests/data/slur-02.mscx | 7 +- src/importexport/mei/tests/data/stem-01.mscx | 1 - src/importexport/mei/tests/data/tempo-01.mscx | 14 +- src/importexport/mei/tests/data/tie-01.mscx | 7 +- .../mei/tests/data/time-signature-01.mscx | 5 +- .../mei/tests/data/time-signature-02.mscx | 14 +- .../mei/tests/data/transpose-01.mscx | 35 +++-- src/importexport/mei/tests/data/trill-01.mscx | 7 +- .../mei/tests/data/tuplet-01.mscx | 1 - .../mei/tests/data/tuplet-02.mscx | 1 - .../mei/tests/data/tuplet-03.mscx | 1 - .../chord_1_tick_long-ref.mscx | 7 +- .../midiimport_data/chord_big_error-ref.mscx | 7 +- .../midiimport_data/chord_collect-ref.mscx | 7 +- .../midiimport_data/chord_legato-ref.mscx | 7 +- .../chord_small_error-ref.mscx | 7 +- .../midiimport_data/clef_melody-ref.mscx | 7 +- .../tests/midiimport_data/clef_prev-ref.mscx | 7 +- .../tests/midiimport_data/clef_tied-ref.mscx | 7 +- .../tests/midiimport_data/division-ref.mscx | 7 +- .../tests/midiimport_data/human_4-4-ref.mscx | 7 +- .../midiimport_data/human_tempo-ref.mscx | 7 +- .../instrument_3staff_organ-ref.mscx | 7 +- .../instrument_channels-ref.mscx | 21 +-- .../midiimport_data/instrument_clef-ref.mscx | 7 +- .../midiimport_data/instrument_grand-ref.mscx | 14 +- .../instrument_grand2-ref.mscx | 14 +- .../midiimport_data/lyrics_time_0-ref.mscx | 7 +- .../midiimport_data/lyrics_voice_1-ref.mscx | 7 +- .../midi/tests/midiimport_data/m1-ref.mscx | 7 +- .../midi/tests/midiimport_data/m2-ref.mscx | 7 +- .../midi/tests/midiimport_data/m3-ref.mscx | 7 +- .../midi/tests/midiimport_data/m4-ref.mscx | 7 +- .../midi/tests/midiimport_data/m5-ref.mscx | 7 +- .../tests/midiimport_data/meter_12-8-ref.mscx | 7 +- .../tests/midiimport_data/meter_15-8-ref.mscx | 7 +- .../tests/midiimport_data/meter_4-4-ref.mscx | 7 +- .../tests/midiimport_data/meter_9-8-ref.mscx | 7 +- .../meter_central_long_note-ref.mscx | 7 +- .../meter_central_long_rest-ref.mscx | 7 +- .../meter_chord_example-ref.mscx | 7 +- .../midiimport_data/meter_dot_tie-ref.mscx | 7 +- .../meter_dots_example1-ref.mscx | 7 +- .../meter_dots_example2-ref.mscx | 7 +- .../meter_dots_example3-ref.mscx | 7 +- .../meter_first_2_8th_rests_compound-ref.mscx | 7 +- .../meter_half_rest_3-4-ref.mscx | 7 +- .../meter_last_quarter_rest_compound-ref.mscx | 7 +- .../midiimport_data/meter_rests-ref.mscx | 7 +- .../meter_two_beats_over-ref.mscx | 7 +- .../midiimport_data/min_duration-ref.mscx | 7 +- .../tests/midiimport_data/perc_drums-ref.mscx | 7 +- .../perc_no_grand_staff-ref.mscx | 14 +- .../midiimport_data/perc_remove_ties-ref.mscx | 7 +- .../perc_respect_beat-ref.mscx | 7 +- .../midiimport_data/perc_short_notes-ref.mscx | 7 +- .../midiimport_data/perc_triplet-ref.mscx | 7 +- .../perc_tuplet_simplify-ref.mscx | 7 +- .../perc_tuplet_simplify2-ref.mscx | 7 +- .../perc_tuplet_voice-ref.mscx | 7 +- .../tests/midiimport_data/pickup-ref.mscx | 7 +- .../midiimport_data/pickup_long-ref.mscx | 7 +- .../midiimport_data/pickup_turn_off-ref.mscx | 7 +- .../midiimport_data/quant_dotted_4th-ref.mscx | 7 +- .../simplify_16th_staccato-ref.mscx | 7 +- .../simplify_32nd_staccato-ref.mscx | 7 +- .../simplify_4th_dotted_tied-ref.mscx | 7 +- .../simplify_8th_dont-ref.mscx | 7 +- .../simplify_8th_dotted_no_staccato-ref.mscx | 7 +- .../simplify_dotted_3-4-ref.mscx | 7 +- .../simplify_staccato_9-8-ref.mscx | 7 +- .../simplify_triplet_staccato-ref.mscx | 7 +- .../midiimport_data/split_2_melodies-ref.mscx | 7 +- .../tests/midiimport_data/split_acid-ref.mscx | 7 +- .../midiimport_data/split_nontuplet-ref.mscx | 7 +- .../midiimport_data/split_octave-ref.mscx | 7 +- .../midiimport_data/split_tuplet-ref.mscx | 7 +- .../tests/midiimport_data/swing_clef-ref.mscx | 7 +- .../midiimport_data/swing_shuffle-ref.mscx | 7 +- .../midiimport_data/swing_triplets-ref.mscx | 7 +- .../midiimport_data/timesig_changes-ref.mscx | 7 +- .../midiimport_data/tuplet_16th_8th-ref.mscx | 7 +- .../tuplet_2_voices_3_5_tuplets-ref.mscx | 7 +- .../tuplet_2_voices_tuplet_non-ref.mscx | 7 +- .../tests/midiimport_data/tuplet_3-4-ref.mscx | 7 +- .../tuplet_3_5_7_tuplets-ref.mscx | 7 +- .../tuplet_5_5_tuplets_rests-ref.mscx | 7 +- .../tuplet_7_staccato-ref.mscx | 7 +- .../midiimport_data/tuplet_duplet-ref.mscx | 7 +- .../midiimport_data/tuplet_mars-ref.mscx | 7 +- .../tuplet_nonuplet_3-4-ref.mscx | 7 +- .../tuplet_nonuplet_4-4-ref.mscx | 7 +- .../tuplet_off_time_other_bar-ref.mscx | 7 +- .../tuplet_off_time_other_bar2-ref.mscx | 7 +- .../tuplet_quadruplet-ref.mscx | 7 +- .../midiimport_data/tuplet_septuplet-ref.mscx | 7 +- .../tuplet_tied_3_5_tuplets-ref.mscx | 7 +- .../tuplet_tied_3_5_tuplets2-ref.mscx | 7 +- .../midiimport_data/tuplet_triplet-ref.mscx | 7 +- .../tuplet_triplet_first_tied-ref.mscx | 7 +- .../tuplet_triplet_first_tied2-ref.mscx | 7 +- .../tuplet_triplet_last_tied-ref.mscx | 7 +- .../tuplet_triplets_mixed-ref.mscx | 7 +- .../tests/midiimport_data/voice_acid-ref.mscx | 7 +- .../midiimport_data/voice_central-ref.mscx | 7 +- .../midiimport_data/voice_intersect-ref.mscx | 7 +- .../midiimport_data/voice_tuplet-ref.mscx | 7 +- .../grand-staff_ref.mscx | 4 +- .../multiple-layouts_ref.mscx | 24 ++- .../mscx_reference_examples/parts_ref.mscx | 8 +- .../time-signature-glyphs_ref.mscx | 4 +- .../altoFluteTremMissingKey_ref.mscx | 6 +- .../project_examples/altoFluteTrem_ref.mscx | 6 +- .../tests/data/project_examples/bcl_ref.mscx | 6 +- .../clarinet38MissingTime_ref.mscx | 6 +- .../data/project_examples/clarinet38_ref.mscx | 6 +- .../project_examples/enharmonicPart_ref.mscx | 6 +- .../key56Wrapped56Edited_ref.mscx | 30 ++-- .../key56Wrapped56Unedited_ref.mscx | 30 ++-- .../project_examples/key77Wrapped_ref.mscx | 24 ++- .../data/project_examples/key77_ref.mscx | 24 ++- .../layoutBarlineStylesInstrument_ref.mscx | 20 ++- .../layoutBarlineStylesNested_ref.mscx | 12 +- .../project_examples/layoutBrackets_ref.mscx | 8 +- .../project_examples/percussionKit_ref.mscx | 6 +- .../project_examples/restPosition_ref.mscx | 6 +- .../musicxml/tests/data/importTie1_ref.mscx | 7 +- .../musicxml/tests/data/importTie2_ref.mscx | 5 +- .../musicxml/tests/data/importTie3_ref.mscx | 7 +- .../musicxml/tests/data/importTie4_ref.mscx | 7 +- .../tests/data/testArpCrossVoice_ref.mscx | 7 +- .../tests/data/testArpOnRest_ref.mscx | 7 +- .../data/testBackupRoundingError_ref.mscx | 7 +- .../tests/data/testBarlineLoc_ref.mscx | 7 +- .../tests/data/testBeamModes_ref.mscx | 7 +- .../tests/data/testBracketTypes_ref.mscx | 7 +- .../musicxml/tests/data/testBuzzRoll_ref.mscx | 5 +- .../tests/data/testChordSymbols2_ref.mscx | 5 +- .../musicxml/tests/data/testCodaHBox_ref.mscx | 7 +- .../tests/data/testCopyrightScale_ref.mscx | 7 +- .../tests/data/testCueGraceNotes_ref.mscx | 7 +- .../tests/data/testCueNotes3_ref.mscx | 7 +- .../tests/data/testDSalCodaMisplaced_ref.mscx | 7 +- .../musicxml/tests/data/testDSalCoda_ref.mscx | 7 +- .../tests/data/testDoletOttavas_ref.mscx | 5 +- ...cateFermataOnGraceNoteAndMainNote_ref.mscx | 5 +- .../testDuplicateFermataOnGraceNote_ref.mscx | 5 +- .../data/testDuplicateInstrChange_ref.mscx | 7 +- .../data/testDurationLargeError_ref.mscx | 7 +- .../data/testDurationRoundingError_ref.mscx | 7 +- .../musicxml/tests/data/testElision_ref.mscx | 7 +- .../data/testExcessHiddenStaves_ref.mscx | 7 +- .../tests/data/testFinaleDynamics_ref.mscx | 7 +- .../tests/data/testFinaleInstr2_ref.mscx | 70 +++++---- .../tests/data/testFinaleInstr_ref.mscx | 141 ++++++++++-------- .../data/testFinaleSystemObjects_ref.mscx | 49 +++--- .../tests/data/testGlissFall_ref.mscx | 7 +- .../tests/data/testImportDrums2_ref.mscx | 7 +- .../tests/data/testImportDrums_ref.mscx | 7 +- .../tests/data/testInferCodaII_ref.mscx | 5 +- .../tests/data/testInferFraction_ref.mscx | 7 +- .../tests/data/testInferSegnoII_ref.mscx | 5 +- .../tests/data/testInferredCredits1_ref.mscx | 7 +- .../tests/data/testInferredCredits2_ref.mscx | 7 +- .../data/testInferredCrescLines2_ref.mscx | 7 +- .../data/testInferredCrescLines_ref.mscx | 7 +- .../data/testInferredDynamicRange_ref.mscx | 7 +- .../testInferredDynamicsExpression_ref.mscx | 7 +- .../data/testInferredFingerings_ref.mscx | 7 +- .../tests/data/testInferredRights_ref.mscx | 7 +- .../tests/data/testInferredTechnique_ref.mscx | 7 +- .../data/testInferredTempoText2_ref.mscx | 14 +- .../tests/data/testInferredTempoText_ref.mscx | 7 +- .../tests/data/testInstrImport_ref.mscx | 126 +++++++++------- .../tests/data/testLyricBracket_ref.mscx | 7 +- .../tests/data/testLyricExtension2_ref.mscx | 7 +- .../tests/data/testLyricExtensions_ref.mscx | 5 +- .../musicxml/tests/data/testLyricPos_ref.mscx | 7 +- .../tests/data/testLyricVisibility_ref.mscx | 7 +- .../tests/data/testMS3KitAndPerc_ref.mscx | 14 +- .../tests/data/testMeasureStyleSlash_ref.mscx | 7 +- .../tests/data/testNamedNoteheads_ref.mscx | 7 +- .../tests/data/testNegativeOffset_ref.mscx | 7 +- .../tests/data/testNoteAttributes2_ref.mscx | 5 +- .../tests/data/testPartNames_ref.mscx | 11 +- .../data/testPedalChangesBroken_ref.mscx | 7 +- .../tests/data/testPlacementDefaults_ref.mscx | 14 +- .../data/testPlacementOffsetDefaults_ref.mscx | 7 +- .../data/testSecondVoiceMelismata_ref.mscx | 7 +- .../tests/data/testSibMetronomeMarks_ref.mscx | 5 +- .../tests/data/testSibOttavas_ref.mscx | 1 - .../tests/data/testSibRitLine_ref.mscx | 5 +- .../tests/data/testStaffEmptiness_ref.mscx | 7 +- .../tests/data/testStickingLyrics_ref.mscx | 7 +- .../musicxml/tests/data/testSticking_ref.mscx | 7 +- .../tests/data/testStringmute_ref.mscx | 7 +- .../tests/data/testSystemBrackets3_ref.mscx | 39 ++--- .../data/testSystemObjectStaves_ref.mscx | 28 ++-- .../tests/data/testTboxAboveBelow2_ref.xml | 4 +- .../tests/data/testTempoLineFermata_ref.mscx | 7 +- .../tests/data/testTempoTextSpace1_ref.mscx | 7 +- .../tests/data/testTempoTextSpace2_ref.mscx | 7 +- .../tests/data/testTextOrder_ref.mscx | 7 +- .../data/testTextQuirkInference_ref.mscx | 7 +- .../musicxml/tests/data/testTimeTick_ref.mscx | 5 +- .../tests/data/testTitleSwapMu_ref.mscx | 28 ++-- .../tests/data/testTitleSwapSib_ref.mscx | 28 ++-- .../tests/data/testTupletTie_ref.mscx | 7 +- .../data/testUnnecessaryBarlines_ref.mscx | 7 +- .../tests/data/testUnterminatedTies_ref.mscx | 7 +- .../tests/data/testVoltaHiding_ref.mscx | 14 +- .../tests/data/testWedgeOffset_ref.mscx | 7 +- .../tabledit/tests/data/bass.mscx | 5 +- .../tabledit/tests/data/chord_C_D.mscx | 5 +- .../tabledit/tests/data/dynamic.mscx | 5 +- .../tabledit/tests/data/fingerings_1.mscx | 5 +- .../tabledit/tests/data/gaps_1.mscx | 1 - .../tabledit/tests/data/gaps_2.mscx | 1 - .../tabledit/tests/data/grace_1.mscx | 5 +- .../tabledit/tests/data/guitar.mscx | 5 +- .../tabledit/tests/data/guitar_bass.mscx | 10 +- .../tabledit/tests/data/guitar_drop_D.mscx | 5 +- .../data/guitar_new_standard_tuning.mscx | 5 +- .../tabledit/tests/data/key_signatures.mscx | 5 +- .../tabledit/tests/data/key_signatures_2.mscx | 10 +- .../tabledit/tests/data/metadata.mscx | 5 +- .../tests/data/multi_track_rests.mscx | 10 +- .../tabledit/tests/data/notes_dotted.mscx | 5 +- .../tabledit/tests/data/notes_normal.mscx | 5 +- .../tabledit/tests/data/pickup_measure.mscx | 1 - .../tabledit/tests/data/positions.mscx | 5 +- .../tabledit/tests/data/reading_list_1.mscx | 5 +- .../tabledit/tests/data/reading_list_10.mscx | 5 +- .../tabledit/tests/data/reading_list_11.mscx | 5 +- .../tabledit/tests/data/reading_list_12.mscx | 10 +- .../tabledit/tests/data/reading_list_2.mscx | 5 +- .../tabledit/tests/data/reading_list_3.mscx | 5 +- .../tabledit/tests/data/reading_list_4.mscx | 5 +- .../tabledit/tests/data/reading_list_5.mscx | 5 +- .../tabledit/tests/data/reading_list_6.mscx | 5 +- .../tabledit/tests/data/reading_list_7.mscx | 5 +- .../tabledit/tests/data/reading_list_8.mscx | 10 +- .../tabledit/tests/data/reading_list_9.mscx | 5 +- .../tabledit/tests/data/rests_dotted.mscx | 5 +- .../tabledit/tests/data/rests_normal.mscx | 5 +- .../tabledit/tests/data/staff_text_1.mscx | 5 +- .../tabledit/tests/data/staff_text_2.mscx | 10 +- .../tabledit/tests/data/tie_1.mscx | 1 - .../tabledit/tests/data/tie_2.mscx | 1 - .../tabledit/tests/data/time_signatures.mscx | 5 +- .../tests/data/time_signatures_2.mscx | 10 +- .../tabledit/tests/data/triplet_eighths.mscx | 5 +- .../tabledit/tests/data/triplet_quarters.mscx | 5 +- .../tabledit/tests/data/triplets_mixed.mscx | 5 +- .../tabledit/tests/data/voices.mscx | 5 +- .../tests/data/voices_multi_part.mscx | 10 +- 1014 files changed, 5397 insertions(+), 3939 deletions(-) mode change 100755 => 100644 src/importexport/mei/tests/data/artic-02.mscx diff --git a/src/engraving/tests/barline_data/barlinedelete-ref.mscx b/src/engraving/tests/barline_data/barlinedelete-ref.mscx index dff833179fdbb..b2bbcc17d5078 100644 --- a/src/engraving/tests/barline_data/barlinedelete-ref.mscx +++ b/src/engraving/tests/barline_data/barlinedelete-ref.mscx @@ -29,10 +29,11 @@ stdNormal - Piano - Piano - Pno. + + Piano + Pno. + Piano 21 108 diff --git a/src/engraving/tests/beam_data/Beam-A.mscx b/src/engraving/tests/beam_data/Beam-A.mscx index 804d47707834e..b02a34a6e1c4d 100644 --- a/src/engraving/tests/beam_data/Beam-A.mscx +++ b/src/engraving/tests/beam_data/Beam-A.mscx @@ -4,6 +4,8 @@ B_B 480 Style Score - - u_u - - Flute - - v_v + u_u G G 1 - w_w + v_v H_H - x_x + w_w I_I 4 4 - y_y + x_x J_J whole - z_z + y_y K_K 72 14 @@ -420,14 +412,14 @@ - 0_0 + z_z - 1_1 + 0_0 M_M whole - 2_2 + 1_1 N_N 72 14 @@ -436,14 +428,14 @@ - 3_3 + 2_2 - 4_4 + 3_3 P_P whole - 5_5 + 4_4 Q_Q 72 14 @@ -452,14 +444,14 @@ - 6_6 + 5_5 - 7_7 + 6_6 S_S whole - 8_8 + 7_7 T_T 72 14 @@ -468,14 +460,14 @@ - 9_9 + 8_8 - +_+ + 9_9 V_V whole - /_/ + +_+ W_W 72 14 @@ -484,14 +476,14 @@ - AB_AB + /_/ - BB_BB + AB_AB Y_Y whole - CB_CB + BB_BB Z_Z 72 14 @@ -500,14 +492,14 @@ - DB_DB + CB_CB - EB_EB + DB_DB b_b whole - FB_FB + EB_EB c_c 72 14 @@ -516,14 +508,14 @@ - GB_GB + FB_FB - HB_HB + GB_GB e_e whole - IB_IB + HB_HB f_f 72 14 @@ -534,8 +526,7 @@ - JB_JB - Oboe + IB_IB 480 Style Score - - NB_NB - - Oboe - - OB_OB + MB_MB G G 1 - PB_PB + NB_NB g_g - QB_QB + OB_OB h_h 4 4 - RB_RB + PB_PB i_i measure 4/4 @@ -626,10 +612,10 @@ - SB_SB + QB_QB - TB_TB + RB_RB j_j measure 4/4 @@ -637,10 +623,10 @@ - UB_UB + SB_SB - VB_VB + TB_TB k_k measure 4/4 @@ -648,10 +634,10 @@ - WB_WB + UB_UB - XB_XB + VB_VB l_l measure 4/4 @@ -659,10 +645,10 @@ - YB_YB + WB_WB - ZB_ZB + XB_XB m_m measure 4/4 @@ -670,10 +656,10 @@ - aB_aB + YB_YB - bB_bB + ZB_ZB n_n measure 4/4 @@ -681,10 +667,10 @@ - cB_cB + aB_aB - dB_dB + bB_bB o_o measure 4/4 @@ -692,10 +678,10 @@ - eB_eB + cB_cB - fB_fB + dB_dB p_p measure 4/4 diff --git a/src/engraving/tests/parts_data/partStyle-score-reload-ref.mscx b/src/engraving/tests/parts_data/partStyle-score-reload-ref.mscx index 2194672674402..5d368bff2482b 100644 --- a/src/engraving/tests/parts_data/partStyle-score-reload-ref.mscx +++ b/src/engraving/tests/parts_data/partStyle-score-reload-ref.mscx @@ -35,7 +35,6 @@ stdNormal - Flute Flute 59 @@ -71,9 +70,10 @@ stdNormal - Oboe - Ob. + + Ob. + Oboe 58 93 @@ -352,7 +352,6 @@ stdNormal - Flute Flute 59 @@ -565,9 +564,10 @@ stdNormal - Oboe - Ob. + + Ob. + Oboe 58 93 diff --git a/src/engraving/tests/parts_data/voices-ref.mscx b/src/engraving/tests/parts_data/voices-ref.mscx index 9d5304de1e4c1..08d9cf555d48c 100644 --- a/src/engraving/tests/parts_data/voices-ref.mscx +++ b/src/engraving/tests/parts_data/voices-ref.mscx @@ -38,10 +38,11 @@ F - Piano - Piano - Pno. + + Piano + Pno. + Piano 21 108 @@ -97,10 +98,11 @@ F - Trombone - Trombone - Tbn. + + Trombone + Tbn. + Trombone 35 74 @@ -1116,10 +1118,11 @@ F - Piano - Piano - Pno. + + Piano + Pno. + Piano 21 108 @@ -1777,10 +1780,11 @@ F - Trombone - Trombone - Tbn. + + Trombone + Tbn. + Trombone 35 74 @@ -2190,10 +2194,11 @@ F - Trombone - Trombone - Tbn. + + Trombone + Tbn. + Trombone 35 74 diff --git a/src/engraving/tests/readwriteundoreset_data/barlines.mscx b/src/engraving/tests/readwriteundoreset_data/barlines.mscx index 63c973cbc0b44..f0228bdd28ccb 100644 --- a/src/engraving/tests/readwriteundoreset_data/barlines.mscx +++ b/src/engraving/tests/readwriteundoreset_data/barlines.mscx @@ -4,6 +4,8 @@ B_B 480