Chris@43
|
1
|
Chris@58
|
2 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
|
Chris@43
|
3
|
Chris@43
|
4 /*
|
Chris@59
|
5 Sonic Visualiser
|
Chris@59
|
6 An audio file viewer and annotation editor.
|
Chris@59
|
7 Centre for Digital Music, Queen Mary, University of London.
|
Chris@59
|
8 This file copyright 2006 Chris Cannam.
|
Chris@43
|
9
|
Chris@59
|
10 This program is free software; you can redistribute it and/or
|
Chris@59
|
11 modify it under the terms of the GNU General Public License as
|
Chris@59
|
12 published by the Free Software Foundation; either version 2 of the
|
Chris@59
|
13 License, or (at your option) any later version. See the file
|
Chris@59
|
14 COPYING included with this distribution for more information.
|
Chris@43
|
15 */
|
Chris@43
|
16
|
Chris@43
|
17 #include "LayerTree.h"
|
Chris@128
|
18 #include "view/PaneStack.h"
|
Chris@43
|
19
|
Chris@298
|
20 #include "base/PlayParameters.h"
|
Chris@128
|
21 #include "view/Pane.h"
|
Chris@128
|
22 #include "layer/Layer.h"
|
Chris@128
|
23 #include "data/model/Model.h"
|
Chris@336
|
24 #include "data/model/WaveFileModel.h"
|
Chris@43
|
25
|
Chris@280
|
26 #include <QIcon>
|
Chris@43
|
27 #include <iostream>
|
Chris@43
|
28
|
Chris@43
|
29
|
Chris@392
|
30 ModelMetadataModel::ModelMetadataModel(PaneStack *stack, bool waveModelsOnly,
|
Chris@336
|
31 QObject *parent) :
|
Chris@43
|
32 QAbstractItemModel(parent),
|
Chris@336
|
33 m_stack(stack),
|
Chris@336
|
34 m_waveModelsOnly(waveModelsOnly)
|
Chris@43
|
35 {
|
Chris@336
|
36 if (m_waveModelsOnly) {
|
Chris@336
|
37 m_modelTypeColumn = -1;
|
Chris@336
|
38 m_modelNameColumn = 0;
|
Chris@336
|
39 m_modelMakerColumn = 1;
|
Chris@336
|
40 m_modelSourceColumn = 2;
|
Chris@336
|
41 m_columnCount = 3;
|
Chris@336
|
42 } else {
|
Chris@336
|
43 m_modelTypeColumn = 0;
|
Chris@336
|
44 m_modelNameColumn = 1;
|
Chris@336
|
45 m_modelMakerColumn = 2;
|
Chris@336
|
46 m_modelSourceColumn = 3;
|
Chris@336
|
47 m_columnCount = 4;
|
Chris@336
|
48 }
|
Chris@336
|
49
|
Chris@336
|
50 connect(stack, SIGNAL(paneAdded()), this, SLOT(paneAdded()));
|
Chris@336
|
51 connect(stack, SIGNAL(paneDeleted()), this, SLOT(paneDeleted()));
|
Chris@298
|
52
|
Chris@298
|
53 for (int i = 0; i < stack->getPaneCount(); ++i) {
|
Chris@298
|
54 Pane *pane = stack->getPane(i);
|
Chris@298
|
55 if (!pane) continue;
|
Chris@298
|
56 connect(pane, SIGNAL(propertyContainerAdded(PropertyContainer *)),
|
Chris@298
|
57 this, SLOT(propertyContainerAdded(PropertyContainer *)));
|
Chris@298
|
58 connect(pane, SIGNAL(propertyContainerRemoved(PropertyContainer *)),
|
Chris@298
|
59 this, SLOT(propertyContainerRemoved(PropertyContainer *)));
|
Chris@298
|
60 connect(pane, SIGNAL(propertyContainerSelected(PropertyContainer *)),
|
Chris@298
|
61 this, SLOT(propertyContainerSelected(PropertyContainer *)));
|
Chris@298
|
62 connect(pane, SIGNAL(propertyContainerPropertyChanged(PropertyContainer *)),
|
Chris@298
|
63 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
|
Chris@298
|
64 connect(pane, SIGNAL(propertyContainerNameChanged(PropertyContainer *)),
|
Chris@298
|
65 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
|
Chris@336
|
66 connect(pane, SIGNAL(layerModelChanged()),
|
Chris@336
|
67 this, SLOT(paneLayerModelChanged()));
|
Chris@336
|
68 }
|
Chris@336
|
69
|
Chris@336
|
70 rebuildModelSet();
|
Chris@336
|
71 }
|
Chris@336
|
72
|
Chris@392
|
73 ModelMetadataModel::~ModelMetadataModel()
|
Chris@336
|
74 {
|
Chris@336
|
75 }
|
Chris@336
|
76
|
Chris@336
|
77 void
|
Chris@392
|
78 ModelMetadataModel::rebuildModelSet()
|
Chris@336
|
79 {
|
Chris@1477
|
80 std::set<ModelId> unfound = m_models;
|
Chris@336
|
81
|
Chris@336
|
82 for (int i = 0; i < m_stack->getPaneCount(); ++i) {
|
Chris@336
|
83
|
Chris@336
|
84 Pane *pane = m_stack->getPane(i);
|
Chris@336
|
85 if (!pane) continue;
|
Chris@336
|
86
|
Chris@336
|
87 for (int j = 0; j < pane->getLayerCount(); ++j) {
|
Chris@336
|
88
|
Chris@336
|
89 Layer *layer = pane->getLayer(j);
|
Chris@336
|
90 if (!layer) continue;
|
Chris@336
|
91
|
Chris@1477
|
92 ModelId modelId = layer->getModel();
|
Chris@1477
|
93 if (modelId.isNone()) continue;
|
Chris@336
|
94
|
Chris@336
|
95 if (m_waveModelsOnly) {
|
Chris@1477
|
96 if (!ModelById::getAs<WaveFileModel>(modelId)) continue;
|
Chris@336
|
97 }
|
Chris@336
|
98
|
Chris@1477
|
99 if (m_models.find(modelId) == m_models.end()) {
|
Chris@1477
|
100 m_models.insert(modelId);
|
Chris@336
|
101 } else {
|
Chris@1477
|
102 unfound.erase(modelId);
|
Chris@336
|
103 }
|
Chris@336
|
104 }
|
Chris@336
|
105 }
|
Chris@336
|
106
|
Chris@1477
|
107 for (ModelId m: unfound) {
|
Chris@1477
|
108 m_models.erase(m);
|
Chris@336
|
109 }
|
Chris@336
|
110
|
Chris@587
|
111 SVDEBUG << "ModelMetadataModel::rebuildModelSet: " << m_models.size() << " models" << endl;
|
Chris@336
|
112 }
|
Chris@336
|
113
|
Chris@336
|
114 void
|
Chris@392
|
115 ModelMetadataModel::paneAdded()
|
Chris@336
|
116 {
|
Chris@336
|
117 rebuildModelSet();
|
Chris@336
|
118 emit layoutChanged();
|
Chris@336
|
119 }
|
Chris@336
|
120
|
Chris@336
|
121 void
|
Chris@392
|
122 ModelMetadataModel::paneDeleted()
|
Chris@336
|
123 {
|
Chris@336
|
124 rebuildModelSet();
|
Chris@336
|
125 emit layoutChanged();
|
Chris@336
|
126 }
|
Chris@336
|
127
|
Chris@336
|
128 void
|
Chris@392
|
129 ModelMetadataModel::paneLayerModelChanged()
|
Chris@336
|
130 {
|
Chris@336
|
131 rebuildModelSet();
|
Chris@336
|
132 emit layoutChanged();
|
Chris@336
|
133 }
|
Chris@336
|
134
|
Chris@336
|
135 void
|
Chris@392
|
136 ModelMetadataModel::propertyContainerAdded(PropertyContainer *)
|
Chris@336
|
137 {
|
Chris@336
|
138 rebuildModelSet();
|
Chris@336
|
139 emit layoutChanged();
|
Chris@336
|
140 }
|
Chris@336
|
141
|
Chris@336
|
142 void
|
Chris@392
|
143 ModelMetadataModel::propertyContainerRemoved(PropertyContainer *)
|
Chris@336
|
144 {
|
Chris@336
|
145 rebuildModelSet();
|
Chris@336
|
146 emit layoutChanged();
|
Chris@336
|
147 }
|
Chris@336
|
148
|
Chris@336
|
149 void
|
Chris@392
|
150 ModelMetadataModel::propertyContainerSelected(PropertyContainer *)
|
Chris@336
|
151 {
|
Chris@336
|
152 }
|
Chris@336
|
153
|
Chris@336
|
154 void
|
Chris@807
|
155 ModelMetadataModel::propertyContainerPropertyChanged(PropertyContainer *)
|
Chris@336
|
156 {
|
Chris@336
|
157 }
|
Chris@336
|
158
|
Chris@336
|
159 void
|
Chris@807
|
160 ModelMetadataModel::playParametersAudibilityChanged(bool )
|
Chris@336
|
161 {
|
Chris@336
|
162 }
|
Chris@336
|
163
|
Chris@336
|
164 QVariant
|
Chris@392
|
165 ModelMetadataModel::data(const QModelIndex &index, int role) const
|
Chris@336
|
166 {
|
Chris@336
|
167 if (!index.isValid()) return QVariant();
|
Chris@336
|
168
|
Chris@807
|
169 // QObject *obj = static_cast<QObject *>(index.internalPointer());
|
Chris@336
|
170 int row = index.row(), col = index.column();
|
Chris@336
|
171
|
Chris@336
|
172 //!!! not exactly the ideal use of a std::set
|
Chris@1477
|
173 std::set<ModelId>::iterator itr = m_models.begin();
|
Chris@336
|
174 for (int i = 0; i < row && itr != m_models.end(); ++i, ++itr);
|
Chris@336
|
175 if (itr == m_models.end()) return QVariant();
|
Chris@336
|
176
|
Chris@1477
|
177 auto model = ModelById::get(*itr);
|
Chris@1477
|
178 if (!model) return QVariant();
|
Chris@336
|
179
|
Chris@336
|
180 if (role != Qt::DisplayRole) {
|
Chris@336
|
181 if (m_waveModelsOnly && col == m_modelNameColumn &&
|
Chris@336
|
182 role == Qt::DecorationRole) {
|
Chris@336
|
183 // There is no meaningful icon for a model, in general --
|
Chris@336
|
184 // the icons we have represent layer types and it would be
|
Chris@336
|
185 // misleading to use them for models. However, if we're
|
Chris@336
|
186 // only showing wave models, we use the waveform icon just
|
Chris@336
|
187 // for decorative purposes.
|
Chris@336
|
188 return QVariant(QIcon(QString(":/icons/waveform.png")));
|
Chris@336
|
189 }
|
Chris@336
|
190 return QVariant();
|
Chris@336
|
191 }
|
Chris@336
|
192
|
Chris@336
|
193 if (col == m_modelTypeColumn) {
|
Chris@336
|
194 return QVariant(model->getTypeName());
|
Chris@336
|
195 } else if (col == m_modelNameColumn) {
|
Chris@336
|
196 return QVariant(model->objectName());
|
Chris@336
|
197 } else if (col == m_modelMakerColumn) {
|
Chris@336
|
198 return QVariant(model->getMaker());
|
Chris@336
|
199 } else if (col == m_modelSourceColumn) {
|
Chris@336
|
200 return QVariant(model->getLocation());
|
Chris@336
|
201 }
|
Chris@336
|
202
|
Chris@336
|
203 return QVariant();
|
Chris@336
|
204 }
|
Chris@336
|
205
|
Chris@336
|
206 bool
|
Chris@807
|
207 ModelMetadataModel::setData(const QModelIndex &, const QVariant &, int )
|
Chris@336
|
208 {
|
Chris@336
|
209 return false;
|
Chris@336
|
210 }
|
Chris@336
|
211
|
Chris@336
|
212 Qt::ItemFlags
|
Chris@807
|
213 ModelMetadataModel::flags(const QModelIndex &) const
|
Chris@336
|
214 {
|
Chris@336
|
215 Qt::ItemFlags flags = Qt::ItemIsEnabled;
|
Chris@336
|
216 return flags;
|
Chris@336
|
217 }
|
Chris@336
|
218
|
Chris@336
|
219 QVariant
|
Chris@392
|
220 ModelMetadataModel::headerData(int section,
|
Chris@1266
|
221 Qt::Orientation orientation,
|
Chris@1266
|
222 int role) const
|
Chris@336
|
223 {
|
Chris@336
|
224 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
Chris@1266
|
225 if (section == m_modelTypeColumn) return QVariant(tr("Type"));
|
Chris@1266
|
226 else if (section == m_modelNameColumn) return QVariant(tr("Name"));
|
Chris@1266
|
227 else if (section == m_modelMakerColumn) return QVariant(tr("Maker"));
|
Chris@1266
|
228 else if (section == m_modelSourceColumn) return QVariant(tr("Source"));
|
Chris@336
|
229 }
|
Chris@336
|
230
|
Chris@336
|
231 return QVariant();
|
Chris@336
|
232 }
|
Chris@336
|
233
|
Chris@336
|
234 QModelIndex
|
Chris@392
|
235 ModelMetadataModel::index(int row, int column, const QModelIndex &parent) const
|
Chris@336
|
236 {
|
Chris@336
|
237 if (!parent.isValid()) {
|
Chris@807
|
238 if (row >= (int)m_models.size()) return QModelIndex();
|
Chris@1408
|
239 return createIndex(row, column, (void *)nullptr);
|
Chris@336
|
240 }
|
Chris@336
|
241
|
Chris@336
|
242 return QModelIndex();
|
Chris@336
|
243 }
|
Chris@336
|
244
|
Chris@336
|
245 QModelIndex
|
Chris@807
|
246 ModelMetadataModel::parent(const QModelIndex &) const
|
Chris@336
|
247 {
|
Chris@336
|
248 return QModelIndex();
|
Chris@336
|
249 }
|
Chris@336
|
250
|
Chris@336
|
251 int
|
Chris@392
|
252 ModelMetadataModel::rowCount(const QModelIndex &parent) const
|
Chris@336
|
253 {
|
Chris@908
|
254 if (!parent.isValid()) return int(m_models.size());
|
Chris@336
|
255 return 0;
|
Chris@336
|
256 }
|
Chris@336
|
257
|
Chris@336
|
258 int
|
Chris@807
|
259 ModelMetadataModel::columnCount(const QModelIndex &) const
|
Chris@336
|
260 {
|
Chris@336
|
261 return m_columnCount;
|
Chris@336
|
262 }
|
Chris@336
|
263
|
Chris@336
|
264
|
Chris@336
|
265
|
Chris@336
|
266 LayerTreeModel::LayerTreeModel(PaneStack *stack, QObject *parent) :
|
Chris@336
|
267 QAbstractItemModel(parent),
|
Chris@336
|
268 m_stack(stack)
|
Chris@336
|
269 {
|
Chris@336
|
270 m_layerNameColumn = 0;
|
Chris@336
|
271 m_layerVisibleColumn = 1;
|
Chris@336
|
272 m_layerPlayedColumn = 2;
|
Chris@336
|
273 m_modelNameColumn = 3;
|
Chris@336
|
274 m_columnCount = 4;
|
Chris@336
|
275
|
Chris@336
|
276 connect(stack, SIGNAL(paneAdded()), this, SLOT(paneAdded()));
|
Chris@336
|
277 connect(stack, SIGNAL(paneAboutToBeDeleted(Pane *)),
|
Chris@336
|
278 this, SLOT(paneAboutToBeDeleted(Pane *)));
|
Chris@336
|
279
|
Chris@336
|
280 for (int i = 0; i < stack->getPaneCount(); ++i) {
|
Chris@336
|
281 Pane *pane = stack->getPane(i);
|
Chris@336
|
282 if (!pane) continue;
|
Chris@336
|
283 connect(pane, SIGNAL(propertyContainerAdded(PropertyContainer *)),
|
Chris@336
|
284 this, SLOT(propertyContainerAdded(PropertyContainer *)));
|
Chris@336
|
285 connect(pane, SIGNAL(propertyContainerRemoved(PropertyContainer *)),
|
Chris@336
|
286 this, SLOT(propertyContainerRemoved(PropertyContainer *)));
|
Chris@336
|
287 connect(pane, SIGNAL(propertyContainerSelected(PropertyContainer *)),
|
Chris@336
|
288 this, SLOT(propertyContainerSelected(PropertyContainer *)));
|
Chris@336
|
289 connect(pane, SIGNAL(propertyContainerPropertyChanged(PropertyContainer *)),
|
Chris@336
|
290 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
|
Chris@336
|
291 connect(pane, SIGNAL(propertyContainerNameChanged(PropertyContainer *)),
|
Chris@336
|
292 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
|
Chris@336
|
293 connect(pane, SIGNAL(layerModelChanged()),
|
Chris@336
|
294 this, SLOT(paneLayerModelChanged()));
|
Chris@336
|
295
|
Chris@298
|
296 for (int j = 0; j < pane->getLayerCount(); ++j) {
|
Chris@298
|
297 Layer *layer = pane->getLayer(j);
|
Chris@298
|
298 if (!layer) continue;
|
Chris@1480
|
299 auto params = layer->getPlayParameters();
|
Chris@298
|
300 if (!params) continue;
|
Chris@1480
|
301 connect(params.get(), SIGNAL(playAudibleChanged(bool)),
|
Chris@298
|
302 this, SLOT(playParametersAudibilityChanged(bool)));
|
Chris@298
|
303 }
|
Chris@298
|
304 }
|
Chris@43
|
305 }
|
Chris@43
|
306
|
Chris@43
|
307 LayerTreeModel::~LayerTreeModel()
|
Chris@43
|
308 {
|
Chris@43
|
309 }
|
Chris@43
|
310
|
Chris@298
|
311 void
|
Chris@336
|
312 LayerTreeModel::paneAdded()
|
Chris@336
|
313 {
|
Chris@336
|
314 emit layoutChanged();
|
Chris@336
|
315 }
|
Chris@336
|
316
|
Chris@336
|
317 void
|
Chris@336
|
318 LayerTreeModel::paneAboutToBeDeleted(Pane *pane)
|
Chris@336
|
319 {
|
Chris@682
|
320 cerr << "paneDeleted: " << pane << endl;
|
Chris@336
|
321 m_deletedPanes.insert(pane);
|
Chris@336
|
322 emit layoutChanged();
|
Chris@336
|
323 }
|
Chris@336
|
324
|
Chris@336
|
325 void
|
Chris@298
|
326 LayerTreeModel::propertyContainerAdded(PropertyContainer *)
|
Chris@298
|
327 {
|
Chris@298
|
328 emit layoutChanged();
|
Chris@298
|
329 }
|
Chris@298
|
330
|
Chris@298
|
331 void
|
Chris@298
|
332 LayerTreeModel::propertyContainerRemoved(PropertyContainer *)
|
Chris@298
|
333 {
|
Chris@298
|
334 emit layoutChanged();
|
Chris@298
|
335 }
|
Chris@298
|
336
|
Chris@298
|
337 void
|
Chris@298
|
338 LayerTreeModel::propertyContainerSelected(PropertyContainer *)
|
Chris@298
|
339 {
|
Chris@298
|
340 emit layoutChanged();
|
Chris@298
|
341 }
|
Chris@298
|
342
|
Chris@298
|
343 void
|
Chris@336
|
344 LayerTreeModel::paneLayerModelChanged()
|
Chris@336
|
345 {
|
Chris@336
|
346 emit layoutChanged();
|
Chris@336
|
347 }
|
Chris@336
|
348
|
Chris@336
|
349 void
|
Chris@298
|
350 LayerTreeModel::propertyContainerPropertyChanged(PropertyContainer *pc)
|
Chris@298
|
351 {
|
Chris@298
|
352 for (int i = 0; i < m_stack->getPaneCount(); ++i) {
|
Chris@298
|
353 Pane *pane = m_stack->getPane(i);
|
Chris@298
|
354 if (!pane) continue;
|
Chris@298
|
355 for (int j = 0; j < pane->getLayerCount(); ++j) {
|
Chris@298
|
356 if (pane->getLayer(j) == pc) {
|
Chris@298
|
357 emit dataChanged(createIndex(pane->getLayerCount() - j - 1,
|
Chris@336
|
358 m_layerNameColumn, pane),
|
Chris@298
|
359 createIndex(pane->getLayerCount() - j - 1,
|
Chris@336
|
360 m_modelNameColumn, pane));
|
Chris@298
|
361 }
|
Chris@298
|
362 }
|
Chris@298
|
363 }
|
Chris@298
|
364 }
|
Chris@298
|
365
|
Chris@298
|
366 void
|
Chris@298
|
367 LayerTreeModel::playParametersAudibilityChanged(bool a)
|
Chris@298
|
368 {
|
Chris@298
|
369 PlayParameters *params = dynamic_cast<PlayParameters *>(sender());
|
Chris@298
|
370 if (!params) return;
|
Chris@298
|
371
|
Chris@587
|
372 SVDEBUG << "LayerTreeModel::playParametersAudibilityChanged("
|
Chris@585
|
373 << params << "," << a << ")" << endl;
|
Chris@298
|
374
|
Chris@298
|
375 for (int i = 0; i < m_stack->getPaneCount(); ++i) {
|
Chris@298
|
376 Pane *pane = m_stack->getPane(i);
|
Chris@298
|
377 if (!pane) continue;
|
Chris@298
|
378 for (int j = 0; j < pane->getLayerCount(); ++j) {
|
Chris@298
|
379 Layer *layer = pane->getLayer(j);
|
Chris@298
|
380 if (!layer) continue;
|
Chris@1480
|
381 if (layer->getPlayParameters().get() == params) { // ugh
|
Chris@587
|
382 SVDEBUG << "LayerTreeModel::playParametersAudibilityChanged("
|
Chris@585
|
383 << params << "," << a << "): row " << pane->getLayerCount() - j - 1 << ", col " << 2 << endl;
|
Chris@298
|
384
|
Chris@298
|
385 emit dataChanged(createIndex(pane->getLayerCount() - j - 1,
|
Chris@336
|
386 m_layerPlayedColumn, pane),
|
Chris@298
|
387 createIndex(pane->getLayerCount() - j - 1,
|
Chris@336
|
388 m_layerPlayedColumn, pane));
|
Chris@298
|
389 }
|
Chris@298
|
390 }
|
Chris@298
|
391 }
|
Chris@298
|
392 }
|
Chris@298
|
393
|
Chris@43
|
394 QVariant
|
Chris@43
|
395 LayerTreeModel::data(const QModelIndex &index, int role) const
|
Chris@43
|
396 {
|
Chris@43
|
397 if (!index.isValid()) return QVariant();
|
Chris@56
|
398
|
Chris@43
|
399 QObject *obj = static_cast<QObject *>(index.internalPointer());
|
Chris@277
|
400 int row = index.row(), col = index.column();
|
Chris@277
|
401
|
Chris@277
|
402 Pane *pane = dynamic_cast<Pane *>(obj);
|
Chris@277
|
403 if (!pane) {
|
Chris@277
|
404 if (col == 0 && row < m_stack->getPaneCount()) {
|
Chris@277
|
405 switch (role) {
|
Chris@277
|
406 case Qt::DisplayRole:
|
Chris@277
|
407 return QVariant(QString("Pane %1").arg(row + 1));
|
Chris@277
|
408 case Qt::DecorationRole:
|
Chris@277
|
409 return QVariant(QIcon(QString(":/icons/pane.png")));
|
Chris@277
|
410 default: break;
|
Chris@277
|
411 }
|
Chris@277
|
412 }
|
Chris@43
|
413 }
|
Chris@43
|
414
|
Chris@277
|
415 if (pane && pane->getLayerCount() > row) {
|
Chris@298
|
416 Layer *layer = pane->getLayer(pane->getLayerCount() - row - 1);
|
Chris@277
|
417 if (layer) {
|
Chris@336
|
418 if (col == m_layerNameColumn) {
|
Chris@277
|
419 switch (role) {
|
Chris@277
|
420 case Qt::DisplayRole:
|
Chris@277
|
421 return QVariant(layer->objectName());
|
Chris@277
|
422 case Qt::DecorationRole:
|
Chris@277
|
423 return QVariant
|
Chris@277
|
424 (QIcon(QString(":/icons/%1.png")
|
Chris@277
|
425 .arg(layer->getPropertyContainerIconName())));
|
Chris@277
|
426 default: break;
|
Chris@277
|
427 }
|
Chris@336
|
428 } else if (col == m_layerVisibleColumn) {
|
Chris@298
|
429 if (role == Qt::CheckStateRole) {
|
Chris@298
|
430 return QVariant(layer->isLayerDormant(pane) ?
|
Chris@298
|
431 Qt::Unchecked : Qt::Checked);
|
Chris@298
|
432 } else if (role == Qt::TextAlignmentRole) {
|
Chris@298
|
433 return QVariant(Qt::AlignHCenter);
|
Chris@298
|
434 }
|
Chris@336
|
435 } else if (col == m_layerPlayedColumn) {
|
Chris@298
|
436 if (role == Qt::CheckStateRole) {
|
Chris@1480
|
437 auto params = layer->getPlayParameters();
|
Chris@298
|
438 if (params) return QVariant(params->isPlayMuted() ?
|
Chris@298
|
439 Qt::Unchecked : Qt::Checked);
|
Chris@298
|
440 else return QVariant();
|
Chris@298
|
441 } else if (role == Qt::TextAlignmentRole) {
|
Chris@298
|
442 return QVariant(Qt::AlignHCenter);
|
Chris@298
|
443 }
|
Chris@336
|
444 } else if (col == m_modelNameColumn) {
|
Chris@1477
|
445 auto model = ModelById::get(layer->getModel());
|
Chris@277
|
446 if (model && role == Qt::DisplayRole) {
|
Chris@277
|
447 return QVariant(model->objectName());
|
Chris@277
|
448 }
|
Chris@277
|
449 }
|
Chris@277
|
450 }
|
Chris@43
|
451 }
|
Chris@43
|
452
|
Chris@43
|
453 return QVariant();
|
Chris@43
|
454 }
|
Chris@43
|
455
|
Chris@298
|
456 bool
|
Chris@298
|
457 LayerTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
Chris@298
|
458 {
|
Chris@298
|
459 if (!index.isValid()) return false;
|
Chris@298
|
460
|
Chris@298
|
461 QObject *obj = static_cast<QObject *>(index.internalPointer());
|
Chris@298
|
462 int row = index.row(), col = index.column();
|
Chris@298
|
463
|
Chris@298
|
464 Pane *pane = dynamic_cast<Pane *>(obj);
|
Chris@298
|
465 if (!pane || pane->getLayerCount() <= row) return false;
|
Chris@298
|
466
|
Chris@298
|
467 Layer *layer = pane->getLayer(pane->getLayerCount() - row - 1);
|
Chris@298
|
468 if (!layer) return false;
|
Chris@298
|
469
|
Chris@336
|
470 if (col == m_layerVisibleColumn) {
|
Chris@298
|
471 if (role == Qt::CheckStateRole) {
|
Chris@298
|
472 layer->showLayer(pane, value.toInt() == Qt::Checked);
|
Chris@298
|
473 emit dataChanged(index, index);
|
Chris@298
|
474 return true;
|
Chris@298
|
475 }
|
Chris@336
|
476 } else if (col == m_layerPlayedColumn) {
|
Chris@298
|
477 if (role == Qt::CheckStateRole) {
|
Chris@1480
|
478 auto params = layer->getPlayParameters();
|
Chris@298
|
479 if (params) {
|
Chris@298
|
480 params->setPlayMuted(value.toInt() == Qt::Unchecked);
|
Chris@298
|
481 emit dataChanged(index, index);
|
Chris@298
|
482 return true;
|
Chris@298
|
483 }
|
Chris@298
|
484 }
|
Chris@298
|
485 }
|
Chris@298
|
486
|
Chris@298
|
487 return false;
|
Chris@298
|
488 }
|
Chris@298
|
489
|
Chris@43
|
490 Qt::ItemFlags
|
Chris@43
|
491 LayerTreeModel::flags(const QModelIndex &index) const
|
Chris@43
|
492 {
|
Chris@298
|
493 Qt::ItemFlags flags = Qt::ItemIsEnabled;
|
Chris@298
|
494 if (!index.isValid()) return flags;
|
Chris@298
|
495
|
Chris@336
|
496 if (index.column() == m_layerVisibleColumn ||
|
Chris@336
|
497 index.column() == m_layerPlayedColumn) {
|
Chris@298
|
498 flags |= Qt::ItemIsUserCheckable;
|
Chris@298
|
499 } else if (index.column() == 0) {
|
Chris@298
|
500 flags |= Qt::ItemIsSelectable;
|
Chris@298
|
501 }
|
Chris@298
|
502
|
Chris@298
|
503 return flags;
|
Chris@43
|
504 }
|
Chris@43
|
505
|
Chris@43
|
506 QVariant
|
Chris@56
|
507 LayerTreeModel::headerData(int section,
|
Chris@1266
|
508 Qt::Orientation orientation,
|
Chris@1266
|
509 int role) const
|
Chris@43
|
510 {
|
Chris@56
|
511 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
|
Chris@1266
|
512 if (section == m_layerNameColumn) return QVariant(tr("Layer"));
|
Chris@336
|
513 else if (section == m_layerVisibleColumn) return QVariant(tr("Shown"));
|
Chris@336
|
514 else if (section == m_layerPlayedColumn) return QVariant(tr("Played"));
|
Chris@1266
|
515 else if (section == m_modelNameColumn) return QVariant(tr("Model"));
|
Chris@56
|
516 }
|
Chris@56
|
517
|
Chris@56
|
518 return QVariant();
|
Chris@43
|
519 }
|
Chris@43
|
520
|
Chris@43
|
521 QModelIndex
|
Chris@43
|
522 LayerTreeModel::index(int row, int column, const QModelIndex &parent) const
|
Chris@43
|
523 {
|
Chris@277
|
524 // cell for a pane contains row, column, pane stack
|
Chris@277
|
525 // -> its parent is the invalid cell
|
Chris@277
|
526
|
Chris@277
|
527 // cell for a layer contains row, column, pane
|
Chris@277
|
528 // -> its parent is row, column, pane stack (which identify the pane)
|
Chris@43
|
529
|
Chris@43
|
530 if (!parent.isValid()) {
|
Chris@277
|
531 if (row >= m_stack->getPaneCount() || column > 0) return QModelIndex();
|
Chris@1266
|
532 return createIndex(row, column, m_stack);
|
Chris@43
|
533 }
|
Chris@43
|
534
|
Chris@43
|
535 QObject *obj = static_cast<QObject *>(parent.internalPointer());
|
Chris@277
|
536
|
Chris@277
|
537 if (obj == m_stack) {
|
Chris@277
|
538 Pane *pane = m_stack->getPane(parent.row());
|
Chris@277
|
539 if (!pane || parent.column() > 0) return QModelIndex();
|
Chris@277
|
540 return createIndex(row, column, pane);
|
Chris@43
|
541 }
|
Chris@43
|
542
|
Chris@43
|
543 return QModelIndex();
|
Chris@43
|
544 }
|
Chris@43
|
545
|
Chris@43
|
546 QModelIndex
|
Chris@43
|
547 LayerTreeModel::parent(const QModelIndex &index) const
|
Chris@43
|
548 {
|
Chris@43
|
549 QObject *obj = static_cast<QObject *>(index.internalPointer());
|
Chris@43
|
550
|
Chris@336
|
551 if (m_deletedPanes.find(obj) != m_deletedPanes.end()) {
|
Chris@336
|
552 // m_deletedPanes.erase(obj);
|
Chris@336
|
553 return QModelIndex();
|
Chris@336
|
554 }
|
Chris@336
|
555
|
Chris@43
|
556 Pane *pane = dynamic_cast<Pane *>(obj);
|
Chris@43
|
557 if (pane) {
|
Chris@277
|
558 int index = m_stack->getPaneIndex(pane);
|
Chris@277
|
559 if (index >= 0) return createIndex(index, 0, m_stack);
|
Chris@43
|
560 }
|
Chris@43
|
561
|
Chris@43
|
562 return QModelIndex();
|
Chris@43
|
563 }
|
Chris@43
|
564
|
Chris@43
|
565 int
|
Chris@43
|
566 LayerTreeModel::rowCount(const QModelIndex &parent) const
|
Chris@43
|
567 {
|
Chris@277
|
568 if (!parent.isValid()) return m_stack->getPaneCount();
|
Chris@43
|
569
|
Chris@43
|
570 QObject *obj = static_cast<QObject *>(parent.internalPointer());
|
Chris@43
|
571
|
Chris@277
|
572 if (obj == m_stack) {
|
Chris@277
|
573 Pane *pane = m_stack->getPane(parent.row());
|
Chris@277
|
574 if (!pane || parent.column() > 0) return 0;
|
Chris@277
|
575 return pane->getLayerCount();
|
Chris@43
|
576 }
|
Chris@43
|
577
|
Chris@43
|
578 return 0;
|
Chris@43
|
579 }
|
Chris@43
|
580
|
Chris@43
|
581 int
|
Chris@43
|
582 LayerTreeModel::columnCount(const QModelIndex &parent) const
|
Chris@43
|
583 {
|
Chris@336
|
584 if (!parent.isValid()) return m_columnCount;
|
Chris@43
|
585
|
Chris@43
|
586 QObject *obj = static_cast<QObject *>(parent.internalPointer());
|
Chris@336
|
587 if (obj == m_stack) return m_columnCount; // row for a layer
|
Chris@56
|
588
|
Chris@43
|
589 return 1;
|
Chris@43
|
590 }
|
Chris@43
|
591
|