void ScoreView::lyricsReturn() { Lyrics* lyrics = toLyrics(editData.element); changeState(ViewState::NORMAL); _score->startCmd(); int newVerse; newVerse = lyrics->no() + 1; Lyrics* oldLyrics = lyrics; lyrics = new Lyrics(_score); lyrics->setTrack(oldLyrics->track()); lyrics->setParent(oldLyrics->segment()->element(oldLyrics->track())); lyrics->setPlacement(oldLyrics->placement()); lyrics->setPropertyFlags(Pid::PLACEMENT, oldLyrics->propertyFlags(Pid::PLACEMENT)); lyrics->setNo(newVerse); _score->undoAddElement(lyrics); _score->endCmd(); _score->select(lyrics, SelectType::SINGLE, 0); startEdit(lyrics, Grip::NO_GRIP); adjustCanvasPosition(lyrics, false); }
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 ScoreView::lyricsUnderscore() { Lyrics* lyrics = toLyrics(editData.element); int track = lyrics->track(); Segment* segment = lyrics->segment(); int verse = lyrics->no(); Placement placement = lyrics->placement(); PropertyFlags pFlags = lyrics->propertyFlags(Pid::PLACEMENT); int endTick = segment->tick(); // a previous melisma cannot extend beyond this point changeState(ViewState::NORMAL); // search next chord Segment* nextSegment = segment; while ((nextSegment = nextSegment->next1(SegmentType::ChordRest))) { Element* el = nextSegment->element(track); if (el && el->isChord()) break; } // look for the lyrics we are moving from; may be the current lyrics or a previous one // we are extending with several underscores Lyrics* fromLyrics = 0; while (segment) { ChordRest* cr = toChordRest(segment->element(track)); if (cr) { fromLyrics = cr->lyrics(verse, placement); if (fromLyrics) break; } segment = segment->prev1(SegmentType::ChordRest); // if the segment has a rest in this track, stop going back Element* e = segment ? segment->element(track) : 0; if (e && !e->isChord()) break; } // one-chord melisma? // if still at melisma initial chord and there is a valid next chord (if not, // there will be no melisma anyway), set a temporary melisma duration if (fromLyrics == lyrics && nextSegment) { _score->startCmd(); lyrics->undoChangeProperty(Pid::LYRIC_TICKS, Lyrics::TEMP_MELISMA_TICKS); _score->setLayoutAll(); _score->endCmd(); } if (nextSegment == 0) { _score->startCmd(); if (fromLyrics) { switch(fromLyrics->syllabic()) { case Lyrics::Syllabic::SINGLE: case Lyrics::Syllabic::END: break; default: fromLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::END)); break; } if (fromLyrics->segment()->tick() < endTick) fromLyrics->undoChangeProperty(Pid::LYRIC_TICKS, endTick - fromLyrics->segment()->tick()); } // leave edit mode, select something (just for user feedback) and update to show extended melisam mscore->changeState(STATE_NORMAL); if (fromLyrics) _score->select(fromLyrics, SelectType::SINGLE, 0); _score->setLayoutAll(); _score->endCmd(); return; } // if a place for a new lyrics has been found, create a lyrics there ChordRest* cr = toChordRest(nextSegment->element(track)); Lyrics* toLyrics = cr->lyrics(verse, placement); bool newLyrics = (toLyrics == 0); if (!toLyrics) { toLyrics = new Lyrics(_score); toLyrics->setTrack(track); toLyrics->setParent(nextSegment->element(track)); toLyrics->setNo(verse); toLyrics->setPlacement(placement); toLyrics->setPropertyFlags(Pid::PLACEMENT, pFlags); toLyrics->setSyllabic(Lyrics::Syllabic::SINGLE); } // as we arrived at toLyrics by an underscore, it cannot have syllabic dashes before else if (toLyrics->syllabic() == Lyrics::Syllabic::MIDDLE) toLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::BEGIN)); else if (toLyrics->syllabic() == Lyrics::Syllabic::END) toLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::SINGLE)); if (fromLyrics) { // as we moved away from fromLyrics by an underscore, // it can be isolated or terminal but cannot have dashes after switch(fromLyrics->syllabic()) { case Lyrics::Syllabic::SINGLE: case Lyrics::Syllabic::END: break; default: fromLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::END)); break; } // for the same reason, if it has a melisma, this cannot extend beyond toLyrics if (fromLyrics->segment()->tick() < endTick) fromLyrics->undoChangeProperty(Pid::LYRIC_TICKS, endTick - fromLyrics->segment()->tick()); } if (newLyrics) _score->undoAddElement(toLyrics); _score->endCmd(); _score->select(toLyrics, SelectType::SINGLE, 0); startEdit(toLyrics, Grip::NO_GRIP); adjustCanvasPosition(toLyrics, false); TextCursor* cursor = Ms::toLyrics(editData.element)->cursor(editData); Ms::toLyrics(editData.element)->selectAll(cursor); }
void ScoreView::lyricsMinus() { Lyrics* lyrics = toLyrics(editData.element); int track = lyrics->track(); Segment* segment = lyrics->segment(); int verse = lyrics->no(); Placement placement = lyrics->placement(); PropertyFlags pFlags = lyrics->propertyFlags(Pid::PLACEMENT); changeState(ViewState::NORMAL); // search next chord Segment* nextSegment = segment; while ((nextSegment = nextSegment->next1(SegmentType::ChordRest))) { Element* el = nextSegment->element(track); if (el && el->isChord()) break; } if (nextSegment == 0) return; // look for the lyrics we are moving from; may be the current lyrics or a previous one // we are extending with several dashes Lyrics* fromLyrics = 0; while (segment) { ChordRest* cr = toChordRest(segment->element(track)); if (!cr) { segment = segment->prev1(SegmentType::ChordRest); continue; } fromLyrics = cr->lyrics(verse, placement); if (fromLyrics) break; segment = segment->prev1(SegmentType::ChordRest); } _score->startCmd(); ChordRest* cr = toChordRest(nextSegment->element(track)); Lyrics* toLyrics = cr->lyrics(verse, placement); bool newLyrics = (toLyrics == 0); if (!toLyrics) { toLyrics = new Lyrics(_score); toLyrics->setTrack(track); toLyrics->setParent(nextSegment->element(track)); toLyrics->setNo(verse); toLyrics->setPlacement(placement); toLyrics->setPropertyFlags(Pid::PLACEMENT, pFlags); toLyrics->setSyllabic(Lyrics::Syllabic::END); } else { // as we arrived at toLyrics by a dash, it cannot be initial or isolated if (toLyrics->syllabic() == Lyrics::Syllabic::BEGIN) toLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::MIDDLE)); else if (toLyrics->syllabic() == Lyrics::Syllabic::SINGLE) toLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::END)); } if (fromLyrics) { // as we moved away from fromLyrics by a dash, // it can have syll. dashes before and after but cannot be isolated or terminal switch(fromLyrics->syllabic()) { case Lyrics::Syllabic::BEGIN: case Lyrics::Syllabic::MIDDLE: break; case Lyrics::Syllabic::SINGLE: fromLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::BEGIN)); break; case Lyrics::Syllabic::END: fromLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::MIDDLE)); break; } // for the same reason, it cannot have a melisma fromLyrics->undoChangeProperty(Pid::LYRIC_TICKS, 0); } if (newLyrics) _score->undoAddElement(toLyrics); _score->endCmd(); _score->select(toLyrics, SelectType::SINGLE, 0); startEdit(toLyrics, Grip::NO_GRIP); adjustCanvasPosition(toLyrics, false); TextCursor* cursor = Ms::toLyrics(editData.element)->cursor(editData); Ms::toLyrics(editData.element)->selectAll(cursor); _score->setLayoutAll(); }