# HG changeset patch # User Chris Cannam # Date 1182856101 0 # Node ID 70537b0434c47f2bd9349c99c6d4e6914c0a3fb4 # Parent 4ed1446ad6046cc2d56bf196c95444f9ef928d03 * Use a command for adding layer measurements diff -r 4ed1446ad604 -r 70537b0434c4 layer/Layer.cpp --- a/layer/Layer.cpp Thu Jun 21 16:12:00 2007 +0000 +++ b/layer/Layer.cpp Tue Jun 26 11:08:21 2007 +0000 @@ -16,6 +16,7 @@ #include "Layer.h" #include "view/View.h" #include "data/model/Model.h" +#include "base/CommandHistory.h" #include @@ -71,24 +72,6 @@ emit layerNameChanged(); } -QString -Layer::toXmlString(QString indent, QString extraAttributes) const -{ - QString s; - - s += indent; - - s += QString("\n") - .arg(encodeEntities(LayerFactory::getInstance()->getLayerTypeName - (LayerFactory::getInstance()->getLayerType(this)))) - .arg(getObjectExportId(this)) - .arg(encodeEntities(objectName())) - .arg(getObjectExportId(getModel())) - .arg(extraAttributes); - - return s; -} - PlayParameters * Layer::getPlayParameters() { @@ -137,13 +120,64 @@ return true; } +bool +Layer::MeasureRect::operator<(const MeasureRect &mr) const +{ + if (haveFrames) { + if (startFrame == mr.startFrame) { + if (endFrame != mr.endFrame) { + return endFrame < mr.endFrame; + } + } else { + return startFrame < mr.startFrame; + } + } else { + if (pixrect.x() == mr.pixrect.x()) { + if (pixrect.width() != mr.pixrect.width()) { + return pixrect.width() < mr.pixrect.width(); + } + } else { + return pixrect.x() < mr.pixrect.x(); + } + } + + // the two rects are equal in x and width + + if (pixrect.y() == mr.pixrect.y()) { + return pixrect.height() < mr.pixrect.height(); + } else { + return pixrect.y() < mr.pixrect.y(); + } +} + +QString +Layer::AddMeasurementRectCommand::getName() const +{ + return tr("Make Measurement"); +} + +void +Layer::AddMeasurementRectCommand::execute() +{ + m_layer->addMeasureRect(m_rect); +} + +void +Layer::AddMeasurementRectCommand::unexecute() +{ + m_layer->deleteMeasureRect(m_rect); +} + void Layer::measureStart(View *v, QMouseEvent *e) { m_draggingRect.pixrect = QRect(e->x(), e->y(), 0, 0); if (hasTimeXAxis()) { + m_draggingRect.haveFrames = true; m_draggingRect.startFrame = v->getFrameForX(e->x()); m_draggingRect.endFrame = m_draggingRect.startFrame; + } else { + m_draggingRect.haveFrames = false; } m_haveDraggingRect = true; } @@ -152,10 +186,13 @@ Layer::measureDrag(View *v, QMouseEvent *e) { if (!m_haveDraggingRect) return; + m_draggingRect.pixrect = QRect(m_draggingRect.pixrect.x(), m_draggingRect.pixrect.y(), e->x() - m_draggingRect.pixrect.x(), - e->y() - m_draggingRect.pixrect.y()); + e->y() - m_draggingRect.pixrect.y()) + .normalized(); + if (hasTimeXAxis()) { m_draggingRect.endFrame = v->getFrameForX(e->x()); } @@ -164,10 +201,12 @@ void Layer::measureEnd(View *v, QMouseEvent *e) { - //!!! command if (!m_haveDraggingRect) return; measureDrag(v, e); - m_measureRectList.push_back(m_draggingRect); + + CommandHistory::getInstance()->addCommand + (new AddMeasurementRectCommand(this, m_draggingRect)); + m_haveDraggingRect = false; } @@ -175,22 +214,53 @@ Layer::paintMeasurementRects(View *v, QPainter &paint) const { if (m_haveDraggingRect) { - v->drawMeasurementRect(paint, this, m_draggingRect.pixrect); + paintMeasurementRect(v, paint, m_draggingRect); } - bool timex = hasTimeXAxis(); - - for (MeasureRectList::const_iterator i = m_measureRectList.begin(); - i != m_measureRectList.end(); ++i) { - - if (timex) { - int x0 = v->getXForFrame(i->startFrame); - int x1 = v->getXForFrame(i->endFrame); - QRect pr = QRect(x0, i->pixrect.y(), x1 - x0, i->pixrect.height()); - i->pixrect = pr; - } - - v->drawMeasurementRect(paint, this, i->pixrect); + for (MeasureRectSet::const_iterator i = m_measureRects.begin(); + i != m_measureRects.end(); ++i) { + paintMeasurementRect(v, paint, *i); } } +void +Layer::paintMeasurementRect(View *v, QPainter &paint, MeasureRect &r) +{ + if (r.haveFrames) { + + int x0 = -1; + int x1 = v->width() + 1; + + if (r.startFrame >= v->getStartFrame()) { + x0 = v->getXForFrame(r.startFrame); + } + if (r.endFrame <= v->getEndFrame()) { + x1 = v->getXForFrame(r.endFrame); + } + + QRect pr = QRect(x0, r.pixrect.y(), + x1 - x0, r.pixrect.height()); + + r.pixrect = pr; + } + + v->drawMeasurementRect(paint, this, r.pixrect); +} + +QString +Layer::toXmlString(QString indent, QString extraAttributes) const +{ + QString s; + + s += indent; + + s += QString("\n") + .arg(encodeEntities(LayerFactory::getInstance()->getLayerTypeName + (LayerFactory::getInstance()->getLayerType(this)))) + .arg(getObjectExportId(this)) + .arg(encodeEntities(objectName())) + .arg(getObjectExportId(getModel())) + .arg(extraAttributes); + + return s; +} diff -r 4ed1446ad604 -r 70537b0434c4 layer/Layer.h --- a/layer/Layer.h Thu Jun 21 16:12:00 2007 +0000 +++ b/layer/Layer.h Tue Jun 26 11:08:21 2007 +0000 @@ -27,6 +27,7 @@ #include #include +#include class ZoomConstraint; class Model; @@ -396,22 +397,54 @@ void layerParametersChanged(); void layerParameterRangesChanged(); + void layerMeasurementRectsChanged(); void layerNameChanged(); void verticalZoomChanged(); protected: struct MeasureRect { + mutable QRect pixrect; - long startFrame; // only valid for a layer that hasTimeXAxis + bool haveFrames; + long startFrame; // only valid if haveFrames long endFrame; // ditto + + bool operator<(const MeasureRect &mr) const; }; - typedef std::vector MeasureRectList; // should be x-ordered - MeasureRectList m_measureRectList; + class AddMeasurementRectCommand : public Command + { + public: + AddMeasurementRectCommand(Layer *layer, MeasureRect rect) : + m_layer(layer), m_rect(rect) { } + + virtual QString getName() const; + virtual void execute(); + virtual void unexecute(); + + private: + Layer *m_layer; + MeasureRect m_rect; + }; + + void addMeasureRect(const MeasureRect &r) { + m_measureRects.insert(r); + emit layerMeasurementRectsChanged(); + } + + void deleteMeasureRect(const MeasureRect &r) { + m_measureRects.erase(r); + emit layerMeasurementRectsChanged(); + } + + typedef std::set MeasureRectSet; + MeasureRectSet m_measureRects; MeasureRect m_draggingRect; bool m_haveDraggingRect; + void paintMeasurementRect(View *v, QPainter &paint, MeasureRect &r); + private: mutable QMutex m_dormancyMutex; mutable std::map m_dormancy; diff -r 4ed1446ad604 -r 70537b0434c4 view/Pane.cpp --- a/view/Pane.cpp Thu Jun 21 16:12:00 2007 +0000 +++ b/view/Pane.cpp Tue Jun 26 11:08:21 2007 +0000 @@ -396,11 +396,11 @@ } } - Layer *topLayer = 0; + Layer *topLayer = getTopLayer(); + const Model *waveformModel = 0; // just for reporting purposes for (LayerList::iterator vi = m_layers.end(); vi != m_layers.begin(); ) { --vi; - if (!topLayer) topLayer = *vi; if (dynamic_cast(*vi)) { waveformModel = (*vi)->getModel(); break; @@ -968,8 +968,7 @@ float &dmin, float &dmax, QString *unit) { - Layer *layer = 0; - if (getLayerCount() > 0) layer = getLayer(getLayerCount() - 1); + Layer *layer = getTopLayer(); if (!layer) return false; bool vlog; QString vunit; @@ -982,8 +981,7 @@ bool Pane::setTopLayerDisplayExtents(float dmin, float dmax) { - Layer *layer = 0; - if (getLayerCount() > 0) layer = getLayer(getLayerCount() - 1); + Layer *layer = getTopLayer(); if (!layer) return false; return layer->setDisplayExtents(dmin, dmax); } @@ -1089,7 +1087,7 @@ } else if (mode == ViewManager::MeasureMode) { - Layer *layer = getSelectedLayer(); + Layer *layer = getTopLayer(); if (layer) layer->measureStart(this, e); update(); } @@ -1175,7 +1173,7 @@ } else if (mode == ViewManager::MeasureMode) { - Layer *layer = getSelectedLayer(); + Layer *layer = getTopLayer(); if (layer) layer->measureEnd(this, e); if (m_measureCursor1) setCursor(*m_measureCursor1); update(); @@ -1268,7 +1266,7 @@ if (m_measureCursor2) setCursor(*m_measureCursor2); - Layer *layer = getSelectedLayer(); + Layer *layer = getTopLayer(); if (layer) layer->measureDrag(this, e); if (hasTopLayerTimeXAxis()) { diff -r 4ed1446ad604 -r 70537b0434c4 view/View.cpp --- a/view/View.cpp Thu Jun 21 16:12:00 2007 +0000 +++ b/view/View.cpp Tue Jun 26 11:08:21 2007 +0000 @@ -466,6 +466,8 @@ this, SLOT(layerParametersChanged())); connect(layer, SIGNAL(layerParameterRangesChanged()), this, SLOT(layerParameterRangesChanged())); + connect(layer, SIGNAL(layerMeasurementRectsChanged()), + this, SLOT(layerMeasurementRectsChanged())); connect(layer, SIGNAL(layerNameChanged()), this, SLOT(layerNameChanged())); connect(layer, SIGNAL(modelChanged()), @@ -784,6 +786,13 @@ } void +View::layerMeasurementRectsChanged() +{ + Layer *layer = dynamic_cast(sender()); + if (layer) update(); +} + +void View::layerNameChanged() { Layer *layer = dynamic_cast(sender()); @@ -1631,6 +1640,9 @@ void View::drawMeasurementRect(QPainter &paint, const Layer *topLayer, QRect r) const { +// std::cerr << "View::drawMeasurementRect(" << r.x() << "," << r.y() << " " +// << r.width() << "x" << r.height() << ")" << std::endl; + if (r.x() + r.width() < 0 || r.x() >= width()) return; int fontHeight = paint.fontMetrics().height(); diff -r 4ed1446ad604 -r 70537b0434c4 view/View.h --- a/view/View.h Thu Jun 21 16:12:00 2007 +0000 +++ b/view/View.h Tue Jun 26 11:08:21 2007 +0000 @@ -153,6 +153,15 @@ virtual Layer *getLayer(int n) { return m_layers[n]; } /** + * Return the top layer. This is the same as + * getLayer(getLayerCount()-1) if there is at least one layer, and + * 0 otherwise. + */ + virtual Layer *getTopLayer() { + return m_layers.empty() ? 0 : m_layers[m_layers.size()-1]; + } + + /** * Return the layer last selected by the user. This is normally * the top layer, the same as getLayer(getLayerCount()-1). * However, if the user has selected the pane itself more recently @@ -261,6 +270,7 @@ virtual void modelReplaced(); virtual void layerParametersChanged(); virtual void layerParameterRangesChanged(); + virtual void layerMeasurementRectsChanged(); virtual void layerNameChanged(); virtual void globalCentreFrameChanged(unsigned long);