comparison data/model/ModelDataTableModel.cpp @ 416:a00902d5f0ab

* basics of data editing in data table view
author Chris Cannam
date Mon, 09 Jun 2008 16:01:50 +0000
parents 0b274e1aaf10
children 12b7bf0c3915
comparison
equal deleted inserted replaced
415:e37e44681720 416:a00902d5f0ab
33 } 33 }
34 34
35 QVariant 35 QVariant
36 ModelDataTableModel::data(const QModelIndex &index, int role) const 36 ModelDataTableModel::data(const QModelIndex &index, int role) const
37 { 37 {
38 if (role != Qt::DisplayRole) { 38 if (role != Qt::DisplayRole && role != Qt::EditRole) {
39 return QVariant(); 39 return QVariant();
40 } 40 }
41 41
42 bool withUnit = (role == Qt::DisplayRole);
43
42 if (!index.isValid()) return QVariant(); 44 if (!index.isValid()) return QVariant();
43 45
44 int row = index.row(), col = index.column(); 46 int row = index.row(), col = index.column();
45 47
46 if (row < 0 || row >= m_rows.size()) return QVariant(); 48 if (row < 0 || row >= m_rows.size()) return QVariant();
47 49
48 if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) { 50 if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) {
49 return dataSparse<SparseOneDimensionalModel::Point>(row, col); 51 return dataSparse<SparseOneDimensionalModel::Point>(row, col, withUnit);
50 } else if (dynamic_cast<const SparseTimeValueModel *>(m_model)) { 52 } else if (dynamic_cast<const SparseTimeValueModel *>(m_model)) {
51 return dataSparse<SparseTimeValueModel::Point>(row, col); 53 return dataSparse<SparseTimeValueModel::Point>(row, col, withUnit);
52 } 54 }
53 55
54 return QVariant(); 56 return QVariant();
55 } 57 }
56 58
57 template <typename PointType> 59 template <typename PointType>
58 QVariant 60 QVariant
59 ModelDataTableModel::dataSparse(int row, int col) const 61 ModelDataTableModel::dataSparse(int row, int col, bool withUnit) const
60 { 62 {
61 size_t frame = m_rows[row]; 63 size_t frame = m_rows[row];
62 64
63 // This is just garbage. This would be a reasonable enough way to 65 // This is just garbage. This would be a reasonable enough way to
64 // handle this in a dynamically typed language but it's hopeless 66 // handle this in a dynamically typed language but it's hopeless
87 if (indexAtFrame > 0) { --indexAtFrame; continue; } 89 if (indexAtFrame > 0) { --indexAtFrame; continue; }
88 90
89 switch (col) { 91 switch (col) {
90 92
91 case 0: 93 case 0:
94 {
95 RealTime rt = RealTime::frame2RealTime(frame, m_model->getSampleRate());
96 std::cerr << "Returning time " << rt << std::endl;
97 return QVariant(rt.toText().c_str());
98 }
99
100 case 1:
92 std::cerr << "Returning frame " << frame << std::endl; 101 std::cerr << "Returning frame " << frame << std::endl;
93 return QVariant(frame); //!!! RealTime 102 return QVariant(frame); //!!! RealTime
94 103
95 case 1: 104 case 2:
96 if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) { 105 if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) {
97 const SparseOneDimensionalModel::Point *cp = 106 const SparseOneDimensionalModel::Point *cp =
98 reinterpret_cast<const SparseOneDimensionalModel::Point *>(point); 107 reinterpret_cast<const SparseOneDimensionalModel::Point *>(point);
99 std::cerr << "Returning label \"" << cp->label.toStdString() << "\"" << std::endl; 108 std::cerr << "Returning label \"" << cp->label.toStdString() << "\"" << std::endl;
100 return QVariant(cp->label); 109 return QVariant(cp->label);
101 } else if (dynamic_cast<const SparseTimeValueModel *>(m_model)) { 110 } else if (dynamic_cast<const SparseTimeValueModel *>(m_model)) {
102 const SparseTimeValueModel::Point *cp = 111 const SparseTimeValueModel::Point *cp =
103 reinterpret_cast<const SparseTimeValueModel::Point *>(point); 112 reinterpret_cast<const SparseTimeValueModel::Point *>(point);
104 std::cerr << "Returning value " << cp->value << std::endl; 113 std::cerr << "Returning value " << cp->value << std::endl;
105 return cp->value; 114 if (withUnit) {
115 return QVariant(QString("%1 %2").arg(cp->value)
116 .arg(dynamic_cast<const SparseTimeValueModel *>(m_model)->getScaleUnits()));
117 } else {
118 return cp->value;
119 }
106 } else return QVariant(); 120 } else return QVariant();
107 121
108 case 2: 122 case 3:
109 if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) { 123 if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) {
110 return QVariant(); 124 return QVariant();
111 } else if (dynamic_cast<const SparseTimeValueModel *>(m_model)) { 125 } else if (dynamic_cast<const SparseTimeValueModel *>(m_model)) {
112 return reinterpret_cast<const SparseTimeValueModel::Point *>(point)->label; 126 return reinterpret_cast<const SparseTimeValueModel::Point *>(point)->label;
113 } else return QVariant(); 127 } else return QVariant();
118 } 132 }
119 133
120 bool 134 bool
121 ModelDataTableModel::setData(const QModelIndex &index, const QVariant &value, int role) 135 ModelDataTableModel::setData(const QModelIndex &index, const QVariant &value, int role)
122 { 136 {
137 if (role != Qt::EditRole) {
138 std::cerr << "setData: ignoring role " << role << std::endl;
139 return false;
140 }
141
142 //!!! see comment about disgustuality of this whole process, in
143 //dataSparse above
144
145 if (!index.isValid()) return false;
146
147 int row = index.row(), col = index.column();
148
149 if (row < 0 || row >= m_rows.size()) return false;
150
151 if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) {
152 return setDataSparse<SparseOneDimensionalModel::Point>(row, col, value);
153 } else if (dynamic_cast<const SparseTimeValueModel *>(m_model)) {
154 return setDataSparse<SparseTimeValueModel::Point>(row, col, value);
155 }
156
157 return false;
158 }
159
160 template <typename PointType>
161 bool
162 ModelDataTableModel::setDataSparse(int row, int col, QVariant value)
163 {
164 size_t frame = m_rows[row];
165
166 typedef SparseModel<PointType> ModelType;
167 typedef std::multiset<PointType, typename PointType::OrderComparator>
168 PointListType;
169 typedef typename ModelType::EditCommand EditCommandType;
170
171 ModelType *sm = dynamic_cast<const ModelType *>(m_model);
172 const PointListType &points = sm->getPoints(frame);
173
174 // it is possible to have more than one point at the same frame
175
176 int indexAtFrame = 0;
177 int ri = row;
178 while (ri > 0 && m_rows[ri-1] == m_rows[row]) { --ri; ++indexAtFrame; }
179
180 for (typename PointListType::const_iterator i = points.begin();
181 i != points.end(); ++i) {
182
183 const PointType *point = &(*i);
184 if (point->frame < frame) continue;
185 if (point->frame > frame) return false;
186 if (indexAtFrame > 0) { --indexAtFrame; continue; }
187
188 switch (col) {
189
190 case 0:
191 {
192 /*
193 RealTime rt = RealTime::frame2RealTime(frame, m_model->getSampleRate());
194 std::cerr << "Returning time " << rt << std::endl;
195 return QVariant(rt.toText().c_str());
196 */
197 }
198
199 case 1:
200 {
201 EditCommandType *command =
202 new EditCommandType(sm, tr("Edit point time"));
203 PointType newPoint(*point);
204 newPoint.frame = value.toInt(); //!!! check validity
205 command->deletePoint(*point);
206 command->addPoint(newPoint);
207 command = command->finish();
208 if (command) emit executeCommand(command);
209 return true;
210 }
211 // std::cerr << "Returning frame " << frame << std::endl;
212 // return QVariant(frame); //!!! RealTime
213
214 case 2:
215 break;
216
217 case 3:
218 break;
219 }
220 }
221
123 return false; 222 return false;
124 } 223 }
125 224
126 Qt::ItemFlags 225 Qt::ItemFlags
127 ModelDataTableModel::flags(const QModelIndex &index) const 226 ModelDataTableModel::flags(const QModelIndex &index) const
128 { 227 {
129 return Qt::ItemFlags(); 228 Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsEditable |
229 Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | Qt::ItemIsSelectable;
230 return flags;
130 } 231 }
131 232
132 QVariant 233 QVariant
133 ModelDataTableModel::headerData(int section, Qt::Orientation orientation, int role) const 234 ModelDataTableModel::headerData(int section, Qt::Orientation orientation, int role) const
134 { 235 {
135 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { 236 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
136 if (section == 0) return QVariant(tr("Frame")); 237 if (section == 0) return QVariant(tr("Time"));
137 else if (section == 1) { 238 if (section == 1) return QVariant(tr("Frame"));
239 else if (section == 2) {
138 if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) { 240 if (dynamic_cast<const SparseOneDimensionalModel *>(m_model)) {
139 return QVariant(tr("Label")); 241 return QVariant(tr("Label"));
140 } else if (dynamic_cast<const SparseTimeValueModel *>(m_model)) { 242 } else if (dynamic_cast<const SparseTimeValueModel *>(m_model)) {
141 return QVariant(tr("Value")); 243 return QVariant(tr("Value"));
142 } 244 }
143 } else if (section == 2) { 245 } else if (section == 3) {
144 if (dynamic_cast<const SparseTimeValueModel *>(m_model)) { 246 if (dynamic_cast<const SparseTimeValueModel *>(m_model)) {
145 return QVariant(tr("Label")); 247 return QVariant(tr("Label"));
146 } 248 }
147 } 249 }
148 } 250 }
173 { 275 {
174 if (parent.isValid()) return 0; 276 if (parent.isValid()) return 0;
175 if (!canHandleModelType(m_model)) return 0; 277 if (!canHandleModelType(m_model)) return 0;
176 278
177 if (dynamic_cast<SparseOneDimensionalModel *>(m_model)) { 279 if (dynamic_cast<SparseOneDimensionalModel *>(m_model)) {
178 return 2; 280 return 3;
179 } else if (dynamic_cast<SparseTimeValueModel *>(m_model)) { 281 } else if (dynamic_cast<SparseTimeValueModel *>(m_model)) {
180 return 3; 282 return 4;
181 } 283 }
182 284
183 return 1; 285 return 2;
286 }
287
288 QModelIndex
289 ModelDataTableModel::getModelIndexForFrame(size_t frame) const
290 {
291 std::vector<size_t>::const_iterator i =
292 std::lower_bound(m_rows.begin(), m_rows.end(), frame);
293 size_t dist = std::distance(m_rows.begin(), i);
294 return createIndex(dist, 0, 0);
184 } 295 }
185 296
186 void 297 void
187 ModelDataTableModel::modelChanged() 298 ModelDataTableModel::modelChanged()
188 { 299 {
189 rebuildRowVector(); 300 rebuildRowVector();
190 emit layoutChanged(); 301 emit layoutChanged();
191 } 302 }
192 303
193 void 304 void
194 ModelDataTableModel::modelChanged(size_t, size_t) 305 ModelDataTableModel::modelChanged(size_t f0, size_t f1)
195 {} 306 {
307 std::cerr << "ModelDataTableModel::modelChanged(" << f0 << "," << f1 << ")" << std::endl;
308 //!!! highly inefficient
309 rebuildRowVector();
310 emit layoutChanged();
311 }
196 312
197 void 313 void
198 ModelDataTableModel::rebuildRowVector() 314 ModelDataTableModel::rebuildRowVector()
199 { 315 {
200 if (!canHandleModelType(m_model)) return; 316 if (!canHandleModelType(m_model)) return;