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