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 Chris Cannam. 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 _SPARSE_TIME_VALUE_MODEL_H_ 00017 #define _SPARSE_TIME_VALUE_MODEL_H_ 00018 00019 #include "SparseValueModel.h" 00020 #include "base/PlayParameterRepository.h" 00021 #include "base/RealTime.h" 00022 00029 struct TimeValuePoint 00030 { 00031 public: 00032 TimeValuePoint(long _frame) : frame(_frame), value(0.0f) { } 00033 TimeValuePoint(long _frame, float _value, QString _label) : 00034 frame(_frame), value(_value), label(_label) { } 00035 00036 int getDimensions() const { return 2; } 00037 00038 long frame; 00039 float value; 00040 QString label; 00041 00042 QString getLabel() const { return label; } 00043 00044 void toXml(QTextStream &stream, QString indent = "", 00045 QString extraAttributes = "") const 00046 { 00047 stream << QString("%1<point frame=\"%2\" value=\"%3\" label=\"%4\" %5/>\n") 00048 .arg(indent).arg(frame).arg(value).arg(XmlExportable::encodeEntities(label)) 00049 .arg(extraAttributes); 00050 } 00051 00052 QString toDelimitedDataString(QString delimiter, int sampleRate) const 00053 { 00054 QStringList list; 00055 list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str(); 00056 list << QString("%1").arg(value); 00057 if (label != "") list << label; 00058 return list.join(delimiter); 00059 } 00060 00061 struct Comparator { 00062 bool operator()(const TimeValuePoint &p1, 00063 const TimeValuePoint &p2) const { 00064 if (p1.frame != p2.frame) return p1.frame < p2.frame; 00065 if (p1.value != p2.value) return p1.value < p2.value; 00066 return p1.label < p2.label; 00067 } 00068 }; 00069 00070 struct OrderComparator { 00071 bool operator()(const TimeValuePoint &p1, 00072 const TimeValuePoint &p2) const { 00073 return p1.frame < p2.frame; 00074 } 00075 }; 00076 }; 00077 00078 00079 class SparseTimeValueModel : public SparseValueModel<TimeValuePoint> 00080 { 00081 Q_OBJECT 00082 00083 public: 00084 SparseTimeValueModel(int sampleRate, int resolution, 00085 bool notifyOnAdd = true) : 00086 SparseValueModel<TimeValuePoint>(sampleRate, resolution, 00087 notifyOnAdd) 00088 { 00089 // Model is playable, but may not sound (if units not Hz or 00090 // range unsuitable) 00091 PlayParameterRepository::getInstance()->addPlayable(this); 00092 } 00093 00094 SparseTimeValueModel(int sampleRate, int resolution, 00095 float valueMinimum, float valueMaximum, 00096 bool notifyOnAdd = true) : 00097 SparseValueModel<TimeValuePoint>(sampleRate, resolution, 00098 valueMinimum, valueMaximum, 00099 notifyOnAdd) 00100 { 00101 // Model is playable, but may not sound (if units not Hz or 00102 // range unsuitable) 00103 PlayParameterRepository::getInstance()->addPlayable(this); 00104 } 00105 00106 virtual ~SparseTimeValueModel() 00107 { 00108 PlayParameterRepository::getInstance()->removePlayable(this); 00109 } 00110 00111 QString getTypeName() const { return tr("Sparse Time-Value"); } 00112 00113 virtual bool canPlay() const { return true; } 00114 virtual bool getDefaultPlayAudible() const { return false; } // user must unmute 00115 00120 virtual int getColumnCount() const 00121 { 00122 return 4; 00123 } 00124 00125 virtual QString getHeading(int column) const 00126 { 00127 switch (column) { 00128 case 0: return tr("Time"); 00129 case 1: return tr("Frame"); 00130 case 2: return tr("Value"); 00131 case 3: return tr("Label"); 00132 default: return tr("Unknown"); 00133 } 00134 } 00135 00136 virtual QVariant getData(int row, int column, int role) const 00137 { 00138 if (column < 2) { 00139 return SparseValueModel<TimeValuePoint>::getData 00140 (row, column, role); 00141 } 00142 00143 PointListConstIterator i = getPointListIteratorForRow(row); 00144 if (i == m_points.end()) return QVariant(); 00145 00146 switch (column) { 00147 case 2: 00148 if (role == Qt::EditRole || role == SortRole) return i->value; 00149 else return QString("%1 %2").arg(i->value).arg(getScaleUnits()); 00150 case 3: return i->label; 00151 default: return QVariant(); 00152 } 00153 } 00154 00155 virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role) 00156 { 00157 if (column < 2) { 00158 return SparseValueModel<TimeValuePoint>::getSetDataCommand 00159 (row, column, value, role); 00160 } 00161 00162 if (role != Qt::EditRole) return 0; 00163 PointListConstIterator i = getPointListIteratorForRow(row); 00164 if (i == m_points.end()) return 0; 00165 EditCommand *command = new EditCommand(this, tr("Edit Data")); 00166 00167 Point point(*i); 00168 command->deletePoint(point); 00169 00170 switch (column) { 00171 case 2: point.value = value.toDouble(); break; 00172 case 3: point.label = value.toString(); break; 00173 } 00174 00175 command->addPoint(point); 00176 return command->finish(); 00177 } 00178 00179 virtual bool isColumnTimeValue(int column) const 00180 { 00181 return (column < 2); 00182 } 00183 00184 virtual SortType getSortType(int column) const 00185 { 00186 if (column == 3) return SortAlphabetical; 00187 return SortNumeric; 00188 } 00189 }; 00190 00191 00192 #endif 00193 00194 00195