comparison view/View.cpp @ 1324:13d9b422f7fe zoom

Merge from default branch
author Chris Cannam
date Mon, 17 Sep 2018 13:51:31 +0100
parents 57d192e26331 769d7890203b
children 97c68bffbda6
comparison
equal deleted inserted replaced
1183:57d192e26331 1324:13d9b422f7fe
39 #include <QTextStream> 39 #include <QTextStream>
40 #include <QFont> 40 #include <QFont>
41 #include <QMessageBox> 41 #include <QMessageBox>
42 #include <QPushButton> 42 #include <QPushButton>
43 #include <QSettings> 43 #include <QSettings>
44 #include <QSvgGenerator>
44 45
45 #include <iostream> 46 #include <iostream>
46 #include <cassert> 47 #include <cassert>
47 #include <cmath> 48 #include <cmath>
48 49
77 { 78 {
78 // cerr << "View::~View(" << this << ")" << endl; 79 // cerr << "View::~View(" << this << ")" << endl;
79 80
80 m_deleting = true; 81 m_deleting = true;
81 delete m_propertyContainer; 82 delete m_propertyContainer;
83 delete m_cache;
84 delete m_buffer;
82 } 85 }
83 86
84 PropertyContainer::PropertyList 87 PropertyContainer::PropertyList
85 View::getProperties() const 88 View::getProperties() const
86 { 89 {
109 return PropertyContainer::InvalidProperty; 112 return PropertyContainer::InvalidProperty;
110 } 113 }
111 114
112 int 115 int
113 View::getPropertyRangeAndValue(const PropertyContainer::PropertyName &name, 116 View::getPropertyRangeAndValue(const PropertyContainer::PropertyName &name,
114 int *min, int *max, int *deflt) const 117 int *min, int *max, int *deflt) const
115 { 118 {
116 if (deflt) *deflt = 1; 119 if (deflt) *deflt = 1;
117 if (name == "Global Scroll") return m_followPan; 120 if (name == "Global Scroll") return m_followPan;
118 if (name == "Global Zoom") return m_followZoom; 121 if (name == "Global Zoom") return m_followZoom;
119 if (name == "Follow Playback") { 122 if (name == "Follow Playback") {
120 if (min) *min = 0; 123 if (min) *min = 0;
121 if (max) *max = 2; 124 if (max) *max = 2;
122 if (deflt) *deflt = int(PlaybackScrollPageWithCentre); 125 if (deflt) *deflt = int(PlaybackScrollPageWithCentre);
123 switch (m_followPlay) { 126 switch (m_followPlay) {
124 case PlaybackScrollContinuous: return 0; 127 case PlaybackScrollContinuous: return 0;
125 case PlaybackScrollPageWithCentre: case PlaybackScrollPage: return 1; 128 case PlaybackScrollPageWithCentre: case PlaybackScrollPage: return 1;
126 case PlaybackIgnore: return 2; 129 case PlaybackIgnore: return 2;
132 return 0; 135 return 0;
133 } 136 }
134 137
135 QString 138 QString
136 View::getPropertyValueLabel(const PropertyContainer::PropertyName &name, 139 View::getPropertyValueLabel(const PropertyContainer::PropertyName &name,
137 int value) const 140 int value) const
138 { 141 {
139 if (name == "Follow Playback") { 142 if (name == "Follow Playback") {
140 switch (value) { 143 switch (value) {
141 default: 144 default:
142 case 0: return tr("Scroll"); 145 case 0: return tr("Scroll");
143 case 1: return tr("Page"); 146 case 1: return tr("Page");
144 case 2: return tr("Off"); 147 case 2: return tr("Off");
145 } 148 }
146 } 149 }
147 return tr("<unknown>"); 150 return tr("<unknown>");
148 } 151 }
149 152
150 void 153 void
151 View::setProperty(const PropertyContainer::PropertyName &name, int value) 154 View::setProperty(const PropertyContainer::PropertyName &name, int value)
152 { 155 {
153 if (name == "Global Scroll") { 156 if (name == "Global Scroll") {
154 setFollowGlobalPan(value != 0); 157 setFollowGlobalPan(value != 0);
155 } else if (name == "Global Zoom") { 158 } else if (name == "Global Zoom") {
156 setFollowGlobalZoom(value != 0); 159 setFollowGlobalZoom(value != 0);
157 } else if (name == "Follow Playback") { 160 } else if (name == "Follow Playback") {
158 switch (value) { 161 switch (value) {
159 default: 162 default:
160 case 0: setPlaybackFollow(PlaybackScrollContinuous); break; 163 case 0: setPlaybackFollow(PlaybackScrollContinuous); break;
161 case 1: setPlaybackFollow(PlaybackScrollPageWithCentre); break; 164 case 1: setPlaybackFollow(PlaybackScrollPageWithCentre); break;
162 case 2: setPlaybackFollow(PlaybackIgnore); break; 165 case 2: setPlaybackFollow(PlaybackIgnore); break;
163 } 166 }
164 } 167 }
165 } 168 }
166 169
167 int 170 int
168 View::getPropertyContainerCount() const 171 View::getPropertyContainerCount() const
172 175
173 const PropertyContainer * 176 const PropertyContainer *
174 View::getPropertyContainer(int i) const 177 View::getPropertyContainer(int i) const
175 { 178 {
176 return (const PropertyContainer *)(((View *)this)-> 179 return (const PropertyContainer *)(((View *)this)->
177 getPropertyContainer(i)); 180 getPropertyContainer(i));
178 } 181 }
179 182
180 PropertyContainer * 183 PropertyContainer *
181 View::getPropertyContainer(int i) 184 View::getPropertyContainer(int i)
182 { 185 {
231 if ((*i)->needsTextLabelHeight()) { 234 if ((*i)->needsTextLabelHeight()) {
232 sortedLayers[getObjectExportId(*i)] = *i; 235 sortedLayers[getObjectExportId(*i)] = *i;
233 } 236 }
234 } 237 }
235 238
236 int y = 15 + paint.fontMetrics().ascent(); 239 int y = ViewManager::scalePixelSize(15) + paint.fontMetrics().ascent();
237 240
238 for (std::map<int, Layer *>::const_iterator i = sortedLayers.begin(); 241 for (std::map<int, Layer *>::const_iterator i = sortedLayers.begin();
239 i != sortedLayers.end(); ++i) { 242 i != sortedLayers.end(); ++i) {
240 if (i->second == layer) return y; 243 if (i->second == layer) break;
241 y += paint.fontMetrics().height(); 244 y += paint.fontMetrics().height();
242 } 245 }
243 246
244 return y; 247 return y;
245 } 248 }
248 View::propertyContainerSelected(View *client, PropertyContainer *pc) 251 View::propertyContainerSelected(View *client, PropertyContainer *pc)
249 { 252 {
250 if (client != this) return; 253 if (client != this) return;
251 254
252 if (pc == m_propertyContainer) { 255 if (pc == m_propertyContainer) {
253 if (m_haveSelectedLayer) { 256 if (m_haveSelectedLayer) {
254 m_haveSelectedLayer = false; 257 m_haveSelectedLayer = false;
255 update(); 258 update();
256 } 259 }
257 return; 260 return;
258 } 261 }
259 262
260 delete m_cache; 263 delete m_cache;
261 m_cache = 0; 264 m_cache = 0;
262 265
263 Layer *selectedLayer = 0; 266 Layer *selectedLayer = 0;
264 267
265 for (LayerList::iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) { 268 for (LayerList::iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) {
266 if (*i == pc) { 269 if (*i == pc) {
267 selectedLayer = *i; 270 selectedLayer = *i;
268 m_layerStack.erase(i); 271 m_layerStack.erase(i);
269 break; 272 break;
270 } 273 }
271 } 274 }
272 275
273 if (selectedLayer) { 276 if (selectedLayer) {
274 m_haveSelectedLayer = true; 277 m_haveSelectedLayer = true;
275 m_layerStack.push_back(selectedLayer); 278 m_layerStack.push_back(selectedLayer);
276 update(); 279 update();
277 } else { 280 } else {
278 m_haveSelectedLayer = false; 281 m_haveSelectedLayer = false;
279 } 282 }
280 283
281 emit propertyContainerSelected(pc); 284 emit propertyContainerSelected(pc);
282 } 285 }
283 286
324 { 327 {
325 bool changeVisible = false; 328 bool changeVisible = false;
326 329
327 if (m_centreFrame != f) { 330 if (m_centreFrame != f) {
328 331
329 int formerPixel = int(m_centreFrame / m_zoomLevel); 332 int formerPixel = int(m_centreFrame / m_zoomLevel);
330 333
331 m_centreFrame = f; 334 m_centreFrame = f;
332 335
333 int newPixel = int(m_centreFrame / m_zoomLevel); 336 int newPixel = int(m_centreFrame / m_zoomLevel);
334 337
335 if (newPixel != formerPixel) { 338 if (newPixel != formerPixel) {
336 339
337 #ifdef DEBUG_VIEW_WIDGET_PAINT 340 #ifdef DEBUG_VIEW_WIDGET_PAINT
338 cout << "View(" << this << ")::setCentreFrame: newPixel " << newPixel << ", formerPixel " << formerPixel << endl; 341 cout << "View(" << this << ")::setCentreFrame: newPixel " << newPixel << ", formerPixel " << formerPixel << endl;
339 #endif 342 #endif
340 update(); 343 update();
341 344
342 changeVisible = true; 345 changeVisible = true;
343 } 346 }
344 347
345 if (e) { 348 if (e) {
346 sv_frame_t rf = alignToReference(f); 349 sv_frame_t rf = alignToReference(f);
347 #ifdef DEBUG_VIEW 350 #ifdef DEBUG_VIEW
348 cerr << "View[" << this << "]::setCentreFrame(" << f 351 cerr << "View[" << this << "]::setCentreFrame(" << f
349 << "): emitting centreFrameChanged(" 352 << "): emitting centreFrameChanged("
350 << rf << ")" << endl; 353 << rf << ")" << endl;
378 return frame; 381 return frame;
379 } 382 }
380 383
381 double 384 double
382 View::getYForFrequency(double frequency, 385 View::getYForFrequency(double frequency,
383 double minf, 386 double minf,
384 double maxf, 387 double maxf,
385 bool logarithmic) const 388 bool logarithmic) const
386 { 389 {
387 Profiler profiler("View::getYForFrequency"); 390 Profiler profiler("View::getYForFrequency");
388 391
389 int h = height(); 392 int h = height();
390 393
391 if (logarithmic) { 394 if (logarithmic) {
392 395
393 static double lastminf = 0.0, lastmaxf = 0.0; 396 static double lastminf = 0.0, lastmaxf = 0.0;
394 static double logminf = 0.0, logmaxf = 0.0; 397 static double logminf = 0.0, logmaxf = 0.0;
395 398
396 if (lastminf != minf) { 399 if (lastminf != minf) {
397 lastminf = (minf == 0.0 ? 1.0 : minf); 400 lastminf = (minf == 0.0 ? 1.0 : minf);
398 logminf = log10(minf); 401 logminf = log10(minf);
399 } 402 }
400 if (lastmaxf != maxf) { 403 if (lastmaxf != maxf) {
401 lastmaxf = (maxf < lastminf ? lastminf : maxf); 404 lastmaxf = (maxf < lastminf ? lastminf : maxf);
402 logmaxf = log10(maxf); 405 logmaxf = log10(maxf);
403 } 406 }
404 407
405 if (logminf == logmaxf) return 0; 408 if (logminf == logmaxf) return 0;
406 return h - (h * (log10(frequency) - logminf)) / (logmaxf - logminf); 409 return h - (h * (log10(frequency) - logminf)) / (logmaxf - logminf);
407 410
408 } else { 411 } else {
409 412
410 if (minf == maxf) return 0; 413 if (minf == maxf) return 0;
411 return h - (h * (frequency - minf)) / (maxf - minf); 414 return h - (h * (frequency - minf)) / (maxf - minf);
412 } 415 }
413 } 416 }
414 417
415 double 418 double
416 View::getFrequencyForY(double y, 419 View::getFrequencyForY(double y,
417 double minf, 420 double minf,
418 double maxf, 421 double maxf,
419 bool logarithmic) const 422 bool logarithmic) const
420 { 423 {
421 double h = height(); 424 double h = height();
422 425
423 if (logarithmic) { 426 if (logarithmic) {
424 427
425 static double lastminf = 0.0, lastmaxf = 0.0; 428 static double lastminf = 0.0, lastmaxf = 0.0;
426 static double logminf = 0.0, logmaxf = 0.0; 429 static double logminf = 0.0, logmaxf = 0.0;
427 430
428 if (lastminf != minf) { 431 if (lastminf != minf) {
429 lastminf = (minf == 0.0 ? 1.0 : minf); 432 lastminf = (minf == 0.0 ? 1.0 : minf);
430 logminf = log10(minf); 433 logminf = log10(minf);
431 } 434 }
432 if (lastmaxf != maxf) { 435 if (lastmaxf != maxf) {
433 lastmaxf = (maxf < lastminf ? lastminf : maxf); 436 lastmaxf = (maxf < lastminf ? lastminf : maxf);
434 logmaxf = log10(maxf); 437 logmaxf = log10(maxf);
435 } 438 }
436 439
437 if (logminf == logmaxf) return 0; 440 if (logminf == logmaxf) return 0;
438 return pow(10.0, logminf + ((logmaxf - logminf) * (h - y)) / h); 441 return pow(10.0, logminf + ((logmaxf - logminf) * (h - y)) / h);
439 442
440 } else { 443 } else {
441 444
442 if (minf == maxf) return 0; 445 if (minf == maxf) return 0;
443 return minf + ((h - y) * (maxf - minf)) / h; 446 return minf + ((h - y) * (maxf - minf)) / h;
444 } 447 }
445 } 448 }
446 449
447 ZoomLevel 450 ZoomLevel
448 View::getZoomLevel() const 451 View::getZoomLevel() const
449 { 452 {
450 #ifdef DEBUG_VIEW_WIDGET_PAINT 453 #ifdef DEBUG_VIEW_WIDGET_PAINT
451 // cout << "zoom level: " << m_zoomLevel << endl; 454 // cout << "zoom level: " << m_zoomLevel << endl;
452 #endif 455 #endif
453 return m_zoomLevel; 456 return m_zoomLevel;
454 } 457 }
455 458
456 int 459 int
477 { 480 {
478 int dpratio = effectiveDevicePixelRatio(); 481 int dpratio = effectiveDevicePixelRatio();
479 if (z < dpratio) return; 482 if (z < dpratio) return;
480 if (z < 1) z = 1; 483 if (z < 1) z = 1;
481 if (m_zoomLevel != int(z)) { 484 if (m_zoomLevel != int(z)) {
482 m_zoomLevel = z; 485 m_zoomLevel = z;
483 emit zoomLevelChanged(z, m_followZoom); 486 emit zoomLevelChanged(z, m_followZoom);
484 update(); 487 update();
485 } 488 }
486 } 489 }
487 490
488 bool 491 bool
489 View::hasLightBackground() const 492 View::hasLightBackground() const
506 } else if (s == maxSignificance && !light) { 509 } else if (s == maxSignificance && !light) {
507 mostSignificantHasDarkBackground = true; 510 mostSignificantHasDarkBackground = true;
508 } 511 }
509 } 512 }
510 513
511 if (int(maxSignificance) >= int(Layer::ColourAndBackgroundSignificant)) { 514 if (int(maxSignificance) >= int(Layer::ColourDistinguishes)) {
512 return !mostSignificantHasDarkBackground; 515 return !mostSignificantHasDarkBackground;
513 } else { 516 } else {
514 return !darkPalette; 517 return !darkPalette;
515 } 518 }
516 } 519 }
591 594
592 pb->setFont(f); 595 pb->setFont(f);
593 pb->hide(); 596 pb->hide();
594 597
595 connect(layer, SIGNAL(layerParametersChanged()), 598 connect(layer, SIGNAL(layerParametersChanged()),
596 this, SLOT(layerParametersChanged())); 599 this, SLOT(layerParametersChanged()));
597 connect(layer, SIGNAL(layerParameterRangesChanged()), 600 connect(layer, SIGNAL(layerParameterRangesChanged()),
598 this, SLOT(layerParameterRangesChanged())); 601 this, SLOT(layerParameterRangesChanged()));
599 connect(layer, SIGNAL(layerMeasurementRectsChanged()), 602 connect(layer, SIGNAL(layerMeasurementRectsChanged()),
600 this, SLOT(layerMeasurementRectsChanged())); 603 this, SLOT(layerMeasurementRectsChanged()));
601 connect(layer, SIGNAL(layerNameChanged()), 604 connect(layer, SIGNAL(layerNameChanged()),
602 this, SLOT(layerNameChanged())); 605 this, SLOT(layerNameChanged()));
603 connect(layer, SIGNAL(modelChanged()), 606 connect(layer, SIGNAL(modelChanged()),
604 this, SLOT(modelChanged())); 607 this, SLOT(modelChanged()));
605 connect(layer, SIGNAL(modelCompletionChanged()), 608 connect(layer, SIGNAL(modelCompletionChanged()),
606 this, SLOT(modelCompletionChanged())); 609 this, SLOT(modelCompletionChanged()));
607 connect(layer, SIGNAL(modelAlignmentCompletionChanged()), 610 connect(layer, SIGNAL(modelAlignmentCompletionChanged()),
608 this, SLOT(modelAlignmentCompletionChanged())); 611 this, SLOT(modelAlignmentCompletionChanged()));
609 connect(layer, SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)), 612 connect(layer, SIGNAL(modelChangedWithin(sv_frame_t, sv_frame_t)),
610 this, SLOT(modelChangedWithin(sv_frame_t, sv_frame_t))); 613 this, SLOT(modelChangedWithin(sv_frame_t, sv_frame_t)));
611 connect(layer, SIGNAL(modelReplaced()), 614 connect(layer, SIGNAL(modelReplaced()),
612 this, SLOT(modelReplaced())); 615 this, SLOT(modelReplaced()));
613 616
614 update(); 617 update();
615 618
616 emit propertyContainerAdded(layer); 619 emit propertyContainerAdded(layer);
617 } 620 }
618 621
619 void 622 void
620 View::removeLayer(Layer *layer) 623 View::removeLayer(Layer *layer)
621 { 624 {
622 if (m_deleting) { 625 if (m_deleting) {
623 return; 626 return;
624 } 627 }
625 628
626 delete m_cache; 629 delete m_cache;
627 m_cache = 0; 630 m_cache = 0;
628 631
629 for (LayerList::iterator i = m_fixedOrderLayers.begin(); 632 for (LayerList::iterator i = m_fixedOrderLayers.begin();
630 i != m_fixedOrderLayers.end(); 633 i != m_fixedOrderLayers.end();
631 ++i) { 634 ++i) {
632 if (*i == layer) { 635 if (*i == layer) {
633 m_fixedOrderLayers.erase(i); 636 m_fixedOrderLayers.erase(i);
634 break; 637 break;
635 } 638 }
636 } 639 }
637 640
638 for (LayerList::iterator i = m_layerStack.begin(); 641 for (LayerList::iterator i = m_layerStack.begin();
639 i != m_layerStack.end(); 642 i != m_layerStack.end();
640 ++i) { 643 ++i) {
641 if (*i == layer) { 644 if (*i == layer) {
642 m_layerStack.erase(i); 645 m_layerStack.erase(i);
643 if (m_progressBars.find(layer) != m_progressBars.end()) { 646 if (m_progressBars.find(layer) != m_progressBars.end()) {
644 delete m_progressBars[layer].bar; 647 delete m_progressBars[layer].bar;
645 delete m_progressBars[layer].cancel; 648 delete m_progressBars[layer].cancel;
646 delete m_progressBars[layer].checkTimer; 649 delete m_progressBars[layer].checkTimer;
647 m_progressBars.erase(layer); 650 m_progressBars.erase(layer);
648 } 651 }
649 break; 652 break;
650 } 653 }
651 } 654 }
652 655
653 disconnect(layer, SIGNAL(layerParametersChanged()), 656 disconnect(layer, SIGNAL(layerParametersChanged()),
654 this, SLOT(layerParametersChanged())); 657 this, SLOT(layerParametersChanged()));
655 disconnect(layer, SIGNAL(layerParameterRangesChanged()), 658 disconnect(layer, SIGNAL(layerParameterRangesChanged()),
702 View::getSelectedLayer() 705 View::getSelectedLayer()
703 { 706 {
704 if (m_haveSelectedLayer && !m_layerStack.empty()) { 707 if (m_haveSelectedLayer && !m_layerStack.empty()) {
705 return getLayer(getLayerCount() - 1); 708 return getLayer(getLayerCount() - 1);
706 } else { 709 } else {
707 return 0; 710 return 0;
708 } 711 }
709 } 712 }
710 713
711 const Layer * 714 const Layer *
712 View::getSelectedLayer() const 715 View::getSelectedLayer() const
716 719
717 void 720 void
718 View::setViewManager(ViewManager *manager) 721 View::setViewManager(ViewManager *manager)
719 { 722 {
720 if (m_manager) { 723 if (m_manager) {
721 m_manager->disconnect(this, SLOT(globalCentreFrameChanged(sv_frame_t))); 724 m_manager->disconnect(this, SLOT(globalCentreFrameChanged(sv_frame_t)));
722 m_manager->disconnect(this, SLOT(viewCentreFrameChanged(View *, sv_frame_t))); 725 m_manager->disconnect(this, SLOT(viewCentreFrameChanged(View *, sv_frame_t)));
723 m_manager->disconnect(this, SLOT(viewManagerPlaybackFrameChanged(sv_frame_t))); 726 m_manager->disconnect(this, SLOT(viewManagerPlaybackFrameChanged(sv_frame_t)));
724 m_manager->disconnect(this, SLOT(viewZoomLevelChanged(View *, ZoomLevel, bool))); 727 m_manager->disconnect(this, SLOT(viewZoomLevelChanged(View *, ZoomLevel, bool)));
725 m_manager->disconnect(this, SLOT(toolModeChanged())); 728 m_manager->disconnect(this, SLOT(toolModeChanged()));
726 m_manager->disconnect(this, SLOT(selectionChanged())); 729 m_manager->disconnect(this, SLOT(selectionChanged()));
727 m_manager->disconnect(this, SLOT(overlayModeChanged())); 730 m_manager->disconnect(this, SLOT(overlayModeChanged()));
728 m_manager->disconnect(this, SLOT(zoomWheelsEnabledChanged())); 731 m_manager->disconnect(this, SLOT(zoomWheelsEnabledChanged()));
729 disconnect(m_manager, SLOT(viewCentreFrameChanged(sv_frame_t, bool, PlaybackFollowMode))); 732 disconnect(m_manager, SLOT(viewCentreFrameChanged(sv_frame_t, bool, PlaybackFollowMode)));
730 disconnect(m_manager, SLOT(zoomLevelChanged(ZoomLevel, bool))); 733 disconnect(m_manager, SLOT(zoomLevelChanged(ZoomLevel, bool)));
731 } 734 }
732 735
733 m_manager = manager; 736 m_manager = manager;
734 737
735 connect(m_manager, SIGNAL(globalCentreFrameChanged(sv_frame_t)), 738 connect(m_manager, SIGNAL(globalCentreFrameChanged(sv_frame_t)),
736 this, SLOT(globalCentreFrameChanged(sv_frame_t))); 739 this, SLOT(globalCentreFrameChanged(sv_frame_t)));
737 connect(m_manager, SIGNAL(viewCentreFrameChanged(View *, sv_frame_t)), 740 connect(m_manager, SIGNAL(viewCentreFrameChanged(View *, sv_frame_t)),
738 this, SLOT(viewCentreFrameChanged(View *, sv_frame_t))); 741 this, SLOT(viewCentreFrameChanged(View *, sv_frame_t)));
739 connect(m_manager, SIGNAL(playbackFrameChanged(sv_frame_t)), 742 connect(m_manager, SIGNAL(playbackFrameChanged(sv_frame_t)),
740 this, SLOT(viewManagerPlaybackFrameChanged(sv_frame_t))); 743 this, SLOT(viewManagerPlaybackFrameChanged(sv_frame_t)));
741 744
742 connect(m_manager, SIGNAL(viewZoomLevelChanged(View *, ZoomLevel, bool)), 745 connect(m_manager, SIGNAL(viewZoomLevelChanged(View *, ZoomLevel, bool)),
743 this, SLOT(viewZoomLevelChanged(View *, ZoomLevel, bool))); 746 this, SLOT(viewZoomLevelChanged(View *, ZoomLevel, bool)));
744 747
745 connect(m_manager, SIGNAL(toolModeChanged()), 748 connect(m_manager, SIGNAL(toolModeChanged()),
746 this, SLOT(toolModeChanged())); 749 this, SLOT(toolModeChanged()));
747 connect(m_manager, SIGNAL(selectionChanged()), 750 connect(m_manager, SIGNAL(selectionChanged()),
748 this, SLOT(selectionChanged())); 751 this, SLOT(selectionChanged()));
749 connect(m_manager, SIGNAL(inProgressSelectionChanged()), 752 connect(m_manager, SIGNAL(inProgressSelectionChanged()),
750 this, SLOT(selectionChanged())); 753 this, SLOT(selectionChanged()));
751 connect(m_manager, SIGNAL(overlayModeChanged()), 754 connect(m_manager, SIGNAL(overlayModeChanged()),
752 this, SLOT(overlayModeChanged())); 755 this, SLOT(overlayModeChanged()));
753 connect(m_manager, SIGNAL(showCentreLineChanged()), 756 connect(m_manager, SIGNAL(showCentreLineChanged()),
754 this, SLOT(overlayModeChanged())); 757 this, SLOT(overlayModeChanged()));
755 connect(m_manager, SIGNAL(zoomWheelsEnabledChanged()), 758 connect(m_manager, SIGNAL(zoomWheelsEnabledChanged()),
759 PlaybackFollowMode)), 762 PlaybackFollowMode)),
760 m_manager, SLOT(viewCentreFrameChanged(sv_frame_t, bool, 763 m_manager, SLOT(viewCentreFrameChanged(sv_frame_t, bool,
761 PlaybackFollowMode))); 764 PlaybackFollowMode)));
762 765
763 connect(this, SIGNAL(zoomLevelChanged(ZoomLevel, bool)), 766 connect(this, SIGNAL(zoomLevelChanged(ZoomLevel, bool)),
764 m_manager, SLOT(viewZoomLevelChanged(ZoomLevel, bool))); 767 m_manager, SLOT(viewZoomLevelChanged(ZoomLevel, bool)));
765 768
766 switch (m_followPlay) { 769 switch (m_followPlay) {
767 770
768 case PlaybackScrollPage: 771 case PlaybackScrollPage:
769 case PlaybackScrollPageWithCentre: 772 case PlaybackScrollPageWithCentre:
831 bool recreate = false; 834 bool recreate = false;
832 835
833 bool discard; 836 bool discard;
834 LayerList scrollables = getScrollableBackLayers(false, discard); 837 LayerList scrollables = getScrollableBackLayers(false, discard);
835 for (LayerList::const_iterator i = scrollables.begin(); 838 for (LayerList::const_iterator i = scrollables.begin();
836 i != scrollables.end(); ++i) { 839 i != scrollables.end(); ++i) {
837 if (*i == obj || (*i)->getModel() == obj) { 840 if (*i == obj || (*i)->getModel() == obj) {
838 recreate = true; 841 recreate = true;
839 break; 842 break;
840 } 843 }
841 } 844 }
842 845
843 if (recreate) { 846 if (recreate) {
844 delete m_cache; 847 delete m_cache;
845 m_cache = 0; 848 m_cache = 0;
846 } 849 }
847 850
848 emit layerModelChanged(); 851 emit layerModelChanged();
849 852
850 checkProgress(obj); 853 checkProgress(obj);
863 #ifdef DEBUG_VIEW_WIDGET_PAINT 866 #ifdef DEBUG_VIEW_WIDGET_PAINT
864 cerr << "View(" << this << ")::modelChangedWithin(" << startFrame << "," << endFrame << ") [me " << myStartFrame << "," << myEndFrame << "]" << endl; 867 cerr << "View(" << this << ")::modelChangedWithin(" << startFrame << "," << endFrame << ") [me " << myStartFrame << "," << myEndFrame << "]" << endl;
865 #endif 868 #endif
866 869
867 if (myStartFrame > 0 && endFrame < myStartFrame) { 870 if (myStartFrame > 0 && endFrame < myStartFrame) {
868 checkProgress(obj); 871 checkProgress(obj);
869 return; 872 return;
870 } 873 }
871 if (startFrame > myEndFrame) { 874 if (startFrame > myEndFrame) {
872 checkProgress(obj); 875 checkProgress(obj);
873 return; 876 return;
874 } 877 }
875 878
876 // If the model that has changed is not used by any of the cached 879 // If the model that has changed is not used by any of the cached
877 // layers, we won't need to recreate the cache 880 // layers, we won't need to recreate the cache
878 881
879 bool recreate = false; 882 bool recreate = false;
880 883
881 bool discard; 884 bool discard;
882 LayerList scrollables = getScrollableBackLayers(false, discard); 885 LayerList scrollables = getScrollableBackLayers(false, discard);
883 for (LayerList::const_iterator i = scrollables.begin(); 886 for (LayerList::const_iterator i = scrollables.begin();
884 i != scrollables.end(); ++i) { 887 i != scrollables.end(); ++i) {
885 if (*i == obj || (*i)->getModel() == obj) { 888 if (*i == obj || (*i)->getModel() == obj) {
886 recreate = true; 889 recreate = true;
887 break; 890 break;
888 } 891 }
889 } 892 }
890 893
891 if (recreate) { 894 if (recreate) {
892 delete m_cache; 895 delete m_cache;
893 m_cache = 0; 896 m_cache = 0;
894 } 897 }
895 898
896 if (startFrame < myStartFrame) startFrame = myStartFrame; 899 if (startFrame < myStartFrame) startFrame = myStartFrame;
897 if (endFrame > myEndFrame) endFrame = myEndFrame; 900 if (endFrame > myEndFrame) endFrame = myEndFrame;
898 901
943 delete m_cache; 946 delete m_cache;
944 m_cache = 0; 947 m_cache = 0;
945 update(); 948 update();
946 949
947 if (layer) { 950 if (layer) {
948 emit propertyContainerPropertyChanged(layer); 951 emit propertyContainerPropertyChanged(layer);
949 } 952 }
950 } 953 }
951 954
952 void 955 void
953 View::layerParameterRangesChanged() 956 View::layerParameterRangesChanged()
991 994
992 void 995 void
993 View::viewManagerPlaybackFrameChanged(sv_frame_t f) 996 View::viewManagerPlaybackFrameChanged(sv_frame_t f)
994 { 997 {
995 if (m_manager) { 998 if (m_manager) {
996 if (sender() != m_manager) return; 999 if (sender() != m_manager) return;
997 } 1000 }
998 1001
999 #ifdef DEBUG_VIEW 1002 #ifdef DEBUG_VIEW
1000 cerr << "View::viewManagerPlaybackFrameChanged(" << f << ")" << endl; 1003 cerr << "View::viewManagerPlaybackFrameChanged(" << f << ")" << endl;
1001 #endif 1004 #endif
1026 bool somethingGoingOn = 1029 bool somethingGoingOn =
1027 ((QApplication::mouseButtons() != Qt::NoButton) || 1030 ((QApplication::mouseButtons() != Qt::NoButton) ||
1028 (QApplication::keyboardModifiers() & Qt::AltModifier)); 1031 (QApplication::keyboardModifiers() & Qt::AltModifier));
1029 1032
1030 bool pointerInVisibleArea = 1033 bool pointerInVisibleArea =
1031 long(m_playPointerFrame) >= getStartFrame() && 1034 long(m_playPointerFrame) >= getStartFrame() &&
1032 (m_playPointerFrame < getEndFrame() || 1035 (m_playPointerFrame < getEndFrame() ||
1033 // include old pointer location so we know to refresh when moving out 1036 // include old pointer location so we know to refresh when moving out
1034 oldPlayPointerFrame < getEndFrame()); 1037 oldPlayPointerFrame < getEndFrame());
1035 1038
1036 switch (m_followPlay) { 1039 switch (m_followPlay) {
1037 1040
1038 case PlaybackScrollContinuous: 1041 case PlaybackScrollContinuous:
1039 if (!somethingGoingOn) { 1042 if (!somethingGoingOn) {
1040 setCentreFrame(m_playPointerFrame, false); 1043 setCentreFrame(m_playPointerFrame, false);
1041 } 1044 }
1042 break; 1045 break;
1043 1046
1044 case PlaybackScrollPage: 1047 case PlaybackScrollPage:
1045 case PlaybackScrollPageWithCentre: 1048 case PlaybackScrollPageWithCentre:
1046 1049
1047 if (!pointerInVisibleArea && somethingGoingOn) { 1050 if (!pointerInVisibleArea && somethingGoingOn) {
1112 update(xnew - 4, 0, 9, height()); 1115 update(xnew - 4, 0, 9, height());
1113 } 1116 }
1114 break; 1117 break;
1115 1118
1116 case PlaybackIgnore: 1119 case PlaybackIgnore:
1117 if (m_playPointerFrame >= getStartFrame() && 1120 if (m_playPointerFrame >= getStartFrame() &&
1118 m_playPointerFrame < getEndFrame()) { 1121 m_playPointerFrame < getEndFrame()) {
1119 update(); 1122 update();
1120 } 1123 }
1121 break; 1124 break;
1122 } 1125 }
1123 } 1126 }
1124 1127
1125 void 1128 void
1126 View::viewZoomLevelChanged(View *p, ZoomLevel z, bool locked) 1129 View::viewZoomLevelChanged(View *p, ZoomLevel z, bool locked)
1135 1138
1136 void 1139 void
1137 View::selectionChanged() 1140 View::selectionChanged()
1138 { 1141 {
1139 if (m_selectionCached) { 1142 if (m_selectionCached) {
1140 delete m_cache; 1143 delete m_cache;
1141 m_cache = 0; 1144 m_cache = 0;
1142 m_selectionCached = false; 1145 m_selectionCached = false;
1143 } 1146 }
1144 update(); 1147 update();
1145 } 1148 }
1146 1149
1147 sv_frame_t 1150 sv_frame_t
1168 bool first = true; 1171 bool first = true;
1169 sv_frame_t startFrame = 0; 1172 sv_frame_t startFrame = 0;
1170 1173
1171 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) { 1174 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) {
1172 1175
1173 if ((*i)->getModel() && (*i)->getModel()->isOK()) { 1176 if ((*i)->getModel() && (*i)->getModel()->isOK()) {
1174 1177
1175 sv_frame_t thisStartFrame = (*i)->getModel()->getStartFrame(); 1178 sv_frame_t thisStartFrame = (*i)->getModel()->getStartFrame();
1176 1179
1177 if (first || thisStartFrame < startFrame) { 1180 if (first || thisStartFrame < startFrame) {
1178 startFrame = thisStartFrame; 1181 startFrame = thisStartFrame;
1179 } 1182 }
1180 first = false; 1183 first = false;
1181 } 1184 }
1182 } 1185 }
1183 return startFrame; 1186 return startFrame;
1184 } 1187 }
1185 1188
1186 sv_frame_t 1189 sv_frame_t
1189 bool first = true; 1192 bool first = true;
1190 sv_frame_t endFrame = 0; 1193 sv_frame_t endFrame = 0;
1191 1194
1192 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) { 1195 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) {
1193 1196
1194 if ((*i)->getModel() && (*i)->getModel()->isOK()) { 1197 if ((*i)->getModel() && (*i)->getModel()->isOK()) {
1195 1198
1196 sv_frame_t thisEndFrame = (*i)->getModel()->getEndFrame(); 1199 sv_frame_t thisEndFrame = (*i)->getModel()->getEndFrame();
1197 1200
1198 if (first || thisEndFrame > endFrame) { 1201 if (first || thisEndFrame > endFrame) {
1199 endFrame = thisEndFrame; 1202 endFrame = thisEndFrame;
1200 } 1203 }
1201 first = false; 1204 first = false;
1202 } 1205 }
1203 } 1206 }
1204 1207
1205 if (first) return getModelsStartFrame(); 1208 if (first) return getModelsStartFrame();
1206 return endFrame; 1209 return endFrame;
1207 } 1210 }
1214 // conversion in the model 1217 // conversion in the model
1215 1218
1216 //!!! nah, this wants to always return the sr of the main model! 1219 //!!! nah, this wants to always return the sr of the main model!
1217 1220
1218 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) { 1221 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) {
1219 if ((*i)->getModel() && (*i)->getModel()->isOK()) { 1222 if ((*i)->getModel() && (*i)->getModel()->isOK()) {
1220 return (*i)->getModel()->getSampleRate(); 1223 return (*i)->getModel()->getSampleRate();
1221 } 1224 }
1222 } 1225 }
1223 return 0; 1226 return 0;
1224 } 1227 }
1225 1228
1226 View::ModelSet 1229 View::ModelSet
1321 bool 1324 bool
1322 View::areLayersScrollable() const 1325 View::areLayersScrollable() const
1323 { 1326 {
1324 // True iff all views are scrollable 1327 // True iff all views are scrollable
1325 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) { 1328 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) {
1326 if (!(*i)->isLayerScrollable(this)) return false; 1329 if (!(*i)->isLayerScrollable(this)) return false;
1327 } 1330 }
1328 return true; 1331 return true;
1329 } 1332 }
1330 1333
1331 View::LayerList 1334 View::LayerList
1342 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) { 1345 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) {
1343 // SVDEBUG << "View::getScrollableBackLayers: calling isLayerDormant on layer " << *i << endl; 1346 // SVDEBUG << "View::getScrollableBackLayers: calling isLayerDormant on layer " << *i << endl;
1344 // cerr << "(name is " << (*i)->objectName() << ")" 1347 // cerr << "(name is " << (*i)->objectName() << ")"
1345 // << endl; 1348 // << endl;
1346 // SVDEBUG << "View::getScrollableBackLayers: I am " << this << endl; 1349 // SVDEBUG << "View::getScrollableBackLayers: I am " << this << endl;
1347 if ((*i)->isLayerDormant(this)) continue; 1350 if ((*i)->isLayerDormant(this)) continue;
1348 if ((*i)->isLayerOpaque()) { 1351 if ((*i)->isLayerOpaque()) {
1349 // You can't see anything behind an opaque layer! 1352 // You can't see anything behind an opaque layer!
1350 scrollables.clear(); 1353 scrollables.clear();
1351 if (metUnscrollable) break; 1354 if (metUnscrollable) break;
1352 } 1355 }
1353 if (!metUnscrollable && (*i)->isLayerScrollable(this)) { 1356 if (!metUnscrollable && (*i)->isLayerScrollable(this)) {
1354 scrollables.push_back(*i); 1357 scrollables.push_back(*i);
1355 } else { 1358 } else {
1356 metUnscrollable = true; 1359 metUnscrollable = true;
1357 } 1360 }
1358 } 1361 }
1359 1362
1360 if (testChanged && scrollables != m_lastScrollableBackLayers) { 1363 if (testChanged && scrollables != m_lastScrollableBackLayers) {
1361 m_lastScrollableBackLayers = scrollables; 1364 m_lastScrollableBackLayers = scrollables;
1362 changed = true; 1365 changed = true;
1363 } 1366 }
1364 return scrollables; 1367 return scrollables;
1365 } 1368 }
1366 1369
1367 View::LayerList 1370 View::LayerList
1374 // should also be considered non-scrollable 1377 // should also be considered non-scrollable
1375 1378
1376 bool started = false; 1379 bool started = false;
1377 1380
1378 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) { 1381 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) {
1379 if ((*i)->isLayerDormant(this)) continue; 1382 if ((*i)->isLayerDormant(this)) continue;
1380 if (!started && (*i)->isLayerScrollable(this)) { 1383 if (!started && (*i)->isLayerScrollable(this)) {
1381 continue; 1384 continue;
1382 } 1385 }
1383 started = true; 1386 started = true;
1384 if ((*i)->isLayerOpaque()) { 1387 if ((*i)->isLayerOpaque()) {
1385 // You can't see anything behind an opaque layer! 1388 // You can't see anything behind an opaque layer!
1386 nonScrollables.clear(); 1389 nonScrollables.clear();
1387 } 1390 }
1388 nonScrollables.push_back(*i); 1391 nonScrollables.push_back(*i);
1389 } 1392 }
1390 1393
1391 if (testChanged && nonScrollables != m_lastNonScrollableBackLayers) { 1394 if (testChanged && nonScrollables != m_lastNonScrollableBackLayers) {
1392 m_lastNonScrollableBackLayers = nonScrollables; 1395 m_lastNonScrollableBackLayers = nonScrollables;
1393 changed = true; 1396 changed = true;
1394 } 1397 }
1395 1398
1396 return nonScrollables; 1399 return nonScrollables;
1397 } 1400 }
1398 1401
1399 int 1402 int
1400 View::getZoomConstraintBlockSize(int blockSize, 1403 View::getZoomConstraintBlockSize(int blockSize,
1401 ZoomConstraint::RoundingDirection dir) 1404 ZoomConstraint::RoundingDirection dir)
1402 const 1405 const
1403 { 1406 {
1404 int candidate = blockSize; 1407 int candidate = blockSize;
1405 bool haveCandidate = false; 1408 bool haveCandidate = false;
1406 1409
1407 PowerOfSqrtTwoZoomConstraint defaultZoomConstraint; 1410 PowerOfSqrtTwoZoomConstraint defaultZoomConstraint;
1408 1411
1409 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) { 1412 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) {
1410 1413
1411 const ZoomConstraint *zoomConstraint = (*i)->getZoomConstraint(); 1414 const ZoomConstraint *zoomConstraint = (*i)->getZoomConstraint();
1412 if (!zoomConstraint) zoomConstraint = &defaultZoomConstraint; 1415 if (!zoomConstraint) zoomConstraint = &defaultZoomConstraint;
1413 1416
1414 int thisBlockSize = 1417 int thisBlockSize =
1415 zoomConstraint->getNearestBlockSize(blockSize, dir); 1418 zoomConstraint->getNearestBlockSize(blockSize, dir);
1416 1419
1417 // Go for the block size that's furthest from the one 1420 // Go for the block size that's furthest from the one
1418 // passed in. Most of the time, that's what we want. 1421 // passed in. Most of the time, that's what we want.
1419 if (!haveCandidate || 1422 if (!haveCandidate ||
1420 (thisBlockSize > blockSize && thisBlockSize > candidate) || 1423 (thisBlockSize > blockSize && thisBlockSize > candidate) ||
1421 (thisBlockSize < blockSize && thisBlockSize < candidate)) { 1424 (thisBlockSize < blockSize && thisBlockSize < candidate)) {
1422 candidate = thisBlockSize; 1425 candidate = thisBlockSize;
1423 haveCandidate = true; 1426 haveCandidate = true;
1424 } 1427 }
1425 } 1428 }
1426 1429
1427 return candidate; 1430 return candidate;
1428 } 1431 }
1429 1432
1430 bool 1433 bool
1431 View::areLayerColoursSignificant() const 1434 View::areLayerColoursSignificant() const
1432 { 1435 {
1433 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) { 1436 for (LayerList::const_iterator i = m_layerStack.begin(); i != m_layerStack.end(); ++i) {
1434 if ((*i)->getLayerColourSignificance() == 1437 if ((*i)->getLayerColourSignificance() ==
1435 Layer::ColourHasMeaningfulValue) return true; 1438 Layer::ColourHasMeaningfulValue) return true;
1436 if ((*i)->isLayerOpaque()) break; 1439 if ((*i)->isLayerOpaque()) break;
1437 } 1440 }
1438 return false; 1441 return false;
1439 } 1442 }
1451 View::zoom(bool in) 1454 View::zoom(bool in)
1452 { 1455 {
1453 ZoomLevel newZoomLevel = m_zoomLevel; 1456 ZoomLevel newZoomLevel = m_zoomLevel;
1454 1457
1455 if (in) { 1458 if (in) {
1456 newZoomLevel = getZoomConstraintLevel(m_zoomLevel.decremented(), 1459 newZoomLevel = getZoomConstraintLevel(m_zoomLevel.decremented(),
1457 ZoomConstraint::RoundDown); 1460 ZoomConstraint::RoundDown);
1458 } else { 1461 } else {
1459 newZoomLevel = getZoomConstraintLevel(m_zoomLevel.incremented(), 1462 newZoomLevel = getZoomConstraintLevel(m_zoomLevel.incremented(),
1460 ZoomConstraint::RoundUp); 1463 ZoomConstraint::RoundUp);
1461 } 1464 }
1462 1465
1463 if (newZoomLevel != m_zoomLevel) { 1466 if (newZoomLevel != m_zoomLevel) {
1464 setZoomLevel(newZoomLevel); 1467 setZoomLevel(newZoomLevel);
1465 } 1468 }
1466 } 1469 }
1467 1470
1468 void 1471 void
1469 View::scroll(bool right, bool lots, bool e) 1472 View::scroll(bool right, bool lots, bool e)
1470 { 1473 {
1471 sv_frame_t delta; 1474 sv_frame_t delta;
1472 if (lots) { 1475 if (lots) {
1473 delta = (getEndFrame() - getStartFrame()) / 2; 1476 delta = (getEndFrame() - getStartFrame()) / 2;
1474 } else { 1477 } else {
1475 delta = (getEndFrame() - getStartFrame()) / 20; 1478 delta = (getEndFrame() - getStartFrame()) / 20;
1476 } 1479 }
1477 if (right) delta = -delta; 1480 if (right) delta = -delta;
1478 1481
1479 if (m_centreFrame < delta) { 1482 if (m_centreFrame < delta) {
1480 setCentreFrame(0, e); 1483 setCentreFrame(0, e);
1481 } else if (m_centreFrame - delta >= getModelsEndFrame()) { 1484 } else if (m_centreFrame - delta >= getModelsEndFrame()) {
1482 setCentreFrame(getModelsEndFrame(), e); 1485 setCentreFrame(getModelsEndFrame(), e);
1483 } else { 1486 } else {
1484 setCentreFrame(m_centreFrame - delta, e); 1487 setCentreFrame(m_centreFrame - delta, e);
1485 } 1488 }
1486 } 1489 }
1487 1490
1488 void 1491 void
1489 View::cancelClicked() 1492 View::cancelClicked()
1490 { 1493 {
1491 QPushButton *cancel = qobject_cast<QPushButton *>(sender()); 1494 QPushButton *cancel = qobject_cast<QPushButton *>(sender());
1492 if (!cancel) return; 1495 if (!cancel) return;
1493 1496
1494 for (ProgressMap::iterator i = m_progressBars.begin(); 1497 for (ProgressMap::iterator i = m_progressBars.begin();
1495 i != m_progressBars.end(); ++i) { 1498 i != m_progressBars.end(); ++i) {
1496 1499
1497 if (i->second.cancel == cancel) { 1500 if (i->second.cancel == cancel) {
1498 1501
1499 Layer *layer = i->first; 1502 Layer *layer = i->first;
1500 Model *model = layer->getModel(); 1503 Model *model = layer->getModel();
1510 if (!m_showProgress) return; 1513 if (!m_showProgress) return;
1511 1514
1512 int ph = height(); 1515 int ph = height();
1513 1516
1514 for (ProgressMap::iterator i = m_progressBars.begin(); 1517 for (ProgressMap::iterator i = m_progressBars.begin();
1515 i != m_progressBars.end(); ++i) { 1518 i != m_progressBars.end(); ++i) {
1516 1519
1517 QProgressBar *pb = i->second.bar; 1520 QProgressBar *pb = i->second.bar;
1518 QPushButton *cancel = i->second.cancel; 1521 QPushButton *cancel = i->second.cancel;
1519 1522
1520 if (i->first == object) { 1523 if (i->first == object) {
1521 1524
1522 // The timer is used to test for stalls. If the progress 1525 // The timer is used to test for stalls. If the progress
1523 // bar does not get updated for some length of time, the 1526 // bar does not get updated for some length of time, the
1524 // timer prompts it to go back into "indeterminate" mode 1527 // timer prompts it to go back into "indeterminate" mode
1525 QTimer *timer = i->second.checkTimer; 1528 QTimer *timer = i->second.checkTimer;
1526 1529
1527 int completion = i->first->getCompletion(this); 1530 int completion = i->first->getCompletion(this);
1528 QString text = i->first->getPropertyContainerName(); 1531 QString text = i->first->getPropertyContainerName();
1529 QString error = i->first->getError(this); 1532 QString error = i->first->getError(this);
1530 1533
1531 if (error != "" && error != m_lastError) { 1534 if (error != "" && error != m_lastError) {
1532 QMessageBox::critical(this, tr("Layer rendering error"), error); 1535 QMessageBox::critical(this, tr("Layer rendering error"), error);
1557 1560
1558 } else if (wfm) { 1561 } else if (wfm) {
1559 update(); // ensure duration &c gets updated 1562 update(); // ensure duration &c gets updated
1560 } 1563 }
1561 1564
1562 if (completion >= 100) { 1565 if (completion >= 100) {
1563 1566
1564 pb->hide(); 1567 pb->hide();
1565 cancel->hide(); 1568 cancel->hide();
1566 timer->stop(); 1569 timer->stop();
1567 1570
1568 } else { 1571 } else {
1569 1572
1570 // cerr << "progress = " << completion << endl; 1573 // cerr << "progress = " << completion << endl;
1571 1574
1572 if (!pb->isVisible()) { 1575 if (!pb->isVisible()) {
1573 i->second.lastCheck = 0; 1576 i->second.lastCheck = 0;
1576 } 1579 }
1577 1580
1578 cancel->move(0, ph - pb->height()/2 - 10); 1581 cancel->move(0, ph - pb->height()/2 - 10);
1579 cancel->show(); 1582 cancel->show();
1580 1583
1581 pb->setValue(completion); 1584 pb->setValue(completion);
1582 pb->move(20, ph - pb->height()); 1585 pb->move(20, ph - pb->height());
1583 1586
1584 pb->show(); 1587 pb->show();
1585 pb->update(); 1588 pb->update();
1586 1589
1587 ph -= pb->height(); 1590 ph -= pb->height();
1588 } 1591 }
1589 } else { 1592 } else {
1590 if (pb->isVisible()) { 1593 if (pb->isVisible()) {
1591 ph -= pb->height(); 1594 ph -= pb->height();
1592 } 1595 }
1593 } 1596 }
1594 } 1597 }
1595 } 1598 }
1596 1599
1597 void 1600 void
1598 View::progressCheckStalledTimerElapsed() 1601 View::progressCheckStalledTimerElapsed()
1615 1618
1616 int 1619 int
1617 View::getProgressBarWidth() const 1620 View::getProgressBarWidth() const
1618 { 1621 {
1619 for (ProgressMap::const_iterator i = m_progressBars.begin(); 1622 for (ProgressMap::const_iterator i = m_progressBars.begin();
1620 i != m_progressBars.end(); ++i) { 1623 i != m_progressBars.end(); ++i) {
1621 if (i->second.bar && i->second.bar->isVisible()) { 1624 if (i->second.bar && i->second.bar->isVisible()) {
1622 return i->second.bar->width(); 1625 return i->second.bar->width();
1623 } 1626 }
1624 } 1627 }
1625 1628
1655 { 1658 {
1656 // Profiler prof("View::paintEvent", false); 1659 // Profiler prof("View::paintEvent", false);
1657 // cerr << "View::paintEvent: centre frame is " << m_centreFrame << endl; 1660 // cerr << "View::paintEvent: centre frame is " << m_centreFrame << endl;
1658 1661
1659 if (m_layerStack.empty()) { 1662 if (m_layerStack.empty()) {
1660 QFrame::paintEvent(e); 1663 QFrame::paintEvent(e);
1661 return; 1664 return;
1662 } 1665 }
1663 1666
1664 // ensure our constraints are met 1667 // ensure our constraints are met
1665 1668
1666 /*!!! Should we do this only if we have layers that can't support other 1669 /*!!! Should we do this only if we have layers that can't support other
1667 zoom levels? 1670 zoom levels?
1668 1671
1669 m_zoomLevel = getZoomConstraintBlockSize(m_zoomLevel, 1672 m_zoomLevel = getZoomConstraintBlockSize(m_zoomLevel,
1670 ZoomConstraint::RoundUp); 1673 ZoomConstraint::RoundUp);
1671 */ 1674 */
1672 1675
1673 QPainter paint; 1676 QPainter paint;
1674 bool repaintCache = false; 1677 bool repaintCache = false;
1675 bool paintedCacheRect = false; 1678 bool paintedCacheRect = false;
1676 1679
1677 QRect cacheRect(rect()); 1680 QRect cacheRect(rect());
1678 1681
1679 if (e) { 1682 if (e) {
1680 cacheRect &= e->rect(); 1683 cacheRect &= e->rect();
1681 #ifdef DEBUG_VIEW_WIDGET_PAINT 1684 #ifdef DEBUG_VIEW_WIDGET_PAINT
1682 cerr << "paint rect " << cacheRect.width() << "x" << cacheRect.height() 1685 cerr << "paint rect " << cacheRect.width() << "x" << cacheRect.height()
1683 << ", my rect " << width() << "x" << height() << endl; 1686 << ", my rect " << width() << "x" << height() << endl;
1684 #endif 1687 #endif
1685 } 1688 }
1686 1689
1687 QRect nonCacheRect(cacheRect); 1690 QRect nonCacheRect(cacheRect);
1688 1691
1729 selectionCacheable = false; 1732 selectionCacheable = false;
1730 } 1733 }
1731 1734
1732 #ifdef DEBUG_VIEW_WIDGET_PAINT 1735 #ifdef DEBUG_VIEW_WIDGET_PAINT
1733 cerr << "View(" << this << ")::paintEvent: have " << scrollables.size() 1736 cerr << "View(" << this << ")::paintEvent: have " << scrollables.size()
1734 << " scrollable back layers and " << nonScrollables.size() 1737 << " scrollable back layers and " << nonScrollables.size()
1735 << " non-scrollable front layers" << endl; 1738 << " non-scrollable front layers" << endl;
1736 cerr << "haveSelections " << haveSelections << ", selectionCacheable " 1739 cerr << "haveSelections " << haveSelections << ", selectionCacheable "
1737 << selectionCacheable << ", m_selectionCached " << m_selectionCached << endl; 1740 << selectionCacheable << ", m_selectionCached " << m_selectionCached << endl;
1738 #endif 1741 #endif
1739 1742
1740 if (layersChanged || scrollables.empty() || 1743 if (layersChanged || scrollables.empty() ||
1741 (haveSelections && (selectionCacheable != m_selectionCached))) { 1744 (haveSelections && (selectionCacheable != m_selectionCached))) {
1742 delete m_cache; 1745 delete m_cache;
1743 m_cache = 0; 1746 m_cache = 0;
1744 m_selectionCached = false; 1747 m_selectionCached = false;
1745 } 1748 }
1746 1749
1747 QSize scaledCacheSize(scaledSize(size(), dpratio)); 1750 QSize scaledCacheSize(scaledSize(size(), dpratio));
1748 QRect scaledCacheRect(scaledRect(cacheRect, dpratio)); 1751 QRect scaledCacheRect(scaledRect(cacheRect, dpratio));
1749 1752
1757 #ifdef DEBUG_VIEW_WIDGET_PAINT 1760 #ifdef DEBUG_VIEW_WIDGET_PAINT
1758 cerr << "View(" << this << "): cache " << m_cache << ", cache zoom " 1761 cerr << "View(" << this << "): cache " << m_cache << ", cache zoom "
1759 << m_cacheZoomLevel << ", zoom " << m_zoomLevel << endl; 1762 << m_cacheZoomLevel << ", zoom " << m_zoomLevel << endl;
1760 #endif 1763 #endif
1761 1764
1762 if (!m_cache || 1765 if (!m_cache ||
1763 m_cacheZoomLevel != m_zoomLevel || 1766 m_cacheZoomLevel != m_zoomLevel ||
1764 scaledCacheSize != m_cache->size()) { 1767 scaledCacheSize != m_cache->size()) {
1765 1768
1766 // cache is not valid 1769 // cache is not valid
1767 1770
1768 if (cacheRect.width() < width()/10) { 1771 if (cacheRect.width() < width()/10) {
1769 delete m_cache; 1772 delete m_cache;
1770 m_cache = 0; 1773 m_cache = 0;
1771 #ifdef DEBUG_VIEW_WIDGET_PAINT 1774 #ifdef DEBUG_VIEW_WIDGET_PAINT
1772 cerr << "View(" << this << ")::paintEvent: small repaint, not bothering to recreate cache" << endl; 1775 cerr << "View(" << this << ")::paintEvent: small repaint, not bothering to recreate cache" << endl;
1773 #endif 1776 #endif
1774 } else { 1777 } else {
1775 delete m_cache; 1778 delete m_cache;
1776 m_cache = new QPixmap(scaledCacheSize); 1779 m_cache = new QPixmap(scaledCacheSize);
1777 #ifdef DEBUG_VIEW_WIDGET_PAINT 1780 #ifdef DEBUG_VIEW_WIDGET_PAINT
1778 cerr << "View(" << this << ")::paintEvent: recreated cache" << endl; 1781 cerr << "View(" << this << ")::paintEvent: recreated cache" << endl;
1779 #endif 1782 #endif
1780 cacheRect = rect(); 1783 cacheRect = rect();
1781 repaintCache = true; 1784 repaintCache = true;
1782 } 1785 }
1783 1786
1784 } else if (m_cacheCentreFrame != m_centreFrame) { 1787 } else if (m_cacheCentreFrame != m_centreFrame) {
1785 1788
1786 int dx = 1789 int dx =
1787 getXForFrame(m_cacheCentreFrame) - 1790 getXForFrame(m_cacheCentreFrame) -
1788 getXForFrame(m_centreFrame); 1791 getXForFrame(m_centreFrame);
1789 1792
1790 if (dx > -width() && dx < width()) { 1793 if (dx > -width() && dx < width()) {
1791 static QPixmap *tmpPixmap = 0; 1794 static QPixmap *tmpPixmap = 0;
1792 if (!tmpPixmap || tmpPixmap->size() != scaledCacheSize) { 1795 if (!tmpPixmap || tmpPixmap->size() != scaledCacheSize) {
1793 delete tmpPixmap; 1796 delete tmpPixmap;
1794 tmpPixmap = new QPixmap(scaledCacheSize); 1797 tmpPixmap = new QPixmap(scaledCacheSize);
1795 } 1798 }
1796 paint.begin(tmpPixmap); 1799 paint.begin(tmpPixmap);
1797 paint.drawPixmap(0, 0, *m_cache); 1800 paint.drawPixmap(0, 0, *m_cache);
1798 paint.end(); 1801 paint.end();
1799 paint.begin(m_cache); 1802 paint.begin(m_cache);
1800 paint.drawPixmap(dx, 0, *tmpPixmap); 1803 paint.drawPixmap(dx, 0, *tmpPixmap);
1801 paint.end(); 1804 paint.end();
1802 if (dx < 0) { 1805 if (dx < 0) {
1803 cacheRect = QRect(width() + dx, 0, -dx, height()); 1806 cacheRect = QRect(width() + dx, 0, -dx, height());
1804 } else { 1807 } else {
1805 cacheRect = QRect(0, 0, dx, height()); 1808 cacheRect = QRect(0, 0, dx, height());
1806 } 1809 }
1807 #ifdef DEBUG_VIEW_WIDGET_PAINT 1810 #ifdef DEBUG_VIEW_WIDGET_PAINT
1808 cerr << "View(" << this << ")::paintEvent: scrolled cache by " << dx << endl; 1811 cerr << "View(" << this << ")::paintEvent: scrolled cache by " << dx << endl;
1809 #endif 1812 #endif
1810 } else { 1813 } else {
1811 cacheRect = rect(); 1814 cacheRect = rect();
1812 #ifdef DEBUG_VIEW_WIDGET_PAINT 1815 #ifdef DEBUG_VIEW_WIDGET_PAINT
1813 cerr << "View(" << this << ")::paintEvent: scrolling too far" << endl; 1816 cerr << "View(" << this << ")::paintEvent: scrolling too far" << endl;
1814 #endif 1817 #endif
1815 } 1818 }
1816 repaintCache = true; 1819 repaintCache = true;
1817 1820
1818 } else { 1821 } else {
1819 #ifdef DEBUG_VIEW_WIDGET_PAINT 1822 #ifdef DEBUG_VIEW_WIDGET_PAINT
1820 cerr << "View(" << this << ")::paintEvent: cache is good" << endl; 1823 cerr << "View(" << this << ")::paintEvent: cache is good" << endl;
1821 #endif 1824 #endif
1822 paint.begin(m_buffer); 1825 paint.begin(m_buffer);
1823 paint.drawPixmap(scaledCacheRect, *m_cache, scaledCacheRect); 1826 paint.drawPixmap(scaledCacheRect, *m_cache, scaledCacheRect);
1824 paint.end(); 1827 paint.end();
1825 QFrame::paintEvent(e); 1828 QFrame::paintEvent(e);
1826 paintedCacheRect = true; 1829 paintedCacheRect = true;
1827 } 1830 }
1828 1831
1829 m_cacheCentreFrame = m_centreFrame; 1832 m_cacheCentreFrame = m_centreFrame;
1830 m_cacheZoomLevel = m_zoomLevel; 1833 m_cacheZoomLevel = m_zoomLevel;
1831 } 1834 }
1832 1835
1833 #ifdef DEBUG_VIEW_WIDGET_PAINT 1836 #ifdef DEBUG_VIEW_WIDGET_PAINT
1834 // cerr << "View(" << this << ")::paintEvent: cacheRect " << cacheRect << ", nonCacheRect " << (nonCacheRect | cacheRect) << ", repaintCache " << repaintCache << ", paintedCacheRect " << paintedCacheRect << endl; 1837 // cerr << "View(" << this << ")::paintEvent: cacheRect " << cacheRect << ", nonCacheRect " << (nonCacheRect | cacheRect) << ", repaintCache " << repaintCache << ", paintedCacheRect " << paintedCacheRect << endl;
1835 #endif 1838 #endif
1840 1843
1841 if (!paintedCacheRect) { 1844 if (!paintedCacheRect) {
1842 1845
1843 QRect rectToPaint; 1846 QRect rectToPaint;
1844 1847
1845 if (repaintCache) { 1848 if (repaintCache) {
1846 paint.begin(m_cache); 1849 paint.begin(m_cache);
1847 rectToPaint = scaledCacheRect; 1850 rectToPaint = scaledCacheRect;
1848 } else { 1851 } else {
1849 paint.begin(m_buffer); 1852 paint.begin(m_buffer);
1850 rectToPaint = scaledCacheRect; 1853 rectToPaint = scaledCacheRect;
1851 } 1854 }
1852 1855
1853 setPaintFont(paint); 1856 setPaintFont(paint);
1854 paint.setClipRect(rectToPaint); 1857 paint.setClipRect(rectToPaint);
1855 1858
1856 paint.setPen(getBackground()); 1859 paint.setPen(getBackground());
1857 paint.setBrush(getBackground()); 1860 paint.setBrush(getBackground());
1858 paint.drawRect(rectToPaint); 1861 paint.drawRect(rectToPaint);
1859 1862
1860 paint.setPen(getForeground()); 1863 paint.setPen(getForeground());
1861 paint.setBrush(Qt::NoBrush); 1864 paint.setBrush(Qt::NoBrush);
1862 1865
1863 for (LayerList::iterator i = scrollables.begin(); i != scrollables.end(); ++i) { 1866 for (LayerList::iterator i = scrollables.begin(); i != scrollables.end(); ++i) {
1864 paint.setRenderHint(QPainter::Antialiasing, false); 1867 paint.setRenderHint(QPainter::Antialiasing, false);
1865 paint.save(); 1868 paint.save();
1866 #ifdef DEBUG_VIEW_WIDGET_PAINT 1869 #ifdef DEBUG_VIEW_WIDGET_PAINT
1867 cerr << "Painting scrollable layer " << *i << " using proxy with repaintCache = " << repaintCache << ", dpratio = " << dpratio << ", rectToPaint = " << rectToPaint.x() << "," << rectToPaint.y() << " " << rectToPaint.width() << "x" << rectToPaint.height() << endl; 1870 cerr << "Painting scrollable layer " << *i << " using proxy with repaintCache = " << repaintCache << ", dpratio = " << dpratio << ", rectToPaint = " << rectToPaint.x() << "," << rectToPaint.y() << " " << rectToPaint.width() << "x" << rectToPaint.height() << endl;
1868 #endif 1871 #endif
1869 (*i)->paint(&proxy, paint, rectToPaint); 1872 (*i)->paint(&proxy, paint, rectToPaint);
1870 paint.restore(); 1873 paint.restore();
1871 } 1874 }
1872 1875
1873 if (haveSelections && selectionCacheable) { 1876 if (haveSelections && selectionCacheable) {
1874 drawSelections(paint); 1877 drawSelections(paint);
1875 m_selectionCached = repaintCache; 1878 m_selectionCached = repaintCache;
1876 } 1879 }
1877 1880
1878 paint.end(); 1881 paint.end();
1879 1882
1880 if (repaintCache) { 1883 if (repaintCache) {
1881 cacheRect |= (e ? e->rect() : rect()); 1884 cacheRect |= (e ? e->rect() : rect());
1882 scaledCacheRect = scaledRect(cacheRect, dpratio); 1885 scaledCacheRect = scaledRect(cacheRect, dpratio);
1883 paint.begin(m_buffer); 1886 paint.begin(m_buffer);
1884 paint.drawPixmap(scaledCacheRect, *m_cache, scaledCacheRect); 1887 paint.drawPixmap(scaledCacheRect, *m_cache, scaledCacheRect);
1885 paint.end(); 1888 paint.end();
1886 } 1889 }
1887 } 1890 }
1888 1891
1889 // Now non-cacheable items. We always need to redraw the 1892 // Now non-cacheable items. We always need to redraw the
1890 // non-cacheable items across at least the area we drew of the 1893 // non-cacheable items across at least the area we drew of the
1891 // cacheable items. 1894 // cacheable items.
1898 paint.setClipRect(scaledNonCacheRect); 1901 paint.setClipRect(scaledNonCacheRect);
1899 setPaintFont(paint); 1902 setPaintFont(paint);
1900 if (scrollables.empty()) { 1903 if (scrollables.empty()) {
1901 paint.setPen(getBackground()); 1904 paint.setPen(getBackground());
1902 paint.setBrush(getBackground()); 1905 paint.setBrush(getBackground());
1903 paint.drawRect(scaledNonCacheRect); 1906 paint.drawRect(scaledNonCacheRect);
1904 } 1907 }
1905 1908
1906 paint.setPen(getForeground()); 1909 paint.setPen(getForeground());
1907 paint.setBrush(Qt::NoBrush); 1910 paint.setBrush(Qt::NoBrush);
1908 1911
1909 for (LayerList::iterator i = nonScrollables.begin(); i != nonScrollables.end(); ++i) { 1912 for (LayerList::iterator i = nonScrollables.begin(); i != nonScrollables.end(); ++i) {
1910 // Profiler profiler2("View::paintEvent non-cacheable"); 1913 // Profiler profiler2("View::paintEvent non-cacheable");
1911 #ifdef DEBUG_VIEW_WIDGET_PAINT 1914 #ifdef DEBUG_VIEW_WIDGET_PAINT
1912 cerr << "Painting non-scrollable layer " << *i << " without proxy with repaintCache = " << repaintCache << ", dpratio = " << dpratio << ", rectToPaint = " << nonCacheRect.x() << "," << nonCacheRect.y() << " " << nonCacheRect.width() << "x" << nonCacheRect.height() << endl; 1915 cerr << "Painting non-scrollable layer " << *i << " without proxy with repaintCache = " << repaintCache << ", dpratio = " << dpratio << ", rectToPaint = " << nonCacheRect.x() << "," << nonCacheRect.y() << " " << nonCacheRect.width() << "x" << nonCacheRect.height() << endl;
1913 #endif 1916 #endif
1914 (*i)->paint(&proxy, paint, scaledNonCacheRect); 1917 (*i)->paint(&proxy, paint, scaledNonCacheRect);
1915 } 1918 }
1916 1919
1917 paint.end(); 1920 paint.end();
1918 1921
1919 paint.begin(this); 1922 paint.begin(this);
1920 QRect finalPaintRect = e ? e->rect() : rect(); 1923 QRect finalPaintRect = e ? e->rect() : rect();
1921 paint.drawPixmap(finalPaintRect, *m_buffer, scaledRect(finalPaintRect, dpratio)); 1924 paint.drawPixmap(finalPaintRect, *m_buffer, scaledRect(finalPaintRect, dpratio));
1923 1926
1924 paint.begin(this); 1927 paint.begin(this);
1925 setPaintFont(paint); 1928 setPaintFont(paint);
1926 if (e) paint.setClipRect(e->rect()); 1929 if (e) paint.setClipRect(e->rect());
1927 if (!m_selectionCached) { 1930 if (!m_selectionCached) {
1928 drawSelections(paint); 1931 drawSelections(paint);
1929 } 1932 }
1930 paint.end(); 1933 paint.end();
1931 1934
1932 bool showPlayPointer = true; 1935 bool showPlayPointer = true;
1933 if (m_followPlay == PlaybackScrollContinuous) { 1936 if (m_followPlay == PlaybackScrollContinuous) {
1945 } 1948 }
1946 } 1949 }
1947 1950
1948 if (showPlayPointer) { 1951 if (showPlayPointer) {
1949 1952
1950 paint.begin(this); 1953 paint.begin(this);
1951 1954
1952 int playx = getXForFrame(m_playPointerFrame); 1955 int playx = getXForFrame(m_playPointerFrame);
1953 1956
1954 paint.setPen(getForeground()); 1957 paint.setPen(getForeground());
1955 paint.drawLine(playx - 1, 0, playx - 1, height() - 1); 1958 paint.drawLine(playx - 1, 0, playx - 1, height() - 1);
1957 paint.drawPoint(playx, 0); 1960 paint.drawPoint(playx, 0);
1958 paint.drawPoint(playx, height() - 1); 1961 paint.drawPoint(playx, height() - 1);
1959 paint.setPen(getBackground()); 1962 paint.setPen(getBackground());
1960 paint.drawLine(playx, 1, playx, height() - 2); 1963 paint.drawLine(playx, 1, playx, height() - 2);
1961 1964
1962 paint.end(); 1965 paint.end();
1963 } 1966 }
1964 1967
1965 QFrame::paintEvent(e); 1968 QFrame::paintEvent(e);
1966 } 1969 }
1967 1970
1971 if (!hasTopLayerTimeXAxis()) return; 1974 if (!hasTopLayerTimeXAxis()) return;
1972 1975
1973 MultiSelection::SelectionList selections; 1976 MultiSelection::SelectionList selections;
1974 1977
1975 if (m_manager) { 1978 if (m_manager) {
1976 selections = m_manager->getSelections(); 1979 selections = m_manager->getSelections();
1977 if (m_manager->haveInProgressSelection()) { 1980 if (m_manager->haveInProgressSelection()) {
1978 bool exclusive; 1981 bool exclusive;
1979 Selection inProgressSelection = 1982 Selection inProgressSelection =
1980 m_manager->getInProgressSelection(exclusive); 1983 m_manager->getInProgressSelection(exclusive);
1981 if (exclusive) selections.clear(); 1984 if (exclusive) selections.clear();
1982 selections.insert(inProgressSelection); 1985 selections.insert(inProgressSelection);
1983 } 1986 }
1984 } 1987 }
1985 1988
1986 paint.save(); 1989 paint.save();
1987 1990
1988 bool translucent = !areLayerColoursSignificant(); 1991 bool translucent = !areLayerColoursSignificant();
1998 QPoint localPos; 2001 QPoint localPos;
1999 sv_frame_t illuminateFrame = -1; 2002 sv_frame_t illuminateFrame = -1;
2000 bool closeToLeft, closeToRight; 2003 bool closeToLeft, closeToRight;
2001 2004
2002 if (shouldIlluminateLocalSelection(localPos, closeToLeft, closeToRight)) { 2005 if (shouldIlluminateLocalSelection(localPos, closeToLeft, closeToRight)) {
2003 illuminateFrame = getFrameForX(localPos.x()); 2006 illuminateFrame = getFrameForX(localPos.x());
2004 } 2007 }
2005 2008
2006 const QFontMetrics &metrics = paint.fontMetrics(); 2009 const QFontMetrics &metrics = paint.fontMetrics();
2007 2010
2008 for (MultiSelection::SelectionList::iterator i = selections.begin(); 2011 for (MultiSelection::SelectionList::iterator i = selections.begin();
2009 i != selections.end(); ++i) { 2012 i != selections.end(); ++i) {
2010 2013
2011 int p0 = getXForFrame(alignFromReference(i->getStartFrame())); 2014 int p0 = getXForFrame(alignFromReference(i->getStartFrame()));
2012 int p1 = getXForFrame(alignFromReference(i->getEndFrame())); 2015 int p1 = getXForFrame(alignFromReference(i->getEndFrame()));
2013 2016
2014 if (p1 < 0 || p0 > width()) continue; 2017 if (p1 < 0 || p0 > width()) continue;
2015 2018
2016 #ifdef DEBUG_VIEW_WIDGET_PAINT 2019 #ifdef DEBUG_VIEW_WIDGET_PAINT
2017 SVDEBUG << "View::drawSelections: " << p0 << ",-1 [" << (p1-p0) << "x" << (height()+1) << "]" << endl; 2020 SVDEBUG << "View::drawSelections: " << p0 << ",-1 [" << (p1-p0) << "x" << (height()+1) << "]" << endl;
2018 #endif 2021 #endif
2019 2022
2020 bool illuminateThis = 2023 bool illuminateThis =
2021 (illuminateFrame >= 0 && i->contains(illuminateFrame)); 2024 (illuminateFrame >= 0 && i->contains(illuminateFrame));
2022 2025
2023 paint.setPen(QColor(150, 150, 255)); 2026 double h = height();
2027 double penWidth = PaintAssistant::scalePenWidth(1.0);
2028 double half = penWidth/2.0;
2029
2030 paint.setPen(QPen(QColor(150, 150, 255), penWidth));
2024 2031
2025 if (translucent && shouldLabelSelections()) { 2032 if (translucent && shouldLabelSelections()) {
2026 paint.drawRect(p0, -1, p1 - p0, height() + 1); 2033 paint.drawRect(QRectF(p0, -penWidth, p1 - p0, h + 2*penWidth));
2027 } else { 2034 } else {
2028 // Make the top & bottom lines of the box visible if we 2035 // Make the top & bottom lines of the box visible if we
2029 // are lacking some of the other visual cues. There's no 2036 // are lacking some of the other visual cues. There's no
2030 // particular logic to this, it's just a question of what 2037 // particular logic to this, it's just a question of what
2031 // I happen to think looks nice. 2038 // I happen to think looks nice.
2032 paint.drawRect(p0, 0, p1 - p0, height() - 1); 2039 paint.drawRect(QRectF(p0, half, p1 - p0, h - penWidth));
2033 } 2040 }
2034 2041
2035 if (illuminateThis) { 2042 if (illuminateThis) {
2036 paint.save(); 2043 paint.save();
2037 paint.setPen(QPen(getForeground(), 2)); 2044 penWidth = PaintAssistant::scalePenWidth(2.0);
2038 if (closeToLeft) { 2045 half = penWidth/2.0;
2039 paint.drawLine(p0, 1, p1, 1); 2046 paint.setPen(QPen(getForeground(), penWidth));
2040 paint.drawLine(p0, 0, p0, height()); 2047 if (closeToLeft) {
2041 paint.drawLine(p0, height() - 1, p1, height() - 1); 2048 paint.drawLine(QLineF(p0, half, p1, half));
2042 } else if (closeToRight) { 2049 paint.drawLine(QLineF(p0, half, p0, h - half));
2043 paint.drawLine(p0, 1, p1, 1); 2050 paint.drawLine(QLineF(p0, h - half, p1, h - half));
2044 paint.drawLine(p1, 0, p1, height()); 2051 } else if (closeToRight) {
2045 paint.drawLine(p0, height() - 1, p1, height() - 1); 2052 paint.drawLine(QLineF(p0, half, p1, half));
2046 } else { 2053 paint.drawLine(QLineF(p1, half, p1, h - half));
2047 paint.setBrush(Qt::NoBrush); 2054 paint.drawLine(QLineF(p0, h - half, p1, h - half));
2048 paint.drawRect(p0, 1, p1 - p0, height() - 2); 2055 } else {
2049 } 2056 paint.setBrush(Qt::NoBrush);
2050 paint.restore(); 2057 paint.drawRect(QRectF(p0, half, p1 - p0, h - penWidth));
2051 } 2058 }
2052 2059 paint.restore();
2053 if (sampleRate && shouldLabelSelections() && m_manager && 2060 }
2061
2062 if (sampleRate && shouldLabelSelections() && m_manager &&
2054 m_manager->shouldShowSelectionExtents()) { 2063 m_manager->shouldShowSelectionExtents()) {
2055 2064
2056 QString startText = QString("%1 / %2") 2065 QString startText = QString("%1 / %2")
2057 .arg(QString::fromStdString 2066 .arg(QString::fromStdString
2058 (RealTime::frame2RealTime 2067 (RealTime::frame2RealTime
2059 (i->getStartFrame(), sampleRate).toText(true))) 2068 (i->getStartFrame(), sampleRate).toText(true)))
2060 .arg(i->getStartFrame()); 2069 .arg(i->getStartFrame());
2061 2070
2062 QString endText = QString(" %1 / %2") 2071 QString endText = QString(" %1 / %2")
2063 .arg(QString::fromStdString 2072 .arg(QString::fromStdString
2064 (RealTime::frame2RealTime 2073 (RealTime::frame2RealTime
2065 (i->getEndFrame(), sampleRate).toText(true))) 2074 (i->getEndFrame(), sampleRate).toText(true)))
2066 .arg(i->getEndFrame()); 2075 .arg(i->getEndFrame());
2067 2076
2068 QString durationText = QString("(%1 / %2) ") 2077 QString durationText = QString("(%1 / %2) ")
2069 .arg(QString::fromStdString 2078 .arg(QString::fromStdString
2070 (RealTime::frame2RealTime 2079 (RealTime::frame2RealTime
2071 (i->getEndFrame() - i->getStartFrame(), sampleRate) 2080 (i->getEndFrame() - i->getStartFrame(), sampleRate)
2072 .toText(true))) 2081 .toText(true)))
2073 .arg(i->getEndFrame() - i->getStartFrame()); 2082 .arg(i->getEndFrame() - i->getStartFrame());
2074 2083
2075 int sw = metrics.width(startText), 2084 int sw = metrics.width(startText),
2076 ew = metrics.width(endText), 2085 ew = metrics.width(endText),
2077 dw = metrics.width(durationText); 2086 dw = metrics.width(durationText);
2078 2087
2079 int sy = metrics.ascent() + metrics.height() + 4; 2088 int sy = metrics.ascent() + metrics.height() + 4;
2080 int ey = sy; 2089 int ey = sy;
2081 int dy = sy + metrics.height(); 2090 int dy = sy + metrics.height();
2082 2091
2083 int sx = p0 + 2; 2092 int sx = p0 + 2;
2084 int ex = sx; 2093 int ex = sx;
2085 int dx = sx; 2094 int dx = sx;
2086 2095
2087 bool durationBothEnds = true; 2096 bool durationBothEnds = true;
2088 2097
2089 if (sw + ew > (p1 - p0)) { 2098 if (sw + ew > (p1 - p0)) {
2090 ey += metrics.height(); 2099 ey += metrics.height();
2091 dy += metrics.height(); 2100 dy += metrics.height();
2092 durationBothEnds = false; 2101 durationBothEnds = false;
2093 } 2102 }
2094 2103
2095 if (ew < (p1 - p0)) { 2104 if (ew < (p1 - p0)) {
2096 ex = p1 - 2 - ew; 2105 ex = p1 - 2 - ew;
2097 } 2106 }
2098 2107
2099 if (dw < (p1 - p0)) { 2108 if (dw < (p1 - p0)) {
2100 dx = p1 - 2 - dw; 2109 dx = p1 - 2 - dw;
2101 } 2110 }
2102 2111
2103 paint.drawText(sx, sy, startText); 2112 PaintAssistant::drawVisibleText(this, paint, sx, sy, startText,
2104 paint.drawText(ex, ey, endText); 2113 PaintAssistant::OutlinedText);
2105 paint.drawText(dx, dy, durationText); 2114 PaintAssistant::drawVisibleText(this, paint, ex, ey, endText,
2115 PaintAssistant::OutlinedText);
2116 PaintAssistant::drawVisibleText(this, paint, dx, dy, durationText,
2117 PaintAssistant::OutlinedText);
2106 if (durationBothEnds) { 2118 if (durationBothEnds) {
2107 paint.drawText(sx, dy, durationText); 2119 PaintAssistant::drawVisibleText(this, paint, sx, dy, durationText,
2108 } 2120 PaintAssistant::OutlinedText);
2109 } 2121 }
2122 }
2110 } 2123 }
2111 2124
2112 paint.restore(); 2125 paint.restore();
2113 } 2126 }
2114 2127
2422 QRect chunk(0, 0, width(), height()); 2435 QRect chunk(0, 0, width(), height());
2423 2436
2424 paint.setPen(getBackground()); 2437 paint.setPen(getBackground());
2425 paint.setBrush(getBackground()); 2438 paint.setBrush(getBackground());
2426 2439
2427 paint.drawRect(QRect(xorigin + x, 0, width(), height())); 2440 paint.drawRect(QRect(xorigin + x, 0, width(), height()));
2428 2441
2429 paint.setPen(getForeground()); 2442 paint.setPen(getForeground());
2430 paint.setBrush(Qt::NoBrush); 2443 paint.setBrush(Qt::NoBrush);
2431 2444
2432 for (LayerList::iterator i = m_layerStack.begin(); 2445 for (LayerList::iterator i = m_layerStack.begin();
2433 i != m_layerStack.end(); ++i) { 2446 i != m_layerStack.end(); ++i) {
2434 if (!((*i)->isLayerDormant(this))){ 2447 if (!((*i)->isLayerDormant(this))){
2435 2448
2436 paint.setRenderHint(QPainter::Antialiasing, false); 2449 paint.setRenderHint(QPainter::Antialiasing, false);
2437 2450
2446 2459
2447 (*i)->setSynchronousPainting(false); 2460 (*i)->setSynchronousPainting(false);
2448 2461
2449 paint.restore(); 2462 paint.restore();
2450 } 2463 }
2451 } 2464 }
2452 } 2465 }
2453 2466
2454 m_centreFrame = origCentreFrame; 2467 m_centreFrame = origCentreFrame;
2455 update(); 2468 update();
2456 return true; 2469 return true;
2457 } 2470 }
2458 2471
2459 QImage * 2472 QImage *
2460 View::toNewImage() 2473 View::renderToNewImage()
2461 { 2474 {
2462 sv_frame_t f0 = getModelsStartFrame(); 2475 sv_frame_t f0 = getModelsStartFrame();
2463 sv_frame_t f1 = getModelsEndFrame(); 2476 sv_frame_t f1 = getModelsEndFrame();
2464 2477
2465 return toNewImage(f0, f1); 2478 return renderPartToNewImage(f0, f1);
2466 } 2479 }
2467 2480
2468 QImage * 2481 QImage *
2469 View::toNewImage(sv_frame_t f0, sv_frame_t f1) 2482 View::renderPartToNewImage(sv_frame_t f0, sv_frame_t f1)
2470 { 2483 {
2471 int x0 = int(f0 / getZoomLevel()); 2484 int x0 = int(f0 / getZoomLevel());
2472 int x1 = int(f1 / getZoomLevel()); 2485 int x1 = int(f1 / getZoomLevel());
2473 2486
2474 QImage *image = new QImage(x1 - x0, height(), QImage::Format_RGB32); 2487 QImage *image = new QImage(x1 - x0, height(), QImage::Format_RGB32);
2483 return image; 2496 return image;
2484 } 2497 }
2485 } 2498 }
2486 2499
2487 QSize 2500 QSize
2488 View::getImageSize() 2501 View::getRenderedImageSize()
2489 { 2502 {
2490 sv_frame_t f0 = getModelsStartFrame(); 2503 sv_frame_t f0 = getModelsStartFrame();
2491 sv_frame_t f1 = getModelsEndFrame(); 2504 sv_frame_t f1 = getModelsEndFrame();
2492 2505
2493 return getImageSize(f0, f1); 2506 return getRenderedPartImageSize(f0, f1);
2494 } 2507 }
2495 2508
2496 QSize 2509 QSize
2497 View::getImageSize(sv_frame_t f0, sv_frame_t f1) 2510 View::getRenderedPartImageSize(sv_frame_t f0, sv_frame_t f1)
2498 { 2511 {
2499 int x0 = int(f0 / getZoomLevel()); 2512 int x0 = int(f0 / getZoomLevel());
2500 int x1 = int(f1 / getZoomLevel()); 2513 int x1 = int(f1 / getZoomLevel());
2501 2514
2502 return QSize(x1 - x0, height()); 2515 return QSize(x1 - x0, height());
2516 }
2517
2518 bool
2519 View::renderToSvgFile(QString filename)
2520 {
2521 sv_frame_t f0 = getModelsStartFrame();
2522 sv_frame_t f1 = getModelsEndFrame();
2523
2524 return renderPartToSvgFile(filename, f0, f1);
2525 }
2526
2527 bool
2528 View::renderPartToSvgFile(QString filename, sv_frame_t f0, sv_frame_t f1)
2529 {
2530 int x0 = int(f0 / getZoomLevel());
2531 int x1 = int(f1 / getZoomLevel());
2532
2533 QSvgGenerator generator;
2534 generator.setFileName(filename);
2535 generator.setSize(QSize(x1 - x0, height()));
2536 generator.setViewBox(QRect(0, 0, x1 - x0, height()));
2537 generator.setTitle(tr("Exported image from %1")
2538 .arg(QApplication::applicationName()));
2539
2540 QPainter paint;
2541 paint.begin(&generator);
2542 bool result = render(paint, 0, f0, f1);
2543 paint.end();
2544 return result;
2503 } 2545 }
2504 2546
2505 void 2547 void
2506 View::toXml(QTextStream &stream, 2548 View::toXml(QTextStream &stream,
2507 QString indent, QString extraAttributes) const 2549 QString indent, QString extraAttributes) const
2513 "zoom=\"%2\" " 2555 "zoom=\"%2\" "
2514 "followPan=\"%3\" " 2556 "followPan=\"%3\" "
2515 "followZoom=\"%4\" " 2557 "followZoom=\"%4\" "
2516 "tracking=\"%5\" " 2558 "tracking=\"%5\" "
2517 " %6>\n") 2559 " %6>\n")
2518 .arg(m_centreFrame) 2560 .arg(m_centreFrame)
2519 .arg(m_zoomLevel) 2561 .arg(m_zoomLevel)
2520 .arg(m_followPan) 2562 .arg(m_followPan)
2521 .arg(m_followZoom) 2563 .arg(m_followZoom)
2522 .arg(m_followPlay == PlaybackScrollContinuous ? "scroll" : 2564 .arg(m_followPlay == PlaybackScrollContinuous ? "scroll" :
2523 m_followPlay == PlaybackScrollPageWithCentre ? "page" : 2565 m_followPlay == PlaybackScrollPageWithCentre ? "page" :
2524 m_followPlay == PlaybackScrollPage ? "daw" : 2566 m_followPlay == PlaybackScrollPage ? "daw" :
2525 "ignore") 2567 "ignore")
2526 .arg(extraAttributes); 2568 .arg(extraAttributes);
2527 2569
2528 for (int i = 0; i < (int)m_fixedOrderLayers.size(); ++i) { 2570 for (int i = 0; i < (int)m_fixedOrderLayers.size(); ++i) {
2529 bool visible = !m_fixedOrderLayers[i]->isLayerDormant(this); 2571 bool visible = !m_fixedOrderLayers[i]->isLayerDormant(this);
2530 m_fixedOrderLayers[i]->toBriefXml(stream, indent + " ", 2572 m_fixedOrderLayers[i]->toBriefXml(stream, indent + " ",
2531 QString("visible=\"%1\"") 2573 QString("visible=\"%1\"")
2538 ViewPropertyContainer::ViewPropertyContainer(View *v) : 2580 ViewPropertyContainer::ViewPropertyContainer(View *v) :
2539 m_v(v) 2581 m_v(v)
2540 { 2582 {
2541 // cerr << "ViewPropertyContainer: " << this << " is owned by View " << v << endl; 2583 // cerr << "ViewPropertyContainer: " << this << " is owned by View " << v << endl;
2542 connect(m_v, SIGNAL(propertyChanged(PropertyContainer::PropertyName)), 2584 connect(m_v, SIGNAL(propertyChanged(PropertyContainer::PropertyName)),
2543 this, SIGNAL(propertyChanged(PropertyContainer::PropertyName))); 2585 this, SIGNAL(propertyChanged(PropertyContainer::PropertyName)));
2544 } 2586 }
2545 2587
2546 ViewPropertyContainer::~ViewPropertyContainer() 2588 ViewPropertyContainer::~ViewPropertyContainer()
2547 { 2589 {
2548 } 2590 }