FiguredBass* Score::addFiguredBass() { Element* el = selection().element(); if (el == 0 || (el->type() != NOTE && el->type() != FIGURED_BASS)) { QMessageBox::information(0, QMessageBox::tr("MuseScore:"), QMessageBox::tr("No note or figured bass selected:\n" "Please select a single note or figured bass and retry operation\n"), QMessageBox::Ok, QMessageBox::NoButton); return 0; } ChordRest* cr; if (el->type() == NOTE) cr = static_cast<Note*>(el)->chord(); else if (el->type() == FIGURED_BASS) cr = static_cast<FiguredBass*>(el)->chordRest(); else return 0; QList<Lyrics*> ll = cr->lyricsList(); int no = ll.size(); FiguredBass* fb = new FiguredBass(this); fb->setTrack(cr->track()); fb->setParent(cr); fb->setNo(no); undoAddElement(fb); select(fb, SELECT_SINGLE, 0); return fb; }
ChordRest* Selection::firstChordRest(int track) const { if (_el.size() == 1) { Element* el = _el[0]; if (el->type() == Element::NOTE) return static_cast<ChordRest*>(el->parent()); else if (el->type() == Element::REST) return static_cast<ChordRest*>(el); return 0; } ChordRest* cr = 0; foreach (Element* el, _el) { if (el->type() == Element::NOTE) el = el->parent(); if (el->isChordRest()) { if (track != -1 && el->track() != track) continue; if (cr) { if (static_cast<ChordRest*>(el)->tick() < cr->tick()) cr = static_cast<ChordRest*>(el); } else cr = static_cast<ChordRest*>(el); } } return cr; }
ChordRest* Selection::lastChordRest(int track) const { if (_el.size() == 1) { Element* el = _el[0]; if (el && el->type() == Element::NOTE) return static_cast<ChordRest*>(el->parent()); else if (el->type() == Element::CHORD || el->type() == Element::REST) return static_cast<ChordRest*>(el); return 0; } ChordRest* cr = 0; for (auto i = _el.begin(); i != _el.end(); ++i) { Element* el = *i; if (el->type() == Element::NOTE) el = ((Note*)el)->chord(); if (el->isChordRest() && static_cast<ChordRest*>(el)->segment()->segmentType() == Segment::SegChordRest) { if (track != -1 && el->track() != track) continue; if (cr) { if (((ChordRest*)el)->tick() >= cr->tick()) cr = (ChordRest*)el; } else cr = (ChordRest*)el; } } return cr; }
bool areTiesConsistent(const Staff *staff) { const int strack = staff->idx() * VOICES; for (int voice = 0; voice < VOICES; ++voice) { bool isTie = false; for (Segment *seg = staff->score()->firstSegment(); seg; seg = seg->next1()) { if (seg->segmentType() == Segment::Type::ChordRest) { ChordRest *cr = static_cast<ChordRest *>(seg->element(strack + voice)); if (cr && cr->type() == Element::Type::REST && isTie) { printInconsistentTieLocation(seg->measure()->no(), staff->idx()); return false; } if (isTiedBack(seg, strack, voice)) { if (!isTie) { printInconsistentTieLocation(seg->measure()->no(), staff->idx()); return false; } isTie = false; } if (isTiedFor(seg, strack, voice)) { if (isTie) { printInconsistentTieLocation(seg->measure()->no(), staff->idx()); return false; } isTie = true; } } } if (isTie) return false; } return true; }
void LyricsLine::layout() { if (lyrics()->ticks() > 0) { // melisma setLineWidth(Spatium(MELISMA_DEFAULT_LINE_THICKNESS)); // Lyrics::_ticks points to the beginning of the last spanned segment, // but the line shall include it: // include the duration of this last segment in the melisma duration bool ticksSet = false; Segment* lastSeg = score()->tick2segment(lyrics()->endTick(), false, Segment::Type::ChordRest, false); if (lastSeg) { // if last segment found, locate the first non-empty ChordRest // in the same staff of this LyricsLine and use its duration int firstTrack = (track() >> 2) << 2; int lastTrack = firstTrack + VOICES; for (int i = firstTrack; i < lastTrack; i++) { ChordRest* cr = static_cast<ChordRest*>(lastSeg->elementAt(i)); if (cr) { setTicks(lyrics()->ticks() + cr->durationTicks()); ticksSet = true; break; } } } // no suitable ChordRest found? go to the end of the last known segment if (!ticksSet) setTicks(lyrics()->ticks()); }
void TestTools::undoChangeVoice() { QString readFile(DIR + "undoChangeVoice.mscx"); QString writeFile1("undoChangeVoice01-test.mscx"); QString reference1(DIR + "undoChangeVoice01-ref.mscx"); QString writeFile2("undoChangeVoice02-test.mscx"); QString reference2(DIR + "undoChangeVoice02-ref.mscx"); Score* score = readScore(readFile); score->doLayout(); // do score->deselectAll(); // select bottom note of all voice 1 chords for (Segment* s = score->firstSegment(Segment::Type::ChordRest); s; s = s->next1()) { ChordRest* cr = static_cast<ChordRest*>(s->element(0)); if (cr && cr->type() == Element::Type::CHORD) { Ms::Chord* c = static_cast<Ms::Chord*>(cr); score->select(c->downNote(), SelectType::ADD); } } // change voice score->changeVoice(1); QVERIFY(saveCompareScore(score, writeFile1, reference1)); // undo score->undo()->undo(); QVERIFY(saveCompareScore(score, writeFile2, reference2)); delete score; }
void MuseScore::tupletDialog() { if (!cs) return; ChordRest* cr = cs->getSelectedChordRest(); if (cr == 0) return; TupletDialog td; if (!td.exec()) return; Tuplet* tuplet = new Tuplet(cs); tuplet->setTrack(cr->track()); tuplet->setTick(cr->tick()); td.setupTuplet(tuplet); // tuplet->setRatio(tuplet->ratio().reduced()); Fraction f1(cr->duration()); tuplet->setDuration(f1); Fraction f = f1 * tuplet->ratio(); f.reduce(); printf("len %s ratio %s base %s\n", qPrintable(f1.print()), qPrintable(tuplet->ratio().print()), qPrintable(f.print())); tuplet->setBaseLen(Fraction(1, f.denominator())); Measure* measure = cr->measure(); tuplet->setParent(measure); cs->cmdCreateTuplet(cr, tuplet); }
void ScoreView::lyricsEndEdit() { Lyrics* lyrics = toLyrics(editData.element); // if not empty, make sure this new lyrics does not fall in the middle // of an existing melisma from a previous lyrics; in case, shorten it int verse = lyrics->no(); Placement placement = lyrics->placement(); int track = lyrics->track(); // search previous lyric Lyrics* prevLyrics = 0; Segment* prevSegment = lyrics->segment()->prev1(SegmentType::ChordRest); Segment* segment = prevSegment; while (segment) { ChordRest* cr = toChordRest(segment->element(track)); if (cr) { prevLyrics = cr->lyrics(verse, placement); if (prevLyrics) break; } segment = segment->prev1(SegmentType::ChordRest); } if (prevLyrics && prevLyrics->syllabic() == Lyrics::Syllabic::END) { int endTick = prevSegment->tick(); // a prev. melisma should not go beyond this segment if (prevLyrics->endTick() >= endTick) prevLyrics->undoChangeProperty(Pid::LYRIC_TICKS, endTick - prevLyrics->segment()->tick()); } }
Segment* Score::tick2segmentEnd(int track, int tick) const { Measure* m = tick2measure(tick); if (m == 0) { qDebug("tick2segment(): not found tick %d\n", tick); return 0; } // loop over all segments for (Segment* segment = m->first(Segment::SegChordRest); segment; segment = segment->next(Segment::SegChordRest)) { ChordRest* cr = static_cast<ChordRest*>(segment->element(track)); if (!cr) continue; // TODO LVI: check if following is correct, see exceptions in // ExportMusicXml::chord() and ExportMusicXml::rest() int endTick = cr->tick() + cr->actualTicks(); if (endTick < tick) continue; // not found yet else if (endTick == tick) { return segment; // found it } else { // endTick > tick (beyond the tick we are looking for) return 0; } } return 0; }
QPointF Pedal::linePos(GripLine grip, System** sys) const { qreal x; qreal nhw = score()->noteHeadWidth(); System* s; if (grip == GripLine::START) { ChordRest* c = static_cast<ChordRest*>(startElement()); s = c->segment()->system(); x = c->pos().x() + c->segment()->pos().x() + c->segment()->measure()->pos().x(); if (beginHook() && beginHookType() == HookType::HOOK_45) x += nhw * .5; } else { ChordRest* c = static_cast<ChordRest*>(endElement()); if (c) { s = c->segment()->system(); x = c->pos().x() + c->segment()->pos().x() + c->segment()->measure()->pos().x(); } else { int t = tick2(); Measure* m = score()->tick2measure(t); s = m->system(); x = m->tick2pos(t); } if (endHook() && endHookType() == HookType::HOOK_45) x += nhw * .5; else x += nhw; } *sys = s; return QPointF(x, 0); }
void Glissando::layout() { Chord* chord = static_cast<Chord*>(parent()); if (chord == 0) { return; } Note* anchor2 = chord->upNote(); Segment* s = chord->segment(); s = s->prev1(); while (s) { if ((s->subtype() & (Segment::SegChordRestGrace)) && s->element(track())) break; s = s->prev1(); } if (s == 0) { qDebug("no segment for first note of glissando found\n"); return; } ChordRest* cr = static_cast<ChordRest*>(s->element(track())); if (cr == 0 || cr->type() != CHORD) { qDebug("no first note for glissando found, track %d\n", track()); return; } Note* anchor1 = static_cast<Chord*>(cr)->upNote(); setPos(0.0, 0.0); QPointF cp1 = anchor1->pagePos(); QPointF cp2 = anchor2->pagePos(); // construct line from notehead to notehead qreal x1 = (anchor1->headWidth()) - (cp2.x() - cp1.x()); qreal y1 = anchor1->pos().y(); qreal x2 = anchor2->pos().x(); qreal y2 = anchor2->pos().y(); // on TAB's, adjust lower end point from string line height to base of note height (= ca. half line spacing) if (chord->staff()->isTabStaff()) { qreal yOff = chord->staff()->lineDistance() * 0.5 * spatium(); if (anchor1->pitch() > anchor2->pitch()) // descending glissando: y2 += yOff; // move ending point to base of note else // ascending glissando: y1 += yOff; // move starting point to base of note } QLineF fullLine(x1, y1, x2, y2); // shorten line on each side by offsets qreal xo = spatium() * .5; qreal yo = xo; // spatium() * .5; QPointF p1 = fullLine.pointAt(xo / fullLine.length()); QPointF p2 = fullLine.pointAt(1 - (yo / fullLine.length())); line = QLineF(p1, p2); qreal lw = spatium() * .15 * .5; QRectF r = QRectF(line.p1(), line.p2()).normalized(); setbbox(r.adjusted(-lw, -lw, lw, lw)); }
void MuseScore::addTempo() { ChordRest* cr = cs->getSelectedChordRest(); if (!cr) return; // double bps = 2.0; SigEvent event = cs->sigmap()->timesig(cr->tick()); Fraction f = event.nominal(); QString text(QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5f))); switch (f.denominator()) { case 1: text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5d)); break; case 2: text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5e)); break; case 4: text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5f)); break; case 8: if(f.numerator() % 3 == 0) text = QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd5f)).arg(QChar(0xd834)).arg(QChar(0xdd6d)); else text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd60)); break; case 16: if(f.numerator() % 3 == 0) text = QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd60)).arg(QChar(0xd834)).arg(QChar(0xdd6d)); else text = text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd61)); break; case 32: if(f.numerator() % 3 == 0) text = QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd61)).arg(QChar(0xd834)).arg(QChar(0xdd6d)); else text = text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd62)); break; case 64: if(f.numerator() % 3 == 0) text = QString("%1%2%3%4 = 80").arg(QChar(0xd834)).arg(QChar(0xdd62)).arg(QChar(0xd834)).arg(QChar(0xdd6d)); else text = text = QString("%1%2 = 80").arg(QChar(0xd834)).arg(QChar(0xdd63)); break; default: break; } TempoText* tt = new TempoText(cs); tt->setParent(cr->segment()); tt->setTrack(cr->track()); tt->setText(text); tt->setFollowText(true); //tt->setTempo(bps); cs->undoAddElement(tt); cv->startEdit(tt); }
void MuseScore::addTempo() { ChordRest* cr = cs->getSelectedChordRest(); if (!cr) return; // double bps = 2.0; SigEvent event = cs->sigmap()->timesig(cr->tick()); Fraction f = event.nominal(); QString text("<sym>noteQuarterUp</sym> = 80"); switch (f.denominator()) { case 1: text = "<sym>noteWhole</sym> = 80"; break; case 2: text = "<sym>noteHalfUp</sym> = 80"; break; case 4: text = "<sym>noteQuarterUp</sym> = 80"; break; case 8: if(f.numerator() % 3 == 0) text = "<sym>noteQuarterUp</sym><sym>textAugmentationDot</sym> = 80"; else text = "<sym>note8thUp</sym> = 80"; break; case 16: if(f.numerator() % 3 == 0) text = text = "<sym>note8thUp</sym><sym>textAugmentationDot</sym> = 80"; else text = "<sym>note16thUp</sym> = 80"; break; case 32: if(f.numerator() % 3 == 0) text = "<sym>note16thUp</sym><sym>textAugmentationDot</sym> = 80"; else text = "<sym>note32thUp</sym> = 80"; break; case 64: if(f.numerator() % 3 == 0) text = "<sym>note32thUp</sym><sym>textAugmentationDot</sym> = 80"; else text = "<sym>note64thUp</sym> = 80"; break; default: break; } TempoText* tt = new TempoText(cs); tt->setParent(cr->segment()); tt->setTrack(cr->track()); tt->setText(text); tt->setFollowText(true); //tt->setTempo(bps); cs->undoAddElement(tt); cv->startEdit(tt); }
QPointF Pedal::linePos(GripLine grip, System** sys) const { qreal x; qreal nhw = score()->noteHeadWidth(); System* s = nullptr; if (grip == GripLine::START) { ChordRest* c = static_cast<ChordRest*>(startElement()); s = c->segment()->system(); x = c->pos().x() + c->segment()->pos().x() + c->segment()->measure()->pos().x(); if (beginHook() && beginHookType() == HookType::HOOK_45) x += nhw * .5; } else { ChordRest* c = nullptr; Element* e = endElement(); if (!e || e == startElement()) { // pedal marking on single note - extend to next note or end of measure Segment* seg = startSegment(); if (seg) { seg = seg->next(); for ( ; seg; seg = seg->next()) { if (seg->segmentType() == Segment::Type::ChordRest) { if (seg->element(track())) break; } else if (seg->segmentType() == Segment::Type::EndBarLine) { break; } } } if (seg) { s = seg->system(); x = seg->pos().x() + seg->measure()->pos().x() - nhw * 2; } } else { c = static_cast<ChordRest*>(endElement()); if (c) { s = c->segment()->system(); x = c->pos().x() + c->segment()->pos().x() + c->segment()->measure()->pos().x(); } } if (!s) { int t = tick2(); Measure* m = score()->tick2measure(t); s = m->system(); x = m->tick2pos(t); } if (endHook() && endHookType() == HookType::HOOK_45) x += nhw * .5; else x += nhw; } *sys = s; return QPointF(x, 0); }
ArticulationProperties::ArticulationProperties(Articulation* na, QWidget* parent) : QDialog(parent) { setupUi(this); setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint); articulation = na; ChordRest* cr = articulation->chordRest(); if (cr) { Segment* segment = cr->segment(); Part* part = articulation->staff()->part(); Instrument* instrument = part->instr(segment->tick()); // const QList<NamedEventList>& midiActions() const; // const QList<MidiArticulation>& articulation() const; // const QList<Channel>& channel() const; foreach(const Channel& a, instrument->channel()) { if (a.name.isEmpty() || a.name == "normal") channelList->addItem(tr("normal")); else channelList->addItem(a.name); } foreach(const NamedEventList& el, instrument->midiActions()) { midiActionList->addItem(el.name); } } #if 0 foreach(const NamedEventList& e, instrument->midiActions) midiActionList->addItem(e.name); articulationChange->setChecked(!articulation->articulationName().isEmpty()); midiAction->setChecked(!articulation->midiActionName().isEmpty()); if (!articulation->articulationName().isEmpty()) { QList<QListWidgetItem*> wl = articulationList ->findItems(st->articulationName(), Qt::MatchExactly); if (!wl.isEmpty()) articulationList->setCurrentRow(articulationList->row(wl[0])); } if (!articulation->midiActionName().isEmpty()) { QList<QListWidgetItem*> wl = midiActionList ->findItems(st->midiActionName(), Qt::MatchExactly); if (!wl.isEmpty()) midiActionList->setCurrentRow(midiActionList->row(wl[0])); } #endif direction->setCurrentIndex(int(articulation->direction())); anchor->setCurrentIndex(int(articulation->anchor())); connect(this, SIGNAL(accepted()), SLOT(saveValues())); }
void ScoreView::lyricsUpDown(bool up, bool end) { Lyrics* lyrics = toLyrics(editData.element); int track = lyrics->track(); ChordRest* cr = lyrics->chordRest(); int verse = lyrics->no(); Placement placement = lyrics->placement(); PropertyFlags pFlags = lyrics->propertyFlags(Pid::PLACEMENT); if (up) { if (verse == 0) return; --verse; } else { ++verse; if (verse > cr->lastVerse(placement)) return; } changeState(ViewState::NORMAL); lyrics = cr->lyrics(verse, placement); if (!lyrics) { lyrics = new Lyrics(_score); lyrics->setTrack(track); lyrics->setParent(cr); lyrics->setNo(verse); lyrics->setPlacement(placement); lyrics->setPropertyFlags(Pid::PLACEMENT, pFlags); _score->startCmd(); _score->undoAddElement(lyrics); _score->endCmd(); } _score->select(lyrics, SelectType::SINGLE, 0); startEdit(lyrics, Grip::NO_GRIP); mscore->changeState(mscoreState()); adjustCanvasPosition(lyrics, false); lyrics = toLyrics(editData.element); TextCursor* cursor = lyrics->cursor(editData); if (end) { cursor->movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); cursor->movePosition(QTextCursor::End, QTextCursor::KeepAnchor); } else { cursor->movePosition(QTextCursor::End, QTextCursor::MoveAnchor); cursor->movePosition(QTextCursor::Start, QTextCursor::KeepAnchor); } _score->setLayoutAll(); _score->update(); }
void TestChordSymbol::testAddPart() { MasterScore* score = test_pre("add-part"); Segment* seg = score->firstSegment(Segment::Type::ChordRest); ChordRest* cr = seg->cr(0); Harmony* harmony = new Harmony(score); harmony->setHarmony("C7"); harmony->setTrack(cr->track()); harmony->setParent(cr->segment()); score->undoAddElement(harmony); score->doLayout(); test_post(score, "add-part"); }
void Segment::removeElement(int track) { Element* el = element(track); if (el->isChordRest()) { ChordRest* cr = (ChordRest*)el; Beam* beam = cr->beam(); if (beam) beam->remove(cr); Tuplet* tuplet = cr->tuplet(); if (tuplet) tuplet->remove(cr); } }
//--------------------------------------------------------- // oscColorNote //--------------------------------------------------------- void MuseScore::oscColorNote(QVariantList list) { qDebug() << list; if(!cs) return; if (list.length() != 2 && list.length() != 3) return; int tick; int pitch; QColor noteColor("red"); //default to red bool ok; tick = list[0].toInt(&ok); if (!ok) return; pitch = list[1].toInt(&ok); if (!ok) return; if(list.length() == 3 && list[2].canConvert(QVariant::String)) { QColor color(list[2].toString()); if(color.isValid()) noteColor = color; } Measure* measure = cs->tick2measure(tick); if(!measure) return; Segment* s = measure->findSegment(Segment::SegChordRest, tick); if (!s) return; //get all chords in segment... int n = cs->nstaves() * VOICES; for (int i = 0; i < n; i++) { Element* e = s->element(i); if (e && e->isChordRest()) { ChordRest* cr = static_cast<ChordRest*>(e); if(cr->type() == Element::CHORD) { Chord* chord = static_cast<Chord*>(cr); for (int idx = 0; idx < chord->notes().length(); idx++) { Note* note = chord->notes()[idx]; if (note->pitch() == pitch) { cs->startCmd(); cs->undo(new ChangeProperty(note, P_COLOR, noteColor)); cs->endCmd(); cs->end(); return; } } } } } }
bool isTied(const Segment *seg, int strack, int voice, Ms::Tie*(Note::*tieFunc)() const) { ChordRest *cr = static_cast<ChordRest *>(seg->element(strack + voice)); if (cr && cr->type() == Element::Type::CHORD) { Chord *chord = static_cast<Chord *>(cr); const auto ¬es = chord->notes(); for (const Note *note: notes) { if ((note->*tieFunc)()) return true; } } return false; }
void ScoreView::lyricsUpDown(bool up, bool end) { Lyrics* lyrics = toLyrics(editObject); int track = lyrics->track(); ChordRest* cr = lyrics->chordRest(); int verse = lyrics->no(); Element::Placement placement = lyrics->placement(); if (placement == Element::Placement::ABOVE) up = !up; if (up) { if (verse == 0) return; --verse; } else { ++verse; if (verse > cr->lastVerse(placement)) return; } endEdit(); _score->startCmd(); lyrics = cr->lyrics(verse, placement); if (!lyrics) { lyrics = new Lyrics(_score); lyrics->setTrack(track); lyrics->setParent(cr); lyrics->setNo(verse); lyrics->setPlacement(placement); _score->undoAddElement(lyrics); } _score->select(lyrics, SelectType::SINGLE, 0); startEdit(lyrics, Grip::NO_GRIP); mscore->changeState(mscoreState()); adjustCanvasPosition(lyrics, false); if (end) { ((Lyrics*)editObject)->movePosition(QTextCursor::Start, QTextCursor::MoveAnchor); ((Lyrics*)editObject)->movePosition(QTextCursor::End, QTextCursor::KeepAnchor); } else { ((Lyrics*)editObject)->movePosition(QTextCursor::End, QTextCursor::MoveAnchor); ((Lyrics*)editObject)->movePosition(QTextCursor::Start, QTextCursor::KeepAnchor); } _score->setLayoutAll(); _score->update(); }
ChordRest* nextChordRest(ChordRest* cr) { if (!cr) return 0; if (cr->isGrace()) { // cr is a grace note Chord* c = static_cast<Chord*>(cr); Chord* pc = static_cast<Chord*>(cr->parent()); QList<Chord*> graceNotesBefore; QList<Chord*> graceNotesAfter; if(cr->isGraceBefore()){ pc->getGraceNotesBefore(&graceNotesBefore); auto i = std::find(graceNotesBefore.begin(), graceNotesBefore.end(), c); if (i == graceNotesBefore.end()) return 0; ++i; if (i != graceNotesBefore.end()) return *i; } else { int n = pc->getGraceNotesAfter(&graceNotesAfter); for(int i = 0; i < n; i++){ if(c == graceNotesAfter[(i)]){ if(i < n - 1) return graceNotesAfter[i + 1]; else return 0; } } } return pc; } int track = cr->track(); Segment::SegmentTypes st = Segment::SegChordRest; for (Segment* seg = cr->segment()->next1(st); seg; seg = seg->next1(st)) { ChordRest* e = static_cast<ChordRest*>(seg->element(track)); if (e) { if (e->type() == Element::CHORD) { Chord* c = static_cast<Chord*>(e); if (!c->graceNotes().empty()) return c->graceNotes().front(); } return e; } } return 0; }
int Selection::tickStart() const { switch (_state) { case SelState::RANGE: return _startSegment->tick(); break; case SelState::LIST: { ChordRest* cr = firstChordRest(); return (cr) ? cr->tick() : -1; break; } default: return -1; } }
int Part::lyricCount() { if (!score()) return 0; int count = 0; Segment::Type st = Segment::Type::ChordRest; for (Segment* seg = score()->firstMeasure()->first(st); seg; seg = seg->next1(st)) { for (int i = startTrack(); i < endTrack() ; ++i) { ChordRest* cr = toChordRest(seg->element(i)); if (cr) count += cr->lyrics().size(); } } return count; }
void Glissando::layout() { Chord* chord = static_cast<Chord*>(parent()); if (chord == 0) { return; } Note* anchor2 = chord->upNote(); Segment* s = chord->segment(); s = s->prev1(); while (s) { if ((s->subtype() == SegChordRest || s->subtype() == SegGrace) && s->element(track())) break; s = s->prev1(); } if (s == 0) { qDebug("no segment for first note of glissando found\n"); return; } ChordRest* cr = static_cast<ChordRest*>(s->element(track())); if (cr == 0 || cr->type() != CHORD) { qDebug("no first note for glissando found, track %d\n", track()); return; } Note* anchor1 = static_cast<Chord*>(cr)->upNote(); setPos(0.0, 0.0); QPointF cp1 = anchor1->pagePos(); QPointF cp2 = anchor2->pagePos(); // construct line from notehead to notehead qreal x1 = (anchor1->headWidth()) - (cp2.x() - cp1.x()); qreal y1 = anchor1->pos().y(); qreal x2 = anchor2->pos().x(); qreal y2 = anchor2->pos().y(); QLineF fullLine(x1, y1, x2, y2); // shorten line on each side by offsets qreal xo = spatium() * .5; qreal yo = xo; // spatium() * .5; QPointF p1 = fullLine.pointAt(xo / fullLine.length()); QPointF p2 = fullLine.pointAt(1 - (yo / fullLine.length())); line = QLineF(p1, p2); qreal lw = spatium() * .15 * .5; QRectF r = QRectF(line.p1(), line.p2()).normalized(); setbbox(r.adjusted(-lw, -lw, lw, lw)); }
Segment* Articulation::segment() const { ChordRest* cr = chordRest(); if (!cr) return 0; Segment* s = 0; if (cr->isGrace()) { if (cr->parent()) s = toSegment(cr->parent()->parent()); } else s = toSegment(cr->parent()); return s; }
QPointF Articulation::pagePos() const { if (parent() == 0 || parent()->parent() == 0) return pos(); if (parent()->isChordRest()) { ChordRest* cr = static_cast<ChordRest*>(parent()); Measure* m = cr->measure(); if (m == 0) return pos(); System* system = m->system(); if (system == 0) return pos(); qreal yp = y() + system->staff(staffIdx() + cr->staffMove())->y() + system->y(); return QPointF(pageX(), yp); } return Element::pagePos(); }
QPointF Arpeggio::gripAnchor(int n) const { Chord* c = chord(); if (c == 0) return QPointF(); if (n == 0) return c->upNote()->pagePos(); else if (n == 1) { Note* dnote = c->downNote(); int btrack = track() + (_span - 1) * VOICES; ChordRest* bchord = static_cast<ChordRest*>(c->segment()->element(btrack)); if (bchord && bchord->type() == CHORD) dnote = static_cast<Chord*>(bchord)->downNote(); return dnote->pagePos(); } return QPointF(); }
void ScoreView::lyricsReturn() { Lyrics* lyrics = (Lyrics*)editObject; Segment* segment = lyrics->segment(); endEdit(); _score->startCmd(); Lyrics* oldLyrics = lyrics; int newVerse; if (lyrics->placeAbove()) { newVerse = oldLyrics->no() - 1; if (newVerse == -1) { // raise all lyrics above newVerse = 0; for (Segment* s = _score->firstSegment(Segment::Type::ChordRest); s; s = s->next1(Segment::Type::ChordRest)) { ChordRest* cr = s->cr(lyrics->track()); if (cr) { for (Lyrics* l : cr->lyrics()) { if (l->placement() == oldLyrics->placement()) l->undoChangeProperty(P_ID::VERSE, l->no() + 1); } } } } } else newVerse = oldLyrics->no() + 1; lyrics = static_cast<Lyrics*>(Element::create(lyrics->type(), _score)); lyrics->setTrack(oldLyrics->track()); lyrics->setParent(segment->element(oldLyrics->track())); lyrics->setPlacement(oldLyrics->placement()); lyrics->setNo(newVerse); _score->undoAddElement(lyrics); _score->select(lyrics, SelectType::SINGLE, 0); startEdit(lyrics, Grip::NO_GRIP); mscore->changeState(mscoreState()); adjustCanvasPosition(lyrics, false); _score->setLayoutAll(); _score->update(); }
ChordRest* Selection::firstChordRest(int track) const { ChordRest* cr = 0; foreach (Element* el, _el) { if (el->type() == NOTE) el = el->parent(); if (el->isChordRest()) { if (track != -1 && el->track() != track) continue; if (cr) { if (static_cast<ChordRest*>(el)->tick() < cr->tick()) cr = static_cast<ChordRest*>(el); } else cr = static_cast<ChordRest*>(el); } } return cr; }