3838#include < dspxmodel/NoteSelectionModel.h>
3939#include < dspxmodel/Note.h>
4040#include < dspxmodel/NoteSequence.h>
41+ #include < dspxmodel/PhonemeInfo.h>
42+ #include < dspxmodel/PhonemeSequence.h>
43+ #include < dspxmodel/Phoneme.h>
4144
4245#include < coreplugin/DspxDocument.h>
4346#include < coreplugin/ProjectTimeline.h>
@@ -313,23 +316,29 @@ namespace Core {
313316 }
314317 }
315318
316- void InsertItemScenario::insertNote () const {
319+ void InsertItemScenario::insertNote (dspx::SingingClip *clip ) const {
317320 Q_D (const InsertItemScenario);
318321 if (!document () || !d->projectTimeline || !window ())
319322 return ;
320323
321324 auto model = document ()->model ();
322325 auto selectionModel = document ()->selectionModel ();
323- auto noteSelectionModel = selectionModel->noteSelectionModel ();
324326
325- auto noteSequence = noteSelectionModel->noteSequenceWithSelectedItems ();
326- if (!noteSequence)
327- return ;
327+ dspx::NoteSequence *noteSequence = nullptr ;
328+
329+ // If clip is provided, use it and its notes
330+ if (clip) {
331+ noteSequence = clip->notes ();
332+ } else {
333+ auto noteSelectionModel = selectionModel->noteSelectionModel ();
334+ noteSequence = noteSelectionModel->noteSequenceWithSelectedItems ();
335+ if (!noteSequence)
336+ return ;
337+ clip = noteSequence->singingClip ();
338+ }
328339
329340 qCInfo (lcInsertItemScenario) << " Inserting note" ;
330341
331- auto clip = noteSequence->singingClip ();
332-
333342 // Calculate initial position: playback position - clip position
334343 const int clipPosition = clip->position ();
335344 const int initialPosition = qMax (0 , d->projectTimeline ->position () - clipPosition);
@@ -376,6 +385,68 @@ namespace Core {
376385 }
377386 }
378387
388+ void InsertItemScenario::insertPhoneme (dspx::Note *note) const {
389+ Q_D (const InsertItemScenario);
390+ if (!document () || !window ())
391+ return ;
392+
393+ auto model = document ()->model ();
394+ auto selectionModel = document ()->selectionModel ();
395+
396+ // If note is not provided, try to get it from the selection
397+ if (!note) {
398+ if (selectionModel->selectionType () == dspx::SelectionModel::ST_Note) {
399+ auto noteSelectionModel = selectionModel->noteSelectionModel ();
400+ const auto selectedNotes = noteSelectionModel->selectedItems ();
401+ if (selectedNotes.isEmpty ())
402+ return ;
403+ note = selectedNotes.first ();
404+ } else {
405+ return ;
406+ }
407+ }
408+
409+ qCInfo (lcInsertItemScenario) << " Inserting phoneme" ;
410+
411+ auto phonemeSequence = note->phonemes ()->edited ();
412+
413+ QQmlComponent component (RuntimeInterface::qmlEngine (), " DiffScope.Core" , " InsertPhonemeDialog" );
414+ QVariantMap properties;
415+ properties.insert (" token" , QString ());
416+ properties.insert (" start" , 0 );
417+ properties.insert (" language" , QString ());
418+ properties.insert (" onset" , false );
419+ auto dialog = createAndPositionDialog (&component, properties);
420+ if (!DocumentEditScenarioPrivate::execDialog (dialog))
421+ return ;
422+
423+ const auto token = dialog->property (" token" ).toString ();
424+ const auto start = dialog->property (" start" ).toInt ();
425+ const auto language = dialog->property (" language" ).toString ();
426+ const auto onset = dialog->property (" onset" ).toBool ();
427+ qCDebug (lcInsertItemScenario) << " Inserting phoneme with token" << token << " start" << start << " language" << language << " onset" << onset << " to note" << note;
428+
429+ dspx::Phoneme *newPhoneme = nullptr ;
430+ bool success = false ;
431+ document ()->transactionController ()->beginScopedTransaction (tr (" Inserting phoneme" ), [=, &newPhoneme, &success] {
432+ newPhoneme = model->createPhoneme ();
433+ newPhoneme->setToken (token);
434+ newPhoneme->setStart (start);
435+ newPhoneme->setLanguage (language);
436+ newPhoneme->setOnset (onset);
437+ if (!phonemeSequence->insertItem (newPhoneme)) {
438+ model->destroyItem (newPhoneme);
439+ newPhoneme = nullptr ;
440+ return false ;
441+ }
442+ success = true ;
443+ qCDebug (lcInsertItemScenario) << " Inserted phoneme" << newPhoneme;
444+ return true ;
445+ }, [] {
446+ qCCritical (lcInsertItemScenario) << " Failed to insert phoneme in exclusive transaction" ;
447+ });
448+ }
449+
379450}
380451
381452#include " moc_InsertItemScenario.cpp"
0 commit comments