# HG changeset patch # User Chris Cannam # Date 1561025459 -3600 # Node ID 2cf4978eb724958ff4b45c0d725c4a38f9a5e3cf # Parent c6c8c1645ab6878f825ad24989c2276a4f59ca17 Fix failure of "Form Note from Selection" to work correctly when an existing note spanned one end of the selection but did not reach the other. Also update subrepos to fix a deadlock diff -r c6c8c1645ab6 -r 2cf4978eb724 repoint-lock.json --- a/repoint-lock.json Wed Jun 19 13:33:33 2019 +0100 +++ b/repoint-lock.json Thu Jun 20 11:10:59 2019 +0100 @@ -4,7 +4,7 @@ "pin": "62987b6d6a3b" }, "svcore": { - "pin": "78fe29adfd16" + "pin": "8efce64dd85e" }, "svgui": { "pin": "de41a11cabc2" diff -r c6c8c1645ab6 -r 2cf4978eb724 src/MainWindow.cpp --- a/src/MainWindow.cpp Wed Jun 19 13:33:33 2019 +0100 +++ b/src/MainWindow.cpp Thu Jun 20 11:10:59 2019 +0100 @@ -2652,11 +2652,10 @@ void MainWindow::formNoteFromSelection() { + Pane *pane = m_analyser->getPane(); Layer *layer0 = m_analyser->getLayer(Analyser::Notes); NoteModel *model = qobject_cast(layer0->getModel()); - - FlexiNoteLayer *layer = - qobject_cast(m_analyser->getLayer(Analyser::Notes)); + FlexiNoteLayer *layer = qobject_cast(layer0); if (!layer) return; MultiSelection::SelectionList selections = m_viewManager->getSelections(); @@ -2665,21 +2664,37 @@ CommandHistory::getInstance()->startCompoundOperation (tr("Form Note from Selection"), true); + for (MultiSelection::SelectionList::iterator k = selections.begin(); k != selections.end(); ++k) { - //!!! This fails in the case where an existing note spans - //!!! one end of the selection but does not reach the - //!!! other end - it doesn't get extended - if (!model->getEventsSpanning(k->getStartFrame(), - k->getEndFrame() - k->getStartFrame()).empty()) { - layer->splitNotesAt(m_analyser->getPane(), k->getStartFrame()); - layer->splitNotesAt(m_analyser->getPane(), k->getEndFrame()); - layer->mergeNotes(m_analyser->getPane(), *k, false); - } else { - layer->addNoteOn(k->getStartFrame(), 100, 100); - layer->addNoteOff(k->getEndFrame(), 100); - layer->mergeNotes(m_analyser->getPane(), *k, false); // only so the note adapts in case of existing pitch track + + // Chop existing events at start and end frames; remember + // the first starting pitch, to use as default for new + // note; delete existing events; create new note; ask + // layer to merge, just in order to adapt the note to the + // existing pitch track if possible. This way we should + // handle all the possible cases of existing notes that + // may or may not overlap the start or end times + + sv_frame_t start = k->getStartFrame(); + sv_frame_t end = k->getEndFrame(); + + EventVector existing = + model->getEventsStartingWithin(start, end - start); + + int defaultPitch = 100; + if (!existing.empty()) { + defaultPitch = int(roundf(existing.begin()->getValue())); } + + layer->splitNotesAt(pane, start); + layer->splitNotesAt(pane, end); + layer->deleteSelection(*k); + + layer->addNoteOn(start, defaultPitch, 100); + layer->addNoteOff(end, defaultPitch); + + layer->mergeNotes(pane, *k, false); } CommandHistory::getInstance()->endCompoundOperation();