svgui
1.9
|
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