comparison layer/TextLayer.cpp @ 1474:36ad3cdabf55 by-id

Further layer updates for ModelById
author Chris Cannam
date Tue, 02 Jul 2019 14:08:44 +0100
parents f2525e6cbdf1
children 37df1530519d
comparison
equal deleted inserted replaced
1473:886c1cd48f9d 1474:36ad3cdabf55
32 #include <iostream> 32 #include <iostream>
33 #include <cmath> 33 #include <cmath>
34 34
35 TextLayer::TextLayer() : 35 TextLayer::TextLayer() :
36 SingleColourLayer(), 36 SingleColourLayer(),
37 m_model(nullptr),
38 m_editing(false), 37 m_editing(false),
39 m_originalPoint(0, 0.0, tr("Empty Label")), 38 m_originalPoint(0, 0.0, tr("Empty Label")),
40 m_editingPoint(0, 0.0, tr("Empty Label")), 39 m_editingPoint(0, 0.0, tr("Empty Label")),
41 m_editingCommand(nullptr) 40 m_editingCommand(nullptr)
42 { 41 {
123 } 122 }
124 123
125 EventVector 124 EventVector
126 TextLayer::getLocalPoints(LayerGeometryProvider *v, int x, int y) const 125 TextLayer::getLocalPoints(LayerGeometryProvider *v, int x, int y) const
127 { 126 {
128 if (!m_model) return {}; 127 auto model = ModelById::getAs<TextModel>(m_model);
128 if (!model) return {};
129 129
130 int overlap = ViewManager::scalePixelSize(150); 130 int overlap = ViewManager::scalePixelSize(150);
131 131
132 sv_frame_t frame0 = v->getFrameForX(-overlap); 132 sv_frame_t frame0 = v->getFrameForX(-overlap);
133 sv_frame_t frame1 = v->getFrameForX(v->getPaintWidth() + overlap); 133 sv_frame_t frame1 = v->getFrameForX(v->getPaintWidth() + overlap);
134 134
135 EventVector points(m_model->getEventsSpanning(frame0, frame1 - frame0)); 135 EventVector points(model->getEventsSpanning(frame0, frame1 - frame0));
136 136
137 EventVector rv; 137 EventVector rv;
138 QFontMetrics metrics = QFontMetrics(QFont()); 138 QFontMetrics metrics = QFontMetrics(QFont());
139 139
140 for (EventVector::iterator i = points.begin(); i != points.end(); ++i) { 140 for (EventVector::iterator i = points.begin(); i != points.end(); ++i) {
168 } 168 }
169 169
170 bool 170 bool
171 TextLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, Event &p) const 171 TextLayer::getPointToDrag(LayerGeometryProvider *v, int x, int y, Event &p) const
172 { 172 {
173 if (!m_model) return false; 173 auto model = ModelById::getAs<TextModel>(m_model);
174 if (!model) return false;
174 175
175 sv_frame_t a = v->getFrameForX(x - ViewManager::scalePixelSize(120)); 176 sv_frame_t a = v->getFrameForX(x - ViewManager::scalePixelSize(120));
176 sv_frame_t b = v->getFrameForX(x + ViewManager::scalePixelSize(10)); 177 sv_frame_t b = v->getFrameForX(x + ViewManager::scalePixelSize(10));
177 EventVector onPoints = m_model->getEventsWithin(a, b); 178 EventVector onPoints = model->getEventsWithin(a, b);
178 if (onPoints.empty()) return false; 179 if (onPoints.empty()) return false;
179 180
180 double nearestDistance = -1; 181 double nearestDistance = -1;
181 182
182 for (EventVector::const_iterator i = onPoints.begin(); 183 for (EventVector::const_iterator i = onPoints.begin();
198 QString 199 QString
199 TextLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const 200 TextLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const
200 { 201 {
201 int x = pos.x(); 202 int x = pos.x();
202 203
203 if (!m_model || !m_model->getSampleRate()) return ""; 204 auto model = ModelById::getAs<TextModel>(m_model);
205 if (!model || !model->getSampleRate()) return "";
204 206
205 EventVector points = getLocalPoints(v, x, pos.y()); 207 EventVector points = getLocalPoints(v, x, pos.y());
206 208
207 if (points.empty()) { 209 if (points.empty()) {
208 if (!m_model->isReady()) { 210 if (!model->isReady()) {
209 return tr("In progress"); 211 return tr("In progress");
210 } else { 212 } else {
211 return ""; 213 return "";
212 } 214 }
213 } 215 }
214 216
215 sv_frame_t useFrame = points.begin()->getFrame(); 217 sv_frame_t useFrame = points.begin()->getFrame();
216 218
217 RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate()); 219 RealTime rt = RealTime::frame2RealTime(useFrame, model->getSampleRate());
218 220
219 QString text; 221 QString text;
220 222
221 if (points.begin()->getLabel() == "") { 223 if (points.begin()->getLabel() == "") {
222 text = QString(tr("Time:\t%1\nHeight:\t%2\nLabel:\t%3")) 224 text = QString(tr("Time:\t%1\nHeight:\t%2\nLabel:\t%3"))
236 bool 238 bool
237 TextLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, 239 TextLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame,
238 int &resolution, 240 int &resolution,
239 SnapType snap) const 241 SnapType snap) const
240 { 242 {
241 if (!m_model) { 243 auto model = ModelById::getAs<TextModel>(m_model);
244 if (!model) {
242 return Layer::snapToFeatureFrame(v, frame, resolution, snap); 245 return Layer::snapToFeatureFrame(v, frame, resolution, snap);
243 } 246 }
244 247
245 // SnapLeft / SnapRight: return frame of nearest feature in that 248 // SnapLeft / SnapRight: return frame of nearest feature in that
246 // direction no matter how far away 249 // direction no matter how far away
247 // 250 //
248 // SnapNeighbouring: return frame of feature that would be used in 251 // SnapNeighbouring: return frame of feature that would be used in
249 // an editing operation, i.e. closest feature in either direction 252 // an editing operation, i.e. closest feature in either direction
250 // but only if it is "close enough" 253 // but only if it is "close enough"
251 254
252 resolution = m_model->getResolution(); 255 resolution = model->getResolution();
253 256
254 if (snap == SnapNeighbouring) { 257 if (snap == SnapNeighbouring) {
255 EventVector points = getLocalPoints(v, v->getXForFrame(frame), -1); 258 EventVector points = getLocalPoints(v, v->getXForFrame(frame), -1);
256 if (points.empty()) return false; 259 if (points.empty()) return false;
257 frame = points.begin()->getFrame(); 260 frame = points.begin()->getFrame();
258 return true; 261 return true;
259 } 262 }
260 263
261 Event e; 264 Event e;
262 if (m_model->getNearestEventMatching 265 if (model->getNearestEventMatching
263 (frame, 266 (frame,
264 [](Event) { return true; }, 267 [](Event) { return true; },
265 snap == SnapLeft ? EventSeries::Backward : EventSeries::Forward, 268 snap == SnapLeft ? EventSeries::Backward : EventSeries::Forward,
266 e)) { 269 e)) {
267 frame = e.getFrame(); 270 frame = e.getFrame();
286 } 289 }
287 290
288 void 291 void
289 TextLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const 292 TextLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const
290 { 293 {
291 if (!m_model || !m_model->isOK()) return; 294 auto model = ModelById::getAs<TextModel>(m_model);
292 295 if (!model || !model->isOK()) return;
293 sv_samplerate_t sampleRate = m_model->getSampleRate(); 296
297 sv_samplerate_t sampleRate = model->getSampleRate();
294 if (!sampleRate) return; 298 if (!sampleRate) return;
295 299
296 // Profiler profiler("TextLayer::paint", true); 300 // Profiler profiler("TextLayer::paint", true);
297 301
298 int x0 = rect.left(), x1 = rect.right(); 302 int x0 = rect.left(), x1 = rect.right();
299 int overlap = ViewManager::scalePixelSize(150); 303 int overlap = ViewManager::scalePixelSize(150);
300 sv_frame_t frame0 = v->getFrameForX(x0 - overlap); 304 sv_frame_t frame0 = v->getFrameForX(x0 - overlap);
301 sv_frame_t frame1 = v->getFrameForX(x1 + overlap); 305 sv_frame_t frame1 = v->getFrameForX(x1 + overlap);
302 306
303 EventVector points(m_model->getEventsWithin(frame0, frame1 - frame0, 2)); 307 EventVector points(model->getEventsWithin(frame0, frame1 - frame0, 2));
304 if (points.empty()) return; 308 if (points.empty()) return;
305 309
306 QColor brushColour(getBaseQColor()); 310 QColor brushColour(getBaseQColor());
307 311
308 int h, s, val; 312 int h, s, val;
311 315
312 QColor penColour; 316 QColor penColour;
313 penColour = v->getForeground(); 317 penColour = v->getForeground();
314 318
315 // SVDEBUG << "TextLayer::paint: resolution is " 319 // SVDEBUG << "TextLayer::paint: resolution is "
316 // << m_model->getResolution() << " frames" << endl; 320 // << model->getResolution() << " frames" << endl;
317 321
318 QPoint localPos; 322 QPoint localPos;
319 Event illuminatePoint(0); 323 Event illuminatePoint(0);
320 bool shouldIlluminate = false; 324 bool shouldIlluminate = false;
321 325
391 void 395 void
392 TextLayer::drawStart(LayerGeometryProvider *v, QMouseEvent *e) 396 TextLayer::drawStart(LayerGeometryProvider *v, QMouseEvent *e)
393 { 397 {
394 // SVDEBUG << "TextLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; 398 // SVDEBUG << "TextLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl;
395 399
396 if (!m_model) { 400 auto model = ModelById::getAs<TextModel>(m_model);
401 if (!model) {
397 SVDEBUG << "TextLayer::drawStart: no model" << endl; 402 SVDEBUG << "TextLayer::drawStart: no model" << endl;
398 return; 403 return;
399 } 404 }
400 405
401 sv_frame_t frame = v->getFrameForX(e->x()); 406 sv_frame_t frame = v->getFrameForX(e->x());
402 if (frame < 0) frame = 0; 407 if (frame < 0) frame = 0;
403 frame = frame / m_model->getResolution() * m_model->getResolution(); 408 frame = frame / model->getResolution() * model->getResolution();
404 409
405 double height = getHeightForY(v, e->y()); 410 double height = getHeightForY(v, e->y());
406 411
407 m_editingPoint = Event(frame, float(height), ""); 412 m_editingPoint = Event(frame, float(height), "");
408 m_originalPoint = m_editingPoint; 413 m_originalPoint = m_editingPoint;
409 414
410 if (m_editingCommand) finish(m_editingCommand); 415 if (m_editingCommand) finish(m_editingCommand);
411 m_editingCommand = new ChangeEventsCommand(m_model, "Add Label"); 416 m_editingCommand = new ChangeEventsCommand(m_model.untyped, "Add Label");
412 m_editingCommand->add(m_editingPoint); 417 m_editingCommand->add(m_editingPoint);
413 418
414 m_editing = true; 419 m_editing = true;
415 } 420 }
416 421
417 void 422 void
418 TextLayer::drawDrag(LayerGeometryProvider *v, QMouseEvent *e) 423 TextLayer::drawDrag(LayerGeometryProvider *v, QMouseEvent *e)
419 { 424 {
420 // SVDEBUG << "TextLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; 425 // SVDEBUG << "TextLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl;
421 426
422 if (!m_model || !m_editing) return; 427 auto model = ModelById::getAs<TextModel>(m_model);
428 if (!model || !m_editing) return;
423 429
424 sv_frame_t frame = v->getFrameForX(e->x()); 430 sv_frame_t frame = v->getFrameForX(e->x());
425 if (frame < 0) frame = 0; 431 if (frame < 0) frame = 0;
426 frame = frame / m_model->getResolution() * m_model->getResolution(); 432 frame = frame / model->getResolution() * model->getResolution();
427 433
428 double height = getHeightForY(v, e->y()); 434 double height = getHeightForY(v, e->y());
429 435
430 m_editingCommand->remove(m_editingPoint); 436 m_editingCommand->remove(m_editingPoint);
431 m_editingPoint = m_editingPoint 437 m_editingPoint = m_editingPoint
436 442
437 void 443 void
438 TextLayer::drawEnd(LayerGeometryProvider *v, QMouseEvent *) 444 TextLayer::drawEnd(LayerGeometryProvider *v, QMouseEvent *)
439 { 445 {
440 // SVDEBUG << "TextLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl; 446 // SVDEBUG << "TextLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl;
441 if (!m_model || !m_editing) return; 447 auto model = ModelById::getAs<TextModel>(m_model);
448 if (!model || !m_editing) return;
442 449
443 bool ok = false; 450 bool ok = false;
444 QString label = QInputDialog::getText(v->getView(), tr("Enter label"), 451 QString label = QInputDialog::getText(v->getView(), tr("Enter label"),
445 tr("Please enter a new label:"), 452 tr("Please enter a new label:"),
446 QLineEdit::Normal, "", &ok); 453 QLineEdit::Normal, "", &ok);
459 } 466 }
460 467
461 void 468 void
462 TextLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e) 469 TextLayer::eraseStart(LayerGeometryProvider *v, QMouseEvent *e)
463 { 470 {
464 if (!m_model) return; 471 auto model = ModelById::getAs<TextModel>(m_model);
472 if (!model) return;
465 473
466 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; 474 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
467 475
468 if (m_editingCommand) { 476 if (m_editingCommand) {
469 finish(m_editingCommand); 477 finish(m_editingCommand);
479 } 487 }
480 488
481 void 489 void
482 TextLayer::eraseEnd(LayerGeometryProvider *v, QMouseEvent *e) 490 TextLayer::eraseEnd(LayerGeometryProvider *v, QMouseEvent *e)
483 { 491 {
484 if (!m_model || !m_editing) return; 492 auto model = ModelById::getAs<TextModel>(m_model);
493 if (!model || !m_editing) return;
485 494
486 m_editing = false; 495 m_editing = false;
487 496
488 Event p; 497 Event p;
489 if (!getPointToDrag(v, e->x(), e->y(), p)) return; 498 if (!getPointToDrag(v, e->x(), e->y(), p)) return;
490 if (p.getFrame() != m_editingPoint.getFrame() || 499 if (p.getFrame() != m_editingPoint.getFrame() ||
491 p.getValue() != m_editingPoint.getValue()) return; 500 p.getValue() != m_editingPoint.getValue()) return;
492 501
493 m_editingCommand = new ChangeEventsCommand(m_model, tr("Erase Point")); 502 m_editingCommand = new ChangeEventsCommand(m_model.untyped, tr("Erase Point"));
494 m_editingCommand->remove(m_editingPoint); 503 m_editingCommand->remove(m_editingPoint);
495 finish(m_editingCommand); 504 finish(m_editingCommand);
496 m_editingCommand = nullptr; 505 m_editingCommand = nullptr;
497 m_editing = false; 506 m_editing = false;
498 } 507 }
500 void 509 void
501 TextLayer::editStart(LayerGeometryProvider *v, QMouseEvent *e) 510 TextLayer::editStart(LayerGeometryProvider *v, QMouseEvent *e)
502 { 511 {
503 // SVDEBUG << "TextLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; 512 // SVDEBUG << "TextLayer::editStart(" << e->x() << "," << e->y() << ")" << endl;
504 513
505 if (!m_model) return; 514 auto model = ModelById::getAs<TextModel>(m_model);
515 if (!model) return;
506 516
507 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) { 517 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) {
508 return; 518 return;
509 } 519 }
510 520
520 } 530 }
521 531
522 void 532 void
523 TextLayer::editDrag(LayerGeometryProvider *v, QMouseEvent *e) 533 TextLayer::editDrag(LayerGeometryProvider *v, QMouseEvent *e)
524 { 534 {
525 if (!m_model || !m_editing) return; 535 auto model = ModelById::getAs<TextModel>(m_model);
536 if (!model || !m_editing) return;
526 537
527 sv_frame_t frameDiff = 538 sv_frame_t frameDiff =
528 v->getFrameForX(e->x()) - v->getFrameForX(m_editOrigin.x()); 539 v->getFrameForX(e->x()) - v->getFrameForX(m_editOrigin.x());
529 double heightDiff = 540 double heightDiff =
530 getHeightForY(v, e->y()) - getHeightForY(v, m_editOrigin.y()); 541 getHeightForY(v, e->y()) - getHeightForY(v, m_editOrigin.y());
531 542
532 sv_frame_t frame = m_originalPoint.getFrame() + frameDiff; 543 sv_frame_t frame = m_originalPoint.getFrame() + frameDiff;
533 double height = m_originalPoint.getValue() + heightDiff; 544 double height = m_originalPoint.getValue() + heightDiff;
534 545
535 if (frame < 0) frame = 0; 546 if (frame < 0) frame = 0;
536 frame = (frame / m_model->getResolution()) * m_model->getResolution(); 547 frame = (frame / model->getResolution()) * model->getResolution();
537 548
538 if (!m_editingCommand) { 549 if (!m_editingCommand) {
539 m_editingCommand = new ChangeEventsCommand(m_model, tr("Drag Label")); 550 m_editingCommand = new ChangeEventsCommand(m_model.untyped, tr("Drag Label"));
540 } 551 }
541 552
542 m_editingCommand->remove(m_editingPoint); 553 m_editingCommand->remove(m_editingPoint);
543 m_editingPoint = m_editingPoint 554 m_editingPoint = m_editingPoint
544 .withFrame(frame) 555 .withFrame(frame)
548 559
549 void 560 void
550 TextLayer::editEnd(LayerGeometryProvider *, QMouseEvent *) 561 TextLayer::editEnd(LayerGeometryProvider *, QMouseEvent *)
551 { 562 {
552 // SVDEBUG << "TextLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl; 563 // SVDEBUG << "TextLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl;
553 if (!m_model || !m_editing) return; 564 auto model = ModelById::getAs<TextModel>(m_model);
565 if (!model || !m_editing) return;
554 566
555 if (m_editingCommand) { 567 if (m_editingCommand) {
556 568
557 QString newName = m_editingCommand->getName(); 569 QString newName = m_editingCommand->getName();
558 570
575 } 587 }
576 588
577 bool 589 bool
578 TextLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e) 590 TextLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e)
579 { 591 {
580 if (!m_model) return false; 592 auto model = ModelById::getAs<TextModel>(m_model);
593 if (!model) return false;
581 594
582 Event text; 595 Event text;
583 if (!getPointToDrag(v, e->x(), e->y(), text)) return false; 596 if (!getPointToDrag(v, e->x(), e->y(), text)) return false;
584 597
585 QString label = text.getLabel(); 598 QString label = text.getLabel();
588 label = QInputDialog::getText(v->getView(), tr("Enter label"), 601 label = QInputDialog::getText(v->getView(), tr("Enter label"),
589 tr("Please enter a new label:"), 602 tr("Please enter a new label:"),
590 QLineEdit::Normal, label, &ok); 603 QLineEdit::Normal, label, &ok);
591 if (ok && label != text.getLabel()) { 604 if (ok && label != text.getLabel()) {
592 ChangeEventsCommand *command = 605 ChangeEventsCommand *command =
593 new ChangeEventsCommand(m_model, tr("Re-Label Point")); 606 new ChangeEventsCommand(m_model.untyped, tr("Re-Label Point"));
594 command->remove(text); 607 command->remove(text);
595 command->add(text.withLabel(label)); 608 command->add(text.withLabel(label));
596 finish(command); 609 finish(command);
597 } 610 }
598 611
600 } 613 }
601 614
602 void 615 void
603 TextLayer::moveSelection(Selection s, sv_frame_t newStartFrame) 616 TextLayer::moveSelection(Selection s, sv_frame_t newStartFrame)
604 { 617 {
605 if (!m_model) return; 618 auto model = ModelById::getAs<TextModel>(m_model);
619 if (!model) return;
606 620
607 ChangeEventsCommand *command = 621 ChangeEventsCommand *command =
608 new ChangeEventsCommand(m_model, tr("Drag Selection")); 622 new ChangeEventsCommand(m_model.untyped, tr("Drag Selection"));
609 623
610 EventVector points = 624 EventVector points =
611 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); 625 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration());
612 626
613 for (Event p: points) { 627 for (Event p: points) {
614 command->remove(p); 628 command->remove(p);
615 Event moved = p.withFrame(p.getFrame() + 629 Event moved = p.withFrame(p.getFrame() +
616 newStartFrame - s.getStartFrame()); 630 newStartFrame - s.getStartFrame());
621 } 635 }
622 636
623 void 637 void
624 TextLayer::resizeSelection(Selection s, Selection newSize) 638 TextLayer::resizeSelection(Selection s, Selection newSize)
625 { 639 {
626 if (!m_model) return; 640 auto model = ModelById::getAs<TextModel>(m_model);
641 if (!model) return;
627 642
628 ChangeEventsCommand *command = 643 ChangeEventsCommand *command =
629 new ChangeEventsCommand(m_model, tr("Resize Selection")); 644 new ChangeEventsCommand(m_model.untyped, tr("Resize Selection"));
630 645
631 EventVector points = 646 EventVector points =
632 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); 647 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration());
633 648
634 double ratio = double(newSize.getDuration()) / double(s.getDuration()); 649 double ratio = double(newSize.getDuration()) / double(s.getDuration());
635 double oldStart = double(s.getStartFrame()); 650 double oldStart = double(s.getStartFrame());
636 double newStart = double(newSize.getStartFrame()); 651 double newStart = double(newSize.getStartFrame());
637 652
649 } 664 }
650 665
651 void 666 void
652 TextLayer::deleteSelection(Selection s) 667 TextLayer::deleteSelection(Selection s)
653 { 668 {
654 if (!m_model) return; 669 auto model = ModelById::getAs<TextModel>(m_model);
670 if (!model) return;
655 671
656 ChangeEventsCommand *command = 672 ChangeEventsCommand *command =
657 new ChangeEventsCommand(m_model, tr("Delete Selection")); 673 new ChangeEventsCommand(m_model.untyped, tr("Delete Selection"));
658 674
659 EventVector points = 675 EventVector points =
660 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); 676 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration());
661 677
662 for (Event p: points) { 678 for (Event p: points) {
663 command->remove(p); 679 command->remove(p);
664 } 680 }
665 681
667 } 683 }
668 684
669 void 685 void
670 TextLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) 686 TextLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to)
671 { 687 {
672 if (!m_model) return; 688 auto model = ModelById::getAs<TextModel>(m_model);
689 if (!model) return;
673 690
674 EventVector points = 691 EventVector points =
675 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); 692 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration());
676 693
677 for (Event p: points) { 694 for (Event p: points) {
678 to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame()))); 695 to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame())));
679 } 696 }
680 } 697 }
681 698
682 bool 699 bool
683 TextLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /* frameOffset */, bool /* interactive */) 700 TextLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /* frameOffset */, bool /* interactive */)
684 { 701 {
685 if (!m_model) return false; 702 auto model = ModelById::getAs<TextModel>(m_model);
703 if (!model) return false;
686 704
687 const EventVector &points = from.getPoints(); 705 const EventVector &points = from.getPoints();
688 706
689 bool realign = false; 707 bool realign = false;
690 708
704 realign = true; 722 realign = true;
705 } 723 }
706 } 724 }
707 725
708 ChangeEventsCommand *command = 726 ChangeEventsCommand *command =
709 new ChangeEventsCommand(m_model, tr("Paste")); 727 new ChangeEventsCommand(m_model.untyped, tr("Paste"));
710 728
711 double valueMin = 0.0, valueMax = 1.0; 729 double valueMin = 0.0, valueMax = 1.0;
712 for (EventVector::const_iterator i = points.begin(); 730 for (EventVector::const_iterator i = points.begin();
713 i != points.end(); ++i) { 731 i != points.end(); ++i) {
714 if (i->hasValue()) { 732 if (i->hasValue()) {