svgui  1.9
TextLayer.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.
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 "TextLayer.h"
17 
18 #include "data/model/Model.h"
19 #include "base/RealTime.h"
20 #include "base/Profiler.h"
21 #include "ColourDatabase.h"
22 #include "view/View.h"
23 
24 #include "data/model/TextModel.h"
25 
26 #include <QPainter>
27 #include <QMouseEvent>
28 #include <QInputDialog>
29 #include <QTextStream>
30 #include <QMessageBox>
31 
32 #include <iostream>
33 #include <cmath>
34 
37  m_model(0),
38  m_editing(false),
39  m_originalPoint(0, 0.0, tr("Empty Label")),
40  m_editingPoint(0, 0.0, tr("Empty Label")),
41  m_editingCommand(0)
42 {
43 
44 }
45 
46 void
47 TextLayer::setModel(TextModel *model)
48 {
49  if (m_model == model) return;
50  m_model = model;
51 
53 
54 // SVDEBUG << "TextLayer::setModel(" << model << ")" << endl;
55 
56  emit modelReplaced();
57 }
58 
59 Layer::PropertyList
61 {
62  PropertyList list = SingleColourLayer::getProperties();
63  return list;
64 }
65 
66 QString
67 TextLayer::getPropertyLabel(const PropertyName &name) const
68 {
70 }
71 
72 Layer::PropertyType
73 TextLayer::getPropertyType(const PropertyName &name) const
74 {
76 }
77 
78 int
79 TextLayer::getPropertyRangeAndValue(const PropertyName &name,
80  int *min, int *max, int *deflt) const
81 {
82  return SingleColourLayer::getPropertyRangeAndValue(name, min, max, deflt);
83 }
84 
85 QString
86 TextLayer::getPropertyValueLabel(const PropertyName &name,
87  int value) const
88 {
89  return SingleColourLayer::getPropertyValueLabel(name, value);
90 }
91 
92 void
93 TextLayer::setProperty(const PropertyName &name, int value)
94 {
95  SingleColourLayer::setProperty(name, value);
96 }
97 
98 bool
99 TextLayer::getValueExtents(float &, float &, bool &, QString &) const
100 {
101  return false;
102 }
103 
104 bool
106 {
107  QPoint discard;
108  return !v->shouldIlluminateLocalFeatures(this, discard);
109 }
110 
111 
112 TextModel::PointList
113 TextLayer::getLocalPoints(View *v, int x, int y) const
114 {
115  if (!m_model) return TextModel::PointList();
116 
117  long frame0 = v->getFrameForX(-150);
118  long frame1 = v->getFrameForX(v->width() + 150);
119 
120  TextModel::PointList points(m_model->getPoints(frame0, frame1));
121 
122  TextModel::PointList rv;
123  QFontMetrics metrics = QFontMetrics(QFont());
124 
125  for (TextModel::PointList::iterator i = points.begin();
126  i != points.end(); ++i) {
127 
128  const TextModel::Point &p(*i);
129 
130  int px = v->getXForFrame(p.frame);
131  int py = getYForHeight(v, p.height);
132 
133  QString label = p.label;
134  if (label == "") {
135  label = tr("<no text>");
136  }
137 
138  QRect rect = metrics.boundingRect
139  (QRect(0, 0, 150, 200),
140  Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, label);
141 
142  if (py + rect.height() > v->height()) {
143  if (rect.height() > v->height()) py = 0;
144  else py = v->height() - rect.height() - 1;
145  }
146 
147  if (x >= px && x < px + rect.width() &&
148  y >= py && y < py + rect.height()) {
149  rv.insert(p);
150  }
151  }
152 
153  return rv;
154 }
155 
156 bool
157 TextLayer::getPointToDrag(View *v, int x, int y, TextModel::Point &p) const
158 {
159  if (!m_model) return false;
160 
161  long a = v->getFrameForX(x - 120);
162  long b = v->getFrameForX(x + 10);
163  TextModel::PointList onPoints = m_model->getPoints(a, b);
164  if (onPoints.empty()) return false;
165 
166  float nearestDistance = -1;
167 
168  for (TextModel::PointList::const_iterator i = onPoints.begin();
169  i != onPoints.end(); ++i) {
170 
171  int yd = getYForHeight(v, (*i).height) - y;
172  int xd = v->getXForFrame((*i).frame) - x;
173  float distance = sqrtf(yd*yd + xd*xd);
174 
175  if (nearestDistance == -1 || distance < nearestDistance) {
176  nearestDistance = distance;
177  p = *i;
178  }
179  }
180 
181  return true;
182 }
183 
184 QString
186 {
187  int x = pos.x();
188 
189  if (!m_model || !m_model->getSampleRate()) return "";
190 
191  TextModel::PointList points = getLocalPoints(v, x, pos.y());
192 
193  if (points.empty()) {
194  if (!m_model->isReady()) {
195  return tr("In progress");
196  } else {
197  return "";
198  }
199  }
200 
201  long useFrame = points.begin()->frame;
202 
203  RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate());
204 
205  QString text;
206 
207  if (points.begin()->label == "") {
208  text = QString(tr("Time:\t%1\nHeight:\t%2\nLabel:\t%3"))
209  .arg(rt.toText(true).c_str())
210  .arg(points.begin()->height)
211  .arg(points.begin()->label);
212  }
213 
214  pos = QPoint(v->getXForFrame(useFrame),
215  getYForHeight(v, points.begin()->height));
216  return text;
217 }
218 
219 
221 
222 bool
224  int &resolution,
225  SnapType snap) const
226 {
227  if (!m_model) {
228  return Layer::snapToFeatureFrame(v, frame, resolution, snap);
229  }
230 
231  resolution = m_model->getResolution();
232  TextModel::PointList points;
233 
234  if (snap == SnapNeighbouring) {
235 
236  points = getLocalPoints(v, v->getXForFrame(frame), -1);
237  if (points.empty()) return false;
238  frame = points.begin()->frame;
239  return true;
240  }
241 
242  points = m_model->getPoints(frame, frame);
243  int snapped = frame;
244  bool found = false;
245 
246  for (TextModel::PointList::const_iterator i = points.begin();
247  i != points.end(); ++i) {
248 
249  if (snap == SnapRight) {
250 
251  if (i->frame > frame) {
252  snapped = i->frame;
253  found = true;
254  break;
255  }
256 
257  } else if (snap == SnapLeft) {
258 
259  if (i->frame <= frame) {
260  snapped = i->frame;
261  found = true; // don't break, as the next may be better
262  } else {
263  break;
264  }
265 
266  } else { // nearest
267 
268  TextModel::PointList::const_iterator j = i;
269  ++j;
270 
271  if (j == points.end()) {
272 
273  snapped = i->frame;
274  found = true;
275  break;
276 
277  } else if (j->frame >= frame) {
278 
279  if (j->frame - frame < frame - i->frame) {
280  snapped = j->frame;
281  } else {
282  snapped = i->frame;
283  }
284  found = true;
285  break;
286  }
287  }
288  }
289 
290  frame = snapped;
291  return found;
292 }
293 
294 int
295 TextLayer::getYForHeight(View *v, float height) const
296 {
297  int h = v->height();
298  return h - int(height * h);
299 }
300 
301 float
303 {
304  int h = v->height();
305  return float(h - y) / h;
306 }
307 
308 void
309 TextLayer::paint(View *v, QPainter &paint, QRect rect) const
310 {
311  if (!m_model || !m_model->isOK()) return;
312 
313  int sampleRate = m_model->getSampleRate();
314  if (!sampleRate) return;
315 
316 // Profiler profiler("TextLayer::paint", true);
317 
318  int x0 = rect.left(), x1 = rect.right();
319  long frame0 = v->getFrameForX(x0);
320  long frame1 = v->getFrameForX(x1);
321 
322  TextModel::PointList points(m_model->getPoints(frame0, frame1));
323  if (points.empty()) return;
324 
325  QColor brushColour(getBaseQColor());
326 
327  int h, s, val;
328  brushColour.getHsv(&h, &s, &val);
329  brushColour.setHsv(h, s, 255, 100);
330 
331  QColor penColour;
332  penColour = v->getForeground();
333 
334 // SVDEBUG << "TextLayer::paint: resolution is "
335 // << m_model->getResolution() << " frames" << endl;
336 
337  QPoint localPos;
338  TextModel::Point illuminatePoint(0);
339  bool shouldIlluminate = false;
340 
341  if (v->shouldIlluminateLocalFeatures(this, localPos)) {
342  shouldIlluminate = getPointToDrag(v, localPos.x(), localPos.y(),
343  illuminatePoint);
344  }
345 
346  int boxMaxWidth = 150;
347  int boxMaxHeight = 200;
348 
349  paint.save();
350  paint.setClipRect(rect.x(), 0, rect.width() + boxMaxWidth, v->height());
351 
352  for (TextModel::PointList::const_iterator i = points.begin();
353  i != points.end(); ++i) {
354 
355  const TextModel::Point &p(*i);
356 
357  int x = v->getXForFrame(p.frame);
358  int y = getYForHeight(v, p.height);
359 
360  if (!shouldIlluminate ||
361  // "illuminatePoint != p"
362  TextModel::Point::Comparator()(illuminatePoint, p) ||
363  TextModel::Point::Comparator()(p, illuminatePoint)) {
364  paint.setPen(penColour);
365  paint.setBrush(brushColour);
366  } else {
367  paint.setBrush(penColour);
368  paint.setPen(v->getBackground());
369  }
370 
371  QString label = p.label;
372  if (label == "") {
373  label = tr("<no text>");
374  }
375 
376  QRect boxRect = paint.fontMetrics().boundingRect
377  (QRect(0, 0, boxMaxWidth, boxMaxHeight),
378  Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, label);
379 
380  QRect textRect = QRect(3, 2, boxRect.width(), boxRect.height());
381  boxRect = QRect(0, 0, boxRect.width() + 6, boxRect.height() + 2);
382 
383  if (y + boxRect.height() > v->height()) {
384  if (boxRect.height() > v->height()) y = 0;
385  else y = v->height() - boxRect.height() - 1;
386  }
387 
388  boxRect = QRect(x, y, boxRect.width(), boxRect.height());
389  textRect = QRect(x + 3, y + 2, textRect.width(), textRect.height());
390 
391 // boxRect = QRect(x, y, boxRect.width(), boxRect.height());
392 // textRect = QRect(x + 3, y + 2, textRect.width(), textRect.height());
393 
394  paint.setRenderHint(QPainter::Antialiasing, false);
395  paint.drawRect(boxRect);
396 
397  paint.setRenderHint(QPainter::Antialiasing, true);
398  paint.drawText(textRect,
399  Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap,
400  label);
401 
405  }
406 
407  paint.restore();
408 
409  // looks like save/restore doesn't deal with this:
410  paint.setRenderHint(QPainter::Antialiasing, false);
411 }
412 
413 void
414 TextLayer::drawStart(View *v, QMouseEvent *e)
415 {
416 // SVDEBUG << "TextLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl;
417 
418  if (!m_model) {
419  SVDEBUG << "TextLayer::drawStart: no model" << endl;
420  return;
421  }
422 
423  long frame = v->getFrameForX(e->x());
424  if (frame < 0) frame = 0;
425  frame = frame / m_model->getResolution() * m_model->getResolution();
426 
427  float height = getHeightForY(v, e->y());
428 
429  m_editingPoint = TextModel::Point(frame, height, "");
431 
433  m_editingCommand = new TextModel::EditCommand(m_model, "Add Label");
434  m_editingCommand->addPoint(m_editingPoint);
435 
436  m_editing = true;
437 }
438 
439 void
440 TextLayer::drawDrag(View *v, QMouseEvent *e)
441 {
442 // SVDEBUG << "TextLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl;
443 
444  if (!m_model || !m_editing) return;
445 
446  long frame = v->getFrameForX(e->x());
447  if (frame < 0) frame = 0;
448  frame = frame / m_model->getResolution() * m_model->getResolution();
449 
450  float height = getHeightForY(v, e->y());
451 
452  m_editingCommand->deletePoint(m_editingPoint);
453  m_editingPoint.frame = frame;
454  m_editingPoint.height = height;
455  m_editingCommand->addPoint(m_editingPoint);
456 }
457 
458 void
459 TextLayer::drawEnd(View *v, QMouseEvent *)
460 {
461 // SVDEBUG << "TextLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl;
462  if (!m_model || !m_editing) return;
463 
464  bool ok = false;
465  QString label = QInputDialog::getText(v, tr("Enter label"),
466  tr("Please enter a new label:"),
467  QLineEdit::Normal, "", &ok);
468 
469  if (ok) {
470  TextModel::RelabelCommand *command =
471  new TextModel::RelabelCommand(m_model, m_editingPoint, label);
472  m_editingCommand->addCommand(command);
473  } else {
474  m_editingCommand->deletePoint(m_editingPoint);
475  }
476 
478  m_editingCommand = 0;
479  m_editing = false;
480 }
481 
482 void
483 TextLayer::eraseStart(View *v, QMouseEvent *e)
484 {
485  if (!m_model) return;
486 
487  if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return;
488 
489  if (m_editingCommand) {
491  m_editingCommand = 0;
492  }
493 
494  m_editing = true;
495 }
496 
497 void
498 TextLayer::eraseDrag(View *, QMouseEvent *)
499 {
500 }
501 
502 void
503 TextLayer::eraseEnd(View *v, QMouseEvent *e)
504 {
505  if (!m_model || !m_editing) return;
506 
507  m_editing = false;
508 
509  TextModel::Point p(0);
510  if (!getPointToDrag(v, e->x(), e->y(), p)) return;
511  if (p.frame != m_editingPoint.frame || p.height != m_editingPoint.height) return;
512 
513  m_editingCommand = new TextModel::EditCommand
514  (m_model, tr("Erase Point"));
515 
516  m_editingCommand->deletePoint(m_editingPoint);
517 
519  m_editingCommand = 0;
520  m_editing = false;
521 }
522 
523 void
524 TextLayer::editStart(View *v, QMouseEvent *e)
525 {
526 // SVDEBUG << "TextLayer::editStart(" << e->x() << "," << e->y() << ")" << endl;
527 
528  if (!m_model) return;
529 
530  if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) {
531  return;
532  }
533 
534  m_editOrigin = e->pos();
536 
537  if (m_editingCommand) {
539  m_editingCommand = 0;
540  }
541 
542  m_editing = true;
543 }
544 
545 void
546 TextLayer::editDrag(View *v, QMouseEvent *e)
547 {
548  if (!m_model || !m_editing) return;
549 
550  long frameDiff = v->getFrameForX(e->x()) - v->getFrameForX(m_editOrigin.x());
551  float heightDiff = getHeightForY(v, e->y()) - getHeightForY(v, m_editOrigin.y());
552 
553  long frame = m_originalPoint.frame + frameDiff;
554  float height = m_originalPoint.height + heightDiff;
555 
556 // long frame = v->getFrameForX(e->x());
557  if (frame < 0) frame = 0;
558  frame = (frame / m_model->getResolution()) * m_model->getResolution();
559 
560 // float height = getHeightForY(v, e->y());
561 
562  if (!m_editingCommand) {
563  m_editingCommand = new TextModel::EditCommand(m_model, tr("Drag Label"));
564  }
565 
566  m_editingCommand->deletePoint(m_editingPoint);
567  m_editingPoint.frame = frame;
568  m_editingPoint.height = height;
569  m_editingCommand->addPoint(m_editingPoint);
570 }
571 
572 void
573 TextLayer::editEnd(View *, QMouseEvent *)
574 {
575 // SVDEBUG << "TextLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl;
576  if (!m_model || !m_editing) return;
577 
578  if (m_editingCommand) {
579 
580  QString newName = m_editingCommand->getName();
581 
582  if (m_editingPoint.frame != m_originalPoint.frame) {
583  if (m_editingPoint.height != m_originalPoint.height) {
584  newName = tr("Move Label");
585  } else {
586  newName = tr("Move Label Horizontally");
587  }
588  } else {
589  newName = tr("Move Label Vertically");
590  }
591 
592  m_editingCommand->setName(newName);
594  }
595 
596  m_editingCommand = 0;
597  m_editing = false;
598 }
599 
600 bool
601 TextLayer::editOpen(View *v, QMouseEvent *e)
602 {
603  if (!m_model) return false;
604 
605  TextModel::Point text(0);
606  if (!getPointToDrag(v, e->x(), e->y(), text)) return false;
607 
608  QString label = text.label;
609 
610  bool ok = false;
611  label = QInputDialog::getText(v, tr("Enter label"),
612  tr("Please enter a new label:"),
613  QLineEdit::Normal, label, &ok);
614  if (ok && label != text.label) {
615  TextModel::RelabelCommand *command =
616  new TextModel::RelabelCommand(m_model, text, label);
618  }
619 
620  return true;
621 }
622 
623 void
624 TextLayer::moveSelection(Selection s, int newStartFrame)
625 {
626  if (!m_model) return;
627 
628  TextModel::EditCommand *command =
629  new TextModel::EditCommand(m_model, tr("Drag Selection"));
630 
631  TextModel::PointList points =
632  m_model->getPoints(s.getStartFrame(), s.getEndFrame());
633 
634  for (TextModel::PointList::iterator i = points.begin();
635  i != points.end(); ++i) {
636 
637  if (s.contains(i->frame)) {
638  TextModel::Point newPoint(*i);
639  newPoint.frame = i->frame + newStartFrame - s.getStartFrame();
640  command->deletePoint(*i);
641  command->addPoint(newPoint);
642  }
643  }
644 
645  finish(command);
646 }
647 
648 void
649 TextLayer::resizeSelection(Selection s, Selection newSize)
650 {
651  if (!m_model) return;
652 
653  TextModel::EditCommand *command =
654  new TextModel::EditCommand(m_model, tr("Resize Selection"));
655 
656  TextModel::PointList points =
657  m_model->getPoints(s.getStartFrame(), s.getEndFrame());
658 
659  double ratio =
660  double(newSize.getEndFrame() - newSize.getStartFrame()) /
661  double(s.getEndFrame() - s.getStartFrame());
662 
663  for (TextModel::PointList::iterator i = points.begin();
664  i != points.end(); ++i) {
665 
666  if (s.contains(i->frame)) {
667 
668  double target = i->frame;
669  target = newSize.getStartFrame() +
670  double(target - s.getStartFrame()) * ratio;
671 
672  TextModel::Point newPoint(*i);
673  newPoint.frame = lrint(target);
674  command->deletePoint(*i);
675  command->addPoint(newPoint);
676  }
677  }
678 
679  finish(command);
680 }
681 
682 void
684 {
685  if (!m_model) return;
686 
687  TextModel::EditCommand *command =
688  new TextModel::EditCommand(m_model, tr("Delete Selection"));
689 
690  TextModel::PointList points =
691  m_model->getPoints(s.getStartFrame(), s.getEndFrame());
692 
693  for (TextModel::PointList::iterator i = points.begin();
694  i != points.end(); ++i) {
695  if (s.contains(i->frame)) command->deletePoint(*i);
696  }
697 
698  finish(command);
699 }
700 
701 void
702 TextLayer::copy(View *v, Selection s, Clipboard &to)
703 {
704  if (!m_model) return;
705 
706  TextModel::PointList points =
707  m_model->getPoints(s.getStartFrame(), s.getEndFrame());
708 
709  for (TextModel::PointList::iterator i = points.begin();
710  i != points.end(); ++i) {
711  if (s.contains(i->frame)) {
712  Clipboard::Point point(i->frame, i->height, i->label);
713  point.setReferenceFrame(alignToReference(v, i->frame));
714  to.addPoint(point);
715  }
716  }
717 }
718 
719 bool
720 TextLayer::paste(View *v, const Clipboard &from, int /* frameOffset */, bool /* interactive */)
721 {
722  if (!m_model) return false;
723 
724  const Clipboard::PointList &points = from.getPoints();
725 
726  bool realign = false;
727 
728  if (clipboardHasDifferentAlignment(v, from)) {
729 
730  QMessageBox::StandardButton button =
731  QMessageBox::question(v, tr("Re-align pasted items?"),
732  tr("The items you are pasting came from a layer with different source material from this one. Do you want to re-align them in time, to match the source material for this layer?"),
733  QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
734  QMessageBox::Yes);
735 
736  if (button == QMessageBox::Cancel) {
737  return false;
738  }
739 
740  if (button == QMessageBox::Yes) {
741  realign = true;
742  }
743  }
744 
745  TextModel::EditCommand *command =
746  new TextModel::EditCommand(m_model, tr("Paste"));
747 
748  float valueMin = 0.0, valueMax = 1.0;
749  for (Clipboard::PointList::const_iterator i = points.begin();
750  i != points.end(); ++i) {
751  if (i->haveValue()) {
752  if (i->getValue() < valueMin) valueMin = i->getValue();
753  if (i->getValue() > valueMax) valueMax = i->getValue();
754  }
755  }
756  if (valueMax < valueMin + 1.0) valueMax = valueMin + 1.0;
757 
758  for (Clipboard::PointList::const_iterator i = points.begin();
759  i != points.end(); ++i) {
760 
761  if (!i->haveFrame()) continue;
762  int frame = 0;
763 
764  if (!realign) {
765 
766  frame = i->getFrame();
767 
768  } else {
769 
770  if (i->haveReferenceFrame()) {
771  frame = i->getReferenceFrame();
772  frame = alignFromReference(v, frame);
773  } else {
774  frame = i->getFrame();
775  }
776  }
777 
778  TextModel::Point newPoint(frame);
779 
780  if (i->haveValue()) {
781  newPoint.height = (i->getValue() - valueMin) / (valueMax - valueMin);
782  } else {
783  newPoint.height = 0.5;
784  }
785 
786  if (i->haveLabel()) {
787  newPoint.label = i->getLabel();
788  } else if (i->haveValue()) {
789  newPoint.label = QString("%1").arg(i->getValue());
790  } else {
791  newPoint.label = tr("New Point");
792  }
793 
794  command->addPoint(newPoint);
795  }
796 
797  finish(command);
798  return true;
799 }
800 
801 int
802 TextLayer::getDefaultColourHint(bool darkbg, bool &impose)
803 {
804  impose = false;
806  (QString(darkbg ? "Bright Orange" : "Orange"));
807 }
808 
809 void
810 TextLayer::toXml(QTextStream &stream,
811  QString indent, QString extraAttributes) const
812 {
813  SingleColourLayer::toXml(stream, indent, extraAttributes);
814 }
815 
816 void
817 TextLayer::setProperties(const QXmlAttributes &attributes)
818 {
820 }
821 
virtual void drawStart(View *v, QMouseEvent *)
Definition: TextLayer.cpp:414
int getFrameForX(int x) const
Return the closest frame to the given pixel x-coordinate.
Definition: View.cpp:363
virtual void paint(View *v, QPainter &paint, QRect rect) const
Paint the given rectangle of this layer onto the given view using the given painter,...
Definition: TextLayer.cpp:309
virtual void deleteSelection(Selection s)
Definition: TextLayer.cpp:683
TextModel::Point m_editingPoint
Definition: TextLayer.h:107
virtual void drawEnd(View *v, QMouseEvent *)
Definition: TextLayer.cpp:459
TextModel::Point m_originalPoint
Definition: TextLayer.h:106
bool getPointToDrag(View *v, int x, int y, TextModel::Point &) const
Definition: TextLayer.cpp:157
virtual bool snapToFeatureFrame(View *, int &, int &resolution, SnapType) const
Adjust the given frame to snap to the nearest feature, if possible.
Definition: Layer.h:183
void connectSignals(const Model *)
Definition: Layer.cpp:49
virtual QColor getForeground() const
Definition: View.cpp:513
void modelReplaced()
void setProperties(const QXmlAttributes &attributes)
Set the particular properties of a layer (those specific to the subclass) from a set of XML attribute...
Definition: TextLayer.cpp:817
void setModel(TextModel *model)
Definition: TextLayer.cpp:47
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.
void addCommand(Command *command)
Add a command to the command history.
virtual bool getValueExtents(float &min, float &max, bool &logarithmic, QString &unit) const
Return the minimum and maximum values for the y axis of the model in this layer, as well as whether t...
Definition: TextLayer.cpp:99
virtual QString getPropertyValueLabel(const PropertyName &, int value) const
Definition: TextLayer.cpp:86
virtual bool shouldIlluminateLocalFeatures(const Layer *, QPoint &) const
Definition: View.h:260
void finish(TextModel::EditCommand *command)
Definition: TextLayer.h:110
virtual void eraseStart(View *v, QMouseEvent *)
Definition: TextLayer.cpp:483
virtual PropertyList getProperties() const
Definition: TextLayer.cpp:60
virtual void eraseDrag(View *v, QMouseEvent *)
Definition: TextLayer.cpp:498
virtual QColor getBaseQColor() const
virtual void editStart(View *v, QMouseEvent *)
Definition: TextLayer.cpp:524
TextModel * m_model
Definition: TextLayer.h:103
virtual void editDrag(View *v, QMouseEvent *)
Definition: TextLayer.cpp:546
int getColourIndex(QString name) const
QPoint m_editOrigin
Definition: TextLayer.h:105
TextModel::PointList getLocalPoints(View *v, int x, int y) const
Definition: TextLayer.cpp:113
virtual void setProperty(const PropertyName &, int value)
Definition: TextLayer.cpp:93
virtual QString getPropertyLabel(const PropertyName &) const
virtual bool snapToFeatureFrame(View *v, int &frame, int &resolution, SnapType snap) const
!! too much overlap with TimeValueLayer/TimeInstantLayer
Definition: TextLayer.cpp:223
virtual int getPropertyRangeAndValue(const PropertyName &, int *min, int *max, int *deflt) const
Definition: TextLayer.cpp:79
virtual void editEnd(View *v, QMouseEvent *)
Definition: TextLayer.cpp:573
virtual void setProperties(const QXmlAttributes &attributes)
Set the particular properties of a layer (those specific to the subclass) from a set of XML attribute...
SnapType
Definition: Layer.h:157
virtual int getPropertyRangeAndValue(const PropertyName &, int *min, int *max, int *deflt) const
static CommandHistory * getInstance()
bool clipboardHasDifferentAlignment(View *v, const Clipboard &clip) const
Definition: Layer.cpp:193
virtual void copy(View *v, Selection s, Clipboard &to)
Definition: TextLayer.cpp:702
int getYForHeight(View *v, float height) const
Definition: TextLayer.cpp:295
virtual PropertyType getPropertyType(const PropertyName &) const
Definition: TextLayer.cpp:73
virtual bool editOpen(View *, QMouseEvent *)
Open an editor on the item under the mouse (e.g.
Definition: TextLayer.cpp:601
virtual int getDefaultColourHint(bool dark, bool &impose)
Definition: TextLayer.cpp:802
virtual void eraseEnd(View *v, QMouseEvent *)
Definition: TextLayer.cpp:503
virtual int alignFromReference(View *v, int frame) const
Definition: Layer.cpp:181
virtual int alignToReference(View *v, int frame) const
Definition: Layer.cpp:169
virtual void drawDrag(View *v, QMouseEvent *)
Definition: TextLayer.cpp:440
View is the base class of widgets that display one or more overlaid views of data against a horizonta...
Definition: View.h:50
virtual void moveSelection(Selection s, int newStartFrame)
Definition: TextLayer.cpp:624
virtual bool isLayerScrollable(const View *v) const
This should return true if the layer can safely be scrolled automatically by a given view (simply cop...
Definition: TextLayer.cpp:105
float getHeightForY(View *v, int y) const
Definition: TextLayer.cpp:302
virtual void resizeSelection(Selection s, Selection newSize)
Definition: TextLayer.cpp:649
virtual QString getPropertyValueLabel(const PropertyName &, int value) const
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: TextLayer.cpp:810
bool m_editing
Definition: TextLayer.h:104
virtual PropertyList getProperties() const
TextModel::EditCommand * m_editingCommand
Definition: TextLayer.h:108
virtual QString getFeatureDescription(View *v, QPoint &) const
Definition: TextLayer.cpp:185
virtual QColor getBackground() const
Definition: View.cpp:493
virtual QString getPropertyLabel(const PropertyName &) const
Definition: TextLayer.cpp:67
virtual PropertyType getPropertyType(const PropertyName &) const
int getXForFrame(int frame) const
Return the pixel x-coordinate corresponding to a given sample frame (which may be negative).
Definition: View.cpp:357
static ColourDatabase * getInstance()
virtual void setProperty(const PropertyName &, int value)
virtual bool paste(View *v, const Clipboard &from, int frameOffset, bool interactive)
Paste from the given clipboard onto the layer at the given frame offset.
Definition: TextLayer.cpp:720