Merge pull request #8795 from RomanPudashkin/parts_and_staves_ID

[MU4] Fixed using of ID for parts/staves
This commit is contained in:
Elnur Ismailzada 2021-08-06 09:08:14 +02:00 committed by GitHub
commit 77a7e306a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
54 changed files with 550 additions and 325 deletions

View file

@ -2572,11 +2572,9 @@ static void readPart(Part* part, XmlReader& e)
while (e.readNextStartElement()) {
const QStringRef& tag(e.name());
if (tag == "Staff") {
Staff* staff = new Staff(_score);
staff->setPart(part);
Staff* staff = createStaff(_score, part);
staff->setStaffType(Fraction(0, 1), StaffType()); // will reset later if needed
_score->staves().push_back(staff);
part->staves()->push_back(staff);
_score->appendStaff(staff);
readStaff(staff, e);
} else if (tag == "Instrument") {
Instrument* i = part->instrument();
@ -2917,7 +2915,7 @@ Score::FileError Read114::read114(MasterScore* masterScore, XmlReader& e)
} else if (tag == "Part") {
Part* part = new Part(masterScore);
readPart(part, e);
masterScore->parts().push_back(part);
masterScore->appendPart(part);
} else if (tag == "Slur") {
Slur* slur = new Slur(masterScore);
Read206::readSlur206(e, slur);

View file

@ -780,10 +780,8 @@ void Read206::readPart206(Part* part, XmlReader& e)
}
}
} else if (tag == "Staff") {
Staff* staff = new Staff(part->score());
staff->setPart(part);
part->score()->staves().push_back(staff);
part->staves()->push_back(staff);
Staff* staff = createStaff(part->score(), part);
part->score()->appendStaff(staff);
readStaff(staff, e);
} else if (part->readProperties(e)) {
} else {
@ -3406,7 +3404,7 @@ bool Read206::readScore206(Score* score, XmlReader& e)
} else if (tag == "Part") {
Part* part = new Part(score);
Read206::readPart206(part, e);
score->parts().push_back(part);
score->appendPart(part);
} else if ((tag == "HairPin") // TODO: do this elements exist here?
|| (tag == "Ottava")
|| (tag == "TextLine")

View file

@ -2069,7 +2069,7 @@ void Score::moveUp(ChordRest* cr)
return;
}
QList<Staff*>* staves = part->staves();
const QList<Staff*>* staves = part->staves();
// we know that staffMove+rstaff-1 index exists due to the previous condition.
if (staff->staffType(cr->tick())->group() != StaffGroup::STANDARD
|| staves->at(rstaff + staffMove - 1)->staffType(cr->tick())->group() != StaffGroup::STANDARD) {
@ -2098,7 +2098,7 @@ void Score::moveDown(ChordRest* cr)
return;
}
QList<Staff*>* staves = part->staves();
const QList<Staff*>* staves = part->staves();
// we know that staffMove+rstaff+1 index exists due to the previous condition.
if (staff->staffType(cr->tick())->group() != StaffGroup::STANDARD
|| staves->at(staffMove + rstaff + 1)->staffType(cr->tick())->group() != StaffGroup::STANDARD) {

View file

@ -114,7 +114,7 @@ bool Excerpt::isEmpty() const
return partScore() ? partScore()->parts().empty() : true;
}
void Excerpt::removePart(const QString& id)
void Excerpt::removePart(const ID& id)
{
int index = 0;
for (const Part* part: parts()) {
@ -228,22 +228,20 @@ void Excerpt::createExcerpt(Excerpt* excerpt)
// Set instruments and create linked staves
for (const Part* part : parts) {
Part* p = new Part(score);
p->setId(part->id());
p->setInstrument(*part->instrument());
p->setPartName(part->partName());
for (Staff* staff : *part->staves()) {
Staff* s = new Staff(score);
Staff* s = createStaff(score, p);
s->setId(staff->id());
s->setPart(p);
// s->setStaffType(0, *staff->staffType(0)); // TODO
s->init(staff);
s->setDefaultClefType(staff->defaultClefType());
// the order of staff - s matters as staff should be the first entry in the
// created link list to make primaryStaff() work
// TODO: change implementation, maybe create an explicit "primary" flag
score->undo(new Link(s, staff));
p->staves()->append(s);
score->staves().append(s);
score->appendStaff(s);
srcStaves.append(staff->idx());
}
score->appendPart(p);

View file

@ -60,7 +60,7 @@ public:
const QList<Part*>& parts() const { return _parts; }
bool containsPart(const Part* part) const;
void removePart(const QString& id);
void removePart(const ID& id);
void setParts(const QList<Part*>& p) { _parts = p; }

View file

@ -168,8 +168,7 @@ void MCursor::move(int t, const Fraction& tick)
void MCursor::addPart(const QString& instrument)
{
Part* part = new Part(_score);
Staff* staff = new Staff(_score);
staff->setPart(part);
Staff* staff = createStaff(_score, part);
InstrumentTemplate* it = searchTemplate(instrument);
if (it == 0) {
qFatal("Did not find instrument <%s>", qPrintable(instrument));

View file

@ -135,6 +135,9 @@ static const int VISUAL_STRING_NONE = -100; // no ordinal for the visu
static const int STRING_NONE = -1; // no ordinal for a physical string (0 = topmost in instrument)
static const int FRET_NONE = -1; // no ordinal for a fret
using ID = uint64_t;
static constexpr ID INVALID_ID = 0;
//---------------------------------------------------------
// BracketType
// System Brackets

View file

@ -48,9 +48,6 @@ namespace Ms {
Part::Part(Score* s)
: ScoreElement(s)
{
static std::atomic_int currentId { 0 };
_id = QString::number(++currentId);
_color = DEFAULT_COLOR;
_show = true;
_soloist = false;
@ -68,6 +65,16 @@ void Part::initFromInstrTemplate(const InstrumentTemplate* t)
setInstrument(Instrument::fromTemplate(t));
}
ID Part::id() const
{
return _id;
}
void Part::setId(const ID& id)
{
_id = id;
}
Part* Part::clone() const
{
return new Part(*this);
@ -142,10 +149,8 @@ bool Part::readProperties(XmlReader& e)
{
const QStringRef& tag(e.name());
if (tag == "Staff") {
Staff* staff = new Staff(score());
staff->setPart(this);
score()->staves().push_back(staff);
_staves.push_back(staff);
Staff* staff = createStaff(score(), this);
score()->appendStaff(staff);
staff->read(e);
} else if (tag == "Instrument") {
Instrument* instr = new Instrument;
@ -195,6 +200,7 @@ void Part::read(XmlReader& e)
void Part::write(XmlWriter& xml) const
{
xml.stag(this);
for (const Staff* staff : _staves) {
staff->write(xml);
}
@ -213,9 +219,30 @@ void Part::write(XmlWriter& xml) const
_preferSharpFlat == PreferSharpFlat::SHARPS ? "sharps" : "flats");
}
instrument()->write(xml, this);
xml.etag();
}
int Part::nstaves() const
{
return _staves.size();
}
const QList<Staff*>* Part::staves() const
{
return &_staves;
}
void Part::appendStaff(Staff* staff)
{
_staves.push_back(staff);
}
void Part::clearStaves()
{
_staves.clear();
}
//---------------------------------------------------------
// setLongNames
//---------------------------------------------------------
@ -241,12 +268,13 @@ void Part::setStaves(int n)
qDebug("Part::setStaves(): remove staves not implemented!");
return;
}
int staffIdx = score()->staffIdx(this) + ns;
for (int i = ns; i < n; ++i) {
Staff* staff = new Staff(score());
staff->setPart(this);
Staff* staff = createStaff(score(), this);
_staves.push_back(staff);
score()->staves().insert(staffIdx, staff);
const_cast<QList<Staff*>&>(score()->staves()).insert(staffIdx, staff);
for (Measure* m = score()->firstMeasure(); m; m = m->nextMeasure()) {
m->insertStaff(staff, staffIdx);
if (m->hasMMRest()) {

View file

@ -70,21 +70,24 @@ class Part final : public ScoreElement
QString _partName; ///< used in tracklist (mixer)
InstrumentList _instruments;
QList<Staff*> _staves;
QString _id; ///< used for MusicXml import
bool _show; ///< show part in partitur if true
bool _soloist; ///< used in score ordering
ID _id = INVALID_ID; ///< used for MusicXml import
bool _show = false; ///< show part in partitur if true
bool _soloist = false; ///< used in score ordering
static const int DEFAULT_COLOR = 0x3399ff;
int _color; ///User specified color for helping to label parts
int _color = 0; ///User specified color for helping to label parts
PreferSharpFlat _preferSharpFlat;
PreferSharpFlat _preferSharpFlat = PreferSharpFlat::DEFAULT;
friend class mu::engraving::compat::Read206;
public:
Part(Score* = 0);
Part(Score* score = nullptr);
void initFromInstrTemplate(const InstrumentTemplate*);
ID id() const;
void setId(const ID& id);
Part* clone() const;
ElementType type() const override { return ElementType::PART; }
@ -93,12 +96,12 @@ public:
bool readProperties(XmlReader&);
void write(XmlWriter& xml) const;
int nstaves() const { return _staves.size(); }
QList<Staff*>* staves() { return &_staves; }
const QList<Staff*>* staves() const { return &_staves; }
int nstaves() const;
const QList<Staff*>* staves() const;
void appendStaff(Staff* staff);
void clearStaves();
Staff* staff(int idx) const;
void setId(const QString& s) { _id = s; }
QString id() const { return _id; }
QString familyId() const;
int startTrack() const;

View file

@ -1030,15 +1030,6 @@ void Score::spell(Note* note)
note->setTpc(Ms::tpc(3, note->pitch(), opt));
}
//---------------------------------------------------------
// appendPart
//---------------------------------------------------------
void Score::appendPart(Part* p)
{
_parts.append(p);
}
//---------------------------------------------------------
// searchPage
// p is in canvas coordinates
@ -2460,8 +2451,15 @@ void Score::cmdRemovePart(Part* part)
void Score::insertPart(Part* part, int idx)
{
if (!part) {
return;
}
bool inserted = false;
int staff = 0;
assignIdIfNeed(*part);
for (QList<Part*>::iterator i = _parts.begin(); i != _parts.end(); ++i) {
if (staff >= idx) {
_parts.insert(i, part);
@ -2477,6 +2475,16 @@ void Score::insertPart(Part* part, int idx)
setInstrumentsChanged(true);
}
void Score::appendPart(Part* part)
{
if (!part) {
return;
}
assignIdIfNeed(*part);
_parts.push_back(part);
}
//---------------------------------------------------------
// removePart
//---------------------------------------------------------
@ -2517,6 +2525,11 @@ void Score::removePart(Part* part)
void Score::insertStaff(Staff* staff, int ridx)
{
if (!staff || !staff->part()) {
return;
}
assignIdIfNeed(*staff);
staff->part()->insertStaff(staff, ridx);
int idx = staffIdx(staff->part()) + ridx;
@ -2542,21 +2555,53 @@ void Score::insertStaff(Staff* staff, int ridx)
}
}
}
#if 0
for (Spanner* s : staff->score()->unmanagedSpanners()) {
if (s->systemFlag()) {
continue;
}
if (s->staffIdx() >= idx) {
int t = s->track() + VOICES;
s->setTrack(t < ntracks() ? t : ntracks() - 1);
if (s->track2() != -1) {
t = s->track2() + VOICES;
s->setTrack2(t < ntracks() ? t : s->track());
}
}
}
void Score::appendStaff(Staff* staff)
{
if (!staff || !staff->part()) {
return;
}
#endif
assignIdIfNeed(*staff);
staff->part()->appendStaff(staff);
_staves.push_back(staff);
}
void Score::assignIdIfNeed(Staff& staff) const
{
if (staff.id() == INVALID_ID) {
staff.setId(newStaffId());
}
}
void Score::assignIdIfNeed(Part& part) const
{
if (part.id() == INVALID_ID) {
part.setId(newPartId());
}
}
ID Score::newStaffId() const
{
ID maxId = 0;
for (const Staff* staff : score()->staves()) {
maxId = std::max(maxId, staff->id());
}
return maxId + 1;
}
ID Score::newPartId() const
{
ID maxId = 0;
for (const Part* part : score()->parts()) {
maxId = std::max(maxId, part->id());
}
return maxId + 1;
}
//---------------------------------------------------------
@ -2785,10 +2830,10 @@ void Score::sortStaves(QList<int>& dst)
Staff* staff = _staves[idx];
if (staff->part() != curPart) {
curPart = staff->part();
curPart->staves()->clear();
curPart->clearStaves();
_parts.push_back(curPart);
}
curPart->staves()->push_back(staff);
curPart->appendStaff(staff);
dl.push_back(staff);
for (int itrack = 0; itrack < VOICES; ++itrack) {
trackMap.insert(idx * VOICES + itrack, track++);
@ -4050,8 +4095,7 @@ void Score::appendPart(const InstrumentTemplate* t)
part->initFromInstrTemplate(t);
int n = nstaves();
for (int i = 0; i < t->nstaves(); ++i) {
Staff* staff = new Staff(this);
staff->setPart(part);
Staff* staff = createStaff(this, part);
StaffType* stt = staff->staffType(Fraction(0, 1));
stt->setLines(t->staffLines[i]);
stt->setSmall(t->smallStaff[i]);
@ -5162,7 +5206,7 @@ int Score::staffIdx(const Part* part) const
return idx;
}
Staff* Score::staff(const QString& staffId) const
Staff* Score::staffById(const ID& staffId) const
{
for (Staff* staff : _staves) {
if (staff->id() == staffId) {
@ -5173,6 +5217,17 @@ Staff* Score::staff(const QString& staffId) const
return nullptr;
}
Part* Score::partById(const ID& partId) const
{
for (Part* part : _parts) {
if (part->id() == partId) {
return part;
}
}
return nullptr;
}
mu::score::AccessibleScore* Score::accessible() const
{
return m_accessible;

View file

@ -571,6 +571,12 @@ private:
void update(bool resetCmdState);
ID newStaffId() const;
ID newPartId() const;
void assignIdIfNeed(Staff& staff) const;
void assignIdIfNeed(Part& part) const;
protected:
int _fileDivision; ///< division of current loading *.msc file
LayoutMode _layoutMode { LayoutMode::PAGE };
@ -623,8 +629,10 @@ public:
void rebuildBspTree();
bool noStaves() const { return _staves.empty(); }
void insertPart(Part*, int);
void appendPart(Part*);
void removePart(Part*);
void insertStaff(Staff*, int);
void appendStaff(Staff*);
void cmdRemoveStaff(int staffIdx);
void removeStaff(Staff*);
void addMeasure(MeasureBase*, MeasureBase*);
@ -688,14 +696,14 @@ public:
bool read400(XmlReader& e);
bool readScore400(XmlReader& e);
QList<Staff*>& staves() { return _staves; }
const QList<Staff*>& staves() const { return _staves; }
int nstaves() const { return _staves.size(); }
int ntracks() const { return _staves.size() * VOICES; }
int staffIdx(const Part*) const;
Staff* staff(int n) const { return ((n >= 0) && (n < _staves.size())) ? _staves.at(n) : nullptr; }
Staff* staff(const QString& staffId) const;
Staff* staffById(const ID& staffId) const;
Part* partById(const ID& partId) const;
Measure* pos2measure(const mu::PointF&, int* staffIdx, int* pitch, Segment**, mu::PointF* offset) const;
void dragPosition(const mu::PointF&, int* staffIdx, Segment**, qreal spacingFactor = 0.5) const;
@ -834,10 +842,8 @@ public:
void changeSelectedNotesVoice(int);
QList<Part*>& parts() { return _parts; }
const QList<Part*>& parts() const { return _parts; }
void appendPart(Part* p);
void appendPart(const InstrumentTemplate*);
void updateStaffIndex();
void sortStaves(QList<int>& dst);

View file

@ -63,7 +63,6 @@ namespace Ms {
Staff::Staff(Score* score)
: Element(score)
{
setId(makeId());
initFromStaffType(0);
}
@ -96,15 +95,6 @@ Staff* Staff::clone() const
return new Staff(*this);
}
//---------------------------------------------------------
// id
//---------------------------------------------------------
QString Staff::id() const
{
return _id;
}
//---------------------------------------------------------
// idx
//---------------------------------------------------------
@ -720,8 +710,8 @@ Fraction Staff::currentKeyTick(const Fraction& tick) const
void Staff::write(XmlWriter& xml) const
{
int idx = this->idx();
xml.stag(this, QString("id=\"%1\"").arg(idx + 1));
xml.stag(this, QString("id=\"%1\"").arg(idx() + 1));
if (links()) {
Score* s = masterScore();
for (auto le : *links()) {
@ -937,17 +927,6 @@ qreal Staff::staffMag(const StaffType* stt) const
return (stt->small() ? score()->styleD(Sid::smallStaffMag) : 1.0) * stt->userMag();
}
void Staff::setId(const QString& id)
{
_id = id;
}
QString Staff::makeId()
{
static std::atomic_int currentId { 0 };
return QString::number(++currentId);
}
qreal Staff::staffMag(const Fraction& tick) const
{
return staffMag(staffType(tick));
@ -1240,6 +1219,7 @@ void Staff::init(const InstrumentTemplate* t, const StaffType* staffType, int ci
void Staff::init(const Staff* s)
{
_id = s->_id;
_staffTypeList = s->_staffTypeList;
setDefaultClefType(s->defaultClefType());
for (BracketItem* i : s->_brackets) {
@ -1261,6 +1241,16 @@ void Staff::init(const Staff* s)
_userDist = s->_userDist;
}
ID Staff::id() const
{
return _id;
}
void Staff::setId(const ID& id)
{
_id = id;
}
void Staff::setScore(Score* score)
{
Element::setScore(score);

View file

@ -78,8 +78,8 @@ public:
};
private:
QString _id;
Part* _part { 0 };
ID _id = INVALID_ID;
Part* _part = nullptr;
ClefList clefs;
ClefTypeList _defaultClefType;
@ -120,14 +120,18 @@ private:
qreal staffMag(const StaffType*) const;
public:
Staff(Score* score = 0);
Staff(Score* score = nullptr);
Staff(const Staff& staff);
Staff* clone() const override;
~Staff();
void init(const InstrumentTemplate*, const StaffType* staffType, int);
void initFromStaffType(const StaffType* staffType);
void init(const Staff*);
ID id() const;
void setId(const ID& id);
ElementType type() const override { return ElementType::STAFF; }
void setScore(Score* score) override;
@ -135,9 +139,6 @@ public:
bool isTop() const;
QString partName() const;
int rstaff() const;
QString id() const;
void setId(const QString& id);
static QString makeId();
int idx() const;
void read(XmlReader&) override;
bool readProperties(XmlReader&) override;
@ -313,5 +314,13 @@ public:
void triggerLayout() const override;
void triggerLayout(const Fraction& tick);
};
inline Staff* createStaff(Score* score, Part* part)
{
Staff* staff = new Staff(score);
staff->setPart(part);
return staff;
}
} // namespace Ms
#endif

View file

@ -49,6 +49,8 @@ set(MODULE_SRC
${CMAKE_CURRENT_LIST_DIR}/logstream.h
${CMAKE_CURRENT_LIST_DIR}/dataformatter.cpp
${CMAKE_CURRENT_LIST_DIR}/dataformatter.h
${CMAKE_CURRENT_LIST_DIR}/id.cpp
${CMAKE_CURRENT_LIST_DIR}/id.h
${CMAKE_CURRENT_LIST_DIR}/val.cpp
${CMAKE_CURRENT_LIST_DIR}/val.h
${CMAKE_CURRENT_LIST_DIR}/settings.cpp

115
src/framework/global/id.cpp Normal file
View file

@ -0,0 +1,115 @@
/*
* 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 "id.h"
using namespace mu;
ID::ID()
: m_id(0)
{
}
ID::ID(const ID& id)
: m_id(id.m_id)
{
}
ID::ID(const uint64_t& id)
: m_id(id)
{
}
bool ID::isValid() const
{
return m_id != 0;
}
ID& ID::operator=(const ID& id)
{
m_id = id.m_id;
return *this;
}
ID& ID::operator+=(const ID& id)
{
m_id += id.m_id;
return *this;
}
ID ID::operator+(const ID& id) const
{
return ID(m_id + id.m_id);
}
ID ID::operator^(const ID& id) const
{
return ID(m_id ^ id.m_id);
}
bool ID::operator==(const ID& id) const
{
return m_id == id.m_id;
}
bool ID::operator==(uint64_t id) const
{
return m_id == id;
}
bool ID::operator!=(const ID& id) const
{
return m_id != id.m_id;
}
bool ID::operator<(const ID& id) const
{
return m_id < id.m_id;
}
bool ID::operator>(const ID& id) const
{
return m_id > id.m_id;
}
uint64_t ID::toUint64() const
{
return m_id;
}
#ifndef NO_QT_SUPPORT
ID::ID(const QString& id)
: m_id(id.toULongLong())
{
}
ID::ID(const QVariant& id)
: m_id(id.toULongLong())
{
}
QString ID::toQString() const
{
return QString::number(m_id);
}
#endif

75
src/framework/global/id.h Normal file
View file

@ -0,0 +1,75 @@
/*
* 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_FRAMEWORK_ID_H
#define MU_FRAMEWORK_ID_H
#include <cstdint>
#include <vector>
#ifndef NO_QT_SUPPORT
#include <QVariant>
#endif
namespace mu {
class ID
{
public:
ID();
ID(const ID& id);
ID(const uint64_t& id);
bool isValid() const;
ID& operator=(const ID& id);
ID& operator+=(const ID& id);
ID operator+(const ID& id) const;
ID operator^(const ID& id) const;
bool operator==(const ID& id) const;
bool operator==(uint64_t id) const;
bool operator!=(const ID& id) const;
bool operator<(const ID& id) const;
bool operator>(const ID& id) const;
uint64_t toUint64() const;
#ifndef NO_QT_SUPPORT
ID(const QString& id);
ID(const QVariant& id);
QString toQString() const;
#endif
private:
uint64_t m_id = 0;
};
using IDList = std::vector<ID>;
inline bool containsId(const IDList& list, const ID& id)
{
return std::find(list.cbegin(), list.cend(), id) != list.cend();
}
}
#endif // MU_FRAMEWORK_ID_H

View file

@ -414,10 +414,8 @@ Score::FileError importBB(MasterScore* score, const QString& name)
}
for (int i = 0; i < ntracks; ++i) {
Part* part = new Part(score);
Staff* s = new Staff(score);
s->setPart(part);
part->insertStaff(s, 0);
score->staves().append(s);
Staff* s = createStaff(score, part);
score->appendStaff(s);
score->appendPart(part);
}

View file

@ -549,14 +549,10 @@ Score::FileError importBww(MasterScore* score, const QString& path)
return Score::FileError::FILE_OPEN_ERROR;
}
QString id("importBww");
Part* part = new Part(score);
part->setId(id);
score->appendPart(part);
Staff* staff = new Staff(score);
staff->setPart(part);
part->staves()->push_back(staff);
score->staves().push_back(staff);
Staff* staff = createStaff(score, part);
score->appendStaff(staff);
Bww::Lexer lex(&fp);
Bww::MsScWriter wrt;

View file

@ -1287,10 +1287,9 @@ void convertCapella(Score* score, Capella* cap, bool capxMode)
}
midiPatch = cl->sound;
Staff* s = new Staff(score);
Staff* s = createStaff(score, part);
s->initFromStaffType(0);
s->setPart(part);
if (cl->bPercussion) {
part->setMidiProgram(0, 128);
} else {
@ -1314,14 +1313,13 @@ void convertCapella(Score* score, Capella* cap, bool capxMode)
}
s->staffType(Fraction(0, 1))->setSmall(cl->bSmall);
part->insertStaff(s, -1);
Interval interval;
// guess diatonic transposition from chromatic transposition for the instrument
int values[23] = { -6, -6, -5, -5, -4, -3, -3, -2, -2, -1, -1, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6 };
interval.diatonic = values[(cl->transp % 12) + 11] + (cl->transp / 12) * 7;
interval.chromatic = cl->transp;
s->part()->instrument()->setTranspose(interval);
score->staves().push_back(s);
score->appendStaff(s);
}
if (bstaff) {
bstaff->setBarLineSpan(span != 0);

View file

@ -708,10 +708,9 @@ bool GuitarPro4::read(QFile* fp)
//
for (int staffIdx = 0; staffIdx < staves; ++staffIdx) {
Part* part = new Part(score);
Staff* s = new Staff(score);
s->setPart(part);
part->insertStaff(s, 0);
score->staves().push_back(s);
Staff* s = createStaff(score, part);
score->appendStaff(s);
score->appendPart(part);
}

View file

@ -919,10 +919,9 @@ bool GuitarPro5::read(QFile* fp)
//
for (int staffIdx = 0; staffIdx < staves; ++staffIdx) {
Part* part = new Part(score);
Staff* s = new Staff(score);
s->setPart(part);
part->insertStaff(s, -1);
score->staves().push_back(s);
Staff* s = createStaff(score, part);
score->appendStaff(s);
score->appendPart(part);
}

View file

@ -484,10 +484,8 @@ void GuitarPro6::readTracks(QDomNode* track)
QDomNode currentNode = nextTrack.firstChild();
Part* part = new Part(score);
bool hasTuning = false;
Staff* s = new Staff(score);
s->setPart(part);
part->insertStaff(s, -1);
score->staves().push_back(s);
Staff* s = createStaff(score, part);
score->appendStaff(s);
while (!currentNode.isNull()) {
QString nodeName = currentNode.nodeName();
if (nodeName == "Name") {
@ -528,10 +526,8 @@ void GuitarPro6::readTracks(QDomNode* track)
qDebug() << "Unknown instrument: " << ref;
}
if (ref.endsWith("-gs") || ref.startsWith("2")) { // grand staff
Staff* s2 = new Staff(score);
s2->setPart(part);
part->insertStaff(s2, -1);
score->staves().push_back(s2);
Staff* s2 = createStaff(score, part);
score->appendStaff(s2);
s->addBracket(new BracketItem(s->score(), BracketType::BRACE, 2));
s->setBarLineSpan(2);
}

View file

@ -42,10 +42,8 @@ void GuitarPro7::readTracks(QDomNode* track)
QDomNode currentNode = nextTrack.firstChild();
Part* part = new Part(score);
bool hasTuning = false;
Staff* s = new Staff(score);
s->setPart(part);
part->insertStaff(s, -1);
score->staves().push_back(s);
Staff* s = createStaff(score, part);
score->appendStaff(s);
while (!currentNode.isNull()) {
QString nodeName = currentNode.nodeName();
if (nodeName == "Name") {
@ -70,10 +68,8 @@ void GuitarPro7::readTracks(QDomNode* track)
qDebug() << "Unknown instrument: " << ref;
}
if (ref.endsWith("-gs") || ref.startsWith("2")) { // grand staff
Staff* s2 = new Staff(score);
s2->setPart(part);
part->insertStaff(s2, -1);
score->staves().push_back(s2);
Staff* s2 = createStaff(score, part);
score->appendStaff(s2);
s->addBracket(new BracketItem(s->score(), BracketType::BRACE, 2));
s->setBarLineSpan(2);
}

View file

@ -1145,10 +1145,9 @@ bool GuitarPro1::read(QFile* fp)
//
for (int staffIdx = 0; staffIdx < staves; ++staffIdx) {
Part* part = new Part(score);
Staff* s = new Staff(score);
s->setPart(part);
part->insertStaff(s, 0);
score->staves().push_back(s);
Staff* s = createStaff(score, part);
score->appendStaff(s);
score->appendPart(part);
}
@ -1583,10 +1582,9 @@ bool GuitarPro2::read(QFile* fp)
//
for (int staffIdx = 0; staffIdx < staves; ++staffIdx) {
Part* part = new Part(score);
Staff* s = new Staff(score);
s->setPart(part);
part->insertStaff(s, 0);
score->staves().push_back(s);
Staff* s = createStaff(score, part);
score->appendStaff(s);
score->appendPart(part);
}
@ -2274,10 +2272,9 @@ bool GuitarPro3::read(QFile* fp)
//
for (int staffIdx = 0; staffIdx < staves; ++staffIdx) {
Part* part = new Part(score);
Staff* s = new Staff(score);
s->setPart(part);
part->insertStaff(s, 0);
score->staves().push_back(s);
Staff* s = createStaff(score, part);
score->appendStaff(s);
score->appendPart(part);
}
@ -2990,14 +2987,12 @@ Score::FileError importGTP(MasterScore* score, const QString& name)
Staff* staff = part->staves()->front();
Staff* s = new Staff(pscore);
s->setPart(p);
Staff* s = createStaff(score, part);
const StaffType* st = staff->constStaffType(Fraction(0, 1));
s->setStaffType(Fraction(0, 1), *st);
s->linkTo(staff);
p->staves()->append(s);
pscore->staves().append(s);
pscore->appendStaff(s);
stavesMap.append(staff->idx());
for (int i = staff->idx() * VOICES, j = 0; i < staff->idx() * VOICES + VOICES; i++, j++) {

View file

@ -788,8 +788,7 @@ void PowerTab::addToScore(ptSection& sec)
//int lastStaff = sec.staffMap.back() + 1;
for (int i = 0; i < staves; ++i) {
Part* part = new Part(score);
Staff* s = new Staff(score);
s->setPart(part);
Staff* s = createStaff(score, part);
part->insertStaff(s, -1);
auto info = &curTrack->infos[i];
std::string ss = info->name;
@ -805,7 +804,7 @@ void PowerTab::addToScore(ptSection& sec)
part->setMidiProgram(info->instrument);
score->staves().push_back(s);
score->appendStaff(s);
score->appendPart(part);
}
}
@ -1308,14 +1307,12 @@ Score::FileError PowerTab::read()
Staff* staff = part->staves()->front();
Staff* s = new Staff(pscore);
s->setPart(p);
Staff* s = createStaff(score, p);
const StaffType* st = staff->staffType(Fraction(0, 1));
s->setStaffType(Fraction(0, 1), *st);
s->linkTo(staff);
p->staves()->append(s);
pscore->staves().append(s);
pscore->appendStaff(s);
stavesMap.append(staff->idx());
for (int i = staff->idx() * VOICES, j = 0; i < staff->idx() * VOICES + VOICES; i++, j++) {
tracks.insert(i, j);

View file

@ -681,10 +681,9 @@ bool MuseData::read(const QString& name)
Part* mpart = new Part(score);
int staves = countStaves(part);
for (int i = 0; i < staves; ++i) {
Staff* staff = new Staff(score);
staff->setPart(mpart);
mpart->insertStaff(staff, i);
score->staves().push_back(staff);
Staff* staff = createStaff(score, mpart);
score->appendStaff(staff);
if ((staves == 2) && (i == 0)) {
staff->setBracketType(0, BracketType::BRACE);
staff->setBracketSpan(0, 2);

View file

@ -1712,13 +1712,9 @@ static void createPart(Score* score, const QString& id, PartMap& pm)
{
Part* part = new Part(score);
pm.insert(id, part);
part->setId(id);
score->appendPart(part);
Staff* staff = new Staff(score);
staff->setPart(part);
part->staves()->push_back(staff);
score->staves().push_back(staff);
// TODO TBD tuplets.resize(VOICES); // part now contains one staff, thus VOICES voices
Staff* staff = createStaff(score, part);
score->appendStaff(staff);
}
//---------------------------------------------------------

View file

@ -312,11 +312,8 @@ void OveToMScore::createStructure()
for (int j = 0; j < partStaffCount; ++j) {
//ovebase::Track* track = m_ove->getTrack(i, j);
Staff* staff = new Staff(m_score);
staff->setPart(part);
part->staves()->push_back(staff);
m_score->staves().push_back(staff);
Staff* staff = createStaff(m_score, part);
m_score->appendStaff(staff);
}
m_score->appendPart(part);

View file

@ -35,13 +35,13 @@ mu::RetVal<PartInstrumentListScoreOrder> SelectInstrumentsScenario::selectInstru
return selectInstruments(params);
}
mu::RetVal<Instrument> SelectInstrumentsScenario::selectInstrument(const std::string& currentInstrumentId) const
mu::RetVal<Instrument> SelectInstrumentsScenario::selectInstrument(const InstrumentKey& currentInstrumentKey) const
{
RetVal<Instrument> result;
QStringList params {
"canSelectMultipleInstruments=false",
"currentInstrumentId=" + QString::fromStdString(currentInstrumentId)
"currentInstrumentId=" + currentInstrumentKey.instrumentId.toQString()
};
RetVal<PartInstrumentListScoreOrder> selectedInstruments = selectInstruments(params);
@ -101,18 +101,18 @@ INotationPartsPtr SelectInstrumentsScenario::notationParts() const
return notation->parts();
}
IDList SelectInstrumentsScenario::partsIds() const
QStringList SelectInstrumentsScenario::partsIds() const
{
auto _notationParts = notationParts();
if (!_notationParts) {
return IDList();
return QStringList();
}
async::NotifyList<const Part*> parts = _notationParts->partList();
IDList result;
QStringList result;
for (const Part* part: parts) {
result << part->id();
result << ID(part->id()).toQString();
}
return result;

View file

@ -36,13 +36,14 @@ class SelectInstrumentsScenario : public notation::ISelectInstrumentsScenario
public:
RetVal<notation::PartInstrumentListScoreOrder> selectInstruments(SelectInstrumentsMode mode = SelectInstrumentsMode::None) const
override;
RetVal<notation::Instrument> selectInstrument(const std::string& currentInstrumentId = "") const override;
RetVal<notation::Instrument> selectInstrument(const notation::InstrumentKey& currentInstrumentId = notation::InstrumentKey()) const
override;
private:
RetVal<notation::PartInstrumentListScoreOrder> selectInstruments(const QStringList& params) const;
notation::INotationPartsPtr notationParts() const;
notation::IDList partsIds() const;
QStringList partsIds() const;
notation::ScoreOrder scoreOrder() const;
};
}

View file

@ -360,7 +360,7 @@ Item {
popup = popupLoader.createPopup(instrumentSettingsComp, this)
item["partId"] = model.itemRole.id()
item["partId"] = model.itemRole.id
item["partName"] = model.itemRole.title
item["instrumentId"] = model.itemRole.instrumentId()
item["instrumentName"] = model.itemRole.instrumentName()
@ -370,7 +370,7 @@ Item {
popup = popupLoader.createPopup(staffSettingsComp, this)
item["staffId"] = model.itemRole.id()
item["staffId"] = model.itemRole.id
item["isSmall"] = model.itemRole.isSmall()
item["cutawayEnabled"] = model.itemRole.cutawayEnabled()
item["type"] = model.itemRole.staffType()

View file

@ -53,11 +53,16 @@ void AbstractInstrumentsPanelTreeItem::appendNewItem()
{
}
QString AbstractInstrumentsPanelTreeItem::id() const
mu::ID AbstractInstrumentsPanelTreeItem::id() const
{
return m_id;
}
QString AbstractInstrumentsPanelTreeItem::idStr() const
{
return m_id.toQString();
}
bool AbstractInstrumentsPanelTreeItem::canChangeVisibility() const
{
return m_canChangeVisibility;
@ -105,7 +110,7 @@ bool AbstractInstrumentsPanelTreeItem::isEmpty() const
return m_children.isEmpty();
}
AbstractInstrumentsPanelTreeItem* AbstractInstrumentsPanelTreeItem::childAtId(const QString& id) const
AbstractInstrumentsPanelTreeItem* AbstractInstrumentsPanelTreeItem::childAtId(const ID& id) const
{
for (AbstractInstrumentsPanelTreeItem* item: m_children) {
if (item->id() == id) {
@ -244,7 +249,7 @@ void AbstractInstrumentsPanelTreeItem::setIsVisible(bool isVisible)
}
}
void AbstractInstrumentsPanelTreeItem::setId(const QString& id)
void AbstractInstrumentsPanelTreeItem::setId(const ID& id)
{
m_id = id;
}

View file

@ -36,6 +36,7 @@ class AbstractInstrumentsPanelTreeItem : public QObject
{
Q_OBJECT
Q_PROPERTY(QString id READ idStr CONSTANT)
Q_PROPERTY(QString title READ title WRITE setTitle NOTIFY titleChanged)
Q_PROPERTY(int type READ type NOTIFY typeChanged)
Q_PROPERTY(bool canChangeVisibility READ canChangeVisibility NOTIFY canChangeVisibilityChanged)
@ -50,8 +51,8 @@ public:
Q_INVOKABLE virtual bool canAcceptDrop(const int type) const;
Q_INVOKABLE virtual void appendNewItem();
Q_INVOKABLE QString id() const;
ID id() const;
QString idStr() const;
QString title() const;
int type() const;
bool isVisible() const;
@ -66,7 +67,7 @@ public:
QList<AbstractInstrumentsPanelTreeItem*> childrenItems() const;
bool isEmpty() const;
AbstractInstrumentsPanelTreeItem* childAtId(const QString& id) const;
AbstractInstrumentsPanelTreeItem* childAtId(const ID& id) const;
AbstractInstrumentsPanelTreeItem* childAtRow(const int row) const;
void appendChild(AbstractInstrumentsPanelTreeItem* child);
@ -84,7 +85,7 @@ public slots:
void setType(InstrumentsTreeItemType::ItemType type);
void setTitle(QString title);
void setIsVisible(bool isVisible);
void setId(const QString& id);
void setId(const ID& id);
signals:
void typeChanged(InstrumentsTreeItemType::ItemType type);
@ -101,7 +102,7 @@ private:
QList<AbstractInstrumentsPanelTreeItem*> m_children;
AbstractInstrumentsPanelTreeItem* m_parent = nullptr;
QString m_id;
ID m_id;
QString m_title;
InstrumentsTreeItemType::ItemType m_type = InstrumentsTreeItemType::ItemType::UNDEFINED;
bool m_isVisible = false;

View file

@ -37,6 +37,17 @@ static const QString CONFIG_KEY("config");
static const QString SOLOIST_KEY("isSoloist");
static const QString IS_EXISTING_PART_KEY("isExistingPart");
static mu::IDList parseIdList(const QString& str)
{
mu::IDList result;
for (const QString& idStr : str.split(',')) {
result.push_back(mu::ID(idStr));
}
return result;
}
InstrumentListModel::InstrumentListModel(QObject* parent)
: QObject(parent)
{
@ -59,7 +70,7 @@ void InstrumentListModel::load(bool canSelectMultipleInstruments, const QString&
m_canSelectMultipleInstruments = canSelectMultipleInstruments;
setInstrumentsMeta(instrumentsMeta.val);
initSelectedInstruments(selectedPartIds.split(','));
initSelectedInstruments(parseIdList(selectedPartIds));
if (!currentInstrumentId.isEmpty()) {
Instrument instrument = instrumentById(currentInstrumentId);
@ -78,8 +89,8 @@ void InstrumentListModel::initSelectedInstruments(const IDList& selectedPartIds)
auto parts = _notationParts->partList();
for (const ID& partId: selectedPartIds) {
auto compareId = [partId](auto p) {
return p->id() == partId;
auto compareId = [partId](const Part* part) {
return ID(part->id()) == partId;
};
auto pi = find_if(begin(parts), end(parts), compareId);
@ -91,11 +102,11 @@ void InstrumentListModel::initSelectedInstruments(const IDList& selectedPartIds)
SelectedInstrumentInfo info;
info.id = partId;
info.id = partId.toQString();
info.isExistingPart = true;
info.name = part->partName();
info.isSoloist = part->soloist();
info.familyId = part->familyId();
info.familyCode = part->familyId();
info.config = Instrument();
m_selectedInstruments << info;
@ -304,7 +315,7 @@ void InstrumentListModel::selectInstrument(const QString& instrumentName, const
info.isSoloist = false;
info.id = suitedInstrument.templateId;
info.name = formatInstrumentTitle(suitedInstrument);
info.familyId = suitedInstrument.familyId;
info.familyCode = suitedInstrument.familyId;
info.config = suitedInstrument;
if (!m_canSelectMultipleInstruments) {
@ -469,8 +480,7 @@ int InstrumentListModel::sortInstrumentsIndex(const SelectedInstrumentInfo& info
};
ScoreOrder order = m_scoreOrders[m_selectedScoreOrderIndex].info;
const QString family = order.instrumentMap.contains(info.id) ? order.instrumentMap[info.id].id : info.familyId;
QString family = order.instrumentMap.contains(info.id) ? order.instrumentMap[info.id].id : info.familyCode;
int index = order.groups.size();
Priority priority = Priority::Undefined;

View file

@ -90,7 +90,7 @@ private:
{
QString id;
QString name;
QString familyId;
QString familyCode;
bool isSoloist = false;
bool isExistingPart = false;
notation::Instrument config;
@ -107,7 +107,7 @@ private:
bool operator==(const ScoreOrderInfo& orderInfo) const { return id == orderInfo.id; }
};
void initSelectedInstruments(const notation::IDList& selectedPartIds);
void initSelectedInstruments(const IDList& selectedPartIds);
notation::INotationPartsPtr notationParts() const;
void initScoreOrders(const QString& currentId);

View file

@ -36,8 +36,8 @@ void InstrumentSettingsModel::load(const QVariant& instrument)
{
QVariantMap map = instrument.toMap();
m_instrumentKey.partId = map["partId"].toString();
m_instrumentKey.instrumentId = map["instrumentId"].toString();
m_instrumentKey.partId = ID(map["partId"]);
m_instrumentKey.instrumentId = ID(map["instrumentId"]);
m_partName = map["partName"].toString();
m_instrumentName = map["instrumentName"].toString();
m_instrumentAbbreviature = map["abbreviature"].toString();
@ -51,7 +51,7 @@ void InstrumentSettingsModel::replaceInstrument()
return;
}
RetVal<Instrument> selectedInstrument = selectInstrumentsScenario()->selectInstrument(m_instrumentKey.instrumentId.toStdString());
RetVal<Instrument> selectedInstrument = selectInstrumentsScenario()->selectInstrument(m_instrumentKey);
if (!selectedInstrument.ret) {
LOGE() << selectedInstrument.ret.toString();
return;

View file

@ -131,17 +131,6 @@ void InstrumentsPanelTreeModel::load()
emit isAddingAvailableChanged(true);
}
IDList InstrumentsPanelTreeModel::currentNotationPartIdList() const
{
IDList result;
for (const Part* part : m_notation->parts()->partList()) {
result << part->id();
}
return result;
}
void InstrumentsPanelTreeModel::selectRow(const QModelIndex& rowIndex)
{
m_selectionModel->select(rowIndex);
@ -500,7 +489,7 @@ AbstractInstrumentsPanelTreeItem* InstrumentsPanelTreeModel::loadPart(const Part
TRACEFUNC;
auto partItem = buildPartItem(part);
QString partId = part->id();
ID partId = part->id();
async::NotifyList<const Staff*> staves = m_masterNotation->parts()->staffList(partId);
@ -574,8 +563,7 @@ AbstractInstrumentsPanelTreeItem* InstrumentsPanelTreeModel::buildPartItem(const
void InstrumentsPanelTreeModel::updatePartItem(PartTreeItem* item, const Part* part)
{
IDList notationPartIdList = currentNotationPartIdList();
bool visible = part->show() && notationPartIdList.contains(part->id());
bool visible = part->show() && m_notation->parts()->partExists(part->id());
item->setId(part->id());
item->setTitle(part->partName().isEmpty() ? part->instrument()->name() : part->partName());
@ -593,7 +581,7 @@ AbstractInstrumentsPanelTreeItem* InstrumentsPanelTreeModel::buildStaffItem(cons
return result;
}
AbstractInstrumentsPanelTreeItem* InstrumentsPanelTreeModel::buildAddStaffControlItem(const QString& partId)
AbstractInstrumentsPanelTreeItem* InstrumentsPanelTreeModel::buildAddStaffControlItem(const ID& partId)
{
auto result = new StaffControlTreeItem(m_masterNotation, m_notation, this);
result->setTitle(qtrc("instruments", "Add staff"));

View file

@ -117,8 +117,6 @@ private:
bool removeRows(int row, int count, const QModelIndex& parent) override;
notation::IDList currentNotationPartIdList() const;
AbstractInstrumentsPanelTreeItem* loadPart(const notation::Part* part);
AbstractInstrumentsPanelTreeItem* modelIndexToItem(const QModelIndex& index) const;
@ -128,7 +126,7 @@ private:
AbstractInstrumentsPanelTreeItem* buildPartItem(const mu::notation::Part* part);
AbstractInstrumentsPanelTreeItem* buildStaffItem(const mu::notation::Staff* staff);
AbstractInstrumentsPanelTreeItem* buildAddStaffControlItem(const QString& partId);
AbstractInstrumentsPanelTreeItem* buildAddStaffControlItem(const ID& partId);
AbstractInstrumentsPanelTreeItem* m_rootItem = nullptr;
uicomponents::ItemMultiSelectionModel* m_selectionModel = nullptr;

View file

@ -93,7 +93,7 @@ void PartTreeItem::moveChildren(const int sourceRow, const int count, AbstractIn
IDList stavesIds;
for (int i = sourceRow; i < sourceRow + count; ++i) {
stavesIds << childAtRow(i)->id();
stavesIds.push_back(childAtRow(i)->id());
}
int destinationRowLast = destinationRow;
@ -115,7 +115,7 @@ void PartTreeItem::removeChildren(const int row, const int count, const bool del
IDList stavesIds;
for (int i = row; i < row + count; ++i) {
stavesIds << childAtRow(i)->id();
stavesIds.push_back(childAtRow(i)->id());
}
if (deleteChild) {

View file

@ -48,7 +48,7 @@ public:
private:
void listenVisibilityChanged();
void createAndAppendPart(const notation::ID& masterPartId);
void createAndAppendPart(const ID& masterPartId);
QString m_instrumentId;
QString m_instrumentName;

View file

@ -35,7 +35,7 @@ void RootTreeItem::moveChildren(const int sourceRow, const int count, AbstractIn
IDList partIds;
for (int i = sourceRow; i < sourceRow + count; ++i) {
partIds << childAtRow(i)->id();
partIds.push_back(childAtRow(i)->id());
}
int destinationRow_ = destinationRow;
@ -61,7 +61,7 @@ void RootTreeItem::removeChildren(const int row, const int count, const bool del
IDList partIds;
for (int i = row; i < row + count; ++i) {
partIds << childAtRow(i)->id();
partIds.push_back(childAtRow(i)->id());
}
if (deleteChild) {

View file

@ -31,7 +31,7 @@ StaffControlTreeItem::StaffControlTreeItem(IMasterNotationPtr masterNotation, IN
void StaffControlTreeItem::appendNewItem()
{
const Part* part = this->part();
const Part* part = masterNotation()->parts()->part(m_partId);
if (!part) {
return;
}
@ -44,18 +44,7 @@ void StaffControlTreeItem::appendNewItem()
masterNotation()->parts()->appendStaff(staff, m_partId);
}
const Part* StaffControlTreeItem::part() const
{
for (const Part* part : notation()->parts()->partList()) {
if (part->id() == m_partId) {
return part;
}
}
return nullptr;
}
void StaffControlTreeItem::setPartId(const QString& id)
void StaffControlTreeItem::setPartId(const ID& id)
{
m_partId = id;
}

View file

@ -36,12 +36,10 @@ public:
Q_INVOKABLE void appendNewItem() override;
void setPartId(const QString& id);
void setPartId(const ID& id);
private:
const notation::Part* part() const;
QString m_partId;
ID m_partId;
};
}

View file

@ -163,8 +163,6 @@ void StaffSettingsModel::createLinkedStaff()
}
Staff* linkedStaff = sourceStaff->clone();
linkedStaff->setId(Staff::makeId());
masterNotationParts()->appendStaff(linkedStaff, sourceStaff->part()->id());
masterNotationParts()->linkStaves(sourceStaff->id(), linkedStaff->id());
}

View file

@ -68,7 +68,7 @@ private:
notation::INotationPartsPtr notationParts() const;
notation::INotationPartsPtr masterNotationParts() const;
notation::ID m_staffId;
ID m_staffId;
bool m_isSmallStaff = false;
bool m_cutawayEnabled = false;
QList<bool> m_voicesVisibility;

View file

@ -114,15 +114,13 @@ mu::Ret MasterNotation::setupNewScore(Ms::MasterScore* score, Ms::MasterScore* t
part->setPartName(tpart->partName());
for (Ms::Staff* tstaff : *tpart->staves()) {
Ms::Staff* staff = new Ms::Staff(score);
staff->setPart(part);
Ms::Staff* staff = Ms::createStaff(score, part);
staff->init(tstaff);
if (tstaff->links() && !part->staves()->isEmpty()) {
Staff* linkedStaff = part->staves()->back();
staff->linkTo(linkedStaff);
}
part->insertStaff(staff, -1);
score->staves().append(staff);
score->appendStaff(staff);
}
score->appendPart(part);
}

View file

@ -92,7 +92,7 @@ NotifyList<const Part*> NotationParts::partList() const
NotifyList<const Staff*> NotationParts::staffList(const ID& partId) const
{
Part* part = this->partModifiable(partId);
const Part* part = this->part(partId);
if (!part) {
return NotifyList<const Staff*>();
}
@ -125,18 +125,12 @@ bool NotationParts::partExists(const ID& partId) const
Part* NotationParts::partModifiable(const ID& partId) const
{
for (Part* part: score()->parts()) {
if (part->id() == partId) {
return part;
}
}
return nullptr;
return score()->partById(partId.toUint64());
}
Staff* NotationParts::staffModifiable(const ID& staffId) const
{
return score()->staff(staffId);
return score()->staffById(staffId.toUint64());
}
std::vector<Staff*> NotationParts::staves(const IDList& stavesIds) const
@ -184,7 +178,7 @@ void NotationParts::setPartVisible(const ID& partId, bool visible)
{
TRACEFUNC;
Part* part = this->partModifiable(partId);
Part* part = partModifiable(partId);
if (part && part->show() == visible) {
return;
@ -203,14 +197,14 @@ void NotationParts::setPartName(const ID& partId, const QString& name)
{
TRACEFUNC;
Part* part = this->partModifiable(partId);
Part* part = partModifiable(partId);
if (!part || part->partName() == name) {
return;
}
startEdit();
doSetPartName(part, name);
score()->undo(new Ms::ChangePart(part, new Ms::Instrument(*part->instrument()), name));
apply();
@ -221,7 +215,7 @@ void NotationParts::setPartSharpFlat(const ID& partId, const SharpFlat& sharpFla
{
TRACEFUNC;
Part* part = this->partModifiable(partId);
Part* part = partModifiable(partId);
if (!part) {
return;
}
@ -239,7 +233,7 @@ void NotationParts::setPartTransposition(const ID& partId, const Interval& trans
{
TRACEFUNC;
Part* part = this->partModifiable(partId);
Part* part = partModifiable(partId);
if (!part) {
return;
}
@ -292,7 +286,7 @@ void NotationParts::setInstrumentName(const InstrumentKey& instrumentKey, const
{
TRACEFUNC;
Part* part = this->partModifiable(instrumentKey.partId);
Part* part = partModifiable(instrumentKey.partId);
if (!part) {
return;
}
@ -310,7 +304,7 @@ void NotationParts::setInstrumentAbbreviature(const InstrumentKey& instrumentKey
{
TRACEFUNC;
Part* part = this->partModifiable(instrumentKey.partId);
Part* part = partModifiable(instrumentKey.partId);
if (!part) {
return;
}
@ -537,6 +531,9 @@ void NotationParts::appendStaff(Staff* staff, const ID& destinationPartId)
staff->setScore(score());
staff->setPart(destinationPart);
//! NOTE: will be generated later after adding to the score
staff->setId(Ms::INVALID_ID);
insertStaff(staff, staffIndex);
setBracketsAndBarlines();
@ -552,13 +549,16 @@ void NotationParts::appendPart(Part* part)
{
TRACEFUNC;
IF_ASSERT_FAILED(part) {
return;
}
QList<Staff*> stavesCopy = *part->staves();
part->staves()->clear();
part->clearStaves();
startEdit();
int partIndex = score()->parts().size();
score()->parts().insert(partIndex, part);
score()->appendPart(part);
if (score()->excerpt()) {
score()->excerpt()->parts().append(part);
@ -610,7 +610,7 @@ void NotationParts::replaceInstrument(const InstrumentKey& instrumentKey, const
{
TRACEFUNC;
Part* part = this->partModifiable(instrumentKey.partId);
Part* part = partModifiable(instrumentKey.partId);
if (!part) {
return;
}
@ -627,7 +627,7 @@ void NotationParts::replaceInstrument(const InstrumentKey& instrumentKey, const
void NotationParts::replaceDrumset(const InstrumentKey& instrumentKey, const Drumset& newDrumset)
{
Part* part = this->partModifiable(instrumentKey.partId);
Part* part = partModifiable(instrumentKey.partId);
if (!part) {
return;
}
@ -724,21 +724,14 @@ void NotationParts::removeStaves(const IDList& stavesIds)
apply();
}
void NotationParts::doSetPartName(Part* part, const QString& name)
{
TRACEFUNC;
score()->undo(new Ms::ChangePart(part, new Ms::Instrument(*part->instrument()), name));
}
void NotationParts::moveParts(const IDList& sourcePartsIds, const ID& destinationPartId, InsertMode mode)
{
TRACEFUNC;
IDList partIds;
QList<ID> partIds;
for (Ms::Part* currentPart: score()->parts()) {
partIds << currentPart->id();
partIds.push_back(currentPart->id());
}
for (const ID& sourcePartId: sourcePartsIds) {
@ -749,7 +742,7 @@ void NotationParts::moveParts(const IDList& sourcePartsIds, const ID& destinatio
}
PartInstrumentList parts;
for (ID& partId: partIds) {
for (const ID& partId: partIds) {
PartInstrument pi;
pi.isExistingPart = true;
pi.partId = partId;
@ -798,11 +791,14 @@ void NotationParts::appendStaves(Part* part, const Instrument& instrument)
{
TRACEFUNC;
IF_ASSERT_FAILED(part) {
return;
}
for (int staffIndex = 0; staffIndex < instrument.staves; ++staffIndex) {
int lastStaffIndex = !score()->staves().isEmpty() ? score()->staves().last()->idx() : 0;
Staff* staff = new Staff(score());
staff->setPart(part);
Staff* staff = Ms::createStaff(score(), part);
initStaff(staff, instrument, Ms::StaffType::preset(StaffType::STANDARD), staffIndex);
if (lastStaffIndex > 0) {
@ -867,15 +863,15 @@ void NotationParts::removeMissingParts(const PartInstrumentList& parts)
IDList partIds;
for (const PartInstrument& pi: parts) {
if (pi.isExistingPart) {
partIds << pi.partId;
partIds.push_back(pi.partId);
}
}
for (const Part* part: partList()) {
if (partIds.contains(part->id())) {
if (containsId(partIds, part->id())) {
continue;
}
partsToRemove << part->id();
partsToRemove.push_back(part->id());
}
doRemoveParts(partsToRemove);
@ -898,9 +894,8 @@ void NotationParts::appendNewParts(const PartInstrumentList& parts)
continue;
}
Part* part = new Part(score());
const Instrument& instrument = pi.instrument;
Part* part = new Part(score());
part->setSoloist(pi.isSoloist);
part->setInstrument(InstrumentsConverter::convertInstrument(instrument));
@ -929,8 +924,10 @@ void NotationParts::updateSoloist(const PartInstrumentList& parts)
TRACEFUNC;
for (const PartInstrument& pi: parts) {
if (pi.isExistingPart && (pi.isSoloist != partModifiable(pi.partId)->soloist())) {
score()->undo(new Ms::SetSoloist(partModifiable(pi.partId), pi.isSoloist));
Part* part = partModifiable(pi.partId);
if (pi.isExistingPart && (pi.isSoloist != part->soloist())) {
score()->undo(new Ms::SetSoloist(part, pi.isSoloist));
}
}
}
@ -999,7 +996,7 @@ void NotationParts::setBracketsAndBarlines()
score()->setBracketsAndBarlines();
}
void NotationParts::notifyAboutPartChanged(Part* part) const
void NotationParts::notifyAboutPartChanged(const Part* part) const
{
IF_ASSERT_FAILED(part) {
return;
@ -1008,7 +1005,7 @@ void NotationParts::notifyAboutPartChanged(Part* part) const
m_partChangedNotifier->itemChanged(part);
}
void NotationParts::notifyAboutPartAdded(Part* part) const
void NotationParts::notifyAboutPartAdded(const Part* part) const
{
IF_ASSERT_FAILED(part) {
return;
@ -1017,7 +1014,7 @@ void NotationParts::notifyAboutPartAdded(Part* part) const
m_partChangedNotifier->itemAdded(part);
}
void NotationParts::notifyAboutPartRemoved(Part* part) const
void NotationParts::notifyAboutPartRemoved(const Part* part) const
{
IF_ASSERT_FAILED(part) {
return;
@ -1026,7 +1023,7 @@ void NotationParts::notifyAboutPartRemoved(Part* part) const
m_partChangedNotifier->itemRemoved(part);
}
void NotationParts::notifyAboutStaffChanged(Staff* staff) const
void NotationParts::notifyAboutStaffChanged(const Staff* staff) const
{
IF_ASSERT_FAILED(staff && staff->part()) {
return;
@ -1039,7 +1036,7 @@ void NotationParts::notifyAboutStaffChanged(Staff* staff) const
}
}
void NotationParts::notifyAboutStaffAdded(Staff* staff, const ID& partId) const
void NotationParts::notifyAboutStaffAdded(const Staff* staff, const ID& partId) const
{
IF_ASSERT_FAILED(staff) {
return;
@ -1052,7 +1049,7 @@ void NotationParts::notifyAboutStaffAdded(Staff* staff, const ID& partId) const
}
}
void NotationParts::notifyAboutStaffRemoved(Staff* staff) const
void NotationParts::notifyAboutStaffRemoved(const Staff* staff) const
{
IF_ASSERT_FAILED(staff) {
return;

View file

@ -87,7 +87,6 @@ private:
void doSetStaffVisible(Staff* staff, bool visible);
void doSetStaffVoiceVisible(Staff* staff, int voiceIndex, bool visible);
void doRemoveParts(const IDList& partsIds);
void doSetPartName(Part* part, const QString& name);
Part* partModifiable(const ID& partId) const;
Staff* staffModifiable(const ID& staffId) const;
@ -106,12 +105,12 @@ private:
void setBracketsAndBarlines();
void notifyAboutPartChanged(Part* part) const;
void notifyAboutPartAdded(Part* part) const;
void notifyAboutPartRemoved(Part* part) const;
void notifyAboutStaffChanged(Staff* staff) const;
void notifyAboutStaffAdded(Staff* staff, const ID& partId) const;
void notifyAboutStaffRemoved(Staff* staff) const;
void notifyAboutPartChanged(const Part* part) const;
void notifyAboutPartAdded(const Part* part) const;
void notifyAboutPartRemoved(const Part* part) const;
void notifyAboutStaffChanged(const Staff* staff) const;
void notifyAboutStaffAdded(const Staff* staff, const ID& partId) const;
void notifyAboutStaffRemoved(const Staff* staff) const;
async::ChangedNotifier<const Staff*>* staffChangedNotifier(const ID& partId) const;
IGetScore* m_getScore = nullptr;

View file

@ -178,17 +178,17 @@ void NotationPlayback::load()
m_instrumentsMidiData.clear();
for (const Part* part : m_notationParts->partList()) {
m_instrumentsMidiData.insert({ part->id().toStdString(), buildMidiData(part) });
m_instrumentsMidiData.insert({ std::to_string(part->id()), buildMidiData(part) });
}
m_notationParts->partList().onItemAdded(this, [this](const Part* part) {
InstrumentTrackId id = part->id().toStdString();
InstrumentTrackId id = std::to_string(part->id());
m_instrumentsMidiData.insert({ id, buildMidiData(part) });
m_instrumentTrackAdded.send(std::move(id));
});
m_notationParts->partList().onItemRemoved(this, [this](const Part* part) {
InstrumentTrackId id = part->id().toStdString();
InstrumentTrackId id = std::to_string(part->id());
m_instrumentsMidiData.erase(id);
m_instrumentTrackRemoved.send(std::move(id));
});
@ -462,7 +462,7 @@ Ret NotationPlayback::playNoteMidiData(const Ms::Note* note) const
const Ms::Instrument* instr = masterNote->part()->instrument(tick);
channel_t midiChannel = instr->channel(masterNote->subchannel())->channel();
MidiData midiData = instrumentMidiData(masterNote->part()->id().toStdString());
MidiData midiData = instrumentMidiData(std::to_string(masterNote->part()->id()));
Events events = m_midiEventsProvider->retrieveEventsForElement(masterNote, midiChannel);
midiData.stream.backgroundStream.send(std::move(events), Ms::MScore::defaultPlayDuration* 2);
@ -477,7 +477,7 @@ Ret NotationPlayback::playChordMidiData(const Ms::Chord* chord) const
Ms::Instrument* instr = part->instrument(tick);
channel_t midiChannel = instr->channel(chord->notes()[0]->subchannel())->channel();
MidiData midiData = instrumentMidiData(part->id().toStdString());
MidiData midiData = instrumentMidiData(std::to_string(part->id()));
Events events = m_midiEventsProvider->retrieveEventsForElement(chord, midiChannel);
midiData.stream.backgroundStream.send(std::move(events), Ms::MScore::defaultPlayDuration* 2);
@ -502,7 +502,7 @@ Ret NotationPlayback::playHarmonyMidiData(const Ms::Harmony* harmony) const
}
channel_t midiChannel = hChannel->channel();
MidiData midiData = instrumentMidiData(harmony->part()->id().toStdString());
MidiData midiData = instrumentMidiData(std::to_string(harmony->part()->id()));
Events events = m_midiEventsProvider->retrieveEventsForElement(harmony, midiChannel);
midiData.stream.backgroundStream.send(std::move(events), Ms::MScore::defaultPlayDuration* 2);

View file

@ -105,7 +105,7 @@ private:
async::Channel<int> m_playPositionTickChanged;
ValCh<LoopBoundaries> m_loopBoundaries;
std::unordered_map<std::string, midi::MidiData> m_instrumentsMidiData;
std::unordered_map<InstrumentTrackId, midi::MidiData> m_instrumentsMidiData;
async::Channel<InstrumentTrackId> m_instrumentTrackRemoved;
async::Channel<InstrumentTrackId> m_instrumentTrackAdded;
};

View file

@ -39,9 +39,9 @@ public:
ShowCurrentInstruments
};
virtual RetVal<notation::PartInstrumentListScoreOrder> selectInstruments(SelectInstrumentsMode mode = SelectInstrumentsMode::None) const
virtual RetVal<PartInstrumentListScoreOrder> selectInstruments(SelectInstrumentsMode mode = SelectInstrumentsMode::None) const
= 0;
virtual RetVal<notation::Instrument> selectInstrument(const std::string& currentInstrumentId = "") const = 0;
virtual RetVal<Instrument> selectInstrument(const InstrumentKey& currentInstrumentKey = InstrumentKey()) const = 0;
};
}

View file

@ -27,6 +27,7 @@
#include "io/path.h"
#include "translation.h"
#include "id.h"
#include "midi/midievent.h"
#include "libmscore/element.h"
@ -121,9 +122,6 @@ using PageList = std::vector<const Page*>;
using StaffList = QList<const Staff*>;
using PartList = QList<const Part*>;
using ID = QString;
using IDList = QList<ID>;
enum class DragMode
{
BothXY = 0,
@ -414,7 +412,7 @@ inline QString formatInstrumentTitle(const Instrument& instrument, int instrumen
struct PartInstrument
{
QString partId;
ID partId;
Instrument instrument;
bool isExistingPart = false;

View file

@ -567,7 +567,7 @@ bool EditStaff::isInstrumentChanged()
void EditStaff::showReplaceInstrumentDialog()
{
RetVal<Instrument> selectedInstrument = selectInstrumentsScenario()->selectInstrument(m_instrumentKey.instrumentId.toStdString());
RetVal<Instrument> selectedInstrument = selectInstrumentsScenario()->selectInstrument(m_instrumentKey);
if (!selectedInstrument.ret) {
LOGE() << selectedInstrument.ret.toString();
return;

View file

@ -147,7 +147,7 @@ EditDrumsetDialog::EditDrumsetDialog(QWidget* parent)
NoteInputState state = m_notation->interaction()->noteInput()->state();
const Staff* staff = m_notation->elements()->msScore()->staff(track2staff(state.currentTrack));
m_instrumentKey.instrumentId = staff ? staff->part()->instrumentId() : QString();
m_instrumentKey.partId = staff ? staff->part()->id() : QString();
m_instrumentKey.partId = staff ? staff->part()->id() : ID();
m_editedDrumset = state.drumset ? *state.drumset : Drumset();
}