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 _TEXT_MODEL_H_ 00017 #define _TEXT_MODEL_H_ 00018 00019 #include "SparseModel.h" 00020 #include "base/XmlExportable.h" 00021 #include "base/RealTime.h" 00022 00023 #include <QStringList> 00024 00031 struct TextPoint : public XmlExportable 00032 { 00033 public: 00034 TextPoint(long _frame) : frame(_frame), height(0.0f) { } 00035 TextPoint(long _frame, float _height, QString _label) : 00036 frame(_frame), height(_height), label(_label) { } 00037 00038 int getDimensions() const { return 2; } 00039 00040 long frame; 00041 float height; 00042 QString label; 00043 00044 QString getLabel() const { return label; } 00045 00046 void toXml(QTextStream &stream, QString indent = "", 00047 QString extraAttributes = "") const 00048 { 00049 stream << QString("%1<point frame=\"%2\" height=\"%3\" label=\"%4\" %5/>\n") 00050 .arg(indent).arg(frame).arg(height) 00051 .arg(encodeEntities(label)).arg(extraAttributes); 00052 } 00053 00054 QString toDelimitedDataString(QString delimiter, int sampleRate) const 00055 { 00056 QStringList list; 00057 list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str(); 00058 list << QString("%1").arg(height); 00059 if (label != "") list << label; 00060 return list.join(delimiter); 00061 } 00062 00063 struct Comparator { 00064 bool operator()(const TextPoint &p1, 00065 const TextPoint &p2) const { 00066 if (p1.frame != p2.frame) return p1.frame < p2.frame; 00067 if (p1.height != p2.height) return p1.height < p2.height; 00068 return p1.label < p2.label; 00069 } 00070 }; 00071 00072 struct OrderComparator { 00073 bool operator()(const TextPoint &p1, 00074 const TextPoint &p2) const { 00075 return p1.frame < p2.frame; 00076 } 00077 }; 00078 }; 00079 00080 00081 // Make this a class rather than a typedef so it can be predeclared. 00082 00083 class TextModel : public SparseModel<TextPoint> 00084 { 00085 Q_OBJECT 00086 00087 public: 00088 TextModel(int sampleRate, int resolution, bool notifyOnAdd = true) : 00089 SparseModel<TextPoint>(sampleRate, resolution, notifyOnAdd) 00090 { } 00091 00092 virtual void toXml(QTextStream &out, 00093 QString indent = "", 00094 QString extraAttributes = "") const 00095 { 00096 SparseModel<TextPoint>::toXml 00097 (out, 00098 indent, 00099 QString("%1 subtype=\"text\"") 00100 .arg(extraAttributes)); 00101 } 00102 00103 QString getTypeName() const { return tr("Text"); } 00104 00109 virtual int getColumnCount() const 00110 { 00111 return 4; 00112 } 00113 00114 virtual QString getHeading(int column) const 00115 { 00116 switch (column) { 00117 case 0: return tr("Time"); 00118 case 1: return tr("Frame"); 00119 case 2: return tr("Height"); 00120 case 3: return tr("Label"); 00121 default: return tr("Unknown"); 00122 } 00123 } 00124 00125 virtual QVariant getData(int row, int column, int role) const 00126 { 00127 if (column < 2) { 00128 return SparseModel<TextPoint>::getData 00129 (row, column, role); 00130 } 00131 00132 PointListConstIterator i = getPointListIteratorForRow(row); 00133 if (i == m_points.end()) return QVariant(); 00134 00135 switch (column) { 00136 case 2: return i->height; 00137 case 3: return i->label; 00138 default: return QVariant(); 00139 } 00140 } 00141 00142 virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role) 00143 { 00144 if (column < 2) { 00145 return SparseModel<TextPoint>::getSetDataCommand 00146 (row, column, value, role); 00147 } 00148 00149 if (role != Qt::EditRole) return 0; 00150 PointListIterator i = getPointListIteratorForRow(row); 00151 if (i == m_points.end()) return 0; 00152 EditCommand *command = new EditCommand(this, tr("Edit Data")); 00153 00154 Point point(*i); 00155 command->deletePoint(point); 00156 00157 switch (column) { 00158 case 2: point.height = value.toDouble(); break; 00159 case 3: point.label = value.toString(); break; 00160 } 00161 00162 command->addPoint(point); 00163 return command->finish(); 00164 } 00165 00166 virtual bool isColumnTimeValue(int column) const 00167 { 00168 return (column < 2); 00169 } 00170 00171 virtual SortType getSortType(int column) const 00172 { 00173 if (column == 3) return SortAlphabetical; 00174 return SortNumeric; 00175 } 00176 00177 }; 00178 00179 00180 #endif 00181 00182 00183