annotate layer/TextLayer.cpp @ 37:21d061e66177

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