svcore
1.9
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 Sonic Visualiser 00005 An audio file viewer and annotation editor. 00006 Centre for Digital Music, Queen Mary, University of London. 00007 This file copyright 2006-2008 Chris Cannam and QMUL. 00008 00009 This program is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU General Public License as 00011 published by the Free Software Foundation; either version 2 of the 00012 License, or (at your option) any later version. See the file 00013 COPYING included with this distribution for more information. 00014 */ 00015 00016 #ifndef _INTERVAL_MODEL_H_ 00017 #define _INTERVAL_MODEL_H_ 00018 00019 #include "SparseValueModel.h" 00020 #include "base/RealTime.h" 00021 00028 template <typename PointType> 00029 class IntervalModel : public SparseValueModel<PointType> 00030 { 00031 public: 00032 IntervalModel(int sampleRate, int resolution, 00033 bool notifyOnAdd = true) : 00034 SparseValueModel<PointType>(sampleRate, resolution, notifyOnAdd) 00035 { } 00036 00037 IntervalModel(int sampleRate, int resolution, 00038 float valueMinimum, float valueMaximum, 00039 bool notifyOnAdd = true) : 00040 SparseValueModel<PointType>(sampleRate, resolution, 00041 valueMinimum, valueMaximum, 00042 notifyOnAdd) 00043 { } 00044 00051 virtual typename SparseValueModel<PointType>::PointList getPoints(long start, long end) const; 00052 00058 virtual typename SparseValueModel<PointType>::PointList getPoints(long frame) const; 00059 00060 virtual const typename SparseModel<PointType>::PointList &getPoints() const { 00061 return SparseModel<PointType>::getPoints(); 00062 } 00063 00068 virtual QVariant getData(int row, int column, int role) const 00069 { 00070 if (column < 2) { 00071 return SparseValueModel<PointType>::getData 00072 (row, column, role); 00073 } 00074 00075 typename SparseModel<PointType>::PointList::const_iterator i 00076 = SparseModel<PointType>::getPointListIteratorForRow(row); 00077 if (i == SparseModel<PointType>::m_points.end()) return QVariant(); 00078 00079 switch (column) { 00080 case 2: 00081 if (role == Qt::EditRole || role == TabularModel::SortRole) return i->value; 00082 else return QString("%1 %2").arg(i->value).arg 00083 (IntervalModel<PointType>::getScaleUnits()); 00084 case 3: return int(i->duration); 00085 default: return QVariant(); 00086 } 00087 } 00088 00089 virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role) 00090 { 00091 typedef IntervalModel<PointType> I; 00092 00093 if (column < 2) { 00094 return SparseValueModel<PointType>::getSetDataCommand 00095 (row, column, value, role); 00096 } 00097 00098 if (role != Qt::EditRole) return 0; 00099 typename I::PointList::const_iterator i 00100 = I::getPointListIteratorForRow(row); 00101 if (i == I::m_points.end()) return 0; 00102 typename I::EditCommand *command = new typename I::EditCommand 00103 (this, I::tr("Edit Data")); 00104 00105 PointType point(*i); 00106 command->deletePoint(point); 00107 00108 switch (column) { 00109 // column cannot be 0 or 1, those cases were handled above 00110 case 2: point.value = value.toDouble(); break; 00111 case 3: point.duration = value.toInt(); break; 00112 } 00113 00114 command->addPoint(point); 00115 return command->finish(); 00116 } 00117 00118 virtual bool isColumnTimeValue(int column) const 00119 { 00120 // NB duration is not a "time value" -- that's for columns 00121 // whose sort ordering is exactly that of the frame time 00122 return (column < 2); 00123 } 00124 }; 00125 00126 template <typename PointType> 00127 typename SparseValueModel<PointType>::PointList 00128 IntervalModel<PointType>::getPoints(long start, long end) const 00129 { 00130 typedef IntervalModel<PointType> I; 00131 00132 if (start > end) return typename I::PointList(); 00133 00134 QMutex &mutex(I::m_mutex); 00135 QMutexLocker locker(&mutex); 00136 00137 PointType endPoint(end); 00138 00139 typename I::PointListConstIterator endItr = I::m_points.upper_bound(endPoint); 00140 00141 if (endItr != I::m_points.end()) ++endItr; 00142 if (endItr != I::m_points.end()) ++endItr; 00143 00144 typename I::PointList rv; 00145 00146 for (typename I::PointListConstIterator i = endItr; i != I::m_points.begin(); ) { 00147 --i; 00148 if (i->frame < start) { 00149 if (i->frame + long(i->duration) >= start) { 00150 rv.insert(*i); 00151 } 00152 } else if (i->frame <= end) { 00153 rv.insert(*i); 00154 } 00155 } 00156 00157 return rv; 00158 } 00159 00160 template <typename PointType> 00161 typename SparseValueModel<PointType>::PointList 00162 IntervalModel<PointType>::getPoints(long frame) const 00163 { 00164 typedef IntervalModel<PointType> I; 00165 00166 QMutex &mutex(I::m_mutex); 00167 QMutexLocker locker(&mutex); 00168 00169 if (I::m_resolution == 0) return typename I::PointList(); 00170 00171 long start = (frame / I::m_resolution) * I::m_resolution; 00172 long end = start + I::m_resolution; 00173 00174 PointType endPoint(end); 00175 00176 typename I::PointListConstIterator endItr = I::m_points.upper_bound(endPoint); 00177 00178 typename I::PointList rv; 00179 00180 for (typename I::PointListConstIterator i = endItr; i != I::m_points.begin(); ) { 00181 --i; 00182 if (i->frame < start) { 00183 if (i->frame + long(i->duration) >= start) { 00184 rv.insert(*i); 00185 } 00186 } else if (i->frame <= end) { 00187 rv.insert(*i); 00188 } 00189 } 00190 00191 return rv; 00192 } 00193 00194 #endif