Mercurial > hg > svgui
comparison layer/NoteLayer.cpp @ 1471:f2525e6cbdf1 by-id
More layer updates
author | Chris Cannam |
---|---|
date | Mon, 01 Jul 2019 14:17:13 +0100 |
parents | 696e569ff21b |
children | e540aa5d89cd |
comparison
equal
deleted
inserted
replaced
1470:696e569ff21b | 1471:f2525e6cbdf1 |
---|---|
46 | 46 |
47 //#define DEBUG_NOTE_LAYER 1 | 47 //#define DEBUG_NOTE_LAYER 1 |
48 | 48 |
49 NoteLayer::NoteLayer() : | 49 NoteLayer::NoteLayer() : |
50 SingleColourLayer(), | 50 SingleColourLayer(), |
51 m_model(nullptr), | |
52 m_editing(false), | 51 m_editing(false), |
53 m_dragPointX(0), | 52 m_dragPointX(0), |
54 m_dragPointY(0), | 53 m_dragPointY(0), |
55 m_dragStartX(0), | 54 m_dragStartX(0), |
56 m_dragStartY(0), | 55 m_dragStartY(0), |
72 if (model) return model->getCompletion(); | 71 if (model) return model->getCompletion(); |
73 else return 0; | 72 else return 0; |
74 } | 73 } |
75 | 74 |
76 void | 75 void |
77 NoteLayer::setModel(ModelId model) | 76 NoteLayer::setModel(ModelId modelId) |
78 { | 77 { |
79 if (m_model == model) return; | 78 auto newModel = ModelById::getAs<NoteModel>(modelId); |
80 m_model = model; | 79 |
81 | 80 if (!modelId.isNone() && !newModel) { |
82 connectSignals(m_model); | 81 throw std::logic_error("Not a NoteModel"); |
83 | 82 } |
84 // SVDEBUG << "NoteLayer::setModel(" << model << ")" << endl; | 83 |
85 | 84 if (m_model == modelId) return; |
85 m_model = modelId; | |
86 | |
87 if (newModel) { | |
88 connectSignals(m_model); | |
89 } | |
90 | |
86 m_scaleMinimum = 0; | 91 m_scaleMinimum = 0; |
87 m_scaleMaximum = 0; | 92 m_scaleMaximum = 0; |
88 | 93 |
89 emit modelReplaced(); | 94 emit modelReplaced(); |
90 } | 95 } |
124 } | 129 } |
125 | 130 |
126 QString | 131 QString |
127 NoteLayer::getScaleUnits() const | 132 NoteLayer::getScaleUnits() const |
128 { | 133 { |
129 if (m_model) return m_model->getScaleUnits(); | 134 auto model = ModelById::getAs<NoteModel>(m_model); |
135 if (model) return model->getScaleUnits(); | |
130 else return ""; | 136 else return ""; |
131 } | 137 } |
132 | 138 |
133 int | 139 int |
134 NoteLayer::getPropertyRangeAndValue(const PropertyName &name, | 140 NoteLayer::getPropertyRangeAndValue(const PropertyName &name, |
145 val = int(m_verticalScale); | 151 val = int(m_verticalScale); |
146 | 152 |
147 } else if (name == "Scale Units") { | 153 } else if (name == "Scale Units") { |
148 | 154 |
149 if (deflt) *deflt = 0; | 155 if (deflt) *deflt = 0; |
150 if (m_model) { | 156 auto model = ModelById::getAs<NoteModel>(m_model); |
157 if (model) { | |
151 val = UnitDatabase::getInstance()->getUnitId | 158 val = UnitDatabase::getInstance()->getUnitId |
152 (getScaleUnits()); | 159 (model->getScaleUnits()); |
153 } | 160 } |
154 | 161 |
155 } else { | 162 } else { |
156 | 163 |
157 val = SingleColourLayer::getPropertyRangeAndValue(name, min, max, deflt); | 164 val = SingleColourLayer::getPropertyRangeAndValue(name, min, max, deflt); |
180 NoteLayer::setProperty(const PropertyName &name, int value) | 187 NoteLayer::setProperty(const PropertyName &name, int value) |
181 { | 188 { |
182 if (name == "Vertical Scale") { | 189 if (name == "Vertical Scale") { |
183 setVerticalScale(VerticalScale(value)); | 190 setVerticalScale(VerticalScale(value)); |
184 } else if (name == "Scale Units") { | 191 } else if (name == "Scale Units") { |
185 if (m_model) { | 192 auto model = ModelById::getAs<NoteModel>(m_model); |
186 m_model->setScaleUnits | 193 if (model) { |
194 model->setScaleUnits | |
187 (UnitDatabase::getInstance()->getUnitById(value)); | 195 (UnitDatabase::getInstance()->getUnitById(value)); |
188 emit modelChanged(); | 196 emit modelChanged(); |
189 } | 197 } |
190 } else { | 198 } else { |
191 return SingleColourLayer::setProperty(name, value); | 199 return SingleColourLayer::setProperty(name, value); |
220 | 228 |
221 bool | 229 bool |
222 NoteLayer::getValueExtents(double &min, double &max, | 230 NoteLayer::getValueExtents(double &min, double &max, |
223 bool &logarithmic, QString &unit) const | 231 bool &logarithmic, QString &unit) const |
224 { | 232 { |
225 if (!m_model) return false; | 233 auto model = ModelById::getAs<NoteModel>(m_model); |
226 min = m_model->getValueMinimum(); | 234 if (!model) return false; |
227 max = m_model->getValueMaximum(); | 235 min = model->getValueMinimum(); |
236 max = model->getValueMaximum(); | |
228 | 237 |
229 if (shouldConvertMIDIToHz()) { | 238 if (shouldConvertMIDIToHz()) { |
230 unit = "Hz"; | 239 unit = "Hz"; |
231 min = Pitch::getFrequencyForPitch(int(lrint(min))); | 240 min = Pitch::getFrequencyForPitch(int(lrint(min))); |
232 max = Pitch::getFrequencyForPitch(int(lrint(max + 1))); | 241 max = Pitch::getFrequencyForPitch(int(lrint(max + 1))); |
233 } else unit = getScaleUnits(); | 242 } else unit = getScaleUnits(); |
234 | 243 |
235 if (m_verticalScale == MIDIRangeScale || | 244 if (m_verticalScale == MIDIRangeScale || |
236 m_verticalScale == LogScale) logarithmic = true; | 245 m_verticalScale == LogScale) { |
246 logarithmic = true; | |
247 } | |
237 | 248 |
238 return true; | 249 return true; |
239 } | 250 } |
240 | 251 |
241 bool | 252 bool |
242 NoteLayer::getDisplayExtents(double &min, double &max) const | 253 NoteLayer::getDisplayExtents(double &min, double &max) const |
243 { | 254 { |
244 if (!m_model || shouldAutoAlign()) return false; | 255 auto model = ModelById::getAs<NoteModel>(m_model); |
256 if (!model || shouldAutoAlign()) return false; | |
245 | 257 |
246 if (m_verticalScale == MIDIRangeScale) { | 258 if (m_verticalScale == MIDIRangeScale) { |
247 min = Pitch::getFrequencyForPitch(0); | 259 min = Pitch::getFrequencyForPitch(0); |
248 max = Pitch::getFrequencyForPitch(127); | 260 max = Pitch::getFrequencyForPitch(127); |
249 return true; | 261 return true; |
250 } | 262 } |
251 | 263 |
252 if (m_scaleMinimum == m_scaleMaximum) { | 264 if (m_scaleMinimum == m_scaleMaximum) { |
253 min = m_model->getValueMinimum(); | 265 min = model->getValueMinimum(); |
254 max = m_model->getValueMaximum(); | 266 max = model->getValueMaximum(); |
255 } else { | 267 } else { |
256 min = m_scaleMinimum; | 268 min = m_scaleMinimum; |
257 max = m_scaleMaximum; | 269 max = m_scaleMaximum; |
258 } | 270 } |
259 | 271 |
270 } | 282 } |
271 | 283 |
272 bool | 284 bool |
273 NoteLayer::setDisplayExtents(double min, double max) | 285 NoteLayer::setDisplayExtents(double min, double max) |
274 { | 286 { |
275 if (!m_model) return false; | 287 if (m_model.isNone()) return false; |
276 | 288 |
277 if (min == max) { | 289 if (min == max) { |
278 if (min == 0.f) { | 290 if (min == 0.f) { |
279 max = 1.f; | 291 max = 1.f; |
280 } else { | 292 } else { |
294 } | 306 } |
295 | 307 |
296 int | 308 int |
297 NoteLayer::getVerticalZoomSteps(int &defaultStep) const | 309 NoteLayer::getVerticalZoomSteps(int &defaultStep) const |
298 { | 310 { |
299 if (shouldAutoAlign()) return 0; | 311 if (shouldAutoAlign() || m_model.isNone()) return 0; |
300 if (!m_model) return 0; | |
301 | |
302 defaultStep = 0; | 312 defaultStep = 0; |
303 return 100; | 313 return 100; |
304 } | 314 } |
305 | 315 |
306 int | 316 int |
307 NoteLayer::getCurrentVerticalZoomStep() const | 317 NoteLayer::getCurrentVerticalZoomStep() const |
308 { | 318 { |
309 if (shouldAutoAlign()) return 0; | 319 if (shouldAutoAlign() || m_model.isNone()) return 0; |
310 if (!m_model) return 0; | |
311 | 320 |
312 RangeMapper *mapper = getNewVerticalZoomRangeMapper(); | 321 RangeMapper *mapper = getNewVerticalZoomRangeMapper(); |
313 if (!mapper) return 0; | 322 if (!mapper) return 0; |
314 | 323 |
315 double dmin, dmax; | 324 double dmin, dmax; |
325 //!!! lots of duplication with TimeValueLayer | 334 //!!! lots of duplication with TimeValueLayer |
326 | 335 |
327 void | 336 void |
328 NoteLayer::setVerticalZoomStep(int step) | 337 NoteLayer::setVerticalZoomStep(int step) |
329 { | 338 { |
330 if (shouldAutoAlign()) return; | 339 if (shouldAutoAlign() || m_model.isNone()) return; |
331 if (!m_model) return; | |
332 | 340 |
333 RangeMapper *mapper = getNewVerticalZoomRangeMapper(); | 341 RangeMapper *mapper = getNewVerticalZoomRangeMapper(); |
334 if (!mapper) return; | 342 if (!mapper) return; |
335 | 343 |
336 double min, max; | 344 double min, max; |
376 } | 384 } |
377 | 385 |
378 RangeMapper * | 386 RangeMapper * |
379 NoteLayer::getNewVerticalZoomRangeMapper() const | 387 NoteLayer::getNewVerticalZoomRangeMapper() const |
380 { | 388 { |
381 if (!m_model) return nullptr; | 389 if (m_model.isNone()) return nullptr; |
382 | 390 |
383 RangeMapper *mapper; | 391 RangeMapper *mapper; |
384 | 392 |
385 double min, max; | 393 double min, max; |
386 bool logarithmic; | 394 bool logarithmic; |
399 } | 407 } |
400 | 408 |
401 EventVector | 409 EventVector |
402 NoteLayer::getLocalPoints(LayerGeometryProvider *v, int x) const | 410 NoteLayer::getLocalPoints(LayerGeometryProvider *v, int x) const |
403 { | 411 { |
404 if (!m_model) return {}; | 412 auto model = ModelById::getAs<NoteModel>(m_model); |
413 if (!model) return {}; | |
405 | 414 |
406 sv_frame_t frame = v->getFrameForX(x); | 415 sv_frame_t frame = v->getFrameForX(x); |
407 | 416 |
408 EventVector local = m_model->getEventsCovering(frame); | 417 EventVector local = model->getEventsCovering(frame); |
409 if (!local.empty()) return local; | 418 if (!local.empty()) return local; |
410 | 419 |
411 int fuzz = ViewManager::scalePixelSize(2); | 420 int fuzz = ViewManager::scalePixelSize(2); |
412 sv_frame_t start = v->getFrameForX(x - fuzz); | 421 sv_frame_t start = v->getFrameForX(x - fuzz); |
413 sv_frame_t end = v->getFrameForX(x + fuzz); | 422 sv_frame_t end = v->getFrameForX(x + fuzz); |
414 | 423 |
415 local = m_model->getEventsStartingWithin(frame, end - frame); | 424 local = model->getEventsStartingWithin(frame, end - frame); |
416 if (!local.empty()) return local; | 425 if (!local.empty()) return local; |
417 | 426 |
418 local = m_model->getEventsSpanning(start, frame - start); | 427 local = model->getEventsSpanning(start, frame - start); |
419 if (!local.empty()) return local; | 428 if (!local.empty()) return local; |
420 | 429 |
421 return {}; | 430 return {}; |
422 } | 431 } |
423 | 432 |
424 bool | 433 bool |
425 NoteLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, Event &point) const | 434 NoteLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, Event &point) const |
426 { | 435 { |
427 if (!m_model) return false; | 436 auto model = ModelById::getAs<NoteModel>(m_model); |
437 if (!model) return false; | |
428 | 438 |
429 sv_frame_t frame = v->getFrameForX(x); | 439 sv_frame_t frame = v->getFrameForX(x); |
430 | 440 |
431 EventVector onPoints = m_model->getEventsCovering(frame); | 441 EventVector onPoints = model->getEventsCovering(frame); |
432 if (onPoints.empty()) return false; | 442 if (onPoints.empty()) return false; |
433 | 443 |
434 int nearestDistance = -1; | 444 int nearestDistance = -1; |
435 for (const auto &p: onPoints) { | 445 for (const auto &p: onPoints) { |
436 int distance = getYForValue(v, p.getValue()) - y; | 446 int distance = getYForValue(v, p.getValue()) - y; |
447 QString | 457 QString |
448 NoteLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const | 458 NoteLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const |
449 { | 459 { |
450 int x = pos.x(); | 460 int x = pos.x(); |
451 | 461 |
452 if (!m_model || !m_model->getSampleRate()) return ""; | 462 auto model = ModelById::getAs<NoteModel>(m_model); |
463 if (!model || !model->getSampleRate()) return ""; | |
453 | 464 |
454 EventVector points = getLocalPoints(v, x); | 465 EventVector points = getLocalPoints(v, x); |
455 | 466 |
456 if (points.empty()) { | 467 if (points.empty()) { |
457 if (!m_model->isReady()) { | 468 if (!model->isReady()) { |
458 return tr("In progress"); | 469 return tr("In progress"); |
459 } else { | 470 } else { |
460 return tr("No local points"); | 471 return tr("No local points"); |
461 } | 472 } |
462 } | 473 } |
467 for (i = points.begin(); i != points.end(); ++i) { | 478 for (i = points.begin(); i != points.end(); ++i) { |
468 | 479 |
469 int y = getYForValue(v, i->getValue()); | 480 int y = getYForValue(v, i->getValue()); |
470 int h = 3; | 481 int h = 3; |
471 | 482 |
472 if (m_model->getValueQuantization() != 0.0) { | 483 if (model->getValueQuantization() != 0.0) { |
473 h = y - getYForValue | 484 h = y - getYForValue |
474 (v, i->getValue() + m_model->getValueQuantization()); | 485 (v, i->getValue() + model->getValueQuantization()); |
475 if (h < 3) h = 3; | 486 if (h < 3) h = 3; |
476 } | 487 } |
477 | 488 |
478 if (pos.y() >= y - h && pos.y() <= y) { | 489 if (pos.y() >= y - h && pos.y() <= y) { |
479 note = *i; | 490 note = *i; |
482 } | 493 } |
483 | 494 |
484 if (i == points.end()) return tr("No local points"); | 495 if (i == points.end()) return tr("No local points"); |
485 | 496 |
486 RealTime rt = RealTime::frame2RealTime(note.getFrame(), | 497 RealTime rt = RealTime::frame2RealTime(note.getFrame(), |
487 m_model->getSampleRate()); | 498 model->getSampleRate()); |
488 RealTime rd = RealTime::frame2RealTime(note.getDuration(), | 499 RealTime rd = RealTime::frame2RealTime(note.getDuration(), |
489 m_model->getSampleRate()); | 500 model->getSampleRate()); |
490 | 501 |
491 QString pitchText; | 502 QString pitchText; |
492 | 503 |
493 float value = note.getValue(); | 504 float value = note.getValue(); |
494 | 505 |
536 bool | 547 bool |
537 NoteLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, | 548 NoteLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, |
538 int &resolution, | 549 int &resolution, |
539 SnapType snap) const | 550 SnapType snap) const |
540 { | 551 { |
541 if (!m_model) { | 552 auto model = ModelById::getAs<NoteModel>(m_model); |
553 if (!model) { | |
542 return Layer::snapToFeatureFrame(v, frame, resolution, snap); | 554 return Layer::snapToFeatureFrame(v, frame, resolution, snap); |
543 } | 555 } |
544 | 556 |
545 // SnapLeft / SnapRight: return frame of nearest feature in that | 557 // SnapLeft / SnapRight: return frame of nearest feature in that |
546 // direction no matter how far away | 558 // direction no matter how far away |
547 // | 559 // |
548 // SnapNeighbouring: return frame of feature that would be used in | 560 // SnapNeighbouring: return frame of feature that would be used in |
549 // an editing operation, i.e. closest feature in either direction | 561 // an editing operation, i.e. closest feature in either direction |
550 // but only if it is "close enough" | 562 // but only if it is "close enough" |
551 | 563 |
552 resolution = m_model->getResolution(); | 564 resolution = model->getResolution(); |
553 | 565 |
554 if (snap == SnapNeighbouring) { | 566 if (snap == SnapNeighbouring) { |
555 EventVector points = getLocalPoints(v, v->getXForFrame(frame)); | 567 EventVector points = getLocalPoints(v, v->getXForFrame(frame)); |
556 if (points.empty()) return false; | 568 if (points.empty()) return false; |
557 frame = points.begin()->getFrame(); | 569 frame = points.begin()->getFrame(); |
558 return true; | 570 return true; |
559 } | 571 } |
560 | 572 |
561 Event e; | 573 Event e; |
562 if (m_model->getNearestEventMatching | 574 if (model->getNearestEventMatching |
563 (frame, | 575 (frame, |
564 [](Event) { return true; }, | 576 [](Event) { return true; }, |
565 snap == SnapLeft ? EventSeries::Backward : EventSeries::Forward, | 577 snap == SnapLeft ? EventSeries::Backward : EventSeries::Forward, |
566 e)) { | 578 e)) { |
567 frame = e.getFrame(); | 579 frame = e.getFrame(); |
576 { | 588 { |
577 min = 0.0; | 589 min = 0.0; |
578 max = 0.0; | 590 max = 0.0; |
579 log = false; | 591 log = false; |
580 | 592 |
593 auto model = ModelById::getAs<NoteModel>(m_model); | |
594 if (!model) return; | |
595 | |
581 QString queryUnits; | 596 QString queryUnits; |
582 if (shouldConvertMIDIToHz()) queryUnits = "Hz"; | 597 if (shouldConvertMIDIToHz()) queryUnits = "Hz"; |
583 else queryUnits = getScaleUnits(); | 598 else queryUnits = getScaleUnits(); |
584 | 599 |
585 if (shouldAutoAlign()) { | 600 if (shouldAutoAlign()) { |
586 | 601 |
587 if (!v->getValueExtents(queryUnits, min, max, log)) { | 602 if (!v->getValueExtents(queryUnits, min, max, log)) { |
588 | 603 |
589 min = m_model->getValueMinimum(); | 604 min = model->getValueMinimum(); |
590 max = m_model->getValueMaximum(); | 605 max = model->getValueMaximum(); |
591 | 606 |
592 if (shouldConvertMIDIToHz()) { | 607 if (shouldConvertMIDIToHz()) { |
593 min = Pitch::getFrequencyForPitch(int(lrint(min))); | 608 min = Pitch::getFrequencyForPitch(int(lrint(min))); |
594 max = Pitch::getFrequencyForPitch(int(lrint(max + 1))); | 609 max = Pitch::getFrequencyForPitch(int(lrint(max + 1))); |
595 } | 610 } |
687 } | 702 } |
688 | 703 |
689 bool | 704 bool |
690 NoteLayer::shouldAutoAlign() const | 705 NoteLayer::shouldAutoAlign() const |
691 { | 706 { |
692 if (!m_model) return false; | 707 if (m_model.isNone()) return false; |
693 return (m_verticalScale == AutoAlignScale); | 708 return (m_verticalScale == AutoAlignScale); |
694 } | 709 } |
695 | 710 |
696 void | 711 void |
697 NoteLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const | 712 NoteLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const |
698 { | 713 { |
699 if (!m_model || !m_model->isOK()) return; | 714 auto model = ModelById::getAs<NoteModel>(m_model); |
700 | 715 if (!model || !model->isOK()) return; |
701 sv_samplerate_t sampleRate = m_model->getSampleRate(); | 716 |
717 sv_samplerate_t sampleRate = model->getSampleRate(); | |
702 if (!sampleRate) return; | 718 if (!sampleRate) return; |
703 | 719 |
704 // Profiler profiler("NoteLayer::paint", true); | 720 // Profiler profiler("NoteLayer::paint", true); |
705 | 721 |
706 int x0 = rect.left(), x1 = rect.right(); | 722 int x0 = rect.left(), x1 = rect.right(); |
707 sv_frame_t frame0 = v->getFrameForX(x0); | 723 sv_frame_t frame0 = v->getFrameForX(x0); |
708 sv_frame_t frame1 = v->getFrameForX(x1); | 724 sv_frame_t frame1 = v->getFrameForX(x1); |
709 | 725 |
710 EventVector points(m_model->getEventsSpanning(frame0, frame1 - frame0)); | 726 EventVector points(model->getEventsSpanning(frame0, frame1 - frame0)); |
711 if (points.empty()) return; | 727 if (points.empty()) return; |
712 | 728 |
713 paint.setPen(getBaseQColor()); | 729 paint.setPen(getBaseQColor()); |
714 | 730 |
715 QColor brushColour(getBaseQColor()); | 731 QColor brushColour(getBaseQColor()); |
716 brushColour.setAlpha(80); | 732 brushColour.setAlpha(80); |
717 | 733 |
718 // SVDEBUG << "NoteLayer::paint: resolution is " | 734 // SVDEBUG << "NoteLayer::paint: resolution is " |
719 // << m_model->getResolution() << " frames" << endl; | 735 // << model->getResolution() << " frames" << endl; |
720 | 736 |
721 double min = m_model->getValueMinimum(); | 737 double min = model->getValueMinimum(); |
722 double max = m_model->getValueMaximum(); | 738 double max = model->getValueMaximum(); |
723 if (max == min) max = min + 1.0; | 739 if (max == min) max = min + 1.0; |
724 | 740 |
725 QPoint localPos; | 741 QPoint localPos; |
726 Event illuminatePoint; | 742 Event illuminatePoint; |
727 bool shouldIlluminate = false; | 743 bool shouldIlluminate = false; |
745 int x = v->getXForFrame(p.getFrame()); | 761 int x = v->getXForFrame(p.getFrame()); |
746 int y = getYForValue(v, p.getValue()); | 762 int y = getYForValue(v, p.getValue()); |
747 int w = v->getXForFrame(p.getFrame() + p.getDuration()) - x; | 763 int w = v->getXForFrame(p.getFrame() + p.getDuration()) - x; |
748 int h = 3; | 764 int h = 3; |
749 | 765 |
750 if (m_model->getValueQuantization() != 0.0) { | 766 if (model->getValueQuantization() != 0.0) { |
751 h = y - getYForValue(v, p.getValue() + m_model->getValueQuantization()); | 767 h = y - getYForValue(v, p.getValue() + model->getValueQuantization()); |
752 if (h < 3) h = 3; | 768 if (h < 3) h = 3; |
753 } | 769 } |
754 | 770 |
755 if (w < 1) w = 1; | 771 if (w < 1) w = 1; |
756 paint.setPen(getBaseQColor()); | 772 paint.setPen(getBaseQColor()); |
758 | 774 |
759 if (shouldIlluminate && illuminatePoint == p) { | 775 if (shouldIlluminate && illuminatePoint == p) { |
760 | 776 |
761 paint.setPen(v->getForeground()); | 777 paint.setPen(v->getForeground()); |
762 paint.setBrush(v->getForeground()); | 778 paint.setBrush(v->getForeground()); |
779 | |
780 // Qt 5.13 deprecates QFontMetrics::width(), but its suggested | |
781 // replacement (horizontalAdvance) was only added in Qt 5.11 | |
782 // which is too new for us | |
783 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | |
763 | 784 |
764 QString vlabel = QString("%1%2").arg(p.getValue()).arg(getScaleUnits()); | 785 QString vlabel = QString("%1%2").arg(p.getValue()).arg(getScaleUnits()); |
765 PaintAssistant::drawVisibleText(v, paint, | 786 PaintAssistant::drawVisibleText(v, paint, |
766 x - paint.fontMetrics().width(vlabel) - 2, | 787 x - paint.fontMetrics().width(vlabel) - 2, |
767 y + paint.fontMetrics().height()/2 | 788 y + paint.fontMetrics().height()/2 |
768 - paint.fontMetrics().descent(), | 789 - paint.fontMetrics().descent(), |
769 vlabel, PaintAssistant::OutlinedText); | 790 vlabel, PaintAssistant::OutlinedText); |
770 | 791 |
771 QString hlabel = RealTime::frame2RealTime | 792 QString hlabel = RealTime::frame2RealTime |
772 (p.getFrame(), m_model->getSampleRate()).toText(true).c_str(); | 793 (p.getFrame(), model->getSampleRate()).toText(true).c_str(); |
773 PaintAssistant::drawVisibleText(v, paint, | 794 PaintAssistant::drawVisibleText(v, paint, |
774 x, | 795 x, |
775 y - h/2 - paint.fontMetrics().descent() - 2, | 796 y - h/2 - paint.fontMetrics().descent() - 2, |
776 hlabel, PaintAssistant::OutlinedText); | 797 hlabel, PaintAssistant::OutlinedText); |
777 } | 798 } |
783 } | 804 } |
784 | 805 |
785 int | 806 int |
786 NoteLayer::getVerticalScaleWidth(LayerGeometryProvider *v, bool, QPainter &paint) const | 807 NoteLayer::getVerticalScaleWidth(LayerGeometryProvider *v, bool, QPainter &paint) const |
787 { | 808 { |
788 if (!m_model) { | 809 if (m_model.isNone()) { |
789 return 0; | 810 return 0; |
790 } | 811 } |
791 | 812 |
792 if (shouldAutoAlign() && !valueExtentsMatchMine(v)) { | 813 if (shouldAutoAlign() && !valueExtentsMatchMine(v)) { |
793 return 0; | 814 return 0; |
801 } | 822 } |
802 | 823 |
803 void | 824 void |
804 NoteLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const | 825 NoteLayer::paintVerticalScale(LayerGeometryProvider *v, bool, QPainter &paint, QRect) const |
805 { | 826 { |
806 if (!m_model || m_model->isEmpty()) return; | 827 auto model = ModelById::getAs<NoteModel>(m_model); |
828 if (!model || model->isEmpty()) return; | |
807 | 829 |
808 QString unit; | 830 QString unit; |
809 double min, max; | 831 double min, max; |
810 bool logarithmic; | 832 bool logarithmic; |
811 | 833 |
841 void | 863 void |
842 NoteLayer::drawStart(LayerGeometryProvider *v, QMouseEvent *e) | 864 NoteLayer::drawStart(LayerGeometryProvider *v, QMouseEvent *e) |
843 { | 865 { |
844 // SVDEBUG << "NoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; | 866 // SVDEBUG << "NoteLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; |
845 | 867 |
846 if (!m_model) return; | 868 auto model = ModelById::getAs<NoteModel>(m_model); |
869 if (!model) return; | |
847 | 870 |
848 sv_frame_t frame = v->getFrameForX(e->x()); | 871 sv_frame_t frame = v->getFrameForX(e->x()); |
849 if (frame < 0) frame = 0; | 872 if (frame < 0) frame = 0; |
850 frame = frame / m_model->getResolution() * m_model->getResolution(); | 873 frame = frame / model->getResolution() * model->getResolution(); |
851 | 874 |
852 double value = getValueForY(v, e->y()); | 875 double value = getValueForY(v, e->y()); |
853 | 876 |
854 m_editingPoint = Event(frame, float(value), 0, 0.8f, tr("New Point")); | 877 m_editingPoint = Event(frame, float(value), 0, 0.8f, tr("New Point")); |
855 m_originalPoint = m_editingPoint; | 878 m_originalPoint = m_editingPoint; |
856 | 879 |
857 if (m_editingCommand) finish(m_editingCommand); | 880 if (m_editingCommand) finish(m_editingCommand); |
858 m_editingCommand = new ChangeEventsCommand(m_model, tr("Draw Point")); | 881 m_editingCommand = new ChangeEventsCommand(m_model.untyped, tr("Draw Point")); |
859 m_editingCommand->add(m_editingPoint); | 882 m_editingCommand->add(m_editingPoint); |
860 | 883 |
861 m_editing = true; | 884 m_editing = true; |
862 } | 885 } |
863 | 886 |
864 void | 887 void |
865 NoteLayer::drawDrag(LayerGeometryProvider *v, QMouseEvent *e) | 888 NoteLayer::drawDrag(LayerGeometryProvider *v, QMouseEvent *e) |
866 { | 889 { |
867 // SVDEBUG << "NoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; | 890 // SVDEBUG << "NoteLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; |
868 | 891 |
869 if (!m_model || !m_editing) return; | 892 auto model = ModelById::getAs<NoteModel>(m_model); |
893 if (!model || !m_editing) return; | |
870 | 894 |
871 sv_frame_t frame = v->getFrameForX(e->x()); | 895 sv_frame_t frame = v->getFrameForX(e->x()); |
872 if (frame < 0) frame = 0; | 896 if (frame < 0) frame = 0; |
873 frame = frame / m_model->getResolution() * m_model->getResolution(); | 897 frame = frame / model->getResolution() * model->getResolution(); |
874 | 898 |
875 double newValue = getValueForY(v, e->y()); | 899 double newValue = getValueForY(v, e->y()); |
876 | 900 |
877 sv_frame_t newFrame = m_editingPoint.getFrame(); | 901 sv_frame_t newFrame = m_editingPoint.getFrame(); |
878 sv_frame_t newDuration = frame - newFrame; | 902 sv_frame_t newDuration = frame - newFrame; |
893 | 917 |
894 void | 918 void |
895 NoteLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *) | 919 NoteLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *) |
896 { | 920 { |
897 // SVDEBUG << "NoteLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl; | 921 // SVDEBUG << "NoteLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl; |
898 if (!m_model || !m_editing) return; | 922 auto model = ModelById::getAs<NoteModel>(m_model); |
923 if (!model || !m_editing) return; | |
899 finish(m_editingCommand); | 924 finish(m_editingCommand); |
900 m_editingCommand = nullptr; | 925 m_editingCommand = nullptr; |
901 m_editing = false; | 926 m_editing = false; |
902 } | 927 } |
903 | 928 |
904 void | 929 void |
905 NoteLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e) | 930 NoteLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e) |
906 { | 931 { |
907 if (!m_model) return; | 932 auto model = ModelById::getAs<NoteModel>(m_model); |
933 if (!model) return; | |
908 | 934 |
909 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; | 935 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; |
910 | 936 |
911 if (m_editingCommand) { | 937 if (m_editingCommand) { |
912 finish(m_editingCommand); | 938 finish(m_editingCommand); |
922 } | 948 } |
923 | 949 |
924 void | 950 void |
925 NoteLayer::eraseEnd(LayerGeometryProvider *v, QMouseEvent *e) | 951 NoteLayer::eraseEnd(LayerGeometryProvider *v, QMouseEvent *e) |
926 { | 952 { |
927 if (!m_model || !m_editing) return; | 953 auto model = ModelById::getAs<NoteModel>(m_model); |
954 if (!model || !m_editing) return; | |
928 | 955 |
929 m_editing = false; | 956 m_editing = false; |
930 | 957 |
931 Event p(0); | 958 Event p(0); |
932 if (!getPointToDrag(v, e->x(), e->y(), p)) return; | 959 if (!getPointToDrag(v, e->x(), e->y(), p)) return; |
933 if (p.getFrame() != m_editingPoint.getFrame() || | 960 if (p.getFrame() != m_editingPoint.getFrame() || |
934 p.getValue() != m_editingPoint.getValue()) return; | 961 p.getValue() != m_editingPoint.getValue()) return; |
935 | 962 |
936 m_editingCommand = new ChangeEventsCommand(m_model, tr("Erase Point")); | 963 m_editingCommand = new ChangeEventsCommand(m_model.untyped, tr("Erase Point")); |
937 | 964 |
938 m_editingCommand->remove(m_editingPoint); | 965 m_editingCommand->remove(m_editingPoint); |
939 | 966 |
940 finish(m_editingCommand); | 967 finish(m_editingCommand); |
941 m_editingCommand = nullptr; | 968 m_editingCommand = nullptr; |
945 void | 972 void |
946 NoteLayer::editStart(LayerGeometryProvider *v, QMouseEvent *e) | 973 NoteLayer::editStart(LayerGeometryProvider *v, QMouseEvent *e) |
947 { | 974 { |
948 // SVDEBUG << "NoteLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; | 975 // SVDEBUG << "NoteLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; |
949 | 976 |
950 if (!m_model) return; | 977 auto model = ModelById::getAs<NoteModel>(m_model); |
978 if (!model) return; | |
951 | 979 |
952 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; | 980 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; |
953 m_originalPoint = m_editingPoint; | 981 m_originalPoint = m_editingPoint; |
954 | 982 |
955 m_dragPointX = v->getXForFrame(m_editingPoint.getFrame()); | 983 m_dragPointX = v->getXForFrame(m_editingPoint.getFrame()); |
968 void | 996 void |
969 NoteLayer::editDrag(LayerGeometryProvider *v, QMouseEvent *e) | 997 NoteLayer::editDrag(LayerGeometryProvider *v, QMouseEvent *e) |
970 { | 998 { |
971 // SVDEBUG << "NoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl; | 999 // SVDEBUG << "NoteLayer::editDrag(" << e->x() << "," << e->y() << ")" << endl; |
972 | 1000 |
973 if (!m_model || !m_editing) return; | 1001 auto model = ModelById::getAs<NoteModel>(m_model); |
1002 if (!model || !m_editing) return; | |
974 | 1003 |
975 int xdist = e->x() - m_dragStartX; | 1004 int xdist = e->x() - m_dragStartX; |
976 int ydist = e->y() - m_dragStartY; | 1005 int ydist = e->y() - m_dragStartY; |
977 int newx = m_dragPointX + xdist; | 1006 int newx = m_dragPointX + xdist; |
978 int newy = m_dragPointY + ydist; | 1007 int newy = m_dragPointY + ydist; |
979 | 1008 |
980 sv_frame_t frame = v->getFrameForX(newx); | 1009 sv_frame_t frame = v->getFrameForX(newx); |
981 if (frame < 0) frame = 0; | 1010 if (frame < 0) frame = 0; |
982 frame = frame / m_model->getResolution() * m_model->getResolution(); | 1011 frame = frame / model->getResolution() * model->getResolution(); |
983 | 1012 |
984 double value = getValueForY(v, newy); | 1013 double value = getValueForY(v, newy); |
985 | 1014 |
986 if (!m_editingCommand) { | 1015 if (!m_editingCommand) { |
987 m_editingCommand = new ChangeEventsCommand(m_model, | 1016 m_editingCommand = new ChangeEventsCommand |
988 tr("Drag Point")); | 1017 (m_model.untyped, tr("Drag Point")); |
989 } | 1018 } |
990 | 1019 |
991 m_editingCommand->remove(m_editingPoint); | 1020 m_editingCommand->remove(m_editingPoint); |
992 m_editingPoint = m_editingPoint | 1021 m_editingPoint = m_editingPoint |
993 .withFrame(frame) | 1022 .withFrame(frame) |
997 | 1026 |
998 void | 1027 void |
999 NoteLayer::editEnd(LayerGeometryProvider *, QMouseEvent *) | 1028 NoteLayer::editEnd(LayerGeometryProvider *, QMouseEvent *) |
1000 { | 1029 { |
1001 // SVDEBUG << "NoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl; | 1030 // SVDEBUG << "NoteLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl; |
1002 if (!m_model || !m_editing) return; | 1031 auto model = ModelById::getAs<NoteModel>(m_model); |
1032 if (!model || !m_editing) return; | |
1003 | 1033 |
1004 if (m_editingCommand) { | 1034 if (m_editingCommand) { |
1005 | 1035 |
1006 QString newName = m_editingCommand->getName(); | 1036 QString newName = m_editingCommand->getName(); |
1007 | 1037 |
1024 } | 1054 } |
1025 | 1055 |
1026 bool | 1056 bool |
1027 NoteLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e) | 1057 NoteLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e) |
1028 { | 1058 { |
1029 if (!m_model) return false; | 1059 auto model = ModelById::getAs<NoteModel>(m_model); |
1060 if (!model) return false; | |
1030 | 1061 |
1031 Event note(0); | 1062 Event note(0); |
1032 if (!getPointToDrag(v, e->x(), e->y(), note)) return false; | 1063 if (!getPointToDrag(v, e->x(), e->y(), note)) return false; |
1033 | 1064 |
1034 // Event note = *points.begin(); | 1065 // Event note = *points.begin(); |
1035 | 1066 |
1036 ItemEditDialog *dialog = new ItemEditDialog | 1067 ItemEditDialog *dialog = new ItemEditDialog |
1037 (m_model->getSampleRate(), | 1068 (model->getSampleRate(), |
1038 ItemEditDialog::ShowTime | | 1069 ItemEditDialog::ShowTime | |
1039 ItemEditDialog::ShowDuration | | 1070 ItemEditDialog::ShowDuration | |
1040 ItemEditDialog::ShowValue | | 1071 ItemEditDialog::ShowValue | |
1041 ItemEditDialog::ShowText, | 1072 ItemEditDialog::ShowText, |
1042 getScaleUnits()); | 1073 getScaleUnits()); |
1056 .withValue(dialog->getValue()) | 1087 .withValue(dialog->getValue()) |
1057 .withDuration(dialog->getFrameDuration()) | 1088 .withDuration(dialog->getFrameDuration()) |
1058 .withLabel(dialog->getText()); | 1089 .withLabel(dialog->getText()); |
1059 | 1090 |
1060 ChangeEventsCommand *command = new ChangeEventsCommand | 1091 ChangeEventsCommand *command = new ChangeEventsCommand |
1061 (m_model, tr("Edit Point")); | 1092 (m_model.untyped, tr("Edit Point")); |
1062 command->remove(note); | 1093 command->remove(note); |
1063 command->add(newNote); | 1094 command->add(newNote); |
1064 finish(command); | 1095 finish(command); |
1065 } | 1096 } |
1066 | 1097 |
1072 } | 1103 } |
1073 | 1104 |
1074 void | 1105 void |
1075 NoteLayer::moveSelection(Selection s, sv_frame_t newStartFrame) | 1106 NoteLayer::moveSelection(Selection s, sv_frame_t newStartFrame) |
1076 { | 1107 { |
1077 if (!m_model) return; | 1108 auto model = ModelById::getAs<NoteModel>(m_model); |
1109 if (!model) return; | |
1078 | 1110 |
1079 ChangeEventsCommand *command = | 1111 ChangeEventsCommand *command = |
1080 new ChangeEventsCommand(m_model, tr("Drag Selection")); | 1112 new ChangeEventsCommand(m_model.untyped, tr("Drag Selection")); |
1081 | 1113 |
1082 EventVector points = | 1114 EventVector points = |
1083 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); | 1115 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); |
1084 | 1116 |
1085 for (Event p: points) { | 1117 for (Event p: points) { |
1086 command->remove(p); | 1118 command->remove(p); |
1087 Event moved = p.withFrame(p.getFrame() + | 1119 Event moved = p.withFrame(p.getFrame() + |
1088 newStartFrame - s.getStartFrame()); | 1120 newStartFrame - s.getStartFrame()); |
1093 } | 1125 } |
1094 | 1126 |
1095 void | 1127 void |
1096 NoteLayer::resizeSelection(Selection s, Selection newSize) | 1128 NoteLayer::resizeSelection(Selection s, Selection newSize) |
1097 { | 1129 { |
1098 if (!m_model || !s.getDuration()) return; | 1130 auto model = ModelById::getAs<NoteModel>(m_model); |
1131 if (!model || !s.getDuration()) return; | |
1099 | 1132 |
1100 ChangeEventsCommand *command = | 1133 ChangeEventsCommand *command = |
1101 new ChangeEventsCommand(m_model, tr("Resize Selection")); | 1134 new ChangeEventsCommand(m_model.untyped, tr("Resize Selection")); |
1102 | 1135 |
1103 EventVector points = | 1136 EventVector points = |
1104 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); | 1137 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); |
1105 | 1138 |
1106 double ratio = double(newSize.getDuration()) / double(s.getDuration()); | 1139 double ratio = double(newSize.getDuration()) / double(s.getDuration()); |
1107 double oldStart = double(s.getStartFrame()); | 1140 double oldStart = double(s.getStartFrame()); |
1108 double newStart = double(newSize.getStartFrame()); | 1141 double newStart = double(newSize.getStartFrame()); |
1109 | 1142 |
1123 } | 1156 } |
1124 | 1157 |
1125 void | 1158 void |
1126 NoteLayer::deleteSelection(Selection s) | 1159 NoteLayer::deleteSelection(Selection s) |
1127 { | 1160 { |
1128 if (!m_model) return; | 1161 auto model = ModelById::getAs<NoteModel>(m_model); |
1162 if (!model) return; | |
1129 | 1163 |
1130 ChangeEventsCommand *command = | 1164 ChangeEventsCommand *command = |
1131 new ChangeEventsCommand(m_model, tr("Delete Selected Points")); | 1165 new ChangeEventsCommand(m_model.untyped, tr("Delete Selected Points")); |
1132 | 1166 |
1133 EventVector points = | 1167 EventVector points = |
1134 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); | 1168 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); |
1135 | 1169 |
1136 for (Event p: points) { | 1170 for (Event p: points) { |
1137 command->remove(p); | 1171 command->remove(p); |
1138 } | 1172 } |
1139 | 1173 |
1141 } | 1175 } |
1142 | 1176 |
1143 void | 1177 void |
1144 NoteLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) | 1178 NoteLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) |
1145 { | 1179 { |
1146 if (!m_model) return; | 1180 auto model = ModelById::getAs<NoteModel>(m_model); |
1181 if (!model) return; | |
1147 | 1182 |
1148 EventVector points = | 1183 EventVector points = |
1149 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); | 1184 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); |
1150 | 1185 |
1151 for (Event p: points) { | 1186 for (Event p: points) { |
1152 to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame()))); | 1187 to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame()))); |
1153 } | 1188 } |
1154 } | 1189 } |
1155 | 1190 |
1156 bool | 1191 bool |
1157 NoteLayer::paste(LayerGeometryProvider *v, const Clipboard &from, | 1192 NoteLayer::paste(LayerGeometryProvider *v, const Clipboard &from, |
1158 sv_frame_t /* frameOffset */, bool /* interactive */) | 1193 sv_frame_t /* frameOffset */, bool /* interactive */) |
1159 { | 1194 { |
1160 if (!m_model) return false; | 1195 auto model = ModelById::getAs<NoteModel>(m_model); |
1196 if (!model) return false; | |
1161 | 1197 |
1162 const EventVector &points = from.getPoints(); | 1198 const EventVector &points = from.getPoints(); |
1163 | 1199 |
1164 bool realign = false; | 1200 bool realign = false; |
1165 | 1201 |
1179 realign = true; | 1215 realign = true; |
1180 } | 1216 } |
1181 } | 1217 } |
1182 | 1218 |
1183 ChangeEventsCommand *command = | 1219 ChangeEventsCommand *command = |
1184 new ChangeEventsCommand(m_model, tr("Paste")); | 1220 new ChangeEventsCommand(m_model.untyped, tr("Paste")); |
1185 | 1221 |
1186 for (EventVector::const_iterator i = points.begin(); | 1222 for (EventVector::const_iterator i = points.begin(); |
1187 i != points.end(); ++i) { | 1223 i != points.end(); ++i) { |
1188 | 1224 |
1189 sv_frame_t frame = 0; | 1225 sv_frame_t frame = 0; |
1203 } | 1239 } |
1204 | 1240 |
1205 Event p = *i; | 1241 Event p = *i; |
1206 Event newPoint = p; | 1242 Event newPoint = p; |
1207 if (!p.hasValue()) { | 1243 if (!p.hasValue()) { |
1208 newPoint = newPoint.withValue((m_model->getValueMinimum() + | 1244 newPoint = newPoint.withValue((model->getValueMinimum() + |
1209 m_model->getValueMaximum()) / 2); | 1245 model->getValueMaximum()) / 2); |
1210 } | 1246 } |
1211 if (!p.hasDuration()) { | 1247 if (!p.hasDuration()) { |
1212 sv_frame_t nextFrame = frame; | 1248 sv_frame_t nextFrame = frame; |
1213 EventVector::const_iterator j = i; | 1249 EventVector::const_iterator j = i; |
1214 for (; j != points.end(); ++j) { | 1250 for (; j != points.end(); ++j) { |
1216 } | 1252 } |
1217 if (j != points.end()) { | 1253 if (j != points.end()) { |
1218 nextFrame = j->getFrame(); | 1254 nextFrame = j->getFrame(); |
1219 } | 1255 } |
1220 if (nextFrame == frame) { | 1256 if (nextFrame == frame) { |
1221 newPoint = newPoint.withDuration(m_model->getResolution()); | 1257 newPoint = newPoint.withDuration(model->getResolution()); |
1222 } else { | 1258 } else { |
1223 newPoint = newPoint.withDuration(nextFrame - frame); | 1259 newPoint = newPoint.withDuration(nextFrame - frame); |
1224 } | 1260 } |
1225 } | 1261 } |
1226 | 1262 |
1239 } | 1275 } |
1240 | 1276 |
1241 void | 1277 void |
1242 NoteLayer::addNoteOff(sv_frame_t frame, int pitch) | 1278 NoteLayer::addNoteOff(sv_frame_t frame, int pitch) |
1243 { | 1279 { |
1280 auto model = ModelById::getAs<NoteModel>(m_model); | |
1281 | |
1244 for (NoteSet::iterator i = m_pendingNoteOns.begin(); | 1282 for (NoteSet::iterator i = m_pendingNoteOns.begin(); |
1245 i != m_pendingNoteOns.end(); ++i) { | 1283 i != m_pendingNoteOns.end(); ++i) { |
1246 | 1284 |
1247 Event p = *i; | 1285 Event p = *i; |
1248 | 1286 |
1249 if (lrintf(p.getValue()) == pitch) { | 1287 if (lrintf(p.getValue()) == pitch) { |
1250 m_pendingNoteOns.erase(i); | 1288 m_pendingNoteOns.erase(i); |
1251 Event note = p.withDuration(frame - p.getFrame()); | 1289 Event note = p.withDuration(frame - p.getFrame()); |
1252 if (m_model) { | 1290 if (model) { |
1253 ChangeEventsCommand *c = new ChangeEventsCommand | 1291 ChangeEventsCommand *c = new ChangeEventsCommand |
1254 (m_model, tr("Record Note")); | 1292 (m_model.untyped, tr("Record Note")); |
1255 c->add(note); | 1293 c->add(note); |
1256 // execute and bundle: | 1294 // execute and bundle: |
1257 CommandHistory::getInstance()->addCommand(c, true, true); | 1295 CommandHistory::getInstance()->addCommand(c, true, true); |
1258 } | 1296 } |
1259 break; | 1297 break; |