replaced notation::Instrument with Ms::Instrument

This commit is contained in:
Roman Pudashkin 2021-08-09 18:17:39 +02:00 committed by pereverzev+v
parent 0a02d8bbfb
commit 86c462da14
25 changed files with 205 additions and 473 deletions

View file

@ -950,6 +950,11 @@ ClefTypeList InstrumentTemplate::clefType(int staffIdx) const
return clefTypes[0];
}
QString InstrumentTemplate::familyId() const
{
return family ? family->id : QString();
}
//---------------------------------------------------------
// defaultClef
// traverse the instrument list for first instrument

View file

@ -119,6 +119,9 @@ public:
bool singleNoteDynamics;
QString groupId;
QStringList genreIds;
InstrumentTemplate();
InstrumentTemplate(const InstrumentTemplate&);
~InstrumentTemplate();
@ -135,6 +138,7 @@ public:
int nstaves() const { return staves; }
void setStaves(int val) { staves = val; }
ClefTypeList clefType(int staffIdx) const;
QString familyId() const;
};
//---------------------------------------------------------

View file

@ -1372,6 +1372,11 @@ bool Instrument::operator==(const Instrument& i) const
&& i._singleNoteDynamics == _singleNoteDynamics;
}
bool Instrument::operator!=(const Instrument& i) const
{
return !(*this == i);
}
//---------------------------------------------------------
// isDifferentInstrument
/// Checks if the passed instrument is a different instrument.
@ -1685,36 +1690,46 @@ QString Instrument::abbreviature() const
// fromTemplate
//---------------------------------------------------------
Instrument Instrument::fromTemplate(const InstrumentTemplate* t)
Instrument Instrument::fromTemplate(const InstrumentTemplate* templ)
{
Instrument instr(t->id);
instr.setAmateurPitchRange(t->minPitchA, t->maxPitchA);
instr.setProfessionalPitchRange(t->minPitchP, t->maxPitchP);
for (const StaffName& sn : t->longNames) {
instr.addLongName(StaffName(sn.name(), sn.pos()));
Instrument instrument(templ->id);
instrument.setAmateurPitchRange(templ->minPitchA, templ->maxPitchA);
instrument.setProfessionalPitchRange(templ->minPitchP, templ->maxPitchP);
for (const StaffName& sn : templ->longNames) {
instrument.addLongName(StaffName(sn.name(), sn.pos()));
}
for (const StaffName& sn : t->shortNames) {
instr.addShortName(StaffName(sn.name(), sn.pos()));
for (const StaffName& sn : templ->shortNames) {
instrument.addShortName(StaffName(sn.name(), sn.pos()));
}
instr.setTrackName(t->trackName);
instr.setTranspose(t->transpose);
instr.setInstrumentId(t->musicXMLid);
if (t->useDrumset) {
instr.setDrumset(t->drumset ? t->drumset : smDrumset);
instrument.setTrackName(templ->trackName);
instrument.setTranspose(templ->transpose);
instrument.setInstrumentId(templ->musicXMLid);
instrument._useDrumset = templ->useDrumset;
if (templ->useDrumset) {
instrument.setDrumset(templ->drumset ? templ->drumset : smDrumset);
}
for (int i = 0; i < t->nstaves(); ++i) {
instr.setClefType(i, t->clefTypes[i]);
for (int i = 0; i < templ->nstaves(); ++i) {
instrument.setClefType(i, templ->clefTypes[i]);
}
instr.setMidiActions(t->midiActions);
instr.setArticulation(t->articulation);
instr._channel.clear();
for (const Channel& c : t->channel) {
instr._channel.append(new Channel(c));
instrument.setMidiActions(templ->midiActions);
instrument.setArticulation(templ->articulation);
instrument._channel.clear();
for (const Channel& c : templ->channel) {
instrument._channel.append(new Channel(c));
}
instr.setStringData(t->stringData);
instr.setSingleNoteDynamics(t->singleNoteDynamics);
instr.setTrait(t->trait);
return instr;
instrument.setStringData(templ->stringData);
instrument.setSingleNoteDynamics(templ->singleNoteDynamics);
instrument.setTrait(templ->trait);
return instrument;
}
Trait Instrument::trait() const

View file

@ -329,9 +329,8 @@ class Instrument
Trait _trait;
public:
Instrument(QString id="");
Instrument(QString id = "");
Instrument(const Instrument&);
void operator=(const Instrument&);
~Instrument();
void read(XmlReader&, Part* part);
@ -346,10 +345,13 @@ public:
QString recognizeInstrumentId() const;
int recognizeMidiProgram() const;
void operator=(const Instrument&);
bool operator==(const Instrument&) const;
bool operator!=(const Instrument&) const;
bool isDifferentInstrument(const Instrument& i) const;
QString getId() const { return _id; }
QString id() const { return _id; }
void setId(const QString& id) { _id = id; }
void setMinPitchP(int v) { _minPitchP = v; }
void setMaxPitchP(int v) { _maxPitchP = v; }

View file

@ -455,7 +455,7 @@ const InstrumentList* Part::instruments() const
QString Part::instrumentId(const Fraction& tick) const
{
return instrument(tick)->getId();
return instrument(tick)->id();
}
//---------------------------------------------------------

View file

@ -238,7 +238,7 @@ void ScoreOrder::setBracketsAndBarlines(Score* score)
int thnBracketSpan { 0 };
for (Part* part : score->parts()) {
InstrumentIndex ii = searchTemplateIndexForId(part->instrument()->getId());
InstrumentIndex ii = searchTemplateIndexForId(part->instrument()->id());
if (!ii.instrTemplate) {
continue;
}
@ -424,7 +424,7 @@ void ScoreOrder::write(Ms::XmlWriter& xml) const
void ScoreOrder::updateInstruments(const Score* score)
{
for (Part* part : score->parts()) {
InstrumentIndex ii = searchTemplateIndexForId(part->instrument()->getId());
InstrumentIndex ii = searchTemplateIndexForId(part->instrument()->id());
if (!ii.instrTemplate || !ii.instrTemplate->family) {
continue;
}

View file

@ -56,7 +56,9 @@ mu::RetVal<Instrument> SelectInstrumentsScenario::selectInstrument(const Instrum
return result;
}
result.val = selectedInstruments.val.instruments.first().instrument;
const InstrumentTemplate& templ = selectedInstruments.val.instruments.first().instrumentTemplate;
result.val = Instrument::fromTemplate(&templ);
return result;
}
@ -83,7 +85,7 @@ mu::RetVal<PartInstrumentListScoreOrder> SelectInstrumentsScenario::selectInstru
pi.isExistingPart = map["isExistingPart"].toBool();
pi.isSoloist = map["isSoloist"].toBool();
pi.partId = map["id"].toString();
pi.instrument = map["instrument"].value<Instrument>();
pi.instrumentTemplate = map["instrument"].value<InstrumentTemplate>();
result.val.instruments << pi;
}

View file

@ -73,8 +73,8 @@ void InstrumentListModel::load(bool canSelectMultipleInstruments, const QString&
initSelectedInstruments(parseIdList(selectedPartIds));
if (!currentInstrumentId.isEmpty()) {
Instrument instrument = instrumentById(currentInstrumentId);
selectGroup(instrument.groupId);
InstrumentTemplate templ = instrumentTemplateById(currentInstrumentId);
selectGroup(templ.groupId);
}
initScoreOrders(currentScoreOrderId);
@ -107,7 +107,6 @@ void InstrumentListModel::initSelectedInstruments(const IDList& selectedPartIds)
info.name = part->partName();
info.isSoloist = part->soloist();
info.familyCode = part->familyId();
info.config = Instrument();
m_selectedInstruments << info;
}
@ -184,14 +183,14 @@ QVariantList InstrumentListModel::groups() const
{
QStringList availableGroups;
for (const Instrument& instrument: m_instrumentsMeta.instrumentTemplates) {
for (const InstrumentTemplate* templ: m_instrumentsMeta.instrumentTemplates) {
constexpr bool compareWithSelectedGroup = false;
if (!isInstrumentAccepted(instrument, compareWithSelectedGroup)) {
if (!isInstrumentAccepted(*templ, compareWithSelectedGroup)) {
continue;
}
if (!availableGroups.contains(instrument.groupId)) {
availableGroups << instrument.groupId;
if (!availableGroups.contains(templ->groupId)) {
availableGroups << templ->groupId;
}
}
@ -217,31 +216,32 @@ QVariantList InstrumentListModel::instruments() const
QHash<QString, QStringList> traits;
QVariantMap availableInstruments;
for (const Instrument& instrument: m_instrumentsMeta.instrumentTemplates) {
const Trait& trait = instrument.trait;
for (const InstrumentTemplate* templ: m_instrumentsMeta.instrumentTemplates) {
const Trait& trait = templ->trait;
const QString& instrumentName = templ->trackName;
if (!isInstrumentAccepted(instrument)) {
if (!isInstrumentAccepted(*templ)) {
continue;
}
if (!trait.name.isEmpty()) {
if (trait.isDefault) {
traits[instrument.name].prepend(trait.name);
traits[instrumentName].prepend(trait.name);
} else {
traits[instrument.name] << trait.name;
traits[instrumentName] << trait.name;
}
}
QVariantMap instrumentObj;
instrumentObj[ID_KEY] = instrument.id;
instrumentObj[NAME_KEY] = instrument.name;
instrumentObj[GROUP_ID] = instrument.groupId;
instrumentObj[ID_KEY] = templ->id;
instrumentObj[NAME_KEY] = instrumentName;
instrumentObj[GROUP_ID] = templ->groupId;
if (traits.contains(instrument.name)) {
instrumentObj[TRAITS_KEY] = traits[instrument.name];
if (traits.contains(instrumentName)) {
instrumentObj[TRAITS_KEY] = traits[instrumentName];
}
availableInstruments[instrument.name] = instrumentObj;
availableInstruments[instrumentName] = instrumentObj;
}
QVariantList result = availableInstruments.values();
@ -294,16 +294,16 @@ void InstrumentListModel::selectGroup(const QString& groupId)
void InstrumentListModel::selectInstrument(const QString& instrumentName, const QString& traitName)
{
Instrument suitedInstrument;
const InstrumentTemplate* suitedTemplate = nullptr;
for (const Instrument& instrument : m_instrumentsMeta.instrumentTemplates) {
if (instrument.name == instrumentName && instrument.trait.name == traitName) {
suitedInstrument = instrument;
for (const InstrumentTemplate* templ : m_instrumentsMeta.instrumentTemplates) {
if (templ->trackName == instrumentName && templ->trait.name == traitName) {
suitedTemplate = templ;
break;
}
}
if (!suitedInstrument.isValid()) {
if (!suitedTemplate) {
LOGE() << QString("Instrument %1 with trait %2 does not exist")
.arg(instrumentName)
.arg(traitName);
@ -313,10 +313,10 @@ void InstrumentListModel::selectInstrument(const QString& instrumentName, const
SelectedInstrumentInfo info;
info.isExistingPart = false;
info.isSoloist = false;
info.id = suitedInstrument.templateId;
info.name = formatInstrumentTitle(suitedInstrument);
info.familyCode = suitedInstrument.familyId;
info.config = suitedInstrument;
info.id = suitedTemplate->id;
info.name = formatInstrumentTitle(suitedTemplate->trackName, suitedTemplate->trait);
info.familyCode = suitedTemplate->familyId();
info.config = *suitedTemplate;
if (!m_canSelectMultipleInstruments) {
m_selectedInstruments.clear();
@ -580,10 +580,10 @@ void InstrumentListModel::updateFamilyStateBySearch()
}
}
bool InstrumentListModel::isInstrumentAccepted(const Instrument& instrument, bool compareWithSelectedGroup) const
bool InstrumentListModel::isInstrumentAccepted(const InstrumentTemplate& instrument, bool compareWithSelectedGroup) const
{
if (isSearching()) {
return instrument.name.contains(m_searchText, Qt::CaseInsensitive);
return instrument.trackName.contains(m_searchText, Qt::CaseInsensitive);
}
if (instrument.groupId != m_selectedGroupId && compareWithSelectedGroup) {
@ -601,15 +601,15 @@ bool InstrumentListModel::isInstrumentAccepted(const Instrument& instrument, boo
return false;
}
Instrument InstrumentListModel::instrumentById(const QString& instrumentId) const
InstrumentTemplate InstrumentListModel::instrumentTemplateById(const QString& instrumentTemplateId) const
{
for (const Instrument& instrument: m_instrumentsMeta.instrumentTemplates) {
if (instrument.id == instrumentId) {
return instrument;
for (const InstrumentTemplate* templ: m_instrumentsMeta.instrumentTemplates) {
if (templ->id == instrumentTemplateId) {
return *templ;
}
}
return Instrument();
return InstrumentTemplate();
}
void InstrumentListModel::checkScoreOrderMatching(bool block)

View file

@ -93,7 +93,7 @@ private:
QString familyCode;
bool isSoloist = false;
bool isExistingPart = false;
notation::Instrument config;
notation::InstrumentTemplate config;
bool operator==(const SelectedInstrumentInfo& info) const { return id == info.id; }
};
@ -120,9 +120,9 @@ private:
void updateFamilyStateBySearch();
bool isInstrumentAccepted(const notation::Instrument& instrument, bool compareWithSelectedGroup = true) const;
bool isInstrumentAccepted(const notation::InstrumentTemplate &instrument, bool compareWithSelectedGroup = true) const;
notation::Instrument instrumentById(const QString& instrumentId) const;
notation::InstrumentTemplate instrumentTemplateById(const QString& instrumentTemplateId) const;
int indexOfScoreOrderId(const QString& id) const;
void sortSelectedInstruments();

View file

@ -60,8 +60,8 @@ void InstrumentSettingsModel::replaceInstrument()
Instrument newInstrument = selectedInstrument.val;
masterNotationParts()->replaceInstrument(m_instrumentKey, newInstrument);
m_instrumentKey.instrumentId = newInstrument.id;
m_instrumentName = newInstrument.name;
m_instrumentKey.instrumentId = newInstrument.id();
m_instrumentName = newInstrument.name();
m_instrumentAbbreviature = newInstrument.abbreviature();
emit dataChanged();

View file

@ -100,8 +100,6 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/internal/inotationmidievents.h
${CMAKE_CURRENT_LIST_DIR}/internal/notationmidievents.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/notationmidievents.h
${CMAKE_CURRENT_LIST_DIR}/internal/instrumentsconverter.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/instrumentsconverter.h
${CMAKE_CURRENT_LIST_DIR}/internal/instrumentsrepository.cpp
${CMAKE_CURRENT_LIST_DIR}/internal/instrumentsrepository.h

View file

@ -1,174 +0,0 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* 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 <https://www.gnu.org/licenses/>.
*/
#include "instrumentsconverter.h"
#include "libmscore/instrument.h"
#include "libmscore/instrtemplate.h"
#include "libmscore/drumset.h"
using namespace mu::notation;
Ms::Instrument InstrumentsConverter::convertInstrument(const Instrument& instrument)
{
Ms::Instrument result;
result.setAmateurPitchRange(instrument.amateurPitchRange.min, instrument.amateurPitchRange.max);
result.setProfessionalPitchRange(instrument.professionalPitchRange.min, instrument.professionalPitchRange.max);
for (const Ms::StaffName& longName : instrument.longNames) {
result.addLongName(Ms::StaffName(longName.name(), longName.pos()));
}
for (const Ms::StaffName& shortName : instrument.shortNames) {
result.addShortName(Ms::StaffName(shortName.name(), shortName.pos()));
}
result.setTrackName(instrument.name);
result.setTranspose(instrument.transpose);
result.setId(instrument.id);
result.setInstrumentId(instrument.musicXMLid);
if (instrument.useDrumset) {
result.setDrumset(instrument.drumset ? instrument.drumset : Ms::smDrumset);
}
for (int i = 0; i < instrument.staves; ++i) {
result.setClefType(i, instrument.clefs[i]);
}
result.setMidiActions(convertMidiActions(instrument.midiActions));
result.setArticulation(instrument.midiArticulations);
result.clearChannels();
for (const InstrumentChannel& channel : instrument.channels) {
result.appendChannel(new InstrumentChannel(channel));
}
result.setStringData(instrument.stringData);
result.setSingleNoteDynamics(instrument.singleNoteDynamics);
result.setTrait(instrument.trait);
return result;
}
Instrument InstrumentsConverter::convertInstrument(const Ms::Instrument& instrument)
{
Instrument result;
result.amateurPitchRange = PitchRange(instrument.minPitchA(), instrument.maxPitchA());
result.professionalPitchRange = PitchRange(instrument.minPitchP(), instrument.maxPitchP());
for (const Ms::StaffName& longName: instrument.longNames()) {
result.longNames << StaffName(longName.name(), longName.pos());
}
for (const Ms::StaffName& shortName: instrument.shortNames()) {
result.shortNames << StaffName(shortName.name(), shortName.pos());
}
result.name = instrument.trackName();
result.transpose = instrument.transpose();
result.id = instrument.getId();
result.musicXMLid = instrument.instrumentId();
result.useDrumset = instrument.useDrumset();
if (instrument.drumset()) {
result.drumset = new Drumset(*instrument.drumset());
}
result.staves = instrument.cleffTypeCount();
for (int i = 0; i < instrument.cleffTypeCount(); ++i) {
result.clefs[i] = instrument.clefType(i);
}
result.midiActions = convertMidiActions(instrument.midiActions());
result.midiArticulations = instrument.articulation();
for (const InstrumentChannel* channel : instrument.channel()) {
result.channels.append(*channel);
}
result.stringData = *instrument.stringData();
result.singleNoteDynamics = instrument.singleNoteDynamics();
result.trait = instrument.trait();
return result;
}
Instrument InstrumentsConverter::convertInstrument(const Ms::InstrumentTemplate& templ)
{
Ms::Instrument msInstrument = Ms::Instrument::fromTemplate(&templ);
Instrument result = convertInstrument(msInstrument);
result.templateId = templ.id;
result.familyId = templ.family ? templ.family->id : QString();
result.sequenceOrder = templ.sequenceOrder;
for (const Ms::InstrumentGenre* msGenre : templ.genres) {
result.genreIds << msGenre->id;
}
return result;
}
QList<Ms::NamedEventList> InstrumentsConverter::convertMidiActions(const MidiActionList& midiActions)
{
QList<Ms::NamedEventList> result;
for (const MidiAction& action: midiActions) {
Ms::NamedEventList event;
event.name = action.name;
event.descr = action.description;
for (const midi::Event& midiEvent: action.events) {
Ms::MidiCoreEvent midiCoreEvent;
midiCoreEvent.setType(static_cast<uchar>(midiEvent.type()));
midiCoreEvent.setChannel(midiCoreEvent.channel());
//!FIXME
//midiCoreEvent.setData(midiEvent.a, midiEvent.b);
event.events.push_back(midiCoreEvent);
}
}
return result;
}
MidiActionList InstrumentsConverter::convertMidiActions(const QList<Ms::NamedEventList>& midiActions)
{
MidiActionList result;
for (const Ms::NamedEventList& coreAction: midiActions) {
MidiAction action;
action.name = coreAction.name;
action.description = coreAction.descr;
for (const Ms::MidiCoreEvent& midiCoreEvent: coreAction.events) {
midi::Event midiEvent(midiCoreEvent.channel(),
static_cast<midi::EventType>(midiCoreEvent.type()),
midiCoreEvent.dataA(),
midiCoreEvent.dataB()
);
action.events.push_back(midiEvent);
}
}
return result;
}

View file

@ -1,48 +0,0 @@
/*
* SPDX-License-Identifier: GPL-3.0-only
* MuseScore-CLA-applies
*
* MuseScore
* Music Composition & Notation
*
* Copyright (C) 2021 MuseScore BVBA and others
*
* 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 <https://www.gnu.org/licenses/>.
*/
#ifndef MU_NOTATION_INSTRUMENTSCONVERTER_H
#define MU_NOTATION_INSTRUMENTSCONVERTER_H
#include "notation/notationtypes.h"
namespace Ms {
class Instrument;
class InstrumentTemplate;
struct NamedEventList;
}
namespace mu::notation {
class InstrumentsConverter
{
public:
static Ms::Instrument convertInstrument(const Instrument& instrument);
static Instrument convertInstrument(const Ms::Instrument& instrument);
static Instrument convertInstrument(const Ms::InstrumentTemplate& templ);
private:
static MidiActionList convertMidiActions(const QList<Ms::NamedEventList>& midiActions);
static QList<Ms::NamedEventList> convertMidiActions(const MidiActionList& midiActions);
};
}
#endif // MU_NOTATION_INSTRUMENTSCONVERTER_H

View file

@ -27,8 +27,6 @@
#include "libmscore/instrtemplate.h"
#include "libmscore/articulation.h"
#include "instrumentsconverter.h"
using namespace mu::notation;
void InstrumentsRepository::init()
@ -93,14 +91,12 @@ void InstrumentsRepository::fillInstrumentsMeta(InstrumentsMeta& meta)
meta.groups << group;
for (const Ms::InstrumentTemplate* msTemplate : msGroup->instrumentTemplates) {
if (msTemplate->trackName.isEmpty() || msTemplate->longNames.isEmpty()) {
for (InstrumentTemplate* templ : msGroup->instrumentTemplates) {
if (templ->trackName.isEmpty() || templ->longNames.isEmpty()) {
continue;
}
Instrument templ = notation::InstrumentsConverter::convertInstrument(*msTemplate);
templ.groupId = msGroup->id;
templ->groupId = msGroup->id;
meta.instrumentTemplates << templ;
}
}

View file

@ -63,8 +63,6 @@
#include "notationnoteinput.h"
#include "notationselection.h"
#include "instrumentsconverter.h"
using namespace mu::notation;
NotationInteraction::NotationInteraction(Notation* notation, INotationUndoStackPtr undoStack)
@ -1068,9 +1066,8 @@ void NotationInteraction::selectInstrument(Ms::InstrumentChange* instrumentChang
return;
}
Ms::Instrument instrument = InstrumentsConverter::convertInstrument(selectedInstrument.val);
instrumentChange->setInit(true);
instrumentChange->setupInstrument(&instrument);
instrumentChange->setupInstrument(&selectedInstrument.val);
}
//! NOTE Copied from Palette::applyPaletteElement

View file

@ -25,7 +25,6 @@
#include "libmscore/excerpt.h"
#include "libmscore/page.h"
#include "instrumentsconverter.h"
#include "igetscore.h"
@ -624,7 +623,7 @@ void NotationParts::replaceInstrument(const InstrumentKey& instrumentKey, const
startEdit();
score()->undo(new Ms::ChangePart(part, new Ms::Instrument(InstrumentsConverter::convertInstrument(newInstrument)),
score()->undo(new Ms::ChangePart(part, new Ms::Instrument(newInstrument),
formatPartTitle(part)));
apply();
@ -799,7 +798,7 @@ void NotationParts::moveStaves(const IDList& sourceStavesIds, const ID& destinat
deselectAll();
}
void NotationParts::appendStaves(Part* part, const Instrument& instrument)
void NotationParts::appendStaves(Part* part, const InstrumentTemplate& templ)
{
TRACEFUNC;
@ -807,11 +806,11 @@ void NotationParts::appendStaves(Part* part, const Instrument& instrument)
return;
}
for (int staffIndex = 0; staffIndex < instrument.staves; ++staffIndex) {
for (int staffIndex = 0; staffIndex < templ.nstaves(); ++staffIndex) {
int lastStaffIndex = !score()->staves().isEmpty() ? score()->staves().last()->idx() : 0;
Staff* staff = Ms::createStaff(score(), part);
initStaff(staff, instrument, Ms::StaffType::preset(StaffType::STANDARD), staffIndex);
initStaff(staff, templ, Ms::StaffType::preset(StaffType::STANDARD), staffIndex);
if (lastStaffIndex > 0) {
staff->setBarLineSpan(score()->staff(lastStaffIndex - 1)->barLineSpan());
@ -836,25 +835,25 @@ void NotationParts::insertStaff(Staff* staff, int destinationStaffIndex)
score()->undoInsertStaff(staff, destinationStaffIndex);
}
void NotationParts::initStaff(Staff* staff, const Instrument& instrument, const Ms::StaffType* staffType, int cleffIndex)
void NotationParts::initStaff(Staff* staff, const InstrumentTemplate& templ, const Ms::StaffType* staffType, int cleffIndex)
{
TRACEFUNC;
const Ms::StaffType* staffTypePreset = staffType ? staffType : instrument.staffTypePreset;
const Ms::StaffType* staffTypePreset = staffType ? staffType : templ.staffTypePreset;
if (!staffTypePreset) {
staffTypePreset = Ms::StaffType::getDefaultPreset(instrument.staffGroup);
staffTypePreset = Ms::StaffType::getDefaultPreset(templ.staffGroup);
}
Ms::StaffType* stt = staff->setStaffType(DEFAULT_TICK, *staffTypePreset);
if (cleffIndex >= MAX_STAVES) {
stt->setSmall(false);
} else {
stt->setSmall(instrument.smallStaff[cleffIndex]);
staff->setBracketType(0, instrument.bracket[cleffIndex]);
staff->setBracketSpan(0, instrument.bracketSpan[cleffIndex]);
staff->setBarLineSpan(instrument.barlineSpan[cleffIndex]);
stt->setSmall(templ.smallStaff[cleffIndex]);
staff->setBracketType(0, templ.bracket[cleffIndex]);
staff->setBracketSpan(0, templ.bracketSpan[cleffIndex]);
staff->setBarLineSpan(templ.barlineSpan[cleffIndex]);
}
staff->setDefaultClefType(instrument.clefs[cleffIndex]);
staff->setDefaultClefType(templ.clefType(cleffIndex));
}
void NotationParts::removeMissingParts(const PartInstrumentList& parts)
@ -884,10 +883,10 @@ void NotationParts::appendNewParts(const PartInstrumentList& parts)
{
TRACEFUNC;
Instruments newInstruments;
InstrumentList newInstruments;
for (const PartInstrument& pi: parts) {
newInstruments << pi.instrument;
newInstruments << Instrument::fromTemplate(&pi.instrumentTemplate);
}
int staffCount = 0;
@ -897,25 +896,28 @@ void NotationParts::appendNewParts(const PartInstrumentList& parts)
continue;
}
const Instrument& instrument = pi.instrument;
Instrument instrument = Instrument::fromTemplate(&pi.instrumentTemplate);
const QList<StaffName>& longNames = instrument.longNames();
const QList<StaffName>& shortNames = instrument.shortNames();
Part* part = new Part(score());
part->setSoloist(pi.isSoloist);
part->setInstrument(InstrumentsConverter::convertInstrument(instrument));
part->setInstrument(instrument);
int instrumentNumber = resolveInstrumentNumber(newInstruments, instrument);
QString formattedPartName = formatInstrumentTitle(instrument, instrumentNumber);
QString longName = !instrument.longNames.empty() ? instrument.longNames.first().name() : QString();
QString formattedLongName = formatInstrumentTitleOnScore(longName, instrument.trait, instrumentNumber);
QString shortName = !instrument.shortNames.empty() ? instrument.shortNames.first().name() : QString();
QString formattedShortName = formatInstrumentTitleOnScore(shortName, instrument.trait, instrumentNumber);
QString formattedPartName = formatInstrumentTitle(instrument.trackName(), instrument.trait(), instrumentNumber);
QString longName = !longNames.isEmpty() ? longNames.first().name() : QString();
QString formattedLongName = formatInstrumentTitleOnScore(longName, instrument.trait(), instrumentNumber);
QString shortName = !shortNames.isEmpty() ? shortNames.first().name() : QString();
QString formattedShortName = formatInstrumentTitleOnScore(shortName, instrument.trait(), instrumentNumber);
part->setPartName(formattedPartName);
part->setLongName(formattedLongName);
part->setShortName(formattedShortName);
score()->undo(new Ms::InsertPart(part, staffCount));
appendStaves(part, pi.instrument);
appendStaves(part, pi.instrumentTemplate);
staffCount += part->nstaves();
m_partChangedNotifier->itemAdded(part);
@ -975,16 +977,16 @@ void NotationParts::updateTracks()
score()->excerpt()->updateTracks();
}
int NotationParts::resolveInstrumentNumber(const Instruments& newInstruments,
int NotationParts::resolveInstrumentNumber(const InstrumentList& newInstruments,
const Instrument& currentInstrument) const
{
int count = 0;
for (const Part* part : score()->parts()) {
const Ms::Instrument* partInstrument = part->instrument();
const Instrument* partInstrument = part->instrument();
if (partInstrument->getId() == currentInstrument.id
&& partInstrument->trait().name == currentInstrument.trait.name) {
if (partInstrument->id() == currentInstrument.id()
&& partInstrument->trait().name == currentInstrument.trait().name) {
++count;
}
}
@ -994,8 +996,8 @@ int NotationParts::resolveInstrumentNumber(const Instruments& newInstruments,
}
for (const Instrument& newInstrument: newInstruments) {
if (newInstrument.id == currentInstrument.id
&& newInstrument.trait.name == currentInstrument.trait.name) {
if (newInstrument.id() == currentInstrument.id()
&& newInstrument.trait().name == currentInstrument.trait().name) {
++count;
}
}

View file

@ -94,9 +94,9 @@ private:
Staff* staffModifiable(const ID& staffId) const;
std::vector<Staff*> staves(const IDList& stavesIds) const;
void appendStaves(Part* part, const Instrument& instrument);
void appendStaves(Part* part, const InstrumentTemplate& templ);
void insertStaff(Staff* staff, int destinationStaffIndex);
void initStaff(Staff* staff, const Instrument& instrument, const Ms::StaffType* staffType, int cleffIndex);
void initStaff(Staff* staff, const InstrumentTemplate& templ, const Ms::StaffType* staffType, int cleffIndex);
void removeMissingParts(const PartInstrumentList& parts);
void appendNewParts(const PartInstrumentList& parts);
@ -105,7 +105,7 @@ private:
void updateTracks();
int resolveInstrumentNumber(const Instruments& newInstruments, const Instrument& currentInstrument) const;
int resolveInstrumentNumber(const InstrumentList& newInstruments, const Instrument& currentInstrument) const;
void setBracketsAndBarlines();

View file

@ -116,11 +116,16 @@ using MidiArticulation = Ms::MidiArticulation;
using Trait = Ms::Trait;
using TraitType = Ms::TraitType;
using InstrumentChannel = Ms::Channel;
using Instrument = Ms::Instrument;
using InstrumentTemplate = Ms::InstrumentTemplate;
using InstrumentTrait = Ms::Trait;
using InstrumentChannelList = QList<InstrumentChannel>;
using PageList = std::vector<const Page*>;
using StaffList = QList<const Staff*>;
using PartList = QList<const Part*>;
using InstrumentList = QList<Instrument>;
using InstrumentTemplateList = QList<const InstrumentTemplate*>;
enum class DragMode
{
@ -323,59 +328,6 @@ using InstrumentGenres = QList<InstrumentGenre>;
static const QString COMMON_GENRE_ID("common");
struct Instrument
{
QString id;
StaffNameList longNames;
StaffNameList shortNames;
QString name;
QString musicXMLid;
QString templateId;
QString description;
int sequenceOrder = 0;
bool extended = false;
int staves = 1;
QString groupId;
QStringList genreIds;
QString familyId;
PitchRange amateurPitchRange;
PitchRange professionalPitchRange;
ClefTypeList clefs[MAX_STAVES];
int staffLines[MAX_STAVES] = { 0 };
BracketType bracket[MAX_STAVES] = { BracketType::NO_BRACKET };
int bracketSpan[MAX_STAVES] = { 0 };
int barlineSpan[MAX_STAVES] = { 0 };
bool smallStaff[MAX_STAVES] = { false };
Interval transpose;
StaffGroup staffGroup = StaffGroup::STANDARD;
const StaffTypePreset* staffTypePreset = nullptr;
bool useDrumset = false;
const Drumset* drumset = nullptr;
StringData stringData;
bool singleNoteDynamics = false;
MidiActionList midiActions;
QList<MidiArticulation> midiArticulations;
InstrumentChannelList channels;
Trait trait;
bool isValid() const { return !id.isEmpty(); }
QString abbreviature() const { return !shortNames.isEmpty() ? shortNames.first().name() : QString(); }
};
using Instruments = QList<Instrument>;
struct InstrumentKey
{
ID instrumentId;
@ -383,21 +335,19 @@ struct InstrumentKey
Fraction tick = Ms::Fraction(0, 1);
};
inline QString formatInstrumentTitle(const Instrument& instrument, int instrumentNumber = 0)
inline QString formatInstrumentTitle(const QString& instrumentName, const InstrumentTrait& trait, int instrumentNumber = 0)
{
const QString& traitName = instrument.trait.name;
const QString& instrumentName = instrument.name;
QString result = instrumentName;
switch (instrument.trait.type) {
switch (trait.type) {
case TraitType::Tuning:
result = mu::qtrc("notation", "%1 %2").arg(traitName).arg(instrumentName);
result = mu::qtrc("notation", "%1 %2").arg(trait.name).arg(instrumentName);
break;
case TraitType::Course:
result = mu::qtrc("notation", "%1 (%2)").arg(instrumentName).arg(traitName);
result = mu::qtrc("notation", "%1 (%2)").arg(instrumentName).arg(trait.name);
break;
case TraitType::Transposition:
result = mu::qtrc("notation", "%1 in %2").arg(instrumentName).arg(traitName);
result = mu::qtrc("notation", "%1 in %2").arg(instrumentName).arg(trait.name);
break;
case TraitType::Unknown:
break;
@ -413,7 +363,7 @@ inline QString formatInstrumentTitle(const Instrument& instrument, int instrumen
struct PartInstrument
{
ID partId;
Instrument instrument;
InstrumentTemplate instrumentTemplate;
bool isExistingPart = false;
bool isSoloist = false;
@ -455,7 +405,7 @@ struct PartInstrumentListScoreOrder
struct InstrumentsMeta
{
Instruments instrumentTemplates;
InstrumentTemplateList instrumentTemplates;
InstrumentGroups groups;
InstrumentGenres genres;
MidiArticulations articulations;
@ -696,7 +646,7 @@ constexpr bool isFretIndexValid(int fretIndex)
}
}
Q_DECLARE_METATYPE(mu::notation::Instrument)
Q_DECLARE_METATYPE(mu::notation::InstrumentTemplate)
Q_DECLARE_METATYPE(mu::notation::ScoreOrder)
#endif // MU_NOTATION_NOTATIONTYPES_H

View file

@ -40,8 +40,6 @@
#include "ui/view/iconcodes.h"
#include "widgetstatestore.h"
#include "internal/instrumentsconverter.h"
using namespace mu::notation;
using namespace mu::ui;
@ -117,10 +115,10 @@ void EditStaff::setStaff(Staff* s, const Fraction& tick)
Part* part = m_orgStaff->part();
Ms::Score* score = part->score();
m_instrument = InstrumentsConverter::convertInstrument(*part->instrument(tick));
m_instrument = *part->instrument(tick);
m_orgInstrument = m_instrument;
m_instrumentKey.instrumentId = m_instrument.id;
m_instrumentKey.instrumentId = m_instrument.id();
m_instrumentKey.partId = part->id();
m_instrumentKey.tick = tick;
@ -190,36 +188,36 @@ void EditStaff::updateStaffType(const Ms::StaffType& staffType)
void EditStaff::updateInstrument()
{
updateInterval(m_instrument.transpose);
updateInterval(m_instrument.transpose());
QList<Ms::StaffName>& snl = m_instrument.shortNames;
QList<Ms::StaffName>& snl = m_instrument.shortNames();
QString df = snl.isEmpty() ? "" : snl[0].name();
shortName->setPlainText(df);
QList<Ms::StaffName>& lnl = m_instrument.longNames;
QList<Ms::StaffName>& lnl = m_instrument.longNames();
df = lnl.isEmpty() ? "" : lnl[0].name();
longName->setPlainText(df);
if (partName->text() == instrumentName->text()) {
// Updates part name if no custom name has been set before
partName->setText(m_instrument.name);
partName->setText(m_instrument.name());
}
instrumentName->setText(m_instrument.name);
instrumentName->setText(m_instrument.name());
m_minPitchA = m_instrument.amateurPitchRange.min;
m_maxPitchA = m_instrument.amateurPitchRange.max;
m_minPitchP = m_instrument.professionalPitchRange.min;
m_maxPitchP = m_instrument.professionalPitchRange.max;
m_minPitchA = m_instrument.minPitchA();
m_maxPitchA = m_instrument.maxPitchA();
m_minPitchP = m_instrument.minPitchP();
m_maxPitchP = m_instrument.maxPitchP();
minPitchA->setText(midiCodeToStr(m_minPitchA));
maxPitchA->setText(midiCodeToStr(m_maxPitchA));
minPitchP->setText(midiCodeToStr(m_minPitchP));
maxPitchP->setText(midiCodeToStr(m_maxPitchP));
singleNoteDynamics->setChecked(m_instrument.singleNoteDynamics);
singleNoteDynamics->setChecked(m_instrument.singleNoteDynamics());
// only show string data controls if instrument has strings
int numStr = m_instrument.stringData.strings();
int numStr = m_instrument.stringData()->strings();
stringDataFrame->setVisible(numStr > 0);
numOfStrings->setText(QString::number(numStr));
@ -322,7 +320,7 @@ void EditStaff::apply()
void EditStaff::minPitchAClicked()
{
int newCode;
EditPitch ep(this, m_instrument.amateurPitchRange.min);
EditPitch ep(this, m_instrument.minPitchA());
ep.setWindowModality(Qt::WindowModal);
if ((newCode = ep.exec()) != -1) {
minPitchA->setText(midiCodeToStr(newCode));
@ -333,7 +331,7 @@ void EditStaff::minPitchAClicked()
void EditStaff::maxPitchAClicked()
{
int newCode;
EditPitch ep(this, m_instrument.amateurPitchRange.max);
EditPitch ep(this, m_instrument.maxPitchP());
ep.setWindowModality(Qt::WindowModal);
if ((newCode = ep.exec()) != -1) {
maxPitchA->setText(midiCodeToStr(newCode));
@ -344,7 +342,7 @@ void EditStaff::maxPitchAClicked()
void EditStaff::minPitchPClicked()
{
int newCode;
EditPitch ep(this, m_instrument.professionalPitchRange.min);
EditPitch ep(this, m_instrument.minPitchP());
ep.setWindowModality(Qt::WindowModal);
if ((newCode = ep.exec()) != -1) {
minPitchP->setText(midiCodeToStr(newCode));
@ -355,7 +353,7 @@ void EditStaff::minPitchPClicked()
void EditStaff::maxPitchPClicked()
{
int newCode;
EditPitch ep(this, m_instrument.professionalPitchRange.max);
EditPitch ep(this, m_instrument.maxPitchP());
ep.setWindowModality(Qt::WindowModal);
if ((newCode = ep.exec()) != -1) {
maxPitchP->setText(midiCodeToStr(newCode));
@ -452,7 +450,7 @@ Instrument EditStaff::instrument() const
}
const Part* part = notationParts->part(m_instrumentKey.partId);
return part ? InstrumentsConverter::convertInstrument(*part->instrument(m_instrumentKey.tick)) : Instrument();
return part ? *part->instrument(m_instrumentKey.tick) : Instrument();
}
void EditStaff::applyStaffProperties()
@ -477,7 +475,7 @@ void EditStaff::applyStaffProperties()
config.hideSystemBarline = hideSystemBarLine->isChecked();
config.mergeMatchingRests = mergeMatchingRests->isChecked();
config.hideMode = Staff::HideMode(hideMode->currentIndex());
config.clefTypeList = m_instrument.clefs[m_orgStaff->rstaff()];
config.clefTypeList = m_instrument.clefType(m_orgStaff->rstaff());
notationParts()->setStaffConfig(m_orgStaff->id(), config);
@ -510,30 +508,30 @@ void EditStaff::applyPartProperties()
interval.flip();
}
m_instrument.transpose = interval;
m_instrument.amateurPitchRange.min = m_minPitchA;
m_instrument.amateurPitchRange.max = m_maxPitchA;
m_instrument.professionalPitchRange.min = m_minPitchP;
m_instrument.professionalPitchRange.max = m_maxPitchP;
m_instrument.setTranspose(interval);
m_instrument.setMinPitchA(m_minPitchA);
m_instrument.setMaxPitchA(m_maxPitchA);
m_instrument.setMinPitchP(m_minPitchP);
m_instrument.setMaxPitchP(m_maxPitchP);
m_instrument.shortNames.clear();
m_instrument.shortNames().clear();
if (sn.length() > 0) {
m_instrument.shortNames.append(Ms::StaffName(sn, 0));
m_instrument.shortNames().append(Ms::StaffName(sn, 0));
}
m_instrument.longNames.clear();
m_instrument.longNames().clear();
if (ln.length() > 0) {
m_instrument.longNames.append(Ms::StaffName(ln, 0));
m_instrument.longNames().append(Ms::StaffName(ln, 0));
}
m_instrument.singleNoteDynamics = singleNoteDynamics->isChecked();
m_instrument.setSingleNoteDynamics(singleNoteDynamics->isChecked());
QString newPartName = partName->text().simplified();
Ms::Interval v1 = m_instrument.transpose;
Ms::Interval v2 = m_orgInstrument.transpose;
Ms::Interval v1 = m_instrument.transpose();
Ms::Interval v2 = m_orgInstrument.transpose();
if (isInstrumentChanged()) {
if (m_instrument != m_orgInstrument) {
notationParts()->replaceInstrument(m_instrumentKey, m_instrument);
}
@ -554,17 +552,6 @@ void EditStaff::applyPartProperties()
}
}
bool EditStaff::isInstrumentChanged()
{
return m_instrument.name != m_orgInstrument.name
|| m_instrument.transpose != m_orgInstrument.transpose
|| m_instrument.amateurPitchRange != m_orgInstrument.amateurPitchRange
|| m_instrument.professionalPitchRange != m_orgInstrument.professionalPitchRange
|| m_instrument.shortNames != m_orgInstrument.shortNames
|| m_instrument.longNames != m_orgInstrument.longNames
|| m_instrument.singleNoteDynamics != m_orgInstrument.singleNoteDynamics;
}
void EditStaff::showReplaceInstrumentDialog()
{
RetVal<Instrument> selectedInstrument = selectInstrumentsScenario()->selectInstrument(m_instrumentKey);
@ -579,8 +566,8 @@ void EditStaff::showReplaceInstrumentDialog()
void EditStaff::editStringDataClicked()
{
int frets = m_instrument.stringData.frets();
QList<Ms::instrString> stringList = m_instrument.stringData.stringList();
int frets = m_instrument.stringData()->frets();
QList<Ms::instrString> stringList = m_instrument.stringData()->stringList();
EditStringData* esd = new EditStringData(this, &stringList, &frets);
esd->setWindowModality(Qt::WindowModal);
@ -603,32 +590,34 @@ void EditStaff::editStringDataClicked()
}
}
// get old string range bottom
for (const Ms::instrString& str : m_instrument.stringData.stringList()) {
for (const Ms::instrString& str : m_instrument.stringData()->stringList()) {
if (str.pitch > oldHighestStringPitch) {
oldHighestStringPitch = str.pitch;
}
}
// if there were no string, arbitrarely set old top to maxPitchA
if (oldHighestStringPitch == INT16_MIN) {
oldHighestStringPitch = m_instrument.amateurPitchRange.max;
oldHighestStringPitch = m_instrument.maxPitchA();
}
// range bottom is surely the pitch of the lowest string
m_instrument.amateurPitchRange.min = lowestStringPitch;
m_instrument.professionalPitchRange.min = lowestStringPitch;
m_instrument.setMinPitchA(lowestStringPitch);
m_instrument.setMinPitchP(lowestStringPitch);
// range top should keep the same interval with the highest string it has now
m_instrument.amateurPitchRange.max = m_instrument.amateurPitchRange.max + highestStringPitch - oldHighestStringPitch;
m_instrument.professionalPitchRange.max = m_instrument.professionalPitchRange.max + highestStringPitch - oldHighestStringPitch;
m_instrument.setMaxPitchA(m_instrument.maxPitchA() + highestStringPitch - oldHighestStringPitch);
m_instrument.setMaxPitchP(m_instrument.maxPitchP() + highestStringPitch - oldHighestStringPitch);
// update dlg controls
minPitchA->setText(midiCodeToStr(m_instrument.amateurPitchRange.min));
maxPitchA->setText(midiCodeToStr(m_instrument.amateurPitchRange.max));
minPitchP->setText(midiCodeToStr(m_instrument.professionalPitchRange.min));
maxPitchP->setText(midiCodeToStr(m_instrument.professionalPitchRange.max));
minPitchA->setText(midiCodeToStr(m_instrument.minPitchA()));
maxPitchA->setText(midiCodeToStr(m_instrument.maxPitchA()));
minPitchP->setText(midiCodeToStr(m_instrument.minPitchP()));
maxPitchP->setText(midiCodeToStr(m_instrument.maxPitchP()));
// if no longer there is any string, leave everything as it is now
}
// update instrument data and dlg controls
m_instrument.stringData = stringData;
m_instrument.setStringData(stringData);
numOfStrings->setText(QString::number(stringData.strings()));
}
}

View file

@ -93,8 +93,6 @@ private:
void applyStaffProperties();
void applyPartProperties();
bool isInstrumentChanged();
QString midiCodeToStr(int midiCode);
Ms::Staff* m_staff = nullptr;

View file

@ -174,14 +174,14 @@ void EditStaffType::setInstrument(const Instrument& instrument)
templateCombo->clear();
// standard group also as fall-back (but excluded by percussion)
bool bStandard = !(instrument.drumset != nullptr);
bool bPerc = (instrument.drumset != nullptr);
bool bTab = (instrument.stringData.frettedStrings() > 0);
bool bStandard = !(instrument.drumset() != nullptr);
bool bPerc = (instrument.drumset() != nullptr);
bool bTab = (instrument.stringData()->frettedStrings() > 0);
int idx = 0;
for (const Ms::StaffType& t : Ms::StaffType::presets()) {
if ((t.group() == Ms::StaffGroup::STANDARD && bStandard)
|| (t.group() == Ms::StaffGroup::PERCUSSION && bPerc)
|| (t.group() == Ms::StaffGroup::TAB && bTab && t.lines() <= instrument.stringData.frettedStrings())) {
|| (t.group() == Ms::StaffGroup::TAB && bTab && t.lines() <= instrument.stringData()->frettedStrings())) {
templateCombo->addItem(t.name(), idx);
}
idx++;

View file

@ -139,7 +139,7 @@ EditDrumsetDialog::EditDrumsetDialog(QWidget* parent)
if (measure && context.staff) {
Ms::Instrument* instrument = context.staff->part()->instrument(measure->tick());
m_instrumentKey.instrumentId = instrument->getId();
m_instrumentKey.instrumentId = instrument->id();
m_instrumentKey.partId = context.staff->part()->id();
m_instrumentKey.tick = measure->tick();
m_editedDrumset = *instrument->drumset();

View file

@ -250,7 +250,7 @@ public:
Ms::Part* part() { return _part; }
QString instrumentId() const { return instrument()->getId(); }
QString instrumentId() const { return instrument()->id(); }
QString longName() const;
QString shortName() const;

View file

@ -111,7 +111,7 @@ public:
int startTrack() const { return part()->startTrack(); }
int endTrack() const { return part()->endTrack(); }
QString instrumentId() const { return part()->instrument()->getId(); }
QString instrumentId() const { return part()->instrument()->id(); }
int harmonyCount() const { return part()->harmonyCount(); }
bool hasPitchedStaff() const { return part()->hasPitchedStaff(); }
bool hasTabStaff() const { return part()->hasTabStaff(); }

View file

@ -109,11 +109,7 @@ ProjectCreateOptions NewScoreModel::parseOptions(const QVariantMap& info) const
Q_ASSERT(!objMap["isExistingPart"].toBool());
PartInstrument pi;
pi.isExistingPart = false;
pi.isSoloist = false;
pi.partId = QString();
pi.instrument = objMap["instrument"].value<Instrument>();
pi.instrumentTemplate = objMap["instrument"].value<InstrumentTemplate>();
scoreOptions.parts << pi;
}