annotate widgets/LayerTree.cpp @ 349:369a197737c7

* Various fixes to object lifetime management, particularly in the spectrum layer and for notification of main model deletion. The main purpose of this is to improve the behaviour of the spectrum, but I think it may also help with #1840922 Various crashes in Layer Summary window.
author Chris Cannam
date Wed, 23 Jan 2008 15:43:27 +0000
parents 4a542ba875c2
children 1d85aa5a49be
rev   line source
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@336 30 ModelDataModel::ModelDataModel(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@336 73 ModelDataModel::~ModelDataModel()
Chris@336 74 {
Chris@336 75 }
Chris@336 76
Chris@336 77 void
Chris@336 78 ModelDataModel::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@336 114 std::cerr << "ModelDataModel::rebuildModelSet: " << m_models.size() << " models" << std::endl;
Chris@336 115 }
Chris@336 116
Chris@336 117 void
Chris@336 118 ModelDataModel::paneAdded()
Chris@336 119 {
Chris@336 120 rebuildModelSet();
Chris@336 121 emit layoutChanged();
Chris@336 122 }
Chris@336 123
Chris@336 124 void
Chris@336 125 ModelDataModel::paneDeleted()
Chris@336 126 {
Chris@336 127 rebuildModelSet();
Chris@336 128 emit layoutChanged();
Chris@336 129 }
Chris@336 130
Chris@336 131 void
Chris@336 132 ModelDataModel::paneLayerModelChanged()
Chris@336 133 {
Chris@336 134 rebuildModelSet();
Chris@336 135 emit layoutChanged();
Chris@336 136 }
Chris@336 137
Chris@336 138 void
Chris@336 139 ModelDataModel::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@336 146 ModelDataModel::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@336 153 ModelDataModel::propertyContainerSelected(PropertyContainer *)
Chris@336 154 {
Chris@336 155 }
Chris@336 156
Chris@336 157 void
Chris@336 158 ModelDataModel::propertyContainerPropertyChanged(PropertyContainer *pc)
Chris@336 159 {
Chris@336 160 }
Chris@336 161
Chris@336 162 void
Chris@336 163 ModelDataModel::playParametersAudibilityChanged(bool a)
Chris@336 164 {
Chris@336 165 }
Chris@336 166
Chris@336 167 QVariant
Chris@336 168 ModelDataModel::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@336 209 ModelDataModel::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@336 215 ModelDataModel::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@336 222 ModelDataModel::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@336 237 ModelDataModel::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@336 248 ModelDataModel::parent(const QModelIndex &index) const
Chris@336 249 {
Chris@336 250 return QModelIndex();
Chris@336 251 }
Chris@336 252
Chris@336 253 int
Chris@336 254 ModelDataModel::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@336 261 ModelDataModel::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@298 374 std::cerr << "LayerTreeModel::playParametersAudibilityChanged("
Chris@298 375 << params << "," << a << ")" << std::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@298 384 std::cerr << "LayerTreeModel::playParametersAudibilityChanged("
Chris@298 385 << params << "," << a << "): row " << pane->getLayerCount() - j - 1 << ", col " << 2 << std::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