From 02d0fcca12ba2b4236d30068701718505bd3a7f5 Mon Sep 17 00:00:00 2001 From: ws Date: Thu, 8 May 2014 17:59:24 +0200 Subject: [PATCH] fix #25646 --- libmscore/clef.cpp | 11 +++- libmscore/clef.h | 9 ++-- libmscore/cleflist.cpp | 25 +++++---- libmscore/edit.cpp | 15 ++++-- libmscore/excerpt.cpp | 1 + libmscore/keysig.cpp | 2 +- libmscore/measure.cpp | 1 + libmscore/part.h | 1 - libmscore/read114.cpp | 2 +- libmscore/score.cpp | 23 +-------- libmscore/segment.cpp | 11 +--- libmscore/staff.cpp | 86 ++++++++++++++----------------- libmscore/staff.h | 11 ++-- libmscore/stafftype.cpp | 12 +++++ libmscore/undo.cpp | 14 ++++- libmscore/undo.h | 15 ++++++ libmscore/xml.h | 1 - mscore/capella.cpp | 1 + mscore/importgtp.cpp | 17 +++--- mtest/guitarpro/tst_guitarpro.cpp | 4 +- mtest/testutils.cpp | 3 ++ 21 files changed, 151 insertions(+), 114 deletions(-) diff --git a/libmscore/clef.cpp b/libmscore/clef.cpp index 64ed49580e..52c6b3bebb 100644 --- a/libmscore/clef.cpp +++ b/libmscore/clef.cpp @@ -210,7 +210,7 @@ void Clef::layout() } // if nothing changed since last layout, do nothing -// if (curClefType == clefType() && curLines == lines && curLineDist == lineDist) +//DEBUG if (curClefType == clefType() && curLines == lines && curLineDist == lineDist) // return; // if something has changed, cache new values and re-layout curClefType = clefType(); @@ -472,6 +472,15 @@ void Clef::setClefType(const QString& s) setClefType(ct); } +//--------------------------------------------------------- +// clefTypeName +//--------------------------------------------------------- + +const char* Clef::clefTypeName() + { + return ClefInfo::tag(clefType()); + } + //--------------------------------------------------------- // clefType //--------------------------------------------------------- diff --git a/libmscore/clef.h b/libmscore/clef.h index 11f9025765..0015f284ce 100644 --- a/libmscore/clef.h +++ b/libmscore/clef.h @@ -15,7 +15,7 @@ /** \file - Definition of classes Clef and ClefList. + Definition of classes Clef */ #include "element.h" @@ -66,8 +66,8 @@ enum class ClefType : signed char { //--------------------------------------------------------- struct ClefTypeList { - ClefType _concertClef; - ClefType _transposingClef; + ClefType _concertClef = ClefType::G; + ClefType _transposingClef = ClefType::G; ClefTypeList() {} ClefTypeList(ClefType a, ClefType b) : _concertClef(a), _transposingClef(b) {} @@ -149,7 +149,7 @@ class Clef : public Element { virtual void draw(QPainter*) const; virtual void read(XmlReader&); virtual void write(Xml&) const; - + virtual bool isEditable() const { return false; } virtual void addElement(Element* e, qreal x, qreal y); @@ -165,6 +165,7 @@ class Clef : public Element { void undoSetShowCourtesy(bool v); static ClefType clefType(const QString& s); + const char* clefTypeName(); ClefType clefType() const; void setClefType(ClefType i); diff --git a/libmscore/cleflist.cpp b/libmscore/cleflist.cpp index 41ab453a7d..87152b2f9e 100644 --- a/libmscore/cleflist.cpp +++ b/libmscore/cleflist.cpp @@ -41,10 +41,12 @@ bool ClefTypeList::operator!=(const ClefTypeList& t) const ClefTypeList ClefList::clef(int tick) const { + if (empty()) + return ClefTypeList(); auto i = upper_bound(tick); - if (i != begin()) - --i; - return i->second; + if (i == begin()) + return ClefTypeList(); + return (--i)->second; } //--------------------------------------------------------- @@ -53,11 +55,17 @@ ClefTypeList ClefList::clef(int tick) const void ClefList::setClef(int tick, ClefTypeList ctl) { - auto i = find(tick); - if (i == end()) - insert(std::pair(tick, ctl)); - else - i->second = ctl; + if (clef(tick) == ctl) + return; + if (clef(tick-1) == ctl) + erase(tick); + else { + auto i = find(tick); + if (i == end()) + insert(std::pair(tick, ctl)); + else + i->second = ctl; + } } //--------------------------------------------------------- @@ -79,6 +87,5 @@ void ClefList::read(XmlReader& e, Score* cs) e.unknown(); } } - } diff --git a/libmscore/edit.cpp b/libmscore/edit.cpp index c995ed17a6..749590dadd 100644 --- a/libmscore/edit.cpp +++ b/libmscore/edit.cpp @@ -1297,16 +1297,23 @@ void Score::deleteItem(Element* el) case Element::CLEF: { Clef* clef = static_cast(el); + int tick = clef->segment()->tick(); Measure* m = clef->measure(); if (m->isMMRest()) { // propagate to original measure m = m->mmRestLast(); Segment* s = m->findSegment(Segment::SegClef, clef->segment()->tick()); - if (s && s->element(clef->track())) - undoRemoveElement(s->element(clef->track())); + if (s && s->element(clef->track())) { + Clef* c = static_cast(s->element(clef->track())); + undoRemoveElement(c); + undo(new SetClefType(c->staff(), tick, c->staff()->clefTypeList(tick-1))); + } } - else - undoRemoveElement(el); + else { + undoRemoveElement(clef); + undo(new SetClefType(clef->staff(), tick, clef->staff()->clefTypeList(tick-1))); + } + cmdUpdateNotes(); } break; diff --git a/libmscore/excerpt.cpp b/libmscore/excerpt.cpp index 646177e6ef..179e8d5bc8 100644 --- a/libmscore/excerpt.cpp +++ b/libmscore/excerpt.cpp @@ -374,6 +374,7 @@ void cloneStaves(Score* oscore, Score* score, const QList& map) for (int dstStaffIdx = 0; dstStaffIdx < n; ++dstStaffIdx) { Staff* srcStaff = oscore->staff(map[dstStaffIdx]); Staff* dstStaff = score->staff(dstStaffIdx); + *dstStaff->clefList() = *srcStaff->clefList(); if (srcStaff->primaryStaff()) { int span = srcStaff->barLineSpan(); int sIdx = srcStaff->idx(); diff --git a/libmscore/keysig.cpp b/libmscore/keysig.cpp index 5936fba4b5..dc15799087 100644 --- a/libmscore/keysig.cpp +++ b/libmscore/keysig.cpp @@ -122,7 +122,7 @@ void KeySig::layout() // determine current clef for this staff ClefType clef = ClefType::G; if (staff()) - clef = staff()->clef(segment()); + clef = staff()->clef(segment()->tick()); int t1 = _sig.accidentalType(); int t2 = _sig.naturalType(); diff --git a/libmscore/measure.cpp b/libmscore/measure.cpp index 24a9c871bd..f9655a41ce 100644 --- a/libmscore/measure.cpp +++ b/libmscore/measure.cpp @@ -2042,6 +2042,7 @@ void Measure::read(XmlReader& e, int staffIdx) clef->setTrack(e.track()); clef->read(e); clef->setGenerated(false); + staff->setClef(e.tick(), clef->clefTypeList()); // there may be more than one clef segment for same tick position if (!segment) { diff --git a/libmscore/part.h b/libmscore/part.h index 668728826d..1d53416bed 100644 --- a/libmscore/part.h +++ b/libmscore/part.h @@ -23,7 +23,6 @@ class Xml; class Staff; class Score; class InstrumentTemplate; -class ClefList; //--------------------------------------------------------- // @@ Part diff --git a/libmscore/read114.cpp b/libmscore/read114.cpp index 27b56941d9..4123388ea3 100644 --- a/libmscore/read114.cpp +++ b/libmscore/read114.cpp @@ -455,7 +455,7 @@ Score::FileError Score::read114(XmlReader& e) s->setBarLineSpan(n - idx); } // first clef can be implicit in 1.3 #22607 - if(s->clefList()->count(0) == 0) { + if (s->clefList()->count(0) == 0) { Segment* seg = firstMeasure()->getSegment(Segment::SegClef, 0); ClefType ct = Clef::clefType("0"); Clef* clef = new Clef(this); diff --git a/libmscore/score.cpp b/libmscore/score.cpp index 7786138059..b3687ed195 100644 --- a/libmscore/score.cpp +++ b/libmscore/score.cpp @@ -3498,27 +3498,8 @@ void Score::undoInsertTime(int tick, int len) void Score::insertTime(int tick, int len) { for (Score* score : scoreList()) { - for(Staff* staff : score->staves()) { - KeyList* kl = staff->keymap(); - KeyList kl2; - for (auto i = kl->upper_bound(tick); i != kl->end();) { - KeySigEvent kse = i->second; - int key = i->first; - kl->erase(i++); - kl2[key + len] = kse; - } - kl->insert(kl2.begin(), kl2.end()); - - ClefList* cl = staff->clefList(); - ClefList cl2; - for (auto i = cl->upper_bound(tick); i != cl->end();) { - ClefTypeList ctl = i->second; - int key = i->first; - cl->erase(i++); - cl2[key + len] = ctl; - } - cl->insert(cl2.begin(), cl2.end()); - } + for (Staff* staff : score->staves()) + staff->insertTime(tick, len); } } diff --git a/libmscore/segment.cpp b/libmscore/segment.cpp index a386b7334d..bfe6f27743 100644 --- a/libmscore/segment.cpp +++ b/libmscore/segment.cpp @@ -181,9 +181,7 @@ Segment::~Segment() foreach(Element* e, _elist) { if (!e) continue; - if (e->type() == CLEF) - e->staff()->removeClef(static_cast(e)); - else if (e->type() == TIMESIG) + if (e->type() == TIMESIG) e->staff()->removeTimeSig(static_cast(e)); delete e; } @@ -462,7 +460,6 @@ void Segment::add(Element* el) score()->sigmap()->pos(tick()), tick(), track, score()); } _elist[track] = el; - el->staff()->addClef(static_cast(el)); empty = false; break; @@ -583,16 +580,12 @@ void Segment::remove(Element* el) removeAnnotation(el); break; - case CLEF: - _elist[track] = 0; - el->staff()->removeClef(static_cast(el)); - break; - case TIMESIG: _elist[track] = 0; el->staff()->removeTimeSig(static_cast(el)); break; + case CLEF: case KEYSIG: case BAR_LINE: case BREATH: diff --git a/libmscore/staff.cpp b/libmscore/staff.cpp index c6c351ff22..e7488008d2 100644 --- a/libmscore/staff.cpp +++ b/libmscore/staff.cpp @@ -172,7 +172,6 @@ Staff::Staff(Score* s) _updateKeymap = true; _linkedStaves = 0; _color = MScore::defaultColor; - setClef(0, ClefType::G); } Staff::Staff(Score* s, Part* p, int rs) @@ -190,7 +189,6 @@ Staff::Staff(Score* s, Part* p, int rs) _updateKeymap = true; _linkedStaves = 0; _color = MScore::defaultColor; - setClef(0, ClefType::G); } //--------------------------------------------------------- @@ -221,36 +219,10 @@ ClefTypeList Staff::clefTypeList(int tick) const ClefType Staff::clef(int tick) const { - ClefTypeList c = clefs.clef(tick); + ClefTypeList c = clefTypeList(tick); return score()->styleB(ST_concertPitch) ? c._concertClef : c._transposingClef; } -ClefType Staff::clef(Segment* segment) const - { - return clef(segment->tick()); - } - -//--------------------------------------------------------- -// timeStretch -//--------------------------------------------------------- - -Fraction Staff::timeStretch(int tick) const - { - TimeSig* timesig = timeSig(tick); - return timesig == 0 ? Fraction(1,1) : timesig->stretch(); - } - -//--------------------------------------------------------- -// addClef -//--------------------------------------------------------- - -void Staff::addClef(Clef* clef) - { - int tick = clef->segment()->tick(); - if (tick == 0 || !clef->generated()) - clefs.setClef(tick, clef->clefTypeList()); - } - //--------------------------------------------------------- // setClef //--------------------------------------------------------- @@ -260,29 +232,23 @@ void Staff::setClef(int tick, const ClefTypeList& ctl) clefs.setClef(tick, ctl); } -void Staff::setClef(int tick, ClefType ct) +//--------------------------------------------------------- +// undoSetClef +//--------------------------------------------------------- + +void Staff::undoSetClef(int tick, const ClefTypeList& ctl) { - setClef(tick, ClefTypeList(ct, ct)); + score()->undo(new SetClefType(this, tick, ctl)); } //--------------------------------------------------------- -// removeClef +// timeStretch //--------------------------------------------------------- -void Staff::removeClef(Clef* clef) +Fraction Staff::timeStretch(int tick) const { - if (clef->generated()) - return; - int tick = clef->segment()->tick(); - if (tick == 0) { - setClef(0, ClefType::G); - return; - } - auto i = clefs.find(tick); - if (i != clefs.end()) - clefs.erase(i); - else - qDebug("Staff::removeClef: Clef at %d not found", tick); + TimeSig* timesig = timeSig(tick); + return timesig == 0 ? Fraction(1,1) : timesig->stretch(); } //--------------------------------------------------------- @@ -431,8 +397,9 @@ void Staff::read(XmlReader& e) qDebug("Staff::read staffTypeIdx %d", staffTypeIdx); _staffType = *StaffType::preset(staffTypeIdx); } - else if (tag == "StaffType") + else if (tag == "StaffType") { _staffType.read(e); + } else if (tag == "small") setSmall(e.readInt()); else if (tag == "invisible") @@ -810,7 +777,7 @@ bool Staff::genKeySig() bool Staff::showLedgerLines() { if (_staffType.group() == TAB_STAFF_GROUP) - return false; + return false; else return _staffType.showLedgerLines(); } @@ -834,5 +801,30 @@ void Staff::undoSetColor(const QColor& /*val*/) // score()->undoChangeProperty(this, P_COLOR, val); } +//--------------------------------------------------------- +// insertTime +//--------------------------------------------------------- + +void Staff::insertTime(int tick, int len) + { + KeyList kl2; + for (auto i = _keymap.upper_bound(tick); i != _keymap.end();) { + KeySigEvent kse = i->second; + int key = i->first; + _keymap.erase(i++); + kl2[key + len] = kse; + } + _keymap.insert(kl2.begin(), kl2.end()); + + ClefList cl2; + for (auto i = clefs.upper_bound(tick); i != clefs.end();) { + ClefTypeList ctl = i->second; + int key = i->first; + clefs.erase(i++); + cl2.setClef(key + len, ctl); + } + clefs.insert(cl2.begin(), cl2.end()); + } + } diff --git a/libmscore/staff.h b/libmscore/staff.h index 532e3af210..665483496d 100644 --- a/libmscore/staff.h +++ b/libmscore/staff.h @@ -37,7 +37,6 @@ class KeyList; class StaffType; class Staff; class StringData; -class ClefList; struct ClefTypeList; class Segment; class Clef; @@ -141,13 +140,13 @@ class Staff : public QObject { QList brackets() const { return _brackets; } void cleanupBrackets(); + ClefList* clefList() { return &clefs; } ClefTypeList clefTypeList(int tick) const; ClefType clef(int tick) const; - ClefType clef(Segment*) const; - void addClef(Clef*); - void removeClef(Clef*); void setClef(int, const ClefTypeList&); - void setClef(int, ClefType); + void setClef(int tick, const ClefType& ct) { setClef(tick, ClefTypeList(ct, ct)); } + void removeClef(int); + void undoSetClef(int, const ClefTypeList&); void addTimeSig(TimeSig*); void removeTimeSig(TimeSig*); @@ -213,11 +212,11 @@ class Staff : public QObject { bool genKeySig(); bool showLedgerLines(); - ClefList* clefList() { return &clefs; } QColor color() const { return _color; } void setColor(const QColor& val) { _color = val; } void undoSetColor(const QColor& val); + void insertTime(int tick, int len); }; } // namespace Ms diff --git a/libmscore/stafftype.cpp b/libmscore/stafftype.cpp index 279e668ba8..13cdc105d1 100644 --- a/libmscore/stafftype.cpp +++ b/libmscore/stafftype.cpp @@ -258,6 +258,18 @@ void StaffType::write(Xml& xml) const void StaffType::read(XmlReader& e) { + QString group = e.attribute("group", "pitched"); + if (group == "tablature") + _group = TAB_STAFF_GROUP; + else if (group == "percussion") + _group = PERCUSSION_STAFF_GROUP; + else if (group == "pitched") + _group = STANDARD_STAFF_GROUP; + else { + qDebug("StaffType::read: unknown group: %s", qPrintable(group)); + _group = STANDARD_STAFF_GROUP; + } + while (e.readNextStartElement()) { const QStringRef& tag(e.name()); if (tag == "name") diff --git a/libmscore/undo.cpp b/libmscore/undo.cpp index 13ea6334c5..061c5e3e5d 100644 --- a/libmscore/undo.cpp +++ b/libmscore/undo.cpp @@ -577,6 +577,8 @@ void Score::undoChangeClef(Staff* ostaff, Segment* seg, ClefType st) clef->setParent(destSeg); score->undo(new AddElement(clef)); } + undo(new SetClefType(clef->staff(), tick, clef->clefTypeList())); + cmdUpdateNotes(); } } @@ -3087,7 +3089,6 @@ void ChangeClefType::flip() clef->setConcertClef(concertClef); clef->setTransposingClef(transposingClef); clef->setClefType(clef->concertPitch() ? concertClef : transposingClef); - clef->staff()->addClef(clef); Segment* segment = clef->segment(); updateNoteLines(segment, clef->track()); @@ -3345,5 +3346,16 @@ void ChangeNoteEvent::flip() // TODO: note->chord()->setPlayEventType(PlayEventType::User); } + +//--------------------------------------------------------- +// SetClefType +//--------------------------------------------------------- + +void SetClefType::flip() + { + ClefTypeList ol = staff->clefTypeList(tick); + staff->setClef(tick, ctl); + ctl = ol; + } } diff --git a/libmscore/undo.h b/libmscore/undo.h index c3cf25ad61..9052040522 100644 --- a/libmscore/undo.h +++ b/libmscore/undo.h @@ -34,6 +34,7 @@ #include "synthesizerstate.h" #include "bracket.h" #include "stafftype.h" +#include "cleflist.h" namespace Ms { @@ -1407,6 +1408,20 @@ class ChangeNoteEvent : public UndoCommand { : note(n), oldEvent(oe), newEvent(ne) {} }; +//--------------------------------------------------------- +// SetClefType +//--------------------------------------------------------- + +class SetClefType : public UndoCommand { + Staff* staff; + int tick; + ClefTypeList ctl; + + void flip(); + + public: + SetClefType(Staff* st, int t, const ClefTypeList& l) : staff(st), tick(t), ctl(l) {} + }; } // namespace Ms #endif diff --git a/libmscore/xml.h b/libmscore/xml.h index 11b7fd6bca..63492e9b26 100644 --- a/libmscore/xml.h +++ b/libmscore/xml.h @@ -26,7 +26,6 @@ namespace Ms { class Spanner; class Beam; class Tuplet; -class ClefList; class Measure; //--------------------------------------------------------- diff --git a/mscore/capella.cpp b/mscore/capella.cpp index 001e2ede73..64627a87e6 100644 --- a/mscore/capella.cpp +++ b/mscore/capella.cpp @@ -570,6 +570,7 @@ static int readCapVoice(Score* score, CapVoice* cvoice, int staffIdx, int tick, Measure* m = score->getCreateMeasure(tick); Segment* s = m->getSegment(Segment::SegClef, tick); s->add(clef); + clef->staff()->setClef(tick, clef->clefTypeList()); } break; case T_KEY: diff --git a/mscore/importgtp.cpp b/mscore/importgtp.cpp index 1db274426d..0e4123a56d 100644 --- a/mscore/importgtp.cpp +++ b/mscore/importgtp.cpp @@ -883,7 +883,7 @@ qDebug("BeginRepeat============================================="); clef->setTrack(i * VOICES); Segment* segment = measure->getSegment(Segment::SegClef, 0); segment->add(clef); - + clef->staff()->setClef(0, clef->clefTypeList()); Channel& ch = instr->channel(0); if (midiChannel == PERC_DEFAULT_STAFF_TYPE) { @@ -1470,6 +1470,7 @@ void GuitarPro3::read(QFile* fp) clef->setTrack(i * VOICES); Segment* segment = measure->getSegment(Segment::SegClef, 0); segment->add(clef); + clef->staff()->setClef(0, clef->clefTypeList()); Channel& ch = instr->channel(0); if (midiChannel == GP_DEFAULT_PERCUSSION_CHANNEL) { @@ -2177,6 +2178,7 @@ void GuitarPro4::read(QFile* fp) clef->setTrack(i * VOICES); Segment* segment = measure->getSegment(Segment::SegClef, 0); segment->add(clef); + clef->staff()->setClef(0, clef->clefTypeList()); Channel& ch = instr->channel(0); @@ -2535,7 +2537,7 @@ void GuitarPro5::readNote(int string, Note* note) uchar noteType = readUChar(); if (noteType == 1) { } - if (noteType == 2) { + else if (noteType == 2) { tieNote = true; } else if (noteType == 3) { // dead notes @@ -2873,8 +2875,9 @@ int GuitarPro5::readBeat(int tick, int voice, Measure* measure, int staffIdx, Tu chord->setStemDirection(Direction::DOWN); else if (rr == 0xa) chord->setStemDirection(Direction::UP); - else - qDebug(" 1beat read 0x%02x", rr); + else { + ; // qDebug(" 1beat read 0x%02x", rr); + } } int r = readChar(); if (r & 0x8) { @@ -3040,7 +3043,7 @@ void GuitarPro5::readTracks() clef->setTrack(i * VOICES); Segment* segment = measure->getSegment(Segment::SegClef, 0); segment->add(clef); - + clef->staff()->setClef(0, clef->clefTypeList()); Channel& ch = instr->channel(0); if (midiChannel == GP_DEFAULT_PERCUSSION_CHANNEL) { @@ -3086,8 +3089,8 @@ void GuitarPro5::readMeasures() for (int staffIdx = 0; staffIdx < staves; ++staffIdx) { readMeasure(measure, staffIdx, tuplets); if (!(((bar == (measures-1)) && (staffIdx == (staves-1))))) { - int a = readChar(); - qDebug(" ======skip %02x", a); + /*int a = */ readChar(); + // qDebug(" ======skip %02x", a); } } } diff --git a/mtest/guitarpro/tst_guitarpro.cpp b/mtest/guitarpro/tst_guitarpro.cpp index e79f5df438..312077e6ec 100644 --- a/mtest/guitarpro/tst_guitarpro.cpp +++ b/mtest/guitarpro/tst_guitarpro.cpp @@ -15,6 +15,7 @@ #include "mtest/testutils.h" #include "libmscore/score.h" #include "mscore/preferences.h" +#include "libmscore/excerpt.h" #define DIR QString("guitarpro/") @@ -29,7 +30,7 @@ class TestGuitarPro : public QObject, public MTest Q_OBJECT void gpReadTest(const char* file, const char* ext); - + private slots: void initTestCase(); void gpTestIrrTuplet() { gpReadTest("testIrrTuplet", "gp4"); } @@ -71,6 +72,7 @@ void TestGuitarPro::gpReadTest(const char* file, const char* ext) { Score* score = readScore(DIR + file + "." + ext); QVERIFY(score); + score->doLayout(); QVERIFY(saveCompareScore(score, QString("%1.%2.mscx").arg(file).arg(ext), DIR + QString("%1.%2-ref.mscx").arg(file).arg(ext))); diff --git a/mtest/testutils.cpp b/mtest/testutils.cpp index 5305ad68d0..b17058bf8b 100644 --- a/mtest/testutils.cpp +++ b/mtest/testutils.cpp @@ -24,6 +24,7 @@ #include "mscore/musescoreCore.h" #include "mscore/shortcut.h" #include "libmscore/xml.h" +#include "libmscore/excerpt.h" namespace Ms { @@ -148,6 +149,8 @@ Score* MTest::readCreatedScore(const QString& name) return 0; } score->updateNotes(); + for (Excerpt* e : score->excerpts()) + e->score()->updateNotes(); return score; }