# HG changeset patch # User Chris Cannam # Date 1553696012 0 # Node ID b5580d93f28b7d6e43fcb0087b4384c4e42872ed # Parent 82d03c9661f953c6e9b7173b1c7f7482b60391fe Remove no-longer-used model base classes diff -r 82d03c9661f9 -r b5580d93f28b data/model/IntervalModel.h --- a/data/model/IntervalModel.h Wed Mar 27 13:15:16 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,194 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Sonic Visualiser - An audio file viewer and annotation editor. - Centre for Digital Music, Queen Mary, University of London. - This file copyright 2006-2008 Chris Cannam and QMUL. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. See the file - COPYING included with this distribution for more information. -*/ - -#ifndef SV_INTERVAL_MODEL_H -#define SV_INTERVAL_MODEL_H - -#include "SparseValueModel.h" -#include "base/RealTime.h" - -/** - * Model containing sparse data (points with some properties) of which - * the properties include a duration and an arbitrary float value. - * The other properties depend on the point type. - */ - -template -class IntervalModel : public SparseValueModel -{ -public: - IntervalModel(sv_samplerate_t sampleRate, int resolution, - bool notifyOnAdd = true) : - SparseValueModel(sampleRate, resolution, notifyOnAdd) - { } - - IntervalModel(sv_samplerate_t sampleRate, int resolution, - float valueMinimum, float valueMaximum, - bool notifyOnAdd = true) : - SparseValueModel(sampleRate, resolution, - valueMinimum, valueMaximum, - notifyOnAdd) - { } - - /** - * PointTypes have a duration, so this returns all points that span any - * of the given range (as well as the usual additional few before - * and after). Consequently this can be very slow (optimised data - * structures still to be done!). - */ - typename SparseValueModel::PointList getPoints(sv_frame_t start, sv_frame_t end) const override; - - /** - * PointTypes have a duration, so this returns all points that span the - * given frame. Consequently this can be very slow (optimised - * data structures still to be done!). - */ - typename SparseValueModel::PointList getPoints(sv_frame_t frame) const override; - - const typename SparseModel::PointList &getPoints() const override { - return SparseModel::getPoints(); - } - - /** - * TabularModel methods. - */ - - QVariant getData(int row, int column, int role) const override - { - if (column < 2) { - return SparseValueModel::getData - (row, column, role); - } - - typename SparseModel::PointList::const_iterator i - = SparseModel::getPointListIteratorForRow(row); - if (i == SparseModel::m_points.end()) return QVariant(); - - switch (column) { - case 2: - if (role == Qt::EditRole || role == TabularModel::SortRole) return i->value; - else return QString("%1 %2").arg(i->value).arg - (IntervalModel::getScaleUnits()); - case 3: return int(i->duration); //!!! could be better presented - default: return QVariant(); - } - } - - Command *getSetDataCommand(int row, int column, const QVariant &value, int role) override - { - typedef IntervalModel I; - - if (column < 2) { - return SparseValueModel::getSetDataCommand - (row, column, value, role); - } - - if (role != Qt::EditRole) return 0; - typename I::PointList::const_iterator i - = I::getPointListIteratorForRow(row); - if (i == I::m_points.end()) return 0; - typename I::EditCommand *command = new typename I::EditCommand - (this, I::tr("Edit Data")); - - PointType point(*i); - command->deletePoint(point); - - switch (column) { - // column cannot be 0 or 1, those cases were handled above - case 2: point.value = float(value.toDouble()); break; - case 3: point.duration = value.toInt(); break; - } - - command->addPoint(point); - return command->finish(); - } - - bool isColumnTimeValue(int column) const override - { - // NB duration is not a "time value" -- that's for columns - // whose sort ordering is exactly that of the frame time - return (column < 2); - } -}; - -template -typename SparseValueModel::PointList -IntervalModel::getPoints(sv_frame_t start, sv_frame_t end) const -{ - typedef IntervalModel I; - - if (start > end) return typename I::PointList(); - - QMutex &mutex(I::m_mutex); - QMutexLocker locker(&mutex); - - PointType endPoint(end); - - typename I::PointListConstIterator endItr = I::m_points.upper_bound(endPoint); - - if (endItr != I::m_points.end()) ++endItr; - if (endItr != I::m_points.end()) ++endItr; - - typename I::PointList rv; - - for (typename I::PointListConstIterator i = endItr; i != I::m_points.begin(); ) { - --i; - if (i->frame < start) { - if (i->frame + i->duration >= start) { - rv.insert(*i); - } - } else if (i->frame <= end) { - rv.insert(*i); - } - } - - return rv; -} - -template -typename SparseValueModel::PointList -IntervalModel::getPoints(sv_frame_t frame) const -{ - typedef IntervalModel I; - - QMutex &mutex(I::m_mutex); - QMutexLocker locker(&mutex); - - if (I::m_resolution == 0) return typename I::PointList(); - - sv_frame_t start = (frame / I::m_resolution) * I::m_resolution; - sv_frame_t end = start + I::m_resolution; - - PointType endPoint(end); - - typename I::PointListConstIterator endItr = I::m_points.upper_bound(endPoint); - - typename I::PointList rv; - - for (typename I::PointListConstIterator i = endItr; i != I::m_points.begin(); ) { - --i; - if (i->frame < start) { - if (i->frame + i->duration >= start) { - rv.insert(*i); - } - } else if (i->frame <= end) { - rv.insert(*i); - } - } - - return rv; -} - -#endif diff -r 82d03c9661f9 -r b5580d93f28b data/model/SparseModel.h --- a/data/model/SparseModel.h Wed Mar 27 13:15:16 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1001 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Sonic Visualiser - An audio file viewer and annotation editor. - Centre for Digital Music, Queen Mary, University of London. - This file copyright 2006 Chris Cannam. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. See the file - COPYING included with this distribution for more information. -*/ - -#ifndef SV_SPARSE_MODEL_H -#define SV_SPARSE_MODEL_H - -#include "Model.h" -#include "TabularModel.h" -#include "base/Command.h" -#include "base/RealTime.h" -#include "system/System.h" - -#include - -#include -#include -#include -#include - -#include - -#include -#include - -/** - * Model containing sparse data (points with some properties). The - * properties depend on the point type. - */ -template -class SparseModel : public Model, - public TabularModel -{ - // If we omit the Q_OBJECT macro, lupdate complains. - - // If we include it, moc fails (can't handle template classes). - - // If we omit it, lupdate still seems to emit translatable - // messages for the tr() strings in here. So I guess we omit it. - -public: - SparseModel(sv_samplerate_t sampleRate, int resolution, - bool notifyOnAdd = true); - virtual ~SparseModel() { } - - bool isOK() const override { return true; } - sv_frame_t getStartFrame() const override; - sv_frame_t getEndFrame() const override; - sv_samplerate_t getSampleRate() const override { return m_sampleRate; } - - // Number of frames of the underlying sample rate that this model - // is capable of resolving to. For example, if m_resolution == 10 - // then every point in this model will be at a multiple of 10 - // sample frames and should be considered to cover a window ending - // 10 sample frames later. - virtual int getResolution() const { - return m_resolution ? m_resolution : 1; - } - virtual void setResolution(int resolution); - - // Extend the end of the model. If this is set to something beyond - // the end of the final point in the model, then getEndFrame() - // will return this value. Otherwise getEndFrame() will return the - // end of the final point. (This is used by the Tony application) - virtual void extendEndFrame(sv_frame_t to) { m_extendTo = to; } - - typedef PointType Point; - typedef std::multiset PointList; - typedef typename PointList::iterator PointListIterator; - typedef typename PointList::const_iterator PointListConstIterator; - - /** - * Return whether the model is empty or not. - */ - virtual bool isEmpty() const; - - /** - * Get the total number of points in the model. - */ - virtual int getPointCount() const; - - /** - * Get all points. - */ - virtual const PointList &getPoints() const; - - /** - * Get all of the points in this model between the given - * boundaries (in frames), as well as up to two points before and - * after the boundaries. If you need exact boundaries, check the - * point coordinates in the returned list. - */ - virtual PointList getPoints(sv_frame_t start, sv_frame_t end) const; - - /** - * Get all points that cover the given frame number, taking the - * resolution of the model into account. - */ - virtual PointList getPoints(sv_frame_t frame) const; - - /** - * Return all points that share the nearest frame number prior to - * the given one at which there are any points. - */ - virtual PointList getPreviousPoints(sv_frame_t frame) const; - - /** - * Return all points that share the nearest frame number - * subsequent to the given one at which there are any points. - */ - virtual PointList getNextPoints(sv_frame_t frame) const; - - /** - * Remove all points. - */ - virtual void clear(); - - /** - * Add a point. - */ - virtual void addPoint(const PointType &point); - - /** - * Remove a point. Points are not necessarily unique, so this - * function will remove the first point that compares equal to the - * supplied one using Point::Comparator. Other identical points - * may remain in the model. - */ - virtual void deletePoint(const PointType &point); - - /** - * Return true if the given point is found in this model, false - * otherwise. - */ - virtual bool containsPoint(const PointType &point); - - bool isReady(int *completion = 0) const override { - bool ready = isOK() && (m_completion == 100); - if (completion) *completion = m_completion; - return ready; - } - - virtual void setCompletion(int completion, bool update = true); - virtual int getCompletion() const { return m_completion; } - - virtual bool hasTextLabels() const { return m_hasTextLabels; } - - bool isSparse() const override { return true; } - - QString getTypeName() const override { return tr("Sparse"); } - - virtual QString getXmlOutputType() const { return "sparse"; } - - void toXml(QTextStream &out, - QString indent = "", - QString extraAttributes = "") const override; - - QString toDelimitedDataString(QString delimiter) const override { - return toDelimitedDataStringWithOptions - (delimiter, DataExportDefaults); - } - - QString toDelimitedDataStringWithOptions(QString delimiter, - DataExportOptions opts) const override { - return toDelimitedDataStringSubsetWithOptions - (delimiter, opts, - std::min(getStartFrame(), sv_frame_t(0)), getEndFrame()); - } - - QString toDelimitedDataStringSubset(QString delimiter, sv_frame_t f0, sv_frame_t f1) const override { - return toDelimitedDataStringSubsetWithOptions - (delimiter, DataExportDefaults, f0, f1); - } - - QString toDelimitedDataStringSubsetWithOptions(QString delimiter, DataExportOptions opts, sv_frame_t f0, sv_frame_t f1) const override { - if (opts & DataExportFillGaps) { - return toDelimitedDataStringSubsetFilled(delimiter, opts, f0, f1); - } else { - QString s; - for (PointListConstIterator i = m_points.begin(); i != m_points.end(); ++i) { - if (i->frame >= f0 && i->frame < f1) { - s += i->toDelimitedDataString(delimiter, opts, m_sampleRate) + "\n"; - } - } - return s; - } - } - - /** - * Command to add a point, with undo. - */ - class AddPointCommand : public Command - { - public: - AddPointCommand(SparseModel *model, - const PointType &point, - QString name = "") : - m_model(model), m_point(point), m_name(name) { } - - QString getName() const override { - return (m_name == "" ? tr("Add Point") : m_name); - } - - void execute() override { m_model->addPoint(m_point); } - void unexecute() override { m_model->deletePoint(m_point); } - - const PointType &getPoint() const { return m_point; } - - private: - SparseModel *m_model; - PointType m_point; - QString m_name; - }; - - - /** - * Command to remove a point, with undo. - */ - class DeletePointCommand : public Command - { - public: - DeletePointCommand(SparseModel *model, - const PointType &point) : - m_model(model), m_point(point) { } - - QString getName() const override { return tr("Delete Point"); } - - void execute() override { m_model->deletePoint(m_point); } - void unexecute() override { m_model->addPoint(m_point); } - - const PointType &getPoint() const { return m_point; } - - private: - SparseModel *m_model; - PointType m_point; - }; - - - /** - * Command to add or remove a series of points, with undo. - * Consecutive add/remove pairs for the same point are collapsed. - */ - class EditCommand : public MacroCommand - { - public: - EditCommand(SparseModel *model, QString commandName); - - virtual void addPoint(const PointType &point); - virtual void deletePoint(const PointType &point); - - /** - * Stack an arbitrary other command in the same sequence. - */ - void addCommand(Command *command) override { addCommand(command, true); } - - /** - * If any points have been added or deleted, return this - * command (so the caller can add it to the command history). - * Otherwise delete the command and return NULL. - */ - virtual EditCommand *finish(); - - protected: - virtual void addCommand(Command *command, bool executeFirst); - - SparseModel *m_model; - }; - - - /** - * Command to relabel a point. - */ - class RelabelCommand : public Command - { - public: - RelabelCommand(SparseModel *model, - const PointType &point, - QString newLabel) : - m_model(model), m_oldPoint(point), m_newPoint(point) { - m_newPoint.label = newLabel; - } - - QString getName() const override { return tr("Re-Label Point"); } - - void execute() override { - m_model->deletePoint(m_oldPoint); - m_model->addPoint(m_newPoint); - std::swap(m_oldPoint, m_newPoint); - } - - void unexecute() override { execute(); } - - private: - SparseModel *m_model; - PointType m_oldPoint; - PointType m_newPoint; - }; - - /** - * TabularModel methods. - */ - - int getRowCount() const override - { - return int(m_points.size()); - } - - sv_frame_t getFrameForRow(int row) const override - { - PointListConstIterator i = getPointListIteratorForRow(row); - if (i == m_points.end()) return 0; - return i->frame; - } - - int getRowForFrame(sv_frame_t frame) const override - { - if (m_rows.empty()) rebuildRowVector(); - std::vector::iterator i = - std::lower_bound(m_rows.begin(), m_rows.end(), frame); - ssize_t row = std::distance(m_rows.begin(), i); - if (i != m_rows.begin() && (i == m_rows.end() || *i != frame)) { - --row; - } - return int(row); - } - - int getColumnCount() const override { return 1; } - QVariant getData(int row, int column, int role) const override - { - PointListConstIterator i = getPointListIteratorForRow(row); - if (i == m_points.end()) { -// cerr << "no iterator for row " << row << " (have " << getRowCount() << " rows)" << endl; - return QVariant(); - } - -// cerr << "returning data for row " << row << " col " << column << endl; - - switch (column) { - case 0: { - if (role == SortRole) return int(i->frame); - RealTime rt = RealTime::frame2RealTime(i->frame, getSampleRate()); - if (role == Qt::EditRole) return rt.toString().c_str(); - else return rt.toText().c_str(); - } - case 1: return int(i->frame); - } - - return QVariant(); - } - - Command *getSetDataCommand(int row, int column, - const QVariant &value, int role) override - { - if (role != Qt::EditRole) return 0; - PointListIterator i = getPointListIteratorForRow(row); - if (i == m_points.end()) return 0; - EditCommand *command = new EditCommand(this, tr("Edit Data")); - - Point point(*i); - command->deletePoint(point); - - switch (column) { - case 0: point.frame = lrint(value.toDouble() * getSampleRate()); break; - case 1: point.frame = value.toInt(); break; - } - - command->addPoint(point); - return command->finish(); - } - - Command *getInsertRowCommand(int row) override - { - EditCommand *command = new EditCommand(this, tr("Insert Data Point")); - Point point(0); - PointListIterator i = getPointListIteratorForRow(row); - if (i == m_points.end() && i != m_points.begin()) --i; - if (i != m_points.end()) point = *i; - command->addPoint(point); - return command->finish(); - } - - Command *getRemoveRowCommand(int row) override - { - PointListIterator i = getPointListIteratorForRow(row); - if (i == m_points.end()) return 0; - EditCommand *command = new EditCommand(this, tr("Delete Data Point")); - command->deletePoint(*i); - return command->finish(); - } - -protected: - sv_samplerate_t m_sampleRate; - int m_resolution; - sv_frame_t m_extendTo; - bool m_notifyOnAdd; - sv_frame_t m_sinceLastNotifyMin; - sv_frame_t m_sinceLastNotifyMax; - bool m_hasTextLabels; - - PointList m_points; - int m_pointCount; - mutable QMutex m_mutex; - int m_completion; - - void getPointIterators(sv_frame_t frame, - PointListIterator &startItr, - PointListIterator &endItr); - void getPointIterators(sv_frame_t frame, - PointListConstIterator &startItr, - PointListConstIterator &endItr) const; - - // This is only used if the model is called on to act in - // TabularModel mode - mutable std::vector m_rows; // map from row number to frame - - void rebuildRowVector() const - { - m_rows.clear(); - for (PointListConstIterator i = m_points.begin(); i != m_points.end(); ++i) { -// std::cerr << "rebuildRowVector: row " << m_rows.size() << " -> " << i->frame << std::endl; - m_rows.push_back(i->frame); - } - } - - PointListIterator getPointListIteratorForRow(int row) - { - if (m_rows.empty()) rebuildRowVector(); - if (row < 0 || row + 1 > int(m_rows.size())) return m_points.end(); - - sv_frame_t frame = m_rows[row]; - int indexAtFrame = 0; - int ri = row; - while (ri > 0 && m_rows[ri-1] == m_rows[row]) { --ri; ++indexAtFrame; } - int initialIndexAtFrame = indexAtFrame; - - PointListIterator i0, i1; - getPointIterators(frame, i0, i1); - PointListIterator i = i0; - - for (i = i0; i != i1; ++i) { - if (i->frame < (int)frame) { continue; } - if (indexAtFrame > 0) { --indexAtFrame; continue; } - return i; - } - - if (indexAtFrame > 0) { - std::cerr << "WARNING: SparseModel::getPointListIteratorForRow: No iterator available for row " << row << " (frame = " << frame << ", index at frame = " << initialIndexAtFrame << ", leftover index " << indexAtFrame << ")" << std::endl; - } - return i; - } - - PointListConstIterator getPointListIteratorForRow(int row) const - { - if (m_rows.empty()) rebuildRowVector(); - if (row < 0 || row + 1 > int(m_rows.size())) return m_points.end(); - - sv_frame_t frame = m_rows[row]; - int indexAtFrame = 0; - int ri = row; - while (ri > 0 && m_rows[ri-1] == m_rows[row]) { --ri; ++indexAtFrame; } - int initialIndexAtFrame = indexAtFrame; - -// std::cerr << "getPointListIteratorForRow " << row << ": initialIndexAtFrame = " << initialIndexAtFrame << " for frame " << frame << std::endl; - - PointListConstIterator i0, i1; - getPointIterators(frame, i0, i1); - PointListConstIterator i = i0; - - for (i = i0; i != i1; ++i) { -// std::cerr << "i->frame is " << i->frame << ", wanting " << frame << std::endl; - - if (i->frame < (int)frame) { continue; } - if (indexAtFrame > 0) { --indexAtFrame; continue; } - return i; - } -/* - if (i == m_points.end()) { - std::cerr << "returning i at end" << std::endl; - } else { - std::cerr << "returning i with i->frame = " << i->frame << std::endl; - } -*/ - if (indexAtFrame > 0) { - std::cerr << "WARNING: SparseModel::getPointListIteratorForRow: No iterator available for row " << row << " (frame = " << frame << ", index at frame = " << initialIndexAtFrame << ", leftover index " << indexAtFrame << ")" << std::endl; - } - return i; - } - - QString toDelimitedDataStringSubsetFilled(QString delimiter, - DataExportOptions opts, - sv_frame_t f0, - sv_frame_t f1) const { - - QString s; - opts &= ~DataExportFillGaps; - - // find frame time of first point in range (if any) - sv_frame_t first = f0; - for (auto &p: m_points) { - if (p.frame >= f0) { - first = p.frame; - break; - } - } - - // project back to first frame time in range according to - // resolution. e.g. if f0 = 2, first = 9, resolution = 4 then - // we start at 5 (because 1 is too early and we need to arrive - // at 9 to match the first actual point). This method is - // stupid but easy to understand: - sv_frame_t f = first; - while (f >= f0 + m_resolution) f -= m_resolution; - - // now progress, either writing the next point (if within - // distance) or a default point - PointListConstIterator itr = m_points.begin(); - - while (f < f1) { - if (itr != m_points.end() && itr->frame <= f) { - s += itr->toDelimitedDataString(delimiter, opts, m_sampleRate); - ++itr; - } else { - s += Point(f).toDelimitedDataString(delimiter, opts, m_sampleRate); - } - s += "\n"; - f += m_resolution; - } - - return s; - } -}; - - -template -SparseModel::SparseModel(sv_samplerate_t sampleRate, - int resolution, - bool notifyOnAdd) : - m_sampleRate(sampleRate), - m_resolution(resolution), - m_extendTo(0), - m_notifyOnAdd(notifyOnAdd), - m_sinceLastNotifyMin(-1), - m_sinceLastNotifyMax(-1), - m_hasTextLabels(false), - m_pointCount(0), - m_completion(100) -{ -} - -template -sv_frame_t -SparseModel::getStartFrame() const -{ - QMutexLocker locker(&m_mutex); - sv_frame_t f = 0; - if (!m_points.empty()) { - f = m_points.begin()->frame; - } - return f; -} - -template -sv_frame_t -SparseModel::getEndFrame() const -{ - QMutexLocker locker(&m_mutex); - sv_frame_t f = 0; - if (!m_points.empty()) { - PointListConstIterator i(m_points.end()); - f = (--i)->frame + getResolution(); - } - if (m_extendTo > f) { - return m_extendTo; - } else { - return f; - } -} - -template -bool -SparseModel::isEmpty() const -{ - return m_pointCount == 0; -} - -template -int -SparseModel::getPointCount() const -{ - return m_pointCount; -} - -template -const typename SparseModel::PointList & -SparseModel::getPoints() const -{ - return m_points; -} - -template -typename SparseModel::PointList -SparseModel::getPoints(sv_frame_t start, sv_frame_t end) const -{ - if (start > end) return PointList(); - QMutexLocker locker(&m_mutex); - - PointType startPoint(start), endPoint(end); - - PointListConstIterator startItr = m_points.lower_bound(startPoint); - PointListConstIterator endItr = m_points.upper_bound(endPoint); - - if (startItr != m_points.begin()) --startItr; - if (startItr != m_points.begin()) --startItr; - if (endItr != m_points.end()) ++endItr; - if (endItr != m_points.end()) ++endItr; - - PointList rv; - - for (PointListConstIterator i = startItr; i != endItr; ++i) { - rv.insert(*i); - } - - return rv; -} - -template -typename SparseModel::PointList -SparseModel::getPoints(sv_frame_t frame) const -{ - PointListConstIterator startItr, endItr; - getPointIterators(frame, startItr, endItr); - - PointList rv; - - for (PointListConstIterator i = startItr; i != endItr; ++i) { - rv.insert(*i); - } - - return rv; -} - -template -void -SparseModel::getPointIterators(sv_frame_t frame, - PointListIterator &startItr, - PointListIterator &endItr) -{ - QMutexLocker locker(&m_mutex); - - if (m_resolution == 0) { - startItr = m_points.end(); - endItr = m_points.end(); - return; - } - - sv_frame_t start = (frame / m_resolution) * m_resolution; - sv_frame_t end = start + m_resolution; - - PointType startPoint(start), endPoint(end); - - startItr = m_points.lower_bound(startPoint); - endItr = m_points.upper_bound(endPoint); -} - -template -void -SparseModel::getPointIterators(sv_frame_t frame, - PointListConstIterator &startItr, - PointListConstIterator &endItr) const -{ - QMutexLocker locker(&m_mutex); - - if (m_resolution == 0) { -// std::cerr << "getPointIterators: resolution == 0, returning end()" << std::endl; - startItr = m_points.end(); - endItr = m_points.end(); - return; - } - - sv_frame_t start = (frame / m_resolution) * m_resolution; - sv_frame_t end = start + m_resolution; - - PointType startPoint(start), endPoint(end); - -// std::cerr << "getPointIterators: start frame " << start << ", end frame " << end << ", m_resolution " << m_resolution << std::endl; - - startItr = m_points.lower_bound(startPoint); - endItr = m_points.upper_bound(endPoint); -} - -template -typename SparseModel::PointList -SparseModel::getPreviousPoints(sv_frame_t originFrame) const -{ - QMutexLocker locker(&m_mutex); - - PointType lookupPoint(originFrame); - PointList rv; - - PointListConstIterator i = m_points.lower_bound(lookupPoint); - if (i == m_points.begin()) return rv; - - --i; - sv_frame_t frame = i->frame; - while (i->frame == frame) { - rv.insert(*i); - if (i == m_points.begin()) break; - --i; - } - - return rv; -} - -template -typename SparseModel::PointList -SparseModel::getNextPoints(sv_frame_t originFrame) const -{ - QMutexLocker locker(&m_mutex); - - PointType lookupPoint(originFrame); - PointList rv; - - PointListConstIterator i = m_points.upper_bound(lookupPoint); - if (i == m_points.end()) return rv; - - sv_frame_t frame = i->frame; - while (i != m_points.end() && i->frame == frame) { - rv.insert(*i); - ++i; - } - - return rv; -} - -template -void -SparseModel::setResolution(int resolution) -{ - { - QMutexLocker locker(&m_mutex); - m_resolution = resolution; - m_rows.clear(); - } - emit modelChanged(); -} - -template -void -SparseModel::clear() -{ - { - QMutexLocker locker(&m_mutex); - m_points.clear(); - m_pointCount = 0; - m_rows.clear(); - } - emit modelChanged(); -} - -template -void -SparseModel::addPoint(const PointType &point) -{ - { - QMutexLocker locker(&m_mutex); - - m_points.insert(point); - m_pointCount++; - if (point.getLabel() != "") m_hasTextLabels = true; - - // Even though this model is nominally sparse, there may still - // be too many signals going on here (especially as they'll - // probably be queued from one thread to another), which is - // why we need the notifyOnAdd as an option rather than a - // necessity (the alternative is to notify on setCompletion). - - if (m_notifyOnAdd) { - m_rows.clear(); //!!! inefficient - } else { - if (m_sinceLastNotifyMin == -1 || - point.frame < m_sinceLastNotifyMin) { - m_sinceLastNotifyMin = point.frame; - } - if (m_sinceLastNotifyMax == -1 || - point.frame > m_sinceLastNotifyMax) { - m_sinceLastNotifyMax = point.frame; - } - } - } - - if (m_notifyOnAdd) { - emit modelChangedWithin(point.frame, point.frame + m_resolution); - } -} - -template -bool -SparseModel::containsPoint(const PointType &point) -{ - QMutexLocker locker(&m_mutex); - - PointListIterator i = m_points.lower_bound(point); - typename PointType::Comparator comparator; - while (i != m_points.end()) { - if (i->frame > point.frame) break; - if (!comparator(*i, point) && !comparator(point, *i)) { - return true; - } - ++i; - } - - return false; -} - -template -void -SparseModel::deletePoint(const PointType &point) -{ - { - QMutexLocker locker(&m_mutex); - - PointListIterator i = m_points.lower_bound(point); - typename PointType::Comparator comparator; - while (i != m_points.end()) { - if (i->frame > point.frame) break; - if (!comparator(*i, point) && !comparator(point, *i)) { - m_points.erase(i); - m_pointCount--; - break; - } - ++i; - } - -// std::cout << "SparseOneDimensionalModel: emit modelChanged(" -// << point.frame << ")" << std::endl; - m_rows.clear(); //!!! inefficient - } - - emit modelChangedWithin(point.frame, point.frame + m_resolution); -} - -template -void -SparseModel::setCompletion(int completion, bool update) -{ -// std::cerr << "SparseModel::setCompletion(" << completion << ")" << std::endl; - bool emitCompletionChanged = true; - bool emitGeneralModelChanged = false; - bool emitRegionChanged = false; - - { - QMutexLocker locker(&m_mutex); - - if (m_completion != completion) { - m_completion = completion; - - if (completion == 100) { - - if (m_notifyOnAdd) { - emitCompletionChanged = false; - } - - m_notifyOnAdd = true; // henceforth - m_rows.clear(); //!!! inefficient - emitGeneralModelChanged = true; - - } else if (!m_notifyOnAdd) { - - if (update && - m_sinceLastNotifyMin >= 0 && - m_sinceLastNotifyMax >= 0) { - m_rows.clear(); //!!! inefficient - emitRegionChanged = true; - } - } - } - } - - if (emitCompletionChanged) { - emit completionChanged(); - } - if (emitGeneralModelChanged) { - emit modelChanged(); - } - if (emitRegionChanged) { - emit modelChangedWithin(m_sinceLastNotifyMin, m_sinceLastNotifyMax); - m_sinceLastNotifyMin = m_sinceLastNotifyMax = -1; - } -} - -template -void -SparseModel::toXml(QTextStream &out, - QString indent, - QString extraAttributes) const -{ -// std::cerr << "SparseModel::toXml: extraAttributes = \"" -// << extraAttributes.toStdString() << std::endl; - - QString type = getXmlOutputType(); - - Model::toXml - (out, - indent, - QString("type=\"%1\" dimensions=\"%2\" resolution=\"%3\" notifyOnAdd=\"%4\" dataset=\"%5\" %6") - .arg(type) - .arg(PointType(0).getDimensions()) - .arg(m_resolution) - .arg(m_notifyOnAdd ? "true" : "false") - .arg(getObjectExportId(&m_points)) - .arg(extraAttributes)); - - out << indent; - out << QString("\n") - .arg(getObjectExportId(&m_points)) - .arg(PointType(0).getDimensions()); - - for (PointListConstIterator i = m_points.begin(); i != m_points.end(); ++i) { - i->toXml(out, indent + " "); - } - - out << indent; - out << "\n"; -} - -template -SparseModel::EditCommand::EditCommand(SparseModel *model, - QString commandName) : - MacroCommand(commandName), - m_model(model) -{ -} - -template -void -SparseModel::EditCommand::addPoint(const PointType &point) -{ - addCommand(new AddPointCommand(m_model, point), true); -} - -template -void -SparseModel::EditCommand::deletePoint(const PointType &point) -{ - addCommand(new DeletePointCommand(m_model, point), true); -} - -template -typename SparseModel::EditCommand * -SparseModel::EditCommand::finish() -{ - if (!m_commands.empty()) { - return this; - } else { - delete this; - return 0; - } -} - -template -void -SparseModel::EditCommand::addCommand(Command *command, - bool executeFirst) -{ - if (executeFirst) command->execute(); - - if (!m_commands.empty()) { - DeletePointCommand *dpc = dynamic_cast(command); - if (dpc) { - AddPointCommand *apc = dynamic_cast - (m_commands[m_commands.size() - 1]); - typename PointType::Comparator comparator; - if (apc) { - if (!comparator(apc->getPoint(), dpc->getPoint()) && - !comparator(dpc->getPoint(), apc->getPoint())) { - deleteCommand(apc); - return; - } - } - } - } - - MacroCommand::addCommand(command); -} - -#endif - - - diff -r 82d03c9661f9 -r b5580d93f28b data/model/SparseValueModel.h --- a/data/model/SparseValueModel.h Wed Mar 27 13:15:16 2019 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ - -/* - Sonic Visualiser - An audio file viewer and annotation editor. - Centre for Digital Music, Queen Mary, University of London. - This file copyright 2006 Chris Cannam. - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. See the file - COPYING included with this distribution for more information. -*/ - -#ifndef SV_SPARSE_VALUE_MODEL_H -#define SV_SPARSE_VALUE_MODEL_H - -#include "SparseModel.h" -#include "base/UnitDatabase.h" - -#include "system/System.h" - -/** - * Model containing sparse data (points with some properties) of which - * one of the properties is an arbitrary float value. The other - * properties depend on the point type. - */ - -template -class SparseValueModel : public SparseModel -{ -public: - SparseValueModel(sv_samplerate_t sampleRate, int resolution, - bool notifyOnAdd = true) : - SparseModel(sampleRate, resolution, notifyOnAdd), - m_valueMinimum(0.f), - m_valueMaximum(0.f), - m_haveExtents(false) - { } - - SparseValueModel(sv_samplerate_t sampleRate, int resolution, - float valueMinimum, float valueMaximum, - bool notifyOnAdd = true) : - SparseModel(sampleRate, resolution, notifyOnAdd), - m_valueMinimum(valueMinimum), - m_valueMaximum(valueMaximum), - m_haveExtents(true) - { } - - using SparseModel::m_points; - using SparseModel::modelChanged; - using SparseModel::getPoints; - using SparseModel::tr; - - QString getTypeName() const override { return tr("Sparse Value"); } - - virtual float getValueMinimum() const { return m_valueMinimum; } - virtual float getValueMaximum() const { return m_valueMaximum; } - - virtual QString getScaleUnits() const { return m_units; } - virtual void setScaleUnits(QString units) { - m_units = units; - UnitDatabase::getInstance()->registerUnit(units); - } - - void addPoint(const PointType &point) override - { - bool allChange = false; - - if (!ISNAN(point.value) && !ISINF(point.value)) { - if (!m_haveExtents || point.value < m_valueMinimum) { - m_valueMinimum = point.value; allChange = true; -// std::cerr << "addPoint: value min = " << m_valueMinimum << std::endl; - } - if (!m_haveExtents || point.value > m_valueMaximum) { - m_valueMaximum = point.value; allChange = true; -// std::cerr << "addPoint: value max = " << m_valueMaximum << " (min = " << m_valueMinimum << ")" << std::endl; - } - m_haveExtents = true; - } - - SparseModel::addPoint(point); - if (allChange) emit modelChanged(); - } - - void deletePoint(const PointType &point) override - { - SparseModel::deletePoint(point); - - if (point.value == m_valueMinimum || - point.value == m_valueMaximum) { - - float formerMin = m_valueMinimum, formerMax = m_valueMaximum; - - for (typename SparseModel::PointList::const_iterator i - = m_points.begin(); - i != m_points.end(); ++i) { - - if (i == m_points.begin() || i->value < m_valueMinimum) { - m_valueMinimum = i->value; -// std::cerr << "deletePoint: value min = " << m_valueMinimum << std::endl; - } - if (i == m_points.begin() || i->value > m_valueMaximum) { - m_valueMaximum = i->value; -// std::cerr << "deletePoint: value max = " << m_valueMaximum << std::endl; - } - } - - if (formerMin != m_valueMinimum || formerMax != m_valueMaximum) { - emit modelChanged(); - } - } - } - - void toXml(QTextStream &stream, - QString indent = "", - QString extraAttributes = "") const override - { - std::cerr << "SparseValueModel::toXml: extraAttributes = \"" - << extraAttributes.toStdString() << "\"" << std::endl; - - SparseModel::toXml - (stream, - indent, - QString("%1 minimum=\"%2\" maximum=\"%3\" units=\"%4\"") - .arg(extraAttributes).arg(m_valueMinimum).arg(m_valueMaximum) - .arg(this->encodeEntities(m_units))); - } - -protected: - float m_valueMinimum; - float m_valueMaximum; - bool m_haveExtents; - QString m_units; -}; - - -#endif - diff -r 82d03c9661f9 -r b5580d93f28b files.pri --- a/files.pri Wed Mar 27 13:15:16 2019 +0000 +++ b/files.pri Wed Mar 27 14:13:32 2019 +0000 @@ -85,7 +85,6 @@ data/model/EventCommands.h \ data/model/FFTModel.h \ data/model/ImageModel.h \ - data/model/IntervalModel.h \ data/model/Labeller.h \ data/model/Model.h \ data/model/ModelDataTableModel.h \ @@ -96,10 +95,8 @@ data/model/RangeSummarisableTimeValueModel.h \ data/model/RegionModel.h \ data/model/RelativelyFineZoomConstraint.h \ - data/model/SparseModel.h \ data/model/SparseOneDimensionalModel.h \ data/model/SparseTimeValueModel.h \ - data/model/SparseValueModel.h \ data/model/TabularModel.h \ data/model/TextModel.h \ data/model/WaveformOversampler.h \