MuseScore/mscore/editlyrics.cpp

552 lines
21 KiB
C++
Raw Normal View History

2013-02-26 15:50:36 +01:00
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2002-2017 Werner Schweer
2013-02-26 15:50:36 +01:00
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================
#include "musescore.h"
#include "scoreview.h"
2017-05-03 16:20:04 +02:00
#include "texttools.h"
#include "libmscore/chordrest.h"
#include "libmscore/lyrics.h"
2013-02-26 15:50:36 +01:00
#include "libmscore/score.h"
#include "libmscore/segment.h"
#include "libmscore/undo.h"
2013-02-26 15:50:36 +01:00
2013-05-13 18:49:17 +02:00
namespace Ms {
2017-05-03 16:20:04 +02:00
//---------------------------------------------------------
// editKeyLyrics
// return true if key is handled
2017-05-03 16:20:04 +02:00
//---------------------------------------------------------
bool ScoreView::editKeyLyrics()
2017-05-03 16:20:04 +02:00
{
2018-06-11 15:54:58 +02:00
Q_ASSERT(editData.element->isLyrics());
2017-05-03 16:20:04 +02:00
const bool textEditing = true;
2017-05-03 16:20:04 +02:00
switch (editData.key) {
case Qt::Key_Space:
if (!editData.control(textEditing)) {
2017-05-03 16:20:04 +02:00
if (editData.s == "_")
lyricsUnderscore();
else // TODO: shift+tab events are filtered by qt
lyricsTab(editData.modifiers & Qt::ShiftModifier, true, false);
}
else
return false;
break;
case Qt::Key_Left:
case Qt::Key_Right:
if (!editData.control(textEditing) && editData.element->edit(editData))
2017-05-03 16:20:04 +02:00
mscore->textTools()->updateTools(editData);
else {
bool kl = editData.key == Qt::Key_Left;
lyricsTab(kl, kl, true); // go to previous/next lyrics
}
break;
case Qt::Key_Up:
case Qt::Key_Down:
lyricsUpDown(editData.key == Qt::Key_Up, true);
break;
case Qt::Key_Return:
lyricsReturn();
break;
case Qt::Key_Minus:
if (editData.control(textEditing)) {
// change into normal minus
editData.modifiers &= ~CONTROL_MODIFIER;
return false;
}
else
lyricsMinus();
break;
case Qt::Key_Underscore:
if (editData.control(textEditing)) {
// change into normal underscore
editData.modifiers = 0; // &= ~CONTROL_MODIFIER;
return false;
2017-05-03 16:20:04 +02:00
}
else
lyricsUnderscore();
2017-05-03 16:20:04 +02:00
break;
default:
return false;
2017-05-03 16:20:04 +02:00
}
return true;
}
2013-02-26 15:50:36 +01:00
//---------------------------------------------------------
// lyricsUpDown
//---------------------------------------------------------
void ScoreView::lyricsUpDown(bool up, bool end)
{
2018-07-19 13:03:25 +02:00
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);
2013-02-26 15:50:36 +01:00
if (up) {
if (verse == 0)
return;
--verse;
}
else {
++verse;
2016-08-27 13:09:27 +02:00
if (verse > cr->lastVerse(placement))
2013-02-26 15:50:36 +01:00
return;
}
2016-08-27 13:09:27 +02:00
changeState(ViewState::NORMAL);
2016-08-24 14:49:34 +02:00
lyrics = cr->lyrics(verse, placement);
2013-02-26 15:50:36 +01:00
if (!lyrics) {
lyrics = new Lyrics(_score);
lyrics->setTrack(track);
lyrics->setParent(cr);
lyrics->setNo(verse);
2016-08-24 14:49:34 +02:00
lyrics->setPlacement(placement);
2018-07-19 13:03:25 +02:00
lyrics->setPropertyFlags(Pid::PLACEMENT, pFlags);
_score->startCmd();
2013-02-26 15:50:36 +01:00
_score->undoAddElement(lyrics);
_score->endCmd();
2013-02-26 15:50:36 +01:00
}
_score->select(lyrics, SelectType::SINGLE, 0);
startEdit(lyrics, Grip::NO_GRIP);
mscore->changeState(mscoreState());
2013-02-26 15:50:36 +01:00
adjustCanvasPosition(lyrics, false);
2017-05-02 14:17:31 +02:00
lyrics = toLyrics(editData.element);
TextCursor* cursor = lyrics->cursor(editData);
2015-02-02 18:59:01 +01:00
if (end) {
cursor->movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
cursor->movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
2015-02-02 18:59:01 +01:00
}
else {
cursor->movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
cursor->movePosition(QTextCursor::Start, QTextCursor::KeepAnchor);
2015-02-02 18:59:01 +01:00
}
2013-02-26 15:50:36 +01:00
2016-03-02 13:20:19 +01:00
_score->setLayoutAll();
2013-06-05 15:47:34 +02:00
_score->update();
2013-02-26 15:50:36 +01:00
}
//---------------------------------------------------------
// lyricsTab
//---------------------------------------------------------
void ScoreView::lyricsTab(bool back, bool end, bool moveOnly)
{
2017-05-03 10:31:11 +02:00
Lyrics* lyrics = toLyrics(editData.element);
2013-02-26 15:50:36 +01:00
int track = lyrics->track();
Segment* segment = lyrics->segment();
int verse = lyrics->no();
2018-01-16 13:38:17 +01:00
Placement placement = lyrics->placement();
2018-07-19 13:03:25 +02:00
PropertyFlags pFlags = lyrics->propertyFlags(Pid::PLACEMENT);
2013-02-26 15:50:36 +01:00
Segment* nextSegment = segment;
if (back) {
// search prev chord
2017-03-08 13:12:26 +01:00
while ((nextSegment = nextSegment->prev1(SegmentType::ChordRest))) {
2013-02-26 15:50:36 +01:00
Element* el = nextSegment->element(track);
if (el && el->isChord())
2013-02-26 15:50:36 +01:00
break;
}
}
else {
// search next chord
2017-03-08 13:12:26 +01:00
while ((nextSegment = nextSegment->next1(SegmentType::ChordRest))) {
2013-02-26 15:50:36 +01:00
Element* el = nextSegment->element(track);
2018-06-11 15:54:58 +02:00
if (el && el->isChord())
2013-02-26 15:50:36 +01:00
break;
}
}
if (nextSegment == 0)
return;
changeState(ViewState::NORMAL);
2013-02-26 15:50:36 +01:00
// look for the lyrics we are moving from; may be the current lyrics or a previous one
// if we are skipping several chords with spaces
Lyrics* fromLyrics = 0;
2013-02-26 15:50:36 +01:00
if (!back) {
while (segment) {
2016-08-17 12:52:35 +02:00
ChordRest* cr = toChordRest(segment->element(track));
if (cr) {
2016-08-24 14:49:34 +02:00
fromLyrics = cr->lyrics(verse, placement);
if (fromLyrics)
2013-02-26 15:50:36 +01:00
break;
}
2017-03-08 13:12:26 +01:00
segment = segment->prev1(SegmentType::ChordRest);
2013-02-26 15:50:36 +01:00
}
}
2016-08-17 12:52:35 +02:00
ChordRest* cr = toChordRest(nextSegment->element(track));
if (!cr) {
2013-02-26 15:50:36 +01:00
qDebug("no next lyrics list: %s", nextSegment->element(track)->name());
return;
}
Lyrics* _toLyrics = cr->lyrics(verse, placement);
2013-02-26 15:50:36 +01:00
bool newLyrics = false;
if (!_toLyrics) {
_toLyrics = new Lyrics(_score);
_toLyrics->setTrack(track);
cr = toChordRest(nextSegment->element(track));
_toLyrics->setParent(cr);
_toLyrics->setNo(verse);
_toLyrics->setPlacement(placement);
2018-07-19 13:03:25 +02:00
_toLyrics->setPropertyFlags(Pid::PLACEMENT, pFlags);
_toLyrics->setSyllabic(Lyrics::Syllabic::SINGLE);
2013-02-26 15:50:36 +01:00
newLyrics = true;
}
_score->startCmd();
if (fromLyrics && !moveOnly) {
switch (_toLyrics->syllabic()) {
// as we arrived at toLyrics by a [Space], it can be the beginning
// of a multi-syllable, but cannot have syllabic dashes before
2014-05-22 21:51:34 +02:00
case Lyrics::Syllabic::SINGLE:
case Lyrics::Syllabic::BEGIN:
2013-02-26 15:50:36 +01:00
break;
2014-05-22 21:51:34 +02:00
case Lyrics::Syllabic::END:
2018-03-27 15:36:00 +02:00
_toLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::SINGLE));
2013-02-26 15:50:36 +01:00
break;
2014-05-22 21:51:34 +02:00
case Lyrics::Syllabic::MIDDLE:
2018-03-27 15:36:00 +02:00
_toLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::BEGIN));
2013-02-26 15:50:36 +01:00
break;
}
// as we moved away from fromLyrics by a [Space], it can be
// the end of a multi-syllable, but cannot have syllabic dashes after
2017-05-03 10:31:11 +02:00
switch (fromLyrics->syllabic()) {
2014-05-22 21:51:34 +02:00
case Lyrics::Syllabic::SINGLE:
case Lyrics::Syllabic::END:
2013-02-26 15:50:36 +01:00
break;
2014-05-22 21:51:34 +02:00
case Lyrics::Syllabic::BEGIN:
2018-03-27 15:36:00 +02:00
fromLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::SINGLE));
2013-02-26 15:50:36 +01:00
break;
2014-05-22 21:51:34 +02:00
case Lyrics::Syllabic::MIDDLE:
2018-03-27 15:36:00 +02:00
fromLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::END));
2013-02-26 15:50:36 +01:00
break;
}
// for the same reason, it cannot have a melisma
2018-03-27 15:36:00 +02:00
fromLyrics->undoChangeProperty(Pid::LYRIC_TICKS, 0);
2013-02-26 15:50:36 +01:00
}
if (newLyrics)
_score->undoAddElement(_toLyrics);
_score->endCmd();
2013-02-26 15:50:36 +01:00
_score->select(_toLyrics, SelectType::SINGLE, 0);
startEdit(_toLyrics, Grip::NO_GRIP);
2013-02-26 15:50:36 +01:00
adjustCanvasPosition(_toLyrics, false);
2017-05-02 14:17:31 +02:00
TextCursor* cursor = toLyrics(editData.element)->cursor(editData);
2015-02-02 18:59:01 +01:00
if (end) {
cursor->movePosition(QTextCursor::Start, QTextCursor::MoveAnchor);
cursor->movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
2015-02-02 18:59:01 +01:00
}
else {
cursor->movePosition(QTextCursor::End, QTextCursor::MoveAnchor);
cursor->movePosition(QTextCursor::Start, QTextCursor::KeepAnchor);
2015-02-02 18:59:01 +01:00
}
2016-03-02 13:20:19 +01:00
_score->setLayoutAll();
2013-02-26 15:50:36 +01:00
}
//---------------------------------------------------------
// lyricsMinus
//---------------------------------------------------------
void ScoreView::lyricsMinus()
{
2017-05-02 14:17:31 +02:00
Lyrics* lyrics = toLyrics(editData.element);
2013-02-26 15:50:36 +01:00
int track = lyrics->track();
Segment* segment = lyrics->segment();
int verse = lyrics->no();
2018-01-16 13:38:17 +01:00
Placement placement = lyrics->placement();
2018-07-19 13:03:25 +02:00
PropertyFlags pFlags = lyrics->propertyFlags(Pid::PLACEMENT);
2013-02-26 15:50:36 +01:00
changeState(ViewState::NORMAL);
2013-02-26 15:50:36 +01:00
// search next chord
Segment* nextSegment = segment;
2017-03-08 13:12:26 +01:00
while ((nextSegment = nextSegment->next1(SegmentType::ChordRest))) {
2013-02-26 15:50:36 +01:00
Element* el = nextSegment->element(track);
if (el && el->isChord())
2013-02-26 15:50:36 +01:00
break;
}
2014-08-27 10:31:52 +02:00
if (nextSegment == 0)
2013-02-26 15:50:36 +01:00
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;
2013-02-26 15:50:36 +01:00
while (segment) {
2016-08-17 12:52:35 +02:00
ChordRest* cr = toChordRest(segment->element(track));
if (!cr) {
2017-03-08 13:12:26 +01:00
segment = segment->prev1(SegmentType::ChordRest);
2013-02-26 15:50:36 +01:00
continue;
}
2016-08-24 14:49:34 +02:00
fromLyrics = cr->lyrics(verse, placement);
if (fromLyrics)
2013-02-26 15:50:36 +01:00
break;
2017-03-08 13:12:26 +01:00
segment = segment->prev1(SegmentType::ChordRest);
2013-02-26 15:50:36 +01:00
}
_score->startCmd();
2016-08-17 12:52:35 +02:00
ChordRest* cr = toChordRest(nextSegment->element(track));
2016-08-24 14:49:34 +02:00
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);
2016-08-24 14:49:34 +02:00
toLyrics->setPlacement(placement);
2018-07-19 13:03:25 +02:00
toLyrics->setPropertyFlags(Pid::PLACEMENT, pFlags);
toLyrics->setSyllabic(Lyrics::Syllabic::END);
2013-02-26 15:50:36 +01:00
}
2014-08-27 10:31:52 +02:00
else {
// as we arrived at toLyrics by a dash, it cannot be initial or isolated
if (toLyrics->syllabic() == Lyrics::Syllabic::BEGIN)
2018-03-27 15:36:00 +02:00
toLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::MIDDLE));
else if (toLyrics->syllabic() == Lyrics::Syllabic::SINGLE)
2018-03-27 15:36:00 +02:00
toLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::END));
2013-02-26 15:50:36 +01:00
}
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()) {
2014-05-22 21:51:34 +02:00
case Lyrics::Syllabic::BEGIN:
case Lyrics::Syllabic::MIDDLE:
2013-02-26 15:50:36 +01:00
break;
2014-05-22 21:51:34 +02:00
case Lyrics::Syllabic::SINGLE:
2018-03-27 15:36:00 +02:00
fromLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::BEGIN));
2013-02-26 15:50:36 +01:00
break;
2014-05-22 21:51:34 +02:00
case Lyrics::Syllabic::END:
2018-03-27 15:36:00 +02:00
fromLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::MIDDLE));
2013-02-26 15:50:36 +01:00
break;
}
// for the same reason, it cannot have a melisma
2018-03-27 15:36:00 +02:00
fromLyrics->undoChangeProperty(Pid::LYRIC_TICKS, 0);
2013-02-26 15:50:36 +01:00
}
2014-08-27 10:31:52 +02:00
if (newLyrics)
_score->undoAddElement(toLyrics);
_score->endCmd();
2013-02-26 15:50:36 +01:00
_score->select(toLyrics, SelectType::SINGLE, 0);
startEdit(toLyrics, Grip::NO_GRIP);
2013-02-26 15:50:36 +01:00
adjustCanvasPosition(toLyrics, false);
2017-05-02 14:17:31 +02:00
TextCursor* cursor = Ms::toLyrics(editData.element)->cursor(editData);
Ms::toLyrics(editData.element)->selectAll(cursor);
2016-03-02 13:20:19 +01:00
_score->setLayoutAll();
2013-02-26 15:50:36 +01:00
}
//---------------------------------------------------------
// lyricsUnderscore
//---------------------------------------------------------
void ScoreView::lyricsUnderscore()
{
Lyrics* lyrics = toLyrics(editData.element);
int track = lyrics->track();
Segment* segment = lyrics->segment();
int verse = lyrics->no();
Placement placement = lyrics->placement();
2018-07-19 13:03:25 +02:00
PropertyFlags pFlags = lyrics->propertyFlags(Pid::PLACEMENT);
Fraction endTick = segment->tick(); // a previous melisma cannot extend beyond this point
2013-02-26 15:50:36 +01:00
changeState(ViewState::NORMAL);
2013-02-26 15:50:36 +01:00
// search next chord
Segment* nextSegment = segment;
2017-03-08 13:12:26 +01:00
while ((nextSegment = nextSegment->next1(SegmentType::ChordRest))) {
2013-02-26 15:50:36 +01:00
Element* el = nextSegment->element(track);
if (el && el->isChord())
2013-02-26 15:50:36 +01:00
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;
2013-02-26 15:50:36 +01:00
while (segment) {
2016-08-17 12:52:35 +02:00
ChordRest* cr = toChordRest(segment->element(track));
if (cr) {
2016-08-24 14:49:34 +02:00
fromLyrics = cr->lyrics(verse, placement);
if (fromLyrics)
2013-02-26 15:50:36 +01:00
break;
}
2017-03-08 13:12:26 +01:00
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;
2013-02-26 15:50:36 +01:00
}
// 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, Fraction::fromTicks(Lyrics::TEMP_MELISMA_TICKS));
_score->setLayoutAll();
_score->endCmd();
}
2013-02-26 15:50:36 +01:00
if (nextSegment == 0) {
_score->startCmd();
if (fromLyrics) {
switch(fromLyrics->syllabic()) {
2014-05-22 21:51:34 +02:00
case Lyrics::Syllabic::SINGLE:
case Lyrics::Syllabic::END:
2013-02-26 15:50:36 +01:00
break;
default:
2018-03-27 15:36:00 +02:00
fromLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::END));
2013-02-26 15:50:36 +01:00
break;
}
if (fromLyrics->segment()->tick() < endTick)
2018-03-27 15:36:00 +02:00
fromLyrics->undoChangeProperty(Pid::LYRIC_TICKS, endTick - fromLyrics->segment()->tick());
2013-02-26 15:50:36 +01:00
}
// 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);
2016-03-02 13:20:19 +01:00
_score->setLayoutAll();
_score->endCmd();
2013-02-26 15:50:36 +01:00
return;
}
// if a place for a new lyrics has been found, create a lyrics there
2013-02-26 15:50:36 +01:00
2016-08-24 14:49:34 +02:00
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);
2016-08-24 14:49:34 +02:00
toLyrics->setPlacement(placement);
2018-07-19 13:03:25 +02:00
toLyrics->setPropertyFlags(Pid::PLACEMENT, pFlags);
toLyrics->setSyllabic(Lyrics::Syllabic::SINGLE);
2013-02-26 15:50:36 +01:00
}
// as we arrived at toLyrics by an underscore, it cannot have syllabic dashes before
else if (toLyrics->syllabic() == Lyrics::Syllabic::MIDDLE)
2018-03-27 15:36:00 +02:00
toLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::BEGIN));
else if (toLyrics->syllabic() == Lyrics::Syllabic::END)
2018-03-27 15:36:00 +02:00
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()) {
2014-05-22 21:51:34 +02:00
case Lyrics::Syllabic::SINGLE:
case Lyrics::Syllabic::END:
2013-02-26 15:50:36 +01:00
break;
default:
2018-03-27 15:36:00 +02:00
fromLyrics->undoChangeProperty(Pid::SYLLABIC, int(Lyrics::Syllabic::END));
2013-02-26 15:50:36 +01:00
break;
}
// for the same reason, if it has a melisma, this cannot extend beyond toLyrics
if (fromLyrics->segment()->tick() < endTick)
2018-03-27 15:36:00 +02:00
fromLyrics->undoChangeProperty(Pid::LYRIC_TICKS, endTick - fromLyrics->segment()->tick());
2013-02-26 15:50:36 +01:00
}
if (newLyrics)
_score->undoAddElement(toLyrics);
_score->endCmd();
2013-02-26 15:50:36 +01:00
_score->select(toLyrics, SelectType::SINGLE, 0);
startEdit(toLyrics, Grip::NO_GRIP);
2013-02-26 15:50:36 +01:00
adjustCanvasPosition(toLyrics, false);
2017-05-02 14:17:31 +02:00
TextCursor* cursor = Ms::toLyrics(editData.element)->cursor(editData);
Ms::toLyrics(editData.element)->selectAll(cursor);
2013-02-26 15:50:36 +01:00
}
//---------------------------------------------------------
// lyricsReturn
//---------------------------------------------------------
void ScoreView::lyricsReturn()
{
2018-07-19 13:03:25 +02:00
Lyrics* lyrics = toLyrics(editData.element);
2013-02-26 15:50:36 +01:00
changeState(ViewState::NORMAL);
2013-02-26 15:50:36 +01:00
_score->startCmd();
2016-08-27 13:09:27 +02:00
int newVerse;
2018-07-19 13:03:25 +02:00
newVerse = lyrics->no() + 1;
Lyrics* oldLyrics = lyrics;
lyrics = new Lyrics(_score);
2013-02-26 15:50:36 +01:00
lyrics->setTrack(oldLyrics->track());
2018-07-19 13:03:25 +02:00
lyrics->setParent(oldLyrics->segment()->element(oldLyrics->track()));
2016-08-24 14:49:34 +02:00
lyrics->setPlacement(oldLyrics->placement());
2018-07-19 13:03:25 +02:00
lyrics->setPropertyFlags(Pid::PLACEMENT, oldLyrics->propertyFlags(Pid::PLACEMENT));
2016-08-27 13:09:27 +02:00
lyrics->setNo(newVerse);
2013-02-26 15:50:36 +01:00
_score->undoAddElement(lyrics);
_score->endCmd();
_score->select(lyrics, SelectType::SINGLE, 0);
startEdit(lyrics, Grip::NO_GRIP);
2013-02-26 15:50:36 +01:00
adjustCanvasPosition(lyrics, false);
}
//---------------------------------------------------------
// lyricsEndEdit
//---------------------------------------------------------
void ScoreView::lyricsEndEdit()
{
2017-05-02 14:17:31 +02:00
Lyrics* lyrics = toLyrics(editData.element);
2013-02-26 15:50:36 +01:00
// 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;
2013-02-26 15:50:36 +01:00
}
segment = segment->prev1(SegmentType::ChordRest);
}
if (prevLyrics && prevLyrics->syllabic() == Lyrics::Syllabic::END) {
Fraction 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());
2013-02-26 15:50:36 +01:00
}
}
2013-05-13 18:49:17 +02:00
}
2013-02-26 15:50:36 +01:00