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