# HG changeset patch # User Chris Cannam # Date 1561637785 -3600 # Node ID 11a150e65ee1c89b89edd64addcafbdf0f33bc60 # Parent de41a11cabc24cacbfd4726caed6e9f6ea812a02 Some work on updating layers for ModelId bits diff -r de41a11cabc2 -r 11a150e65ee1 layer/Colour3DPlotLayer.cpp --- a/layer/Colour3DPlotLayer.cpp Thu Jun 13 15:35:01 2019 +0100 +++ b/layer/Colour3DPlotLayer.cpp Thu Jun 27 13:16:25 2019 +0100 @@ -43,7 +43,6 @@ Colour3DPlotLayer::Colour3DPlotLayer() : - m_model(nullptr), m_colourScale(ColourScaleType::Linear), m_colourScaleSet(false), m_colourMap(0), @@ -59,20 +58,26 @@ m_miny(0), m_maxy(0), m_synchronous(false), - m_peakCache(nullptr), m_peakCacheDivisor(8) { QSettings settings; settings.beginGroup("Preferences"); - setColourMap(settings.value("colour-3d-plot-colour", ColourMapper::Green).toInt()); + setColourMap(settings.value("colour-3d-plot-colour", + ColourMapper::Green).toInt()); settings.endGroup(); } Colour3DPlotLayer::~Colour3DPlotLayer() { invalidateRenderers(); - if (m_peakCache) m_peakCache->aboutToDelete(); - delete m_peakCache; +} + +const ZoomConstraint * +Colour3DPlotLayer::getZoomConstraint() const +{ + auto model = ModelById::get(m_model); + if (model) return model->getZoomConstraint(); + else return nullptr; } ColourScaleType @@ -136,20 +141,23 @@ } void -Colour3DPlotLayer::setModel(const DenseThreeDimensionalModel *model) +Colour3DPlotLayer::setModel(ModelId modelId) { - SVDEBUG << "Colour3DPlotLayer::setModel(" << model << ")" << endl; + SVDEBUG << "Colour3DPlotLayer::setModel(" << modelId << ")" << endl; + + if (m_model == modelId) return; - if (m_model == model) return; - const DenseThreeDimensionalModel *oldModel = m_model; - m_model = model; - if (!m_model || !m_model->isOK()) return; + auto model = ModelById::getAs(modelId); + if (!model) throw std::logic_error("Not a DenseThreeDimensionalModel"); + +//!!! const DenseThreeDimensionalModel *oldModel = m_model; + m_model = modelId; connectSignals(m_model); - connect(m_model, SIGNAL(modelChanged()), + connect(model.get(), SIGNAL(modelChanged()), this, SLOT(handleModelChanged())); - connect(m_model, SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)), + connect(model.get(), SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)), this, SLOT(handleModelChangedWithin(sv_frame_t, sv_frame_t))); m_peakResolution = 256; @@ -164,7 +172,7 @@ invalidatePeakCache(); emit modelReplaced(); - emit sliceableModelReplaced(oldModel, model); +//!!! emit sliceableModelReplaced(oldModel, model); } void @@ -173,8 +181,7 @@ // renderers use the peak cache, so we must invalidate those too invalidateRenderers(); invalidateMagnitudes(); - - if (m_peakCache) m_peakCache->aboutToDelete(); + delete m_peakCache; m_peakCache = nullptr; } @@ -211,8 +218,9 @@ Colour3DPlotLayer::handleModelChanged() { if (!m_colourScaleSet && m_colourScale == ColourScaleType::Linear) { - if (m_model) { - if (m_model->shouldUseLogValueScale()) { + auto model = ModelById::getAs(m_model); + if (model) { + if (model->shouldUseLogValueScale()) { setColourScale(ColourScaleType::Log); } else { m_colourScaleSet = true; @@ -227,8 +235,9 @@ Colour3DPlotLayer::handleModelChangedWithin(sv_frame_t startFrame, sv_frame_t endFrame) { if (!m_colourScaleSet && m_colourScale == ColourScaleType::Linear) { - if (m_model && m_model->getWidth() > 50) { - if (m_model->shouldUseLogValueScale()) { + auto model = ModelById::getAs(m_model); + if (model && model->getWidth() > 50) { + if (model->shouldUseLogValueScale()) { setColourScale(ColourScaleType::Log); } else { m_colourScaleSet = true; @@ -649,14 +658,23 @@ return false; } +int +Colour3DPlotLayer::getCompletion(LayerGeometryProvider *) const +{ + auto model = ModelById::get(m_model); + if (model) return model->getCompletion(); + else return 0; +} + bool Colour3DPlotLayer::getValueExtents(double &min, double &max, bool &logarithmic, QString &unit) const { - if (!m_model) return false; + auto model = ModelById::getAs(m_model); + if (!model) return false; min = 0; - max = double(m_model->getHeight()); + max = double(model->getHeight()); logarithmic = (m_binScale == BinScale::Log); unit = ""; @@ -667,9 +685,10 @@ bool Colour3DPlotLayer::getDisplayExtents(double &min, double &max) const { - if (!m_model) return false; + auto model = ModelById::getAs(m_model); + if (!model) return false; - double hmax = double(m_model->getHeight()); + double hmax = double(model->getHeight()); min = m_miny; max = m_maxy; @@ -686,8 +705,6 @@ bool Colour3DPlotLayer::setDisplayExtents(double min, double max) { - if (!m_model) return false; - m_miny = int(lrint(min)); m_maxy = int(lrint(max)); @@ -707,37 +724,40 @@ int Colour3DPlotLayer::getVerticalZoomSteps(int &defaultStep) const { - if (!m_model) return 0; + auto model = ModelById::getAs(m_model); + if (!model) return 0; defaultStep = 0; - int h = m_model->getHeight(); + int h = model->getHeight(); return h; } int Colour3DPlotLayer::getCurrentVerticalZoomStep() const { - if (!m_model) return 0; + auto model = ModelById::getAs(m_model); + if (!model) return 0; double min, max; getDisplayExtents(min, max); - return m_model->getHeight() - int(lrint(max - min)); + return model->getHeight() - int(lrint(max - min)); } void Colour3DPlotLayer::setVerticalZoomStep(int step) { - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; // SVDEBUG << "Colour3DPlotLayer::setVerticalZoomStep(" <getHeight(), + 0, model->getHeight(), ""); } double Colour3DPlotLayer::getYForBin(const LayerGeometryProvider *v, double bin) const { double y = bin; - if (!m_model) return y; - double mn = 0, mx = m_model->getHeight(); + auto model = ModelById::getAs(m_model); + if (!model) return y; + double mn = 0, mx = model->getHeight(); getDisplayExtents(mn, mx); double h = v->getPaintHeight(); if (m_binScale == BinScale::Linear) { @@ -777,8 +802,9 @@ Colour3DPlotLayer::getBinForY(const LayerGeometryProvider *v, double y) const { double bin = y; - if (!m_model) return bin; - double mn = 0, mx = m_model->getHeight(); + auto model = ModelById::getAs(m_model); + if (!model) return bin; + double mn = 0, mx = model->getHeight(); getDisplayExtents(mn, mx); double h = v->getPaintHeight(); if (m_binScale == BinScale::Linear) { @@ -798,17 +824,18 @@ QString Colour3DPlotLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const { - if (!m_model) return ""; + auto model = ModelById::getAs(m_model); + if (!model) return ""; int x = pos.x(); int y = pos.y(); - sv_frame_t modelStart = m_model->getStartFrame(); - int modelResolution = m_model->getResolution(); + sv_frame_t modelStart = model->getStartFrame(); + int modelResolution = model->getResolution(); double srRatio = v->getViewManager()->getMainModelSampleRate() / - m_model->getSampleRate(); + model->getSampleRate(); int sx0 = int((double(v->getFrameForX(x)) / srRatio - double(modelStart)) / modelResolution); @@ -816,7 +843,7 @@ int f0 = sx0 * modelResolution; int f1 = f0 + modelResolution; - int sh = m_model->getHeight(); + int sh = model->getHeight(); int symin = m_miny; int symax = m_maxy; @@ -832,26 +859,26 @@ int sy = getIBinForY(v, y); - if (sy < 0 || sy >= m_model->getHeight()) { + if (sy < 0 || sy >= model->getHeight()) { return ""; } if (m_invertVertical) { - sy = m_model->getHeight() - sy - 1; + sy = model->getHeight() - sy - 1; } - float value = m_model->getValueAt(sx0, sy); + float value = model->getValueAt(sx0, sy); // cerr << "bin value (" << sx0 << "," << sy << ") is " << value << endl; - QString binName = m_model->getBinName(sy); + QString binName = model->getBinName(sy); if (binName == "") binName = QString("[%1]").arg(sy + 1); else binName = QString("%1 [%2]").arg(binName).arg(sy + 1); QString text = tr("Time:\t%1 - %2\nBin:\t%3\nValue:\t%4") - .arg(RealTime::frame2RealTime(f0, m_model->getSampleRate()) + .arg(RealTime::frame2RealTime(f0, model->getSampleRate()) .toText(true).c_str()) - .arg(RealTime::frame2RealTime(f1, m_model->getSampleRate()) + .arg(RealTime::frame2RealTime(f1, model->getSampleRate()) .toText(true).c_str()) .arg(binName) .arg(value); @@ -870,15 +897,16 @@ int Colour3DPlotLayer::getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &paint) const { - if (!m_model) return 0; + auto model = ModelById::getAs(m_model); + if (!model) return 0; - QString sampleText = QString("[%1]").arg(m_model->getHeight()); + QString sampleText = QString("[%1]").arg(model->getHeight()); int tw = paint.fontMetrics().width(sampleText); bool another = false; - for (int i = 0; i < m_model->getHeight(); ++i) { - if (m_model->getBinName(i).length() > sampleText.length()) { - sampleText = m_model->getBinName(i); + for (int i = 0; i < model->getHeight(); ++i) { + if (model->getBinName(i).length() > sampleText.length()) { + sampleText = model->getBinName(i); another = true; } } @@ -892,7 +920,8 @@ void Colour3DPlotLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect rect) const { - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; int h = rect.height(), w = rect.width(); @@ -948,7 +977,7 @@ paint.setPen(v->getForeground()); - int sh = m_model->getHeight(); + int sh = model->getHeight(); int symin = m_miny; int symax = m_maxy; @@ -994,10 +1023,10 @@ int idx = i - 1; if (m_invertVertical) { - idx = m_model->getHeight() - idx - 1; + idx = model->getHeight() - idx - 1; } - QString text = m_model->getBinName(idx); + QString text = model->getBinName(idx); if (text == "") text = QString("[%1]").arg(idx + 1); int ty = y0 + (h/2) - (paint.fontMetrics().height()/2) + @@ -1013,13 +1042,15 @@ Colour3DPlotRenderer * Colour3DPlotLayer::getRenderer(const LayerGeometryProvider *v) const { + auto model = ModelById::getAs(m_model); + if (!model) return nullptr; + int viewId = v->getId(); if (m_renderers.find(viewId) == m_renderers.end()) { Colour3DPlotRenderer::Sources sources; sources.verticalBinLayer = this; - sources.fft = nullptr; sources.source = m_model; sources.peakCaches.push_back(getPeakCache()); @@ -1037,16 +1068,16 @@ maxValue = m_viewMags[viewId].getMax(); } else if (m_normalization == ColumnNormalization::Hybrid) { minValue = 0; - maxValue = log10(m_model->getMaximumLevel() + 1.0); + maxValue = log10(model->getMaximumLevel() + 1.0); } else if (m_normalization == ColumnNormalization::None) { - minValue = m_model->getMinimumLevel(); - maxValue = m_model->getMaximumLevel(); + minValue = model->getMinimumLevel(); + maxValue = model->getMaximumLevel(); } SVDEBUG << "Colour3DPlotLayer: rebuilding renderer, value range is " << minValue << " -> " << maxValue - << " (model min = " << m_model->getMinimumLevel() - << ", max = " << m_model->getMaximumLevel() << ")" + << " (model min = " << model->getMinimumLevel() + << ", max = " << model->getMaximumLevel() << ")" << endl; if (maxValue <= minValue) { @@ -1139,9 +1170,10 @@ void Colour3DPlotLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const { + auto model = ModelById::getAs(m_model); /* - if (m_model) { - SVDEBUG << "Colour3DPlotLayer::paint: model says shouldUseLogValueScale = " << m_model->shouldUseLogValueScale() << endl; + if (model) { + SVDEBUG << "Colour3DPlotLayer::paint: model says shouldUseLogValueScale = " << model->shouldUseLogValueScale() << endl; } */ Profiler profiler("Colour3DPlotLayer::paint"); @@ -1150,7 +1182,7 @@ #endif int completion = 0; - if (!m_model || !m_model->isOK() || !m_model->isReady(&completion)) { + if (!model || !model->isOK() || !model->isReady(&completion)) { if (completion > 0) { paint.fillRect(0, 10, v->getPaintWidth() * completion / 100, 10, QColor(120, 120, 120)); @@ -1158,7 +1190,7 @@ return; } - if (m_model->getWidth() == 0) { + if (model->getWidth() == 0) { #ifdef DEBUG_COLOUR_3D_PLOT_LAYER_PAINT SVDEBUG << "Colour3DPlotLayer::paint(): model width == 0, " << "nothing to paint (yet)" << endl; @@ -1174,11 +1206,12 @@ int &resolution, SnapType snap) const { - if (!m_model) { + auto model = ModelById::getAs(m_model); + if (!model) { return Layer::snapToFeatureFrame(v, frame, resolution, snap); } - resolution = m_model->getResolution(); + resolution = model->getResolution(); sv_frame_t left = (frame / resolution) * resolution; sv_frame_t right = left + resolution; diff -r de41a11cabc2 -r 11a150e65ee1 layer/Colour3DPlotLayer.h --- a/layer/Colour3DPlotLayer.h Thu Jun 13 15:35:01 2019 +0100 +++ b/layer/Colour3DPlotLayer.h Thu Jun 27 13:16:25 2019 +0100 @@ -46,23 +46,28 @@ Colour3DPlotLayer(); ~Colour3DPlotLayer(); - const ZoomConstraint *getZoomConstraint() const override { - return m_model ? m_model->getZoomConstraint() : 0; - } - const Model *getModel() const override { return m_model; } - void paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const override; + ModelId getModel() const override { return m_model; } + + const ZoomConstraint *getZoomConstraint() const override; + + void paint(LayerGeometryProvider *v, + QPainter &paint, QRect rect) const override; void setSynchronousPainting(bool synchronous) override; - int getVerticalScaleWidth(LayerGeometryProvider *v, bool, QPainter &) const override; - void paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect rect) const override; + int getVerticalScaleWidth(LayerGeometryProvider *v, + bool, QPainter &) const override; + void paintVerticalScale(LayerGeometryProvider *v, + bool, QPainter &paint, QRect rect) const override; - QString getFeatureDescription(LayerGeometryProvider *v, QPoint &) const override; + QString getFeatureDescription(LayerGeometryProvider *v, + QPoint &) const override; bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, - int &resolution, - SnapType snap) const override; + int &resolution, + SnapType snap) const override; - void setLayerDormant(const LayerGeometryProvider *v, bool dormant) override; + void setLayerDormant(const LayerGeometryProvider *v, + bool dormant) override; bool isLayerScrollable(const LayerGeometryProvider *v) const override; @@ -70,9 +75,9 @@ return ColourHasMeaningfulValue; } - void setModel(const DenseThreeDimensionalModel *model); + void setModel(ModelId model); // a DenseThreeDimensionalModel - int getCompletion(LayerGeometryProvider *) const override { return m_model->getCompletion(); } + int getCompletion(LayerGeometryProvider *) const override; PropertyList getProperties() const override; PropertyType getPropertyType(const PropertyName &) const override; @@ -80,11 +85,11 @@ QString getPropertyIconName(const PropertyName &) const override; QString getPropertyGroupName(const PropertyName &) const override; int getPropertyRangeAndValue(const PropertyName &, - int *min, int *max, int *deflt) const override; + int *min, int *max, int *deflt) const override; QString getPropertyValueLabel(const PropertyName &, - int value) const override; + int value) const override; QString getPropertyValueIconName(const PropertyName &, - int value) const override; + int value) const override; RangeMapper *getNewPropertyRangeMapper(const PropertyName &) const override; void setProperty(const PropertyName &, int value) override; void setProperties(const QXmlAttributes &) override; @@ -132,30 +137,30 @@ bool hasLightBackground() const override; bool getValueExtents(double &min, double &max, - bool &logarithmic, QString &unit) const override; + bool &logarithmic, QString &unit) const override; bool getDisplayExtents(double &min, double &max) const override; bool setDisplayExtents(double min, double max) override; bool getYScaleValue(const LayerGeometryProvider *, int /* y */, - double &/* value */, QString &/* unit */) const override; + double &/* value */, QString &/* unit */) const override; int getVerticalZoomSteps(int &defaultStep) const override; int getCurrentVerticalZoomStep() const override; void setVerticalZoomStep(int) override; RangeMapper *getNewVerticalZoomRangeMapper() const override; - const Model *getSliceableModel() const override { return m_model; } + ModelId getSliceableModel() const override { return m_model; } void toXml(QTextStream &stream, QString indent = "", - QString extraAttributes = "") const override; + QString extraAttributes = "") const override; protected slots: void handleModelChanged(); void handleModelChangedWithin(sv_frame_t, sv_frame_t); protected: - const DenseThreeDimensionalModel *m_model; // I do not own this + ModelId m_model; // A DenseThreeDimensionalModel ColourScaleType m_colourScale; bool m_colourScaleSet; @@ -184,8 +189,8 @@ mutable Dense3DModelPeakCache *m_peakCache; const int m_peakCacheDivisor; + void invalidatePeakCache(); Dense3DModelPeakCache *getPeakCache() const; - void invalidatePeakCache(); typedef std::map ViewMagMap; // key is view id mutable ViewMagMap m_viewMags; diff -r de41a11cabc2 -r 11a150e65ee1 layer/Colour3DPlotRenderer.cpp --- a/layer/Colour3DPlotRenderer.cpp Thu Jun 13 15:35:01 2019 +0100 +++ b/layer/Colour3DPlotRenderer.cpp Thu Jun 27 13:16:25 2019 +0100 @@ -334,7 +334,7 @@ Colour3DPlotRenderer::RenderType Colour3DPlotRenderer::decideRenderType(const LayerGeometryProvider *v) const { - const DenseThreeDimensionalModel *model = m_sources.source; + auto model = ModelById::getAs(m_sources.source); if (!model || !v || !(v->getViewManager())) { return DrawBufferPixelResolution; // or anything } @@ -398,7 +398,7 @@ } if (m_params.colourScale.getScale() == ColourScaleType::Phase && - m_sources.fft) { + !m_sources.fft.isNone()) { return column; } else { column = ColumnOp::applyGain(column, m_params.scaleFactor); @@ -414,27 +414,31 @@ Profiler profiler("Colour3DPlotRenderer::getColumn"); ColumnOp::Column column; + ColumnOp::Column fullColumn; - if (m_params.colourScale.getScale() == ColourScaleType::Phase && - m_sources.fft) { - - ColumnOp::Column fullColumn = m_sources.fft->getPhases(sx); - - column = vector(fullColumn.data() + minbin, - fullColumn.data() + minbin + nbins); - - } else { - - ColumnOp::Column fullColumn = - (peakCacheIndex >= 0 ? - m_sources.peakCaches[peakCacheIndex] : - m_sources.source) - ->getColumn(sx); - - column = vector(fullColumn.data() + minbin, - fullColumn.data() + minbin + nbins); + if (m_params.colourScale.getScale() == ColourScaleType::Phase) { + auto fftModel = ModelById::getAs(m_sources.fft); + if (fftModel) { + fullColumn = fftModel->getPhases(sx); + } } + if (fullColumn.empty()) { + + if (peakCacheIndex >= 0) { + fullColumn = m_sources.peakCaches[peakCacheIndex]->getColumn(sx); + } else { + auto model = ModelById::getAs + (m_sources.source); + if (!model) { + return vector(nbins, 0.f); + } + fullColumn = model->getColumn(sx); + } + } + + column = vector(fullColumn.data() + minbin, + fullColumn.data() + minbin + nbins); return column; } @@ -451,7 +455,8 @@ bool illuminate = v->shouldIlluminateLocalFeatures (m_sources.verticalBinLayer, illuminatePos); - const DenseThreeDimensionalModel *model = m_sources.source; + auto model = ModelById::getAs(m_sources.source); + if (!model) return magRange; int x0 = rect.left(); int x1 = rect.right() + 1; @@ -602,7 +607,7 @@ peakCacheIndex = -1; binsPerPeak = -1; - const DenseThreeDimensionalModel *model = m_sources.source; + auto model = ModelById::getAs(m_sources.source); if (!model) return; if (m_params.binDisplay == BinDisplay::PeakFrequencies) return; if (m_params.colourScale.getScale() == ColourScaleType::Phase) return; @@ -653,10 +658,8 @@ // buffer is at the same resolution as the target in the cache, so // no extra scaling needed. - const DenseThreeDimensionalModel *model = m_sources.source; - if (!model || !model->isOK() || !model->isReady()) { - throw std::logic_error("no source model provided, or model not ready"); - } + auto model = ModelById::getAs(m_sources.source); + if (!model) return; int h = v->getPaintHeight(); @@ -794,10 +797,8 @@ // buffer is at bin resolution, i.e. buffer x == source column // number. We use toolkit smooth scaling for interpolation. - const DenseThreeDimensionalModel *model = m_sources.source; - if (!model || !model->isOK() || !model->isReady()) { - throw std::logic_error("no source model provided, or model not ready"); - } + auto model = ModelById::getAs(m_sources.source); + if (!model) return; // The draw buffer will contain a fragment at bin resolution. We // need to ensure that it starts and ends at points where a @@ -950,7 +951,10 @@ Profiler profiler("Colour3DPlotRenderer::renderDrawBuffer"); int divisor = 1; - const DenseThreeDimensionalModel *sourceModel = m_sources.source; + auto model = ModelById::getAs(m_sources.source); + if (!model) return 0; + + const DenseThreeDimensionalModel *sourceModel = model.get(); if (peakCacheIndex >= 0) { divisor = m_sources.peakCaches[peakCacheIndex]->getColumnsPerPeak(); sourceModel = m_sources.peakCaches[peakCacheIndex]; @@ -1125,7 +1129,8 @@ RenderTimer::SlowRender : RenderTimer::NoTimeout); - const FFTModel *fft = m_sources.fft; + auto fft = ModelById::getAs(m_sources.fft); + if (!fft) return 0; int sh = fft->getHeight(); diff -r de41a11cabc2 -r 11a150e65ee1 layer/Colour3DPlotRenderer.h --- a/layer/Colour3DPlotRenderer.h Thu Jun 13 15:35:01 2019 +0100 +++ b/layer/Colour3DPlotRenderer.h Thu Jun 27 13:16:25 2019 +0100 @@ -23,16 +23,16 @@ #include "base/ColumnOp.h" #include "base/MagnitudeRange.h" +#include "data/model/Model.h" + #include #include #include class LayerGeometryProvider; class VerticalBinLayer; -class DenseThreeDimensionalModel; +class RenderTimer; class Dense3DModelPeakCache; -class FFTModel; -class RenderTimer; enum class BinDisplay { AllBins, @@ -49,12 +49,12 @@ { public: struct Sources { - Sources() : verticalBinLayer(0), source(0), fft(0) { } + Sources() : verticalBinLayer(0) { } // These must all outlive this class - const VerticalBinLayer *verticalBinLayer; // always - const DenseThreeDimensionalModel *source; // always - const FFTModel *fft; // optionally + const VerticalBinLayer *verticalBinLayer; // always + ModelId source; // always; a DenseThreeDimensionalModel + ModelId fft; // optionally std::vector peakCaches; // zero or more }; diff -r de41a11cabc2 -r 11a150e65ee1 layer/FlexiNoteLayer.cpp --- a/layer/FlexiNoteLayer.cpp Thu Jun 13 15:35:01 2019 +0100 +++ b/layer/FlexiNoteLayer.cpp Thu Jun 27 13:16:25 2019 +0100 @@ -53,7 +53,6 @@ FlexiNoteLayer::FlexiNoteLayer() : SingleColourLayer(), - m_model(nullptr), m_editing(false), m_intelligentActions(true), m_dragPointX(0), @@ -73,16 +72,17 @@ } void -FlexiNoteLayer::setModel(NoteModel *model) +FlexiNoteLayer::setModel(ModelId modelId) { - if (m_model == model) return; - m_model = model; + if (m_model == modelId) return; + + auto model = ModelById::getAs(modelId); + if (!model) throw std::logic_error("Not a NoteModel"); + + m_model = modelId; connectSignals(m_model); - // m_scaleMinimum = 0; - // m_scaleMaximum = 0; - emit modelReplaced(); } @@ -123,7 +123,8 @@ QString FlexiNoteLayer::getScaleUnits() const { - if (m_model) return m_model->getScaleUnits(); + auto model = ModelById::getAs(m_model); + if (model) return model->getScaleUnits(); else return ""; } @@ -144,7 +145,8 @@ } else if (name == "Scale Units") { if (deflt) *deflt = 0; - if (m_model) { + auto model = ModelById::getAs(m_model); + if (model) { val = UnitDatabase::getInstance()->getUnitId (getScaleUnits()); } @@ -179,8 +181,9 @@ if (name == "Vertical Scale") { setVerticalScale(VerticalScale(value)); } else if (name == "Scale Units") { - if (m_model) { - m_model->setScaleUnits + auto model = ModelById::getAs(m_model); + if (model) { + model->setScaleUnits (UnitDatabase::getInstance()->getUnitById(value)); emit modelChanged(); } @@ -215,13 +218,22 @@ // return false; } +int +FlexiNoteLayer::getCompletion(LayerGeometryProvider *) const +{ + auto model = ModelById::get(m_model); + if (model) return model->getCompletion(); + else return 0; +} + bool FlexiNoteLayer::getValueExtents(double &min, double &max, bool &logarithmic, QString &unit) const { - if (!m_model) return false; - min = m_model->getValueMinimum(); - max = m_model->getValueMaximum(); + auto model = ModelById::getAs(m_model); + if (!model) return false; + min = model->getValueMinimum(); + max = model->getValueMaximum(); if (shouldConvertMIDIToHz()) { unit = "Hz"; @@ -238,7 +250,8 @@ bool FlexiNoteLayer::getDisplayExtents(double &min, double &max) const { - if (!m_model || shouldAutoAlign()) { + auto model = ModelById::getAs(m_model); + if (!model || shouldAutoAlign()) { // std::cerr << "No model or shouldAutoAlign()" << std::endl; return false; } @@ -250,8 +263,8 @@ } if (m_scaleMinimum == m_scaleMaximum) { - min = m_model->getValueMinimum(); - max = m_model->getValueMaximum(); + min = model->getValueMinimum(); + max = model->getValueMaximum(); } else { min = m_scaleMinimum; max = m_scaleMaximum; @@ -272,7 +285,8 @@ bool FlexiNoteLayer::setDisplayExtents(double min, double max) { - if (!m_model) return false; + auto model = ModelById::getAs(m_model); + if (!model) return false; if (min == max) { if (min == 0.f) { @@ -297,7 +311,8 @@ FlexiNoteLayer::getVerticalZoomSteps(int &defaultStep) const { if (shouldAutoAlign()) return 0; - if (!m_model) return 0; + auto model = ModelById::getAs(m_model); + if (!model) return 0; defaultStep = 0; return 100; @@ -307,7 +322,8 @@ FlexiNoteLayer::getCurrentVerticalZoomStep() const { if (shouldAutoAlign()) return 0; - if (!m_model) return 0; + auto model = ModelById::getAs(m_model); + if (!model) return 0; RangeMapper *mapper = getNewVerticalZoomRangeMapper(); if (!mapper) return 0; @@ -328,7 +344,8 @@ FlexiNoteLayer::setVerticalZoomStep(int step) { if (shouldAutoAlign()) return; - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; RangeMapper *mapper = getNewVerticalZoomRangeMapper(); if (!mapper) return; @@ -378,7 +395,8 @@ RangeMapper * FlexiNoteLayer::getNewVerticalZoomRangeMapper() const { - if (!m_model) return nullptr; + auto model = ModelById::getAs(m_model); + if (!model) return nullptr; RangeMapper *mapper; @@ -401,21 +419,22 @@ EventVector FlexiNoteLayer::getLocalPoints(LayerGeometryProvider *v, int x) const { - if (!m_model) return {}; + auto model = ModelById::getAs(m_model); + if (!model) return {}; sv_frame_t frame = v->getFrameForX(x); - EventVector local = m_model->getEventsCovering(frame); + EventVector local = model->getEventsCovering(frame); if (!local.empty()) return local; int fuzz = ViewManager::scalePixelSize(2); sv_frame_t start = v->getFrameForX(x - fuzz); sv_frame_t end = v->getFrameForX(x + fuzz); - local = m_model->getEventsStartingWithin(frame, end - frame); + local = model->getEventsStartingWithin(frame, end - frame); if (!local.empty()) return local; - local = m_model->getEventsSpanning(start, frame - start); + local = model->getEventsSpanning(start, frame - start); if (!local.empty()) return local; return {}; @@ -424,11 +443,12 @@ bool FlexiNoteLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, Event &point) const { - if (!m_model) return false; + auto model = ModelById::getAs(m_model); + if (!model) return false; sv_frame_t frame = v->getFrameForX(x); - EventVector onPoints = m_model->getEventsCovering(frame); + EventVector onPoints = model->getEventsCovering(frame); if (onPoints.empty()) return false; int nearestDistance = -1; @@ -448,11 +468,12 @@ FlexiNoteLayer::getNoteToEdit(LayerGeometryProvider *v, int x, int y, Event &point) const { // GF: find the note that is closest to the cursor - if (!m_model) return false; + auto model = ModelById::getAs(m_model); + if (!model) return false; sv_frame_t frame = v->getFrameForX(x); - EventVector onPoints = m_model->getEventsCovering(frame); + EventVector onPoints = model->getEventsCovering(frame); if (onPoints.empty()) return false; int nearestDistance = -1; @@ -473,12 +494,13 @@ { int x = pos.x(); - if (!m_model || !m_model->getSampleRate()) return ""; + auto model = ModelById::getAs(m_model); + if (!model || !model->getSampleRate()) return ""; EventVector points = getLocalPoints(v, x); if (points.empty()) { - if (!m_model->isReady()) { + if (!model->isReady()) { return tr("In progress"); } else { return tr("No local points"); @@ -493,9 +515,9 @@ int y = getYForValue(v, i->getValue()); int h = NOTE_HEIGHT; // GF: larger notes - if (m_model->getValueQuantization() != 0.0) { + if (model->getValueQuantization() != 0.0) { h = y - getYForValue - (v, i->getValue() + m_model->getValueQuantization()); + (v, i->getValue() + model->getValueQuantization()); if (h < NOTE_HEIGHT) h = NOTE_HEIGHT; } @@ -509,9 +531,9 @@ if (i == points.end()) return tr("No local points"); RealTime rt = RealTime::frame2RealTime(note.getFrame(), - m_model->getSampleRate()); + model->getSampleRate()); RealTime rd = RealTime::frame2RealTime(note.getDuration(), - m_model->getSampleRate()); + model->getSampleRate()); QString pitchText; @@ -562,11 +584,12 @@ int &resolution, SnapType snap) const { - if (!m_model) { + auto model = ModelById::getAs(m_model); + if (!model) { return Layer::snapToFeatureFrame(v, frame, resolution, snap); } - resolution = m_model->getResolution(); + resolution = model->getResolution(); EventVector points; if (snap == SnapNeighbouring) { @@ -577,7 +600,7 @@ return true; } - points = m_model->getEventsCovering(frame); + points = model->getEventsCovering(frame); sv_frame_t snapped = frame; bool found = false; @@ -650,8 +673,9 @@ if (!v->getValueExtents(queryUnits, min, max, log)) { - min = m_model->getValueMinimum(); - max = m_model->getValueMaximum(); + auto model = ModelById::getAs(m_model); + min = model->getValueMinimum(); + max = model->getValueMaximum(); if (shouldConvertMIDIToHz()) { min = Pitch::getFrequencyForPitch(int(lrint(min))); @@ -752,16 +776,16 @@ bool FlexiNoteLayer::shouldAutoAlign() const { - if (!m_model) return false; return (m_verticalScale == AutoAlignScale); } void FlexiNoteLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const { - if (!m_model || !m_model->isOK()) return; + auto model = ModelById::getAs(m_model); + if (!model || !model->isOK()) return; - sv_samplerate_t sampleRate = m_model->getSampleRate(); + sv_samplerate_t sampleRate = model->getSampleRate(); if (!sampleRate) return; // Profiler profiler("FlexiNoteLayer::paint", true); @@ -770,7 +794,7 @@ sv_frame_t frame0 = v->getFrameForX(x0); sv_frame_t frame1 = v->getFrameForX(x1); - EventVector points(m_model->getEventsSpanning(frame0, frame1 - frame0)); + EventVector points(model->getEventsSpanning(frame0, frame1 - frame0)); if (points.empty()) return; paint.setPen(getBaseQColor()); @@ -779,10 +803,10 @@ brushColour.setAlpha(80); // SVDEBUG << "FlexiNoteLayer::paint: resolution is " -// << m_model->getResolution() << " frames" << endl; +// << model->getResolution() << " frames" << endl; - double min = m_model->getValueMinimum(); - double max = m_model->getValueMaximum(); + double min = model->getValueMinimum(); + double max = model->getValueMaximum(); if (max == min) max = min + 1.0; QPoint localPos; @@ -810,8 +834,8 @@ int w = v->getXForFrame(p.getFrame() + p.getDuration()) - x; int h = NOTE_HEIGHT; //GF: larger notes - if (m_model->getValueQuantization() != 0.0) { - h = y - getYForValue(v, p.getValue() + m_model->getValueQuantization()); + if (model->getValueQuantization() != 0.0) { + h = y - getYForValue(v, p.getValue() + model->getValueQuantization()); if (h < NOTE_HEIGHT) h = NOTE_HEIGHT; //GF: larger notes } @@ -827,7 +851,7 @@ paint.setPen(v->getForeground()); QString vlabel = tr("freq: %1%2") - .arg(p.getValue()).arg(m_model->getScaleUnits()); + .arg(p.getValue()).arg(model->getScaleUnits()); PaintAssistant::drawVisibleText (v, paint, x, @@ -837,7 +861,7 @@ QString hlabel = tr("dur: %1") .arg(RealTime::frame2RealTime - (p.getDuration(), m_model->getSampleRate()).toText(true) + (p.getDuration(), model->getSampleRate()).toText(true) .c_str()); PaintAssistant::drawVisibleText (v, paint, @@ -869,7 +893,7 @@ int FlexiNoteLayer::getVerticalScaleWidth(LayerGeometryProvider *v, bool, QPainter &paint) const { - if (!m_model || shouldAutoAlign()) { + if (shouldAutoAlign()) { return 0; } else { if (m_verticalScale == LogScale || m_verticalScale == MIDIRangeScale) { @@ -883,7 +907,8 @@ void FlexiNoteLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const { - if (!m_model || m_model->isEmpty()) return; + auto model = ModelById::getAs(m_model); + if (!model || model->isEmpty()) return; QString unit; double min, max; @@ -923,11 +948,12 @@ { // SVDEBUG << "FlexiNoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; sv_frame_t frame = v->getFrameForX(e->x()); if (frame < 0) frame = 0; - frame = frame / m_model->getResolution() * m_model->getResolution(); + frame = frame / model->getResolution() * model->getResolution(); double value = getValueForY(v, e->y()); @@ -935,7 +961,7 @@ m_originalPoint = m_editingPoint; if (m_editingCommand) finish(m_editingCommand); - m_editingCommand = new ChangeEventsCommand(m_model, tr("Draw Point")); + m_editingCommand = new ChangeEventsCommand(m_model, tr("Draw Point")); m_editingCommand->add(m_editingPoint); m_editing = true; @@ -946,11 +972,12 @@ { // SVDEBUG << "FlexiNoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; - if (!m_model || !m_editing) return; + auto model = ModelById::getAs(m_model); + if (!model || !m_editing) return; sv_frame_t frame = v->getFrameForX(e->x()); if (frame < 0) frame = 0; - frame = frame / m_model->getResolution() * m_model->getResolution(); + frame = frame / model->getResolution() * model->getResolution(); double newValue = getValueForY(v, e->y()); @@ -975,7 +1002,8 @@ FlexiNoteLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *) { // SVDEBUG << "FlexiNoteLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl; - if (!m_model || !m_editing) return; + auto model = ModelById::getAs(m_model); + if (!model || !m_editing) return; finish(m_editingCommand); m_editingCommand = nullptr; m_editing = false; @@ -984,7 +1012,8 @@ void FlexiNoteLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e) { - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; @@ -1004,15 +1033,15 @@ void FlexiNoteLayer::eraseEnd(LayerGeometryProvider *v, QMouseEvent *e) { - if (!m_model || !m_editing) return; - + if (!m_editing) return; m_editing = false; Event p(0); if (!getPointToDrag(v, e->x(), e->y(), p)) return; - if (p.getFrame() != m_editingPoint.getFrame() || p.getValue() != m_editingPoint.getValue()) return; + if (p.getFrame() != m_editingPoint.getFrame() || + p.getValue() != m_editingPoint.getValue()) return; - m_editingCommand = new ChangeEventsCommand(m_model, tr("Erase Point")); + m_editingCommand = new ChangeEventsCommand(m_model, tr("Erase Point")); m_editingCommand->remove(m_editingPoint); finish(m_editingCommand); m_editingCommand = nullptr; @@ -1025,7 +1054,8 @@ // SVDEBUG << "FlexiNoteLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; std::cerr << "FlexiNoteLayer::editStart(" << e->x() << "," << e->y() << ")" << std::endl; - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; m_originalPoint = m_editingPoint; @@ -1056,7 +1086,7 @@ m_greatestLeftNeighbourFrame = -1; m_smallestRightNeighbourFrame = std::numeric_limits::max(); - EventVector allEvents = m_model->getAllEvents(); + EventVector allEvents = model->getAllEvents(); for (auto currentNote: allEvents) { @@ -1082,7 +1112,8 @@ // SVDEBUG << "FlexiNoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl; std::cerr << "FlexiNoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << std::endl; - if (!m_model || !m_editing) return; + auto model = ModelById::getAs(m_model); + if (!model || !m_editing) return; int xdist = e->x() - m_dragStartX; int ydist = e->y() - m_dragStartY; @@ -1091,12 +1122,13 @@ sv_frame_t dragFrame = v->getFrameForX(newx); if (dragFrame < 0) dragFrame = 0; - dragFrame = dragFrame / m_model->getResolution() * m_model->getResolution(); + dragFrame = dragFrame / model->getResolution() * model->getResolution(); double value = getValueForY(v, newy); if (!m_editingCommand) { - m_editingCommand = new ChangeEventsCommand(m_model, tr("Drag Point")); + m_editingCommand = + new ChangeEventsCommand(m_model, tr("Drag Point")); } m_editingCommand->remove(m_editingPoint); @@ -1182,7 +1214,8 @@ std::cerr << "FlexiNoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << std::endl; - if (!m_model || !m_editing) return; + auto model = ModelById::getAs(m_model); + if (!model || !m_editing) return; if (m_editingCommand) { @@ -1218,9 +1251,11 @@ void FlexiNoteLayer::splitStart(LayerGeometryProvider *v, QMouseEvent *e) { + auto model = ModelById::getAs(m_model); + if (!model) return; + // GF: note splitting starts (!! remove printing soon) std::cerr << "splitStart (n.b. editStart will be called later, if the user drags the mouse)" << std::endl; - if (!m_model) return; if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; // m_originalPoint = m_editingPoint; @@ -1241,9 +1276,10 @@ void FlexiNoteLayer::splitEnd(LayerGeometryProvider *v, QMouseEvent *e) { + auto model = ModelById::getAs(m_model); // GF: note splitting ends. (!! remove printing soon) std::cerr << "splitEnd" << std::endl; - if (!m_model || !m_editing || m_editMode != SplitNote) return; + if (!model || !m_editing || m_editMode != SplitNote) return; int xdist = e->x() - m_dragStartX; int ydist = e->y() - m_dragStartY; @@ -1266,13 +1302,15 @@ void FlexiNoteLayer::splitNotesAt(LayerGeometryProvider *v, sv_frame_t frame, QMouseEvent *e) { - EventVector onPoints = m_model->getEventsCovering(frame); + auto model = ModelById::getAs(m_model); + if (!model) return; + + EventVector onPoints = model->getEventsCovering(frame); if (onPoints.empty()) return; Event note(*onPoints.begin()); - ChangeEventsCommand *command = new ChangeEventsCommand - (m_model, tr("Edit Point")); + auto command = new ChangeEventsCommand(m_model, tr("Edit Point")); command->remove(note); if (!e || !(e->modifiers() & Qt::ShiftModifier)) { @@ -1306,15 +1344,16 @@ void FlexiNoteLayer::addNote(LayerGeometryProvider *v, QMouseEvent *e) { + auto model = ModelById::getAs(m_model); std::cerr << "addNote" << std::endl; - if (!m_model) return; + if (!model) return; sv_frame_t duration = 10000; sv_frame_t frame = v->getFrameForX(e->x()); double value = getValueForY(v, e->y()); - EventVector noteList = m_model->getAllEvents(); + EventVector noteList = model->getAllEvents(); if (m_intelligentActions) { sv_frame_t smallestRightNeighbourFrame = 0; @@ -1333,16 +1372,15 @@ } if (!m_intelligentActions || - (m_model->getEventsCovering(frame).empty() && duration > 0)) { + (model->getEventsCovering(frame).empty() && duration > 0)) { Event newNote(frame, float(value), duration, 100.f, tr("new note")); - ChangeEventsCommand *command = new ChangeEventsCommand - (m_model, tr("Add Point")); + auto command = new ChangeEventsCommand(m_model, tr("Add Point")); command->add(newNote); finish(command); } } -SparseTimeValueModel * +ModelId FlexiNoteLayer::getAssociatedPitchModel(LayerGeometryProvider *v) const { // Better than we used to do, but still not very satisfactory @@ -1354,29 +1392,28 @@ if (layer && layer->getLayerPresentationName() != "candidate") { // cerr << "FlexiNoteLayer::getAssociatedPitchModel: looks like our layer is " << layer << endl; - SparseTimeValueModel *model = qobject_cast - (layer->getModel()); -// cerr << "FlexiNoteLayer::getAssociatedPitchModel: and its model is " << model << endl; + auto modelId = layer->getModel(); + auto model = ModelById::getAs(modelId); if (model && model->getScaleUnits() == "Hz") { - cerr << "FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl; - return model; +// cerr << "FlexiNoteLayer::getAssociatedPitchModel: it's good, returning " << model << endl; + return modelId; } } } - cerr << "FlexiNoteLayer::getAssociatedPitchModel: failed to find a model" << endl; - return nullptr; +// cerr << "FlexiNoteLayer::getAssociatedPitchModel: failed to find a model" << endl; + return {}; } void FlexiNoteLayer::snapSelectedNotesToPitchTrack(LayerGeometryProvider *v, Selection s) { - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; EventVector points = - m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); + model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); - ChangeEventsCommand *command = new ChangeEventsCommand - (m_model, tr("Snap Notes")); + auto command = new ChangeEventsCommand(m_model, tr("Snap Notes")); cerr << "snapSelectedNotesToPitchTrack: selection is from " << s.getStartFrame() << " to " << s.getEndFrame() << endl; @@ -1408,18 +1445,20 @@ void FlexiNoteLayer::mergeNotes(LayerGeometryProvider *v, Selection s, bool inclusive) { + auto model = ModelById::getAs(m_model); + if (!model) return; + EventVector points; if (inclusive) { - points = m_model->getEventsSpanning(s.getStartFrame(), s.getDuration()); + points = model->getEventsSpanning(s.getStartFrame(), s.getDuration()); } else { - points = m_model->getEventsWithin(s.getStartFrame(), s.getDuration()); + points = model->getEventsWithin(s.getStartFrame(), s.getDuration()); } EventVector::iterator i = points.begin(); if (i == points.end()) return; - ChangeEventsCommand *command = - new ChangeEventsCommand(m_model, tr("Merge Notes")); + auto command = new ChangeEventsCommand(m_model, tr("Merge Notes")); Event newNote(*i); @@ -1446,7 +1485,8 @@ bool FlexiNoteLayer::updateNoteValueFromPitchCurve(LayerGeometryProvider *v, Event ¬e) const { - SparseTimeValueModel *model = getAssociatedPitchModel(v); + ModelId modelId = getAssociatedPitchModel(v); + auto model = ModelById::getAs(modelId); if (!model) return false; std::cerr << model->getTypeName() << std::endl; @@ -1525,8 +1565,7 @@ void FlexiNoteLayer::getRelativeMousePosition(LayerGeometryProvider *v, Event ¬e, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const { - // GF: TODO: consoloidate the tolerance values - if (!m_model) return; + // GF: TODO: consolidate the tolerance values int ctol = 0; int noteStartX = v->getXForFrame(note.getFrame()); @@ -1555,7 +1594,8 @@ FlexiNoteLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e) { std::cerr << "Opening note editor dialog" << std::endl; - if (!m_model) return false; + auto model = ModelById::getAs(m_model); + if (!model) return false; Event note(0); if (!getPointToDrag(v, e->x(), e->y(), note)) return false; @@ -1563,7 +1603,7 @@ // Event note = *points.begin(); ItemEditDialog *dialog = new ItemEditDialog - (m_model->getSampleRate(), + (model->getSampleRate(), ItemEditDialog::ShowTime | ItemEditDialog::ShowDuration | ItemEditDialog::ShowValue | @@ -1583,8 +1623,7 @@ .withDuration(dialog->getFrameDuration()) .withLabel(dialog->getText()); - ChangeEventsCommand *command = new ChangeEventsCommand - (m_model, tr("Edit Point")); + auto command = new ChangeEventsCommand(m_model, tr("Edit Point")); command->remove(note); command->add(newNote); finish(command); @@ -1597,13 +1636,13 @@ void FlexiNoteLayer::moveSelection(Selection s, sv_frame_t newStartFrame) { - if (!m_model) return; - - ChangeEventsCommand *command = - new ChangeEventsCommand(m_model, tr("Drag Selection")); + auto model = ModelById::getAs(m_model); + if (!model) return; + + auto command = new ChangeEventsCommand(m_model, tr("Drag Selection")); EventVector points = - m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); + model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); for (Event p: points) { command->remove(p); @@ -1618,13 +1657,13 @@ void FlexiNoteLayer::resizeSelection(Selection s, Selection newSize) { - if (!m_model || !s.getDuration()) return; + auto model = ModelById::getAs(m_model); + if (!model || !s.getDuration()) return; - ChangeEventsCommand *command = - new ChangeEventsCommand(m_model, tr("Resize Selection")); + auto command = new ChangeEventsCommand(m_model, tr("Resize Selection")); EventVector points = - m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); + model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); double ratio = double(newSize.getDuration()) / double(s.getDuration()); double oldStart = double(s.getStartFrame()); @@ -1648,13 +1687,14 @@ void FlexiNoteLayer::deleteSelection(Selection s) { - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; - ChangeEventsCommand *command = - new ChangeEventsCommand(m_model, tr("Delete Selected Points")); + auto command = + new ChangeEventsCommand(m_model, tr("Delete Selected Points")); EventVector points = - m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); + model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); for (Event p: points) { command->remove(p); @@ -1666,13 +1706,14 @@ void FlexiNoteLayer::deleteSelectionInclusive(Selection s) { - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; - ChangeEventsCommand *command = - new ChangeEventsCommand(m_model, tr("Delete Selected Points")); + auto command = + new ChangeEventsCommand(m_model, tr("Delete Selected Points")); EventVector points = - m_model->getEventsSpanning(s.getStartFrame(), s.getDuration()); + model->getEventsSpanning(s.getStartFrame(), s.getDuration()); for (Event p: points) { command->remove(p); @@ -1684,10 +1725,11 @@ void FlexiNoteLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) { - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; EventVector points = - m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); + model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); for (Event p: points) { to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame()))); @@ -1697,7 +1739,8 @@ bool FlexiNoteLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /*frameOffset */, bool /* interactive */) { - if (!m_model) return false; + auto model = ModelById::getAs(m_model); + if (!model) return false; const EventVector &points = from.getPoints(); @@ -1720,8 +1763,7 @@ } } - ChangeEventsCommand *command = - new ChangeEventsCommand(m_model, tr("Paste")); + auto command = new ChangeEventsCommand(m_model, tr("Paste")); for (EventVector::const_iterator i = points.begin(); i != points.end(); ++i) { @@ -1745,8 +1787,8 @@ Event p = *i; Event newPoint = p; if (!p.hasValue()) { - newPoint = newPoint.withValue((m_model->getValueMinimum() + - m_model->getValueMaximum()) / 2); + newPoint = newPoint.withValue((model->getValueMinimum() + + model->getValueMaximum()) / 2); } if (!p.hasDuration()) { sv_frame_t nextFrame = frame; @@ -1758,7 +1800,7 @@ nextFrame = j->getFrame(); } if (nextFrame == frame) { - newPoint = newPoint.withDuration(m_model->getResolution()); + newPoint = newPoint.withDuration(model->getResolution()); } else { newPoint = newPoint.withDuration(nextFrame - frame); } @@ -1789,13 +1831,11 @@ if (lrintf(p.getValue()) == pitch) { m_pendingNoteOns.erase(i); Event note = p.withDuration(frame - p.getFrame()); - if (m_model) { - ChangeEventsCommand *c = new ChangeEventsCommand - (m_model, tr("Record Note")); - c->add(note); - // execute and bundle: - CommandHistory::getInstance()->addCommand(c, true, true); - } + auto c = new ChangeEventsCommand + (m_model, tr("Record Note")); + c->add(note); + // execute and bundle: + CommandHistory::getInstance()->addCommand(c, true, true); break; } } @@ -1840,10 +1880,13 @@ void FlexiNoteLayer::setVerticalRangeToNoteRange(LayerGeometryProvider *v) { + auto model = ModelById::getAs(m_model); + if (!model) return; + double minf = std::numeric_limits::max(); double maxf = 0; bool hasNotes = 0; - EventVector allPoints = m_model->getAllEvents(); + EventVector allPoints = model->getAllEvents(); for (EventVector::const_iterator i = allPoints.begin(); i != allPoints.end(); ++i) { hasNotes = 1; diff -r de41a11cabc2 -r 11a150e65ee1 layer/FlexiNoteLayer.h --- a/layer/FlexiNoteLayer.h Thu Jun 13 15:35:01 2019 +0100 +++ b/layer/FlexiNoteLayer.h Thu Jun 27 13:16:25 2019 +0100 @@ -81,8 +81,8 @@ void snapSelectedNotesToPitchTrack(LayerGeometryProvider *v, Selection s); void mergeNotes(LayerGeometryProvider *v, Selection s, bool inclusive); - const Model *getModel() const override { return m_model; } - void setModel(NoteModel *model); + ModelId getModel() const override { return m_model; } + void setModel(ModelId model); // a NoteModel please PropertyList getProperties() const override; QString getPropertyLabel(const PropertyName &) const override; @@ -118,10 +118,10 @@ bool isLayerEditable() const override { return true; } - int getCompletion(LayerGeometryProvider *) const override { return m_model->getCompletion(); } + int getCompletion(LayerGeometryProvider *) const override; bool getValueExtents(double &min, double &max, - bool &log, QString &unit) const override; + bool &log, QString &unit) const override; bool getDisplayExtents(double &min, double &max) const override; bool setDisplayExtents(double min, double max) override; @@ -176,11 +176,11 @@ bool getPointToDrag(LayerGeometryProvider *v, int x, int y, Event &) const; bool getNoteToEdit(LayerGeometryProvider *v, int x, int y, Event &) const; void getRelativeMousePosition(LayerGeometryProvider *v, Event ¬e, int x, int y, bool &closeToLeft, bool &closeToRight, bool &closeToTop, bool &closeToBottom) const; - SparseTimeValueModel *getAssociatedPitchModel(LayerGeometryProvider *v) const; + ModelId getAssociatedPitchModel(LayerGeometryProvider *v) const; bool updateNoteValueFromPitchCurve(LayerGeometryProvider *v, Event ¬e) const; void splitNotesAt(LayerGeometryProvider *v, sv_frame_t frame, QMouseEvent *e); - NoteModel *m_model; + ModelId m_model; bool m_editing; bool m_intelligentActions; int m_dragPointX; @@ -191,7 +191,7 @@ Event m_editingPoint; sv_frame_t m_greatestLeftNeighbourFrame; sv_frame_t m_smallestRightNeighbourFrame; - ChangeEventsCommand *m_editingCommand; + ChangeEventsCommand *m_editingCommand; VerticalScale m_verticalScale; EditMode m_editMode; @@ -203,7 +203,7 @@ bool shouldAutoAlign() const; - void finish(ChangeEventsCommand *command) { + void finish(ChangeEventsCommand *command) { Command *c = command->finish(); if (c) CommandHistory::getInstance()->addCommand(c, false); } diff -r de41a11cabc2 -r 11a150e65ee1 layer/ImageLayer.cpp --- a/layer/ImageLayer.cpp Thu Jun 13 15:35:01 2019 +0100 +++ b/layer/ImageLayer.cpp Thu Jun 27 13:16:25 2019 +0100 @@ -43,8 +43,6 @@ ImageLayer::m_imageMapMutex; ImageLayer::ImageLayer() : - Layer(), - m_model(nullptr), m_editing(false), m_editingCommand(nullptr) { @@ -58,11 +56,23 @@ } } +int +ImageLayer::getCompletion(LayerGeometryProvider *) const +{ + auto model = ModelById::get(m_model); + if (model) return model->getCompletion(); + else return 0; +} + void -ImageLayer::setModel(ImageModel *model) +ImageLayer::setModel(ModelId modelId) { - if (m_model == model) return; - m_model = model; + if (m_model == modelId) return; + + auto model = ModelById::getAs(modelId); + if (!model) throw std::logic_error("Not an ImageModel"); + + m_model = modelId; connectSignals(m_model); @@ -122,10 +132,11 @@ EventVector ImageLayer::getLocalPoints(LayerGeometryProvider *v, int x, int ) const { - if (!m_model) return {}; + auto model = ModelById::getAs(m_model); + if (!model) return {}; // SVDEBUG << "ImageLayer::getLocalPoints(" << x << "," << y << "):"; - EventVector points(m_model->getAllEvents()); + EventVector points(model->getAllEvents()); EventVector rv; @@ -169,12 +180,13 @@ { int x = pos.x(); - if (!m_model || !m_model->getSampleRate()) return ""; + auto model = ModelById::getAs(m_model); + if (!model || !model->getSampleRate()) return ""; EventVector points = getLocalPoints(v, x, pos.y()); if (points.empty()) { - if (!m_model->isReady()) { + if (!model->isReady()) { return tr("In progress"); } else { return ""; @@ -183,7 +195,7 @@ // int useFrame = points.begin()->frame; -// RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate()); +// RealTime rt = RealTime::frame2RealTime(useFrame, model->getSampleRate()); QString text; /* @@ -208,11 +220,12 @@ int &resolution, SnapType snap) const { - if (!m_model) { + auto model = ModelById::getAs(m_model); + if (!model) { return Layer::snapToFeatureFrame(v, frame, resolution, snap); } - resolution = m_model->getResolution(); + resolution = model->getResolution(); if (snap == SnapNeighbouring) { EventVector points = getLocalPoints(v, v->getXForFrame(frame), -1); @@ -222,7 +235,7 @@ } Event e; - if (m_model->getNearestEventMatching + if (model->getNearestEventMatching (frame, [](Event) { return true; }, snap == SnapLeft ? EventSeries::Backward : EventSeries::Forward, @@ -237,9 +250,10 @@ void ImageLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const { - if (!m_model || !m_model->isOK()) return; + auto model = ModelById::getAs(m_model); + if (!model || !model->isOK()) return; - sv_samplerate_t sampleRate = m_model->getSampleRate(); + sv_samplerate_t sampleRate = model->getSampleRate(); if (!sampleRate) return; // Profiler profiler("ImageLayer::paint", true); @@ -250,7 +264,7 @@ sv_frame_t frame0 = v->getFrameForX(x0); sv_frame_t frame1 = v->getFrameForX(x1); - EventVector points(m_model->getEventsWithin(frame0, frame1 - frame0, 2)); + EventVector points(model->getEventsWithin(frame0, frame1 - frame0, 2)); if (points.empty()) return; paint.save(); @@ -513,20 +527,21 @@ { // SVDEBUG << "ImageLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; - if (!m_model) { + auto model = ModelById::getAs(m_model); + if (!model) { SVDEBUG << "ImageLayer::drawStart: no model" << endl; return; } sv_frame_t frame = v->getFrameForX(e->x()); if (frame < 0) frame = 0; - frame = frame / m_model->getResolution() * m_model->getResolution(); + frame = frame / model->getResolution() * model->getResolution(); m_editingPoint = Event(frame); m_originalPoint = m_editingPoint; if (m_editingCommand) finish(m_editingCommand); - m_editingCommand = new ChangeEventsCommand(m_model, "Add Image"); + m_editingCommand = new ChangeEventsCommand(m_model, "Add Image"); m_editingCommand->add(m_editingPoint); m_editing = true; @@ -537,11 +552,12 @@ { // SVDEBUG << "ImageLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; - if (!m_model || !m_editing) return; + auto model = ModelById::getAs(m_model); + if (!model || !m_editing) return; sv_frame_t frame = v->getFrameForX(e->x()); if (frame < 0) frame = 0; - frame = frame / m_model->getResolution() * m_model->getResolution(); + frame = frame / model->getResolution() * model->getResolution(); m_editingCommand->remove(m_editingPoint); m_editingPoint = m_editingPoint @@ -553,7 +569,8 @@ ImageLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *) { // SVDEBUG << "ImageLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl; - if (!m_model || !m_editing) return; + auto model = ModelById::getAs(m_model); + if (!model || !m_editing) return; ImageDialog dialog(tr("Select image"), "", ""); @@ -586,8 +603,8 @@ } Event point = Event(frame).withURI(url); - ChangeEventsCommand *command = - new ChangeEventsCommand(m_model, "Add Image"); + auto command = + new ChangeEventsCommand(m_model, "Add Image"); command->add(point); finish(command); return true; @@ -598,7 +615,8 @@ { // SVDEBUG << "ImageLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; EventVector points = getLocalPoints(v, e->x(), e->y()); if (points.empty()) return; @@ -618,16 +636,17 @@ void ImageLayer::editDrag(LayerGeometryProvider *v, QMouseEvent *e) { - if (!m_model || !m_editing) return; + auto model = ModelById::getAs(m_model); + if (!model || !m_editing) return; sv_frame_t frameDiff = v->getFrameForX(e->x()) - v->getFrameForX(m_editOrigin.x()); sv_frame_t frame = m_originalPoint.getFrame() + frameDiff; if (frame < 0) frame = 0; - frame = (frame / m_model->getResolution()) * m_model->getResolution(); + frame = (frame / model->getResolution()) * model->getResolution(); if (!m_editingCommand) { - m_editingCommand = new ChangeEventsCommand(m_model, tr("Move Image")); + m_editingCommand = new ChangeEventsCommand(m_model, tr("Move Image")); } m_editingCommand->remove(m_editingPoint); @@ -640,7 +659,8 @@ ImageLayer::editEnd(LayerGeometryProvider *, QMouseEvent *) { // SVDEBUG << "ImageLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl; - if (!m_model || !m_editing) return; + auto model = ModelById::getAs(m_model); + if (!model || !m_editing) return; if (m_editingCommand) { finish(m_editingCommand); @@ -653,7 +673,8 @@ bool ImageLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e) { - if (!m_model) return false; + auto model = ModelById::getAs(m_model); + if (!model) return false; EventVector points = getLocalPoints(v, e->x(), e->y()); if (points.empty()) return false; @@ -669,8 +690,8 @@ checkAddSource(dialog.getImage()); - ChangeEventsCommand *command = - new ChangeEventsCommand(m_model, tr("Edit Image")); + auto command = + new ChangeEventsCommand(m_model, tr("Edit Image")); command->remove(*points.begin()); command->add(points.begin()-> withURI(dialog.getImage()).withLabel(dialog.getLabel())); @@ -683,13 +704,14 @@ void ImageLayer::moveSelection(Selection s, sv_frame_t newStartFrame) { - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; - ChangeEventsCommand *command = - new ChangeEventsCommand(m_model, tr("Drag Selection")); + auto command = + new ChangeEventsCommand(m_model, tr("Drag Selection")); EventVector points = - m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); + model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); for (Event p: points) { command->remove(p); @@ -704,13 +726,14 @@ void ImageLayer::resizeSelection(Selection s, Selection newSize) { - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; - ChangeEventsCommand *command = - new ChangeEventsCommand(m_model, tr("Resize Selection")); + auto command = + new ChangeEventsCommand(m_model, tr("Resize Selection")); EventVector points = - m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); + model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); double ratio = double(newSize.getDuration()) / double(s.getDuration()); double oldStart = double(s.getStartFrame()); @@ -732,13 +755,14 @@ void ImageLayer::deleteSelection(Selection s) { - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; - ChangeEventsCommand *command = - new ChangeEventsCommand(m_model, tr("Delete Selection")); + auto command = + new ChangeEventsCommand(m_model, tr("Delete Selection")); EventVector points = - m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); + model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); for (Event p: points) { command->remove(p); @@ -750,10 +774,11 @@ void ImageLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) { - if (!m_model) return; + auto model = ModelById::getAs(m_model); + if (!model) return; EventVector points = - m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); + model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); for (Event p: points) { to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame()))); @@ -763,7 +788,8 @@ bool ImageLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /* frameOffset */, bool /* interactive */) { - if (!m_model) return false; + auto model = ModelById::getAs(m_model); + if (!model) return false; const EventVector &points = from.getPoints(); @@ -786,8 +812,7 @@ } } - ChangeEventsCommand *command = - new ChangeEventsCommand(m_model, tr("Paste")); + auto command = new ChangeEventsCommand(m_model, tr("Paste")); for (EventVector::const_iterator i = points.begin(); i != points.end(); ++i) { @@ -863,7 +888,8 @@ void ImageLayer::checkAddSources() { - const EventVector &points(m_model->getAllEvents()); + auto model = ModelById::getAs(m_model); + const EventVector &points(model->getAllEvents()); for (EventVector::const_iterator i = points.begin(); i != points.end(); ++i) { diff -r de41a11cabc2 -r 11a150e65ee1 layer/ImageLayer.h --- a/layer/ImageLayer.h Thu Jun 13 15:35:01 2019 +0100 +++ b/layer/ImageLayer.h Thu Jun 27 13:16:25 2019 +0100 @@ -43,8 +43,8 @@ QString getFeatureDescription(LayerGeometryProvider *v, QPoint &) const override; bool snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, - int &resolution, - SnapType snap) const override; + int &resolution, + SnapType snap) const override; void drawStart(LayerGeometryProvider *v, QMouseEvent *) override; void drawDrag(LayerGeometryProvider *v, QMouseEvent *) override; @@ -64,16 +64,16 @@ bool editOpen(LayerGeometryProvider *, QMouseEvent *) override; // on double-click - const Model *getModel() const override { return m_model; } - void setModel(ImageModel *model); + ModelId getModel() const override { return m_model; } + void setModel(ModelId model); // an ImageModel please PropertyList getProperties() const override; QString getPropertyLabel(const PropertyName &) const override; PropertyType getPropertyType(const PropertyName &) const override; int getPropertyRangeAndValue(const PropertyName &, - int *min, int *max, int *deflt) const override; + int *min, int *max, int *deflt) const override; QString getPropertyValueLabel(const PropertyName &, - int value) const override; + int value) const override; void setProperty(const PropertyName &, int value) override; ColourSignificance getLayerColourSignificance() const override { @@ -84,13 +84,13 @@ bool isLayerEditable() const override { return true; } - int getCompletion(LayerGeometryProvider *) const override { return m_model->getCompletion(); } + int getCompletion(LayerGeometryProvider *) const override; bool getValueExtents(double &min, double &max, - bool &logarithmic, QString &unit) const override; + bool &logarithmic, QString &unit) const override; void toXml(QTextStream &stream, QString indent = "", - QString extraAttributes = "") const override; + QString extraAttributes = "") const override; int getVerticalScaleWidth(LayerGeometryProvider *, bool, QPainter &) const override { return 0; } @@ -127,14 +127,14 @@ QString getLocalFilename(QString img) const; void checkAddSource(QString img) const; - ImageModel *m_model; + ModelId m_model; // an ImageModel bool m_editing; QPoint m_editOrigin; Event m_originalPoint; Event m_editingPoint; - ChangeEventsCommand *m_editingCommand; + ChangeEventsCommand *m_editingCommand; - void finish(ChangeEventsCommand *command) { + void finish(ChangeEventsCommand *command) { Command *c = command->finish(); if (c) CommandHistory::getInstance()->addCommand(c, false); } diff -r de41a11cabc2 -r 11a150e65ee1 layer/Layer.cpp --- a/layer/Layer.cpp Thu Jun 13 15:35:01 2019 +0100 +++ b/layer/Layer.cpp Thu Jun 27 13:16:25 2019 +0100 @@ -46,18 +46,21 @@ } void -Layer::connectSignals(const Model *model) +Layer::connectSignals(ModelId modelId) { - connect(model, SIGNAL(modelChanged()), + auto model = ModelById::get(modelId); + if (!model) return; + + connect(model.get(), SIGNAL(modelChanged()), this, SIGNAL(modelChanged())); - connect(model, SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)), + connect(model.get(), SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)), this, SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t))); - connect(model, SIGNAL(completionChanged()), + connect(model.get(), SIGNAL(completionChanged()), this, SIGNAL(modelCompletionChanged())); - connect(model, SIGNAL(alignmentCompletionChanged()), + connect(model.get(), SIGNAL(alignmentCompletionChanged()), this, SIGNAL(modelAlignmentCompletionChanged())); } @@ -84,7 +87,8 @@ (factory->getLayerType(this)); QString modelName; - if (getModel()) modelName = getModel()->objectName(); + auto model = ModelById::get(getModel()); + if (model) modelName = model->objectName(); QString text; if (modelName != "") { @@ -107,7 +111,7 @@ Layer::getPlayParameters() { // cerr << "Layer (" << this << ", " << objectName() << ")::getPlayParameters: model is "<< getModel() << endl; - const Model *model = getModel(); + auto model = ModelById::get(getModel()); if (model) { return PlayParameterRepository::getInstance()->getPlayParameters(model); } @@ -143,10 +147,10 @@ { if (!hasTimeXAxis()) return false; - const Model *m = getModel(); - if (!m) return false; + auto model = ModelById::get(getModel()); + if (!model) return false; - value = double(v->getFrameForX(x)) / m->getSampleRate(); + value = double(v->getFrameForX(x)) / model->getSampleRate(); unit = "s"; return true; } @@ -168,10 +172,9 @@ sv_frame_t Layer::alignToReference(LayerGeometryProvider *v, sv_frame_t frame) const { - const Model *m = getModel(); - SVDEBUG << "Layer::alignToReference(" << frame << "): model = " << m << ", alignment reference = " << (m ? m->getAlignmentReference() : nullptr) << endl; - if (m && m->getAlignmentReference()) { - return m->alignToReference(frame); + auto model = ModelById::get(getModel()); + if (model && !model->getAlignmentReference().isNone()) { + return model->alignToReference(frame); } else { return v->getView()->alignToReference(frame); } @@ -180,10 +183,9 @@ sv_frame_t Layer::alignFromReference(LayerGeometryProvider *v, sv_frame_t frame) const { - const Model *m = getModel(); - SVDEBUG << "Layer::alignFromReference(" << frame << "): model = " << m << ", alignment reference = " << (m ? m->getAlignmentReference() : nullptr) << endl; - if (m && m->getAlignmentReference()) { - return m->alignFromReference(frame); + auto model = ModelById::get(getModel()); + if (model && !model->getAlignmentReference().isNone()) { + return model->alignFromReference(frame); } else { return v->getView()->alignFromReference(frame); } @@ -644,12 +646,16 @@ .arg(extraAttributes).arg(encodeEntities(m_presentationName)); } + int modelExportId = -1; + auto model = ModelById::get(getModel()); + if (model) modelExportId = model->getExportId(); + stream << QString("getLayerTypeName (LayerFactory::getInstance()->getLayerType(this)))) .arg(getExportId()) .arg(encodeEntities(objectName())) - .arg(getModel() ? getModel()->getExportId() : -1) + .arg(modelExportId) .arg(extraAttributes); if (m_measureRects.empty()) { @@ -678,12 +684,16 @@ .arg(extraAttributes).arg(encodeEntities(m_presentationName)); } + int modelExportId = -1; + auto model = ModelById::get(getModel()); + if (model) modelExportId = model->getExportId(); + stream << QString("\n") .arg(encodeEntities(LayerFactory::getInstance()->getLayerTypeName (LayerFactory::getInstance()->getLayerType(this)))) .arg(getExportId()) .arg(encodeEntities(objectName())) - .arg(getModel() ? getModel()->getExportId() : -1) + .arg(modelExportId) .arg(extraAttributes); } diff -r de41a11cabc2 -r 11a150e65ee1 layer/Layer.h --- a/layer/Layer.h Thu Jun 13 15:35:01 2019 +0100 +++ b/layer/Layer.h Thu Jun 27 13:16:25 2019 +0100 @@ -20,6 +20,8 @@ #include "base/XmlExportable.h" #include "base/Selection.h" +#include "data/model/Model.h" + #include "widgets/CommandHistory.h" #include "system/System.h" @@ -36,7 +38,6 @@ #include class ZoomConstraint; -class Model; class QPainter; class View; class LayerGeometryProvider; @@ -59,10 +60,10 @@ Layer(); virtual ~Layer(); - virtual const Model *getModel() const = 0; - Model *getModel() { - return const_cast(const_cast(this)->getModel()); - } + /** + * Return the ID of the model represented in this layer. + */ + virtual ModelId getModel() const = 0; /** * Return a zoom constraint object defining the supported zoom @@ -570,7 +571,7 @@ void verticalZoomChanged(); protected: - void connectSignals(const Model *); + void connectSignals(ModelId); virtual sv_frame_t alignToReference(LayerGeometryProvider *v, sv_frame_t frame) const; virtual sv_frame_t alignFromReference(LayerGeometryProvider *v, sv_frame_t frame) const; diff -r de41a11cabc2 -r 11a150e65ee1 layer/SliceableLayer.h --- a/layer/SliceableLayer.h Thu Jun 13 15:35:01 2019 +0100 +++ b/layer/SliceableLayer.h Thu Jun 27 13:16:25 2019 +0100 @@ -34,14 +34,15 @@ // spectrogram that was constructed from a DenseTimeValueModel). // The SliceableLayer retains ownership of the model, and will // emit sliceableModelReplaced if it is about to become invalid. - virtual const Model *getSliceableModel() const = 0; - + virtual ModelId getSliceableModel() const = 0; +/*!!! signals: // Emitted when a model that was obtained through // getSliceableModel is about to be deleted. If replacement is // non-NULL, it may be used instead. void sliceableModelReplaced(const Model *modelToBeReplaced, const Model *replacement); +*/ }; #endif