svgui
1.9
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 Sonic Visualiser 00005 An audio file viewer and annotation editor. 00006 Centre for Digital Music, Queen Mary, University of London. 00007 This file copyright 2006 Chris Cannam. 00008 00009 This program is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU General Public License as 00011 published by the Free Software Foundation; either version 2 of the 00012 License, or (at your option) any later version. See the file 00013 COPYING included with this distribution for more information. 00014 */ 00015 00016 #include "TextLayer.h" 00017 00018 #include "data/model/Model.h" 00019 #include "base/RealTime.h" 00020 #include "base/Profiler.h" 00021 #include "ColourDatabase.h" 00022 #include "view/View.h" 00023 00024 #include "data/model/TextModel.h" 00025 00026 #include <QPainter> 00027 #include <QMouseEvent> 00028 #include <QInputDialog> 00029 #include <QTextStream> 00030 #include <QMessageBox> 00031 00032 #include <iostream> 00033 #include <cmath> 00034 00035 TextLayer::TextLayer() : 00036 SingleColourLayer(), 00037 m_model(0), 00038 m_editing(false), 00039 m_originalPoint(0, 0.0, tr("Empty Label")), 00040 m_editingPoint(0, 0.0, tr("Empty Label")), 00041 m_editingCommand(0) 00042 { 00043 00044 } 00045 00046 void 00047 TextLayer::setModel(TextModel *model) 00048 { 00049 if (m_model == model) return; 00050 m_model = model; 00051 00052 connectSignals(m_model); 00053 00054 // SVDEBUG << "TextLayer::setModel(" << model << ")" << endl; 00055 00056 emit modelReplaced(); 00057 } 00058 00059 Layer::PropertyList 00060 TextLayer::getProperties() const 00061 { 00062 PropertyList list = SingleColourLayer::getProperties(); 00063 return list; 00064 } 00065 00066 QString 00067 TextLayer::getPropertyLabel(const PropertyName &name) const 00068 { 00069 return SingleColourLayer::getPropertyLabel(name); 00070 } 00071 00072 Layer::PropertyType 00073 TextLayer::getPropertyType(const PropertyName &name) const 00074 { 00075 return SingleColourLayer::getPropertyType(name); 00076 } 00077 00078 int 00079 TextLayer::getPropertyRangeAndValue(const PropertyName &name, 00080 int *min, int *max, int *deflt) const 00081 { 00082 return SingleColourLayer::getPropertyRangeAndValue(name, min, max, deflt); 00083 } 00084 00085 QString 00086 TextLayer::getPropertyValueLabel(const PropertyName &name, 00087 int value) const 00088 { 00089 return SingleColourLayer::getPropertyValueLabel(name, value); 00090 } 00091 00092 void 00093 TextLayer::setProperty(const PropertyName &name, int value) 00094 { 00095 SingleColourLayer::setProperty(name, value); 00096 } 00097 00098 bool 00099 TextLayer::getValueExtents(float &, float &, bool &, QString &) const 00100 { 00101 return false; 00102 } 00103 00104 bool 00105 TextLayer::isLayerScrollable(const View *v) const 00106 { 00107 QPoint discard; 00108 return !v->shouldIlluminateLocalFeatures(this, discard); 00109 } 00110 00111 00112 TextModel::PointList 00113 TextLayer::getLocalPoints(View *v, int x, int y) const 00114 { 00115 if (!m_model) return TextModel::PointList(); 00116 00117 long frame0 = v->getFrameForX(-150); 00118 long frame1 = v->getFrameForX(v->width() + 150); 00119 00120 TextModel::PointList points(m_model->getPoints(frame0, frame1)); 00121 00122 TextModel::PointList rv; 00123 QFontMetrics metrics = QFontMetrics(QFont()); 00124 00125 for (TextModel::PointList::iterator i = points.begin(); 00126 i != points.end(); ++i) { 00127 00128 const TextModel::Point &p(*i); 00129 00130 int px = v->getXForFrame(p.frame); 00131 int py = getYForHeight(v, p.height); 00132 00133 QString label = p.label; 00134 if (label == "") { 00135 label = tr("<no text>"); 00136 } 00137 00138 QRect rect = metrics.boundingRect 00139 (QRect(0, 0, 150, 200), 00140 Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, label); 00141 00142 if (py + rect.height() > v->height()) { 00143 if (rect.height() > v->height()) py = 0; 00144 else py = v->height() - rect.height() - 1; 00145 } 00146 00147 if (x >= px && x < px + rect.width() && 00148 y >= py && y < py + rect.height()) { 00149 rv.insert(p); 00150 } 00151 } 00152 00153 return rv; 00154 } 00155 00156 bool 00157 TextLayer::getPointToDrag(View *v, int x, int y, TextModel::Point &p) const 00158 { 00159 if (!m_model) return false; 00160 00161 long a = v->getFrameForX(x - 120); 00162 long b = v->getFrameForX(x + 10); 00163 TextModel::PointList onPoints = m_model->getPoints(a, b); 00164 if (onPoints.empty()) return false; 00165 00166 float nearestDistance = -1; 00167 00168 for (TextModel::PointList::const_iterator i = onPoints.begin(); 00169 i != onPoints.end(); ++i) { 00170 00171 int yd = getYForHeight(v, (*i).height) - y; 00172 int xd = v->getXForFrame((*i).frame) - x; 00173 float distance = sqrtf(yd*yd + xd*xd); 00174 00175 if (nearestDistance == -1 || distance < nearestDistance) { 00176 nearestDistance = distance; 00177 p = *i; 00178 } 00179 } 00180 00181 return true; 00182 } 00183 00184 QString 00185 TextLayer::getFeatureDescription(View *v, QPoint &pos) const 00186 { 00187 int x = pos.x(); 00188 00189 if (!m_model || !m_model->getSampleRate()) return ""; 00190 00191 TextModel::PointList points = getLocalPoints(v, x, pos.y()); 00192 00193 if (points.empty()) { 00194 if (!m_model->isReady()) { 00195 return tr("In progress"); 00196 } else { 00197 return ""; 00198 } 00199 } 00200 00201 long useFrame = points.begin()->frame; 00202 00203 RealTime rt = RealTime::frame2RealTime(useFrame, m_model->getSampleRate()); 00204 00205 QString text; 00206 00207 if (points.begin()->label == "") { 00208 text = QString(tr("Time:\t%1\nHeight:\t%2\nLabel:\t%3")) 00209 .arg(rt.toText(true).c_str()) 00210 .arg(points.begin()->height) 00211 .arg(points.begin()->label); 00212 } 00213 00214 pos = QPoint(v->getXForFrame(useFrame), 00215 getYForHeight(v, points.begin()->height)); 00216 return text; 00217 } 00218 00219 00221 00222 bool 00223 TextLayer::snapToFeatureFrame(View *v, int &frame, 00224 int &resolution, 00225 SnapType snap) const 00226 { 00227 if (!m_model) { 00228 return Layer::snapToFeatureFrame(v, frame, resolution, snap); 00229 } 00230 00231 resolution = m_model->getResolution(); 00232 TextModel::PointList points; 00233 00234 if (snap == SnapNeighbouring) { 00235 00236 points = getLocalPoints(v, v->getXForFrame(frame), -1); 00237 if (points.empty()) return false; 00238 frame = points.begin()->frame; 00239 return true; 00240 } 00241 00242 points = m_model->getPoints(frame, frame); 00243 int snapped = frame; 00244 bool found = false; 00245 00246 for (TextModel::PointList::const_iterator i = points.begin(); 00247 i != points.end(); ++i) { 00248 00249 if (snap == SnapRight) { 00250 00251 if (i->frame > frame) { 00252 snapped = i->frame; 00253 found = true; 00254 break; 00255 } 00256 00257 } else if (snap == SnapLeft) { 00258 00259 if (i->frame <= frame) { 00260 snapped = i->frame; 00261 found = true; // don't break, as the next may be better 00262 } else { 00263 break; 00264 } 00265 00266 } else { // nearest 00267 00268 TextModel::PointList::const_iterator j = i; 00269 ++j; 00270 00271 if (j == points.end()) { 00272 00273 snapped = i->frame; 00274 found = true; 00275 break; 00276 00277 } else if (j->frame >= frame) { 00278 00279 if (j->frame - frame < frame - i->frame) { 00280 snapped = j->frame; 00281 } else { 00282 snapped = i->frame; 00283 } 00284 found = true; 00285 break; 00286 } 00287 } 00288 } 00289 00290 frame = snapped; 00291 return found; 00292 } 00293 00294 int 00295 TextLayer::getYForHeight(View *v, float height) const 00296 { 00297 int h = v->height(); 00298 return h - int(height * h); 00299 } 00300 00301 float 00302 TextLayer::getHeightForY(View *v, int y) const 00303 { 00304 int h = v->height(); 00305 return float(h - y) / h; 00306 } 00307 00308 void 00309 TextLayer::paint(View *v, QPainter &paint, QRect rect) const 00310 { 00311 if (!m_model || !m_model->isOK()) return; 00312 00313 int sampleRate = m_model->getSampleRate(); 00314 if (!sampleRate) return; 00315 00316 // Profiler profiler("TextLayer::paint", true); 00317 00318 int x0 = rect.left(), x1 = rect.right(); 00319 long frame0 = v->getFrameForX(x0); 00320 long frame1 = v->getFrameForX(x1); 00321 00322 TextModel::PointList points(m_model->getPoints(frame0, frame1)); 00323 if (points.empty()) return; 00324 00325 QColor brushColour(getBaseQColor()); 00326 00327 int h, s, val; 00328 brushColour.getHsv(&h, &s, &val); 00329 brushColour.setHsv(h, s, 255, 100); 00330 00331 QColor penColour; 00332 penColour = v->getForeground(); 00333 00334 // SVDEBUG << "TextLayer::paint: resolution is " 00335 // << m_model->getResolution() << " frames" << endl; 00336 00337 QPoint localPos; 00338 TextModel::Point illuminatePoint(0); 00339 bool shouldIlluminate = false; 00340 00341 if (v->shouldIlluminateLocalFeatures(this, localPos)) { 00342 shouldIlluminate = getPointToDrag(v, localPos.x(), localPos.y(), 00343 illuminatePoint); 00344 } 00345 00346 int boxMaxWidth = 150; 00347 int boxMaxHeight = 200; 00348 00349 paint.save(); 00350 paint.setClipRect(rect.x(), 0, rect.width() + boxMaxWidth, v->height()); 00351 00352 for (TextModel::PointList::const_iterator i = points.begin(); 00353 i != points.end(); ++i) { 00354 00355 const TextModel::Point &p(*i); 00356 00357 int x = v->getXForFrame(p.frame); 00358 int y = getYForHeight(v, p.height); 00359 00360 if (!shouldIlluminate || 00361 // "illuminatePoint != p" 00362 TextModel::Point::Comparator()(illuminatePoint, p) || 00363 TextModel::Point::Comparator()(p, illuminatePoint)) { 00364 paint.setPen(penColour); 00365 paint.setBrush(brushColour); 00366 } else { 00367 paint.setBrush(penColour); 00368 paint.setPen(v->getBackground()); 00369 } 00370 00371 QString label = p.label; 00372 if (label == "") { 00373 label = tr("<no text>"); 00374 } 00375 00376 QRect boxRect = paint.fontMetrics().boundingRect 00377 (QRect(0, 0, boxMaxWidth, boxMaxHeight), 00378 Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, label); 00379 00380 QRect textRect = QRect(3, 2, boxRect.width(), boxRect.height()); 00381 boxRect = QRect(0, 0, boxRect.width() + 6, boxRect.height() + 2); 00382 00383 if (y + boxRect.height() > v->height()) { 00384 if (boxRect.height() > v->height()) y = 0; 00385 else y = v->height() - boxRect.height() - 1; 00386 } 00387 00388 boxRect = QRect(x, y, boxRect.width(), boxRect.height()); 00389 textRect = QRect(x + 3, y + 2, textRect.width(), textRect.height()); 00390 00391 // boxRect = QRect(x, y, boxRect.width(), boxRect.height()); 00392 // textRect = QRect(x + 3, y + 2, textRect.width(), textRect.height()); 00393 00394 paint.setRenderHint(QPainter::Antialiasing, false); 00395 paint.drawRect(boxRect); 00396 00397 paint.setRenderHint(QPainter::Antialiasing, true); 00398 paint.drawText(textRect, 00399 Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, 00400 label); 00401 00405 } 00406 00407 paint.restore(); 00408 00409 // looks like save/restore doesn't deal with this: 00410 paint.setRenderHint(QPainter::Antialiasing, false); 00411 } 00412 00413 void 00414 TextLayer::drawStart(View *v, QMouseEvent *e) 00415 { 00416 // SVDEBUG << "TextLayer::drawStart(" << e->x() << "," << e->y() << ")" << endl; 00417 00418 if (!m_model) { 00419 SVDEBUG << "TextLayer::drawStart: no model" << endl; 00420 return; 00421 } 00422 00423 long frame = v->getFrameForX(e->x()); 00424 if (frame < 0) frame = 0; 00425 frame = frame / m_model->getResolution() * m_model->getResolution(); 00426 00427 float height = getHeightForY(v, e->y()); 00428 00429 m_editingPoint = TextModel::Point(frame, height, ""); 00430 m_originalPoint = m_editingPoint; 00431 00432 if (m_editingCommand) finish(m_editingCommand); 00433 m_editingCommand = new TextModel::EditCommand(m_model, "Add Label"); 00434 m_editingCommand->addPoint(m_editingPoint); 00435 00436 m_editing = true; 00437 } 00438 00439 void 00440 TextLayer::drawDrag(View *v, QMouseEvent *e) 00441 { 00442 // SVDEBUG << "TextLayer::drawDrag(" << e->x() << "," << e->y() << ")" << endl; 00443 00444 if (!m_model || !m_editing) return; 00445 00446 long frame = v->getFrameForX(e->x()); 00447 if (frame < 0) frame = 0; 00448 frame = frame / m_model->getResolution() * m_model->getResolution(); 00449 00450 float height = getHeightForY(v, e->y()); 00451 00452 m_editingCommand->deletePoint(m_editingPoint); 00453 m_editingPoint.frame = frame; 00454 m_editingPoint.height = height; 00455 m_editingCommand->addPoint(m_editingPoint); 00456 } 00457 00458 void 00459 TextLayer::drawEnd(View *v, QMouseEvent *) 00460 { 00461 // SVDEBUG << "TextLayer::drawEnd(" << e->x() << "," << e->y() << ")" << endl; 00462 if (!m_model || !m_editing) return; 00463 00464 bool ok = false; 00465 QString label = QInputDialog::getText(v, tr("Enter label"), 00466 tr("Please enter a new label:"), 00467 QLineEdit::Normal, "", &ok); 00468 00469 if (ok) { 00470 TextModel::RelabelCommand *command = 00471 new TextModel::RelabelCommand(m_model, m_editingPoint, label); 00472 m_editingCommand->addCommand(command); 00473 } else { 00474 m_editingCommand->deletePoint(m_editingPoint); 00475 } 00476 00477 finish(m_editingCommand); 00478 m_editingCommand = 0; 00479 m_editing = false; 00480 } 00481 00482 void 00483 TextLayer::eraseStart(View *v, QMouseEvent *e) 00484 { 00485 if (!m_model) return; 00486 00487 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) return; 00488 00489 if (m_editingCommand) { 00490 finish(m_editingCommand); 00491 m_editingCommand = 0; 00492 } 00493 00494 m_editing = true; 00495 } 00496 00497 void 00498 TextLayer::eraseDrag(View *, QMouseEvent *) 00499 { 00500 } 00501 00502 void 00503 TextLayer::eraseEnd(View *v, QMouseEvent *e) 00504 { 00505 if (!m_model || !m_editing) return; 00506 00507 m_editing = false; 00508 00509 TextModel::Point p(0); 00510 if (!getPointToDrag(v, e->x(), e->y(), p)) return; 00511 if (p.frame != m_editingPoint.frame || p.height != m_editingPoint.height) return; 00512 00513 m_editingCommand = new TextModel::EditCommand 00514 (m_model, tr("Erase Point")); 00515 00516 m_editingCommand->deletePoint(m_editingPoint); 00517 00518 finish(m_editingCommand); 00519 m_editingCommand = 0; 00520 m_editing = false; 00521 } 00522 00523 void 00524 TextLayer::editStart(View *v, QMouseEvent *e) 00525 { 00526 // SVDEBUG << "TextLayer::editStart(" << e->x() << "," << e->y() << ")" << endl; 00527 00528 if (!m_model) return; 00529 00530 if (!getPointToDrag(v, e->x(), e->y(), m_editingPoint)) { 00531 return; 00532 } 00533 00534 m_editOrigin = e->pos(); 00535 m_originalPoint = m_editingPoint; 00536 00537 if (m_editingCommand) { 00538 finish(m_editingCommand); 00539 m_editingCommand = 0; 00540 } 00541 00542 m_editing = true; 00543 } 00544 00545 void 00546 TextLayer::editDrag(View *v, QMouseEvent *e) 00547 { 00548 if (!m_model || !m_editing) return; 00549 00550 long frameDiff = v->getFrameForX(e->x()) - v->getFrameForX(m_editOrigin.x()); 00551 float heightDiff = getHeightForY(v, e->y()) - getHeightForY(v, m_editOrigin.y()); 00552 00553 long frame = m_originalPoint.frame + frameDiff; 00554 float height = m_originalPoint.height + heightDiff; 00555 00556 // long frame = v->getFrameForX(e->x()); 00557 if (frame < 0) frame = 0; 00558 frame = (frame / m_model->getResolution()) * m_model->getResolution(); 00559 00560 // float height = getHeightForY(v, e->y()); 00561 00562 if (!m_editingCommand) { 00563 m_editingCommand = new TextModel::EditCommand(m_model, tr("Drag Label")); 00564 } 00565 00566 m_editingCommand->deletePoint(m_editingPoint); 00567 m_editingPoint.frame = frame; 00568 m_editingPoint.height = height; 00569 m_editingCommand->addPoint(m_editingPoint); 00570 } 00571 00572 void 00573 TextLayer::editEnd(View *, QMouseEvent *) 00574 { 00575 // SVDEBUG << "TextLayer::editEnd(" << e->x() << "," << e->y() << ")" << endl; 00576 if (!m_model || !m_editing) return; 00577 00578 if (m_editingCommand) { 00579 00580 QString newName = m_editingCommand->getName(); 00581 00582 if (m_editingPoint.frame != m_originalPoint.frame) { 00583 if (m_editingPoint.height != m_originalPoint.height) { 00584 newName = tr("Move Label"); 00585 } else { 00586 newName = tr("Move Label Horizontally"); 00587 } 00588 } else { 00589 newName = tr("Move Label Vertically"); 00590 } 00591 00592 m_editingCommand->setName(newName); 00593 finish(m_editingCommand); 00594 } 00595 00596 m_editingCommand = 0; 00597 m_editing = false; 00598 } 00599 00600 bool 00601 TextLayer::editOpen(View *v, QMouseEvent *e) 00602 { 00603 if (!m_model) return false; 00604 00605 TextModel::Point text(0); 00606 if (!getPointToDrag(v, e->x(), e->y(), text)) return false; 00607 00608 QString label = text.label; 00609 00610 bool ok = false; 00611 label = QInputDialog::getText(v, tr("Enter label"), 00612 tr("Please enter a new label:"), 00613 QLineEdit::Normal, label, &ok); 00614 if (ok && label != text.label) { 00615 TextModel::RelabelCommand *command = 00616 new TextModel::RelabelCommand(m_model, text, label); 00617 CommandHistory::getInstance()->addCommand(command); 00618 } 00619 00620 return true; 00621 } 00622 00623 void 00624 TextLayer::moveSelection(Selection s, int newStartFrame) 00625 { 00626 if (!m_model) return; 00627 00628 TextModel::EditCommand *command = 00629 new TextModel::EditCommand(m_model, tr("Drag Selection")); 00630 00631 TextModel::PointList points = 00632 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); 00633 00634 for (TextModel::PointList::iterator i = points.begin(); 00635 i != points.end(); ++i) { 00636 00637 if (s.contains(i->frame)) { 00638 TextModel::Point newPoint(*i); 00639 newPoint.frame = i->frame + newStartFrame - s.getStartFrame(); 00640 command->deletePoint(*i); 00641 command->addPoint(newPoint); 00642 } 00643 } 00644 00645 finish(command); 00646 } 00647 00648 void 00649 TextLayer::resizeSelection(Selection s, Selection newSize) 00650 { 00651 if (!m_model) return; 00652 00653 TextModel::EditCommand *command = 00654 new TextModel::EditCommand(m_model, tr("Resize Selection")); 00655 00656 TextModel::PointList points = 00657 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); 00658 00659 double ratio = 00660 double(newSize.getEndFrame() - newSize.getStartFrame()) / 00661 double(s.getEndFrame() - s.getStartFrame()); 00662 00663 for (TextModel::PointList::iterator i = points.begin(); 00664 i != points.end(); ++i) { 00665 00666 if (s.contains(i->frame)) { 00667 00668 double target = i->frame; 00669 target = newSize.getStartFrame() + 00670 double(target - s.getStartFrame()) * ratio; 00671 00672 TextModel::Point newPoint(*i); 00673 newPoint.frame = lrint(target); 00674 command->deletePoint(*i); 00675 command->addPoint(newPoint); 00676 } 00677 } 00678 00679 finish(command); 00680 } 00681 00682 void 00683 TextLayer::deleteSelection(Selection s) 00684 { 00685 if (!m_model) return; 00686 00687 TextModel::EditCommand *command = 00688 new TextModel::EditCommand(m_model, tr("Delete Selection")); 00689 00690 TextModel::PointList points = 00691 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); 00692 00693 for (TextModel::PointList::iterator i = points.begin(); 00694 i != points.end(); ++i) { 00695 if (s.contains(i->frame)) command->deletePoint(*i); 00696 } 00697 00698 finish(command); 00699 } 00700 00701 void 00702 TextLayer::copy(View *v, Selection s, Clipboard &to) 00703 { 00704 if (!m_model) return; 00705 00706 TextModel::PointList points = 00707 m_model->getPoints(s.getStartFrame(), s.getEndFrame()); 00708 00709 for (TextModel::PointList::iterator i = points.begin(); 00710 i != points.end(); ++i) { 00711 if (s.contains(i->frame)) { 00712 Clipboard::Point point(i->frame, i->height, i->label); 00713 point.setReferenceFrame(alignToReference(v, i->frame)); 00714 to.addPoint(point); 00715 } 00716 } 00717 } 00718 00719 bool 00720 TextLayer::paste(View *v, const Clipboard &from, int /* frameOffset */, bool /* interactive */) 00721 { 00722 if (!m_model) return false; 00723 00724 const Clipboard::PointList &points = from.getPoints(); 00725 00726 bool realign = false; 00727 00728 if (clipboardHasDifferentAlignment(v, from)) { 00729 00730 QMessageBox::StandardButton button = 00731 QMessageBox::question(v, tr("Re-align pasted items?"), 00732 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?"), 00733 QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, 00734 QMessageBox::Yes); 00735 00736 if (button == QMessageBox::Cancel) { 00737 return false; 00738 } 00739 00740 if (button == QMessageBox::Yes) { 00741 realign = true; 00742 } 00743 } 00744 00745 TextModel::EditCommand *command = 00746 new TextModel::EditCommand(m_model, tr("Paste")); 00747 00748 float valueMin = 0.0, valueMax = 1.0; 00749 for (Clipboard::PointList::const_iterator i = points.begin(); 00750 i != points.end(); ++i) { 00751 if (i->haveValue()) { 00752 if (i->getValue() < valueMin) valueMin = i->getValue(); 00753 if (i->getValue() > valueMax) valueMax = i->getValue(); 00754 } 00755 } 00756 if (valueMax < valueMin + 1.0) valueMax = valueMin + 1.0; 00757 00758 for (Clipboard::PointList::const_iterator i = points.begin(); 00759 i != points.end(); ++i) { 00760 00761 if (!i->haveFrame()) continue; 00762 int frame = 0; 00763 00764 if (!realign) { 00765 00766 frame = i->getFrame(); 00767 00768 } else { 00769 00770 if (i->haveReferenceFrame()) { 00771 frame = i->getReferenceFrame(); 00772 frame = alignFromReference(v, frame); 00773 } else { 00774 frame = i->getFrame(); 00775 } 00776 } 00777 00778 TextModel::Point newPoint(frame); 00779 00780 if (i->haveValue()) { 00781 newPoint.height = (i->getValue() - valueMin) / (valueMax - valueMin); 00782 } else { 00783 newPoint.height = 0.5; 00784 } 00785 00786 if (i->haveLabel()) { 00787 newPoint.label = i->getLabel(); 00788 } else if (i->haveValue()) { 00789 newPoint.label = QString("%1").arg(i->getValue()); 00790 } else { 00791 newPoint.label = tr("New Point"); 00792 } 00793 00794 command->addPoint(newPoint); 00795 } 00796 00797 finish(command); 00798 return true; 00799 } 00800 00801 int 00802 TextLayer::getDefaultColourHint(bool darkbg, bool &impose) 00803 { 00804 impose = false; 00805 return ColourDatabase::getInstance()->getColourIndex 00806 (QString(darkbg ? "Bright Orange" : "Orange")); 00807 } 00808 00809 void 00810 TextLayer::toXml(QTextStream &stream, 00811 QString indent, QString extraAttributes) const 00812 { 00813 SingleColourLayer::toXml(stream, indent, extraAttributes); 00814 } 00815 00816 void 00817 TextLayer::setProperties(const QXmlAttributes &attributes) 00818 { 00819 SingleColourLayer::setProperties(attributes); 00820 } 00821