annotate data/model/SparseTimeValueModel.h @ 631:3a5ee4b6c9ad

* Complete the overhaul of CSV file import; now you can pick the purpose for each column in the file, and SV should do the rest. The most significant practical improvement here is that we can now handle files in which time and duration do not necessarily appear in known columns.
author Chris Cannam
date Mon, 19 Jul 2010 17:08:56 +0000
parents 1415e35881f6
children e22b6e89a7f7
rev   line source
Chris@147 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@147 2
Chris@147 3 /*
Chris@147 4 Sonic Visualiser
Chris@147 5 An audio file viewer and annotation editor.
Chris@147 6 Centre for Digital Music, Queen Mary, University of London.
Chris@147 7 This file copyright 2006 Chris Cannam.
Chris@147 8
Chris@147 9 This program is free software; you can redistribute it and/or
Chris@147 10 modify it under the terms of the GNU General Public License as
Chris@147 11 published by the Free Software Foundation; either version 2 of the
Chris@147 12 License, or (at your option) any later version. See the file
Chris@147 13 COPYING included with this distribution for more information.
Chris@147 14 */
Chris@147 15
Chris@147 16 #ifndef _SPARSE_TIME_VALUE_MODEL_H_
Chris@147 17 #define _SPARSE_TIME_VALUE_MODEL_H_
Chris@147 18
Chris@147 19 #include "SparseValueModel.h"
Chris@150 20 #include "base/PlayParameterRepository.h"
Chris@147 21 #include "base/RealTime.h"
Chris@147 22
Chris@147 23 /**
Chris@147 24 * Time/value point type for use in a SparseModel or SparseValueModel.
Chris@147 25 * With this point type, the model basically represents a wiggly-line
Chris@147 26 * plot with points at arbitrary intervals of the model resolution.
Chris@147 27 */
Chris@147 28
Chris@147 29 struct TimeValuePoint
Chris@147 30 {
Chris@147 31 public:
Chris@147 32 TimeValuePoint(long _frame) : frame(_frame), value(0.0f) { }
Chris@147 33 TimeValuePoint(long _frame, float _value, QString _label) :
Chris@147 34 frame(_frame), value(_value), label(_label) { }
Chris@147 35
Chris@147 36 int getDimensions() const { return 2; }
Chris@147 37
Chris@147 38 long frame;
Chris@147 39 float value;
Chris@147 40 QString label;
Chris@338 41
Chris@338 42 QString getLabel() const { return label; }
Chris@147 43
Chris@314 44 void toXml(QTextStream &stream, QString indent = "",
Chris@314 45 QString extraAttributes = "") const
Chris@147 46 {
Chris@314 47 stream << QString("%1<point frame=\"%2\" value=\"%3\" label=\"%4\" %5/>\n")
Chris@603 48 .arg(indent).arg(frame).arg(value).arg(XmlExportable::encodeEntities(label))
Chris@603 49 .arg(extraAttributes);
Chris@147 50 }
Chris@147 51
Chris@147 52 QString toDelimitedDataString(QString delimiter, size_t sampleRate) const
Chris@147 53 {
Chris@147 54 QStringList list;
Chris@147 55 list << RealTime::frame2RealTime(frame, sampleRate).toString().c_str();
Chris@147 56 list << QString("%1").arg(value);
Chris@318 57 if (label != "") list << label;
Chris@147 58 return list.join(delimiter);
Chris@147 59 }
Chris@147 60
Chris@147 61 struct Comparator {
Chris@147 62 bool operator()(const TimeValuePoint &p1,
Chris@147 63 const TimeValuePoint &p2) const {
Chris@147 64 if (p1.frame != p2.frame) return p1.frame < p2.frame;
Chris@147 65 if (p1.value != p2.value) return p1.value < p2.value;
Chris@147 66 return p1.label < p2.label;
Chris@147 67 }
Chris@147 68 };
Chris@147 69
Chris@147 70 struct OrderComparator {
Chris@147 71 bool operator()(const TimeValuePoint &p1,
Chris@147 72 const TimeValuePoint &p2) const {
Chris@147 73 return p1.frame < p2.frame;
Chris@147 74 }
Chris@147 75 };
Chris@147 76 };
Chris@147 77
Chris@147 78
Chris@147 79 class SparseTimeValueModel : public SparseValueModel<TimeValuePoint>
Chris@147 80 {
Chris@423 81 Q_OBJECT
Chris@423 82
Chris@147 83 public:
Chris@147 84 SparseTimeValueModel(size_t sampleRate, size_t resolution,
Chris@256 85 bool notifyOnAdd = true) :
Chris@256 86 SparseValueModel<TimeValuePoint>(sampleRate, resolution,
Chris@256 87 notifyOnAdd)
Chris@256 88 {
Chris@391 89 // not yet playable
Chris@256 90 }
Chris@256 91
Chris@256 92 SparseTimeValueModel(size_t sampleRate, size_t resolution,
Chris@147 93 float valueMinimum, float valueMaximum,
Chris@147 94 bool notifyOnAdd = true) :
Chris@147 95 SparseValueModel<TimeValuePoint>(sampleRate, resolution,
Chris@147 96 valueMinimum, valueMaximum,
Chris@147 97 notifyOnAdd)
Chris@147 98 {
Chris@391 99 // not yet playable
Chris@147 100 }
Chris@345 101
Chris@345 102 QString getTypeName() const { return tr("Sparse Time-Value"); }
Chris@420 103
Chris@420 104 /**
Chris@420 105 * TabularModel methods.
Chris@420 106 */
Chris@420 107
Chris@420 108 virtual int getColumnCount() const
Chris@420 109 {
Chris@420 110 return 4;
Chris@420 111 }
Chris@420 112
Chris@420 113 virtual QString getHeading(int column) const
Chris@420 114 {
Chris@420 115 switch (column) {
Chris@420 116 case 0: return tr("Time");
Chris@420 117 case 1: return tr("Frame");
Chris@420 118 case 2: return tr("Value");
Chris@420 119 case 3: return tr("Label");
Chris@420 120 default: return tr("Unknown");
Chris@420 121 }
Chris@420 122 }
Chris@420 123
Chris@420 124 virtual QVariant getData(int row, int column, int role) const
Chris@420 125 {
Chris@425 126 if (column < 2) {
Chris@425 127 return SparseValueModel<TimeValuePoint>::getData
Chris@425 128 (row, column, role);
Chris@425 129 }
Chris@425 130
Chris@606 131 PointListConstIterator i = getPointListIteratorForRow(row);
Chris@420 132 if (i == m_points.end()) return QVariant();
Chris@420 133
Chris@420 134 switch (column) {
Chris@420 135 case 2:
Chris@422 136 if (role == Qt::EditRole || role == SortRole) return i->value;
Chris@420 137 else return QString("%1 %2").arg(i->value).arg(getScaleUnits());
Chris@420 138 case 3: return i->label;
Chris@420 139 default: return QVariant();
Chris@420 140 }
Chris@420 141 }
Chris@420 142
Chris@424 143 virtual Command *getSetDataCommand(int row, int column, const QVariant &value, int role)
Chris@420 144 {
Chris@425 145 if (column < 2) {
Chris@425 146 return SparseValueModel<TimeValuePoint>::getSetDataCommand
Chris@425 147 (row, column, value, role);
Chris@425 148 }
Chris@425 149
Chris@420 150 if (role != Qt::EditRole) return false;
Chris@606 151 PointListConstIterator i = getPointListIteratorForRow(row);
Chris@424 152 if (i == m_points.end()) return false;
Chris@420 153 EditCommand *command = new EditCommand(this, tr("Edit Data"));
Chris@420 154
Chris@420 155 Point point(*i);
Chris@420 156 command->deletePoint(point);
Chris@420 157
Chris@420 158 switch (column) {
Chris@423 159 case 2: point.value = value.toDouble(); break;
Chris@420 160 case 3: point.label = value.toString(); break;
Chris@420 161 }
Chris@420 162
Chris@420 163 command->addPoint(point);
Chris@420 164 return command->finish();
Chris@420 165 }
Chris@420 166
Chris@420 167 virtual bool isColumnTimeValue(int column) const
Chris@420 168 {
Chris@420 169 return (column < 2);
Chris@420 170 }
Chris@422 171
Chris@422 172 virtual SortType getSortType(int column) const
Chris@422 173 {
Chris@422 174 if (column == 3) return SortAlphabetical;
Chris@422 175 return SortNumeric;
Chris@422 176 }
Chris@147 177 };
Chris@147 178
Chris@147 179
Chris@147 180 #endif
Chris@147 181
Chris@147 182
Chris@147 183