00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "Pane.h"
00017 #include "layer/Layer.h"
00018 #include "data/model/Model.h"
00019 #include "base/ZoomConstraint.h"
00020 #include "base/RealTime.h"
00021 #include "base/Profiler.h"
00022 #include "ViewManager.h"
00023 #include "base/CommandHistory.h"
00024 #include "base/TextAbbrev.h"
00025 #include "base/Preferences.h"
00026 #include "layer/WaveformLayer.h"
00027
00029 #include "data/model/WaveFileModel.h"
00030
00031 #include <QPaintEvent>
00032 #include <QPainter>
00033 #include <QBitmap>
00034 #include <QDragEnterEvent>
00035 #include <QDropEvent>
00036 #include <QCursor>
00037 #include <QTextStream>
00038
00039 #include <iostream>
00040 #include <cmath>
00041
00043 #include <QFrame>
00044 #include <QGridLayout>
00045 #include <QPushButton>
00046 #include "widgets/Thumbwheel.h"
00047 #include "widgets/Panner.h"
00048 #include "widgets/RangeInputDialog.h"
00049 #include "widgets/NotifyingPushButton.h"
00050
00051 #include "widgets/KeyReference.h"
00052
00053
00054
00055 using std::cerr;
00056 using std::endl;
00057
00058 QCursor *Pane::m_measureCursor1 = 0;
00059 QCursor *Pane::m_measureCursor2 = 0;
00060
00061 Pane::Pane(QWidget *w) :
00062 View(w, true),
00063 m_identifyFeatures(false),
00064 m_clickedInRange(false),
00065 m_shiftPressed(false),
00066 m_ctrlPressed(false),
00067 m_navigating(false),
00068 m_resizing(false),
00069 m_editing(false),
00070 m_releasing(false),
00071 m_centreLineVisible(true),
00072 m_scaleWidth(0),
00073 m_headsUpDisplay(0),
00074 m_vpan(0),
00075 m_hthumb(0),
00076 m_vthumb(0),
00077 m_reset(0),
00078 m_mouseInWidget(false)
00079 {
00080 setObjectName("Pane");
00081 setMouseTracking(true);
00082 setAcceptDrops(true);
00083
00084 updateHeadsUpDisplay();
00085 }
00086
00087 void
00088 Pane::updateHeadsUpDisplay()
00089 {
00090 Profiler profiler("Pane::updateHeadsUpDisplay", true);
00091
00092 if (!isVisible()) return;
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111 Layer *layer = 0;
00112 if (getLayerCount() > 0) layer = getLayer(getLayerCount() - 1);
00113
00114 if (!m_headsUpDisplay) {
00115
00116 m_headsUpDisplay = new QFrame(this);
00117
00118 QGridLayout *layout = new QGridLayout;
00119 layout->setMargin(0);
00120 layout->setSpacing(0);
00121 m_headsUpDisplay->setLayout(layout);
00122
00123 m_hthumb = new Thumbwheel(Qt::Horizontal);
00124 m_hthumb->setObjectName(tr("Horizontal Zoom"));
00125 m_hthumb->setCursor(Qt::ArrowCursor);
00126 layout->addWidget(m_hthumb, 1, 0, 1, 2);
00127 m_hthumb->setFixedWidth(70);
00128 m_hthumb->setFixedHeight(16);
00129 m_hthumb->setDefaultValue(0);
00130 m_hthumb->setSpeed(0.6);
00131 connect(m_hthumb, SIGNAL(valueChanged(int)), this,
00132 SLOT(horizontalThumbwheelMoved(int)));
00133 connect(m_hthumb, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
00134 connect(m_hthumb, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
00135
00136 m_vpan = new Panner;
00137 m_vpan->setCursor(Qt::ArrowCursor);
00138 layout->addWidget(m_vpan, 0, 1);
00139 m_vpan->setFixedWidth(12);
00140 m_vpan->setFixedHeight(70);
00141 m_vpan->setAlpha(80, 130);
00142 connect(m_vpan, SIGNAL(rectExtentsChanged(float, float, float, float)),
00143 this, SLOT(verticalPannerMoved(float, float, float, float)));
00144 connect(m_vpan, SIGNAL(doubleClicked()),
00145 this, SLOT(editVerticalPannerExtents()));
00146 connect(m_vpan, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
00147 connect(m_vpan, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
00148
00149 m_vthumb = new Thumbwheel(Qt::Vertical);
00150 m_vthumb->setObjectName(tr("Vertical Zoom"));
00151 m_vthumb->setCursor(Qt::ArrowCursor);
00152 layout->addWidget(m_vthumb, 0, 2);
00153 m_vthumb->setFixedWidth(16);
00154 m_vthumb->setFixedHeight(70);
00155 connect(m_vthumb, SIGNAL(valueChanged(int)), this,
00156 SLOT(verticalThumbwheelMoved(int)));
00157 connect(m_vthumb, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
00158 connect(m_vthumb, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
00159
00160 if (layer) {
00161 RangeMapper *rm = layer->getNewVerticalZoomRangeMapper();
00162 if (rm) m_vthumb->setRangeMapper(rm);
00163 }
00164
00165 m_reset = new NotifyingPushButton;
00166 m_reset->setCursor(Qt::ArrowCursor);
00167 m_reset->setFixedHeight(16);
00168 m_reset->setFixedWidth(16);
00169 layout->addWidget(m_reset, 1, 2);
00170 connect(m_reset, SIGNAL(clicked()), m_hthumb, SLOT(resetToDefault()));
00171 connect(m_reset, SIGNAL(clicked()), m_vthumb, SLOT(resetToDefault()));
00172 connect(m_reset, SIGNAL(clicked()), m_vpan, SLOT(resetToDefault()));
00173 connect(m_reset, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget()));
00174 connect(m_reset, SIGNAL(mouseLeft()), this, SLOT(mouseLeftWidget()));
00175 }
00176
00177 int count = 0;
00178 int current = 0;
00179 int level = 1;
00180
00182 bool haveConstraint = false;
00183 for (LayerList::const_iterator i = m_layers.begin(); i != m_layers.end();
00184 ++i) {
00185 if ((*i)->getZoomConstraint() && !(*i)->supportsOtherZoomLevels()) {
00186 haveConstraint = true;
00187 break;
00188 }
00189 }
00190
00191 if (haveConstraint) {
00192 while (true) {
00193 if (getZoomLevel() == level) current = count;
00194 int newLevel = getZoomConstraintBlockSize(level + 1,
00195 ZoomConstraint::RoundUp);
00196 if (newLevel == level) break;
00197 level = newLevel;
00198 if (++count == 50) break;
00199 }
00200 } else {
00201
00202 while (true) {
00203 if (getZoomLevel() >= level) current = count;
00204 int step = level / 10;
00205 int pwr = 0;
00206 while (step > 0) {
00207 ++pwr;
00208 step /= 2;
00209 }
00210 step = 1;
00211 while (pwr > 0) {
00212 step *= 2;
00213 --pwr;
00214 }
00215
00216 level += step;
00217 if (++count == 100 || level > 262144) break;
00218 }
00219 }
00220
00221
00222
00223 m_hthumb->setMinimumValue(0);
00224 m_hthumb->setMaximumValue(count);
00225 m_hthumb->setValue(count - current);
00226
00227
00228
00229
00230
00231 if (count != 50 && m_hthumb->getDefaultValue() == 0) {
00232 m_hthumb->setDefaultValue(count - current);
00233
00234 }
00235
00236 bool haveVThumb = false;
00237
00238 if (layer) {
00239 int defaultStep = 0;
00240 int max = layer->getVerticalZoomSteps(defaultStep);
00241 if (max == 0) {
00242 m_vthumb->hide();
00243 } else {
00244 haveVThumb = true;
00245 m_vthumb->show();
00246 m_vthumb->blockSignals(true);
00247 m_vthumb->setMinimumValue(0);
00248 m_vthumb->setMaximumValue(max);
00249 m_vthumb->setDefaultValue(defaultStep);
00250 m_vthumb->setValue(layer->getCurrentVerticalZoomStep());
00251 m_vthumb->blockSignals(false);
00252
00253
00254
00255
00256
00257 }
00258 }
00259
00260 updateVerticalPanner();
00261
00262 if (m_manager && m_manager->getZoomWheelsEnabled() &&
00263 width() > 120 && height() > 100) {
00264 if (!m_headsUpDisplay->isVisible()) {
00265 m_headsUpDisplay->show();
00266 }
00267 if (haveVThumb) {
00268 m_headsUpDisplay->setFixedHeight(m_vthumb->height() + m_hthumb->height());
00269 m_headsUpDisplay->move(width() - 86, height() - 86);
00270 } else {
00271 m_headsUpDisplay->setFixedHeight(m_hthumb->height());
00272 m_headsUpDisplay->move(width() - 86, height() - 16);
00273 }
00274 } else {
00275 m_headsUpDisplay->hide();
00276 }
00277 }
00278
00279 void
00280 Pane::updateVerticalPanner()
00281 {
00282 if (!m_vpan || !m_manager || !m_manager->getZoomWheelsEnabled()) return;
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293 Layer *layer = 0;
00294 if (getLayerCount() > 0) layer = getLayer(getLayerCount() - 1);
00295 int discard;
00296 if (layer && layer->getVerticalZoomSteps(discard) == 0) {
00297 m_vpan->hide();
00298 return;
00299 }
00300
00301 float vmin, vmax, dmin, dmax;
00302 if (getTopLayerDisplayExtents(vmin, vmax, dmin, dmax) && vmax != vmin) {
00303 float y0 = (dmin - vmin) / (vmax - vmin);
00304 float y1 = (dmax - vmin) / (vmax - vmin);
00305 m_vpan->blockSignals(true);
00306 m_vpan->setRectExtents(0, 1.0 - y1, 1, y1 - y0);
00307 m_vpan->blockSignals(false);
00308 m_vpan->show();
00309 } else {
00310 m_vpan->hide();
00311 }
00312 }
00313
00314 bool
00315 Pane::shouldIlluminateLocalFeatures(const Layer *layer, QPoint &pos) const
00316 {
00317 QPoint discard;
00318 bool b0, b1;
00319
00320 if (m_manager && m_manager->getToolMode() == ViewManager::MeasureMode) {
00321 return false;
00322 }
00323
00324 if (m_manager && !m_manager->shouldIlluminateLocalFeatures()) {
00325 return false;
00326 }
00327
00328 if (layer == getSelectedLayer() &&
00329 !shouldIlluminateLocalSelection(discard, b0, b1)) {
00330
00331 pos = m_identifyPoint;
00332 return m_identifyFeatures;
00333 }
00334
00335 return false;
00336 }
00337
00338 bool
00339 Pane::shouldIlluminateLocalSelection(QPoint &pos,
00340 bool &closeToLeft,
00341 bool &closeToRight) const
00342 {
00343 if (m_identifyFeatures &&
00344 m_manager &&
00345 m_manager->getToolMode() == ViewManager::EditMode &&
00346 !m_manager->getSelections().empty() &&
00347 !selectionIsBeingEdited()) {
00348
00349 Selection s(getSelectionAt(m_identifyPoint.x(),
00350 closeToLeft, closeToRight));
00351
00352 if (!s.isEmpty()) {
00353 if (getSelectedLayer() && getSelectedLayer()->isLayerEditable()) {
00354
00355 pos = m_identifyPoint;
00356 return true;
00357 }
00358 }
00359 }
00360
00361 return false;
00362 }
00363
00364 bool
00365 Pane::selectionIsBeingEdited() const
00366 {
00367 if (!m_editingSelection.isEmpty()) {
00368 if (m_mousePos != m_clickPos &&
00369 getFrameForX(m_mousePos.x()) != getFrameForX(m_clickPos.x())) {
00370 return true;
00371 }
00372 }
00373 return false;
00374 }
00375
00376 void
00377 Pane::setCentreLineVisible(bool visible)
00378 {
00379 m_centreLineVisible = visible;
00380 update();
00381 }
00382
00383 void
00384 Pane::paintEvent(QPaintEvent *e)
00385 {
00386
00387
00388 QPainter paint;
00389
00390 QRect r(rect());
00391 if (e) r = e->rect();
00392
00393 View::paintEvent(e);
00394
00395 paint.begin(this);
00396 setPaintFont(paint);
00397
00398 if (e) paint.setClipRect(r);
00399
00400 ViewManager::ToolMode toolMode = m_manager->getToolMode();
00401
00402 if (m_manager &&
00403
00404 m_mouseInWidget &&
00405 toolMode == ViewManager::MeasureMode) {
00406
00407 for (LayerList::iterator vi = m_layers.end(); vi != m_layers.begin(); ) {
00408 --vi;
00409
00410 std::vector<QRect> crosshairExtents;
00411
00412 if ((*vi)->getCrosshairExtents(this, paint, m_identifyPoint,
00413 crosshairExtents)) {
00414 (*vi)->paintCrosshairs(this, paint, m_identifyPoint);
00415 break;
00416 } else if ((*vi)->isLayerOpaque()) {
00417 break;
00418 }
00419 }
00420 }
00421
00422 Layer *topLayer = getTopLayer();
00423 bool haveSomeTimeXAxis = false;
00424
00425 const Model *waveformModel = 0;
00426 const Model *workModel = 0;
00427
00428 for (LayerList::iterator vi = m_layers.end(); vi != m_layers.begin(); ) {
00429 --vi;
00430 if (!haveSomeTimeXAxis && (*vi)->hasTimeXAxis()) {
00431 haveSomeTimeXAxis = true;
00432 }
00433 if (dynamic_cast<WaveformLayer *>(*vi)) {
00434 waveformModel = (*vi)->getModel();
00435 workModel = waveformModel;
00436 } else {
00437 Model *m = (*vi)->getModel();
00438 if (dynamic_cast<WaveFileModel *>(m)) {
00439 workModel = m;
00440 } else if (m && dynamic_cast<WaveFileModel *>(m->getSourceModel())) {
00441 workModel = m->getSourceModel();
00442 }
00443 }
00444
00445 if (waveformModel && workModel && haveSomeTimeXAxis) break;
00446 }
00447
00448 m_scaleWidth = 0;
00449
00450 if (m_manager && m_manager->shouldShowVerticalScale() && topLayer) {
00451 drawVerticalScale(r, topLayer, paint);
00452 }
00453
00454 if (m_identifyFeatures &&
00455 m_manager && m_manager->shouldIlluminateLocalFeatures() &&
00456 topLayer) {
00457 drawFeatureDescription(topLayer, paint);
00458 }
00459
00460 int sampleRate = getModelsSampleRate();
00461 paint.setBrush(Qt::NoBrush);
00462
00463 if (m_centreLineVisible &&
00464 m_manager &&
00465 m_manager->shouldShowCentreLine()) {
00466 drawCentreLine(sampleRate, paint, !haveSomeTimeXAxis);
00467 }
00468
00469 paint.setPen(QColor(50, 50, 50));
00470
00471 if (waveformModel &&
00472 m_manager &&
00473 m_manager->shouldShowDuration()) {
00474 drawDurationAndRate(r, waveformModel, sampleRate, paint);
00475 }
00476
00477 bool haveWorkTitle = false;
00478
00479 if (workModel &&
00480 m_manager &&
00481 m_manager->shouldShowWorkTitle()) {
00482 drawWorkTitle(r, paint, workModel);
00483 haveWorkTitle = true;
00484 }
00485
00486 if (workModel &&
00487 m_manager &&
00488 m_manager->getAlignMode()) {
00489 drawAlignmentStatus(r, paint, workModel, haveWorkTitle);
00490 }
00491
00492 if (m_manager &&
00493 m_manager->shouldShowLayerNames()) {
00494 drawLayerNames(r, paint);
00495 }
00496
00497 if (m_shiftPressed && m_clickedInRange &&
00498 (toolMode == ViewManager::NavigateMode || m_navigating)) {
00499
00501
00502
00503 paint.setPen(Qt::blue);
00505 paint.drawRect(m_clickPos.x(), m_clickPos.y(),
00506 m_mousePos.x() - m_clickPos.x(),
00507 m_mousePos.y() - m_clickPos.y());
00508
00509 }
00510
00511 if (toolMode == ViewManager::MeasureMode && topLayer) {
00512 bool showFocus = false;
00513 if (!m_manager || !m_manager->isPlaying()) showFocus = true;
00514 topLayer->paintMeasurementRects(this, paint, showFocus, m_identifyPoint);
00515 }
00516
00517 if (selectionIsBeingEdited()) {
00518 drawEditingSelection(paint);
00519 }
00520
00521 paint.end();
00522 }
00523
00524 size_t
00525 Pane::getVerticalScaleWidth() const
00526 {
00527 if (m_scaleWidth > 0) return m_scaleWidth;
00528 else return 0;
00529 }
00530
00531 void
00532 Pane::drawVerticalScale(QRect r, Layer *topLayer, QPainter &paint)
00533 {
00534 Layer *scaleLayer = 0;
00535
00536 float min, max;
00537 bool log;
00538 QString unit;
00539
00540
00541
00542
00543
00544
00545
00546
00547 int sw = topLayer->getVerticalScaleWidth(this, paint);
00548
00549 if (sw > 0) {
00550 scaleLayer = topLayer;
00551 m_scaleWidth = sw;
00552
00553 } else {
00554
00555 bool hasDisplayExtents = topLayer->getDisplayExtents(min, max);
00556 bool hasValueExtents = topLayer->getValueExtents(min, max, log, unit);
00557
00558 if (!hasDisplayExtents) {
00559
00560 if (!hasValueExtents) {
00561
00562 for (LayerList::iterator vi = m_layers.end();
00563 vi != m_layers.begin(); ) {
00564
00565 --vi;
00566
00567 if ((*vi) == topLayer) continue;
00568
00569 sw = (*vi)->getVerticalScaleWidth(this, paint);
00570
00571 if (sw > 0) {
00572 scaleLayer = *vi;
00573 m_scaleWidth = sw;
00574 break;
00575 }
00576 }
00577 } else if (unit != "") {
00578
00579 QString requireUnit = unit;
00580
00581 for (LayerList::iterator vi = m_layers.end();
00582 vi != m_layers.begin(); ) {
00583
00584 --vi;
00585
00586 if ((*vi) == topLayer) continue;
00587
00588 if ((*vi)->getDisplayExtents(min, max)) {
00589
00590
00591
00592
00593
00594
00595 if ((*vi)->getValueExtents(min, max, log, unit) &&
00596 unit == requireUnit) {
00597
00598 sw = (*vi)->getVerticalScaleWidth(this, paint);
00599 if (sw > 0) {
00600 scaleLayer = *vi;
00601 m_scaleWidth = sw;
00602 }
00603 }
00604 break;
00605 }
00606 }
00607 }
00608 }
00609 }
00610
00611 if (!scaleLayer) m_scaleWidth = 0;
00612
00613 if (m_scaleWidth > 0 && r.left() < m_scaleWidth) {
00614
00615
00616
00617
00618 paint.save();
00619
00620 paint.setPen(getForeground());
00621 paint.setBrush(getBackground());
00622 paint.drawRect(0, -1, m_scaleWidth, height()+1);
00623
00624 paint.setBrush(Qt::NoBrush);
00625 scaleLayer->paintVerticalScale
00626 (this, paint, QRect(0, 0, m_scaleWidth, height()));
00627
00628 paint.restore();
00629 }
00630 }
00631
00632 void
00633 Pane::drawFeatureDescription(Layer *topLayer, QPainter &paint)
00634 {
00635 QPoint pos = m_identifyPoint;
00636 QString desc = topLayer->getFeatureDescription(this, pos);
00637
00638 if (desc != "") {
00639
00640 paint.save();
00641
00642 int tabStop =
00643 paint.fontMetrics().width(tr("Some lengthy prefix:"));
00644
00645 QRect boundingRect =
00646 paint.fontMetrics().boundingRect
00647 (rect(),
00648 Qt::AlignRight | Qt::AlignTop | Qt::TextExpandTabs,
00649 desc, tabStop);
00650
00651 if (hasLightBackground()) {
00652 paint.setPen(Qt::NoPen);
00653 paint.setBrush(QColor(250, 250, 250, 200));
00654 } else {
00655 paint.setPen(Qt::NoPen);
00656 paint.setBrush(QColor(50, 50, 50, 200));
00657 }
00658
00659 int extra = paint.fontMetrics().descent();
00660 paint.drawRect(width() - boundingRect.width() - 10 - extra,
00661 10 - extra,
00662 boundingRect.width() + 2 * extra,
00663 boundingRect.height() + extra);
00664
00665 if (hasLightBackground()) {
00666 paint.setPen(QColor(150, 20, 0));
00667 } else {
00668 paint.setPen(QColor(255, 150, 100));
00669 }
00670
00671 QTextOption option;
00672 option.setWrapMode(QTextOption::NoWrap);
00673 option.setAlignment(Qt::AlignRight | Qt::AlignTop);
00674 option.setTabStop(tabStop);
00675 paint.drawText(QRectF(width() - boundingRect.width() - 10, 10,
00676 boundingRect.width(),
00677 boundingRect.height()),
00678 desc,
00679 option);
00680
00681 paint.restore();
00682 }
00683 }
00684
00685 void
00686 Pane::drawCentreLine(int sampleRate, QPainter &paint, bool omitLine)
00687 {
00688 int fontHeight = paint.fontMetrics().height();
00689 int fontAscent = paint.fontMetrics().ascent();
00690
00691 QColor c = QColor(0, 0, 0);
00692 if (!hasLightBackground()) {
00693 c = QColor(240, 240, 240);
00694 }
00695
00696 paint.setPen(c);
00697 int x = width() / 2;
00698
00699 if (!omitLine) {
00700 paint.drawLine(x, 0, x, height() - 1);
00701 paint.drawLine(x-1, 1, x+1, 1);
00702 paint.drawLine(x-2, 0, x+2, 0);
00703 paint.drawLine(x-1, height() - 2, x+1, height() - 2);
00704 paint.drawLine(x-2, height() - 1, x+2, height() - 1);
00705 }
00706
00707 paint.setPen(QColor(50, 50, 50));
00708
00709 int y = height() - fontHeight + fontAscent - 6;
00710
00711 LayerList::iterator vi = m_layers.end();
00712
00713 if (vi != m_layers.begin()) {
00714
00715 switch ((*--vi)->getPreferredFrameCountPosition()) {
00716
00717 case Layer::PositionTop:
00718 y = fontAscent + 6;
00719 break;
00720
00721 case Layer::PositionMiddle:
00722 y = (height() - fontHeight) / 2
00723 + fontAscent;
00724 break;
00725
00726 case Layer::PositionBottom:
00727
00728 break;
00729 }
00730 }
00731
00732 if (m_manager && m_manager->shouldShowFrameCount()) {
00733
00734 if (sampleRate) {
00735
00736 QString text(QString::fromStdString
00737 (RealTime::frame2RealTime
00738 (m_centreFrame, sampleRate).toText(true)));
00739
00740 int tw = paint.fontMetrics().width(text);
00741 int x = width()/2 - 4 - tw;
00742
00743 drawVisibleText(paint, x, y, text, OutlinedText);
00744 }
00745
00746 QString text = QString("%1").arg(m_centreFrame);
00747
00748 int x = width()/2 + 4;
00749
00750 drawVisibleText(paint, x, y, text, OutlinedText);
00751 }
00752 }
00753
00754 void
00755 Pane::drawAlignmentStatus(QRect r, QPainter &paint, const Model *model,
00756 bool down)
00757 {
00758 const Model *reference = model->getAlignmentReference();
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768 QString text;
00769 int completion = 100;
00770
00771 if (reference == model) {
00772 text = tr("Reference");
00773 } else if (!reference) {
00774 text = tr("Unaligned");
00775 } else {
00776 completion = model->getAlignmentCompletion();
00777 if (completion == 0) {
00778 text = tr("Unaligned");
00779 } else if (completion < 100) {
00780 text = tr("Aligning: %1%").arg(completion);
00781 } else {
00782 text = tr("Aligned");
00783 }
00784 }
00785
00786 paint.save();
00787 QFont font(paint.font());
00788 font.setBold(true);
00789 paint.setFont(font);
00790 if (completion < 100) paint.setBrush(Qt::red);
00791
00792 int y = 5;
00793 if (down) y += paint.fontMetrics().height();
00794 int w = paint.fontMetrics().width(text);
00795 int h = paint.fontMetrics().height();
00796 if (r.top() > h + y || r.left() > w + m_scaleWidth + 5) {
00797 paint.restore();
00798 return;
00799 }
00800
00801 drawVisibleText(paint, m_scaleWidth + 5,
00802 paint.fontMetrics().ascent() + y, text, OutlinedText);
00803
00804 paint.restore();
00805 }
00806
00807 void
00808 Pane::modelAlignmentCompletionChanged()
00809 {
00810 View::modelAlignmentCompletionChanged();
00811 update(QRect(0, 0, 300, 100));
00812 }
00813
00814 void
00815 Pane::drawWorkTitle(QRect r, QPainter &paint, const Model *model)
00816 {
00817 QString title = model->getTitle();
00818 QString maker = model->getMaker();
00819
00820
00821 if (title == "") return;
00822
00823 QString text = title;
00824 if (maker != "") {
00825 text = tr("%1 - %2").arg(title).arg(maker);
00826 }
00827
00828 paint.save();
00829 QFont font(paint.font());
00830 font.setItalic(true);
00831 paint.setFont(font);
00832
00833 int y = 5;
00834 int w = paint.fontMetrics().width(text);
00835 int h = paint.fontMetrics().height();
00836 if (r.top() > h + y || r.left() > w + m_scaleWidth + 5) {
00837 paint.restore();
00838 return;
00839 }
00840
00841 drawVisibleText(paint, m_scaleWidth + 5,
00842 paint.fontMetrics().ascent() + y, text, OutlinedText);
00843
00844 paint.restore();
00845 }
00846
00847 void
00848 Pane::drawLayerNames(QRect r, QPainter &paint)
00849 {
00850 int fontHeight = paint.fontMetrics().height();
00851 int fontAscent = paint.fontMetrics().ascent();
00852
00853 int lly = height() - 6;
00854 if (m_manager->getZoomWheelsEnabled()) {
00855 lly -= 20;
00856 }
00857
00858 if (r.y() + r.height() < lly - int(m_layers.size()) * fontHeight) {
00859 return;
00860 }
00861
00862 QStringList texts;
00863 std::vector<QPixmap> pixmaps;
00864 for (LayerList::iterator i = m_layers.begin(); i != m_layers.end(); ++i) {
00865 texts.push_back((*i)->getLayerPresentationName());
00866
00867
00868 pixmaps.push_back((*i)->getLayerPresentationPixmap
00869 (QSize(fontAscent, fontAscent)));
00870 }
00871
00872 int maxTextWidth = width() / 3;
00873 texts = TextAbbrev::abbreviate(texts, paint.fontMetrics(), maxTextWidth);
00874
00875 int llx = width() - maxTextWidth - 5;
00876 if (m_manager->getZoomWheelsEnabled()) {
00877 llx -= 36;
00878 }
00879
00880 if (r.x() + r.width() >= llx - fontAscent - 3) {
00881
00882 for (size_t i = 0; i < texts.size(); ++i) {
00883
00884
00885
00886 if (i + 1 == texts.size()) {
00887 paint.setPen(getForeground());
00888 }
00889
00890 drawVisibleText(paint, llx,
00891 lly - fontHeight + fontAscent,
00892 texts[i], OutlinedText);
00893
00894 if (!pixmaps[i].isNull()) {
00895 paint.drawPixmap(llx - fontAscent - 3,
00896 lly - fontHeight + (fontHeight-fontAscent)/2,
00897 pixmaps[i]);
00898 }
00899
00900 lly -= fontHeight;
00901 }
00902 }
00903 }
00904
00905 void
00906 Pane::drawEditingSelection(QPainter &paint)
00907 {
00908 int offset = m_mousePos.x() - m_clickPos.x();
00909 int p0 = getXForFrame(m_editingSelection.getStartFrame()) + offset;
00910 int p1 = getXForFrame(m_editingSelection.getEndFrame()) + offset;
00911
00912 if (m_editingSelectionEdge < 0) {
00913 p1 = getXForFrame(m_editingSelection.getEndFrame());
00914 } else if (m_editingSelectionEdge > 0) {
00915 p0 = getXForFrame(m_editingSelection.getStartFrame());
00916 }
00917
00918 paint.save();
00919 paint.setPen(QPen(getForeground(), 2));
00920
00922
00923 if (m_editingSelectionEdge < 0) {
00924 paint.drawLine(p0, 1, p1, 1);
00925 paint.drawLine(p0, 0, p0, height());
00926 paint.drawLine(p0, height() - 1, p1, height() - 1);
00927 } else if (m_editingSelectionEdge > 0) {
00928 paint.drawLine(p0, 1, p1, 1);
00929 paint.drawLine(p1, 0, p1, height());
00930 paint.drawLine(p0, height() - 1, p1, height() - 1);
00931 } else {
00932 paint.setBrush(Qt::NoBrush);
00933 paint.drawRect(p0, 1, p1 - p0, height() - 2);
00934 }
00935 paint.restore();
00936 }
00937
00938 void
00939 Pane::drawDurationAndRate(QRect r, const Model *waveformModel,
00940 int sampleRate, QPainter &paint)
00941 {
00942 int fontHeight = paint.fontMetrics().height();
00943 int fontAscent = paint.fontMetrics().ascent();
00944
00945 if (r.y() + r.height() < height() - fontHeight - 6) return;
00946
00947 size_t modelRate = waveformModel->getSampleRate();
00948 size_t nativeRate = waveformModel->getNativeRate();
00949 size_t playbackRate = m_manager->getPlaybackSampleRate();
00950 size_t outputRate = m_manager->getOutputSampleRate();
00951
00952 QString srNote = "";
00953
00954
00955
00956
00957
00958
00959
00960 if (playbackRate != 0) {
00961 if (modelRate == playbackRate) {
00962 if (modelRate != outputRate || modelRate != nativeRate) {
00963 srNote = " " + tr("(R)");
00964 }
00965 } else {
00966 srNote = " " + tr("(X)");
00967 }
00968 }
00969
00970 QString desc = tr("%1 / %2Hz%3")
00971 .arg(RealTime::frame2RealTime(waveformModel->getEndFrame(),
00972 sampleRate)
00973 .toText(false).c_str())
00974 .arg(nativeRate)
00975 .arg(srNote);
00976
00977 if (r.x() < m_scaleWidth + 5 + paint.fontMetrics().width(desc)) {
00978 drawVisibleText(paint, m_scaleWidth + 5,
00979 height() - fontHeight + fontAscent - 6,
00980 desc, OutlinedText);
00981 }
00982 }
00983
00984 bool
00985 Pane::render(QPainter &paint, int xorigin, size_t f0, size_t f1)
00986 {
00987 if (!View::render(paint, xorigin + m_scaleWidth, f0, f1)) {
00988 return false;
00989 }
00990
00991 if (m_scaleWidth > 0) {
00992
00993 for (LayerList::iterator vi = m_layers.end(); vi != m_layers.begin(); ) {
00994 --vi;
00995
00996 paint.save();
00997
00998 paint.setPen(getForeground());
00999 paint.setBrush(getBackground());
01000 paint.drawRect(xorigin, -1, m_scaleWidth, height()+1);
01001
01002 paint.setBrush(Qt::NoBrush);
01003 (*vi)->paintVerticalScale
01004 (this, paint, QRect(xorigin, 0, m_scaleWidth, height()));
01005
01006 paint.restore();
01007 break;
01008 }
01009 }
01010
01011 return true;
01012 }
01013
01014 QImage *
01015 Pane::toNewImage(size_t f0, size_t f1)
01016 {
01017 size_t x0 = f0 / getZoomLevel();
01018 size_t x1 = f1 / getZoomLevel();
01019
01020 QImage *image = new QImage(x1 - x0 + m_scaleWidth,
01021 height(), QImage::Format_RGB32);
01022
01023 int formerScaleWidth = m_scaleWidth;
01024
01025 if (m_manager && m_manager->shouldShowVerticalScale()) {
01026 for (LayerList::iterator vi = m_layers.end(); vi != m_layers.begin(); ) {
01027 --vi;
01028 QPainter paint(image);
01029 m_scaleWidth = (*vi)->getVerticalScaleWidth(this, paint);
01030 break;
01031 }
01032 } else {
01033 m_scaleWidth = 0;
01034 }
01035
01036 if (m_scaleWidth != formerScaleWidth) {
01037 delete image;
01038 image = new QImage(x1 - x0 + m_scaleWidth,
01039 height(), QImage::Format_RGB32);
01040 }
01041
01042 QPainter *paint = new QPainter(image);
01043 if (!render(*paint, 0, f0, f1)) {
01044 delete paint;
01045 delete image;
01046 return 0;
01047 } else {
01048 delete paint;
01049 return image;
01050 }
01051 }
01052
01053 QSize
01054 Pane::getImageSize(size_t f0, size_t f1)
01055 {
01056 QSize s = View::getImageSize(f0, f1);
01057 QImage *image = new QImage(100, 100, QImage::Format_RGB32);
01058 QPainter paint(image);
01059
01060 int sw = 0;
01061 if (m_manager && m_manager->shouldShowVerticalScale()) {
01062 for (LayerList::iterator vi = m_layers.end(); vi != m_layers.begin(); ) {
01063 --vi;
01064 QPainter paint(image);
01065 sw = (*vi)->getVerticalScaleWidth(this, paint);
01066 break;
01067 }
01068 }
01069
01070 return QSize(sw + s.width(), s.height());
01071 }
01072
01073 size_t
01074 Pane::getFirstVisibleFrame() const
01075 {
01076 long f0 = getFrameForX(m_scaleWidth);
01077 size_t f = View::getFirstVisibleFrame();
01078 if (f0 < 0 || f0 < long(f)) return f;
01079 return f0;
01080 }
01081
01082 Selection
01083 Pane::getSelectionAt(int x, bool &closeToLeftEdge, bool &closeToRightEdge) const
01084 {
01085 closeToLeftEdge = closeToRightEdge = false;
01086
01087 if (!m_manager) return Selection();
01088
01089 long testFrame = getFrameForX(x - 5);
01090 if (testFrame < 0) {
01091 testFrame = getFrameForX(x);
01092 if (testFrame < 0) return Selection();
01093 }
01094
01095 Selection selection = m_manager->getContainingSelection(testFrame, true);
01096 if (selection.isEmpty()) return selection;
01097
01098 int lx = getXForFrame(selection.getStartFrame());
01099 int rx = getXForFrame(selection.getEndFrame());
01100
01101 int fuzz = 2;
01102 if (x < lx - fuzz || x > rx + fuzz) return Selection();
01103
01104 int width = rx - lx;
01105 fuzz = 3;
01106 if (width < 12) fuzz = width / 4;
01107 if (fuzz < 1) fuzz = 1;
01108
01109 if (x < lx + fuzz) closeToLeftEdge = true;
01110 if (x > rx - fuzz) closeToRightEdge = true;
01111
01112 return selection;
01113 }
01114
01115 bool
01116 Pane::canTopLayerMoveVertical()
01117 {
01118 float vmin, vmax, dmin, dmax;
01119 if (!getTopLayerDisplayExtents(vmin, vmax, dmin, dmax)) return false;
01120 if (dmin <= vmin && dmax >= vmax) return false;
01121 return true;
01122 }
01123
01124 bool
01125 Pane::getTopLayerDisplayExtents(float &vmin, float &vmax,
01126 float &dmin, float &dmax,
01127 QString *unit)
01128 {
01129 Layer *layer = getTopLayer();
01130 if (!layer) return false;
01131 bool vlog;
01132 QString vunit;
01133 bool rv = (layer->getValueExtents(vmin, vmax, vlog, vunit) &&
01134 layer->getDisplayExtents(dmin, dmax));
01135 if (unit) *unit = vunit;
01136 return rv;
01137 }
01138
01139 bool
01140 Pane::setTopLayerDisplayExtents(float dmin, float dmax)
01141 {
01142 Layer *layer = getTopLayer();
01143 if (!layer) return false;
01144 return layer->setDisplayExtents(dmin, dmax);
01145 }
01146
01147 void
01148 Pane::registerShortcuts(KeyReference &kr)
01149 {
01150 kr.setCategory(tr("Zoom"));
01151 kr.registerAlternativeShortcut(tr("Zoom In"), tr("Wheel Up"));
01152 kr.registerAlternativeShortcut(tr("Zoom Out"), tr("Wheel Down"));
01153
01154 kr.setCategory(tr("General Pane Mouse Actions"));
01155
01156 kr.registerShortcut(tr("Zoom"), tr("Wheel"),
01157 tr("Zoom in or out in time axis"));
01158 kr.registerShortcut(tr("Ctrl+Wheel"), tr("Scroll"),
01159 tr("Scroll rapidly left or right in time axis"));
01160 kr.registerShortcut(tr("Zoom Vertically"), tr("Shift+Wheel"),
01161 tr("Zoom in or out in the vertical axis"));
01162 kr.registerShortcut(tr("Scroll Vertically"), tr("Alt+Wheel"),
01163 tr("Scroll up or down in the vertical axis"));
01164 kr.registerShortcut(tr("Navigate"), tr("Middle"),
01165 tr("Click middle button and drag to navigate with any tool"));
01166 kr.registerShortcut(tr("Relocate"), tr("Double-Click Middle"),
01167 tr("Double-click middle button to relocate with any tool"));
01168 kr.registerShortcut(tr("Menu"), tr("Right"),
01169 tr("Show pane context menu"));
01170
01171 kr.setCategory(tr("Navigate Tool Mouse Actions"));
01172
01173 kr.registerShortcut(tr("Navigate"), tr("Left"),
01174 tr("Click left button and drag to move around"));
01175 kr.registerShortcut(tr("Zoom to Area"), tr("Shift+Left"),
01176 tr("Shift-click left button and drag to zoom to a rectangular area"));
01177 kr.registerShortcut(tr("Relocate"), tr("Double-Click Left"),
01178 tr("Double-click left button to jump to clicked location"));
01179 kr.registerShortcut(tr("Edit"), tr("Double-Click Left"),
01180 tr("Double-click left button on an item to edit it"));
01181
01182 kr.setCategory(tr("Select Tool Mouse Actions"));
01183 kr.registerShortcut(tr("Select"), tr("Left"),
01184 tr("Click left button and drag to select region; drag region edge to resize"));
01185 kr.registerShortcut(tr("Multi Select"), tr("Ctrl+Left"),
01186 tr("Ctrl-click left button and drag to select an additional region"));
01187 kr.registerShortcut(tr("Fine Select"), tr("Shift+Left"),
01188 tr("Shift-click left button and drag to select without snapping to items or grid"));
01189
01190 kr.setCategory(tr("Edit Tool Mouse Actions"));
01191 kr.registerShortcut(tr("Move"), tr("Left"),
01192 tr("Click left button on an item or selected region and drag to move"));
01193 kr.registerShortcut(tr("Edit"), tr("Double-Click Left"),
01194 tr("Double-click left button on an item to edit it"));
01195
01196 kr.setCategory(tr("Draw Tool Mouse Actions"));
01197 kr.registerShortcut(tr("Draw"), tr("Left"),
01198 tr("Click left button and drag to create new item"));
01199
01200 kr.setCategory(tr("Measure Tool Mouse Actions"));
01201 kr.registerShortcut(tr("Measure Area"), tr("Left"),
01202 tr("Click left button and drag to measure a rectangular area"));
01203 kr.registerShortcut(tr("Measure Item"), tr("Double-Click Left"),
01204 tr("Click left button and drag to measure extents of an item or shape"));
01205 kr.registerShortcut(tr("Zoom to Area"), tr("Shift+Left"),
01206 tr("Shift-click left button and drag to zoom to a rectangular area"));
01207 }
01208
01209 void
01210 Pane::mousePressEvent(QMouseEvent *e)
01211 {
01212 if (e->buttons() & Qt::RightButton) {
01213 emit contextHelpChanged("");
01214 emit rightButtonMenuRequested(mapToGlobal(e->pos()));
01215 return;
01216 }
01217
01218
01219
01220 m_clickPos = e->pos();
01221 m_mousePos = m_clickPos;
01222 m_clickedInRange = true;
01223 m_editingSelection = Selection();
01224 m_editingSelectionEdge = 0;
01225 m_shiftPressed = (e->modifiers() & Qt::ShiftModifier);
01226 m_ctrlPressed = (e->modifiers() & Qt::ControlModifier);
01227 m_dragMode = UnresolvedDrag;
01228
01229 ViewManager::ToolMode mode = ViewManager::NavigateMode;
01230 if (m_manager) mode = m_manager->getToolMode();
01231
01232 m_navigating = false;
01233 m_resizing = false;
01234 m_editing = false;
01235 m_releasing = false;
01236
01237 if (mode == ViewManager::NavigateMode ||
01238 (e->buttons() & Qt::MidButton) ||
01239 (mode == ViewManager::MeasureMode &&
01240 (e->buttons() & Qt::LeftButton) && m_shiftPressed)) {
01241
01242 if (mode != ViewManager::NavigateMode) {
01243 setCursor(Qt::PointingHandCursor);
01244 }
01245
01246 m_navigating = true;
01247 m_dragCentreFrame = m_centreFrame;
01248 m_dragStartMinValue = 0;
01249
01250 float vmin, vmax, dmin, dmax;
01251 if (getTopLayerDisplayExtents(vmin, vmax, dmin, dmax)) {
01252 m_dragStartMinValue = dmin;
01253 }
01254
01255 } else if (mode == ViewManager::SelectMode) {
01256
01257 if (!hasTopLayerTimeXAxis()) return;
01258
01259 bool closeToLeft = false, closeToRight = false;
01260 Selection selection = getSelectionAt(e->x(), closeToLeft, closeToRight);
01261
01262 if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) {
01263
01264 m_manager->removeSelection(selection);
01265
01266 if (closeToLeft) {
01267 m_selectionStartFrame = selection.getEndFrame();
01268 } else {
01269 m_selectionStartFrame = selection.getStartFrame();
01270 }
01271
01272 m_manager->setInProgressSelection(selection, false);
01273 m_resizing = true;
01274
01275 } else {
01276
01277 int mouseFrame = getFrameForX(e->x());
01278 size_t resolution = 1;
01279 int snapFrame = mouseFrame;
01280
01281 Layer *layer = getSelectedLayer();
01282 if (layer && !m_shiftPressed) {
01283 layer->snapToFeatureFrame(this, snapFrame,
01284 resolution, Layer::SnapLeft);
01285 }
01286
01287 if (snapFrame < 0) snapFrame = 0;
01288 m_selectionStartFrame = snapFrame;
01289 if (m_manager) {
01290 m_manager->setInProgressSelection
01291 (Selection(alignToReference(snapFrame),
01292 alignToReference(snapFrame + resolution)),
01293 !m_ctrlPressed);
01294 }
01295
01296 m_resizing = false;
01297 }
01298
01299 update();
01300
01301 } else if (mode == ViewManager::DrawMode) {
01302
01303 Layer *layer = getSelectedLayer();
01304 if (layer && layer->isLayerEditable()) {
01305 layer->drawStart(this, e);
01306 }
01307
01308 } else if (mode == ViewManager::EraseMode) {
01309
01310 Layer *layer = getSelectedLayer();
01311 if (layer && layer->isLayerEditable()) {
01312 layer->eraseStart(this, e);
01313 }
01314
01315 } else if (mode == ViewManager::EditMode) {
01316
01317
01318
01319
01320 } else if (mode == ViewManager::MeasureMode) {
01321
01322 Layer *layer = getTopLayer();
01323 if (layer) layer->measureStart(this, e);
01324 update();
01325 }
01326
01327 emit paneInteractedWith();
01328 }
01329
01330 void
01331 Pane::mouseReleaseEvent(QMouseEvent *e)
01332 {
01333 if (e->buttons() & Qt::RightButton) {
01334 return;
01335 }
01336
01337
01338
01339 ViewManager::ToolMode mode = ViewManager::NavigateMode;
01340 if (m_manager) mode = m_manager->getToolMode();
01341
01342 m_releasing = true;
01343
01344 if (m_clickedInRange) {
01345 mouseMoveEvent(e);
01346 }
01347
01348 if (m_navigating || mode == ViewManager::NavigateMode) {
01349
01350 m_navigating = false;
01351
01352 if (mode != ViewManager::NavigateMode) {
01353
01354 toolModeChanged();
01355 }
01356
01357 if (m_shiftPressed) {
01358
01359 int x0 = std::min(m_clickPos.x(), m_mousePos.x());
01360 int x1 = std::max(m_clickPos.x(), m_mousePos.x());
01361
01362 int y0 = std::min(m_clickPos.y(), m_mousePos.y());
01363 int y1 = std::max(m_clickPos.y(), m_mousePos.y());
01364
01365 zoomToRegion(x0, y0, x1, y1);
01366 }
01367
01368 } else if (mode == ViewManager::SelectMode) {
01369
01370 if (!hasTopLayerTimeXAxis()) {
01371 m_releasing = false;
01372 return;
01373 }
01374
01375 if (m_manager && m_manager->haveInProgressSelection()) {
01376
01377 bool exclusive;
01378 Selection selection = m_manager->getInProgressSelection(exclusive);
01379
01380 if (selection.getEndFrame() < selection.getStartFrame() + 2) {
01381 selection = Selection();
01382 }
01383
01384 m_manager->clearInProgressSelection();
01385
01386 if (exclusive) {
01387 m_manager->setSelection(selection);
01388 } else {
01389 m_manager->addSelection(selection);
01390 }
01391 }
01392
01393 update();
01394
01395 } else if (mode == ViewManager::DrawMode) {
01396
01397 Layer *layer = getSelectedLayer();
01398 if (layer && layer->isLayerEditable()) {
01399 layer->drawEnd(this, e);
01400 update();
01401 }
01402
01403 } else if (mode == ViewManager::EraseMode) {
01404
01405 Layer *layer = getSelectedLayer();
01406 if (layer && layer->isLayerEditable()) {
01407 layer->eraseEnd(this, e);
01408 update();
01409 }
01410
01411 } else if (mode == ViewManager::EditMode) {
01412
01413 if (m_editing) {
01414 if (!editSelectionEnd(e)) {
01415 Layer *layer = getSelectedLayer();
01416 if (layer && layer->isLayerEditable()) {
01417 layer->editEnd(this, e);
01418 update();
01419 }
01420 }
01421 }
01422
01423 } else if (mode == ViewManager::MeasureMode) {
01424
01425 Layer *layer = getTopLayer();
01426 if (layer) layer->measureEnd(this, e);
01427 if (m_measureCursor1) setCursor(*m_measureCursor1);
01428 update();
01429 }
01430
01431 m_clickedInRange = false;
01432 m_releasing = false;
01433
01434 emit paneInteractedWith();
01435 }
01436
01437 void
01438 Pane::mouseMoveEvent(QMouseEvent *e)
01439 {
01440 if (e->buttons() & Qt::RightButton) {
01441 return;
01442 }
01443
01444
01445
01446 updateContextHelp(&e->pos());
01447
01448 if (m_navigating && m_clickedInRange && !m_releasing) {
01449
01450
01451
01452
01453
01454
01455 if (!(e->buttons() & Qt::LeftButton) &&
01456 !(e->buttons() & Qt::MidButton)) {
01457 m_clickedInRange = false;
01458 return;
01459 }
01460 }
01461
01462 ViewManager::ToolMode mode = ViewManager::NavigateMode;
01463 if (m_manager) mode = m_manager->getToolMode();
01464
01465 QPoint prevPoint = m_identifyPoint;
01466 m_identifyPoint = e->pos();
01467
01468 if (!m_clickedInRange) {
01469
01470 if (mode == ViewManager::SelectMode && hasTopLayerTimeXAxis()) {
01471 bool closeToLeft = false, closeToRight = false;
01472 getSelectionAt(e->x(), closeToLeft, closeToRight);
01473 if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) {
01474 setCursor(Qt::SizeHorCursor);
01475 } else {
01476 setCursor(Qt::ArrowCursor);
01477 }
01478 }
01479
01480 if (!m_manager->isPlaying()) {
01481
01482 bool updating = false;
01483
01484 if (getSelectedLayer() &&
01485 m_manager->shouldIlluminateLocalFeatures()) {
01486
01487 bool previouslyIdentifying = m_identifyFeatures;
01488 m_identifyFeatures = true;
01489
01490 if (m_identifyFeatures != previouslyIdentifying ||
01491 m_identifyPoint != prevPoint) {
01492 update();
01493 updating = true;
01494 }
01495 }
01496
01497 if (!updating && mode == ViewManager::MeasureMode &&
01498 m_manager && !m_manager->isPlaying()) {
01499
01500 Layer *layer = getTopLayer();
01501 if (layer && layer->nearestMeasurementRectChanged
01502 (this, prevPoint, m_identifyPoint)) {
01503 update();
01504 }
01505 }
01506 }
01507
01508 return;
01509 }
01510
01511 if (m_navigating || mode == ViewManager::NavigateMode) {
01512
01513 if (m_shiftPressed) {
01514
01515 m_mousePos = e->pos();
01516 update();
01517
01518 } else {
01519
01520 dragTopLayer(e);
01521 }
01522
01523 } else if (mode == ViewManager::SelectMode) {
01524
01525 if (!hasTopLayerTimeXAxis()) return;
01526
01527 dragExtendSelection(e);
01528
01529 } else if (mode == ViewManager::DrawMode) {
01530
01531 Layer *layer = getSelectedLayer();
01532 if (layer && layer->isLayerEditable()) {
01533 layer->drawDrag(this, e);
01534 }
01535
01536 } else if (mode == ViewManager::EraseMode) {
01537
01538 Layer *layer = getSelectedLayer();
01539 if (layer && layer->isLayerEditable()) {
01540 layer->eraseDrag(this, e);
01541 }
01542
01543 } else if (mode == ViewManager::EditMode) {
01544
01545 if (m_editing) {
01546 if (!editSelectionDrag(e)) {
01547 Layer *layer = getSelectedLayer();
01548 if (layer && layer->isLayerEditable()) {
01549 layer->editDrag(this, e);
01550 }
01551 }
01552 }
01553
01554 if (!m_editing) {
01555
01556 DragMode newDragMode = updateDragMode
01557 (m_dragMode,
01558 m_clickPos,
01559 e->pos(),
01560 true,
01561 true,
01562 true,
01563 true);
01564
01565 if (newDragMode != UnresolvedDrag) {
01566
01567 m_editing = true;
01568
01569 QMouseEvent clickEvent(QEvent::MouseButtonPress,
01570 m_clickPos,
01571 Qt::NoButton,
01572 e->buttons(),
01573 e->modifiers());
01574
01575 if (!editSelectionStart(&clickEvent)) {
01576 Layer *layer = getSelectedLayer();
01577 if (layer && layer->isLayerEditable()) {
01578 layer->editStart(this, &clickEvent);
01579 }
01580 }
01581 }
01582 }
01583
01584 } else if (mode == ViewManager::MeasureMode) {
01585
01586 if (m_measureCursor2) setCursor(*m_measureCursor2);
01587
01588 Layer *layer = getTopLayer();
01589 if (layer) {
01590 layer->measureDrag(this, e);
01591 if (layer->hasTimeXAxis()) edgeScrollMaybe(e->x());
01592 }
01593
01594 update();
01595 }
01596 }
01597
01598 void
01599 Pane::zoomToRegion(int x0, int y0, int x1, int y1)
01600 {
01601 int w = x1 - x0;
01602
01603 long newStartFrame = getFrameForX(x0);
01604
01605 long visibleFrames = getEndFrame() - getStartFrame();
01606 if (newStartFrame <= -visibleFrames) {
01607 newStartFrame = -visibleFrames + 1;
01608 }
01609
01610 if (newStartFrame >= long(getModelsEndFrame())) {
01611 newStartFrame = getModelsEndFrame() - 1;
01612 }
01613
01614 float ratio = float(w) / float(width());
01615
01616 size_t newZoomLevel = (size_t)nearbyint(m_zoomLevel * ratio);
01617 if (newZoomLevel < 1) newZoomLevel = 1;
01618
01619
01620 setZoomLevel(getZoomConstraintBlockSize(newZoomLevel));
01621 setStartFrame(newStartFrame);
01622
01623 QString unit;
01624 float min, max;
01625 bool log;
01626 Layer *layer = 0;
01627 for (LayerList::const_iterator i = m_layers.begin();
01628 i != m_layers.end(); ++i) {
01629 if ((*i)->getValueExtents(min, max, log, unit) &&
01630 (*i)->getDisplayExtents(min, max)) {
01631 layer = *i;
01632 break;
01633 }
01634 }
01635
01636 if (layer) {
01637 if (log) {
01638 min = (min < 0.0) ? -log10f(-min) : (min == 0.0) ? 0.0 : log10f(min);
01639 max = (max < 0.0) ? -log10f(-max) : (max == 0.0) ? 0.0 : log10f(max);
01640 }
01641 float rmin = min + ((max - min) * (height() - y1)) / height();
01642 float rmax = min + ((max - min) * (height() - y0)) / height();
01643 std::cerr << "min: " << min << ", max: " << max << ", y0: " << y0 << ", y1: " << y1 << ", h: " << height() << ", rmin: " << rmin << ", rmax: " << rmax << std::endl;
01644 if (log) {
01645 rmin = powf(10, rmin);
01646 rmax = powf(10, rmax);
01647 }
01648 std::cerr << "finally: rmin: " << rmin << ", rmax: " << rmax << " " << unit.toStdString() << std::endl;
01649
01650 layer->setDisplayExtents(rmin, rmax);
01651 updateVerticalPanner();
01652 }
01653 }
01654
01655 void
01656 Pane::dragTopLayer(QMouseEvent *e)
01657 {
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683 m_dragMode = updateDragMode
01684 (m_dragMode,
01685 m_clickPos,
01686 e->pos(),
01687 true,
01688 canTopLayerMoveVertical(),
01689 canTopLayerMoveVertical() || (m_manager && m_manager->isPlaying()),
01690 !(m_manager && m_manager->isPlaying()));
01691
01692 if (m_dragMode == HorizontalDrag ||
01693 m_dragMode == FreeDrag) {
01694
01695 long frameOff = getFrameForX(e->x()) - getFrameForX(m_clickPos.x());
01696
01697 size_t newCentreFrame = m_dragCentreFrame;
01698
01699 if (frameOff < 0) {
01700 newCentreFrame -= frameOff;
01701 } else if (newCentreFrame >= size_t(frameOff)) {
01702 newCentreFrame -= frameOff;
01703 } else {
01704 newCentreFrame = 0;
01705 }
01706
01707 #ifdef DEBUG_PANE
01708 std::cerr << "Pane::dragTopLayer: newCentreFrame = " << newCentreFrame <<
01709 ", models end frame = " << getModelsEndFrame() << std::endl;
01710 #endif
01711
01712 if (newCentreFrame >= getModelsEndFrame()) {
01713 newCentreFrame = getModelsEndFrame();
01714 if (newCentreFrame > 0) --newCentreFrame;
01715 }
01716
01717 if (getXForFrame(m_centreFrame) != getXForFrame(newCentreFrame)) {
01718 setCentreFrame(newCentreFrame);
01719 }
01720 }
01721
01722 if (m_dragMode == VerticalDrag ||
01723 m_dragMode == FreeDrag) {
01724
01725 float vmin = 0.f, vmax = 0.f;
01726 float dmin = 0.f, dmax = 0.f;
01727
01728 if (getTopLayerDisplayExtents(vmin, vmax, dmin, dmax)) {
01729
01730
01731
01732 int ydiff = e->y() - m_clickPos.y();
01733 float perpix = (dmax - dmin) / height();
01734 float valdiff = ydiff * perpix;
01735
01736
01737 if (m_dragMode == UnresolvedDrag && ydiff != 0) {
01738 m_dragMode = VerticalDrag;
01739 }
01740
01741 float newmin = m_dragStartMinValue + valdiff;
01742 float newmax = m_dragStartMinValue + (dmax - dmin) + valdiff;
01743 if (newmin < vmin) {
01744 newmax += vmin - newmin;
01745 newmin += vmin - newmin;
01746 }
01747 if (newmax > vmax) {
01748 newmin -= newmax - vmax;
01749 newmax -= newmax - vmax;
01750 }
01751
01752
01753
01754 setTopLayerDisplayExtents(newmin, newmax);
01755 updateVerticalPanner();
01756 }
01757 }
01758 }
01759
01760 Pane::DragMode
01761 Pane::updateDragMode(DragMode dragMode,
01762 QPoint origin,
01763 QPoint point,
01764 bool canMoveHorizontal,
01765 bool canMoveVertical,
01766 bool resistHorizontal,
01767 bool resistVertical)
01768 {
01769 int xdiff = point.x() - origin.x();
01770 int ydiff = point.y() - origin.y();
01771
01772 int smallThreshold = 10, bigThreshold = 80;
01773
01774
01775
01776
01777 if (dragMode == UnresolvedDrag) {
01778
01779 if (abs(ydiff) > smallThreshold &&
01780 abs(ydiff) > abs(xdiff) * 2 &&
01781 canMoveVertical) {
01782
01783 dragMode = VerticalDrag;
01784 } else if (abs(xdiff) > smallThreshold &&
01785 abs(xdiff) > abs(ydiff) * 2 &&
01786 canMoveHorizontal) {
01787
01788 dragMode = HorizontalDrag;
01789 } else if (abs(xdiff) > smallThreshold &&
01790 abs(ydiff) > smallThreshold &&
01791 canMoveVertical &&
01792 canMoveHorizontal) {
01793
01794 dragMode = FreeDrag;
01795 }
01796 }
01797
01798 if (dragMode == VerticalDrag && canMoveHorizontal) {
01799 if (abs(xdiff) > bigThreshold) dragMode = FreeDrag;
01800 }
01801
01802 if (dragMode == HorizontalDrag && canMoveVertical) {
01803 if (abs(ydiff) > bigThreshold) dragMode = FreeDrag;
01804 }
01805
01806 if (dragMode == UnresolvedDrag) {
01807 if (!resistHorizontal && xdiff != 0) {
01808 dragMode = HorizontalDrag;
01809 }
01810 if (!resistVertical && ydiff != 0) {
01811 if (dragMode == HorizontalDrag) dragMode = FreeDrag;
01812 else dragMode = VerticalDrag;
01813 }
01814 }
01815
01816 return dragMode;
01817 }
01818
01819 void
01820 Pane::dragExtendSelection(QMouseEvent *e)
01821 {
01822 int mouseFrame = getFrameForX(e->x());
01823 size_t resolution = 1;
01824 int snapFrameLeft = mouseFrame;
01825 int snapFrameRight = mouseFrame;
01826
01827 Layer *layer = getSelectedLayer();
01828 if (layer && !m_shiftPressed) {
01829 layer->snapToFeatureFrame(this, snapFrameLeft,
01830 resolution, Layer::SnapLeft);
01831 layer->snapToFeatureFrame(this, snapFrameRight,
01832 resolution, Layer::SnapRight);
01833 }
01834
01835
01836
01837 if (snapFrameLeft < 0) snapFrameLeft = 0;
01838 if (snapFrameRight < 0) snapFrameRight = 0;
01839
01840 size_t min, max;
01841
01842 if (m_selectionStartFrame > size_t(snapFrameLeft)) {
01843 min = snapFrameLeft;
01844 max = m_selectionStartFrame;
01845 } else if (size_t(snapFrameRight) > m_selectionStartFrame) {
01846 min = m_selectionStartFrame;
01847 max = snapFrameRight;
01848 } else {
01849 min = snapFrameLeft;
01850 max = snapFrameRight;
01851 }
01852
01853 if (m_manager) {
01854 m_manager->setInProgressSelection(Selection(alignToReference(min),
01855 alignToReference(max)),
01856 !m_resizing && !m_ctrlPressed);
01857 }
01858
01859 edgeScrollMaybe(e->x());
01860
01861 update();
01862 }
01863
01864 void
01865 Pane::edgeScrollMaybe(int x)
01866 {
01867 int mouseFrame = getFrameForX(x);
01868
01869 bool doScroll = false;
01870 if (!m_manager) doScroll = true;
01871 if (!m_manager->isPlaying()) doScroll = true;
01872 if (m_followPlay != PlaybackScrollContinuous) doScroll = true;
01873
01874 if (doScroll) {
01875 int offset = mouseFrame - getStartFrame();
01876 int available = getEndFrame() - getStartFrame();
01877 int move = 0;
01878 if (offset >= available * 0.95) {
01879 move = int(offset - available * 0.95) + 1;
01880 } else if (offset <= available * 0.10) {
01881 move = int(available * 0.10 - offset) + 1;
01882 move = -move;
01883 }
01884 if (move != 0) {
01885 setCentreFrame(m_centreFrame + move);
01886 update();
01887 }
01888 }
01889 }
01890
01891 void
01892 Pane::mouseDoubleClickEvent(QMouseEvent *e)
01893 {
01894 if (e->buttons() & Qt::RightButton) {
01895 return;
01896 }
01897
01898
01899
01900 m_clickPos = e->pos();
01901 m_clickedInRange = true;
01902 m_shiftPressed = (e->modifiers() & Qt::ShiftModifier);
01903 m_ctrlPressed = (e->modifiers() & Qt::ControlModifier);
01904
01905 ViewManager::ToolMode mode = ViewManager::NavigateMode;
01906 if (m_manager) mode = m_manager->getToolMode();
01907
01908 bool relocate = (mode == ViewManager::NavigateMode ||
01909 (e->buttons() & Qt::MidButton));
01910
01911 if (mode == ViewManager::NavigateMode ||
01912 mode == ViewManager::EditMode) {
01913
01914 Layer *layer = getSelectedLayer();
01915 if (layer && layer->isLayerEditable()) {
01916 if (layer->editOpen(this, e)) relocate = false;
01917 }
01918
01919 } else if (mode == ViewManager::MeasureMode) {
01920
01921 Layer *layer = getTopLayer();
01922 if (layer) layer->measureDoubleClick(this, e);
01923 update();
01924 }
01925
01926 if (relocate) {
01927
01928 long f = getFrameForX(e->x());
01929
01930 setCentreFrame(f);
01931
01932 m_dragCentreFrame = f;
01933 m_dragStartMinValue = 0;
01934 m_dragMode = UnresolvedDrag;
01935
01936 float vmin, vmax, dmin, dmax;
01937 if (getTopLayerDisplayExtents(vmin, vmax, dmin, dmax)) {
01938 m_dragStartMinValue = dmin;
01939 }
01940 }
01941 }
01942
01943 void
01944 Pane::enterEvent(QEvent *)
01945 {
01946 m_mouseInWidget = true;
01947 }
01948
01949 void
01950 Pane::leaveEvent(QEvent *)
01951 {
01952 m_mouseInWidget = false;
01953 bool previouslyIdentifying = m_identifyFeatures;
01954 m_identifyFeatures = false;
01955 if (previouslyIdentifying) update();
01956 emit contextHelpChanged("");
01957 }
01958
01959 void
01960 Pane::resizeEvent(QResizeEvent *)
01961 {
01962 updateHeadsUpDisplay();
01963 }
01964
01965 void
01966 Pane::wheelEvent(QWheelEvent *e)
01967 {
01968
01969
01970 int count = e->delta();
01971
01972 if (count > 0) {
01973 if (count >= 120) count /= 120;
01974 else count = 1;
01975 }
01976
01977 if (count < 0) {
01978 if (count <= -120) count /= 120;
01979 else count = -1;
01980 }
01981
01982 if (e->modifiers() & Qt::ControlModifier) {
01983
01984
01985
01986 if (getStartFrame() < 0 &&
01987 getEndFrame() >= getModelsEndFrame()) return;
01988
01989 long delta = ((width() / 2) * count * m_zoomLevel);
01990
01991 if (int(m_centreFrame) < delta) {
01992 setCentreFrame(0);
01993 } else if (int(m_centreFrame) - delta >= int(getModelsEndFrame())) {
01994 setCentreFrame(getModelsEndFrame());
01995 } else {
01996 setCentreFrame(m_centreFrame - delta);
01997 }
01998
01999 } else if (e->modifiers() & Qt::ShiftModifier) {
02000
02001
02002
02003 if (m_vpan) {
02004 m_vpan->scroll(e->delta() > 0);
02005 }
02006
02007 } else if (e->modifiers() & Qt::AltModifier) {
02008
02009
02010
02011 if (m_vthumb) {
02012 m_vthumb->scroll(e->delta() > 0);
02013 }
02014
02015 } else {
02016
02017
02018
02019 int newZoomLevel = m_zoomLevel;
02020
02021 while (count > 0) {
02022 if (newZoomLevel <= 2) {
02023 newZoomLevel = 1;
02024 break;
02025 }
02026 newZoomLevel = getZoomConstraintBlockSize(newZoomLevel - 1,
02027 ZoomConstraint::RoundDown);
02028 --count;
02029 }
02030
02031 while (count < 0) {
02032 newZoomLevel = getZoomConstraintBlockSize(newZoomLevel + 1,
02033 ZoomConstraint::RoundUp);
02034 ++count;
02035 }
02036
02037 if (newZoomLevel != m_zoomLevel) {
02038 setZoomLevel(newZoomLevel);
02039 }
02040 }
02041
02042 emit paneInteractedWith();
02043 }
02044
02045 void
02046 Pane::horizontalThumbwheelMoved(int value)
02047 {
02049
02050 int count = 0;
02051 int level = 1;
02052
02053
02055 bool haveConstraint = false;
02056 for (LayerList::const_iterator i = m_layers.begin(); i != m_layers.end();
02057 ++i) {
02058 if ((*i)->getZoomConstraint() && !(*i)->supportsOtherZoomLevels()) {
02059 haveConstraint = true;
02060 break;
02061 }
02062 }
02063
02064 if (haveConstraint) {
02065 while (true) {
02066 if (m_hthumb->getMaximumValue() - value == count) break;
02067 int newLevel = getZoomConstraintBlockSize(level + 1,
02068 ZoomConstraint::RoundUp);
02069 if (newLevel == level) break;
02070 level = newLevel;
02071 if (++count == 50) break;
02072 }
02073 } else {
02074 while (true) {
02075 if (m_hthumb->getMaximumValue() - value == count) break;
02076 int step = level / 10;
02077 int pwr = 0;
02078 while (step > 0) {
02079 ++pwr;
02080 step /= 2;
02081 }
02082 step = 1;
02083 while (pwr > 0) {
02084 step *= 2;
02085 --pwr;
02086 }
02087
02088 level += step;
02089 if (++count == 100 || level > 262144) break;
02090 }
02091 }
02092
02093
02094 setZoomLevel(level);
02095 }
02096
02097 void
02098 Pane::verticalThumbwheelMoved(int value)
02099 {
02100 Layer *layer = 0;
02101 if (getLayerCount() > 0) layer = getLayer(getLayerCount() - 1);
02102 if (layer) {
02103 int defaultStep = 0;
02104 int max = layer->getVerticalZoomSteps(defaultStep);
02105 if (max == 0) {
02106 updateHeadsUpDisplay();
02107 return;
02108 }
02109 if (value > max) {
02110 value = max;
02111 }
02112 layer->setVerticalZoomStep(value);
02113 updateVerticalPanner();
02114 }
02115 }
02116
02117 void
02118 Pane::verticalPannerMoved(float x0, float y0, float w, float h)
02119 {
02120 float vmin, vmax, dmin, dmax;
02121 if (!getTopLayerDisplayExtents(vmin, vmax, dmin, dmax)) return;
02122 float y1 = y0 + h;
02123 float newmax = vmin + ((1.0 - y0) * (vmax - vmin));
02124 float newmin = vmin + ((1.0 - y1) * (vmax - vmin));
02125 std::cerr << "verticalPannerMoved: (" << x0 << "," << y0 << "," << w
02126 << "," << h << ") -> (" << newmin << "," << newmax << ")" << std::endl;
02127 setTopLayerDisplayExtents(newmin, newmax);
02128 }
02129
02130 void
02131 Pane::editVerticalPannerExtents()
02132 {
02133 if (!m_vpan || !m_manager || !m_manager->getZoomWheelsEnabled()) return;
02134
02135 float vmin, vmax, dmin, dmax;
02136 QString unit;
02137 if (!getTopLayerDisplayExtents(vmin, vmax, dmin, dmax, &unit)
02138 || vmax == vmin) {
02139 return;
02140 }
02141
02142 RangeInputDialog dialog(tr("Enter new range"),
02143 tr("New vertical display range, from %1 to %2 %4:")
02144 .arg(vmin).arg(vmax).arg(unit),
02145 unit, vmin, vmax, this);
02146 dialog.setRange(dmin, dmax);
02147
02148 if (dialog.exec() == QDialog::Accepted) {
02149 dialog.getRange(dmin, dmax);
02150 setTopLayerDisplayExtents(dmin, dmax);
02151 updateVerticalPanner();
02152 }
02153 }
02154
02155 void
02156 Pane::dragEnterEvent(QDragEnterEvent *e)
02157 {
02158 QStringList formats(e->mimeData()->formats());
02159 std::cerr << "dragEnterEvent: format: "
02160 << formats.join(",").toStdString()
02161 << ", possibleActions: " << e->possibleActions()
02162 << ", proposedAction: " << e->proposedAction() << std::endl;
02163
02164 if (e->provides("text/uri-list") || e->provides("text/plain")) {
02165
02166 if (e->proposedAction() & Qt::CopyAction) {
02167 e->acceptProposedAction();
02168 } else {
02169 e->setDropAction(Qt::CopyAction);
02170 e->accept();
02171 }
02172 }
02173 }
02174
02175 void
02176 Pane::dropEvent(QDropEvent *e)
02177 {
02178 std::cerr << "dropEvent: text: \"" << e->mimeData()->text().toStdString()
02179 << "\"" << std::endl;
02180
02181 if (e->provides("text/uri-list") || e->provides("text/plain")) {
02182
02183 if (e->proposedAction() & Qt::CopyAction) {
02184 e->acceptProposedAction();
02185 } else {
02186 e->setDropAction(Qt::CopyAction);
02187 e->accept();
02188 }
02189
02190 if (e->provides("text/uri-list")) {
02191
02192 std::cerr << "accepting... data is \"" << e->encodedData("text/uri-list").data() << "\"" << std::endl;
02193 emit dropAccepted(QString::fromLocal8Bit
02194 (e->encodedData("text/uri-list").data())
02195 .split(QRegExp("[\\r\\n]+"),
02196 QString::SkipEmptyParts));
02197 } else {
02198 emit dropAccepted(QString::fromLocal8Bit
02199 (e->encodedData("text/plain").data()));
02200 }
02201 }
02202 }
02203
02204 bool
02205 Pane::editSelectionStart(QMouseEvent *e)
02206 {
02207 if (!m_identifyFeatures ||
02208 !m_manager ||
02209 m_manager->getToolMode() != ViewManager::EditMode) {
02210 return false;
02211 }
02212
02213 bool closeToLeft, closeToRight;
02214 Selection s(getSelectionAt(e->x(), closeToLeft, closeToRight));
02215 if (s.isEmpty()) return false;
02216 m_editingSelection = s;
02217 m_editingSelectionEdge = (closeToLeft ? -1 : closeToRight ? 1 : 0);
02218 m_mousePos = e->pos();
02219 return true;
02220 }
02221
02222 bool
02223 Pane::editSelectionDrag(QMouseEvent *e)
02224 {
02225 if (m_editingSelection.isEmpty()) return false;
02226 m_mousePos = e->pos();
02227 update();
02228 return true;
02229 }
02230
02231 bool
02232 Pane::editSelectionEnd(QMouseEvent *)
02233 {
02234 if (m_editingSelection.isEmpty()) return false;
02235
02236 int offset = m_mousePos.x() - m_clickPos.x();
02237 Layer *layer = getSelectedLayer();
02238
02239 if (offset == 0 || !layer) {
02240 m_editingSelection = Selection();
02241 return true;
02242 }
02243
02244 int p0 = getXForFrame(m_editingSelection.getStartFrame()) + offset;
02245 int p1 = getXForFrame(m_editingSelection.getEndFrame()) + offset;
02246
02247 long f0 = getFrameForX(p0);
02248 long f1 = getFrameForX(p1);
02249
02250 Selection newSelection(f0, f1);
02251
02252 if (m_editingSelectionEdge == 0) {
02253
02254 CommandHistory::getInstance()->startCompoundOperation
02255 (tr("Drag Selection"), true);
02256
02257 layer->moveSelection(m_editingSelection, f0);
02258
02259 } else {
02260
02261 CommandHistory::getInstance()->startCompoundOperation
02262 (tr("Resize Selection"), true);
02263
02264 if (m_editingSelectionEdge < 0) {
02265 f1 = m_editingSelection.getEndFrame();
02266 } else {
02267 f0 = m_editingSelection.getStartFrame();
02268 }
02269
02270 newSelection = Selection(f0, f1);
02271 layer->resizeSelection(m_editingSelection, newSelection);
02272 }
02273
02274 m_manager->removeSelection(m_editingSelection);
02275 m_manager->addSelection(newSelection);
02276
02277 CommandHistory::getInstance()->endCompoundOperation();
02278
02279 m_editingSelection = Selection();
02280 return true;
02281 }
02282
02283 void
02284 Pane::toolModeChanged()
02285 {
02286 ViewManager::ToolMode mode = m_manager->getToolMode();
02287
02288
02289 if (mode == ViewManager::MeasureMode && !m_measureCursor1) {
02290 m_measureCursor1 = new QCursor(QBitmap(":/icons/measure1cursor.xbm"),
02291 QBitmap(":/icons/measure1mask.xbm"),
02292 15, 14);
02293 m_measureCursor2 = new QCursor(QBitmap(":/icons/measure2cursor.xbm"),
02294 QBitmap(":/icons/measure2mask.xbm"),
02295 16, 17);
02296 }
02297
02298 switch (mode) {
02299
02300 case ViewManager::NavigateMode:
02301 setCursor(Qt::PointingHandCursor);
02302 break;
02303
02304 case ViewManager::SelectMode:
02305 setCursor(Qt::ArrowCursor);
02306 break;
02307
02308 case ViewManager::EditMode:
02309 setCursor(Qt::UpArrowCursor);
02310 break;
02311
02312 case ViewManager::DrawMode:
02313 setCursor(Qt::CrossCursor);
02314 break;
02315
02316 case ViewManager::EraseMode:
02317 setCursor(Qt::CrossCursor);
02318 break;
02319
02320 case ViewManager::MeasureMode:
02321 if (m_measureCursor1) setCursor(*m_measureCursor1);
02322 break;
02323
02324
02325
02326
02327
02328
02329 }
02330 }
02331
02332 void
02333 Pane::zoomWheelsEnabledChanged()
02334 {
02335 updateHeadsUpDisplay();
02336 update();
02337 }
02338
02339 void
02340 Pane::viewZoomLevelChanged(View *v, unsigned long z, bool locked)
02341 {
02342
02343
02344
02345 View::viewZoomLevelChanged(v, z, locked);
02346
02347 if (m_hthumb && !m_hthumb->isVisible()) return;
02348
02349 if (v != this) {
02350 if (!locked || !m_followZoom) return;
02351 }
02352
02353 if (m_manager && m_manager->getZoomWheelsEnabled()) {
02354 updateHeadsUpDisplay();
02355 }
02356 }
02357
02358 void
02359 Pane::propertyContainerSelected(View *v, PropertyContainer *pc)
02360 {
02361 Layer *layer = 0;
02362
02363 if (getLayerCount() > 0) {
02364 layer = getLayer(getLayerCount() - 1);
02365 disconnect(layer, SIGNAL(verticalZoomChanged()),
02366 this, SLOT(verticalZoomChanged()));
02367 }
02368
02369 View::propertyContainerSelected(v, pc);
02370 updateHeadsUpDisplay();
02371
02372 if (m_vthumb) {
02373 RangeMapper *rm = 0;
02374 if (layer) rm = layer->getNewVerticalZoomRangeMapper();
02375 if (rm) m_vthumb->setRangeMapper(rm);
02376 }
02377
02378 if (getLayerCount() > 0) {
02379 layer = getLayer(getLayerCount() - 1);
02380 connect(layer, SIGNAL(verticalZoomChanged()),
02381 this, SLOT(verticalZoomChanged()));
02382 }
02383 }
02384
02385 void
02386 Pane::verticalZoomChanged()
02387 {
02388 Layer *layer = 0;
02389
02390 if (getLayerCount() > 0) {
02391
02392 layer = getLayer(getLayerCount() - 1);
02393
02394 if (m_vthumb && m_vthumb->isVisible()) {
02395 m_vthumb->setValue(layer->getCurrentVerticalZoomStep());
02396 }
02397 }
02398 }
02399
02400 void
02401 Pane::updateContextHelp(const QPoint *pos)
02402 {
02403 QString help = "";
02404
02405 if (m_clickedInRange) {
02406 emit contextHelpChanged("");
02407 return;
02408 }
02409
02410 ViewManager::ToolMode mode = ViewManager::NavigateMode;
02411 if (m_manager) mode = m_manager->getToolMode();
02412
02413 bool editable = false;
02414 Layer *layer = getSelectedLayer();
02415 if (layer && layer->isLayerEditable()) {
02416 editable = true;
02417 }
02418
02419 if (mode == ViewManager::NavigateMode) {
02420
02421 help = tr("Click and drag to navigate");
02422
02423 } else if (mode == ViewManager::SelectMode) {
02424
02425 if (!hasTopLayerTimeXAxis()) return;
02426
02427 bool haveSelection = (m_manager && !m_manager->getSelections().empty());
02428
02429 if (haveSelection) {
02430 if (editable) {
02431 help = tr("Click and drag to select a range; hold Shift to avoid snapping to items; hold Ctrl for multi-select; middle-click and drag to navigate");
02432 } else {
02433 help = tr("Click and drag to select a range; hold Ctrl for multi-select; middle-click and drag to navigate");
02434 }
02435
02436 if (pos) {
02437 bool closeToLeft = false, closeToRight = false;
02438 Selection selection = getSelectionAt(pos->x(), closeToLeft, closeToRight);
02439 if ((closeToLeft || closeToRight) && !(closeToLeft && closeToRight)) {
02440
02441 help = tr("Click and drag to move the selection boundary");
02442 }
02443 }
02444 } else {
02445 if (editable) {
02446 help = tr("Click and drag to select a range; hold Shift to avoid snapping to items; middle-click to navigate");
02447 } else {
02448 help = tr("Click and drag to select a range; middle-click and drag to navigate");
02449 }
02450 }
02451
02452 } else if (mode == ViewManager::DrawMode) {
02453
02455 if (editable) {
02456 help = tr("Click to add a new item in the active layer");
02457 }
02458
02459 } else if (mode == ViewManager::EraseMode) {
02460
02462 if (editable) {
02463 help = tr("Click to erase an item from the active layer");
02464 }
02465
02466 } else if (mode == ViewManager::EditMode) {
02467
02469 if (editable) {
02470 help = tr("Click and drag an item in the active layer to move it");
02471 if (pos) {
02472 bool closeToLeft = false, closeToRight = false;
02473 Selection selection = getSelectionAt(pos->x(), closeToLeft, closeToRight);
02474 if (!selection.isEmpty()) {
02475 help = tr("Click and drag to move all items in the selected range");
02476 }
02477 }
02478 }
02479 }
02480
02481 emit contextHelpChanged(help);
02482 }
02483
02484 void
02485 Pane::mouseEnteredWidget()
02486 {
02487 QWidget *w = dynamic_cast<QWidget *>(sender());
02488 if (!w) return;
02489
02490 if (w == m_vpan) {
02491 emit contextHelpChanged(tr("Click and drag to adjust the visible range of the vertical scale"));
02492 } else if (w == m_vthumb) {
02493 emit contextHelpChanged(tr("Click and drag to adjust the vertical zoom level"));
02494 } else if (w == m_hthumb) {
02495 emit contextHelpChanged(tr("Click and drag to adjust the horizontal zoom level"));
02496 } else if (w == m_reset) {
02497 emit contextHelpChanged(tr("Reset horizontal and vertical zoom levels to their defaults"));
02498 }
02499 }
02500
02501 void
02502 Pane::mouseLeftWidget()
02503 {
02504 emit contextHelpChanged("");
02505 }
02506
02507 void
02508 Pane::toXml(QTextStream &stream,
02509 QString indent, QString extraAttributes) const
02510 {
02511 View::toXml
02512 (stream, indent,
02513 QString("type=\"pane\" centreLineVisible=\"%1\" height=\"%2\" %3")
02514 .arg(m_centreLineVisible).arg(height()).arg(extraAttributes));
02515 }
02516
02517