annotate data/model/IntervalModel.h @ 591:7065e921f122

* add reviewFileForAppend callback
author Chris Cannam
date Thu, 14 May 2009 15:48:07 +0000
parents 6441b31b37ac
children d7f3dfe6f9a4
rev   line source
Chris@437 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@437 2
Chris@437 3 /*
Chris@437 4 Sonic Visualiser
Chris@437 5 An audio file viewer and annotation editor.
Chris@437 6 Centre for Digital Music, Queen Mary, University of London.
Chris@437 7 This file copyright 2006-2008 Chris Cannam and QMUL.
Chris@437 8
Chris@437 9 This program is free software; you can redistribute it and/or
Chris@437 10 modify it under the terms of the GNU General Public License as
Chris@437 11 published by the Free Software Foundation; either version 2 of the
Chris@437 12 License, or (at your option) any later version. See the file
Chris@437 13 COPYING included with this distribution for more information.
Chris@437 14 */
Chris@437 15
Chris@437 16 #ifndef _INTERVAL_MODEL_H_
Chris@437 17 #define _INTERVAL_MODEL_H_
Chris@437 18
Chris@437 19 #include "SparseValueModel.h"
Chris@437 20 #include "base/RealTime.h"
Chris@437 21
Chris@437 22 /**
Chris@437 23 * Model containing sparse data (points with some properties) of which
Chris@437 24 * the properties include a duration and an arbitrary float value.
Chris@437 25 * The other properties depend on the point type.
Chris@437 26 */
Chris@437 27
Chris@437 28 template <typename PointType>
Chris@437 29 class IntervalModel : public SparseValueModel<PointType>
Chris@437 30 {
Chris@437 31 public:
Chris@437 32 IntervalModel(size_t sampleRate, size_t resolution,
Chris@437 33 bool notifyOnAdd = true) :
Chris@437 34 SparseValueModel<PointType>(sampleRate, resolution, notifyOnAdd)
Chris@437 35 { }
Chris@437 36
Chris@437 37 IntervalModel(size_t sampleRate, size_t resolution,
Chris@437 38 float valueMinimum, float valueMaximum,
Chris@437 39 bool notifyOnAdd = true) :
Chris@437 40 SparseValueModel<PointType>(sampleRate, resolution,
Chris@437 41 valueMinimum, valueMaximum,
Chris@437 42 notifyOnAdd)
Chris@437 43 { }
Chris@437 44
Chris@437 45 /**
Chris@437 46 * PointTypes have a duration, so this returns all points that span any
Chris@437 47 * of the given range (as well as the usual additional few before
Chris@437 48 * and after). Consequently this can be very slow (optimised data
Chris@437 49 * structures still to be done!).
Chris@437 50 */
Chris@437 51 virtual typename SparseValueModel<PointType>::PointList getPoints(long start, long end) const;
Chris@437 52
Chris@437 53 /**
Chris@437 54 * PointTypes have a duration, so this returns all points that span the
Chris@437 55 * given frame. Consequently this can be very slow (optimised
Chris@437 56 * data structures still to be done!).
Chris@437 57 */
Chris@437 58 virtual typename SparseValueModel<PointType>::PointList getPoints(long frame) const;
Chris@437 59
Chris@459 60 virtual const typename SparseModel<PointType>::PointList &getPoints() const {
Chris@459 61 return SparseModel<PointType>::getPoints();
Chris@459 62 }
Chris@459 63
Chris@437 64 /**
Chris@437 65 * TabularModel methods.
Chris@437 66 */
Chris@437 67
Chris@437 68 virtual QVariant getData(int row, int column, int role) const
Chris@437 69 {
Chris@437 70 if (column < 2) {
Chris@437 71 return SparseValueModel<PointType>::getData
Chris@437 72 (row, column, role);
Chris@437 73 }
Chris@437 74
Chris@437 75 typename SparseModel<PointType>::PointList::const_iterator i
Chris@437 76 = SparseModel<PointType>::getPointListIteratorForRow(row);
Chris@437 77 if (i == SparseModel<PointType>::m_points.end()) return QVariant();
Chris@437 78
Chris@437 79 switch (column) {
Chris@437 80 case 2:
Chris@437 81 if (role == Qt::EditRole || role == TabularModel::SortRole) return i->value;
Chris@437 82 else return QString("%1 %2").arg(i->value).arg
Chris@437 83 (IntervalModel<PointType>::getScaleUnits());
Chris@437 84 case 3: return int(i->duration); //!!! could be better presented
Chris@437 85 default: return QVariant();
Chris@437 86 }
Chris@437 87 }
Chris@437 88
Chris@437 89 virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role)
Chris@437 90 {
Chris@438 91 typedef IntervalModel<PointType> I;
Chris@438 92
Chris@437 93 if (column < 2) {
Chris@437 94 return SparseValueModel<PointType>::getSetDataCommand
Chris@437 95 (row, column, value, role);
Chris@437 96 }
Chris@437 97
Chris@437 98 if (role != Qt::EditRole) return false;
Chris@438 99 typename I::PointList::const_iterator i
Chris@438 100 = I::getPointListIteratorForRow(row);
Chris@438 101 if (i == I::m_points.end()) return false;
Chris@438 102 typename I::EditCommand *command = new typename I::EditCommand
Chris@438 103 (this, I::tr("Edit Data"));
Chris@437 104
Chris@437 105 PointType point(*i);
Chris@437 106 command->deletePoint(point);
Chris@437 107
Chris@437 108 switch (column) {
Chris@437 109 case 0: case 1: point.frame = value.toInt(); break;
Chris@437 110 case 2: point.value = value.toDouble(); break;
Chris@437 111 case 3: point.duration = value.toInt(); break;
Chris@437 112 }
Chris@437 113
Chris@437 114 command->addPoint(point);
Chris@437 115 return command->finish();
Chris@437 116 }
Chris@437 117
Chris@437 118 virtual bool isColumnTimeValue(int column) const
Chris@437 119 {
Chris@437 120 return (column < 2 || column == 3);
Chris@437 121 }
Chris@437 122 };
Chris@437 123
Chris@437 124 template <typename PointType>
Chris@437 125 typename SparseValueModel<PointType>::PointList
Chris@437 126 IntervalModel<PointType>::getPoints(long start, long end) const
Chris@437 127 {
Chris@437 128 typedef IntervalModel<PointType> I;
Chris@437 129
Chris@437 130 if (start > end) return typename I::PointList();
Chris@437 131
Chris@437 132 QMutex &mutex(I::m_mutex);
Chris@437 133 QMutexLocker locker(&mutex);
Chris@437 134
Chris@437 135 PointType endPoint(end);
Chris@437 136
Chris@437 137 typename I::PointListIterator endItr = I::m_points.upper_bound(endPoint);
Chris@437 138
Chris@437 139 if (endItr != I::m_points.end()) ++endItr;
Chris@437 140 if (endItr != I::m_points.end()) ++endItr;
Chris@437 141
Chris@437 142 typename I::PointList rv;
Chris@437 143
Chris@437 144 for (typename I::PointListIterator i = endItr; i != I::m_points.begin(); ) {
Chris@437 145 --i;
Chris@437 146 if (i->frame < start) {
Chris@437 147 if (i->frame + long(i->duration) >= start) {
Chris@437 148 rv.insert(*i);
Chris@437 149 }
Chris@437 150 } else if (i->frame <= end) {
Chris@437 151 rv.insert(*i);
Chris@437 152 }
Chris@437 153 }
Chris@437 154
Chris@437 155 return rv;
Chris@437 156 }
Chris@437 157
Chris@437 158 template <typename PointType>
Chris@437 159 typename SparseValueModel<PointType>::PointList
Chris@437 160 IntervalModel<PointType>::getPoints(long frame) const
Chris@437 161 {
Chris@437 162 typedef IntervalModel<PointType> I;
Chris@437 163
Chris@437 164 QMutex &mutex(I::m_mutex);
Chris@437 165 QMutexLocker locker(&mutex);
Chris@437 166
Chris@437 167 if (I::m_resolution == 0) return typename I::PointList();
Chris@437 168
Chris@437 169 long start = (frame / I::m_resolution) * I::m_resolution;
Chris@437 170 long end = start + I::m_resolution;
Chris@437 171
Chris@437 172 PointType endPoint(end);
Chris@437 173
Chris@437 174 typename I::PointListIterator endItr = I::m_points.upper_bound(endPoint);
Chris@437 175
Chris@437 176 typename I::PointList rv;
Chris@437 177
Chris@437 178 for (typename I::PointListIterator i = endItr; i != I::m_points.begin(); ) {
Chris@437 179 --i;
Chris@437 180 if (i->frame < start) {
Chris@437 181 if (i->frame + long(i->duration) >= start) {
Chris@437 182 rv.insert(*i);
Chris@437 183 }
Chris@437 184 } else if (i->frame <= end) {
Chris@437 185 rv.insert(*i);
Chris@437 186 }
Chris@437 187 }
Chris@437 188
Chris@437 189 return rv;
Chris@437 190 }
Chris@437 191
Chris@437 192 #endif