diff layer/NoteLayer.cpp @ 1486:ac0a8addabcf

Merge from branch by-id
author Chris Cannam
date Wed, 17 Jul 2019 14:25:16 +0100
parents e540aa5d89cd
children 0fa49a6ce64f
line wrap: on
line diff
--- a/layer/NoteLayer.cpp	Thu Jun 13 15:35:01 2019 +0100
+++ b/layer/NoteLayer.cpp	Wed Jul 17 14:25:16 2019 +0100
@@ -48,7 +48,6 @@
 
 NoteLayer::NoteLayer() :
     SingleColourLayer(),
-    m_model(nullptr),
     m_editing(false),
     m_dragPointX(0),
     m_dragPointY(0),
@@ -65,16 +64,30 @@
     SVDEBUG << "constructed NoteLayer" << endl;
 }
 
+int
+NoteLayer::getCompletion(LayerGeometryProvider *) const
+{
+    auto model = ModelById::get(m_model);
+    if (model) return model->getCompletion();
+    else return 0;
+}
+
 void
-NoteLayer::setModel(NoteModel *model)
-{        
-    if (m_model == model) return;
-    m_model = model;
+NoteLayer::setModel(ModelId modelId)
+{
+    auto newModel = ModelById::getAs<NoteModel>(modelId);
+    
+    if (!modelId.isNone() && !newModel) {
+        throw std::logic_error("Not a NoteModel");
+    }
+    
+    if (m_model == modelId) return;
+    m_model = modelId;
 
-    connectSignals(m_model);
-
-//    SVDEBUG << "NoteLayer::setModel(" << model << ")" << endl;
-
+    if (newModel) {
+        connectSignals(m_model);
+    }
+    
     m_scaleMinimum = 0;
     m_scaleMaximum = 0;
 
@@ -118,7 +131,8 @@
 QString
 NoteLayer::getScaleUnits() const
 {
-    if (m_model) return m_model->getScaleUnits();
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (model) return model->getScaleUnits();
     else return "";
 }
 
@@ -139,9 +153,10 @@
     } else if (name == "Scale Units") {
 
         if (deflt) *deflt = 0;
-        if (m_model) {
+        auto model = ModelById::getAs<NoteModel>(m_model);
+        if (model) {
             val = UnitDatabase::getInstance()->getUnitId
-                (getScaleUnits());
+                (model->getScaleUnits());
         }
 
     } else {
@@ -174,10 +189,11 @@
     if (name == "Vertical Scale") {
         setVerticalScale(VerticalScale(value));
     } else if (name == "Scale Units") {
-        if (m_model) {
-            m_model->setScaleUnits
+        auto model = ModelById::getAs<NoteModel>(m_model);
+        if (model) {
+            model->setScaleUnits
                 (UnitDatabase::getInstance()->getUnitById(value));
-            emit modelChanged();
+            emit modelChanged(m_model);
         }
     } else {
         return SingleColourLayer::setProperty(name, value);
@@ -214,9 +230,10 @@
 NoteLayer::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<NoteModel>(m_model);
+    if (!model) return false;
+    min = model->getValueMinimum();
+    max = model->getValueMaximum();
 
     if (shouldConvertMIDIToHz()) {
         unit = "Hz";
@@ -225,7 +242,9 @@
     } else unit = getScaleUnits();
 
     if (m_verticalScale == MIDIRangeScale ||
-        m_verticalScale == LogScale) logarithmic = true;
+        m_verticalScale == LogScale) {
+        logarithmic = true;
+    }
 
     return true;
 }
@@ -233,7 +252,8 @@
 bool
 NoteLayer::getDisplayExtents(double &min, double &max) const
 {
-    if (!m_model || shouldAutoAlign()) return false;
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model || shouldAutoAlign()) return false;
 
     if (m_verticalScale == MIDIRangeScale) {
         min = Pitch::getFrequencyForPitch(0);
@@ -242,8 +262,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;
@@ -264,7 +284,7 @@
 bool
 NoteLayer::setDisplayExtents(double min, double max)
 {
-    if (!m_model) return false;
+    if (m_model.isNone()) return false;
 
     if (min == max) {
         if (min == 0.f) {
@@ -288,9 +308,7 @@
 int
 NoteLayer::getVerticalZoomSteps(int &defaultStep) const
 {
-    if (shouldAutoAlign()) return 0;
-    if (!m_model) return 0;
-
+    if (shouldAutoAlign() || m_model.isNone()) return 0;
     defaultStep = 0;
     return 100;
 }
@@ -298,8 +316,7 @@
 int
 NoteLayer::getCurrentVerticalZoomStep() const
 {
-    if (shouldAutoAlign()) return 0;
-    if (!m_model) return 0;
+    if (shouldAutoAlign() || m_model.isNone()) return 0;
 
     RangeMapper *mapper = getNewVerticalZoomRangeMapper();
     if (!mapper) return 0;
@@ -319,8 +336,7 @@
 void
 NoteLayer::setVerticalZoomStep(int step)
 {
-    if (shouldAutoAlign()) return;
-    if (!m_model) return;
+    if (shouldAutoAlign() || m_model.isNone()) return;
 
     RangeMapper *mapper = getNewVerticalZoomRangeMapper();
     if (!mapper) return;
@@ -370,7 +386,7 @@
 RangeMapper *
 NoteLayer::getNewVerticalZoomRangeMapper() const
 {
-    if (!m_model) return nullptr;
+    if (m_model.isNone()) return nullptr;
     
     RangeMapper *mapper;
 
@@ -393,21 +409,22 @@
 EventVector
 NoteLayer::getLocalPoints(LayerGeometryProvider *v, int x) const
 {
-    if (!m_model) return {};
+    auto model = ModelById::getAs<NoteModel>(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 {};
@@ -416,11 +433,12 @@
 bool
 NoteLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, Event &point) const
 {
-    if (!m_model) return false;
+    auto model = ModelById::getAs<NoteModel>(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;
@@ -441,12 +459,13 @@
 {
     int x = pos.x();
 
-    if (!m_model || !m_model->getSampleRate()) return "";
+    auto model = ModelById::getAs<NoteModel>(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");
@@ -461,9 +480,9 @@
         int y = getYForValue(v, i->getValue());
         int h = 3;
 
-        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 < 3) h = 3;
         }
 
@@ -476,9 +495,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;
 
@@ -530,7 +549,8 @@
                               int &resolution,
                               SnapType snap) const
 {
-    if (!m_model) {
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model) {
         return Layer::snapToFeatureFrame(v, frame, resolution, snap);
     }
 
@@ -541,7 +561,7 @@
     // an editing operation, i.e. closest feature in either direction
     // but only if it is "close enough"
 
-    resolution = m_model->getResolution();
+    resolution = model->getResolution();
 
     if (snap == SnapNeighbouring) {
         EventVector points = getLocalPoints(v, v->getXForFrame(frame));
@@ -551,7 +571,7 @@
     }    
 
     Event e;
-    if (m_model->getNearestEventMatching
+    if (model->getNearestEventMatching
         (frame,
          [](Event) { return true; },
          snap == SnapLeft ? EventSeries::Backward : EventSeries::Forward,
@@ -570,6 +590,9 @@
     max = 0.0;
     log = false;
 
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model) return;
+    
     QString queryUnits;
     if (shouldConvertMIDIToHz()) queryUnits = "Hz";
     else queryUnits = getScaleUnits();
@@ -578,8 +601,8 @@
 
         if (!v->getValueExtents(queryUnits, min, max, log)) {
 
-            min = m_model->getValueMinimum();
-            max = m_model->getValueMaximum();
+            min = model->getValueMinimum();
+            max = model->getValueMaximum();
 
             if (shouldConvertMIDIToHz()) {
                 min = Pitch::getFrequencyForPitch(int(lrint(min)));
@@ -681,16 +704,17 @@
 bool
 NoteLayer::shouldAutoAlign() const
 {
-    if (!m_model) return false;
+    if (m_model.isNone()) return false;
     return (m_verticalScale == AutoAlignScale);
 }
 
 void
 NoteLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const
 {
-    if (!m_model || !m_model->isOK()) return;
+    auto model = ModelById::getAs<NoteModel>(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("NoteLayer::paint", true);
@@ -699,7 +723,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());
@@ -708,10 +732,10 @@
     brushColour.setAlpha(80);
 
 //    SVDEBUG << "NoteLayer::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;
@@ -739,8 +763,8 @@
         int w = v->getXForFrame(p.getFrame() + p.getDuration()) - x;
         int h = 3;
         
-        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 < 3) h = 3;
         }
 
@@ -753,6 +777,11 @@
             paint.setPen(v->getForeground());
             paint.setBrush(v->getForeground());
 
+    // Qt 5.13 deprecates QFontMetrics::width(), but its suggested
+    // replacement (horizontalAdvance) was only added in Qt 5.11
+    // which is too new for us
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+
             QString vlabel = QString("%1%2").arg(p.getValue()).arg(getScaleUnits());
             PaintAssistant::drawVisibleText(v, paint, 
                                x - paint.fontMetrics().width(vlabel) - 2,
@@ -761,7 +790,7 @@
                                vlabel, PaintAssistant::OutlinedText);
 
             QString hlabel = RealTime::frame2RealTime
-                (p.getFrame(), m_model->getSampleRate()).toText(true).c_str();
+                (p.getFrame(), model->getSampleRate()).toText(true).c_str();
             PaintAssistant::drawVisibleText(v, paint, 
                                x,
                                y - h/2 - paint.fontMetrics().descent() - 2,
@@ -777,7 +806,7 @@
 int
 NoteLayer::getVerticalScaleWidth(LayerGeometryProvider *v, bool, QPainter &paint) const
 {
-    if (!m_model) {
+    if (m_model.isNone()) {
         return 0;
     }
 
@@ -795,7 +824,8 @@
 void
 NoteLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const
 {
-    if (!m_model || m_model->isEmpty()) return;
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model || model->isEmpty()) return;
 
     QString unit;
     double min, max;
@@ -835,11 +865,12 @@
 {
 //    SVDEBUG << "NoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl;
 
-    if (!m_model) return;
+    auto model = ModelById::getAs<NoteModel>(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());
 
@@ -847,7 +878,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.untyped, tr("Draw Point"));
     m_editingCommand->add(m_editingPoint);
 
     m_editing = true;
@@ -858,11 +889,12 @@
 {
 //    SVDEBUG << "NoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl;
 
-    if (!m_model || !m_editing) return;
+    auto model = ModelById::getAs<NoteModel>(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());
 
@@ -887,7 +919,8 @@
 NoteLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *)
 {
 //    SVDEBUG << "NoteLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl;
-    if (!m_model || !m_editing) return;
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model || !m_editing) return;
     finish(m_editingCommand);
     m_editingCommand = nullptr;
     m_editing = false;
@@ -896,7 +929,8 @@
 void
 NoteLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e)
 {
-    if (!m_model) return;
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model) return;
 
     if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
 
@@ -916,7 +950,8 @@
 void
 NoteLayer::eraseEnd(LayerGeometryProvider *v, QMouseEvent *e)
 {
-    if (!m_model || !m_editing) return;
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model || !m_editing) return;
 
     m_editing = false;
 
@@ -925,7 +960,7 @@
     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.untyped, tr("Erase Point"));
 
     m_editingCommand->remove(m_editingPoint);
 
@@ -939,7 +974,8 @@
 {
 //    SVDEBUG << "NoteLayer::editStart(" << e->x() << "," << e->y() << ")" << endl;
 
-    if (!m_model) return;
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model) return;
 
     if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
     m_originalPoint = m_editingPoint;
@@ -962,7 +998,8 @@
 {
 //    SVDEBUG << "NoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl;
 
-    if (!m_model || !m_editing) return;
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model || !m_editing) return;
 
     int xdist = e->x() - m_dragStartX;
     int ydist = e->y() - m_dragStartY;
@@ -971,13 +1008,13 @@
 
     sv_frame_t frame = v->getFrameForX(newx);
     if (frame < 0) frame = 0;
-    frame = frame / m_model->getResolution() * m_model->getResolution();
+    frame = frame / 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.untyped, tr("Drag Point"));
     }
 
     m_editingCommand->remove(m_editingPoint);
@@ -991,7 +1028,8 @@
 NoteLayer::editEnd(LayerGeometryProvider *, QMouseEvent *)
 {
 //    SVDEBUG << "NoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl;
-    if (!m_model || !m_editing) return;
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model || !m_editing) return;
 
     if (m_editingCommand) {
 
@@ -1018,7 +1056,8 @@
 bool
 NoteLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e)
 {
-    if (!m_model) return false;
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model) return false;
 
     Event note(0);
     if (!getPointToDrag(v, e->x(), e->y(), note)) return false;
@@ -1026,7 +1065,7 @@
 //    Event note = *points.begin();
 
     ItemEditDialog *dialog = new ItemEditDialog
-        (m_model->getSampleRate(),
+        (model->getSampleRate(),
          ItemEditDialog::ShowTime |
          ItemEditDialog::ShowDuration |
          ItemEditDialog::ShowValue |
@@ -1050,7 +1089,7 @@
             .withLabel(dialog->getText());
         
         ChangeEventsCommand *command = new ChangeEventsCommand
-            (m_model, tr("Edit Point"));
+            (m_model.untyped, tr("Edit Point"));
         command->remove(note);
         command->add(newNote);
         finish(command);
@@ -1066,13 +1105,14 @@
 void
 NoteLayer::moveSelection(Selection s, sv_frame_t newStartFrame)
 {
-    if (!m_model) return;
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model) return;
 
     ChangeEventsCommand *command =
-        new ChangeEventsCommand(m_model, tr("Drag Selection"));
+        new ChangeEventsCommand(m_model.untyped, 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);
@@ -1087,13 +1127,14 @@
 void
 NoteLayer::resizeSelection(Selection s, Selection newSize)
 {
-    if (!m_model || !s.getDuration()) return;
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model || !s.getDuration()) return;
 
     ChangeEventsCommand *command =
-        new ChangeEventsCommand(m_model, tr("Resize Selection"));
+        new ChangeEventsCommand(m_model.untyped, 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());
@@ -1117,13 +1158,14 @@
 void
 NoteLayer::deleteSelection(Selection s)
 {
-    if (!m_model) return;
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model) return;
 
     ChangeEventsCommand *command =
-        new ChangeEventsCommand(m_model, tr("Delete Selected Points"));
+        new ChangeEventsCommand(m_model.untyped, 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);
@@ -1135,10 +1177,11 @@
 void
 NoteLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to)
 {
-    if (!m_model) return;
+    auto model = ModelById::getAs<NoteModel>(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())));
@@ -1149,7 +1192,8 @@
 NoteLayer::paste(LayerGeometryProvider *v, const Clipboard &from,
                  sv_frame_t /* frameOffset */, bool /* interactive */)
 {
-    if (!m_model) return false;
+    auto model = ModelById::getAs<NoteModel>(m_model);
+    if (!model) return false;
 
     const EventVector &points = from.getPoints();
 
@@ -1173,7 +1217,7 @@
     }
 
     ChangeEventsCommand *command =
-        new ChangeEventsCommand(m_model, tr("Paste"));
+        new ChangeEventsCommand(m_model.untyped, tr("Paste"));
 
     for (EventVector::const_iterator i = points.begin();
          i != points.end(); ++i) {
@@ -1197,8 +1241,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;
@@ -1210,7 +1254,7 @@
                 nextFrame = j->getFrame();
             }
             if (nextFrame == frame) {
-                newPoint = newPoint.withDuration(m_model->getResolution());
+                newPoint = newPoint.withDuration(model->getResolution());
             } else {
                 newPoint = newPoint.withDuration(nextFrame - frame);
             }
@@ -1233,6 +1277,8 @@
 void
 NoteLayer::addNoteOff(sv_frame_t frame, int pitch)
 {
+    auto model = ModelById::getAs<NoteModel>(m_model);
+
     for (NoteSet::iterator i = m_pendingNoteOns.begin();
          i != m_pendingNoteOns.end(); ++i) {
 
@@ -1241,9 +1287,9 @@
         if (lrintf(p.getValue()) == pitch) {
             m_pendingNoteOns.erase(i);
             Event note = p.withDuration(frame - p.getFrame());
-            if (m_model) {
+            if (model) {
                 ChangeEventsCommand *c = new ChangeEventsCommand
-                    (m_model, tr("Record Note"));
+                    (m_model.untyped, tr("Record Note"));
                 c->add(note);
                 // execute and bundle:
                 CommandHistory::getInstance()->addCommand(c, true, true);