Mercurial > hg > svgui
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()) { |