comparison layer/ImageLayer.cpp @ 1486:ac0a8addabcf

Merge from branch by-id
author Chris Cannam
date Wed, 17 Jul 2019 14:25:16 +0100
parents e540aa5d89cd
children 37df1530519d
comparison
equal deleted inserted replaced
1468:de41a11cabc2 1486:ac0a8addabcf
41 41
42 QMutex 42 QMutex
43 ImageLayer::m_imageMapMutex; 43 ImageLayer::m_imageMapMutex;
44 44
45 ImageLayer::ImageLayer() : 45 ImageLayer::ImageLayer() :
46 Layer(),
47 m_model(nullptr),
48 m_editing(false), 46 m_editing(false),
49 m_editingCommand(nullptr) 47 m_editingCommand(nullptr)
50 { 48 {
51 } 49 }
52 50
56 i != m_fileSources.end(); ++i) { 54 i != m_fileSources.end(); ++i) {
57 delete i->second; 55 delete i->second;
58 } 56 }
59 } 57 }
60 58
61 void 59 int
62 ImageLayer::setModel(ImageModel *model) 60 ImageLayer::getCompletion(LayerGeometryProvider *) const
63 { 61 {
64 if (m_model == model) return; 62 auto model = ModelById::get(m_model);
65 m_model = model; 63 if (model) return model->getCompletion();
66 64 else return 0;
67 connectSignals(m_model); 65 }
66
67 void
68 ImageLayer::setModel(ModelId modelId)
69 {
70 auto newModel = ModelById::getAs<ImageModel>(modelId);
71
72 if (!modelId.isNone() && !newModel) {
73 throw std::logic_error("Not an ImageModel");
74 }
75
76 if (m_model == modelId) return;
77 m_model = modelId;
78
79 if (newModel) {
80 connectSignals(m_model);
81 }
68 82
69 emit modelReplaced(); 83 emit modelReplaced();
70 } 84 }
71 85
72 Layer::PropertyList 86 Layer::PropertyList
120 } 134 }
121 135
122 EventVector 136 EventVector
123 ImageLayer::getLocalPoints(LayerGeometryProvider *v, int x, int ) const 137 ImageLayer::getLocalPoints(LayerGeometryProvider *v, int x, int ) const
124 { 138 {
125 if (!m_model) return {}; 139 auto model = ModelById::getAs<ImageModel>(m_model);
140 if (!model) return {};
126 141
127 // SVDEBUG << "ImageLayer::getLocalPoints(" << x << "," << y << "):"; 142 // SVDEBUG << "ImageLayer::getLocalPoints(" << x << "," << y << "):";
128 EventVector points(m_model->getAllEvents()); 143 EventVector points(model->getAllEvents());
129 144
130 EventVector rv; 145 EventVector rv;
131 146
132 for (EventVector::const_iterator i = points.begin(); i != points.end(); ) { 147 for (EventVector::const_iterator i = points.begin(); i != points.end(); ) {
133 148
167 QString 182 QString
168 ImageLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const 183 ImageLayer::getFeatureDescription(LayerGeometryProvider *v, QPoint &pos) const
169 { 184 {
170 int x = pos.x(); 185 int x = pos.x();
171 186
172 if (!m_model || !m_model->getSampleRate()) return ""; 187 auto model = ModelById::getAs<ImageModel>(m_model);
188 if (!model || !model->getSampleRate()) return "";
173 189
174 EventVector points = getLocalPoints(v, x, pos.y()); 190 EventVector points = getLocalPoints(v, x, pos.y());
175 191
176 if (points.empty()) { 192 if (points.empty()) {
177 if (!m_model->isReady()) { 193 if (!model->isReady()) {
178 return tr("In progress"); 194 return tr("In progress");
179 } else { 195 } else {
180 return ""; 196 return "";
181 } 197 }
182 } 198 }
183 199
184 // int useFrame = points.begin()->frame; 200 // int useFrame = points.begin()->frame;
185 201
186 // RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate()); 202 // RealTime rt = RealTime::frame2RealTime(useFrame, model->getSampleRate());
187 203
188 QString text; 204 QString text;
189 /* 205 /*
190 if (points.begin()->label == "") { 206 if (points.begin()->label == "") {
191 text = QString(tr("Time:\t%1\nHeight:\t%2\nLabel:\t%3")) 207 text = QString(tr("Time:\t%1\nHeight:\t%2\nLabel:\t%3"))
206 bool 222 bool
207 ImageLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame, 223 ImageLayer::snapToFeatureFrame(LayerGeometryProvider *v, sv_frame_t &frame,
208 int &resolution, 224 int &resolution,
209 SnapType snap) const 225 SnapType snap) const
210 { 226 {
211 if (!m_model) { 227 auto model = ModelById::getAs<ImageModel>(m_model);
228 if (!model) {
212 return Layer::snapToFeatureFrame(v, frame, resolution, snap); 229 return Layer::snapToFeatureFrame(v, frame, resolution, snap);
213 } 230 }
214 231
215 resolution = m_model->getResolution(); 232 resolution = model->getResolution();
216 233
217 if (snap == SnapNeighbouring) { 234 if (snap == SnapNeighbouring) {
218 EventVector points = getLocalPoints(v, v->getXForFrame(frame), -1); 235 EventVector points = getLocalPoints(v, v->getXForFrame(frame), -1);
219 if (points.empty()) return false; 236 if (points.empty()) return false;
220 frame = points.begin()->getFrame(); 237 frame = points.begin()->getFrame();
221 return true; 238 return true;
222 } 239 }
223 240
224 Event e; 241 Event e;
225 if (m_model->getNearestEventMatching 242 if (model->getNearestEventMatching
226 (frame, 243 (frame,
227 [](Event) { return true; }, 244 [](Event) { return true; },
228 snap == SnapLeft ? EventSeries::Backward : EventSeries::Forward, 245 snap == SnapLeft ? EventSeries::Backward : EventSeries::Forward,
229 e)) { 246 e)) {
230 frame = e.getFrame(); 247 frame = e.getFrame();
235 } 252 }
236 253
237 void 254 void
238 ImageLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const 255 ImageLayer::paint(LayerGeometryProvider *v, QPainter &paint, QRect rect) const
239 { 256 {
240 if (!m_model || !m_model->isOK()) return; 257 auto model = ModelById::getAs<ImageModel>(m_model);
241 258 if (!model || !model->isOK()) return;
242 sv_samplerate_t sampleRate = m_model->getSampleRate(); 259
260 sv_samplerate_t sampleRate = model->getSampleRate();
243 if (!sampleRate) return; 261 if (!sampleRate) return;
244 262
245 // Profiler profiler("ImageLayer::paint", true); 263 // Profiler profiler("ImageLayer::paint", true);
246 264
247 // int x0 = rect.left(), x1 = rect.right(); 265 // int x0 = rect.left(), x1 = rect.right();
248 int x0 = 0, x1 = v->getPaintWidth(); 266 int x0 = 0, x1 = v->getPaintWidth();
249 267
250 sv_frame_t frame0 = v->getFrameForX(x0); 268 sv_frame_t frame0 = v->getFrameForX(x0);
251 sv_frame_t frame1 = v->getFrameForX(x1); 269 sv_frame_t frame1 = v->getFrameForX(x1);
252 270
253 EventVector points(m_model->getEventsWithin(frame0, frame1 - frame0, 2)); 271 EventVector points(model->getEventsWithin(frame0, frame1 - frame0, 2));
254 if (points.empty()) return; 272 if (points.empty()) return;
255 273
256 paint.save(); 274 paint.save();
257 paint.setClipRect(rect.x(), 0, rect.width(), v->getPaintHeight()); 275 paint.setClipRect(rect.x(), 0, rect.width(), v->getPaintHeight());
258 276
338 } 356 }
339 357
340 if (likelyWidth > availableWidth) { 358 if (likelyWidth > availableWidth) {
341 likelyWidth = availableWidth; 359 likelyWidth = availableWidth;
342 } 360 }
361
362 // Qt 5.13 deprecates QFontMetrics::width(), but its suggested
363 // replacement (horizontalAdvance) was only added in Qt 5.11
364 // which is too new for us
365 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
343 366
344 int singleWidth = paint.fontMetrics().width(label); 367 int singleWidth = paint.fontMetrics().width(label);
345 if (singleWidth < availableWidth && singleWidth < likelyWidth * 2) { 368 if (singleWidth < availableWidth && singleWidth < likelyWidth * 2) {
346 likelyWidth = singleWidth + 4; 369 likelyWidth = singleWidth + 4;
347 } 370 }
511 void 534 void
512 ImageLayer::drawStart(LayerGeometryProvider *v, QMouseEvent *e) 535 ImageLayer::drawStart(LayerGeometryProvider *v, QMouseEvent *e)
513 { 536 {
514 // SVDEBUG << "ImageLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; 537 // SVDEBUG << "ImageLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl;
515 538
516 if (!m_model) { 539 auto model = ModelById::getAs<ImageModel>(m_model);
540 if (!model) {
517 SVDEBUG << "ImageLayer::drawStart: no model" << endl; 541 SVDEBUG << "ImageLayer::drawStart: no model" << endl;
518 return; 542 return;
519 } 543 }
520 544
521 sv_frame_t frame = v->getFrameForX(e->x()); 545 sv_frame_t frame = v->getFrameForX(e->x());
522 if (frame < 0) frame = 0; 546 if (frame < 0) frame = 0;
523 frame = frame / m_model->getResolution() * m_model->getResolution(); 547 frame = frame / model->getResolution() * model->getResolution();
524 548
525 m_editingPoint = Event(frame); 549 m_editingPoint = Event(frame);
526 m_originalPoint = m_editingPoint; 550 m_originalPoint = m_editingPoint;
527 551
528 if (m_editingCommand) finish(m_editingCommand); 552 if (m_editingCommand) finish(m_editingCommand);
529 m_editingCommand = new ChangeEventsCommand(m_model, "Add Image"); 553 m_editingCommand = new ChangeEventsCommand(m_model.untyped, "Add Image");
530 m_editingCommand->add(m_editingPoint); 554 m_editingCommand->add(m_editingPoint);
531 555
532 m_editing = true; 556 m_editing = true;
533 } 557 }
534 558
535 void 559 void
536 ImageLayer::drawDrag(LayerGeometryProvider *v, QMouseEvent *e) 560 ImageLayer::drawDrag(LayerGeometryProvider *v, QMouseEvent *e)
537 { 561 {
538 // SVDEBUG << "ImageLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; 562 // SVDEBUG << "ImageLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl;
539 563
540 if (!m_model || !m_editing) return; 564 auto model = ModelById::getAs<ImageModel>(m_model);
565 if (!model || !m_editing) return;
541 566
542 sv_frame_t frame = v->getFrameForX(e->x()); 567 sv_frame_t frame = v->getFrameForX(e->x());
543 if (frame < 0) frame = 0; 568 if (frame < 0) frame = 0;
544 frame = frame / m_model->getResolution() * m_model->getResolution(); 569 frame = frame / model->getResolution() * model->getResolution();
545 570
546 m_editingCommand->remove(m_editingPoint); 571 m_editingCommand->remove(m_editingPoint);
547 m_editingPoint = m_editingPoint 572 m_editingPoint = m_editingPoint
548 .withFrame(frame); 573 .withFrame(frame);
549 m_editingCommand->add(m_editingPoint); 574 m_editingCommand->add(m_editingPoint);
551 576
552 void 577 void
553 ImageLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *) 578 ImageLayer::drawEnd(LayerGeometryProvider *, QMouseEvent *)
554 { 579 {
555 // SVDEBUG << "ImageLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl; 580 // SVDEBUG << "ImageLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl;
556 if (!m_model || !m_editing) return; 581 auto model = ModelById::getAs<ImageModel>(m_model);
582 if (!model || !m_editing) return;
557 583
558 ImageDialog dialog(tr("Select image"), "", ""); 584 ImageDialog dialog(tr("Select image"), "", "");
559 585
560 m_editingCommand->remove(m_editingPoint); 586 m_editingCommand->remove(m_editingPoint);
561 587
584 m_fileSources.erase(url); 610 m_fileSources.erase(url);
585 return false; 611 return false;
586 } 612 }
587 613
588 Event point = Event(frame).withURI(url); 614 Event point = Event(frame).withURI(url);
589 ChangeEventsCommand *command = 615 auto command =
590 new ChangeEventsCommand(m_model, "Add Image"); 616 new ChangeEventsCommand(m_model.untyped, "Add Image");
591 command->add(point); 617 command->add(point);
592 finish(command); 618 finish(command);
593 return true; 619 return true;
594 } 620 }
595 621
596 void 622 void
597 ImageLayer::editStart(LayerGeometryProvider *v, QMouseEvent *e) 623 ImageLayer::editStart(LayerGeometryProvider *v, QMouseEvent *e)
598 { 624 {
599 // SVDEBUG << "ImageLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; 625 // SVDEBUG << "ImageLayer::editStart(" << e->x() << "," << e->y() << ")" << endl;
600 626
601 if (!m_model) return; 627 auto model = ModelById::getAs<ImageModel>(m_model);
628 if (!model) return;
602 629
603 EventVector points = getLocalPoints(v, e->x(), e->y()); 630 EventVector points = getLocalPoints(v, e->x(), e->y());
604 if (points.empty()) return; 631 if (points.empty()) return;
605 632
606 m_editOrigin = e->pos(); 633 m_editOrigin = e->pos();
616 } 643 }
617 644
618 void 645 void
619 ImageLayer::editDrag(LayerGeometryProvider *v, QMouseEvent *e) 646 ImageLayer::editDrag(LayerGeometryProvider *v, QMouseEvent *e)
620 { 647 {
621 if (!m_model || !m_editing) return; 648 auto model = ModelById::getAs<ImageModel>(m_model);
649 if (!model || !m_editing) return;
622 650
623 sv_frame_t frameDiff = v->getFrameForX(e->x()) - v->getFrameForX(m_editOrigin.x()); 651 sv_frame_t frameDiff = v->getFrameForX(e->x()) - v->getFrameForX(m_editOrigin.x());
624 sv_frame_t frame = m_originalPoint.getFrame() + frameDiff; 652 sv_frame_t frame = m_originalPoint.getFrame() + frameDiff;
625 653
626 if (frame < 0) frame = 0; 654 if (frame < 0) frame = 0;
627 frame = (frame / m_model->getResolution()) * m_model->getResolution(); 655 frame = (frame / model->getResolution()) * model->getResolution();
628 656
629 if (!m_editingCommand) { 657 if (!m_editingCommand) {
630 m_editingCommand = new ChangeEventsCommand(m_model, tr("Move Image")); 658 m_editingCommand = new ChangeEventsCommand(m_model.untyped, tr("Move Image"));
631 } 659 }
632 660
633 m_editingCommand->remove(m_editingPoint); 661 m_editingCommand->remove(m_editingPoint);
634 m_editingPoint = m_editingPoint 662 m_editingPoint = m_editingPoint
635 .withFrame(frame); 663 .withFrame(frame);
638 666
639 void 667 void
640 ImageLayer::editEnd(LayerGeometryProvider *, QMouseEvent *) 668 ImageLayer::editEnd(LayerGeometryProvider *, QMouseEvent *)
641 { 669 {
642 // SVDEBUG << "ImageLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl; 670 // SVDEBUG << "ImageLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl;
643 if (!m_model || !m_editing) return; 671 auto model = ModelById::getAs<ImageModel>(m_model);
672 if (!model || !m_editing) return;
644 673
645 if (m_editingCommand) { 674 if (m_editingCommand) {
646 finish(m_editingCommand); 675 finish(m_editingCommand);
647 } 676 }
648 677
651 } 680 }
652 681
653 bool 682 bool
654 ImageLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e) 683 ImageLayer::editOpen(LayerGeometryProvider *v, QMouseEvent *e)
655 { 684 {
656 if (!m_model) return false; 685 auto model = ModelById::getAs<ImageModel>(m_model);
686 if (!model) return false;
657 687
658 EventVector points = getLocalPoints(v, e->x(), e->y()); 688 EventVector points = getLocalPoints(v, e->x(), e->y());
659 if (points.empty()) return false; 689 if (points.empty()) return false;
660 690
661 QString image = points.begin()->getURI(); 691 QString image = points.begin()->getURI();
667 697
668 if (dialog.exec() == QDialog::Accepted) { 698 if (dialog.exec() == QDialog::Accepted) {
669 699
670 checkAddSource(dialog.getImage()); 700 checkAddSource(dialog.getImage());
671 701
672 ChangeEventsCommand *command = 702 auto command =
673 new ChangeEventsCommand(m_model, tr("Edit Image")); 703 new ChangeEventsCommand(m_model.untyped, tr("Edit Image"));
674 command->remove(*points.begin()); 704 command->remove(*points.begin());
675 command->add(points.begin()-> 705 command->add(points.begin()->
676 withURI(dialog.getImage()).withLabel(dialog.getLabel())); 706 withURI(dialog.getImage()).withLabel(dialog.getLabel()));
677 finish(command); 707 finish(command);
678 } 708 }
681 } 711 }
682 712
683 void 713 void
684 ImageLayer::moveSelection(Selection s, sv_frame_t newStartFrame) 714 ImageLayer::moveSelection(Selection s, sv_frame_t newStartFrame)
685 { 715 {
686 if (!m_model) return; 716 auto model = ModelById::getAs<ImageModel>(m_model);
687 717 if (!model) return;
688 ChangeEventsCommand *command = 718
689 new ChangeEventsCommand(m_model, tr("Drag Selection")); 719 auto command =
720 new ChangeEventsCommand(m_model.untyped, tr("Drag Selection"));
690 721
691 EventVector points = 722 EventVector points =
692 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); 723 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration());
693 724
694 for (Event p: points) { 725 for (Event p: points) {
695 command->remove(p); 726 command->remove(p);
696 Event moved = p.withFrame(p.getFrame() + 727 Event moved = p.withFrame(p.getFrame() +
697 newStartFrame - s.getStartFrame()); 728 newStartFrame - s.getStartFrame());
702 } 733 }
703 734
704 void 735 void
705 ImageLayer::resizeSelection(Selection s, Selection newSize) 736 ImageLayer::resizeSelection(Selection s, Selection newSize)
706 { 737 {
707 if (!m_model) return; 738 auto model = ModelById::getAs<ImageModel>(m_model);
708 739 if (!model) return;
709 ChangeEventsCommand *command = 740
710 new ChangeEventsCommand(m_model, tr("Resize Selection")); 741 auto command =
742 new ChangeEventsCommand(m_model.untyped, tr("Resize Selection"));
711 743
712 EventVector points = 744 EventVector points =
713 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); 745 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration());
714 746
715 double ratio = double(newSize.getDuration()) / double(s.getDuration()); 747 double ratio = double(newSize.getDuration()) / double(s.getDuration());
716 double oldStart = double(s.getStartFrame()); 748 double oldStart = double(s.getStartFrame());
717 double newStart = double(newSize.getStartFrame()); 749 double newStart = double(newSize.getStartFrame());
718 750
730 } 762 }
731 763
732 void 764 void
733 ImageLayer::deleteSelection(Selection s) 765 ImageLayer::deleteSelection(Selection s)
734 { 766 {
735 if (!m_model) return; 767 auto model = ModelById::getAs<ImageModel>(m_model);
736 768 if (!model) return;
737 ChangeEventsCommand *command = 769
738 new ChangeEventsCommand(m_model, tr("Delete Selection")); 770 auto command =
771 new ChangeEventsCommand(m_model.untyped, tr("Delete Selection"));
739 772
740 EventVector points = 773 EventVector points =
741 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); 774 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration());
742 775
743 for (Event p: points) { 776 for (Event p: points) {
744 command->remove(p); 777 command->remove(p);
745 } 778 }
746 779
748 } 781 }
749 782
750 void 783 void
751 ImageLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to) 784 ImageLayer::copy(LayerGeometryProvider *v, Selection s, Clipboard &to)
752 { 785 {
753 if (!m_model) return; 786 auto model = ModelById::getAs<ImageModel>(m_model);
787 if (!model) return;
754 788
755 EventVector points = 789 EventVector points =
756 m_model->getEventsStartingWithin(s.getStartFrame(), s.getDuration()); 790 model->getEventsStartingWithin(s.getStartFrame(), s.getDuration());
757 791
758 for (Event p: points) { 792 for (Event p: points) {
759 to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame()))); 793 to.addPoint(p.withReferenceFrame(alignToReference(v, p.getFrame())));
760 } 794 }
761 } 795 }
762 796
763 bool 797 bool
764 ImageLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /* frameOffset */, bool /* interactive */) 798 ImageLayer::paste(LayerGeometryProvider *v, const Clipboard &from, sv_frame_t /* frameOffset */, bool /* interactive */)
765 { 799 {
766 if (!m_model) return false; 800 auto model = ModelById::getAs<ImageModel>(m_model);
801 if (!model) return false;
767 802
768 const EventVector &points = from.getPoints(); 803 const EventVector &points = from.getPoints();
769 804
770 bool realign = false; 805 bool realign = false;
771 806
784 if (button == QMessageBox::Yes) { 819 if (button == QMessageBox::Yes) {
785 realign = true; 820 realign = true;
786 } 821 }
787 } 822 }
788 823
789 ChangeEventsCommand *command = 824 auto command = new ChangeEventsCommand(m_model.untyped, tr("Paste"));
790 new ChangeEventsCommand(m_model, tr("Paste"));
791 825
792 for (EventVector::const_iterator i = points.begin(); 826 for (EventVector::const_iterator i = points.begin();
793 i != points.end(); ++i) { 827 i != points.end(); ++i) {
794 828
795 sv_frame_t frame = 0; 829 sv_frame_t frame = 0;
861 } 895 }
862 896
863 void 897 void
864 ImageLayer::checkAddSources() 898 ImageLayer::checkAddSources()
865 { 899 {
866 const EventVector &points(m_model->getAllEvents()); 900 auto model = ModelById::getAs<ImageModel>(m_model);
901 const EventVector &points(model->getAllEvents());
867 902
868 for (EventVector::const_iterator i = points.begin(); 903 for (EventVector::const_iterator i = points.begin();
869 i != points.end(); ++i) { 904 i != points.end(); ++i) {
870 905
871 checkAddSource((*i).getURI()); 906 checkAddSource((*i).getURI());
893 928
894 QMutexLocker locker(&m_imageMapMutex); 929 QMutexLocker locker(&m_imageMapMutex);
895 m_images.erase(img); 930 m_images.erase(img);
896 for (ViewImageMap::iterator i = m_scaled.begin(); i != m_scaled.end(); ++i) { 931 for (ViewImageMap::iterator i = m_scaled.begin(); i != m_scaled.end(); ++i) {
897 i->second.erase(img); 932 i->second.erase(img);
898 emit modelChanged(); 933 emit modelChanged(getModel());
899 } 934 }
900 } 935 }
901 936
902 void 937 void
903 ImageLayer::toXml(QTextStream &stream, 938 ImageLayer::toXml(QTextStream &stream,