Mercurial > hg > svapp
comparison framework/MainWindowBase.cpp @ 684:5e9b1956b609 by-id
ModelId updates
author | Chris Cannam |
---|---|
date | Wed, 03 Jul 2019 14:21:05 +0100 |
parents | 331be52cd473 |
children | 7540733f5480 |
comparison
equal
deleted
inserted
replaced
683:0736beb8b852 | 684:5e9b1956b609 |
---|---|
103 #include <QDateTime> | 103 #include <QDateTime> |
104 #include <QProcess> | 104 #include <QProcess> |
105 #include <QCheckBox> | 105 #include <QCheckBox> |
106 #include <QRegExp> | 106 #include <QRegExp> |
107 #include <QScrollArea> | 107 #include <QScrollArea> |
108 #include <QDesktopWidget> | 108 #include <QScreen> |
109 #include <QSignalMapper> | 109 #include <QSignalMapper> |
110 | 110 |
111 #include <iostream> | 111 #include <iostream> |
112 #include <cstdio> | 112 #include <cstdio> |
113 #include <errno.h> | 113 #include <errno.h> |
505 } | 505 } |
506 | 506 |
507 void | 507 void |
508 MainWindowBase::resizeConstrained(QSize size) | 508 MainWindowBase::resizeConstrained(QSize size) |
509 { | 509 { |
510 QDesktopWidget *desktop = QApplication::desktop(); | 510 QScreen *screen = QApplication::primaryScreen(); |
511 QRect available = desktop->availableGeometry(); | 511 QRect available = screen->availableGeometry(); |
512 QSize actual(std::min(size.width(), available.width()), | 512 QSize actual(std::min(size.width(), available.width()), |
513 std::min(size.height(), available.height())); | 513 std::min(size.height(), available.height())); |
514 resize(actual); | 514 resize(actual); |
515 } | 515 } |
516 | 516 |
573 MainWindowBase::getOpenFileName(FileFinder::FileType type) | 573 MainWindowBase::getOpenFileName(FileFinder::FileType type) |
574 { | 574 { |
575 FileFinder *ff = FileFinder::getInstance(); | 575 FileFinder *ff = FileFinder::getInstance(); |
576 | 576 |
577 if (type == FileFinder::AnyFile) { | 577 if (type == FileFinder::AnyFile) { |
578 if (getMainModel() != nullptr && | 578 if (!getMainModelId().isNone() && |
579 m_paneStack != nullptr && | 579 m_paneStack != nullptr && |
580 m_paneStack->getCurrentPane() != nullptr) { // can import a layer | 580 m_paneStack->getCurrentPane() != nullptr) { // can import a layer |
581 return ff->getOpenFileName(FileFinder::AnyFile, m_sessionFile); | 581 return ff->getOpenFileName(FileFinder::AnyFile, m_sessionFile); |
582 } else { | 582 } else { |
583 return ff->getOpenFileName(FileFinder::SessionOrAudioFile, | 583 return ff->getOpenFileName(FileFinder::SessionOrAudioFile, |
666 (currentPane != nullptr); | 666 (currentPane != nullptr); |
667 bool haveCurrentLayer = | 667 bool haveCurrentLayer = |
668 (haveCurrentPane && | 668 (haveCurrentPane && |
669 (currentLayer != nullptr)); | 669 (currentLayer != nullptr)); |
670 bool haveMainModel = | 670 bool haveMainModel = |
671 (getMainModel() != nullptr); | 671 (!getMainModelId().isNone()); |
672 bool havePlayTarget = | 672 bool havePlayTarget = |
673 (m_playTarget != nullptr || m_audioIO != nullptr); | 673 (m_playTarget != nullptr || m_audioIO != nullptr); |
674 bool haveSelection = | 674 bool haveSelection = |
675 (m_viewManager && | 675 (m_viewManager && |
676 !m_viewManager->getSelections().empty()); | 676 !m_viewManager->getSelections().empty()); |
691 bool haveClipboardContents = | 691 bool haveClipboardContents = |
692 (m_viewManager && | 692 (m_viewManager && |
693 !m_viewManager->getClipboard().empty()); | 693 !m_viewManager->getClipboard().empty()); |
694 bool haveTabularLayer = | 694 bool haveTabularLayer = |
695 (haveCurrentLayer && | 695 (haveCurrentLayer && |
696 dynamic_cast<TabularModel *>(currentLayer->getModel())); | 696 ModelById::isa<TabularModel>(currentLayer->getModel())); |
697 | 697 |
698 emit canAddPane(haveMainModel); | 698 emit canAddPane(haveMainModel); |
699 emit canDeleteCurrentPane(haveCurrentPane); | 699 emit canDeleteCurrentPane(haveCurrentPane); |
700 emit canZoom(haveMainModel && haveCurrentPane); | 700 emit canZoom(haveMainModel && haveCurrentPane); |
701 emit canScroll(haveMainModel && haveCurrentPane); | 701 emit canScroll(haveMainModel && haveCurrentPane); |
837 } | 837 } |
838 | 838 |
839 if (m_viewManager->getPlaySoloMode()) { | 839 if (m_viewManager->getPlaySoloMode()) { |
840 currentPaneChanged(m_paneStack->getCurrentPane()); | 840 currentPaneChanged(m_paneStack->getCurrentPane()); |
841 } else { | 841 } else { |
842 m_viewManager->setPlaybackModel(nullptr); | 842 m_viewManager->setPlaybackModel({}); |
843 if (m_playSource) { | 843 if (m_playSource) { |
844 m_playSource->clearSoloModelSet(); | 844 m_playSource->clearSoloModelSet(); |
845 } | 845 } |
846 } | 846 } |
847 } | 847 } |
855 if (!p) return; | 855 if (!p) return; |
856 | 856 |
857 if (!(m_viewManager && | 857 if (!(m_viewManager && |
858 m_playSource && | 858 m_playSource && |
859 m_viewManager->getPlaySoloMode())) { | 859 m_viewManager->getPlaySoloMode())) { |
860 if (m_viewManager) m_viewManager->setPlaybackModel(nullptr); | 860 if (m_viewManager) { |
861 m_viewManager->setPlaybackModel(ModelId()); | |
862 } | |
861 return; | 863 return; |
862 } | 864 } |
863 | 865 |
864 Model *prevPlaybackModel = m_viewManager->getPlaybackModel(); | 866 ModelId prevPlaybackModel = m_viewManager->getPlaybackModel(); |
865 | 867 |
866 // What we want here is not the currently playing frame (unless we | 868 // What we want here is not the currently playing frame (unless we |
867 // are about to clear out the audio playback buffers -- which may | 869 // are about to clear out the audio playback buffers -- which may |
868 // or may not be possible, depending on the audio driver). What | 870 // or may not be possible, depending on the audio driver). What |
869 // we want is the frame that was last committed to the soundcard | 871 // we want is the frame that was last committed to the soundcard |
876 cerr << "currentPaneChanged: current frame (in ref model) = " << frame << endl; | 878 cerr << "currentPaneChanged: current frame (in ref model) = " << frame << endl; |
877 | 879 |
878 View::ModelSet soloModels = p->getModels(); | 880 View::ModelSet soloModels = p->getModels(); |
879 | 881 |
880 View::ModelSet sources; | 882 View::ModelSet sources; |
881 for (View::ModelSet::iterator mi = soloModels.begin(); | 883 for (ModelId modelId: sources) { |
882 mi != soloModels.end(); ++mi) { | |
883 // If a model in this pane is derived from something else, | 884 // If a model in this pane is derived from something else, |
884 // then we want to play that model as well -- if the model | 885 // then we want to play that model as well -- if the model |
885 // that's derived from it is not something that is itself | 886 // that's derived from it is not something that is itself |
886 // individually playable (e.g. a waveform) | 887 // individually playable (e.g. a waveform) |
887 if (*mi && | 888 if (auto model = ModelById::get(modelId)) { |
888 !dynamic_cast<RangeSummarisableTimeValueModel *>(*mi) && | 889 if (!ModelById::isa<RangeSummarisableTimeValueModel>(modelId) && |
889 (*mi)->getSourceModel()) { | 890 !model->getSourceModel().isNone()) { |
890 sources.insert((*mi)->getSourceModel()); | 891 sources.insert(model->getSourceModel()); |
891 } | 892 } |
892 } | 893 } |
893 for (View::ModelSet::iterator mi = sources.begin(); | 894 } |
894 mi != sources.end(); ++mi) { | 895 for (ModelId modelId: sources) { |
895 soloModels.insert(*mi); | 896 soloModels.insert(modelId); |
896 } | 897 } |
897 | 898 |
898 //!!! Need an "atomic" way of telling the play source that the | 899 //!!! Need an "atomic" way of telling the play source that the |
899 //playback model has changed, and changing it on ViewManager -- | 900 //playback model has changed, and changing it on ViewManager -- |
900 //the play source should be making the setPlaybackModel call to | 901 //the play source should be making the setPlaybackModel call to |
901 //ViewManager | 902 //ViewManager |
902 | 903 |
903 for (View::ModelSet::iterator mi = soloModels.begin(); | 904 ModelId newPlaybackModel; |
904 mi != soloModels.end(); ++mi) { | 905 |
905 if (dynamic_cast<RangeSummarisableTimeValueModel *>(*mi)) { | 906 for (ModelId modelId: soloModels) { |
906 m_viewManager->setPlaybackModel(*mi); | 907 if (ModelById::isa<RangeSummarisableTimeValueModel>(modelId)) { |
907 } | 908 m_viewManager->setPlaybackModel(modelId); |
908 } | 909 newPlaybackModel = modelId; |
909 | 910 } |
910 RangeSummarisableTimeValueModel *a = | 911 } |
911 dynamic_cast<RangeSummarisableTimeValueModel *>(prevPlaybackModel); | |
912 RangeSummarisableTimeValueModel *b = | |
913 dynamic_cast<RangeSummarisableTimeValueModel *>(m_viewManager-> | |
914 getPlaybackModel()); | |
915 | 912 |
916 m_playSource->setSoloModelSet(soloModels); | 913 m_playSource->setSoloModelSet(soloModels); |
917 | 914 |
918 if (a && b && (a != b)) { | 915 if (!prevPlaybackModel.isNone() && !newPlaybackModel.isNone() && |
919 if (m_playSource->isPlaying()) m_playSource->play(frame); | 916 prevPlaybackModel != newPlaybackModel) { |
917 if (m_playSource->isPlaying()) { | |
918 m_playSource->play(frame); | |
919 } | |
920 } | 920 } |
921 } | 921 } |
922 | 922 |
923 void | 923 void |
924 MainWindowBase::currentLayerChanged(Pane *p, Layer *) | 924 MainWindowBase::currentLayerChanged(Pane *p, Layer *) |
956 } | 956 } |
957 | 957 |
958 void | 958 void |
959 MainWindowBase::selectAll() | 959 MainWindowBase::selectAll() |
960 { | 960 { |
961 if (!getMainModel()) return; | |
962 m_viewManager->setSelection(Selection(getModelsStartFrame(), | 961 m_viewManager->setSelection(Selection(getModelsStartFrame(), |
963 getModelsEndFrame())); | 962 getModelsEndFrame())); |
964 } | 963 } |
965 | 964 |
966 void | 965 void |
967 MainWindowBase::selectToStart() | 966 MainWindowBase::selectToStart() |
968 { | 967 { |
969 if (!getMainModel()) return; | 968 m_viewManager->setSelection(Selection(getModelsStartFrame(), |
970 m_viewManager->setSelection(Selection(getMainModel()->getStartFrame(), | |
971 m_viewManager->getGlobalCentreFrame())); | 969 m_viewManager->getGlobalCentreFrame())); |
972 } | 970 } |
973 | 971 |
974 void | 972 void |
975 MainWindowBase::selectToEnd() | 973 MainWindowBase::selectToEnd() |
976 { | 974 { |
977 if (!getMainModel()) return; | |
978 m_viewManager->setSelection(Selection(m_viewManager->getGlobalCentreFrame(), | 975 m_viewManager->setSelection(Selection(m_viewManager->getGlobalCentreFrame(), |
979 getMainModel()->getEndFrame())); | 976 getModelsEndFrame())); |
980 } | 977 } |
981 | 978 |
982 void | 979 void |
983 MainWindowBase::selectVisible() | 980 MainWindowBase::selectVisible() |
984 { | 981 { |
985 Model *model = getMainModel(); | 982 auto model = getMainModel(); |
986 if (!model) return; | 983 if (!model) return; |
987 | 984 |
988 Pane *currentPane = m_paneStack->getCurrentPane(); | 985 Pane *currentPane = m_paneStack->getCurrentPane(); |
989 if (!currentPane) return; | 986 if (!currentPane) return; |
990 | 987 |
991 sv_frame_t startFrame, endFrame; | 988 sv_frame_t startFrame, endFrame; |
992 | 989 |
993 if (currentPane->getStartFrame() < 0) startFrame = 0; | 990 if (currentPane->getStartFrame() < 0) { |
994 else startFrame = currentPane->getStartFrame(); | 991 startFrame = 0; |
995 | 992 } else { |
996 if (currentPane->getEndFrame() > model->getEndFrame()) endFrame = model->getEndFrame(); | 993 startFrame = currentPane->getStartFrame(); |
997 else endFrame = currentPane->getEndFrame(); | 994 } |
995 | |
996 if (currentPane->getEndFrame() > model->getEndFrame()) { | |
997 endFrame = model->getEndFrame(); | |
998 } else { | |
999 endFrame = currentPane->getEndFrame(); | |
1000 } | |
998 | 1001 |
999 m_viewManager->setSelection(Selection(startFrame, endFrame)); | 1002 m_viewManager->setSelection(Selection(startFrame, endFrame)); |
1000 } | 1003 } |
1001 | 1004 |
1002 void | 1005 void |
1206 } | 1209 } |
1207 } | 1210 } |
1208 | 1211 |
1209 if (layer) { | 1212 if (layer) { |
1210 | 1213 |
1211 Model *model = layer->getModel(); | 1214 ModelId model = layer->getModel(); |
1212 SparseOneDimensionalModel *sodm = | 1215 auto sodm = ModelById::getAs<SparseOneDimensionalModel>(model); |
1213 dynamic_cast<SparseOneDimensionalModel *>(model); | |
1214 | 1216 |
1215 if (sodm) { | 1217 if (sodm) { |
1216 Event point(frame, ""); | 1218 Event point(frame, ""); |
1217 Event prevPoint(0); | 1219 Event prevPoint(0); |
1218 bool havePrevPoint = false; | 1220 bool havePrevPoint = false; |
1219 | 1221 |
1220 ChangeEventsCommand *command = | 1222 ChangeEventsCommand *command = |
1221 new ChangeEventsCommand(sodm, tr("Add Point")); | 1223 new ChangeEventsCommand(model.untyped, tr("Add Point")); |
1222 | 1224 |
1223 if (m_labeller) { | 1225 if (m_labeller) { |
1224 | 1226 |
1225 if (m_labeller->requiresPrevPoint()) { | 1227 if (m_labeller->requiresPrevPoint()) { |
1226 | 1228 |
1253 (frame, | 1255 (frame, |
1254 sodm->getSampleRate()) | 1256 sodm->getSampleRate()) |
1255 .toText(false).c_str())); | 1257 .toText(false).c_str())); |
1256 | 1258 |
1257 Command *c = command->finish(); | 1259 Command *c = command->finish(); |
1258 if (c) CommandHistory::getInstance()->addCommand(c, false); | 1260 if (c) { |
1261 CommandHistory::getInstance()->addCommand(c, false); | |
1262 } | |
1259 } | 1263 } |
1260 } | 1264 } |
1261 } | 1265 } |
1262 | 1266 |
1263 void | 1267 void |
1298 .toText(false).c_str()); | 1302 .toText(false).c_str()); |
1299 | 1303 |
1300 Layer *layer = pane->getSelectedLayer(); | 1304 Layer *layer = pane->getSelectedLayer(); |
1301 if (!layer) return; | 1305 if (!layer) return; |
1302 | 1306 |
1303 RegionModel *rm = dynamic_cast<RegionModel *>(layer->getModel()); | 1307 auto rm = ModelById::getAs<RegionModel>(layer->getModel()); |
1304 if (rm) { | 1308 if (rm) { |
1305 Event point(alignedStart, | 1309 Event point(alignedStart, |
1306 rm->getValueMaximum() + 1, | 1310 rm->getValueMaximum() + 1, |
1307 alignedDuration, | 1311 alignedDuration, |
1308 ""); | 1312 ""); |
1309 ChangeEventsCommand *command = new ChangeEventsCommand(rm, name); | 1313 ChangeEventsCommand *command = new ChangeEventsCommand |
1314 (rm->getId().untyped, name); | |
1310 command->add(point); | 1315 command->add(point); |
1311 c = command->finish(); | 1316 c = command->finish(); |
1312 } | 1317 } |
1313 | 1318 |
1314 if (c) { | 1319 if (c) { |
1315 CommandHistory::getInstance()->addCommand(c, false); | 1320 CommandHistory::getInstance()->addCommand(c, false); |
1316 return; | 1321 return; |
1317 } | 1322 } |
1318 | 1323 |
1319 NoteModel *nm = dynamic_cast<NoteModel *>(layer->getModel()); | 1324 auto nm = ModelById::getAs<NoteModel>(layer->getModel()); |
1320 if (nm) { | 1325 if (nm) { |
1321 Event point(alignedStart, | 1326 Event point(alignedStart, |
1322 nm->getValueMinimum(), | 1327 nm->getValueMinimum(), |
1323 alignedDuration, | 1328 alignedDuration, |
1324 1.f, | 1329 1.f, |
1325 ""); | 1330 ""); |
1326 ChangeEventsCommand *command = new ChangeEventsCommand(nm, name); | 1331 ChangeEventsCommand *command = new ChangeEventsCommand |
1332 (nm->getId().untyped, name); | |
1327 command->add(point); | 1333 command->add(point); |
1328 c = command->finish(); | 1334 c = command->finish(); |
1329 } | 1335 } |
1330 | 1336 |
1331 if (c) { | 1337 if (c) { |
1343 Layer *layer = dynamic_cast<TimeInstantLayer *>(pane->getSelectedLayer()); | 1349 Layer *layer = dynamic_cast<TimeInstantLayer *>(pane->getSelectedLayer()); |
1344 if (!layer) return; | 1350 if (!layer) return; |
1345 | 1351 |
1346 MultiSelection ms(m_viewManager->getSelection()); | 1352 MultiSelection ms(m_viewManager->getSelection()); |
1347 | 1353 |
1348 Model *model = layer->getModel(); | 1354 auto sodm = ModelById::getAs<SparseOneDimensionalModel>(layer->getModel()); |
1349 SparseOneDimensionalModel *sodm = dynamic_cast<SparseOneDimensionalModel *> | |
1350 (model); | |
1351 if (!sodm) return; | 1355 if (!sodm) return; |
1352 | 1356 |
1353 if (!m_labeller) return; | 1357 if (!m_labeller) return; |
1354 | 1358 |
1355 Labeller labeller(*m_labeller); | 1359 Labeller labeller(*m_labeller); |
1356 labeller.setSampleRate(sodm->getSampleRate()); | 1360 labeller.setSampleRate(sodm->getSampleRate()); |
1357 /*!!! to be updated after SODM API update | 1361 |
1358 Command *c = labeller.labelAll<SparseOneDimensionalModel::Point>(*sodm, &ms); | 1362 /*!!! |
1363 Command *c = labeller.labelAll(sodm->getId().untyped, &ms); | |
1359 if (c) CommandHistory::getInstance()->addCommand(c, false); | 1364 if (c) CommandHistory::getInstance()->addCommand(c, false); |
1360 */ | 1365 */ |
1361 } | 1366 } |
1362 | 1367 |
1363 void | 1368 void |
1369 Layer *layer = dynamic_cast<TimeInstantLayer *>(pane->getSelectedLayer()); | 1374 Layer *layer = dynamic_cast<TimeInstantLayer *>(pane->getSelectedLayer()); |
1370 if (!layer) return; | 1375 if (!layer) return; |
1371 | 1376 |
1372 MultiSelection ms(m_viewManager->getSelection()); | 1377 MultiSelection ms(m_viewManager->getSelection()); |
1373 | 1378 |
1374 Model *model = layer->getModel(); | 1379 auto sodm = ModelById::getAs<SparseOneDimensionalModel>(layer->getModel()); |
1375 SparseOneDimensionalModel *sodm = | |
1376 dynamic_cast<SparseOneDimensionalModel *>(model); | |
1377 if (!sodm) return; | 1380 if (!sodm) return; |
1378 | 1381 |
1379 if (!m_labeller) return; | 1382 if (!m_labeller) return; |
1380 | 1383 |
1381 Labeller labeller(*m_labeller); | 1384 Labeller labeller(*m_labeller); |
1382 labeller.setSampleRate(sodm->getSampleRate()); | 1385 labeller.setSampleRate(sodm->getSampleRate()); |
1383 | 1386 |
1384 (void)n; | 1387 (void)n; |
1385 /*!!! to be updated after SODM API update | 1388 /*!!! |
1386 Command *c = labeller.subdivide<SparseOneDimensionalModel::Point> | 1389 Command *c = labeller.subdivide(sodm->getId().untyped, &ms, n); |
1387 (*sodm, &ms, n); | |
1388 if (c) CommandHistory::getInstance()->addCommand(c, false); | 1390 if (c) CommandHistory::getInstance()->addCommand(c, false); |
1389 */ | 1391 */ |
1390 } | 1392 } |
1391 | 1393 |
1392 void | 1394 void |
1393 MainWindowBase::winnowInstantsBy(int n) | 1395 MainWindowBase::winnowInstantsBy(int n) |
1394 { | 1396 { |
1398 Layer *layer = dynamic_cast<TimeInstantLayer *>(pane->getSelectedLayer()); | 1400 Layer *layer = dynamic_cast<TimeInstantLayer *>(pane->getSelectedLayer()); |
1399 if (!layer) return; | 1401 if (!layer) return; |
1400 | 1402 |
1401 MultiSelection ms(m_viewManager->getSelection()); | 1403 MultiSelection ms(m_viewManager->getSelection()); |
1402 | 1404 |
1403 Model *model = layer->getModel(); | 1405 auto sodm = ModelById::getAs<SparseOneDimensionalModel>(layer->getModel()); |
1404 SparseOneDimensionalModel *sodm = | |
1405 dynamic_cast<SparseOneDimensionalModel *>(model); | |
1406 if (!sodm) return; | 1406 if (!sodm) return; |
1407 | 1407 |
1408 if (!m_labeller) return; | 1408 if (!m_labeller) return; |
1409 | 1409 |
1410 Labeller labeller(*m_labeller); | 1410 Labeller labeller(*m_labeller); |
1411 labeller.setSampleRate(sodm->getSampleRate()); | 1411 labeller.setSampleRate(sodm->getSampleRate()); |
1412 | 1412 |
1413 (void)n; | 1413 (void)n; |
1414 /*!!! to be updated after SODM API update | 1414 //!!! to update: (and the above two functions) |
1415 Command *c = labeller.winnow<SparseOneDimensionalModel::Point> | 1415 /* |
1416 (*sodm, &ms, n); | 1416 Command *c = labeller.winnow(sodm->getId.untyped, &ms, n); |
1417 if (c) CommandHistory::getInstance()->addCommand(c, false); | 1417 if (c) CommandHistory::getInstance()->addCommand(c, false); |
1418 */ | 1418 */ |
1419 } | 1419 } |
1420 | 1420 |
1421 MainWindowBase::FileOpenStatus | 1421 MainWindowBase::FileOpenStatus |
1422 MainWindowBase::openPath(QString fileOrUrl, AudioFileOpenMode mode) | 1422 MainWindowBase::openPath(QString fileOrUrl, AudioFileOpenMode mode) |
1423 { | 1423 { |
1563 | 1563 |
1564 if (rate == 0) { | 1564 if (rate == 0) { |
1565 SVDEBUG << "Yes, preserving incoming file rate" << endl; | 1565 SVDEBUG << "Yes, preserving incoming file rate" << endl; |
1566 } | 1566 } |
1567 | 1567 |
1568 ReadOnlyWaveFileModel *newModel = new ReadOnlyWaveFileModel(source, rate); | 1568 auto newModel = std::make_shared<ReadOnlyWaveFileModel>(source, rate); |
1569 | |
1570 if (!newModel->isOK()) { | 1569 if (!newModel->isOK()) { |
1571 delete newModel; | |
1572 m_openingAudioFile = false; | 1570 m_openingAudioFile = false; |
1573 if (source.wasCancelled()) { | 1571 if (source.wasCancelled()) { |
1574 return FileOpenCancelled; | 1572 return FileOpenCancelled; |
1575 } else { | 1573 } else { |
1576 return FileOpenFailed; | 1574 return FileOpenFailed; |
1577 } | 1575 } |
1578 } | 1576 } |
1579 | 1577 |
1580 return addOpenedAudioModel(source, newModel, mode, templateName, true); | 1578 ModelById::add(newModel); |
1579 | |
1580 return addOpenedAudioModel(source, newModel->getId(), | |
1581 mode, templateName, true); | |
1581 } | 1582 } |
1582 | 1583 |
1583 MainWindowBase::FileOpenStatus | 1584 MainWindowBase::FileOpenStatus |
1584 MainWindowBase::addOpenedAudioModel(FileSource source, | 1585 MainWindowBase::addOpenedAudioModel(FileSource source, |
1585 WaveFileModel *newModel, | 1586 ModelId newModel, |
1586 AudioFileOpenMode mode, | 1587 AudioFileOpenMode mode, |
1587 QString templateName, | 1588 QString templateName, |
1588 bool registerSource) | 1589 bool registerSource) |
1589 { | 1590 { |
1590 if (mode == AskUser) { | 1591 if (mode == AskUser) { |
1606 (this, tr("Select target for import"), | 1607 (this, tr("Select target for import"), |
1607 tr("<b>Select a target for import</b><p>You already have an audio file loaded.<br>What would you like to do with the new audio file?"), | 1608 tr("<b>Select a target for import</b><p>You already have an audio file loaded.<br>What would you like to do with the new audio file?"), |
1608 items, lastMode, &ok); | 1609 items, lastMode, &ok); |
1609 | 1610 |
1610 if (!ok || item.isEmpty()) { | 1611 if (!ok || item.isEmpty()) { |
1611 delete newModel; | 1612 ModelById::release(newModel); |
1612 m_openingAudioFile = false; | 1613 m_openingAudioFile = false; |
1613 return FileOpenCancelled; | 1614 return FileOpenCancelled; |
1614 } | 1615 } |
1615 | 1616 |
1616 for (int i = 0; i < items.size(); ++i) { | 1617 for (int i = 0; i < items.size(); ++i) { |
1633 | 1634 |
1634 Pane *pane = m_paneStack->getCurrentPane(); | 1635 Pane *pane = m_paneStack->getCurrentPane(); |
1635 if (pane) { | 1636 if (pane) { |
1636 if (getMainModel()) { | 1637 if (getMainModel()) { |
1637 View::ModelSet models(pane->getModels()); | 1638 View::ModelSet models(pane->getModels()); |
1638 if (models.find(getMainModel()) != models.end()) { | 1639 if (models.find(getMainModelId()) != models.end()) { |
1639 // Current pane contains main model: replace that | 1640 // Current pane contains main model: replace that |
1640 mode = ReplaceMainModel; | 1641 mode = ReplaceMainModel; |
1641 } | 1642 } |
1642 // Otherwise the current pane has a non-default model, | 1643 // Otherwise the current pane has a non-default model, |
1643 // which we will deal with later | 1644 // which we will deal with later |
1650 // We seem to have no current pane! Oh well | 1651 // We seem to have no current pane! Oh well |
1651 mode = CreateAdditionalModel; | 1652 mode = CreateAdditionalModel; |
1652 } | 1653 } |
1653 } | 1654 } |
1654 | 1655 |
1655 if (mode == CreateAdditionalModel && !getMainModel()) { | 1656 if (mode == CreateAdditionalModel && getMainModelId().isNone()) { |
1656 SVDEBUG << "Mode is CreateAdditionalModel but we have no main model, switching to ReplaceSession mode" << endl; | 1657 SVDEBUG << "Mode is CreateAdditionalModel but we have no main model, switching to ReplaceSession mode" << endl; |
1657 mode = ReplaceSession; | 1658 mode = ReplaceSession; |
1658 } | 1659 } |
1659 | 1660 |
1660 bool loadedTemplate = false; | 1661 bool loadedTemplate = false; |
1688 | 1689 |
1689 emit activity(tr("Import audio file \"%1\"").arg(source.getLocation())); | 1690 emit activity(tr("Import audio file \"%1\"").arg(source.getLocation())); |
1690 | 1691 |
1691 if (mode == ReplaceMainModel) { | 1692 if (mode == ReplaceMainModel) { |
1692 | 1693 |
1693 Model *prevMain = getMainModel(); | 1694 ModelId prevMain = getMainModelId(); |
1694 if (prevMain) { | 1695 if (!prevMain.isNone()) { |
1695 m_playSource->removeModel(prevMain); | 1696 m_playSource->removeModel(prevMain); |
1696 PlayParameterRepository::getInstance()->removePlayable(prevMain); | 1697 //!!! shouldn't this stuff be handled by Document? |
1697 } | 1698 PlayParameterRepository::getInstance()->removePlayable |
1698 PlayParameterRepository::getInstance()->addPlayable(newModel); | 1699 (prevMain.untyped); |
1700 } | |
1701 PlayParameterRepository::getInstance()->addPlayable(newModel.untyped); | |
1699 | 1702 |
1700 SVDEBUG << "SV about to call setMainModel(" << newModel << "): prevMain is " << prevMain << endl; | 1703 SVDEBUG << "SV about to call setMainModel(" << newModel << "): prevMain is " << prevMain << endl; |
1701 | 1704 |
1702 m_document->setMainModel(newModel); | 1705 m_document->setMainModel(newModel); |
1703 | 1706 |
1930 | 1933 |
1931 try { | 1934 try { |
1932 | 1935 |
1933 MIDIFileImportDialog midiDlg(this); | 1936 MIDIFileImportDialog midiDlg(this); |
1934 | 1937 |
1935 Model *model = DataFileReaderFactory::loadNonCSV | 1938 Model *newModelPtr = DataFileReaderFactory::loadNonCSV |
1936 (path, &midiDlg, getMainModel()->getSampleRate()); | 1939 (path, &midiDlg, getMainModel()->getSampleRate()); |
1937 | 1940 |
1938 if (!model) { | 1941 if (!newModelPtr) { |
1939 CSVFormatDialog *dialog = | 1942 CSVFormatDialog *dialog = |
1940 new CSVFormatDialog(this, | 1943 new CSVFormatDialog(this, |
1941 path, | 1944 path, |
1942 getMainModel()->getSampleRate(), | 1945 getMainModel()->getSampleRate(), |
1943 5); | 1946 5); |
1944 if (dialog->exec() == QDialog::Accepted) { | 1947 if (dialog->exec() == QDialog::Accepted) { |
1945 model = DataFileReaderFactory::loadCSV | 1948 newModelPtr = DataFileReaderFactory::loadCSV |
1946 (path, dialog->getFormat(), | 1949 (path, dialog->getFormat(), |
1947 getMainModel()->getSampleRate()); | 1950 getMainModel()->getSampleRate()); |
1948 } | 1951 } |
1949 delete dialog; | 1952 delete dialog; |
1950 } | 1953 } |
1951 | 1954 |
1952 if (model) { | 1955 if (newModelPtr) { |
1953 | 1956 |
1954 SVDEBUG << "MainWindowBase::openLayer: Have model" << endl; | 1957 SVDEBUG << "MainWindowBase::openLayer: Have model" << endl; |
1955 | 1958 |
1956 emit activity(tr("Import MIDI file \"%1\"").arg(source.getLocation())); | 1959 emit activity(tr("Import MIDI file \"%1\"").arg(source.getLocation())); |
1957 | 1960 |
1958 Layer *newLayer = m_document->createImportedLayer(model); | 1961 ModelId modelId = newModelPtr->getId(); |
1962 ModelById::add(std::shared_ptr<Model>(newModelPtr)); | |
1963 | |
1964 Layer *newLayer = m_document->createImportedLayer(modelId); | |
1959 | 1965 |
1960 if (newLayer) { | 1966 if (newLayer) { |
1961 | 1967 |
1962 m_document->addLayerToView(pane, newLayer); | 1968 m_document->addLayerToView(pane, newLayer); |
1963 m_paneStack->setCurrentLayer(pane, newLayer); | 1969 m_paneStack->setCurrentLayer(pane, newLayer); |
1994 // shouldn't happen, as the menu action should have been disabled | 2000 // shouldn't happen, as the menu action should have been disabled |
1995 cerr << "WARNING: MainWindowBase::openImage: no current pane" << endl; | 2001 cerr << "WARNING: MainWindowBase::openImage: no current pane" << endl; |
1996 return FileOpenWrongMode; | 2002 return FileOpenWrongMode; |
1997 } | 2003 } |
1998 | 2004 |
1999 if (!m_document->getMainModel()) { | 2005 if (!getMainModel()) { |
2000 return FileOpenWrongMode; | 2006 return FileOpenWrongMode; |
2001 } | 2007 } |
2002 | 2008 |
2003 bool newLayer = false; | 2009 bool newLayer = false; |
2004 | 2010 |
2367 .arg(source.getLocation()).arg(importer.getErrorString())); | 2373 .arg(source.getLocation()).arg(importer.getErrorString())); |
2368 } | 2374 } |
2369 return FileOpenFailed; | 2375 return FileOpenFailed; |
2370 } | 2376 } |
2371 | 2377 |
2372 std::vector<Model *> models = importer.getDataModels(&dialog); | 2378 std::vector<Model *> modelPtrs = importer.getDataModels(&dialog); |
2373 | 2379 |
2374 dialog.setMessage(tr("Importing from RDF...")); | 2380 dialog.setMessage(tr("Importing from RDF...")); |
2375 | 2381 |
2376 if (models.empty()) { | 2382 if (modelPtrs.empty()) { |
2377 QMessageBox::critical | 2383 QMessageBox::critical |
2378 (this, tr("Failed to import RDF"), | 2384 (this, tr("Failed to import RDF"), |
2379 tr("<b>Failed to import RDF</b><p>No suitable data models found for import from RDF document at \"%1\"</p>").arg(source.getLocation())); | 2385 tr("<b>Failed to import RDF</b><p>No suitable data models found for import from RDF document at \"%1\"</p>").arg(source.getLocation())); |
2380 return FileOpenFailed; | 2386 return FileOpenFailed; |
2381 } | 2387 } |
2382 | 2388 |
2383 emit activity(tr("Import RDF document \"%1\"").arg(source.getLocation())); | 2389 emit activity(tr("Import RDF document \"%1\"").arg(source.getLocation())); |
2384 | 2390 |
2385 std::set<Model *> added; | 2391 std::set<ModelId> modelIds; |
2386 | 2392 |
2387 for (int i = 0; i < (int)models.size(); ++i) { | 2393 for (Model *modelPtr: modelPtrs) { |
2388 | 2394 modelIds.insert(modelPtr->getId()); |
2389 Model *m = models[i]; | 2395 ModelById::add(std::shared_ptr<Model>(modelPtr)); |
2390 WaveFileModel *w = dynamic_cast<WaveFileModel *>(m); | 2396 } |
2391 | 2397 |
2392 if (w) { | 2398 std::set<ModelId> added; |
2399 | |
2400 for (auto modelId: modelIds) { | |
2401 | |
2402 if (ModelById::isa<WaveFileModel>(modelId)) { | |
2393 | 2403 |
2394 Pane *pane = addPaneToStack(); | 2404 Pane *pane = addPaneToStack(); |
2395 Layer *layer = nullptr; | 2405 Layer *layer = nullptr; |
2396 | 2406 |
2397 if (m_timeRulerLayer) { | 2407 if (m_timeRulerLayer) { |
2398 m_document->addLayerToView(pane, m_timeRulerLayer); | 2408 m_document->addLayerToView(pane, m_timeRulerLayer); |
2399 } | 2409 } |
2400 | 2410 |
2401 if (!getMainModel()) { | 2411 if (!getMainModel()) { |
2402 m_document->setMainModel(w); | 2412 m_document->setMainModel(modelId); |
2403 layer = m_document->createMainModelLayer(LayerFactory::Waveform); | 2413 layer = m_document->createMainModelLayer(LayerFactory::Waveform); |
2404 } else { | 2414 } else { |
2405 layer = m_document->createImportedLayer(w); | 2415 layer = m_document->createImportedLayer(modelId); |
2406 } | 2416 } |
2407 | 2417 |
2408 m_document->addLayerToView(pane, layer); | 2418 m_document->addLayerToView(pane, layer); |
2409 | 2419 |
2410 added.insert(w); | 2420 added.insert(modelId); |
2411 | 2421 |
2412 for (int j = 0; j < (int)models.size(); ++j) { | 2422 for (auto otherId: modelIds) { |
2413 | 2423 |
2414 Model *dm = models[j]; | 2424 if (otherId == modelId) continue; |
2415 | 2425 |
2416 if (dm == m) continue; | 2426 bool isDependent = false; |
2417 if (dm->getSourceModel() != m) continue; | 2427 if (auto dm = ModelById::get(otherId)) { |
2418 | 2428 if (dm->getSourceModel() == modelId) { |
2419 layer = m_document->createImportedLayer(dm); | 2429 isDependent = true; |
2430 } | |
2431 } | |
2432 if (!isDependent) continue; | |
2433 | |
2434 layer = m_document->createImportedLayer(otherId); | |
2420 | 2435 |
2421 if (layer->isLayerOpaque() || | 2436 if (layer->isLayerOpaque() || |
2422 dynamic_cast<Colour3DPlotLayer *>(layer)) { | 2437 dynamic_cast<Colour3DPlotLayer *>(layer)) { |
2423 | 2438 |
2424 // these always go in a new pane, with nothing | 2439 // these always go in a new pane, with nothing |
2460 } | 2475 } |
2461 | 2476 |
2462 m_document->addLayerToView(pane, layer); | 2477 m_document->addLayerToView(pane, layer); |
2463 } | 2478 } |
2464 | 2479 |
2465 added.insert(dm); | 2480 added.insert(otherId); |
2466 } | 2481 } |
2467 } | 2482 } |
2468 } | 2483 } |
2469 | 2484 |
2470 for (int i = 0; i < (int)models.size(); ++i) { | 2485 for (auto modelId : modelIds) { |
2471 | 2486 |
2472 Model *m = models[i]; | 2487 if (added.find(modelId) == added.end()) { |
2473 | |
2474 if (added.find(m) == added.end()) { | |
2475 | 2488 |
2476 Layer *layer = m_document->createImportedLayer(m); | 2489 Layer *layer = m_document->createImportedLayer(modelId); |
2477 if (!layer) return FileOpenFailed; | 2490 if (!layer) return FileOpenFailed; |
2478 | 2491 |
2479 Pane *singleLayerPane = addPaneToStack(); | 2492 Pane *singleLayerPane = addPaneToStack(); |
2480 if (m_timeRulerLayer) { | 2493 if (m_timeRulerLayer) { |
2481 m_document->addLayerToView(singleLayerPane, m_timeRulerLayer); | 2494 m_document->addLayerToView(singleLayerPane, m_timeRulerLayer); |
2649 SVCERR << "MainWindowBase::audioChannelCountIncreased: we were recording already, so resuming IO now" << endl; | 2662 SVCERR << "MainWindowBase::audioChannelCountIncreased: we were recording already, so resuming IO now" << endl; |
2650 m_audioIO->resume(); | 2663 m_audioIO->resume(); |
2651 } | 2664 } |
2652 } | 2665 } |
2653 | 2666 |
2654 WaveFileModel * | 2667 ModelId |
2668 MainWindowBase::getMainModelId() | |
2669 { | |
2670 if (!m_document) return {}; | |
2671 return m_document->getMainModel(); | |
2672 } | |
2673 | |
2674 std::shared_ptr<WaveFileModel> | |
2655 MainWindowBase::getMainModel() | 2675 MainWindowBase::getMainModel() |
2656 { | 2676 { |
2657 if (!m_document) return nullptr; | 2677 return ModelById::getAs<WaveFileModel>(getMainModelId()); |
2658 return m_document->getMainModel(); | |
2659 } | |
2660 | |
2661 const WaveFileModel * | |
2662 MainWindowBase::getMainModel() const | |
2663 { | |
2664 if (!m_document) return nullptr; | |
2665 return m_document->getMainModel(); | |
2666 } | 2678 } |
2667 | 2679 |
2668 void | 2680 void |
2669 MainWindowBase::createDocument() | 2681 MainWindowBase::createDocument() |
2670 { | 2682 { |
2677 connect(m_document, SIGNAL(layerAboutToBeDeleted(Layer *)), | 2689 connect(m_document, SIGNAL(layerAboutToBeDeleted(Layer *)), |
2678 this, SLOT(layerAboutToBeDeleted(Layer *))); | 2690 this, SLOT(layerAboutToBeDeleted(Layer *))); |
2679 connect(m_document, SIGNAL(layerInAView(Layer *, bool)), | 2691 connect(m_document, SIGNAL(layerInAView(Layer *, bool)), |
2680 this, SLOT(layerInAView(Layer *, bool))); | 2692 this, SLOT(layerInAView(Layer *, bool))); |
2681 | 2693 |
2682 connect(m_document, SIGNAL(modelAdded(Model *)), | 2694 connect(m_document, SIGNAL(modelAdded(ModelId )), |
2683 this, SLOT(modelAdded(Model *))); | 2695 this, SLOT(modelAdded(ModelId ))); |
2684 connect(m_document, SIGNAL(mainModelChanged(WaveFileModel *)), | 2696 connect(m_document, SIGNAL(mainModelChanged(WaveFileModel *)), |
2685 this, SLOT(mainModelChanged(WaveFileModel *))); | 2697 this, SLOT(mainModelChanged(WaveFileModel *))); |
2686 connect(m_document, SIGNAL(modelAboutToBeDeleted(Model *)), | 2698 connect(m_document, SIGNAL(modelAboutToBeDeleted(ModelId )), |
2687 this, SLOT(modelAboutToBeDeleted(Model *))); | 2699 this, SLOT(modelAboutToBeDeleted(ModelId ))); |
2688 | 2700 |
2689 connect(m_document, SIGNAL(modelGenerationFailed(QString, QString)), | 2701 connect(m_document, SIGNAL(modelGenerationFailed(QString, QString)), |
2690 this, SLOT(modelGenerationFailed(QString, QString))); | 2702 this, SLOT(modelGenerationFailed(QString, QString))); |
2691 connect(m_document, SIGNAL(modelRegenerationWarning(QString, QString, QString)), | 2703 connect(m_document, SIGNAL(modelRegenerationWarning(QString, QString, QString)), |
2692 this, SLOT(modelRegenerationWarning(QString, QString, QString))); | 2704 this, SLOT(modelRegenerationWarning(QString, QString, QString))); |
2789 { | 2801 { |
2790 if (QFileInfo(path).suffix() == "") path += ".svl"; | 2802 if (QFileInfo(path).suffix() == "") path += ".svl"; |
2791 | 2803 |
2792 QString suffix = QFileInfo(path).suffix().toLower(); | 2804 QString suffix = QFileInfo(path).suffix().toLower(); |
2793 | 2805 |
2794 Model *model = layer->getModel(); | 2806 auto model = ModelById::get(layer->getModel()); |
2807 if (!model) { | |
2808 error = tr("Internal error: unknown model"); | |
2809 return false; | |
2810 } | |
2795 | 2811 |
2796 if (suffix == "xml" || suffix == "svl") { | 2812 if (suffix == "xml" || suffix == "svl") { |
2797 | 2813 |
2798 QFile file(path); | 2814 QFile file(path); |
2799 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { | 2815 if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { |
2817 << "</sv>\n"; | 2833 << "</sv>\n"; |
2818 } | 2834 } |
2819 | 2835 |
2820 } else if (suffix == "mid" || suffix == "midi") { | 2836 } else if (suffix == "mid" || suffix == "midi") { |
2821 | 2837 |
2822 NoteModel *nm = dynamic_cast<NoteModel *>(model); | 2838 auto nm = ModelById::getAs<NoteModel>(layer->getModel()); |
2823 | 2839 |
2824 if (!nm) { | 2840 if (!nm) { |
2825 error = tr("Can't export non-note layers to MIDI"); | 2841 error = tr("Can't export non-note layers to MIDI"); |
2826 } else { | 2842 } else { |
2827 MIDIFileWriter writer(path, nm, nm->getSampleRate()); | 2843 MIDIFileWriter writer(path, nm.get(), nm->getSampleRate()); |
2828 writer.write(); | 2844 writer.write(); |
2829 if (!writer.isOK()) { | 2845 if (!writer.isOK()) { |
2830 error = writer.getError(); | 2846 error = writer.getError(); |
2831 } | 2847 } |
2832 } | 2848 } |
2833 | 2849 |
2834 } else if (suffix == "ttl" || suffix == "n3") { | 2850 } else if (suffix == "ttl" || suffix == "n3") { |
2835 | 2851 |
2836 if (!RDFExporter::canExportModel(model)) { | 2852 if (!RDFExporter::canExportModel(model.get())) { |
2837 error = tr("Sorry, cannot export this layer type to RDF (supported types are: region, note, text, time instants, time values)"); | 2853 error = tr("Sorry, cannot export this layer type to RDF (supported types are: region, note, text, time instants, time values)"); |
2838 } else { | 2854 } else { |
2839 RDFExporter exporter(path, model); | 2855 RDFExporter exporter(path, model.get()); |
2840 exporter.write(); | 2856 exporter.write(); |
2841 if (!exporter.isOK()) { | 2857 if (!exporter.isOK()) { |
2842 error = exporter.getError(); | 2858 error = exporter.getError(); |
2843 } | 2859 } |
2844 } | 2860 } |
2845 | 2861 |
2846 } else { | 2862 } else { |
2847 | 2863 |
2848 CSVFileWriter writer(path, model, | 2864 CSVFileWriter writer(path, model.get(), |
2849 ((suffix == "csv") ? "," : "\t")); | 2865 ((suffix == "csv") ? "," : "\t")); |
2850 writer.write(); | 2866 writer.write(); |
2851 | 2867 |
2852 if (!writer.isOK()) { | 2868 if (!writer.isOK()) { |
2853 error = writer.getError(); | 2869 error = writer.getError(); |
2921 MainWindowBase::zoomToFit() | 2937 MainWindowBase::zoomToFit() |
2922 { | 2938 { |
2923 Pane *currentPane = m_paneStack->getCurrentPane(); | 2939 Pane *currentPane = m_paneStack->getCurrentPane(); |
2924 if (!currentPane) return; | 2940 if (!currentPane) return; |
2925 | 2941 |
2926 Model *model = getMainModel(); | 2942 auto model = getMainModel(); |
2927 if (!model) return; | 2943 if (!model) return; |
2928 | 2944 |
2929 sv_frame_t start = model->getStartFrame(); | 2945 sv_frame_t start = model->getStartFrame(); |
2930 sv_frame_t end = model->getEndFrame(); | 2946 sv_frame_t end = model->getEndFrame(); |
2931 if (m_playSource) end = std::max(end, m_playSource->getPlayEndFrame()); | 2947 if (m_playSource) end = std::max(end, m_playSource->getPlayEndFrame()); |
3241 if (m_viewManager) m_viewManager->setGlobalCentreFrame(0); | 3257 if (m_viewManager) m_viewManager->setGlobalCentreFrame(0); |
3242 | 3258 |
3243 SVCERR << "MainWindowBase::record: about to resume" << endl; | 3259 SVCERR << "MainWindowBase::record: about to resume" << endl; |
3244 m_audioIO->resume(); | 3260 m_audioIO->resume(); |
3245 | 3261 |
3246 WritableWaveFileModel *model = m_recordTarget->startRecording(); | 3262 WritableWaveFileModel *modelPtr = m_recordTarget->startRecording(); |
3247 if (!model) { | 3263 if (!modelPtr) { |
3248 SVCERR << "ERROR: MainWindowBase::record: Recording failed" << endl; | 3264 SVCERR << "ERROR: MainWindowBase::record: Recording failed" << endl; |
3249 QMessageBox::critical | 3265 QMessageBox::critical |
3250 (this, tr("Recording failed"), | 3266 (this, tr("Recording failed"), |
3251 tr("<b>Recording failed</b><p>Failed to switch to record mode (some internal problem?)</p>")); | 3267 tr("<b>Recording failed</b><p>Failed to switch to record mode (some internal problem?)</p>")); |
3252 if (action) action->setChecked(false); | 3268 if (action) action->setChecked(false); |
3253 return; | 3269 return; |
3254 } | 3270 } |
3255 | 3271 |
3256 if (!model->isOK()) { | 3272 if (!modelPtr->isOK()) { |
3257 SVCERR << "MainWindowBase::record: Model not OK, stopping and suspending" << endl; | 3273 SVCERR << "MainWindowBase::record: Model not OK, stopping and suspending" << endl; |
3258 m_recordTarget->stopRecording(); | 3274 m_recordTarget->stopRecording(); |
3259 m_audioIO->suspend(); | 3275 m_audioIO->suspend(); |
3260 if (action) action->setChecked(false); | 3276 if (action) action->setChecked(false); |
3261 delete model; | 3277 delete modelPtr; |
3262 return; | 3278 return; |
3263 } | 3279 } |
3264 | 3280 |
3265 SVCERR << "MainWindowBase::record: Model is OK, continuing..." << endl; | 3281 SVCERR << "MainWindowBase::record: Model is OK, continuing..." << endl; |
3266 | 3282 |
3267 PlayParameterRepository::getInstance()->addPlayable(model); | 3283 QString location = modelPtr->getLocation(); |
3284 | |
3285 auto modelId = modelPtr->getId(); | |
3286 ModelById::add(std::shared_ptr<Model>(modelPtr)); | |
3287 PlayParameterRepository::getInstance()->addPlayable(modelId.untyped); | |
3268 | 3288 |
3269 if (m_audioRecordMode == RecordReplaceSession || !getMainModel()) { | 3289 if (m_audioRecordMode == RecordReplaceSession || !getMainModel()) { |
3270 | 3290 |
3271 //!!! duplication with openAudio here | 3291 //!!! duplication with openAudio here |
3272 | 3292 |
3277 FileOpenStatus tplStatus = openSessionTemplate(templateName); | 3297 FileOpenStatus tplStatus = openSessionTemplate(templateName); |
3278 if (tplStatus == FileOpenCancelled) { | 3298 if (tplStatus == FileOpenCancelled) { |
3279 SVCERR << "MainWindowBase::record: Session template open cancelled, stopping and suspending" << endl; | 3299 SVCERR << "MainWindowBase::record: Session template open cancelled, stopping and suspending" << endl; |
3280 m_recordTarget->stopRecording(); | 3300 m_recordTarget->stopRecording(); |
3281 m_audioIO->suspend(); | 3301 m_audioIO->suspend(); |
3282 PlayParameterRepository::getInstance()->removePlayable(model); | 3302 PlayParameterRepository::getInstance()->removePlayable |
3303 (modelId.untyped); | |
3304 ModelById::release(modelId); | |
3283 return; | 3305 return; |
3284 } | 3306 } |
3285 if (tplStatus != FileOpenFailed) { | 3307 if (tplStatus != FileOpenFailed) { |
3286 loadedTemplate = true; | 3308 loadedTemplate = true; |
3287 } | 3309 } |
3290 if (!loadedTemplate) { | 3312 if (!loadedTemplate) { |
3291 closeSession(); | 3313 closeSession(); |
3292 createDocument(); | 3314 createDocument(); |
3293 } | 3315 } |
3294 | 3316 |
3295 Model *prevMain = getMainModel(); | 3317 ModelId prevMain = getMainModelId(); |
3296 if (prevMain) { | 3318 if (!prevMain.isNone()) { |
3297 m_playSource->removeModel(prevMain); | 3319 m_playSource->removeModel(prevMain); |
3298 PlayParameterRepository::getInstance()->removePlayable(prevMain); | 3320 PlayParameterRepository::getInstance()->removePlayable |
3321 (prevMain.untyped); | |
3299 } | 3322 } |
3300 | 3323 |
3301 m_document->setMainModel(model); | 3324 m_document->setMainModel(modelId); |
3302 setupMenus(); | 3325 setupMenus(); |
3303 findTimeRulerLayer(); | 3326 findTimeRulerLayer(); |
3304 | 3327 |
3305 m_originalLocation = model->getLocation(); | 3328 m_originalLocation = location; |
3306 | 3329 |
3307 if (loadedTemplate || (m_sessionFile == "")) { | 3330 if (loadedTemplate || (m_sessionFile == "")) { |
3308 CommandHistory::getInstance()->clear(); | 3331 CommandHistory::getInstance()->clear(); |
3309 CommandHistory::getInstance()->documentSaved(); | 3332 CommandHistory::getInstance()->documentSaved(); |
3310 } | 3333 } |
3315 } else { | 3338 } else { |
3316 | 3339 |
3317 CommandHistory::getInstance()->startCompoundOperation | 3340 CommandHistory::getInstance()->startCompoundOperation |
3318 (tr("Import Recorded Audio"), true); | 3341 (tr("Import Recorded Audio"), true); |
3319 | 3342 |
3320 m_document->addImportedModel(model); | 3343 m_document->addImportedModel(modelId); |
3321 | 3344 |
3322 AddPaneCommand *command = new AddPaneCommand(this); | 3345 AddPaneCommand *command = new AddPaneCommand(this); |
3323 CommandHistory::getInstance()->addCommand(command); | 3346 CommandHistory::getInstance()->addCommand(command); |
3324 | 3347 |
3325 Pane *pane = command->getPane(); | 3348 Pane *pane = command->getPane(); |
3326 | 3349 |
3327 if (m_timeRulerLayer) { | 3350 if (m_timeRulerLayer) { |
3328 m_document->addLayerToView(pane, m_timeRulerLayer); | 3351 m_document->addLayerToView(pane, m_timeRulerLayer); |
3329 } | 3352 } |
3330 | 3353 |
3331 Layer *newLayer = m_document->createImportedLayer(model); | 3354 Layer *newLayer = m_document->createImportedLayer(modelId); |
3332 | 3355 |
3333 if (newLayer) { | 3356 if (newLayer) { |
3334 m_document->addLayerToView(pane, newLayer); | 3357 m_document->addLayerToView(pane, newLayer); |
3335 } | 3358 } |
3336 | 3359 |
3337 CommandHistory::getInstance()->endCompoundOperation(); | 3360 CommandHistory::getInstance()->endCompoundOperation(); |
3338 } | 3361 } |
3339 | 3362 |
3340 updateMenuStates(); | 3363 updateMenuStates(); |
3341 m_recentFiles.addFile(model->getLocation()); | 3364 m_recentFiles.addFile(location); |
3342 currentPaneChanged(m_paneStack->getCurrentPane()); | 3365 currentPaneChanged(m_paneStack->getCurrentPane()); |
3343 | 3366 |
3344 emit audioFileLoaded(); | 3367 emit audioFileLoaded(); |
3345 } | 3368 } |
3346 | 3369 |
3722 Layer *layer = nullptr; | 3745 Layer *layer = nullptr; |
3723 Pane *pane = m_paneStack->getCurrentPane(); | 3746 Pane *pane = m_paneStack->getCurrentPane(); |
3724 if (pane) layer = pane->getSelectedLayer(); | 3747 if (pane) layer = pane->getSelectedLayer(); |
3725 if (!layer) return; | 3748 if (!layer) return; |
3726 | 3749 |
3727 Model *model = layer->getModel(); | 3750 auto tabular = ModelById::getAs<TabularModel>(layer->getModel()); |
3728 if (!model) return; | |
3729 | |
3730 TabularModel *tabular = dynamic_cast<TabularModel *>(model); | |
3731 if (!tabular) { | 3751 if (!tabular) { |
3732 //!!! how to prevent this function from being active if not | 3752 //!!! how to prevent this function from being active if not |
3733 //appropriate model type? or will we ultimately support | 3753 //appropriate model type? or will we ultimately support |
3734 //tabular display for all editable models? | 3754 //tabular display for all editable models? |
3735 SVDEBUG << "NOTE: Not a tabular model" << endl; | 3755 SVDEBUG << "NOTE: Not a tabular model" << endl; |
3744 } | 3764 } |
3745 } | 3765 } |
3746 | 3766 |
3747 QString title = layer->getLayerPresentationName(); | 3767 QString title = layer->getLayerPresentationName(); |
3748 | 3768 |
3749 ModelDataTableDialog *dialog = new ModelDataTableDialog(tabular, title, this); | 3769 ModelDataTableDialog *dialog = new ModelDataTableDialog |
3770 (layer->getModel(), title, this); | |
3750 dialog->setAttribute(Qt::WA_DeleteOnClose); | 3771 dialog->setAttribute(Qt::WA_DeleteOnClose); |
3751 | 3772 |
3752 connectLayerEditDialog(dialog); | 3773 connectLayerEditDialog(dialog); |
3753 | 3774 |
3754 m_layerDataDialogMap[layer] = dialog; | 3775 m_layerDataDialogMap[layer] = dialog; |
4003 // SVDEBUG << "MainWindowBase::layerInAView(" << layer << "," << inAView << ")" << endl; | 4024 // SVDEBUG << "MainWindowBase::layerInAView(" << layer << "," << inAView << ")" << endl; |
4004 | 4025 |
4005 if (!inAView) removeLayerEditDialog(layer); | 4026 if (!inAView) removeLayerEditDialog(layer); |
4006 | 4027 |
4007 // Check whether we need to add or remove model from play source | 4028 // Check whether we need to add or remove model from play source |
4008 Model *model = layer->getModel(); | 4029 ModelId modelId = layer->getModel(); |
4009 if (model) { | 4030 if (!modelId.isNone()) { |
4010 if (inAView) { | 4031 if (inAView) { |
4011 m_playSource->addModel(model); | 4032 m_playSource->addModel(modelId); |
4012 } else { | 4033 } else { |
4013 bool found = false; | 4034 bool found = false; |
4014 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) { | 4035 for (int i = 0; i < m_paneStack->getPaneCount(); ++i) { |
4015 Pane *pane = m_paneStack->getPane(i); | 4036 Pane *pane = m_paneStack->getPane(i); |
4016 if (!pane) continue; | 4037 if (!pane) continue; |
4017 for (int j = 0; j < pane->getLayerCount(); ++j) { | 4038 for (int j = 0; j < pane->getLayerCount(); ++j) { |
4018 Layer *pl = pane->getLayer(j); | 4039 Layer *pl = pane->getLayer(j); |
4019 if (pl && | 4040 if (pl && |
4020 !dynamic_cast<TimeRulerLayer *>(pl) && | 4041 !dynamic_cast<TimeRulerLayer *>(pl) && |
4021 (pl->getModel() == model)) { | 4042 (pl->getModel() == modelId)) { |
4022 found = true; | 4043 found = true; |
4023 break; | 4044 break; |
4024 } | 4045 } |
4025 } | 4046 } |
4026 if (found) break; | 4047 if (found) break; |
4027 } | 4048 } |
4028 if (!found) { | 4049 if (!found) { |
4029 m_playSource->removeModel(model); | 4050 m_playSource->removeModel(modelId); |
4030 } | 4051 } |
4031 } | 4052 } |
4032 } | 4053 } |
4033 | 4054 |
4034 updateMenuStates(); | 4055 updateMenuStates(); |
4050 delete dialog; | 4071 delete dialog; |
4051 } | 4072 } |
4052 } | 4073 } |
4053 | 4074 |
4054 void | 4075 void |
4055 MainWindowBase::modelAdded(Model *model) | 4076 MainWindowBase::modelAdded(ModelId model) |
4056 { | 4077 { |
4057 // SVDEBUG << "MainWindowBase::modelAdded(" << model << ")" << endl; | 4078 // SVDEBUG << "MainWindowBase::modelAdded(" << model << ")" << endl; |
4058 std::cerr << "\nAdding model " << model->getTypeName() << " to playsource " << std::endl; | 4079 std::cerr << "\nAdding model " << model << " to playsource " << std::endl; |
4059 m_playSource->addModel(model); | 4080 m_playSource->addModel(model); |
4060 } | 4081 } |
4061 | 4082 |
4062 void | 4083 void |
4063 MainWindowBase::mainModelChanged(WaveFileModel *model) | 4084 MainWindowBase::mainModelChanged(ModelId modelId) |
4064 { | 4085 { |
4065 // SVDEBUG << "MainWindowBase::mainModelChanged(" << model << ")" << endl; | 4086 // SVDEBUG << "MainWindowBase::mainModelChanged(" << model << ")" << endl; |
4066 updateDescriptionLabel(); | 4087 updateDescriptionLabel(); |
4088 auto model = ModelById::getAs<WaveFileModel>(modelId); | |
4067 if (model) m_viewManager->setMainModelSampleRate(model->getSampleRate()); | 4089 if (model) m_viewManager->setMainModelSampleRate(model->getSampleRate()); |
4068 if (model && !(m_playTarget || m_audioIO) && | 4090 if (model && !(m_playTarget || m_audioIO) && |
4069 (m_soundOptions & WithAudioOutput)) { | 4091 (m_soundOptions & WithAudioOutput)) { |
4070 createAudioIO(); | 4092 createAudioIO(); |
4071 } | 4093 } |
4072 } | 4094 } |
4073 | 4095 |
4074 void | 4096 void |
4075 MainWindowBase::modelAboutToBeDeleted(Model *model) | 4097 MainWindowBase::modelAboutToBeDeleted(ModelId model) |
4076 { | 4098 { |
4077 // SVDEBUG << "MainWindowBase::modelAboutToBeDeleted(" << model << ")" << endl; | |
4078 if (model == m_viewManager->getPlaybackModel()) { | 4099 if (model == m_viewManager->getPlaybackModel()) { |
4079 m_viewManager->setPlaybackModel(nullptr); | 4100 m_viewManager->setPlaybackModel({}); |
4080 } | 4101 } |
4081 m_playSource->removeModel(model); | 4102 m_playSource->removeModel(model); |
4082 } | 4103 } |
4083 | 4104 |
4084 void | 4105 void |
4116 | 4137 |
4117 updateMenuStates(); | 4138 updateMenuStates(); |
4118 } | 4139 } |
4119 | 4140 |
4120 void | 4141 void |
4121 MainWindowBase::alignmentComplete(AlignmentModel *model) | 4142 MainWindowBase::alignmentComplete(ModelId alignmentModelId) |
4122 { | 4143 { |
4123 cerr << "MainWindowBase::alignmentComplete(" << model << ")" << endl; | 4144 cerr << "MainWindowBase::alignmentComplete(" << alignmentModelId << ")" << endl; |
4124 } | 4145 } |
4125 | 4146 |
4126 void | 4147 void |
4127 MainWindowBase::pollOSC() | 4148 MainWindowBase::pollOSC() |
4128 { | 4149 { |