remove code duplication: LinkedStaves
This commit is contained in:
parent
020927213f
commit
903817537c
22 changed files with 193 additions and 159 deletions
|
@ -222,7 +222,7 @@ Chord::Chord(const Chord& c, bool link)
|
|||
: ChordRest(c, link)
|
||||
{
|
||||
if (link)
|
||||
score()->undo(new Link(const_cast<Chord*>(&c), this));
|
||||
score()->undo(new Link(this, const_cast<Chord*>(&c)));
|
||||
_ledgerLines = 0;
|
||||
|
||||
for (Note* onote : c._notes) {
|
||||
|
@ -265,12 +265,12 @@ Chord::Chord(const Chord& c, bool link)
|
|||
Arpeggio* a = new Arpeggio(*(c._arpeggio));
|
||||
add(a);
|
||||
if (link)
|
||||
score()->undo(new Link(const_cast<Arpeggio*>(c._arpeggio), a));
|
||||
score()->undo(new Link(a, const_cast<Arpeggio*>(c._arpeggio)));
|
||||
}
|
||||
if (c._tremolo) {
|
||||
Tremolo* t = new Tremolo(*(c._tremolo));
|
||||
if (link) {
|
||||
score()->undo(new Link(const_cast<Tremolo*>(c._tremolo), t));
|
||||
score()->undo(new Link(t, const_cast<Tremolo*>(c._tremolo)));
|
||||
if (c._tremolo->twoNotes())
|
||||
t->setChords(0, 0);
|
||||
}
|
||||
|
|
|
@ -157,7 +157,10 @@ void Excerpt::createExcerpt(Excerpt* excerpt)
|
|||
s->setPart(p);
|
||||
s->setStaffType(0, staff->staffType(0)); // TODO
|
||||
s->setDefaultClefType(staff->defaultClefType());
|
||||
score->undo(new LinkStaff(s, staff));
|
||||
// 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);
|
||||
srcStaves.append(staff->idx());
|
||||
|
@ -169,13 +172,15 @@ void Excerpt::createExcerpt(Excerpt* excerpt)
|
|||
if (excerpt->tracks().isEmpty()) {
|
||||
QMultiMap<int, int> tracks;
|
||||
for (Staff* s : score->staves()) {
|
||||
LinkedStaves* ls = s->linkedStaves();
|
||||
const LinkedElements* ls = s->links();
|
||||
if (ls == 0)
|
||||
continue;
|
||||
for (Staff* ps : ls->staves()) {
|
||||
for (auto le : *ls) {
|
||||
Staff* ps = toStaff(le);
|
||||
if (ps->primaryStaff()) {
|
||||
for (int i = 0; i < VOICES; i++)
|
||||
for (int i = 0; i < VOICES; i++) {
|
||||
tracks.insert(ps->idx() * VOICES + i % VOICES, s->idx() * VOICES + i % VOICES);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -284,8 +289,9 @@ void MasterScore::deleteExcerpt(Excerpt* excerpt)
|
|||
for (Staff* s : partScore->staves()) {
|
||||
Staff* staff = nullptr;
|
||||
// find staff in the main score
|
||||
if (s->linkedStaves()) {
|
||||
for (Staff* s2 : s->linkedStaves()->staves()) {
|
||||
if (s->links()) {
|
||||
for (auto le : *s->links()) {
|
||||
Staff* s2 = toStaff(le);
|
||||
if ((s2->score() == this) && s2->primaryStaff()) {
|
||||
staff = s2;
|
||||
break;
|
||||
|
@ -315,7 +321,7 @@ void MasterScore::deleteExcerpt(Excerpt* excerpt)
|
|||
}
|
||||
}
|
||||
// unlink the staff
|
||||
undo(new UnlinkStaff(staff, s));
|
||||
undo(new Unlink(staff));
|
||||
}
|
||||
}
|
||||
undo(new RemoveExcerpt(excerpt));
|
||||
|
@ -801,7 +807,7 @@ void Excerpt::cloneStaff(Staff* srcStaff, Staff* dstStaff)
|
|||
Score* score = srcStaff->score();
|
||||
TieMap tieMap;
|
||||
|
||||
score->undo(new LinkStaff(dstStaff, srcStaff));
|
||||
score->undo(new Link(dstStaff, srcStaff));
|
||||
|
||||
int srcStaffIdx = srcStaff->idx();
|
||||
int dstStaffIdx = dstStaff->idx();
|
||||
|
|
|
@ -1101,10 +1101,10 @@ void Measure::cmdAddStaves(int sStaff, int eStaff, bool createRest)
|
|||
QList<int> sl;
|
||||
for (int staffIdx = sStaff; staffIdx < eStaff; ++staffIdx) {
|
||||
Staff* s = score()->staff(staffIdx);
|
||||
if (s->linkedStaves()) {
|
||||
if (s->links()) {
|
||||
bool alreadyInList = false;
|
||||
for (int idx : sl) {
|
||||
if (s->linkedStaves()->staves().contains(score()->staff(idx))) {
|
||||
if (s->links()->contains(score()->staff(idx))) {
|
||||
alreadyInList = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -559,7 +559,7 @@ Note::Note(const Note& n, bool link)
|
|||
: Element(n)
|
||||
{
|
||||
if (link)
|
||||
score()->undo(new Link(const_cast<Note*>(&n), this));
|
||||
score()->undo(new Link(this, const_cast<Note*>(&n)));
|
||||
_subchannel = n._subchannel;
|
||||
_line = n._line;
|
||||
_fret = n._fret;
|
||||
|
@ -599,7 +599,7 @@ Note::Note(const Note& n, bool link)
|
|||
Element* ce = e->clone();
|
||||
add(ce);
|
||||
if (link)
|
||||
score()->undo(new Link(const_cast<Element*>(e), ce));
|
||||
score()->undo(new Link(ce, const_cast<Element*>(e)));
|
||||
}
|
||||
|
||||
_playEvents = n._playEvents;
|
||||
|
@ -1363,7 +1363,7 @@ bool Note::readProperties(XmlReader& e)
|
|||
if (id != -1 &&
|
||||
// DISABLE if pasting into a staff with linked staves
|
||||
// because the glissando is not properly cloned into the linked staves
|
||||
(!e.pasteMode() || !staff()->linkedStaves() || staff()->linkedStaves()->empty())) {
|
||||
(!e.pasteMode() || !staff()->links() || staff()->links()->empty())) {
|
||||
Spanner* placeholder = new TextLine(score());
|
||||
placeholder->setAnchor(Spanner::Anchor::NOTE);
|
||||
placeholder->setEndElement(this);
|
||||
|
@ -1399,7 +1399,7 @@ bool Note::readProperties(XmlReader& e)
|
|||
sp->read(e);
|
||||
// DISABLE pasting of glissandi into staves with other lionked staves
|
||||
// because the glissando is not properly cloned into the linked staves
|
||||
if (e.pasteMode() && staff()->linkedStaves() && !staff()->linkedStaves()->empty()) {
|
||||
if (e.pasteMode() && staff()->links() && !staff()->links()->empty()) {
|
||||
e.removeSpanner(sp); // read() added the element to the XMLReader: remove it
|
||||
delete sp;
|
||||
}
|
||||
|
|
|
@ -675,9 +675,10 @@ bool ScoreRange::write(Score* score, int tick) const
|
|||
// clone staff if appropriate after all voices have been copied
|
||||
int staffIdx = track / VOICES;
|
||||
Staff* ostaff = score->staff(staffIdx);
|
||||
LinkedStaves* linkedStaves = ostaff->linkedStaves();
|
||||
const LinkedElements* linkedStaves = ostaff->links();
|
||||
if (linkedStaves) {
|
||||
for (Staff* nstaff : linkedStaves->staves()) {
|
||||
for (auto le : *linkedStaves) {
|
||||
Staff* nstaff = toStaff(le);
|
||||
if (nstaff == ostaff)
|
||||
continue;
|
||||
Excerpt::cloneStaff2(ostaff, nstaff, tick, tick + dl->duration().ticks());
|
||||
|
|
|
@ -59,7 +59,7 @@ Rest::Rest(const Rest& r, bool link)
|
|||
: ChordRest(r, link)
|
||||
{
|
||||
if (link) {
|
||||
score()->undo(new Link(const_cast<Rest*>(&r), this));
|
||||
score()->undo(new Link(this, const_cast<Rest*>(&r)));
|
||||
setAutoplace(true);
|
||||
}
|
||||
_gap = r._gap;
|
||||
|
|
|
@ -1788,10 +1788,11 @@ void MasterScore::addExcerpt(Excerpt* ex)
|
|||
Score* score = ex->partScore();
|
||||
|
||||
for (Staff* s : score->staves()) {
|
||||
LinkedStaves* ls = s->linkedStaves();
|
||||
const LinkedElements* ls = s->links();
|
||||
if (ls == 0)
|
||||
continue;
|
||||
for (Staff* ps : ls->staves()) {
|
||||
for (auto le : *ls) {
|
||||
Staff* ps = toStaff(le);
|
||||
if (ps->score() == this) {
|
||||
ex->parts().append(ps->part());
|
||||
break;
|
||||
|
@ -1801,10 +1802,11 @@ void MasterScore::addExcerpt(Excerpt* ex)
|
|||
if (ex->tracks().isEmpty()) { // SHOULDN'T HAPPEN, protected in the UI
|
||||
QMultiMap<int, int> tracks;
|
||||
for (Staff* s : score->staves()) {
|
||||
LinkedStaves* ls = s->linkedStaves();
|
||||
const LinkedElements* ls = s->links();
|
||||
if (ls == 0)
|
||||
continue;
|
||||
for (Staff* ps : ls->staves()) {
|
||||
for (auto le : *ls) {
|
||||
Staff* ps = toStaff(le);
|
||||
if (ps->primaryStaff()) {
|
||||
for (int i = 0; i < VOICES; i++)
|
||||
tracks.insert(ps->idx() * VOICES + i % VOICES, s->idx() * VOICES + i % VOICES);
|
||||
|
@ -2412,16 +2414,18 @@ void Score::cmdRemoveStaff(int staffIdx)
|
|||
|
||||
// remove linked staff and measures in linked staves in excerpts
|
||||
// unlink staff in the same score
|
||||
if (s->linkedStaves()) {
|
||||
Staff* sameScoreLinkedStaff = nullptr;
|
||||
auto staves = s->linkedStaves()->staves();
|
||||
for (Staff* staff : staves) {
|
||||
|
||||
if (s->links()) {
|
||||
Staff* sameScoreLinkedStaff = 0;
|
||||
auto staves = s->links();
|
||||
for (auto le : *staves) {
|
||||
Staff* staff = toStaff(le);
|
||||
if (staff == s)
|
||||
continue;
|
||||
Score* lscore = staff->score();
|
||||
if (lscore != this) {
|
||||
lscore->undoRemoveStaff(staff);
|
||||
s->score()->undo(new UnlinkStaff(s, staff));
|
||||
s->score()->undo(new Unlink(staff));
|
||||
if (staff->part()->nstaves() == 0) {
|
||||
int pIndex = lscore->staffIdx(staff->part());
|
||||
lscore->undoRemovePart(staff->part(), pIndex);
|
||||
|
@ -2431,7 +2435,8 @@ void Score::cmdRemoveStaff(int staffIdx)
|
|||
sameScoreLinkedStaff = staff;
|
||||
}
|
||||
if (sameScoreLinkedStaff)
|
||||
s->score()->undo(new UnlinkStaff(sameScoreLinkedStaff, s)); // once should be enough
|
||||
// s->score()->undo(new Unlink(sameScoreLinkedStaff)); // once should be enough
|
||||
s->score()->undo(new Unlink(s)); // once should be enough
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3531,10 +3536,10 @@ QList<int> Score::uniqueStaves() const
|
|||
|
||||
for (int staffIdx = 0; staffIdx < nstaves(); ++staffIdx) {
|
||||
Staff* s = staff(staffIdx);
|
||||
if (s->linkedStaves()) {
|
||||
if (s->links()) {
|
||||
bool alreadyInList = false;
|
||||
for (int idx : sl) {
|
||||
if (s->linkedStaves()->staves().contains(staff(idx))) {
|
||||
if (s->links()->contains(staff(idx))) {
|
||||
alreadyInList = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -398,28 +398,28 @@ void ScoreElement::reset()
|
|||
|
||||
//---------------------------------------------------------
|
||||
// linkTo
|
||||
// link this to element
|
||||
//---------------------------------------------------------
|
||||
|
||||
void ScoreElement::linkTo(ScoreElement* element)
|
||||
{
|
||||
Q_ASSERT(element != this);
|
||||
if (!_links) {
|
||||
if (element->links()) {
|
||||
_links = element->_links;
|
||||
Q_ASSERT(_links->contains(element));
|
||||
}
|
||||
else {
|
||||
_links = new LinkedElements(score());
|
||||
_links->append(element);
|
||||
element->_links = _links;
|
||||
}
|
||||
Q_ASSERT(!_links->contains(this));
|
||||
_links->append(this);
|
||||
Q_ASSERT(!_links);
|
||||
|
||||
if (element->links()) {
|
||||
_links = element->_links;
|
||||
Q_ASSERT(_links->contains(element));
|
||||
}
|
||||
else {
|
||||
if (isStaff())
|
||||
_links = new LinkedElements(score(), -1); // dont use lid
|
||||
else
|
||||
_links = new LinkedElements(score());
|
||||
_links->append(element);
|
||||
element->_links = _links;
|
||||
}
|
||||
Q_ASSERT(!_links->contains(this));
|
||||
_links->append(this);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -428,25 +428,28 @@ void ScoreElement::linkTo(ScoreElement* element)
|
|||
|
||||
void ScoreElement::unlink()
|
||||
{
|
||||
if (_links) {
|
||||
if (!_links->contains(this)) {
|
||||
qDebug("%s: links size %d, this %p score %p", name(), _links->size(), this, score());
|
||||
for (auto e : *_links)
|
||||
printf(" %s %p score %p\n", e->name(), e, e->score());
|
||||
qFatal("list does not contain 'this'");
|
||||
}
|
||||
_links->removeOne(this);
|
||||
Q_ASSERT(_links);
|
||||
Q_ASSERT(_links->contains(this));
|
||||
_links->removeOne(this);
|
||||
|
||||
// if link list is empty, remove list
|
||||
if (_links->size() <= 1) {
|
||||
if (!_links->empty()) { // abnormal case: only "this" is in list
|
||||
_links->front()->_links = 0;
|
||||
qDebug("one element left in list");
|
||||
}
|
||||
delete _links;
|
||||
}
|
||||
_links = 0; // this element is not linked anymore
|
||||
// if link list is empty, remove list
|
||||
if (_links->size() <= 1) {
|
||||
if (!_links->empty())
|
||||
_links->front()->_links = 0;
|
||||
delete _links;
|
||||
}
|
||||
_links = 0; // this element is not linked anymore
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// isLinked
|
||||
/// return true if se is different and
|
||||
/// linked to this element
|
||||
//---------------------------------------------------------
|
||||
|
||||
bool ScoreElement::isLinked(ScoreElement* se)
|
||||
{
|
||||
return se != this && _links && _links->contains(se);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -467,7 +470,7 @@ QList<ScoreElement*> ScoreElement::linkList() const
|
|||
{
|
||||
QList<ScoreElement*> el;
|
||||
if (_links)
|
||||
el.append(*_links);
|
||||
el = *_links;
|
||||
else
|
||||
el.append(const_cast<ScoreElement*>(this));
|
||||
return el;
|
||||
|
@ -485,7 +488,8 @@ LinkedElements::LinkedElements(Score* score)
|
|||
LinkedElements::LinkedElements(Score* score, int id)
|
||||
{
|
||||
_lid = id;
|
||||
score->linkId(id); // remember used id
|
||||
if (_lid != -1)
|
||||
score->linkId(id); // remember used id
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -224,9 +224,12 @@ class ScoreElement {
|
|||
|
||||
void linkTo(ScoreElement*);
|
||||
void unlink();
|
||||
bool isLinked(ScoreElement*);
|
||||
|
||||
virtual void undoUnlink();
|
||||
int lid() const { return _links ? _links->lid() : 0; }
|
||||
const LinkedElements* links() const { return _links; }
|
||||
// const LinkedElements* links() const { return _links; }
|
||||
LinkedElements* links() const { return _links; }
|
||||
void setLinks(LinkedElements* le) { _links = le; }
|
||||
|
||||
//---------------------------------------------------
|
||||
|
|
|
@ -250,11 +250,13 @@ QString Staff::partName() const
|
|||
|
||||
Staff::~Staff()
|
||||
{
|
||||
#if 0
|
||||
if (_linkedStaves) {
|
||||
_linkedStaves->remove(this);
|
||||
if (_linkedStaves->empty())
|
||||
delete _linkedStaves;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -551,9 +553,10 @@ void Staff::write(XmlWriter& xml) const
|
|||
{
|
||||
int idx = this->idx();
|
||||
xml.stag(QString("Staff id=\"%1\"").arg(idx + 1));
|
||||
if (linkedStaves()) {
|
||||
if (links()) {
|
||||
Score* s = masterScore();
|
||||
for (Staff* staff : linkedStaves()->staves()) {
|
||||
for (auto le : *links()) {
|
||||
Staff* staff = toStaff(le);
|
||||
if ((staff->score() == s) && (staff != this))
|
||||
xml.tag("linkedTo", staff->idx() + 1);
|
||||
}
|
||||
|
@ -865,6 +868,7 @@ void Staff::setSlashStyle(int tick, bool val)
|
|||
staffType(tick)->setSlashStyle(val);
|
||||
}
|
||||
|
||||
#if 0
|
||||
//---------------------------------------------------------
|
||||
// linkTo
|
||||
//---------------------------------------------------------
|
||||
|
@ -925,24 +929,7 @@ void LinkedStaves::remove(Staff* staff)
|
|||
{
|
||||
_staves.removeOne(staff);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// isLinked
|
||||
/// return true if staff is different and
|
||||
/// linked to this staff
|
||||
//---------------------------------------------------------
|
||||
|
||||
bool Staff::isLinked(Staff* staff)
|
||||
{
|
||||
if (staff == this || !_linkedStaves)
|
||||
return false;
|
||||
|
||||
for (Staff* s : _linkedStaves->staves()) {
|
||||
if (s == staff)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------
|
||||
// primaryStaff
|
||||
|
@ -954,11 +941,12 @@ bool Staff::isLinked(Staff* staff)
|
|||
|
||||
bool Staff::primaryStaff() const
|
||||
{
|
||||
if (!_linkedStaves)
|
||||
if (!_links)
|
||||
return true;
|
||||
QList<Staff*> s;
|
||||
QList<Staff*> ss;
|
||||
foreach(Staff* staff, _linkedStaves->staves()) {
|
||||
for (auto e : *_links) {
|
||||
Staff* staff = toStaff(e);
|
||||
if (staff->score() == score()) {
|
||||
s.append(staff);
|
||||
if (!staff->isTabStaff(0))
|
||||
|
@ -1214,8 +1202,11 @@ void Staff::insertTime(int tick, int len)
|
|||
QList<Staff*> Staff::staffList() const
|
||||
{
|
||||
QList<Staff*> staffList;
|
||||
if (_linkedStaves)
|
||||
staffList = _linkedStaves->staves();
|
||||
if (_links) {
|
||||
for (ScoreElement* e : *_links)
|
||||
staffList.append(toStaff(e));
|
||||
// staffList = _linkedStaves->staves();
|
||||
}
|
||||
else
|
||||
staffList.append(const_cast<Staff*>(this));
|
||||
return staffList;
|
||||
|
|
|
@ -45,6 +45,7 @@ class BracketItem;
|
|||
|
||||
enum class Key;
|
||||
|
||||
#if 0
|
||||
//---------------------------------------------------------
|
||||
// LinkedStaves
|
||||
//---------------------------------------------------------
|
||||
|
@ -60,6 +61,7 @@ class LinkedStaves {
|
|||
void remove(Staff*);
|
||||
bool empty() const { return _staves.empty(); }
|
||||
};
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------
|
||||
// SwingParameters
|
||||
|
@ -104,7 +106,7 @@ class Staff final : public ScoreElement {
|
|||
|
||||
StaffTypeList _staffTypeList;
|
||||
|
||||
LinkedStaves* _linkedStaves { 0 };
|
||||
// LinkedStaves* _linkedStaves { 0 };
|
||||
QMap<int,int> _channelList[VOICES];
|
||||
QMap<int,SwingParameters> _swingList;
|
||||
bool _playbackVoice[VOICES] { true, true, true, true };
|
||||
|
@ -233,12 +235,12 @@ class Staff final : public ScoreElement {
|
|||
int pitchOffset(int tick) { return _pitchOffsets.pitchOffset(tick); }
|
||||
void updateOttava();
|
||||
|
||||
LinkedStaves* linkedStaves() const { return _linkedStaves; }
|
||||
void setLinkedStaves(LinkedStaves* l) { _linkedStaves = l; }
|
||||
// LinkedStaves* linkedStaves() const { return _linkedStaves; }
|
||||
// void setLinkedStaves(LinkedStaves* l) { _linkedStaves = l; }
|
||||
QList<Staff*> staffList() const;
|
||||
void linkTo(Staff* staff);
|
||||
bool isLinked(Staff* staff);
|
||||
void unlink(Staff* staff);
|
||||
// void linkTo(Staff* staff);
|
||||
// bool isLinked(Staff* staff);
|
||||
// void unlink(Staff* staff);
|
||||
bool primaryStaff() const;
|
||||
|
||||
qreal userDist() const { return _userDist; }
|
||||
|
|
|
@ -364,7 +364,7 @@ bool Score::transpose(TransposeMode mode, TransposeDirection direction, Key trKe
|
|||
continue;
|
||||
bool alreadyThere = false;
|
||||
for (Staff* s2 : sl) {
|
||||
if (s2 == s || (s2->linkedStaves() && s2->linkedStaves()->staves().contains(s))) {
|
||||
if (s2 == s || (s2->links() && s2->links()->contains(s))) {
|
||||
alreadyThere = true;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2060,45 +2060,62 @@ void ChangeNoteEvent::flip(EditData*)
|
|||
// LinkUnlink
|
||||
//---------------------------------------------------------
|
||||
|
||||
void LinkUnlink::doLink()
|
||||
LinkUnlink::~LinkUnlink()
|
||||
{
|
||||
Q_ASSERT(le);
|
||||
e->linkTo(le);
|
||||
if (le && mustDelete)
|
||||
delete le;
|
||||
}
|
||||
|
||||
void LinkUnlink::doUnlink()
|
||||
void LinkUnlink::link()
|
||||
{
|
||||
// find appropriate target element to unlink
|
||||
// use current le if valid; pick something else in link list if not but that shouldn't happen!
|
||||
if (le->size() == 1)
|
||||
le->front()->setLinks(le);
|
||||
|
||||
const LinkedElements* l = e->links();
|
||||
if (l) {
|
||||
// don't use current le if null or if it is no longer linked (shouldn't happen)
|
||||
if (le && !l->contains(le)) {
|
||||
le = nullptr;
|
||||
qWarning("current le %p no longer linked", le);
|
||||
}
|
||||
if (!le) {
|
||||
// shouldn't happen
|
||||
// find something other than current element (e) in link list, so we can link if asked to redo
|
||||
for (ScoreElement* ee : *l) {
|
||||
if (e != ee) {
|
||||
le = ee;
|
||||
break;
|
||||
}
|
||||
}
|
||||
qDebug("current le was null... we picked a new one le %p", le);
|
||||
}
|
||||
le->append(e);
|
||||
e->setLinks(le);
|
||||
}
|
||||
|
||||
void LinkUnlink::unlink()
|
||||
{
|
||||
Q_ASSERT(le->contains(e));
|
||||
le->removeOne(e);
|
||||
if (le->size() == 1) {
|
||||
le->front()->setLinks(0);
|
||||
mustDelete = true;
|
||||
}
|
||||
else
|
||||
qWarning("current element %p(%s) has no links", e, e->name());
|
||||
|
||||
if (e)
|
||||
e->unlink();
|
||||
else
|
||||
qWarning("nothing found to unlink");
|
||||
e->setLinks(0);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Link
|
||||
// link e1 to e2
|
||||
//---------------------------------------------------------
|
||||
|
||||
Link::Link(ScoreElement* e1, ScoreElement* e2)
|
||||
{
|
||||
Q_ASSERT(e1->links() == 0);
|
||||
le = e2->links();
|
||||
if (!le) {
|
||||
if (e1->isStaff())
|
||||
le = new LinkedElements(e1->score(), -1);
|
||||
else
|
||||
le = new LinkedElements(e1->score());
|
||||
le->push_back(e2);
|
||||
}
|
||||
e = e1;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Unlink
|
||||
//---------------------------------------------------------
|
||||
|
||||
Unlink::Unlink(ScoreElement* _e)
|
||||
{
|
||||
e = _e;
|
||||
le = e->links();
|
||||
Q_ASSERT(le);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ChangeStartEndSpanner::flip
|
||||
|
|
|
@ -1118,15 +1118,18 @@ class ChangeNoteEvent : public UndoCommand {
|
|||
//---------------------------------------------------------
|
||||
|
||||
class LinkUnlink : public UndoCommand {
|
||||
ScoreElement* e;
|
||||
ScoreElement* le;
|
||||
bool mustDelete { false };
|
||||
|
||||
protected:
|
||||
void doLink();
|
||||
void doUnlink();
|
||||
LinkedElements* le;
|
||||
ScoreElement* e;
|
||||
|
||||
void link();
|
||||
void unlink();
|
||||
|
||||
public:
|
||||
LinkUnlink(ScoreElement* _e, ScoreElement* _le) : e(_e), le(_le) {}
|
||||
LinkUnlink() {}
|
||||
~LinkUnlink();
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -1134,11 +1137,10 @@ class LinkUnlink : public UndoCommand {
|
|||
//---------------------------------------------------------
|
||||
|
||||
class Unlink : public LinkUnlink {
|
||||
|
||||
public:
|
||||
Unlink(ScoreElement* _e) : LinkUnlink(_e, 0) {}
|
||||
virtual void undo(EditData*) override { doLink(); }
|
||||
virtual void redo(EditData*) override { doUnlink(); }
|
||||
Unlink(ScoreElement*);
|
||||
virtual void undo(EditData*) override { link(); }
|
||||
virtual void redo(EditData*) override { unlink(); }
|
||||
UNDO_NAME("Unlink")
|
||||
};
|
||||
|
||||
|
@ -1147,14 +1149,14 @@ class Unlink : public LinkUnlink {
|
|||
//---------------------------------------------------------
|
||||
|
||||
class Link : public LinkUnlink {
|
||||
|
||||
public:
|
||||
Link(ScoreElement* e, ScoreElement* le) : LinkUnlink(le, e) {}
|
||||
virtual void undo(EditData*) override { doUnlink(); }
|
||||
virtual void redo(EditData*) override { doLink(); }
|
||||
Link(ScoreElement*, ScoreElement*);
|
||||
virtual void undo(EditData*) override { unlink(); }
|
||||
virtual void redo(EditData*) override { link(); }
|
||||
UNDO_NAME("Link")
|
||||
};
|
||||
|
||||
#if 0
|
||||
//---------------------------------------------------------
|
||||
// LinkStaff
|
||||
//---------------------------------------------------------
|
||||
|
@ -1185,6 +1187,7 @@ class UnlinkStaff : public UndoCommand {
|
|||
virtual void redo(EditData*) override { s1->unlink(s2); } // s2 is removed
|
||||
UNDO_NAME("UnlinkStaff")
|
||||
};
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------
|
||||
// ChangeStartEndSpanner
|
||||
|
|
|
@ -519,7 +519,7 @@ MasterScore* MuseScore::getNewFile()
|
|||
Staff* staff = new Staff(score);
|
||||
staff->setPart(part);
|
||||
staff->init(tstaff);
|
||||
if (tstaff->linkedStaves() && !part->staves()->isEmpty()) {
|
||||
if (tstaff->links() && !part->staves()->isEmpty()) {
|
||||
Staff* linkedStaff = part->staves()->back();
|
||||
staff->linkTo(linkedStaff);
|
||||
}
|
||||
|
|
|
@ -485,8 +485,9 @@ void MuseScore::editInstrList()
|
|||
masterScore->undo(new RemoveExcerpt(excerpt));
|
||||
else {
|
||||
for (Staff* s : sl) {
|
||||
LinkedStaves* sll = s->linkedStaves();
|
||||
for (Staff* ss : sll->staves())
|
||||
const LinkedElements* sll = s->links();
|
||||
for (auto le : *sll) {
|
||||
Staff* ss = toStaff(le);
|
||||
if (ss->primaryStaff()) {
|
||||
for (int i = s->idx() * VOICES; i < (s->idx() + 1) * VOICES; i++) {
|
||||
int strack = tr.key(i, -1);
|
||||
|
@ -496,6 +497,7 @@ void MuseScore::editInstrList()
|
|||
tr.insert(ss->idx() + strack % VOICES, tr.value(strack, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -462,10 +462,11 @@ void InstrumentsWidget::genPartList(Score* cs)
|
|||
sli->setClefType(s->clefType(0));
|
||||
sli->setDefaultClefType(s->defaultClefType());
|
||||
sli->setPartIdx(s->rstaff());
|
||||
const LinkedStaves* ls = s->linkedStaves();
|
||||
const LinkedElements* ls = s->links();
|
||||
bool bLinked = false;
|
||||
if (ls && !ls->empty()) {
|
||||
foreach(Staff* ps, ls->staves()) {
|
||||
for (auto le : *ls) {
|
||||
Staff* ps = toStaff(le);
|
||||
if (ps != s && ps->score() == s->score()) {
|
||||
bLinked = true;
|
||||
break;
|
||||
|
|
|
@ -303,7 +303,7 @@ void TestLinks::test4LinkedParts_94911()
|
|||
// we should have now 2 staves and 4 linked rests
|
||||
QVERIFY(score->staves().size() == 2);
|
||||
QVERIFY(nscore->staves().size() == 2);
|
||||
QVERIFY(score->staves()[0]->linkedStaves()->staves().size() == 4);
|
||||
QVERIFY(score->staves()[0]->links()->size() == 4);
|
||||
e = s->element(0);
|
||||
QVERIFY(e->type() == ElementType::REST);
|
||||
QVERIFY(e->links()->size() == 4);
|
||||
|
@ -325,7 +325,7 @@ void TestLinks::test4LinkedParts_94911()
|
|||
// we should have now 2 staves and *4* linked rest
|
||||
// no excerpt
|
||||
QVERIFY(score->staves().size() == 1);
|
||||
QVERIFY(score->staves()[0]->linkedStaves() == nullptr);
|
||||
// QVERIFY(score->staves()[0]->links() == nullptr);
|
||||
e = s->element(0);
|
||||
QVERIFY(e->isRest());
|
||||
QVERIFY(e->links() == nullptr);
|
||||
|
@ -336,7 +336,7 @@ void TestLinks::test4LinkedParts_94911()
|
|||
// we should have now 2 staves and 4 linked rests
|
||||
QCOMPARE(nscore->staves().size(), 2);
|
||||
QCOMPARE(score->staves().size(), 2);
|
||||
QVERIFY(score->staves()[0]->linkedStaves()->staves().size() == 4);
|
||||
QVERIFY(score->staves()[0]->links()->size() == 4);
|
||||
e = s->element(0);
|
||||
QVERIFY(e->type() == ElementType::REST);
|
||||
QVERIFY(e->links()->size() == 4);
|
||||
|
@ -350,7 +350,7 @@ void TestLinks::test4LinkedParts_94911()
|
|||
// we should have now 2 staves and *4* linked rest
|
||||
// no excerpt
|
||||
QVERIFY(score->staves().size() == 1);
|
||||
QVERIFY(score->staves()[0]->linkedStaves() == nullptr);
|
||||
QVERIFY(score->staves()[0]->links() == nullptr);
|
||||
e = s->element(0);
|
||||
QVERIFY(e->type() == ElementType::REST);
|
||||
QVERIFY(e->links() == nullptr);
|
||||
|
@ -421,7 +421,7 @@ void TestLinks::test5LinkedParts_94911()
|
|||
// we should have now 2 staves and 3 linked rests
|
||||
QCOMPARE(score->staves().size(), 2);
|
||||
QCOMPARE(nscore->staves().size(), 1);
|
||||
QVERIFY(score->staves()[0]->linkedStaves()->staves().size() == 3);
|
||||
QVERIFY(score->staves()[0]->links()->size() == 3);
|
||||
e = s->element(0);
|
||||
QVERIFY(e->type() == ElementType::REST);
|
||||
QVERIFY(e->links()->size() == 3);
|
||||
|
@ -434,7 +434,7 @@ void TestLinks::test5LinkedParts_94911()
|
|||
score->undoStack()->undo(&ed);
|
||||
// we should have now 1 staves and 2 linked rests
|
||||
QVERIFY(score->staves().size() == 1);
|
||||
QVERIFY(score->staves()[0]->linkedStaves()->staves().size() == 2);
|
||||
QVERIFY(score->staves()[0]->links()->size() == 2);
|
||||
e = s->element(0);
|
||||
QVERIFY(e->type() == ElementType::REST);
|
||||
QVERIFY(e->links()->size() == 2);
|
||||
|
@ -444,7 +444,7 @@ void TestLinks::test5LinkedParts_94911()
|
|||
score->undoStack()->redo(&ed);
|
||||
// we should have now 2 staves and 3 linked rests
|
||||
QVERIFY(score->staves().size() == 2);
|
||||
QVERIFY(score->staves()[0]->linkedStaves()->staves().size() == 3);
|
||||
QVERIFY(score->staves()[0]->links()->size() == 3);
|
||||
e = s->element(0);
|
||||
QVERIFY(e->type() == ElementType::REST);
|
||||
QVERIFY(e->links()->size() == 3);
|
||||
|
@ -454,7 +454,6 @@ void TestLinks::test5LinkedParts_94911()
|
|||
QVERIFY(score->excerpts().size() == 1);
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(TestLinks)
|
||||
#include "tst_links.moc"
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@
|
|||
</Chord>
|
||||
<Breath>
|
||||
<symbol>breathMarkComma</symbol>
|
||||
<lid>117</lid>
|
||||
<lid>116</lid>
|
||||
</Breath>
|
||||
<Chord>
|
||||
<lid>10</lid>
|
||||
|
@ -738,7 +738,7 @@
|
|||
</Chord>
|
||||
<Breath>
|
||||
<symbol>breathMarkComma</symbol>
|
||||
<lid>117</lid>
|
||||
<lid>116</lid>
|
||||
</Breath>
|
||||
<Chord>
|
||||
<lid>10</lid>
|
||||
|
|
|
@ -137,7 +137,7 @@
|
|||
</Note>
|
||||
<ChordLine>
|
||||
<subtype>1</subtype>
|
||||
<lid>117</lid>
|
||||
<lid>116</lid>
|
||||
</ChordLine>
|
||||
</Chord>
|
||||
<Chord>
|
||||
|
@ -737,7 +737,7 @@
|
|||
</Note>
|
||||
<ChordLine>
|
||||
<subtype>1</subtype>
|
||||
<lid>117</lid>
|
||||
<lid>116</lid>
|
||||
</ChordLine>
|
||||
</Chord>
|
||||
<Chord>
|
||||
|
|
|
@ -133,7 +133,7 @@
|
|||
<Note>
|
||||
<lid>9</lid>
|
||||
<Fingering>
|
||||
<lid>117</lid>
|
||||
<lid>116</lid>
|
||||
<text>3</text>
|
||||
</Fingering>
|
||||
<pitch>74</pitch>
|
||||
|
@ -733,7 +733,7 @@
|
|||
<Note>
|
||||
<lid>9</lid>
|
||||
<Fingering>
|
||||
<lid>117</lid>
|
||||
<lid>116</lid>
|
||||
<text>3</text>
|
||||
</Fingering>
|
||||
<pitch>74</pitch>
|
||||
|
|
|
@ -134,7 +134,7 @@
|
|||
<lid>9</lid>
|
||||
<Symbol>
|
||||
<name>gClef</name>
|
||||
<lid>117</lid>
|
||||
<lid>116</lid>
|
||||
</Symbol>
|
||||
<pitch>74</pitch>
|
||||
<tpc>16</tpc>
|
||||
|
@ -734,7 +734,7 @@
|
|||
<lid>9</lid>
|
||||
<Symbol>
|
||||
<name>gClef</name>
|
||||
<lid>117</lid>
|
||||
<lid>116</lid>
|
||||
</Symbol>
|
||||
<pitch>74</pitch>
|
||||
<tpc>16</tpc>
|
||||
|
|
Loading…
Reference in a new issue