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 _REGION_MODEL_H_ 00017 #define _REGION_MODEL_H_ 00018 00019 #include "IntervalModel.h" 00020 #include "base/RealTime.h" 00021 00036 struct RegionRec 00037 { 00038 public: 00039 RegionRec() : frame(0), value(0.f), duration(0) { } 00040 RegionRec(long _frame) : frame(_frame), value(0.0f), duration(0) { } 00041 RegionRec(long _frame, float _value, int _duration, QString _label) : 00042 frame(_frame), value(_value), duration(_duration), label(_label) { } 00043 00044 int getDimensions() const { return 3; } 00045 00046 long frame; 00047 float value; 00048 int duration; 00049 QString label; 00050 00051 QString getLabel() const { return label; } 00052 00053 void toXml(QTextStream &stream, 00054 QString indent = "", 00055 QString extraAttributes = "") const 00056 { 00057 stream << 00058 QString("%1<point frame=\"%2\" value=\"%3\" duration=\"%4\" label=\"%5\" %6/>\n") 00059 .arg(indent).arg(frame).arg(value).arg(duration) 00060 .arg(XmlExportable::encodeEntities(label)).arg(extraAttributes); 00061 } 00062 00063 QString toDelimitedDataString(QString delimiter, int sampleRate) const 00064 { 00065 QStringList list; 00066 list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str(); 00067 list << QString("%1").arg(value); 00068 list << RealTime::frame2RealTime(duration, sampleRate).toString().c_str(); 00069 if (label != "") list << label; 00070 return list.join(delimiter); 00071 } 00072 00073 struct Comparator { 00074 bool operator()(const RegionRec &p1, 00075 const RegionRec &p2) const { 00076 if (p1.frame != p2.frame) return p1.frame < p2.frame; 00077 if (p1.value != p2.value) return p1.value < p2.value; 00078 if (p1.duration != p2.duration) return p1.duration < p2.duration; 00079 return p1.label < p2.label; 00080 } 00081 }; 00082 00083 struct OrderComparator { 00084 bool operator()(const RegionRec &p1, 00085 const RegionRec &p2) const { 00086 return p1.frame < p2.frame; 00087 } 00088 }; 00089 }; 00090 00091 00092 class RegionModel : public IntervalModel<RegionRec> 00093 { 00094 Q_OBJECT 00095 00096 public: 00097 RegionModel(int sampleRate, int resolution, 00098 bool notifyOnAdd = true) : 00099 IntervalModel<RegionRec>(sampleRate, resolution, notifyOnAdd), 00100 m_valueQuantization(0), 00101 m_haveDistinctValues(false) 00102 { 00103 } 00104 00105 RegionModel(int sampleRate, int resolution, 00106 float valueMinimum, float valueMaximum, 00107 bool notifyOnAdd = true) : 00108 IntervalModel<RegionRec>(sampleRate, resolution, 00109 valueMinimum, valueMaximum, 00110 notifyOnAdd), 00111 m_valueQuantization(0), 00112 m_haveDistinctValues(false) 00113 { 00114 } 00115 00116 virtual ~RegionModel() 00117 { 00118 } 00119 00120 float getValueQuantization() const { return m_valueQuantization; } 00121 void setValueQuantization(float q) { m_valueQuantization = q; } 00122 00123 bool haveDistinctValues() const { return m_haveDistinctValues; } 00124 00125 QString getTypeName() const { return tr("Region"); } 00126 00127 virtual void toXml(QTextStream &out, 00128 QString indent = "", 00129 QString extraAttributes = "") const 00130 { 00131 std::cerr << "RegionModel::toXml: extraAttributes = \"" 00132 << extraAttributes.toStdString() << std::endl; 00133 00134 IntervalModel<RegionRec>::toXml 00135 (out, 00136 indent, 00137 QString("%1 subtype=\"region\" valueQuantization=\"%2\"") 00138 .arg(extraAttributes).arg(m_valueQuantization)); 00139 } 00140 00145 virtual int getColumnCount() const 00146 { 00147 return 5; 00148 } 00149 00150 virtual QString getHeading(int column) const 00151 { 00152 switch (column) { 00153 case 0: return tr("Time"); 00154 case 1: return tr("Frame"); 00155 case 2: return tr("Value"); 00156 case 3: return tr("Duration"); 00157 case 4: return tr("Label"); 00158 default: return tr("Unknown"); 00159 } 00160 } 00161 00162 virtual QVariant getData(int row, int column, int role) const 00163 { 00164 if (column < 4) { 00165 return IntervalModel<RegionRec>::getData(row, column, role); 00166 } 00167 00168 PointListConstIterator i = getPointListIteratorForRow(row); 00169 if (i == m_points.end()) return QVariant(); 00170 00171 switch (column) { 00172 case 4: return i->label; 00173 default: return QVariant(); 00174 } 00175 } 00176 00177 virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role) 00178 { 00179 if (column < 4) { 00180 return IntervalModel<RegionRec>::getSetDataCommand 00181 (row, column, value, role); 00182 } 00183 00184 if (role != Qt::EditRole) return 0; 00185 PointListIterator i = getPointListIteratorForRow(row); 00186 if (i == m_points.end()) return 0; 00187 EditCommand *command = new EditCommand(this, tr("Edit Data")); 00188 00189 Point point(*i); 00190 command->deletePoint(point); 00191 00192 switch (column) { 00193 case 4: point.label = value.toString(); break; 00194 } 00195 00196 command->addPoint(point); 00197 return command->finish(); 00198 } 00199 00200 virtual SortType getSortType(int column) const 00201 { 00202 if (column == 4) return SortAlphabetical; 00203 return SortNumeric; 00204 } 00205 00206 virtual void addPoint(const Point &point) 00207 { 00208 if (point.value != 0.f) m_haveDistinctValues = true; 00209 IntervalModel<RegionRec>::addPoint(point); 00210 } 00211 00212 protected: 00213 float m_valueQuantization; 00214 bool m_haveDistinctValues; 00215 }; 00216 00217 #endif