svgui  1.9
LayerTree.cpp
Go to the documentation of this file.
00001 
00002 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
00003 
00004 /*
00005     Sonic Visualiser
00006     An audio file viewer and annotation editor.
00007     Centre for Digital Music, Queen Mary, University of London.
00008     This file copyright 2006 Chris Cannam.
00009     
00010     This program is free software; you can redistribute it and/or
00011     modify it under the terms of the GNU General Public License as
00012     published by the Free Software Foundation; either version 2 of the
00013     License, or (at your option) any later version.  See the file
00014     COPYING included with this distribution for more information.
00015 */
00016 
00017 #include "LayerTree.h"
00018 #include "view/PaneStack.h"
00019 
00020 #include "base/PlayParameters.h"
00021 #include "view/Pane.h"
00022 #include "layer/Layer.h"
00023 #include "data/model/Model.h"
00024 #include "data/model/WaveFileModel.h"
00025 
00026 #include <QIcon>
00027 #include <iostream>
00028 
00029 
00030 ModelMetadataModel::ModelMetadataModel(PaneStack *stack, bool waveModelsOnly,
00031                                QObject *parent) :
00032     QAbstractItemModel(parent),
00033     m_stack(stack),
00034     m_waveModelsOnly(waveModelsOnly)
00035 {
00036     if (m_waveModelsOnly) {
00037         m_modelTypeColumn = -1;
00038         m_modelNameColumn = 0;
00039         m_modelMakerColumn = 1;
00040         m_modelSourceColumn = 2;
00041         m_columnCount = 3;
00042     } else {
00043         m_modelTypeColumn = 0;
00044         m_modelNameColumn = 1;
00045         m_modelMakerColumn = 2;
00046         m_modelSourceColumn = 3;
00047         m_columnCount = 4;
00048     }
00049 
00050     connect(stack, SIGNAL(paneAdded()), this, SLOT(paneAdded()));
00051     connect(stack, SIGNAL(paneDeleted()), this, SLOT(paneDeleted()));
00052 
00053     for (int i = 0; i < stack->getPaneCount(); ++i) {
00054         Pane *pane = stack->getPane(i);
00055         if (!pane) continue;
00056         connect(pane, SIGNAL(propertyContainerAdded(PropertyContainer *)),
00057                 this, SLOT(propertyContainerAdded(PropertyContainer *)));
00058         connect(pane, SIGNAL(propertyContainerRemoved(PropertyContainer *)),
00059                 this, SLOT(propertyContainerRemoved(PropertyContainer *)));
00060         connect(pane, SIGNAL(propertyContainerSelected(PropertyContainer *)),
00061                 this, SLOT(propertyContainerSelected(PropertyContainer *)));
00062         connect(pane, SIGNAL(propertyContainerPropertyChanged(PropertyContainer *)),
00063                 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
00064         connect(pane, SIGNAL(propertyContainerNameChanged(PropertyContainer *)),
00065                 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
00066         connect(pane, SIGNAL(layerModelChanged()),
00067                 this, SLOT(paneLayerModelChanged()));
00068     }
00069 
00070     rebuildModelSet();
00071 }
00072 
00073 ModelMetadataModel::~ModelMetadataModel()
00074 {
00075 }
00076 
00077 void
00078 ModelMetadataModel::rebuildModelSet()
00079 {
00080     std::set<Model *> unfound = m_models;
00081 
00082     for (int i = 0; i < m_stack->getPaneCount(); ++i) {
00083 
00084         Pane *pane = m_stack->getPane(i);
00085         if (!pane) continue;
00086 
00087         for (int j = 0; j < pane->getLayerCount(); ++j) {
00088 
00089             Layer *layer = pane->getLayer(j);
00090             if (!layer) continue;
00091 
00092             Model *model = layer->getModel();
00093             if (!model) continue;
00094 
00095             if (m_waveModelsOnly) {
00096                 if (!dynamic_cast<WaveFileModel *>(model)) continue;
00097             }
00098 
00099             if (m_models.find(model) == m_models.end()) {
00100                 connect(model, SIGNAL(aboutToBeDeleted()),
00101                         this, SLOT(rebuildModelSet()));
00102                 m_models.insert(model);
00103             } else {
00104                 unfound.erase(model);
00105             }
00106         }
00107     }
00108 
00109     for (std::set<Model *>::iterator i = unfound.begin();
00110          i != unfound.end(); ++i) {
00111         m_models.erase(*i);
00112     }
00113 
00114     SVDEBUG << "ModelMetadataModel::rebuildModelSet: " << m_models.size() << " models" << endl;
00115 }
00116 
00117 void
00118 ModelMetadataModel::paneAdded()
00119 {
00120     rebuildModelSet();
00121     emit layoutChanged();
00122 }
00123 
00124 void
00125 ModelMetadataModel::paneDeleted()
00126 {
00127     rebuildModelSet();
00128     emit layoutChanged();
00129 }
00130 
00131 void
00132 ModelMetadataModel::paneLayerModelChanged()
00133 {
00134     rebuildModelSet();
00135     emit layoutChanged();
00136 }
00137 
00138 void
00139 ModelMetadataModel::propertyContainerAdded(PropertyContainer *)
00140 {
00141     rebuildModelSet();
00142     emit layoutChanged();
00143 }
00144 
00145 void
00146 ModelMetadataModel::propertyContainerRemoved(PropertyContainer *)
00147 {
00148     rebuildModelSet();
00149     emit layoutChanged();
00150 }
00151 
00152 void
00153 ModelMetadataModel::propertyContainerSelected(PropertyContainer *)
00154 {
00155 }
00156 
00157 void
00158 ModelMetadataModel::propertyContainerPropertyChanged(PropertyContainer *)
00159 {
00160 }
00161 
00162 void
00163 ModelMetadataModel::playParametersAudibilityChanged(bool )
00164 {
00165 }
00166 
00167 QVariant
00168 ModelMetadataModel::data(const QModelIndex &index, int role) const
00169 {
00170     if (!index.isValid()) return QVariant();
00171 
00172 //    QObject *obj = static_cast<QObject *>(index.internalPointer());
00173     int row = index.row(), col = index.column();
00174 
00176     std::set<Model *>::iterator itr = m_models.begin();
00177     for (int i = 0; i < row && itr != m_models.end(); ++i, ++itr);
00178     if (itr == m_models.end()) return QVariant();
00179 
00180     Model *model = *itr;
00181 
00182     if (role != Qt::DisplayRole) {
00183         if (m_waveModelsOnly && col == m_modelNameColumn &&
00184             role == Qt::DecorationRole) {
00185             // There is no meaningful icon for a model, in general --
00186             // the icons we have represent layer types and it would be
00187             // misleading to use them for models.  However, if we're
00188             // only showing wave models, we use the waveform icon just
00189             // for decorative purposes.
00190             return QVariant(QIcon(QString(":/icons/waveform.png")));
00191         }
00192         return QVariant();
00193     }
00194     
00195     if (col == m_modelTypeColumn) {
00196         return QVariant(model->getTypeName());
00197     } else if (col == m_modelNameColumn) {
00198         return QVariant(model->objectName());
00199     } else if (col == m_modelMakerColumn) {
00200         return QVariant(model->getMaker());
00201     } else if (col == m_modelSourceColumn) {
00202         return QVariant(model->getLocation());
00203     }        
00204     
00205     return QVariant();
00206 }
00207 
00208 bool
00209 ModelMetadataModel::setData(const QModelIndex &, const QVariant &, int )
00210 {
00211     return false;
00212 }
00213 
00214 Qt::ItemFlags
00215 ModelMetadataModel::flags(const QModelIndex &) const
00216 {
00217     Qt::ItemFlags flags = Qt::ItemIsEnabled;
00218     return flags;
00219 }
00220 
00221 QVariant
00222 ModelMetadataModel::headerData(int section,
00223                            Qt::Orientation orientation,
00224                            int role) const
00225 {
00226     if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
00227         if (section == m_modelTypeColumn) return QVariant(tr("Type"));
00228         else if (section == m_modelNameColumn) return QVariant(tr("Name"));
00229         else if (section == m_modelMakerColumn) return QVariant(tr("Maker"));
00230         else if (section == m_modelSourceColumn) return QVariant(tr("Source"));
00231     }
00232 
00233     return QVariant();
00234 }
00235 
00236 QModelIndex
00237 ModelMetadataModel::index(int row, int column, const QModelIndex &parent) const
00238 {
00239     if (!parent.isValid()) {
00240         if (row >= (int)m_models.size()) return QModelIndex();
00241         return createIndex(row, column, (void *)0);
00242     }
00243 
00244     return QModelIndex();
00245 }
00246 
00247 QModelIndex
00248 ModelMetadataModel::parent(const QModelIndex &) const
00249 {
00250     return QModelIndex();
00251 }
00252 
00253 int
00254 ModelMetadataModel::rowCount(const QModelIndex &parent) const
00255 {
00256     if (!parent.isValid()) return m_models.size();
00257     return 0;
00258 }
00259 
00260 int
00261 ModelMetadataModel::columnCount(const QModelIndex &) const
00262 {
00263     return m_columnCount;
00264 }
00265 
00266 
00267 
00268 LayerTreeModel::LayerTreeModel(PaneStack *stack, QObject *parent) :
00269     QAbstractItemModel(parent),
00270     m_stack(stack)
00271 {
00272     m_layerNameColumn = 0;
00273     m_layerVisibleColumn = 1;
00274     m_layerPlayedColumn = 2;
00275     m_modelNameColumn = 3;
00276     m_columnCount = 4;
00277 
00278     connect(stack, SIGNAL(paneAdded()), this, SLOT(paneAdded()));
00279     connect(stack, SIGNAL(paneAboutToBeDeleted(Pane *)),
00280             this, SLOT(paneAboutToBeDeleted(Pane *)));
00281 
00282     for (int i = 0; i < stack->getPaneCount(); ++i) {
00283         Pane *pane = stack->getPane(i);
00284         if (!pane) continue;
00285         connect(pane, SIGNAL(propertyContainerAdded(PropertyContainer *)),
00286                 this, SLOT(propertyContainerAdded(PropertyContainer *)));
00287         connect(pane, SIGNAL(propertyContainerRemoved(PropertyContainer *)),
00288                 this, SLOT(propertyContainerRemoved(PropertyContainer *)));
00289         connect(pane, SIGNAL(propertyContainerSelected(PropertyContainer *)),
00290                 this, SLOT(propertyContainerSelected(PropertyContainer *)));
00291         connect(pane, SIGNAL(propertyContainerPropertyChanged(PropertyContainer *)),
00292                 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
00293         connect(pane, SIGNAL(propertyContainerNameChanged(PropertyContainer *)),
00294                 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
00295         connect(pane, SIGNAL(layerModelChanged()),
00296                 this, SLOT(paneLayerModelChanged()));
00297 
00298         for (int j = 0; j < pane->getLayerCount(); ++j) {
00299             Layer *layer = pane->getLayer(j);
00300             if (!layer) continue;
00301             PlayParameters *params = layer->getPlayParameters();
00302             if (!params) continue;
00303             connect(params, SIGNAL(playAudibleChanged(bool)),
00304                     this, SLOT(playParametersAudibilityChanged(bool)));
00305         }
00306     }
00307 }
00308 
00309 LayerTreeModel::~LayerTreeModel()
00310 {
00311 }
00312 
00313 void
00314 LayerTreeModel::paneAdded()
00315 {
00316     emit layoutChanged();
00317 }
00318 
00319 void
00320 LayerTreeModel::paneAboutToBeDeleted(Pane *pane)
00321 {
00322     cerr << "paneDeleted: " << pane << endl;
00323     m_deletedPanes.insert(pane);
00324     emit layoutChanged();
00325 }
00326 
00327 void
00328 LayerTreeModel::propertyContainerAdded(PropertyContainer *)
00329 {
00330     emit layoutChanged();
00331 }
00332 
00333 void
00334 LayerTreeModel::propertyContainerRemoved(PropertyContainer *)
00335 {
00336     emit layoutChanged();
00337 }
00338 
00339 void
00340 LayerTreeModel::propertyContainerSelected(PropertyContainer *)
00341 {
00342     emit layoutChanged();
00343 }
00344 
00345 void
00346 LayerTreeModel::paneLayerModelChanged()
00347 {
00348     emit layoutChanged();
00349 }
00350 
00351 void
00352 LayerTreeModel::propertyContainerPropertyChanged(PropertyContainer *pc)
00353 {
00354     for (int i = 0; i < m_stack->getPaneCount(); ++i) {
00355         Pane *pane = m_stack->getPane(i);
00356         if (!pane) continue;
00357         for (int j = 0; j < pane->getLayerCount(); ++j) {
00358             if (pane->getLayer(j) == pc) {
00359                 emit dataChanged(createIndex(pane->getLayerCount() - j - 1,
00360                                              m_layerNameColumn, pane),
00361                                  createIndex(pane->getLayerCount() - j - 1,
00362                                              m_modelNameColumn, pane));
00363             }
00364         }
00365     }
00366 }
00367 
00368 void
00369 LayerTreeModel::playParametersAudibilityChanged(bool a)
00370 {
00371     PlayParameters *params = dynamic_cast<PlayParameters *>(sender());
00372     if (!params) return;
00373 
00374     SVDEBUG << "LayerTreeModel::playParametersAudibilityChanged("
00375               << params << "," << a << ")" << endl;
00376 
00377     for (int i = 0; i < m_stack->getPaneCount(); ++i) {
00378         Pane *pane = m_stack->getPane(i);
00379         if (!pane) continue;
00380         for (int j = 0; j < pane->getLayerCount(); ++j) {
00381             Layer *layer = pane->getLayer(j);
00382             if (!layer) continue;
00383             if (layer->getPlayParameters() == params) {
00384                 SVDEBUG << "LayerTreeModel::playParametersAudibilityChanged("
00385                           << params << "," << a << "): row " << pane->getLayerCount() - j - 1 << ", col " << 2 << endl;
00386 
00387                 emit dataChanged(createIndex(pane->getLayerCount() - j - 1,
00388                                              m_layerPlayedColumn, pane),
00389                                  createIndex(pane->getLayerCount() - j - 1,
00390                                              m_layerPlayedColumn, pane));
00391             }
00392         }
00393     }
00394 }
00395 
00396 QVariant
00397 LayerTreeModel::data(const QModelIndex &index, int role) const
00398 {
00399     if (!index.isValid()) return QVariant();
00400 
00401     QObject *obj = static_cast<QObject *>(index.internalPointer());
00402     int row = index.row(), col = index.column();
00403 
00404     Pane *pane = dynamic_cast<Pane *>(obj);
00405     if (!pane) {
00406         if (col == 0 && row < m_stack->getPaneCount()) {
00407             switch (role) {
00408             case Qt::DisplayRole:
00409                 return QVariant(QString("Pane %1").arg(row + 1));
00410             case Qt::DecorationRole:
00411                 return QVariant(QIcon(QString(":/icons/pane.png")));
00412             default: break;
00413             }
00414         }
00415     }
00416 
00417     if (pane && pane->getLayerCount() > row) {
00418         Layer *layer = pane->getLayer(pane->getLayerCount() - row - 1);
00419         if (layer) {
00420             if (col == m_layerNameColumn) {
00421                 switch (role) {
00422                 case Qt::DisplayRole:
00423                     return QVariant(layer->objectName());
00424                 case Qt::DecorationRole:
00425                     return QVariant
00426                         (QIcon(QString(":/icons/%1.png")
00427                                .arg(layer->getPropertyContainerIconName())));
00428                 default: break;
00429                 }
00430             } else if (col == m_layerVisibleColumn) {
00431                 if (role == Qt::CheckStateRole) {
00432                     return QVariant(layer->isLayerDormant(pane) ?
00433                                     Qt::Unchecked : Qt::Checked);
00434                 } else if (role == Qt::TextAlignmentRole) {
00435                     return QVariant(Qt::AlignHCenter);
00436                 }
00437             } else if (col == m_layerPlayedColumn) {
00438                 if (role == Qt::CheckStateRole) {
00439                     PlayParameters *params = layer->getPlayParameters();
00440                     if (params) return QVariant(params->isPlayMuted() ?
00441                                                 Qt::Unchecked : Qt::Checked);
00442                     else return QVariant();
00443                 } else if (role == Qt::TextAlignmentRole) {
00444                     return QVariant(Qt::AlignHCenter);
00445                 }
00446             } else if (col == m_modelNameColumn) {
00447                 Model *model = layer->getModel();
00448                 if (model && role == Qt::DisplayRole) {
00449                     return QVariant(model->objectName());
00450                 }
00451             }
00452         }
00453     }
00454 
00455     return QVariant();
00456 }
00457 
00458 bool
00459 LayerTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
00460 {
00461     if (!index.isValid()) return false;
00462 
00463     QObject *obj = static_cast<QObject *>(index.internalPointer());
00464     int row = index.row(), col = index.column();
00465 
00466     Pane *pane = dynamic_cast<Pane *>(obj);
00467     if (!pane || pane->getLayerCount() <= row) return false;
00468 
00469     Layer *layer = pane->getLayer(pane->getLayerCount() - row - 1);
00470     if (!layer) return false;
00471 
00472     if (col == m_layerVisibleColumn) {
00473         if (role == Qt::CheckStateRole) {
00474             layer->showLayer(pane, value.toInt() == Qt::Checked);
00475             emit dataChanged(index, index);
00476             return true;
00477         }
00478     } else if (col == m_layerPlayedColumn) {
00479         if (role == Qt::CheckStateRole) {
00480             PlayParameters *params = layer->getPlayParameters();
00481             if (params) {
00482                 params->setPlayMuted(value.toInt() == Qt::Unchecked);
00483                 emit dataChanged(index, index);
00484                 return true;
00485             }
00486         }
00487     }
00488 
00489     return false;
00490 }
00491 
00492 Qt::ItemFlags
00493 LayerTreeModel::flags(const QModelIndex &index) const
00494 {
00495     Qt::ItemFlags flags = Qt::ItemIsEnabled;
00496     if (!index.isValid()) return flags;
00497 
00498     if (index.column() == m_layerVisibleColumn ||
00499         index.column() == m_layerPlayedColumn) {
00500         flags |= Qt::ItemIsUserCheckable;
00501     } else if (index.column() == 0) {
00502         flags |= Qt::ItemIsSelectable;
00503     }
00504 
00505     return flags;
00506 }
00507 
00508 QVariant
00509 LayerTreeModel::headerData(int section,
00510                            Qt::Orientation orientation,
00511                            int role) const
00512 {
00513     if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
00514         if (section == m_layerNameColumn) return QVariant(tr("Layer"));
00515         else if (section == m_layerVisibleColumn) return QVariant(tr("Shown"));
00516         else if (section == m_layerPlayedColumn) return QVariant(tr("Played"));
00517         else if (section == m_modelNameColumn) return QVariant(tr("Model"));
00518     }
00519 
00520     return QVariant();
00521 }
00522 
00523 QModelIndex
00524 LayerTreeModel::index(int row, int column, const QModelIndex &parent) const
00525 {
00526     // cell for a pane contains row, column, pane stack
00527     // -> its parent is the invalid cell
00528 
00529     // cell for a layer contains row, column, pane
00530     // -> its parent is row, column, pane stack (which identify the pane)
00531 
00532     if (!parent.isValid()) {
00533         if (row >= m_stack->getPaneCount() || column > 0) return QModelIndex();
00534         return createIndex(row, column, m_stack);
00535     }
00536 
00537     QObject *obj = static_cast<QObject *>(parent.internalPointer());
00538 
00539     if (obj == m_stack) {
00540         Pane *pane = m_stack->getPane(parent.row());
00541         if (!pane || parent.column() > 0) return QModelIndex();
00542         return createIndex(row, column, pane);
00543     }
00544 
00545     return QModelIndex();
00546 }
00547 
00548 QModelIndex
00549 LayerTreeModel::parent(const QModelIndex &index) const
00550 {
00551     QObject *obj = static_cast<QObject *>(index.internalPointer());
00552 
00553     if (m_deletedPanes.find(obj) != m_deletedPanes.end()) {
00554 //        m_deletedPanes.erase(obj);
00555         return QModelIndex();
00556     }
00557 
00558     Pane *pane = dynamic_cast<Pane *>(obj);
00559     if (pane) {
00560         int index = m_stack->getPaneIndex(pane);
00561         if (index >= 0) return createIndex(index, 0, m_stack);
00562     }
00563 
00564     return QModelIndex();
00565 }
00566 
00567 int
00568 LayerTreeModel::rowCount(const QModelIndex &parent) const
00569 {
00570     if (!parent.isValid()) return m_stack->getPaneCount();
00571 
00572     QObject *obj = static_cast<QObject *>(parent.internalPointer());
00573     
00574     if (obj == m_stack) {
00575         Pane *pane = m_stack->getPane(parent.row());
00576         if (!pane || parent.column() > 0) return 0;
00577         return pane->getLayerCount();
00578     }
00579 
00580     return 0;
00581 }
00582 
00583 int
00584 LayerTreeModel::columnCount(const QModelIndex &parent) const
00585 {
00586     if (!parent.isValid()) return m_columnCount;
00587 
00588     QObject *obj = static_cast<QObject *>(parent.internalPointer());
00589     if (obj == m_stack) return m_columnCount; // row for a layer
00590 
00591     return 1;
00592 }
00593