annotate layer/TimeInstantLayer.cpp @ 38:beb801473743

* Rearrange spectrogram cacheing so that gain, normalization, instantaneous frequency calculations etc can be done from the cached data (increasing the size of the cache, but also the usability).
author Chris Cannam
date Thu, 23 Feb 2006 18:01:31 +0000
parents 202d1dca67d2
children 78515b1e29eb
rev   line source
Chris@0 1 /* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@0 4 A waveform viewer and audio annotation editor.
Chris@5 5 Chris Cannam, Queen Mary University of London, 2005-2006
Chris@0 6
Chris@0 7 This is experimental software. Not for distribution.
Chris@0 8 */
Chris@0 9
Chris@0 10 #include "TimeInstantLayer.h"
Chris@0 11
Chris@0 12 #include "base/Model.h"
Chris@0 13 #include "base/RealTime.h"
Chris@0 14 #include "base/View.h"
Chris@0 15 #include "base/Profiler.h"
Chris@0 16
Chris@0 17 #include "model/SparseOneDimensionalModel.h"
Chris@0 18
Chris@0 19 #include <QPainter>
Chris@17 20 #include <QMouseEvent>
Chris@0 21
Chris@0 22 #include <iostream>
Chris@0 23
Chris@0 24 TimeInstantLayer::TimeInstantLayer(View *w) :
Chris@0 25 Layer(w),
Chris@0 26 m_model(0),
Chris@18 27 m_editing(false),
Chris@17 28 m_editingPoint(0, tr("New Point")),
Chris@22 29 m_editingCommand(0),
Chris@28 30 m_colour(QColor(200, 50, 255)),
Chris@28 31 m_plotStyle(PlotInstants)
Chris@0 32 {
Chris@0 33 m_view->addLayer(this);
Chris@0 34 }
Chris@0 35
Chris@0 36 void
Chris@0 37 TimeInstantLayer::setModel(SparseOneDimensionalModel *model)
Chris@0 38 {
Chris@0 39 if (m_model == model) return;
Chris@0 40 m_model = model;
Chris@0 41
Chris@0 42 connect(m_model, SIGNAL(modelChanged()), this, SIGNAL(modelChanged()));
Chris@0 43 connect(m_model, SIGNAL(modelChanged(size_t, size_t)),
Chris@0 44 this, SIGNAL(modelChanged(size_t, size_t)));
Chris@0 45
Chris@0 46 connect(m_model, SIGNAL(completionChanged()),
Chris@0 47 this, SIGNAL(modelCompletionChanged()));
Chris@0 48
Chris@0 49 std::cerr << "TimeInstantLayer::setModel(" << model << ")" << std::endl;
Chris@0 50
Chris@0 51 emit modelReplaced();
Chris@0 52 }
Chris@0 53
Chris@0 54 Layer::PropertyList
Chris@0 55 TimeInstantLayer::getProperties() const
Chris@0 56 {
Chris@0 57 PropertyList list;
Chris@0 58 list.push_back(tr("Colour"));
Chris@28 59 list.push_back(tr("Plot Type"));
Chris@0 60 return list;
Chris@0 61 }
Chris@0 62
Chris@0 63 Layer::PropertyType
Chris@20 64 TimeInstantLayer::getPropertyType(const PropertyName &) const
Chris@0 65 {
Chris@0 66 return ValueProperty;
Chris@0 67 }
Chris@0 68
Chris@0 69 int
Chris@0 70 TimeInstantLayer::getPropertyRangeAndValue(const PropertyName &name,
Chris@0 71 int *min, int *max) const
Chris@0 72 {
Chris@0 73 int deft = 0;
Chris@0 74
Chris@0 75 if (name == tr("Colour")) {
Chris@0 76
Chris@10 77 if (min) *min = 0;
Chris@10 78 if (max) *max = 5;
Chris@0 79
Chris@0 80 if (m_colour == Qt::black) deft = 0;
Chris@0 81 else if (m_colour == Qt::darkRed) deft = 1;
Chris@0 82 else if (m_colour == Qt::darkBlue) deft = 2;
Chris@0 83 else if (m_colour == Qt::darkGreen) deft = 3;
Chris@0 84 else if (m_colour == QColor(200, 50, 255)) deft = 4;
Chris@0 85 else if (m_colour == QColor(255, 150, 50)) deft = 5;
Chris@0 86
Chris@28 87 } else if (name == tr("Plot Type")) {
Chris@28 88
Chris@28 89 if (min) *min = 0;
Chris@28 90 if (max) *max = 1;
Chris@28 91
Chris@28 92 deft = int(m_plotStyle);
Chris@28 93
Chris@0 94 } else {
Chris@0 95
Chris@0 96 deft = Layer::getPropertyRangeAndValue(name, min, max);
Chris@0 97 }
Chris@0 98
Chris@0 99 return deft;
Chris@0 100 }
Chris@0 101
Chris@0 102 QString
Chris@0 103 TimeInstantLayer::getPropertyValueLabel(const PropertyName &name,
Chris@0 104 int value) const
Chris@0 105 {
Chris@0 106 if (name == tr("Colour")) {
Chris@0 107 switch (value) {
Chris@0 108 default:
Chris@0 109 case 0: return tr("Black");
Chris@0 110 case 1: return tr("Red");
Chris@0 111 case 2: return tr("Blue");
Chris@0 112 case 3: return tr("Green");
Chris@0 113 case 4: return tr("Purple");
Chris@0 114 case 5: return tr("Orange");
Chris@0 115 }
Chris@28 116 } else if (name == tr("Plot Type")) {
Chris@28 117 switch (value) {
Chris@28 118 default:
Chris@28 119 case 0: return tr("Instants");
Chris@28 120 case 1: return tr("Segmentation");
Chris@28 121 }
Chris@0 122 }
Chris@0 123 return tr("<unknown>");
Chris@0 124 }
Chris@0 125
Chris@0 126 void
Chris@0 127 TimeInstantLayer::setProperty(const PropertyName &name, int value)
Chris@0 128 {
Chris@0 129 if (name == tr("Colour")) {
Chris@0 130 switch (value) {
Chris@0 131 default:
Chris@0 132 case 0: setBaseColour(Qt::black); break;
Chris@0 133 case 1: setBaseColour(Qt::darkRed); break;
Chris@0 134 case 2: setBaseColour(Qt::darkBlue); break;
Chris@0 135 case 3: setBaseColour(Qt::darkGreen); break;
Chris@0 136 case 4: setBaseColour(QColor(200, 50, 255)); break;
Chris@0 137 case 5: setBaseColour(QColor(255, 150, 50)); break;
Chris@0 138 }
Chris@28 139 } else if (name == tr("Plot Type")) {
Chris@28 140 setPlotStyle(PlotStyle(value));
Chris@0 141 }
Chris@0 142 }
Chris@0 143
Chris@0 144 void
Chris@0 145 TimeInstantLayer::setBaseColour(QColor colour)
Chris@0 146 {
Chris@0 147 if (m_colour == colour) return;
Chris@0 148 m_colour = colour;
Chris@0 149 emit layerParametersChanged();
Chris@0 150 }
Chris@0 151
Chris@28 152 void
Chris@28 153 TimeInstantLayer::setPlotStyle(PlotStyle style)
Chris@28 154 {
Chris@28 155 if (m_plotStyle == style) return;
Chris@28 156 m_plotStyle = style;
Chris@28 157 emit layerParametersChanged();
Chris@28 158 }
Chris@28 159
Chris@0 160 bool
Chris@0 161 TimeInstantLayer::isLayerScrollable() const
Chris@0 162 {
Chris@0 163 QPoint discard;
Chris@0 164 return !m_view->shouldIlluminateLocalFeatures(this, discard);
Chris@0 165 }
Chris@0 166
Chris@0 167 SparseOneDimensionalModel::PointList
Chris@0 168 TimeInstantLayer::getLocalPoints(int x) const
Chris@0 169 {
Chris@28 170 // Return a set of points that all have the same frame number, the
Chris@28 171 // nearest to the given x coordinate, and that are within a
Chris@28 172 // certain fuzz distance of that x coordinate.
Chris@28 173
Chris@0 174 if (!m_model) return SparseOneDimensionalModel::PointList();
Chris@0 175
Chris@20 176 long frame = getFrameForX(x);
Chris@0 177
Chris@0 178 SparseOneDimensionalModel::PointList onPoints =
Chris@0 179 m_model->getPoints(frame);
Chris@0 180
Chris@0 181 if (!onPoints.empty()) {
Chris@0 182 return onPoints;
Chris@0 183 }
Chris@0 184
Chris@0 185 SparseOneDimensionalModel::PointList prevPoints =
Chris@0 186 m_model->getPreviousPoints(frame);
Chris@0 187 SparseOneDimensionalModel::PointList nextPoints =
Chris@0 188 m_model->getNextPoints(frame);
Chris@0 189
Chris@0 190 SparseOneDimensionalModel::PointList usePoints = prevPoints;
Chris@0 191
Chris@0 192 if (prevPoints.empty()) {
Chris@0 193 usePoints = nextPoints;
Chris@20 194 } else if (prevPoints.begin()->frame < m_view->getStartFrame() &&
Chris@20 195 !(nextPoints.begin()->frame > m_view->getEndFrame())) {
Chris@0 196 usePoints = nextPoints;
Chris@0 197 } else if (nextPoints.begin()->frame - frame <
Chris@0 198 frame - prevPoints.begin()->frame) {
Chris@0 199 usePoints = nextPoints;
Chris@0 200 }
Chris@0 201
Chris@28 202 if (!usePoints.empty()) {
Chris@28 203 int fuzz = 2;
Chris@28 204 int px = getXForFrame(usePoints.begin()->frame);
Chris@28 205 if ((px > x && px - x > fuzz) ||
Chris@28 206 (px < x && x - px > fuzz + 1)) {
Chris@28 207 usePoints.clear();
Chris@28 208 }
Chris@28 209 }
Chris@28 210
Chris@0 211 return usePoints;
Chris@0 212 }
Chris@0 213
Chris@25 214 QString
Chris@25 215 TimeInstantLayer::getFeatureDescription(QPoint &pos) const
Chris@0 216 {
Chris@25 217 int x = pos.x();
Chris@0 218
Chris@25 219 if (!m_model || !m_model->getSampleRate()) return "";
Chris@0 220
Chris@0 221 SparseOneDimensionalModel::PointList points = getLocalPoints(x);
Chris@0 222
Chris@0 223 if (points.empty()) {
Chris@0 224 if (!m_model->isReady()) {
Chris@25 225 return tr("In progress");
Chris@25 226 } else {
Chris@25 227 return tr("No local points");
Chris@0 228 }
Chris@0 229 }
Chris@0 230
Chris@0 231 long useFrame = points.begin()->frame;
Chris@0 232
Chris@0 233 RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate());
Chris@25 234
Chris@25 235 QString text;
Chris@0 236
Chris@25 237 if (points.begin()->label == "") {
Chris@25 238 text = QString(tr("Time:\t%1\nNo label"))
Chris@25 239 .arg(rt.toText(true).c_str());
Chris@25 240 } else {
Chris@25 241 text = QString(tr("Time:\t%1\nLabel:\t%2"))
Chris@25 242 .arg(rt.toText(true).c_str())
Chris@25 243 .arg(points.begin()->label);
Chris@25 244 }
Chris@0 245
Chris@25 246 pos = QPoint(getXForFrame(useFrame), pos.y());
Chris@25 247 return text;
Chris@0 248 }
Chris@0 249
Chris@28 250 bool
Chris@28 251 TimeInstantLayer::snapToFeatureFrame(int &frame,
Chris@28 252 size_t &resolution,
Chris@28 253 SnapType snap) const
Chris@13 254 {
Chris@13 255 if (!m_model) {
Chris@28 256 return Layer::snapToFeatureFrame(frame, resolution, snap);
Chris@13 257 }
Chris@13 258
Chris@13 259 resolution = m_model->getResolution();
Chris@28 260 SparseOneDimensionalModel::PointList points;
Chris@13 261
Chris@28 262 if (snap == SnapNeighbouring) {
Chris@28 263
Chris@28 264 points = getLocalPoints(getXForFrame(frame));
Chris@28 265 if (points.empty()) return false;
Chris@28 266 frame = points.begin()->frame;
Chris@28 267 return true;
Chris@28 268 }
Chris@28 269
Chris@28 270 points = m_model->getPoints(frame, frame);
Chris@28 271 int snapped = frame;
Chris@28 272 bool found = false;
Chris@13 273
Chris@13 274 for (SparseOneDimensionalModel::PointList::const_iterator i = points.begin();
Chris@13 275 i != points.end(); ++i) {
Chris@13 276
Chris@28 277 if (snap == SnapRight) {
Chris@28 278
Chris@28 279 if (i->frame >= frame) {
Chris@28 280 snapped = i->frame;
Chris@28 281 found = true;
Chris@13 282 break;
Chris@13 283 }
Chris@28 284
Chris@28 285 } else if (snap == SnapLeft) {
Chris@28 286
Chris@13 287 if (i->frame <= frame) {
Chris@28 288 snapped = i->frame;
Chris@28 289 found = true; // don't break, as the next may be better
Chris@28 290 } else {
Chris@28 291 break;
Chris@28 292 }
Chris@28 293
Chris@28 294 } else { // nearest
Chris@28 295
Chris@28 296 SparseOneDimensionalModel::PointList::const_iterator j = i;
Chris@28 297 ++j;
Chris@28 298
Chris@28 299 if (j == points.end()) {
Chris@28 300
Chris@28 301 snapped = i->frame;
Chris@28 302 found = true;
Chris@28 303 break;
Chris@28 304
Chris@28 305 } else if (j->frame >= frame) {
Chris@28 306
Chris@28 307 if (j->frame - frame < frame - i->frame) {
Chris@28 308 snapped = j->frame;
Chris@28 309 } else {
Chris@28 310 snapped = i->frame;
Chris@28 311 }
Chris@28 312 found = true;
Chris@28 313 break;
Chris@13 314 }
Chris@13 315 }
Chris@13 316 }
Chris@13 317
Chris@28 318 frame = snapped;
Chris@28 319 return found;
Chris@13 320 }
Chris@13 321
Chris@0 322 void
Chris@0 323 TimeInstantLayer::paint(QPainter &paint, QRect rect) const
Chris@0 324 {
Chris@0 325 if (!m_model || !m_model->isOK()) return;
Chris@0 326
Chris@0 327 // Profiler profiler("TimeInstantLayer::paint", true);
Chris@0 328
Chris@20 329 int x0 = rect.left(), x1 = rect.right();
Chris@0 330
Chris@20 331 long frame0 = getFrameForX(x0);
Chris@20 332 long frame1 = getFrameForX(x1);
Chris@0 333
Chris@0 334 SparseOneDimensionalModel::PointList points(m_model->getPoints
Chris@0 335 (frame0, frame1));
Chris@0 336
Chris@28 337 bool odd = false;
Chris@28 338 if (m_plotStyle == PlotSegmentation && !points.empty()) {
Chris@28 339 int index = m_model->getIndexOf(*points.begin());
Chris@28 340 odd = ((index % 2) == 1);
Chris@28 341 }
Chris@28 342
Chris@0 343 paint.setPen(m_colour);
Chris@0 344
Chris@0 345 QColor brushColour(m_colour);
Chris@0 346 brushColour.setAlpha(100);
Chris@0 347 paint.setBrush(brushColour);
Chris@0 348
Chris@28 349 QColor oddBrushColour(brushColour);
Chris@28 350 if (m_plotStyle == PlotSegmentation) {
Chris@28 351 if (m_colour == Qt::black) {
Chris@28 352 oddBrushColour = Qt::gray;
Chris@28 353 } else if (m_colour == Qt::darkRed) {
Chris@28 354 oddBrushColour = Qt::red;
Chris@28 355 } else if (m_colour == Qt::darkBlue) {
Chris@28 356 oddBrushColour = Qt::blue;
Chris@28 357 } else if (m_colour == Qt::darkGreen) {
Chris@28 358 oddBrushColour = Qt::green;
Chris@28 359 } else {
Chris@28 360 oddBrushColour = oddBrushColour.light(150);
Chris@28 361 }
Chris@28 362 oddBrushColour.setAlpha(100);
Chris@28 363 }
Chris@28 364
Chris@0 365 // std::cerr << "TimeInstantLayer::paint: resolution is "
Chris@0 366 // << m_model->getResolution() << " frames" << std::endl;
Chris@0 367
Chris@0 368 QPoint localPos;
Chris@0 369 long illuminateFrame = -1;
Chris@0 370
Chris@0 371 if (m_view->shouldIlluminateLocalFeatures(this, localPos)) {
Chris@0 372 SparseOneDimensionalModel::PointList localPoints =
Chris@0 373 getLocalPoints(localPos.x());
Chris@0 374 if (!localPoints.empty()) illuminateFrame = localPoints.begin()->frame;
Chris@0 375 }
Chris@0 376
Chris@23 377 int prevX = -1;
Chris@23 378
Chris@0 379 for (SparseOneDimensionalModel::PointList::const_iterator i = points.begin();
Chris@0 380 i != points.end(); ++i) {
Chris@0 381
Chris@0 382 const SparseOneDimensionalModel::Point &p(*i);
Chris@17 383 SparseOneDimensionalModel::PointList::const_iterator j = i;
Chris@17 384 ++j;
Chris@0 385
Chris@20 386 int x = getXForFrame(p.frame);
Chris@23 387 if (x == prevX && p.frame != illuminateFrame) continue;
Chris@23 388
Chris@20 389 int iw = getXForFrame(p.frame + m_model->getResolution()) - x;
Chris@16 390 if (iw < 2) {
Chris@17 391 if (iw < 1) {
Chris@17 392 iw = 2;
Chris@17 393 if (j != points.end()) {
Chris@20 394 int nx = getXForFrame(j->frame);
Chris@17 395 if (nx < x + 3) iw = 1;
Chris@17 396 }
Chris@17 397 } else {
Chris@17 398 iw = 2;
Chris@17 399 }
Chris@16 400 }
Chris@20 401
Chris@0 402 if (p.frame == illuminateFrame) {
Chris@0 403 paint.setPen(Qt::black); //!!!
Chris@0 404 } else {
Chris@0 405 paint.setPen(brushColour);
Chris@0 406 }
Chris@23 407
Chris@28 408 if (m_plotStyle == PlotInstants) {
Chris@28 409 if (iw > 1) {
Chris@28 410 paint.drawRect(x, 0, iw - 1, m_view->height() - 1);
Chris@28 411 } else {
Chris@28 412 paint.drawLine(x, 0, x, m_view->height() - 1);
Chris@28 413 }
Chris@23 414 } else {
Chris@28 415
Chris@28 416 if (odd) paint.setBrush(oddBrushColour);
Chris@28 417 else paint.setBrush(brushColour);
Chris@28 418
Chris@28 419 int nx;
Chris@28 420
Chris@28 421 if (j != points.end()) {
Chris@28 422 const SparseOneDimensionalModel::Point &q(*j);
Chris@28 423 nx = getXForFrame(q.frame);
Chris@28 424 } else {
Chris@28 425 nx = getXForFrame(m_model->getEndFrame());
Chris@28 426 }
Chris@28 427
Chris@28 428 if (nx >= x) {
Chris@28 429
Chris@28 430 if (illuminateFrame != p.frame &&
Chris@28 431 (nx < x + 5 || x >= m_view->width() - 1)) {
Chris@28 432 paint.setPen(Qt::NoPen);
Chris@28 433 }
Chris@28 434
Chris@28 435 paint.drawRect(x, -1, nx - x, m_view->height() + 1);
Chris@28 436 }
Chris@28 437
Chris@28 438 odd = !odd;
Chris@23 439 }
Chris@28 440
Chris@0 441 paint.setPen(m_colour);
Chris@0 442
Chris@0 443 if (p.label != "") {
Chris@0 444
Chris@0 445 // only draw if there's enough room from here to the next point
Chris@0 446
Chris@0 447 int lw = paint.fontMetrics().width(p.label);
Chris@0 448 bool good = true;
Chris@0 449
Chris@17 450 if (j != points.end()) {
Chris@20 451 int nx = getXForFrame(j->frame);
Chris@20 452 if (nx >= x && nx - x - iw - 3 <= lw) good = false;
Chris@0 453 }
Chris@0 454
Chris@0 455 if (good) {
Chris@20 456 paint.drawText(x + iw + 2,
Chris@0 457 m_view->height() - paint.fontMetrics().height(),
Chris@0 458 p.label);
Chris@0 459 }
Chris@0 460 }
Chris@23 461
Chris@23 462 prevX = x;
Chris@0 463 }
Chris@0 464 }
Chris@0 465
Chris@17 466 void
Chris@17 467 TimeInstantLayer::drawStart(QMouseEvent *e)
Chris@17 468 {
Chris@17 469 std::cerr << "TimeInstantLayer::drawStart(" << e->x() << ")" << std::endl;
Chris@17 470
Chris@17 471 if (!m_model) return;
Chris@17 472
Chris@20 473 long frame = getFrameForX(e->x());
Chris@17 474 if (frame < 0) frame = 0;
Chris@21 475 frame = frame / m_model->getResolution() * m_model->getResolution();
Chris@22 476
Chris@17 477 m_editingPoint = SparseOneDimensionalModel::Point(frame, tr("New Point"));
Chris@22 478
Chris@22 479 if (m_editingCommand) m_editingCommand->finish();
Chris@22 480 m_editingCommand = new SparseOneDimensionalModel::EditCommand(m_model,
Chris@22 481 tr("Draw Point"));
Chris@22 482 m_editingCommand->addPoint(m_editingPoint);
Chris@22 483
Chris@18 484 m_editing = true;
Chris@17 485 }
Chris@17 486
Chris@17 487 void
Chris@17 488 TimeInstantLayer::drawDrag(QMouseEvent *e)
Chris@17 489 {
Chris@17 490 std::cerr << "TimeInstantLayer::drawDrag(" << e->x() << ")" << std::endl;
Chris@17 491
Chris@18 492 if (!m_model || !m_editing) return;
Chris@17 493
Chris@20 494 long frame = getFrameForX(e->x());
Chris@17 495 if (frame < 0) frame = 0;
Chris@21 496 frame = frame / m_model->getResolution() * m_model->getResolution();
Chris@22 497 m_editingCommand->deletePoint(m_editingPoint);
Chris@17 498 m_editingPoint.frame = frame;
Chris@22 499 m_editingCommand->addPoint(m_editingPoint);
Chris@17 500 }
Chris@17 501
Chris@17 502 void
Chris@17 503 TimeInstantLayer::drawEnd(QMouseEvent *e)
Chris@17 504 {
Chris@17 505 std::cerr << "TimeInstantLayer::drawEnd(" << e->x() << ")" << std::endl;
Chris@18 506 if (!m_model || !m_editing) return;
Chris@23 507 QString newName = tr("Add Point at %1 s")
Chris@23 508 .arg(RealTime::frame2RealTime(m_editingPoint.frame,
Chris@23 509 m_model->getSampleRate())
Chris@23 510 .toText(false).c_str());
Chris@23 511 m_editingCommand->setName(newName);
Chris@22 512 m_editingCommand->finish();
Chris@22 513 m_editingCommand = 0;
Chris@18 514 m_editing = false;
Chris@18 515 }
Chris@18 516
Chris@18 517 void
Chris@18 518 TimeInstantLayer::editStart(QMouseEvent *e)
Chris@18 519 {
Chris@18 520 std::cerr << "TimeInstantLayer::editStart(" << e->x() << ")" << std::endl;
Chris@18 521
Chris@17 522 if (!m_model) return;
Chris@18 523
Chris@18 524 SparseOneDimensionalModel::PointList points = getLocalPoints(e->x());
Chris@18 525 if (points.empty()) return;
Chris@18 526
Chris@18 527 m_editingPoint = *points.begin();
Chris@22 528
Chris@22 529 if (m_editingCommand) {
Chris@22 530 m_editingCommand->finish();
Chris@22 531 m_editingCommand = 0;
Chris@22 532 }
Chris@22 533
Chris@18 534 m_editing = true;
Chris@18 535 }
Chris@18 536
Chris@18 537 void
Chris@18 538 TimeInstantLayer::editDrag(QMouseEvent *e)
Chris@18 539 {
Chris@18 540 std::cerr << "TimeInstantLayer::editDrag(" << e->x() << ")" << std::endl;
Chris@18 541
Chris@18 542 if (!m_model || !m_editing) return;
Chris@18 543
Chris@20 544 long frame = getFrameForX(e->x());
Chris@18 545 if (frame < 0) frame = 0;
Chris@21 546 frame = frame / m_model->getResolution() * m_model->getResolution();
Chris@22 547
Chris@22 548 if (!m_editingCommand) {
Chris@22 549 m_editingCommand = new SparseOneDimensionalModel::EditCommand(m_model,
Chris@22 550 tr("Drag Point"));
Chris@22 551 }
Chris@22 552
Chris@22 553 m_editingCommand->deletePoint(m_editingPoint);
Chris@18 554 m_editingPoint.frame = frame;
Chris@22 555 m_editingCommand->addPoint(m_editingPoint);
Chris@18 556 }
Chris@18 557
Chris@18 558 void
Chris@18 559 TimeInstantLayer::editEnd(QMouseEvent *e)
Chris@18 560 {
Chris@18 561 std::cerr << "TimeInstantLayer::editEnd(" << e->x() << ")" << std::endl;
Chris@18 562 if (!m_model || !m_editing) return;
Chris@23 563 if (m_editingCommand) {
Chris@23 564 QString newName = tr("Move Point to %1 s")
Chris@23 565 .arg(RealTime::frame2RealTime(m_editingPoint.frame,
Chris@23 566 m_model->getSampleRate())
Chris@23 567 .toText(false).c_str());
Chris@23 568 m_editingCommand->setName(newName);
Chris@23 569 m_editingCommand->finish();
Chris@23 570 }
Chris@22 571 m_editingCommand = 0;
Chris@18 572 m_editing = false;
Chris@17 573 }
Chris@17 574
Chris@6 575 QString
Chris@6 576 TimeInstantLayer::toXmlString(QString indent, QString extraAttributes) const
Chris@6 577 {
Chris@6 578 return Layer::toXmlString(indent, extraAttributes +
Chris@28 579 QString(" colour=\"%1\" plotStyle=\"%2\"")
Chris@28 580 .arg(encodeColour(m_colour)).arg(m_plotStyle));
Chris@6 581 }
Chris@0 582
Chris@11 583 void
Chris@11 584 TimeInstantLayer::setProperties(const QXmlAttributes &attributes)
Chris@11 585 {
Chris@11 586 QString colourSpec = attributes.value("colour");
Chris@11 587 if (colourSpec != "") {
Chris@11 588 QColor colour(colourSpec);
Chris@11 589 if (colour.isValid()) {
Chris@11 590 setBaseColour(QColor(colourSpec));
Chris@11 591 }
Chris@11 592 }
Chris@28 593
Chris@28 594 bool ok;
Chris@28 595 PlotStyle style = (PlotStyle)
Chris@28 596 attributes.value("plotStyle").toInt(&ok);
Chris@28 597 if (ok) setPlotStyle(style);
Chris@11 598 }
Chris@11 599
Chris@0 600 #ifdef INCLUDE_MOCFILES
Chris@0 601 #include "TimeInstantLayer.moc.cpp"
Chris@0 602 #endif
Chris@0 603