# HG changeset patch # User Chris Cannam # Date 1141236781 0 # Node ID 78515b1e29eb7c302207452c9a1419da273ebe67 # Parent 1bdf285c4eac2adc673ac43f1c6e5c24078d6105 * Rejig project file a bit to do pkg-config detection &c and change some HAVE_* symbol names accordingly * Add selection move/resize/delete * First stubs for add layer / pane commands diff -r 1bdf285c4eac -r 78515b1e29eb layer/NoteLayer.cpp --- a/layer/NoteLayer.cpp Mon Feb 27 17:34:41 2006 +0000 +++ b/layer/NoteLayer.cpp Wed Mar 01 18:13:01 2006 +0000 @@ -617,6 +617,66 @@ m_editing = false; } +void +NoteLayer::moveSelection(Selection s, size_t newStartFrame) +{ + NoteModel::EditCommand *command = + new NoteModel::EditCommand(m_model, tr("Drag Selection")); + + NoteModel::PointList points = + m_model->getPoints(s.getStartFrame(), s.getEndFrame()); + + for (NoteModel::PointList::iterator i = points.begin(); + i != points.end(); ++i) { + + if (s.contains(i->frame)) { + NoteModel::Point newPoint(*i); + newPoint.frame = i->frame + newStartFrame - s.getStartFrame(); + command->deletePoint(*i); + command->addPoint(newPoint); + } + } + + command->finish(); +} + +void +NoteLayer::resizeSelection(Selection s, Selection newSize) +{ + NoteModel::EditCommand *command = + new NoteModel::EditCommand(m_model, tr("Resize Selection")); + + NoteModel::PointList points = + m_model->getPoints(s.getStartFrame(), s.getEndFrame()); + + double ratio = + double(newSize.getEndFrame() - newSize.getStartFrame()) / + double(s.getEndFrame() - s.getStartFrame()); + + for (NoteModel::PointList::iterator i = points.begin(); + i != points.end(); ++i) { + + if (s.contains(i->frame)) { + + double targetStart = i->frame; + targetStart = newSize.getStartFrame() + + double(targetStart - s.getStartFrame()) * ratio; + + double targetEnd = i->frame + i->duration; + targetEnd = newSize.getStartFrame() + + double(targetEnd - s.getStartFrame()) * ratio; + + NoteModel::Point newPoint(*i); + newPoint.frame = lrint(targetStart); + newPoint.duration = lrint(targetEnd - targetStart); + command->deletePoint(*i); + command->addPoint(newPoint); + } + } + + command->finish(); +} + QString NoteLayer::toXmlString(QString indent, QString extraAttributes) const { diff -r 1bdf285c4eac -r 78515b1e29eb layer/NoteLayer.h --- a/layer/NoteLayer.h Mon Feb 27 17:34:41 2006 +0000 +++ b/layer/NoteLayer.h Wed Mar 01 18:13:01 2006 +0000 @@ -42,6 +42,9 @@ virtual void editDrag(QMouseEvent *); virtual void editEnd(QMouseEvent *); + virtual void moveSelection(Selection s, size_t newStartFrame); + virtual void resizeSelection(Selection s, Selection newSize); + virtual const Model *getModel() const { return m_model; } void setModel(NoteModel *model); diff -r 1bdf285c4eac -r 78515b1e29eb layer/SpectrogramLayer.cpp --- a/layer/SpectrogramLayer.cpp Mon Feb 27 17:34:41 2006 +0000 +++ b/layer/SpectrogramLayer.cpp Wed Mar 01 18:13:01 2006 +0000 @@ -1327,7 +1327,7 @@ m_layer.m_cache->resize(width, height); m_layer.setCacheColourmap(); - m_layer.m_cache->reset(); +//!!! m_layer.m_cache->reset(); // We don't need a lock when writing to or reading from // the pixels in the cache. We do need to ensure we have @@ -2165,6 +2165,18 @@ if (haveValues) { float dbMin = AudioLevel::multiplier_to_dB(magMin); float dbMax = AudioLevel::multiplier_to_dB(magMax); + QString dbMinString; + QString dbMaxString; + if (dbMin == AudioLevel::DB_FLOOR) { + dbMinString = tr("-Inf"); + } else { + dbMinString = QString("%1").arg(lrintf(dbMin)); + } + if (dbMax == AudioLevel::DB_FLOOR) { + dbMaxString = tr("-Inf"); + } else { + dbMaxString = QString("%1").arg(lrintf(dbMax)); + } if (lrintf(dbMin) != lrintf(dbMax)) { text += tr("dB:\t%1 - %2").arg(lrintf(dbMin)).arg(lrintf(dbMax)); } else { diff -r 1bdf285c4eac -r 78515b1e29eb layer/TextLayer.cpp --- a/layer/TextLayer.cpp Mon Feb 27 17:34:41 2006 +0000 +++ b/layer/TextLayer.cpp Wed Mar 01 18:13:01 2006 +0000 @@ -589,6 +589,61 @@ } } +void +TextLayer::moveSelection(Selection s, size_t newStartFrame) +{ + TextModel::EditCommand *command = + new TextModel::EditCommand(m_model, tr("Drag Selection")); + + TextModel::PointList points = + m_model->getPoints(s.getStartFrame(), s.getEndFrame()); + + for (TextModel::PointList::iterator i = points.begin(); + i != points.end(); ++i) { + + if (s.contains(i->frame)) { + TextModel::Point newPoint(*i); + newPoint.frame = i->frame + newStartFrame - s.getStartFrame(); + command->deletePoint(*i); + command->addPoint(newPoint); + } + } + + command->finish(); +} + +void +TextLayer::resizeSelection(Selection s, Selection newSize) +{ + TextModel::EditCommand *command = + new TextModel::EditCommand(m_model, tr("Resize Selection")); + + TextModel::PointList points = + m_model->getPoints(s.getStartFrame(), s.getEndFrame()); + + double ratio = + double(newSize.getEndFrame() - newSize.getStartFrame()) / + double(s.getEndFrame() - s.getStartFrame()); + + for (TextModel::PointList::iterator i = points.begin(); + i != points.end(); ++i) { + + if (s.contains(i->frame)) { + + double target = i->frame; + target = newSize.getStartFrame() + + double(target - s.getStartFrame()) * ratio; + + TextModel::Point newPoint(*i); + newPoint.frame = lrint(target); + command->deletePoint(*i); + command->addPoint(newPoint); + } + } + + command->finish(); +} + QString TextLayer::toXmlString(QString indent, QString extraAttributes) const { diff -r 1bdf285c4eac -r 78515b1e29eb layer/TextLayer.h --- a/layer/TextLayer.h Mon Feb 27 17:34:41 2006 +0000 +++ b/layer/TextLayer.h Wed Mar 01 18:13:01 2006 +0000 @@ -42,6 +42,9 @@ virtual void editDrag(QMouseEvent *); virtual void editEnd(QMouseEvent *); + virtual void moveSelection(Selection s, size_t newStartFrame); + virtual void resizeSelection(Selection s, Selection newSize); + virtual void editOpen(QMouseEvent *); // on double-click virtual const Model *getModel() const { return m_model; } diff -r 1bdf285c4eac -r 78515b1e29eb layer/TimeInstantLayer.cpp --- a/layer/TimeInstantLayer.cpp Mon Feb 27 17:34:41 2006 +0000 +++ b/layer/TimeInstantLayer.cpp Wed Mar 01 18:13:01 2006 +0000 @@ -572,6 +572,82 @@ m_editing = false; } +void +TimeInstantLayer::moveSelection(Selection s, size_t newStartFrame) +{ + SparseOneDimensionalModel::EditCommand *command = + new SparseOneDimensionalModel::EditCommand(m_model, + tr("Drag Selection")); + + SparseOneDimensionalModel::PointList points = + m_model->getPoints(s.getStartFrame(), s.getEndFrame()); + + for (SparseOneDimensionalModel::PointList::iterator i = points.begin(); + i != points.end(); ++i) { + + if (s.contains(i->frame)) { + SparseOneDimensionalModel::Point newPoint(*i); + newPoint.frame = i->frame + newStartFrame - s.getStartFrame(); + command->deletePoint(*i); + command->addPoint(newPoint); + } + } + + command->finish(); +} + +void +TimeInstantLayer::resizeSelection(Selection s, Selection newSize) +{ + SparseOneDimensionalModel::EditCommand *command = + new SparseOneDimensionalModel::EditCommand(m_model, + tr("Resize Selection")); + + SparseOneDimensionalModel::PointList points = + m_model->getPoints(s.getStartFrame(), s.getEndFrame()); + + double ratio = + double(newSize.getEndFrame() - newSize.getStartFrame()) / + double(s.getEndFrame() - s.getStartFrame()); + + for (SparseOneDimensionalModel::PointList::iterator i = points.begin(); + i != points.end(); ++i) { + + if (s.contains(i->frame)) { + + double target = i->frame; + target = newSize.getStartFrame() + + double(target - s.getStartFrame()) * ratio; + + SparseOneDimensionalModel::Point newPoint(*i); + newPoint.frame = lrint(target); + command->deletePoint(*i); + command->addPoint(newPoint); + } + } + + command->finish(); +} + +void +TimeInstantLayer::deleteSelection(Selection s) +{ + SparseOneDimensionalModel::EditCommand *command = + new SparseOneDimensionalModel::EditCommand(m_model, + tr("Delete Selection")); + + SparseOneDimensionalModel::PointList points = + m_model->getPoints(s.getStartFrame(), s.getEndFrame()); + + for (SparseOneDimensionalModel::PointList::iterator i = points.begin(); + i != points.end(); ++i) { + if (s.contains(i->frame)) command->deletePoint(*i); + } + + command->finish(); +} + + QString TimeInstantLayer::toXmlString(QString indent, QString extraAttributes) const { diff -r 1bdf285c4eac -r 78515b1e29eb layer/TimeInstantLayer.h --- a/layer/TimeInstantLayer.h Mon Feb 27 17:34:41 2006 +0000 +++ b/layer/TimeInstantLayer.h Wed Mar 01 18:13:01 2006 +0000 @@ -42,6 +42,10 @@ virtual void editDrag(QMouseEvent *); virtual void editEnd(QMouseEvent *); + virtual void moveSelection(Selection s, size_t newStartFrame); + virtual void resizeSelection(Selection s, Selection newSize); + virtual void deleteSelection(Selection s); + virtual const Model *getModel() const { return m_model; } void setModel(SparseOneDimensionalModel *model); diff -r 1bdf285c4eac -r 78515b1e29eb layer/TimeValueLayer.cpp --- a/layer/TimeValueLayer.cpp Mon Feb 27 17:34:41 2006 +0000 +++ b/layer/TimeValueLayer.cpp Wed Mar 01 18:13:01 2006 +0000 @@ -695,6 +695,63 @@ m_editing = false; } +void +TimeValueLayer::moveSelection(Selection s, size_t newStartFrame) +{ + SparseTimeValueModel::EditCommand *command = + new SparseTimeValueModel::EditCommand(m_model, + tr("Drag Selection")); + + SparseTimeValueModel::PointList points = + m_model->getPoints(s.getStartFrame(), s.getEndFrame()); + + for (SparseTimeValueModel::PointList::iterator i = points.begin(); + i != points.end(); ++i) { + + if (s.contains(i->frame)) { + SparseTimeValueModel::Point newPoint(*i); + newPoint.frame = i->frame + newStartFrame - s.getStartFrame(); + command->deletePoint(*i); + command->addPoint(newPoint); + } + } + + command->finish(); +} + +void +TimeValueLayer::resizeSelection(Selection s, Selection newSize) +{ + SparseTimeValueModel::EditCommand *command = + new SparseTimeValueModel::EditCommand(m_model, + tr("Resize Selection")); + + SparseTimeValueModel::PointList points = + m_model->getPoints(s.getStartFrame(), s.getEndFrame()); + + double ratio = + double(newSize.getEndFrame() - newSize.getStartFrame()) / + double(s.getEndFrame() - s.getStartFrame()); + + for (SparseTimeValueModel::PointList::iterator i = points.begin(); + i != points.end(); ++i) { + + if (s.contains(i->frame)) { + + double target = i->frame; + target = newSize.getStartFrame() + + double(target - s.getStartFrame()) * ratio; + + SparseTimeValueModel::Point newPoint(*i); + newPoint.frame = lrint(target); + command->deletePoint(*i); + command->addPoint(newPoint); + } + } + + command->finish(); +} + QString TimeValueLayer::toXmlString(QString indent, QString extraAttributes) const { diff -r 1bdf285c4eac -r 78515b1e29eb layer/TimeValueLayer.h --- a/layer/TimeValueLayer.h Mon Feb 27 17:34:41 2006 +0000 +++ b/layer/TimeValueLayer.h Wed Mar 01 18:13:01 2006 +0000 @@ -45,6 +45,9 @@ virtual void editDrag(QMouseEvent *); virtual void editEnd(QMouseEvent *); + virtual void moveSelection(Selection s, size_t newStartFrame); + virtual void resizeSelection(Selection s, Selection newSize); + virtual const Model *getModel() const { return m_model; } void setModel(SparseTimeValueModel *model); diff -r 1bdf285c4eac -r 78515b1e29eb widgets/LayerTree.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/LayerTree.cpp Wed Mar 01 18:13:01 2006 +0000 @@ -0,0 +1,207 @@ + +/* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */ + +/* + A waveform viewer and audio annotation editor. + Chris Cannam, Queen Mary University of London, 2005-2006 + + This is experimental software. Not for distribution. +*/ + +#include "LayerTree.h" +#include "PaneStack.h" + +#include "widgets/Pane.h" +#include "base/Layer.h" + +#include + + +LayerTreeModel::LayerTreeModel(PaneStack *stack, QObject *parent) : + QAbstractItemModel(parent), + m_stack(stack) +{ +} + +LayerTreeModel::~LayerTreeModel() +{ +} + +QVariant +LayerTreeModel::data(const QModelIndex &index, int role) const +{ + std::cerr << "LayerTreeModel::data(" << &index << ", role " << role << ")" << std::endl; + + if (!index.isValid()) return QVariant(); + if (role != Qt::DisplayRole) return QVariant(); + + QObject *obj = static_cast(index.internalPointer()); + + PaneStack *paneStack = dynamic_cast(obj); + if (paneStack) { + std::cerr << "node is pane stack" << std::endl; + return QVariant("Pane stack"); + } + + Pane *pane = dynamic_cast(obj); + if (pane) { + // need index of pane in pane stack + for (int i = 0; i < m_stack->getPaneCount(); ++i) { + if (pane == m_stack->getPane(i)) { + std::cerr << "node is pane " << i << std::endl; + return QVariant(QString("Pane %1").arg(i + 1)); + } + } + return QVariant(); + } + + Layer *layer = dynamic_cast(obj); + if (layer) { + std::cerr << "node is layer" << std::endl; + return QVariant(QString("%1").arg(layer->objectName())); + } + + return QVariant(); +} + +/* +Qt::ItemFlags +LayerTreeModel::flags(const QModelIndex &index) const +{ +} + +QVariant +LayerTreeModel::headerData(const QModelIndex &index, + Qt::Orientation orientation, + int role) const +{ +} +*/ + +QModelIndex +LayerTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + std::cerr << "LayerTreeModel::index(" << row << ", " << column << ", " + << &parent << ")" << std::endl; + + if (!parent.isValid()) { + // this is the pane stack + std::cerr << "parent invalid, returning pane stack as root" << std::endl; + return createIndex(row, column, m_stack); + } + + QObject *obj = static_cast(parent.internalPointer()); + + PaneStack *paneStack = dynamic_cast(obj); + if (paneStack) { + if (paneStack == m_stack && row < m_stack->getPaneCount()) { + std::cerr << "parent is pane stack, returning a pane" << std::endl; + return createIndex(row, column, m_stack->getPane(row)); + } + std::cerr << "parent is wrong pane stack, returning nothing" << std::endl; + return QModelIndex(); + } + + Pane *pane = dynamic_cast(obj); + if (pane) { + if (row < pane->getLayerCount()) { + std::cerr << "parent is pane, returning layer" << std::endl; + return createIndex(row, column, pane->getLayer(row)); + } + } + + std::cerr << "unknown parent, returning nothing" << std::endl; + return QModelIndex(); +} + +QModelIndex +LayerTreeModel::parent(const QModelIndex &index) const +{ + std::cerr << "LayerTreeModel::parent(" << &index << ")" << std::endl; + + QObject *obj = static_cast(index.internalPointer()); + + PaneStack *paneStack = dynamic_cast(obj); + if (paneStack) { + std::cerr << "node is pane stack, returning no parent" << std::endl; + return QModelIndex(); + } + + Pane *pane = dynamic_cast(obj); + if (pane) { + std::cerr << "node is pane, returning pane stack as parent" << std::endl; + return createIndex(0, 0, m_stack); + } + + Layer *layer = dynamic_cast(obj); + if (layer) { + const View *view = layer->getView(); + Pane *pane = const_cast(dynamic_cast(view)); + if (pane) { + // need index of pane in pane stack + for (int i = 0; i < m_stack->getPaneCount(); ++i) { + if (pane == m_stack->getPane(i)) { + std::cerr << "node is layer, returning pane " << i << " as parent" << std::endl; + return createIndex(i, 0, pane); + } + } + } + std::cerr << "node is layer, but no parent found" << std::endl; + return QModelIndex(); + } + + + + std::cerr << "unknown node" << std::endl; + return QModelIndex(); +} + +int +LayerTreeModel::rowCount(const QModelIndex &parent) const +{ + std::cerr << "LayerTreeModel::rowCount(" << &parent << ")" << std::endl; + + if (!parent.isValid()) { + std::cerr << "parent invalid, returning 1 for the pane stack" << std::endl; + return 1; // the pane stack + } + + QObject *obj = static_cast(parent.internalPointer()); + + PaneStack *paneStack = dynamic_cast(obj); + if (paneStack) { + if (paneStack == m_stack) { + std::cerr << "parent is pane stack, returning " + << m_stack->getPaneCount() << " panes" << std::endl; + return m_stack->getPaneCount(); + } else { + return 0; + } + } + + Pane *pane = dynamic_cast(obj); + if (pane) { + std::cerr << "parent is pane, returning " + << pane->getLayerCount() << " layers" << std::endl; + return pane->getLayerCount(); + } + + std::cerr << "parent unknown, returning 0" << std::endl; + return 0; +} + +int +LayerTreeModel::columnCount(const QModelIndex &parent) const +{ + if (!parent.isValid()) return 1; + + QObject *obj = static_cast(parent.internalPointer()); + + Pane *pane = dynamic_cast(obj); + if (pane) { + return 1; // 2; // layer and model + } + + return 1; +} + diff -r 1bdf285c4eac -r 78515b1e29eb widgets/LayerTree.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/LayerTree.h Wed Mar 01 18:13:01 2006 +0000 @@ -0,0 +1,45 @@ + +/* -*- c-basic-offset: 4 -*- vi:set ts=8 sts=4 sw=4: */ + +/* + A waveform viewer and audio annotation editor. + Chris Cannam, Queen Mary University of London, 2005-2006 + + This is experimental software. Not for distribution. +*/ + +#ifndef _LAYER_TREE_H_ +#define _LAYER_TREE_H_ + +#include + +class PaneStack; + +class LayerTreeModel : public QAbstractItemModel +{ + Q_OBJECT + +public: + LayerTreeModel(PaneStack *stack, QObject *parent = 0); + virtual ~LayerTreeModel(); + + QVariant data(const QModelIndex &index, int role) const; + +// Qt::ItemFlags flags(const QModelIndex &index) const; + +// QVariant headerData(int section, Qt::Orientation orientation, +// int role = Qt::DisplayRole) const; + + QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const; + + QModelIndex parent(const QModelIndex &index) const; + + int rowCount(const QModelIndex &parent = QModelIndex()) const; + int columnCount(const QModelIndex &parent = QModelIndex()) const; + +protected: + PaneStack *m_stack; +}; + +#endif diff -r 1bdf285c4eac -r 78515b1e29eb widgets/Pane.cpp --- a/widgets/Pane.cpp Mon Feb 27 17:34:41 2006 +0000 +++ b/widgets/Pane.cpp Wed Mar 01 18:13:01 2006 +0000 @@ -817,6 +817,12 @@ bool Pane::editSelectionStart(QMouseEvent *e) { + if (!m_identifyFeatures || + !m_manager || + m_manager->getToolMode() != ViewManager::EditMode) { + return false; + } + bool closeToLeft, closeToRight; Selection s(getSelectionAt(e->x(), closeToLeft, closeToRight)); if (s.isEmpty()) return false; @@ -839,6 +845,42 @@ Pane::editSelectionEnd(QMouseEvent *e) { if (m_editingSelection.isEmpty()) return false; + + int offset = m_mousePos.x() - m_clickPos.x(); + Layer *layer = getSelectedLayer(); + + if (offset == 0 || !layer) { + m_editingSelection = Selection(); + return true; + } + + int p0 = getXForFrame(m_editingSelection.getStartFrame()) + offset; + int p1 = getXForFrame(m_editingSelection.getEndFrame()) + offset; + + long f0 = getFrameForX(p0); + long f1 = getFrameForX(p1); + + Selection newSelection(f0, f1); + + if (m_editingSelectionEdge == 0) { + + layer->moveSelection(m_editingSelection, f0); + + } else { + + if (m_editingSelectionEdge < 0) { + f1 = m_editingSelection.getEndFrame(); + } else { + f0 = m_editingSelection.getStartFrame(); + } + + newSelection = Selection(f0, f1); + layer->resizeSelection(m_editingSelection, newSelection); + } + + m_manager->removeSelection(m_editingSelection); + m_manager->addSelection(newSelection); + m_editingSelection = Selection(); return true; } diff -r 1bdf285c4eac -r 78515b1e29eb widgets/PaneStack.h --- a/widgets/PaneStack.h Mon Feb 27 17:34:41 2006 +0000 +++ b/widgets/PaneStack.h Wed Mar 01 18:13:01 2006 +0000 @@ -30,9 +30,12 @@ Pane *addPane(bool suppressPropertyBox = false); // I own the returned value Pane *getPane(int n); // I own the returned value - void deletePane(Pane *pane); // Deletes the pane and all its views + void deletePane(Pane *pane); // Deletes the pane and all its layers int getPaneCount() const; +//!!! void hidePane(Pane *pane); +// void showPane(Pane *pane); + void setCurrentPane(Pane *pane); void setCurrentLayer(Pane *pane, Layer *layer); Pane *getCurrentPane();