Mercurial > hg > sonic-visualiser
diff main/MainWindow.cpp @ 2300:eb7f4579e5cc by-id
Updates throughout for ModelById logic
author | Chris Cannam |
---|---|
date | Thu, 04 Jul 2019 14:32:08 +0100 |
parents | f78177863e26 |
children | 23fea10161a6 |
line wrap: on
line diff
--- a/main/MainWindow.cpp Mon Jun 24 16:58:10 2019 +0100 +++ b/main/MainWindow.cpp Thu Jul 04 14:32:08 2019 +0100 @@ -1294,11 +1294,11 @@ int backgroundTypeCount = int(sizeof(backgroundTypes) / sizeof(backgroundTypes[0])); - std::vector<Model *> models; + std::vector<ModelId> models; if (m_document) models = m_document->getTransformInputModels(); bool plural = (models.size() > 1); if (models.empty()) { - models.push_back(getMainModel()); // probably 0 + models.push_back(getMainModelId()); // probably None at this point } for (int i = 0; i < backgroundTypeCount; ++i) { @@ -1382,19 +1382,21 @@ default: break; } - std::vector<Model *> candidateModels = models; + std::vector<ModelId> candidateModels = models; + if (candidateModels.empty()) { + throw std::logic_error("candidateModels should not be empty"); + } - for (std::vector<Model *>::iterator mi = - candidateModels.begin(); - mi != candidateModels.end(); ++mi) { + for (auto modelId: candidateModels) { + + auto model = ModelById::get(modelId); - Model *model = *mi; - int channels = 0; if (model) { - DenseTimeValueModel *dtvm = - dynamic_cast<DenseTimeValueModel *>(model); - if (dtvm) channels = dtvm->getChannelCount(); + if (auto dtvm = ModelById::getAs<DenseTimeValueModel> + (modelId)) { + channels = dtvm->getChannelCount(); + } } if (channels < 1 && getMainModel()) { channels = getMainModel()->getChannelCount(); @@ -1419,14 +1421,14 @@ connect(this, SIGNAL(canAddPane(bool)), action, SLOT(setEnabled(bool))); m_paneActions.push_back - ({ action, LayerConfiguration(type, model) }); + ({ action, LayerConfiguration(type, modelId) }); } else { connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); m_layerActions.push_back - ({ action, LayerConfiguration(type, model) }); + ({ action, LayerConfiguration(type, modelId) }); } if (shortcutText != "") { m_keyReference->registerShortcut(action); @@ -1461,7 +1463,7 @@ if (isDefault) { action = new QAction(icon, actionText, this); - if (!model || model == getMainModel()) { + if (!model || modelId == getMainModelId()) { // Default for the shortcut is to // attach to an action that uses the // main model as input. But this may @@ -1482,21 +1484,21 @@ connect(this, SIGNAL(canAddPane(bool)), action, SLOT(setEnabled(bool))); m_paneActions.push_back - ({ action, LayerConfiguration(type, model, c - 1) }); + ({ action, LayerConfiguration(type, modelId, c - 1) }); } else { connect(action, SIGNAL(triggered()), this, SLOT(addLayer())); connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); m_layerActions.push_back - ({ action, LayerConfiguration(type, model, c - 1) }); + ({ action, LayerConfiguration(type, modelId, c - 1) }); } submenu->addAction(action); } if (isDefault && menuType == layerMenuType && - mi == candidateModels.begin()) { + modelId == *candidateModels.begin()) { // only add for one model, one channel, one menu on // right button -- the action itself will discover // which model is the correct one (based on pane) @@ -1507,7 +1509,7 @@ connect(this, SIGNAL(canAddLayer(bool)), action, SLOT(setEnabled(bool))); m_layerActions.push_back - ({ action, LayerConfiguration(type, nullptr, 0) }); + ({ action, LayerConfiguration(type, ModelId(), 0) }); m_rightButtonLayerMenu->addAction(action); } } @@ -1620,7 +1622,7 @@ } void -MainWindow::updateLayerShortcutsFor(Model *model) +MainWindow::updateLayerShortcutsFor(ModelId modelId) { // Called when e.g. the current pane has changed, to ensure the // various layer shortcuts select an action whose input model is @@ -1629,9 +1631,11 @@ set<LayerFactory::LayerType> seen; for (auto &a : m_paneActions) { - if (!a.second.sourceModel) continue; // empty pane/layer shortcut + if (a.second.sourceModel.isNone()) { + continue; // empty pane/layer shortcut + } auto type = a.second.layer; - if (a.second.sourceModel == model && seen.find(type) == seen.end()) { + if (a.second.sourceModel == modelId && seen.find(type) == seen.end()) { a.first->setShortcut(shortcutFor(type, true)); seen.insert(type); } else { @@ -1642,9 +1646,11 @@ seen.clear(); for (auto &a : m_layerActions) { - if (!a.second.sourceModel) continue; // empty pane/layer shortcut + if (a.second.sourceModel.isNone()) { + continue; // empty pane/layer shortcut + } auto type = a.second.layer; - if (a.second.sourceModel == model && seen.find(type) == seen.end()) { + if (a.second.sourceModel == modelId && seen.find(type) == seen.end()) { a.first->setShortcut(shortcutFor(type, false)); seen.insert(type); } else { @@ -2690,11 +2696,12 @@ void MainWindow::exportAudio(bool asData) { - if (!getMainModel()) return; - - RangeSummarisableTimeValueModel *model = getMainModel(); - std::set<RangeSummarisableTimeValueModel *> otherModels; - RangeSummarisableTimeValueModel *current = model; + auto modelId = getMainModelId(); + if (modelId.isNone()) return; + + std::set<ModelId> otherModelIds; + ModelId current = modelId; + if (m_paneStack) { for (int i = 0; i < m_paneStack->getPaneCount(); ++i) { Pane *pane = m_paneStack->getPane(i); @@ -2703,37 +2710,39 @@ Layer *layer = pane->getLayer(j); if (!layer) continue; cerr << "layer = " << layer->objectName() << endl; - Model *m = layer->getModel(); - RangeSummarisableTimeValueModel *wm = - dynamic_cast<RangeSummarisableTimeValueModel *>(m); - if (wm) { - cerr << "found: " << wm->objectName() << endl; - otherModels.insert(wm); + ModelId m = layer->getModel(); + if (ModelById::isa<RangeSummarisableTimeValueModel>(m)) { + otherModelIds.insert(m); if (pane == m_paneStack->getCurrentPane()) { - current = wm; + current = m; } } } } } - if (!otherModels.empty()) { - std::map<QString, RangeSummarisableTimeValueModel *> m; - m[tr("1. %2").arg(model->objectName())] = model; + if (!otherModelIds.empty()) { + std::map<QString, ModelId> m; + QString unnamed = tr("<unnamed>"); + QString oname = unnamed; + if (auto mp = ModelById::get(modelId)) { + oname = mp->objectName(); + } + m[tr("1. %2").arg(oname)] = modelId; int n = 2; int c = 0; - for (std::set<RangeSummarisableTimeValueModel *>::const_iterator i - = otherModels.begin(); - i != otherModels.end(); ++i) { - if (*i == model) continue; - m[tr("%1. %2").arg(n).arg((*i)->objectName())] = *i; + for (auto otherModelId: otherModelIds) { + if (otherModelId == modelId) continue; + oname = unnamed; + if (auto mp = ModelById::get(otherModelId)) { + oname = mp->objectName(); + } + m[tr("%1. %2").arg(n).arg(oname)] = otherModelId; ++n; - if (*i == current) c = n-1; + if (otherModelId == current) c = n-1; } QStringList items; - for (std::map<QString, RangeSummarisableTimeValueModel *> - ::const_iterator i = m.begin(); - i != m.end(); ++i) { - items << i->first; + for (auto i: m) { + items << i.first; } if (items.size() > 1) { bool ok = false; @@ -2743,14 +2752,20 @@ items, c, false, &ok); if (!ok || item.isEmpty()) return; if (m.find(item) == m.end()) { - cerr << "WARNING: Model " << item - << " not found in list!" << endl; + SVCERR << "WARNING: Model " << item + << " not found in list!" << endl; } else { - model = m[item]; + modelId = m[item]; } } } + auto model = ModelById::getAs<DenseTimeValueModel>(modelId); + if (!model) { + SVCERR << "ERROR: Chosen model is not a DenseTimeValueModel!" << endl; + return; + } + QString path; if (asData) { path = getSaveFileName(FileFinder::CSVFile); @@ -2835,7 +2850,7 @@ model->getSampleRate(), model->getChannelCount(), WavFileWriter::WriteToTemporary); - subwriter.writeModel(model, &subms); + subwriter.writeModel(model.get(), &subms); ok = subwriter.isOK(); if (!ok) { @@ -2856,7 +2871,7 @@ this, Qt::ApplicationModal }; - CSVFileWriter writer(path, model, &dialog, + CSVFileWriter writer(path, model.get(), &dialog, ((QFileInfo(path).suffix() == "csv") ? "," : "\t")); if (selectionToWrite) { @@ -2871,7 +2886,7 @@ model->getSampleRate(), model->getChannelCount(), WavFileWriter::WriteToTemporary); - writer.writeModel(model, selectionToWrite); + writer.writeModel(model.get(), selectionToWrite); ok = writer.isOK(); error = writer.getError(); } @@ -2936,8 +2951,10 @@ } else { + auto modelId = ModelById::add(std::shared_ptr<Model>(model)); + status = addOpenedAudioModel(path, - model, + modelId, CreateAdditionalModel, getDefaultSessionTemplate(), false); @@ -2997,11 +3014,11 @@ Layer *layer = pane->getSelectedLayer(); if (!layer) return; - Model *model = layer->getModel(); - if (!model) return; + ModelId modelId = layer->getModel(); + if (modelId.isNone()) return; FileFinder::FileType type = FileFinder::LayerFileNoMidi; - if (dynamic_cast<NoteModel *>(model)) type = FileFinder::LayerFile; + if (ModelById::isa<NoteModel>(modelId)) type = FileFinder::LayerFile; QString path = getSaveFileName(type); if (path == "") return; @@ -3387,7 +3404,7 @@ } QString mainModelLocation; - WaveFileModel *mm = getMainModel(); + auto mm = getMainModel(); if (mm) mainModelLocation = mm->getLocation(); if (mainModelLocation != "") { openAudio(mainModelLocation, ReplaceSession, n); @@ -3837,32 +3854,31 @@ Layer *newLayer = m_document->createLayer(configuration.layer); - Model *suggestedModel = configuration.sourceModel; - Model *model = nullptr; - - if (suggestedModel) { + ModelId suggestedModelId = configuration.sourceModel; + ModelId modelId; + + if (!suggestedModelId.isNone()) { // check its validity - std::vector<Model *> inputModels = m_document->getTransformInputModels(); - for (size_t j = 0; j < inputModels.size(); ++j) { - if (inputModels[j] == suggestedModel) { - model = suggestedModel; - break; + std::vector<ModelId> inputModels = m_document->getTransformInputModels(); + for (auto im: inputModels) { + if (im == suggestedModelId) { + modelId = suggestedModelId; } } - if (!model) { - cerr << "WARNING: Model " << (void *)suggestedModel - << " appears in pane action map, but is not reported " - << "by document as a valid transform source" << endl; + if (modelId.isNone()) { + cerr << "WARNING: Model " << modelId + << " appears in pane action map, but is not reported " + << "by document as a valid transform source" << endl; } } - if (!model) { - model = m_document->getMainModel(); + if (modelId.isNone()) { + modelId = m_document->getMainModel(); } - m_document->setModel(newLayer, model); + m_document->setModel(newLayer, modelId); m_document->setChannel(newLayer, configuration.channel); m_document->addLayerToView(pane, newLayer); @@ -3976,11 +3992,9 @@ } else { - Model *model = i->second.sourceModel; - - cerr << "model = "<< model << endl; - - if (!model) { + ModelId modelId = i->second.sourceModel; + + if (modelId.isNone()) { if (type == LayerFactory::TimeRuler) { newLayer = m_document->createMainModelLayer(type); } else { @@ -3989,27 +4003,25 @@ // the current pane -- this is the case for // right-button menu layer additions Pane::ModelSet ms = pane->getModels(); - foreach (Model *m, ms) { - RangeSummarisableTimeValueModel *r = - dynamic_cast<RangeSummarisableTimeValueModel *>(m); - if (r) model = m; + for (ModelId m: ms) { + if (ModelById::isa<RangeSummarisableTimeValueModel>(m)) { + modelId = m; + } } - if (!model) model = getMainModel(); + if (modelId.isNone()) { + modelId = getMainModelId(); + } } } - if (model) { + if (!modelId.isNone()) { newLayer = m_document->createLayer(type); - if (m_document->isKnownModel(model)) { + if (m_document->isKnownModel(modelId)) { m_document->setChannel(newLayer, i->second.channel); - m_document->setModel(newLayer, model); + m_document->setModel(newLayer, modelId); } else { - cerr << "WARNING: MainWindow::addLayer: unknown model " - << model - << " (\"" - << model->objectName() - << "\") in layer action map" - << endl; + SVCERR << "WARNING: MainWindow::addLayer: unknown model " + << modelId << " in layer action map" << endl; } } } @@ -4066,10 +4078,10 @@ return; } - std::vector<Model *> candidateInputModels = + std::vector<ModelId> candidateInputModels = m_document->getTransformInputModels(); - Model *defaultInputModel = nullptr; + ModelId defaultInputModelId; for (int j = 0; j < pane->getLayerCount(); ++j) { @@ -4078,37 +4090,37 @@ if (LayerFactory::getInstance()->getLayerType(layer) != LayerFactory::Waveform && - !layer->isLayerOpaque()) continue; - - Model *model = layer->getModel(); - if (!model) continue; - - for (size_t k = 0; k < candidateInputModels.size(); ++k) { - if (candidateInputModels[k] == model) { - defaultInputModel = model; + !layer->isLayerOpaque()) { + continue; + } + + ModelId modelId = layer->getModel(); + if (modelId.isNone()) continue; + + for (ModelId candidateId: candidateInputModels) { + if (candidateId == modelId) { + defaultInputModelId = modelId; break; } } - if (defaultInputModel) break; + if (!defaultInputModelId.isNone()) break; } - AggregateWaveModel *aggregate = nullptr; + ModelId aggregate; if (candidateInputModels.size() > 1) { // Add an aggregate model as another option AggregateWaveModel::ChannelSpecList sl; - foreach (Model *m, candidateInputModels) { - RangeSummarisableTimeValueModel *r = - qobject_cast<RangeSummarisableTimeValueModel *>(m); - if (r) { - sl.push_back(AggregateWaveModel::ModelChannelSpec(r->getId(), -1)); + for (ModelId mid: candidateInputModels) { + if (ModelById::isa<RangeSummarisableTimeValueModel>(mid)) { + sl.push_back(AggregateWaveModel::ModelChannelSpec(mid, -1)); } } if (!sl.empty()) { - aggregate = new AggregateWaveModel(sl); + auto aggregate = std::make_shared<AggregateWaveModel>(sl); aggregate->setObjectName(tr("Multiplex all of the above")); - candidateInputModels.push_back(aggregate); + candidateInputModels.push_back(ModelById::add(aggregate)); } } @@ -4124,23 +4136,24 @@ getConfigurationForTransform (transform, candidateInputModels, - defaultInputModel, + defaultInputModelId, m_playSource, startFrame, duration, &configurator); - if (aggregate) { + if (!aggregate.isNone()) { if (input.getModel() == aggregate) { - aggregate->setObjectName(tr("Multiplexed audio")); + if (auto aggregateModel = ModelById::get(aggregate)) { + aggregateModel->setObjectName(tr("Multiplexed audio")); + } m_document->addAggregateModel(aggregate); } else { - aggregate->aboutToDelete(); - delete aggregate; + ModelById::release(aggregate); } } - if (!input.getModel()) return; + if (input.getModel().isNone()) return; // SVDEBUG << "MainWindow::addLayer: Input model is " << input.getModel() << " \"" << input.getModel()->objectName() << "\"" << endl << "transform:" << endl << transform.toXmlString() << endl; @@ -4330,7 +4343,7 @@ if (layer && LayerFactory::getInstance()->getLayerType(layer) == LayerFactory::Waveform && - layer->getModel() == getMainModel()) { + layer->getModel() == getMainModelId()) { containsMainModel = true; break; } @@ -4341,15 +4354,14 @@ for (int i = pane->getLayerCount(); i > 0; ) { --i; Layer *layer = pane->getLayer(i); - RangeSummarisableTimeValueModel *tvm = - qobject_cast<RangeSummarisableTimeValueModel *>(layer->getModel()); - if (tvm) { + ModelId modelId = layer->getModel(); + if (ModelById::isa<RangeSummarisableTimeValueModel>(modelId)) { auto type = LayerFactory::getInstance()->getLayerType(layer); if (type != LayerFactory::TimeRuler) { - updateLayerShortcutsFor(tvm); + updateLayerShortcutsFor(modelId); } if (type == LayerFactory::Waveform) { - m_panLayer->setModel(tvm); + m_panLayer->setModel(modelId); panLayerSet = true; break; } @@ -4357,14 +4369,20 @@ } if (containsMainModel && !panLayerSet) { - m_panLayer->setModel(getMainModel()); + m_panLayer->setModel(getMainModelId()); } } void MainWindow::updateVisibleRangeDisplay(Pane *p) const { - if (!getMainModel() || !p) { + sv_samplerate_t sampleRate = 0; + if (auto mm = getMainModel()) { + sampleRate = mm->getSampleRate(); + } else { + return; + } + if (!p) { return; } @@ -4388,12 +4406,8 @@ endFrame = p->getLastVisibleFrame(); } - RealTime start = RealTime::frame2RealTime - (startFrame, getMainModel()->getSampleRate()); - - RealTime end = RealTime::frame2RealTime - (endFrame, getMainModel()->getSampleRate()); - + RealTime start = RealTime::frame2RealTime(startFrame, sampleRate); + RealTime end = RealTime::frame2RealTime(endFrame, sampleRate); RealTime duration = end - start; QString startStr, endStr, durationStr; @@ -4586,13 +4600,11 @@ if (!m_playSource || !m_playSource->isPlaying()) continue; - Model *model = static_cast<Layer *>(currentTimeValueLayer)->getModel(); - SparseTimeValueModel *tvm = - dynamic_cast<SparseTimeValueModel *>(model); - if (tvm) { + ModelId modelId = currentTimeValueLayer->getModel(); + if (ModelById::isa<SparseTimeValueModel>(modelId)) { Event point(frame, float(ev.getPitch() % 12), ""); AddEventCommand *command = new AddEventCommand - (tvm, point, tr("Add Point")); + (modelId.untyped, point, tr("Add Point")); CommandHistory::getInstance()->addCommand(command); } @@ -4639,20 +4651,20 @@ } void -MainWindow::modelAdded(Model *model) +MainWindow::modelAdded(ModelId modelId) { - MainWindowBase::modelAdded(model); - if (dynamic_cast<DenseTimeValueModel *>(model)) { + MainWindowBase::modelAdded(modelId); + if (ModelById::isa<DenseTimeValueModel>(modelId)) { setupPaneAndLayerMenus(); } } void -MainWindow::mainModelChanged(WaveFileModel *model) +MainWindow::mainModelChanged(ModelId modelId) { - m_panLayer->setModel(model); - - MainWindowBase::mainModelChanged(model); + m_panLayer->setModel(modelId); + + MainWindowBase::mainModelChanged(modelId); if (m_playTarget || m_audioIO) { connect(m_mainLevelPan, SIGNAL(levelChanged(float)), @@ -4684,19 +4696,6 @@ } void -MainWindow::modelAboutToBeDeleted(Model *model) -{ - if (model == m_panLayer->getModel()) { - if (model == getMainModel()) { - m_panLayer->setModel(nullptr); - } else { - m_panLayer->setModel(getMainModel()); - } - } - MainWindowBase::modelAboutToBeDeleted(model); -} - -void MainWindow::setInstantsNumbering() { QAction *a = dynamic_cast<QAction *>(sender());