svgui  1.9
Layer.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2006 Chris Cannam and QMUL.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #include "Layer.h"
17 #include "view/View.h"
18 #include "data/model/Model.h"
19 #include "widgets/CommandHistory.h"
20 
21 #include <iostream>
22 
23 #include <QMutexLocker>
24 #include <QMouseEvent>
25 #include <QTextStream>
26 
27 #include <QDomDocument>
28 #include <QDomElement>
29 #include <QDomNamedNodeMap>
30 #include <QDomAttr>
31 
32 #include "LayerFactory.h"
33 #include "base/PlayParameterRepository.h"
34 
35 #include <cmath>
36 
38  m_haveDraggingRect(false),
39  m_haveCurrentMeasureRect(false)
40 {
41 }
42 
44 {
45 // SVDEBUG << "Layer::~Layer(" << this << ")" << endl;
46 }
47 
48 void
49 Layer::connectSignals(const Model *model)
50 {
51  connect(model, SIGNAL(modelChanged()),
52  this, SIGNAL(modelChanged()));
53 
54  connect(model, SIGNAL(modelChangedWithin(int, int)),
55  this, SIGNAL(modelChangedWithin(int, int)));
56 
57  connect(model, SIGNAL(completionChanged()),
58  this, SIGNAL(modelCompletionChanged()));
59 
60  connect(model, SIGNAL(alignmentCompletionChanged()),
61  this, SIGNAL(modelAlignmentCompletionChanged()));
62 }
63 
64 QString
66 {
68  (LayerFactory::getInstance()->getLayerType(this));
69 }
70 
71 void
73 {
74  m_presentationName = name;
75 }
76 
77 QString
79 {
80  if (m_presentationName != "") return m_presentationName;
81 
83  QString layerName = factory->getLayerPresentationName
84  (factory->getLayerType(this));
85 
86  QString modelName;
87  if (getModel()) modelName = getModel()->objectName();
88 
89  QString text;
90  if (modelName != "") {
91  text = QString("%1: %2").arg(modelName).arg(layerName);
92  } else {
93  text = layerName;
94  }
95 
96  return text;
97 }
98 
99 void
100 Layer::setObjectName(const QString &name)
101 {
102  QObject::setObjectName(name);
103  emit layerNameChanged();
104 }
105 
106 PlayParameters *
108 {
109 // cerr << "Layer (" << this << ", " << objectName() << ")::getPlayParameters: model is "<< getModel() << endl;
110  const Model *model = getModel();
111  if (model) {
112  return PlayParameterRepository::getInstance()->getPlayParameters(model);
113  }
114  return 0;
115 }
116 
117 void
118 Layer::setLayerDormant(const View *v, bool dormant)
119 {
120  const void *vv = (const void *)v;
121  QMutexLocker locker(&m_dormancyMutex);
122  m_dormancy[vv] = dormant;
123 }
124 
125 bool
127 {
128  const void *vv = (const void *)v;
129  QMutexLocker locker(&m_dormancyMutex);
130  if (m_dormancy.find(vv) == m_dormancy.end()) return false;
131  return m_dormancy.find(vv)->second;
132 }
133 
134 void
135 Layer::showLayer(View *view, bool show)
136 {
137  setLayerDormant(view, !show);
138  emit layerParametersChanged();
139 }
140 
141 bool
142 Layer::getXScaleValue(const View *v, int x, float &value, QString &unit) const
143 {
144  if (!hasTimeXAxis()) return false;
145 
146  const Model *m = getModel();
147  if (!m) return false;
148 
149  value = float(v->getFrameForX(x)) / m->getSampleRate();
150  unit = "s";
151  return true;
152 }
153 
154 bool
155 Layer::getYScaleDifference(const View *v, int y0, int y1,
156  float &diff, QString &unit) const
157 {
158  float v0, v1;
159  if (!getYScaleValue(v, y0, v0, unit) ||
160  !getYScaleValue(v, y1, v1, unit)) {
161  diff = 0.f;
162  return false;
163  }
164  diff = fabsf(v1 - v0);
165  return true;
166 }
167 
168 int
169 Layer::alignToReference(View *v, int frame) const
170 {
171  const Model *m = getModel();
172  SVDEBUG << "Layer::alignToReference(" << frame << "): model = " << m << ", alignment reference = " << (m ? m->getAlignmentReference() : 0) << endl;
173  if (m && m->getAlignmentReference()) {
174  return m->alignToReference(frame);
175  } else {
176  return v->alignToReference(frame);
177  }
178 }
179 
180 int
181 Layer::alignFromReference(View *v, int frame) const
182 {
183  const Model *m = getModel();
184  SVDEBUG << "Layer::alignFromReference(" << frame << "): model = " << m << ", alignment reference = " << (m ? m->getAlignmentReference() : 0) << endl;
185  if (m && m->getAlignmentReference()) {
186  return m->alignFromReference(frame);
187  } else {
188  return v->alignFromReference(frame);
189  }
190 }
191 
192 bool
193 Layer::clipboardHasDifferentAlignment(View *v, const Clipboard &clip) const
194 {
195  // Notes on pasting to an aligned layer:
196  //
197  // Each point may have a reference frame that may differ from the
198  // point's given frame (in its source model). If it has no
199  // reference frame, we have to assume the source model was not
200  // aligned or was the reference model: when cutting or copying
201  // points from a layer, we must always set their reference frame
202  // correctly if we are aligned.
203  //
204  // When pasting:
205  // - if point's reference and aligned frames differ:
206  // - if this layer is aligned:
207  // - if point's aligned frame matches this layer's aligned version
208  // of point's reference frame:
209  // - we can paste at reference frame or our frame
210  // - else
211  // - we can paste at reference frame, result of aligning reference
212  // frame in our model, or literal source frame
213  // - else
214  // - we can paste at reference (our) frame, or literal source frame
215  // - else
216  // - if this layer is aligned:
217  // - we can paste at reference (point's only available) frame,
218  // or result of aligning reference frame in our model
219  // - else
220  // - we can only paste at reference frame
221  //
222  // Which of these alternatives are useful?
223  //
224  // Example: we paste between two tracks that are aligned to the
225  // same reference, and the points are at 10s and 20s in the source
226  // track, corresponding to 5s and 10s in the reference but 20s and
227  // 30s in the target track.
228  //
229  // The obvious default is to paste at 20s and 30s; if we aren't
230  // doing that, would it be better to paste at 5s and 10s or at 10s
231  // and 20s? We probably don't ever want to do the former, do we?
232  // We either want to be literal all the way through, or aligned
233  // all the way through.
234 
235  for (Clipboard::PointList::const_iterator i = clip.getPoints().begin();
236  i != clip.getPoints().end(); ++i) {
237 
238  // In principle, we want to know whether the aligned version
239  // of the reference frame in our layer is the same as the
240  // source frame contained in the clipboard point. However,
241  // because of rounding during alignment, that won't
242  // necessarily be the case even if the clipboard point came
243  // from our layer! What we need to check is whether, if we
244  // aligned the clipboard point's frame back to the reference
245  // using this layer's alignment, we would obtain the same
246  // reference frame as that for the clipboard point.
247 
248  // What if the clipboard point has no reference frame? Then
249  // we have to treat it as having its own frame as the
250  // reference (i.e. having been copied from the reference
251  // model).
252 
253  int sourceFrame = i->getFrame();
254  int referenceFrame = sourceFrame;
255  if (i->haveReferenceFrame()) {
256  referenceFrame = i->getReferenceFrame();
257  }
258  int myMappedFrame = alignToReference(v, sourceFrame);
259 
260 // cerr << "sourceFrame = " << sourceFrame << ", referenceFrame = " << referenceFrame << " (have = " << i->haveReferenceFrame() << "), myMappedFrame = " << myMappedFrame << endl;
261 
262  if (myMappedFrame != referenceFrame) return true;
263  }
264 
265  return false;
266 }
267 
268 bool
270 {
271  if (haveFrames) {
272  if (startFrame == mr.startFrame) {
273  if (endFrame != mr.endFrame) {
274  return endFrame < mr.endFrame;
275  }
276  } else {
277  return startFrame < mr.startFrame;
278  }
279  } else {
280  if (pixrect.x() == mr.pixrect.x()) {
281  if (pixrect.width() != mr.pixrect.width()) {
282  return pixrect.width() < mr.pixrect.width();
283  }
284  } else {
285  return pixrect.x() < mr.pixrect.x();
286  }
287  }
288 
289  // the two rects are equal in x and width
290 
291  if (pixrect.y() == mr.pixrect.y()) {
292  return pixrect.height() < mr.pixrect.height();
293  } else {
294  return pixrect.y() < mr.pixrect.y();
295  }
296 }
297 
298 void
299 Layer::MeasureRect::toXml(QTextStream &stream, QString indent) const
300 {
301  stream << indent;
302  stream << QString("<measurement ");
303 
304  if (haveFrames) {
305  stream << QString("startFrame=\"%1\" endFrame=\"%2\" ")
306  .arg(startFrame).arg(endFrame);
307  } else {
308  stream << QString("startX=\"%1\" endX=\"%2\" ")
309  .arg(pixrect.x()).arg(pixrect.x() << pixrect.width());
310  }
311 
312  stream << QString("startY=\"%1\" endY=\"%2\"/>\n")
313  .arg(startY).arg(endY);
314 }
315 
316 void
317 Layer::addMeasurementRect(const QXmlAttributes &attributes)
318 {
319  MeasureRect rect;
320  QString fs = attributes.value("startFrame");
321  int x0 = 0, x1 = 0;
322  if (fs != "") {
323  rect.startFrame = fs.toInt();
324  rect.endFrame = attributes.value("endFrame").toInt();
325  rect.haveFrames = true;
326  } else {
327  x0 = attributes.value("startX").toInt();
328  x1 = attributes.value("endX").toInt();
329  rect.haveFrames = false;
330  }
331  rect.startY = attributes.value("startY").toDouble();
332  rect.endY = attributes.value("endY").toDouble();
333  rect.pixrect = QRect(x0, 0, x1 - x0, 0);
334  addMeasureRectToSet(rect);
335 }
336 
337 QString
339 {
340  return tr("Make Measurement");
341 }
342 
343 void
345 {
346  m_layer->addMeasureRectToSet(m_rect);
347 }
348 
349 void
351 {
352  m_layer->deleteMeasureRectFromSet(m_rect);
353 }
354 
355 QString
357 {
358  return tr("Delete Measurement");
359 }
360 
361 void
363 {
364  m_layer->deleteMeasureRectFromSet(m_rect);
365 }
366 
367 void
369 {
370  m_layer->addMeasureRectToSet(m_rect);
371 }
372 
373 void
374 Layer::measureStart(View *v, QMouseEvent *e)
375 {
377  QRect(e->x(), e->y(), 0, 0));
378  m_haveDraggingRect = true;
379 }
380 
381 void
382 Layer::measureDrag(View *v, QMouseEvent *e)
383 {
384  if (!m_haveDraggingRect) return;
385 
387  QRect(m_draggingRect.pixrect.x(),
389  e->x() - m_draggingRect.pixrect.x(),
390  e->y() - m_draggingRect.pixrect.y()));
391 }
392 
393 void
394 Layer::measureEnd(View *v, QMouseEvent *e)
395 {
396  if (!m_haveDraggingRect) return;
397  measureDrag(v, e);
398 
399  if (!m_draggingRect.pixrect.isNull()) {
402  }
403 
404  m_haveDraggingRect = false;
405 }
406 
407 void
409 {
410  // nothing, in the base class
411 }
412 
413 void
415 {
416  if (!m_haveCurrentMeasureRect) return;
417 
418  MeasureRectSet::const_iterator focusRectItr =
420 
421  if (focusRectItr == m_measureRects.end()) return;
422 
424  (new DeleteMeasurementRectCommand(this, *focusRectItr));
425 }
426 
427 void
429  bool showFocus, QPoint focusPoint) const
430 {
432 
433  MeasureRectSet::const_iterator focusRectItr = m_measureRects.end();
434 
435  if (m_haveDraggingRect) {
436 
438 
439  } else if (showFocus) {
440 
441  focusRectItr = findFocusedMeasureRect(focusPoint);
442  }
443 
444  m_haveCurrentMeasureRect = false;
445 
446  for (MeasureRectSet::const_iterator i = m_measureRects.begin();
447  i != m_measureRects.end(); ++i) {
448 
449  bool focused = (i == focusRectItr);
450  paintMeasurementRect(v, paint, *i, focused);
451 
452  if (focused) {
454  m_currentMeasureRectPoint = focusPoint;
455  }
456  }
457 }
458 
459 bool
460 Layer::nearestMeasurementRectChanged(View *v, QPoint prev, QPoint now) const
461 {
463 
464  MeasureRectSet::const_iterator i0 = findFocusedMeasureRect(prev);
465  MeasureRectSet::const_iterator i1 = findFocusedMeasureRect(now);
466 
467  return (i0 != i1);
468 }
469 
470 void
472 {
473  int sf = v->getStartFrame();
474  int ef = v->getEndFrame();
475 
476  for (MeasureRectSet::const_iterator i = m_measureRects.begin();
477  i != m_measureRects.end(); ++i) {
478 
479  // This logic depends on the fact that if one measure rect in
480  // a layer has frame values, they all will. That is in fact
481  // the case, because haveFrames is based on whether the layer
482  // hasTimeXAxis() or not. Measure rect ordering in the rect
483  // set wouldn't work correctly either, if haveFrames could
484  // vary.
485 
486  if (i->haveFrames) {
487  if (i->startFrame >= ef) break;
488  if (i->endFrame <= sf) continue;
489  }
490 
491  int x0 = i->pixrect.x();
492  int x1 = x0 + i->pixrect.width();
493 
494  if (i->haveFrames) {
495  if (i->startFrame >= v->getStartFrame()) {
496  x0 = v->getXForFrame(i->startFrame);
497  }
498  if (i->endFrame <= int(v->getEndFrame())) {
499  x1 = v->getXForFrame(i->endFrame);
500  }
501  }
502 
503  i->pixrect = QRect(x0, i->pixrect.y(), x1 - x0, i->pixrect.height());
504 
506  }
507 }
508 
509 void
511 {
512  int y0 = lrint(r.startY * v->height());
513  int y1 = lrint(r.endY * v->height());
514  r.pixrect = QRect(r.pixrect.x(), y0, r.pixrect.width(), y1 - y0);
515 }
516 
517 void
518 Layer::setMeasureRectYCoord(View *v, MeasureRect &r, bool start, int y) const
519 {
520  if (start) {
521  r.startY = double(y) / double(v->height());
522  r.endY = r.startY;
523  } else {
524  r.endY = double(y) / double(v->height());
525  }
526 }
527 
528 void
530 {
531  r.pixrect = pixrect;
532  r.haveFrames = hasTimeXAxis();
533  if (r.haveFrames) {
534  r.startFrame = v->getFrameForX(pixrect.x());
535  r.endFrame = v->getFrameForX(pixrect.x() + pixrect.width());
536  }
537  setMeasureRectYCoord(v, r, true, pixrect.y());
538  setMeasureRectYCoord(v, r, false, pixrect.y() + pixrect.height());
539 }
540 
541 Layer::MeasureRectSet::const_iterator
542 Layer::findFocusedMeasureRect(QPoint focusPoint) const
543 {
544  float frDist = 0;
545  MeasureRectSet::const_iterator focusRectItr = m_measureRects.end();
546 
547  for (MeasureRectSet::const_iterator i = m_measureRects.begin();
548  i != m_measureRects.end(); ++i) {
549 
550  if (!i->pixrect.adjusted(-2, -2, 2, 2).contains(focusPoint)) continue;
551 
552  int cx = i->pixrect.x() + i->pixrect.width()/2;
553  int cy = i->pixrect.y() + i->pixrect.height()/2;
554  int xd = focusPoint.x() - cx;
555  int yd = focusPoint.y() - cy;
556 
557  float d = sqrt(float(xd * xd + yd * yd));
558 
559  if (focusRectItr == m_measureRects.end() || d < frDist) {
560  focusRectItr = i;
561  frDist = d;
562  }
563  }
564 
565  return focusRectItr;
566 }
567 
568 void
570  const MeasureRect &r, bool focus) const
571 {
572  if (r.haveFrames) {
573 
574  int x0 = -1;
575  int x1 = v->width() + 1;
576 
577  if (r.startFrame >= v->getStartFrame()) {
578  x0 = v->getXForFrame(r.startFrame);
579  }
580  if (r.endFrame <= v->getEndFrame()) {
581  x1 = v->getXForFrame(r.endFrame);
582  }
583 
584  QRect pr = QRect(x0, r.pixrect.y(), x1 - x0, r.pixrect.height());
585  r.pixrect = pr;
586  }
587 
588  v->drawMeasurementRect(paint, this, r.pixrect.normalized(), focus);
589 }
590 
591 void
592 Layer::toXml(QTextStream &stream,
593  QString indent, QString extraAttributes) const
594 {
595  stream << indent;
596 
597  if (m_presentationName != "") {
598  extraAttributes = QString("%1 presentationName=\"%2\"")
599  .arg(extraAttributes).arg(encodeEntities(m_presentationName));
600  }
601 
602  stream << QString("<layer id=\"%2\" type=\"%1\" name=\"%3\" model=\"%4\" %5")
603  .arg(encodeEntities(LayerFactory::getInstance()->getLayerTypeName
604  (LayerFactory::getInstance()->getLayerType(this))))
605  .arg(getObjectExportId(this))
606  .arg(encodeEntities(objectName()))
607  .arg(getObjectExportId(getModel()))
608  .arg(extraAttributes);
609 
610  if (m_measureRects.empty()) {
611  stream << QString("/>\n");
612  return;
613  }
614 
615  stream << QString(">\n");
616 
617  for (MeasureRectSet::const_iterator i = m_measureRects.begin();
618  i != m_measureRects.end(); ++i) {
619  i->toXml(stream, indent + " ");
620  }
621 
622  stream << QString("</layer>\n");
623 }
624 
625 void
626 Layer::toBriefXml(QTextStream &stream,
627  QString indent, QString extraAttributes) const
628 {
629  stream << indent;
630 
631  if (m_presentationName != "") {
632  extraAttributes = QString("%1 presentationName=\"%2\"")
633  .arg(extraAttributes).arg(encodeEntities(m_presentationName));
634  }
635 
636  stream << QString("<layer id=\"%2\" type=\"%1\" name=\"%3\" model=\"%4\" %5/>\n")
637  .arg(encodeEntities(LayerFactory::getInstance()->getLayerTypeName
638  (LayerFactory::getInstance()->getLayerType(this))))
639  .arg(getObjectExportId(this))
640  .arg(encodeEntities(objectName()))
641  .arg(getObjectExportId(getModel()))
642  .arg(extraAttributes);
643 }
644 
MeasureRectSet m_measureRects
Definition: Layer.h:599
void toXml(QTextStream &stream, QString indent) const
Definition: Layer.cpp:299
static LayerFactory * getInstance()
int getFrameForX(int x) const
Return the closest frame to the given pixel x-coordinate.
Definition: View.cpp:363
void modelChangedWithin(int startFrame, int endFrame)
QString getLayerIconName(LayerType)
QPoint m_currentMeasureRectPoint
Definition: Layer.h:603
bool m_haveCurrentMeasureRect
Definition: Layer.h:602
virtual void addMeasurementRect(const QXmlAttributes &)
Add a measurement rectangle from the given XML attributes (presumably taken from a measurement elemen...
Definition: Layer.cpp:317
Layer()
Definition: Layer.cpp:37
virtual bool hasTimeXAxis() const
Definition: Layer.h:415
MeasureRect m_draggingRect
Definition: Layer.h:600
void connectSignals(const Model *)
Definition: Layer.cpp:49
void showLayer(View *, bool show)
Definition: Layer.cpp:135
virtual void toXml(QTextStream &stream, QString indent="", QString extraAttributes="") const
Convert the layer's data (though not those of the model it refers to) into XML for file output.
Definition: Layer.cpp:592
void updateMeasurePixrects(View *v) const
Definition: Layer.cpp:471
virtual void measureDoubleClick(View *, QMouseEvent *)
Definition: Layer.cpp:408
QMutex m_dormancyMutex
Definition: Layer.h:623
virtual QString getName() const
Definition: Layer.cpp:356
virtual bool nearestMeasurementRectChanged(View *, QPoint prev, QPoint now) const
Definition: Layer.cpp:460
void addCommand(Command *command)
Add a command to the command history.
virtual void measureDrag(View *, QMouseEvent *)
Definition: Layer.cpp:382
virtual void toBriefXml(QTextStream &stream, QString indent="", QString extraAttributes="") const
Produce XML containing the layer's ID and type.
Definition: Layer.cpp:626
void paintMeasurementRect(View *v, QPainter &paint, const MeasureRect &r, bool focus) const
Definition: Layer.cpp:569
virtual bool getYScaleValue(const View *, int, float &, QString &) const
Return the value and unit at the given y coordinate in the given view.
Definition: Layer.h:467
virtual void updateMeasureRectYCoords(View *v, const MeasureRect &r) const
Definition: Layer.cpp:510
virtual void setLayerDormant(const View *v, bool dormant)
Indicate that a layer is not currently visible in the given view and is not expected to become visibl...
Definition: Layer.cpp:118
virtual void setObjectName(const QString &name)
Definition: Layer.cpp:100
bool operator<(const MeasureRect &mr) const
Definition: Layer.cpp:269
virtual QString getName() const
Definition: Layer.cpp:338
int alignToReference(int) const
Definition: View.cpp:1322
virtual void setMeasureRectFromPixrect(View *v, MeasureRect &r, QRect pixrect) const
Definition: Layer.cpp:529
virtual void deleteCurrentMeasureRect()
Definition: Layer.cpp:414
QString getLayerPresentationName(LayerType type)
virtual void paintMeasurementRects(View *, QPainter &, bool showFocus, QPoint focusPoint) const
Definition: Layer.cpp:428
int getStartFrame() const
Retrieve the first visible sample frame on the widget.
Definition: View.cpp:302
int alignFromReference(int) const
Definition: View.cpp:1313
virtual void setMeasureRectYCoord(View *v, MeasureRect &r, bool start, int y) const
Definition: Layer.cpp:518
void layerParametersChanged()
int getEndFrame() const
Retrieve the last visible sample frame on the widget.
Definition: View.cpp:308
static CommandHistory * getInstance()
std::map< const void *, bool > m_dormancy
Definition: Layer.h:624
bool clipboardHasDifferentAlignment(View *v, const Clipboard &clip) const
Definition: Layer.cpp:193
virtual QString getPropertyContainerIconName() const
Definition: Layer.cpp:65
void modelChanged()
virtual void measureEnd(View *, QMouseEvent *)
Definition: Layer.cpp:394
virtual bool getYScaleDifference(const View *v, int y0, int y1, float &diff, QString &unit) const
Return the difference between the values at the given y coordinates in the given view,...
Definition: Layer.cpp:155
bool m_haveDraggingRect
Definition: Layer.h:601
void modelAlignmentCompletionChanged()
virtual int alignFromReference(View *v, int frame) const
Definition: Layer.cpp:181
virtual int alignToReference(View *v, int frame) const
Definition: Layer.cpp:169
LayerType getLayerType(const Layer *)
virtual const Model * getModel() const =0
View is the base class of widgets that display one or more overlaid views of data against a horizonta...
Definition: View.h:50
virtual ~Layer()
Definition: Layer.cpp:43
virtual bool getXScaleValue(const View *v, int x, float &value, QString &unit) const
Return the value and unit at the given x coordinate in the given view.
Definition: Layer.cpp:142
virtual void setPresentationName(QString name)
Definition: Layer.cpp:72
double startY
Definition: Layer.h:551
void modelCompletionChanged()
QString m_presentationName
Definition: Layer.h:620
virtual void paint(View *, QPainter &, QRect) const =0
Paint the given rectangle of this layer onto the given view using the given painter,...
virtual void measureStart(View *, QMouseEvent *)
Definition: Layer.cpp:374
void addMeasureRectToSet(const MeasureRect &r)
Definition: Layer.h:588
MeasureRectSet::const_iterator findFocusedMeasureRect(QPoint) const
Definition: Layer.cpp:542
virtual QString getLayerPresentationName() const
Definition: Layer.cpp:78
virtual PlayParameters * getPlayParameters()
Definition: Layer.cpp:107
void layerNameChanged()
virtual bool isLayerDormant(const View *v) const
Return whether the layer is dormant (i.e.
Definition: Layer.cpp:126
int getXForFrame(int frame) const
Return the pixel x-coordinate corresponding to a given sample frame (which may be negative).
Definition: View.cpp:357
virtual void drawMeasurementRect(QPainter &p, const Layer *, QRect rect, bool focus) const
Definition: View.cpp:2097