annotate widgets/LayerTree.cpp @ 308:cda569dfbdfe

* Add labelling option for instants inserted through tapping (closes FR#1674184) Needs some refinement still, but it's almost functionally complete
author Chris Cannam
date Mon, 08 Oct 2007 14:44:38 +0000
parents 226cb289bdf4
children 4a542ba875c2
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@43 24
Chris@280 25 #include <QIcon>
Chris@43 26 #include <iostream>
Chris@43 27
Chris@43 28
Chris@43 29 LayerTreeModel::LayerTreeModel(PaneStack *stack, QObject *parent) :
Chris@43 30 QAbstractItemModel(parent),
Chris@43 31 m_stack(stack)
Chris@43 32 {
Chris@271 33 connect(stack, SIGNAL(paneAdded()), this, SIGNAL(layoutChanged()));
Chris@271 34 connect(stack, SIGNAL(paneDeleted()), this, SIGNAL(layoutChanged()));
Chris@298 35
Chris@298 36 for (int i = 0; i < stack->getPaneCount(); ++i) {
Chris@298 37 Pane *pane = stack->getPane(i);
Chris@298 38 if (!pane) continue;
Chris@298 39 connect(pane, SIGNAL(propertyContainerAdded(PropertyContainer *)),
Chris@298 40 this, SLOT(propertyContainerAdded(PropertyContainer *)));
Chris@298 41 connect(pane, SIGNAL(propertyContainerRemoved(PropertyContainer *)),
Chris@298 42 this, SLOT(propertyContainerRemoved(PropertyContainer *)));
Chris@298 43 connect(pane, SIGNAL(propertyContainerSelected(PropertyContainer *)),
Chris@298 44 this, SLOT(propertyContainerSelected(PropertyContainer *)));
Chris@298 45 connect(pane, SIGNAL(propertyContainerPropertyChanged(PropertyContainer *)),
Chris@298 46 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
Chris@298 47 connect(pane, SIGNAL(propertyContainerNameChanged(PropertyContainer *)),
Chris@298 48 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
Chris@298 49 for (int j = 0; j < pane->getLayerCount(); ++j) {
Chris@298 50 Layer *layer = pane->getLayer(j);
Chris@298 51 if (!layer) continue;
Chris@298 52 PlayParameters *params = layer->getPlayParameters();
Chris@298 53 if (!params) continue;
Chris@298 54 connect(params, SIGNAL(playAudibleChanged(bool)),
Chris@298 55 this, SLOT(playParametersAudibilityChanged(bool)));
Chris@298 56 }
Chris@298 57 }
Chris@43 58 }
Chris@43 59
Chris@43 60 LayerTreeModel::~LayerTreeModel()
Chris@43 61 {
Chris@43 62 }
Chris@43 63
Chris@298 64 void
Chris@298 65 LayerTreeModel::propertyContainerAdded(PropertyContainer *)
Chris@298 66 {
Chris@298 67 emit layoutChanged();
Chris@298 68 }
Chris@298 69
Chris@298 70 void
Chris@298 71 LayerTreeModel::propertyContainerRemoved(PropertyContainer *)
Chris@298 72 {
Chris@298 73 emit layoutChanged();
Chris@298 74 }
Chris@298 75
Chris@298 76 void
Chris@298 77 LayerTreeModel::propertyContainerSelected(PropertyContainer *)
Chris@298 78 {
Chris@298 79 emit layoutChanged();
Chris@298 80 }
Chris@298 81
Chris@298 82 void
Chris@298 83 LayerTreeModel::propertyContainerPropertyChanged(PropertyContainer *pc)
Chris@298 84 {
Chris@298 85 for (int i = 0; i < m_stack->getPaneCount(); ++i) {
Chris@298 86 Pane *pane = m_stack->getPane(i);
Chris@298 87 if (!pane) continue;
Chris@298 88 for (int j = 0; j < pane->getLayerCount(); ++j) {
Chris@298 89 if (pane->getLayer(j) == pc) {
Chris@298 90 emit dataChanged(createIndex(pane->getLayerCount() - j - 1,
Chris@298 91 0, pane),
Chris@298 92 createIndex(pane->getLayerCount() - j - 1,
Chris@298 93 3, pane));
Chris@298 94 }
Chris@298 95 }
Chris@298 96 }
Chris@298 97 }
Chris@298 98
Chris@298 99 void
Chris@298 100 LayerTreeModel::playParametersAudibilityChanged(bool a)
Chris@298 101 {
Chris@298 102 PlayParameters *params = dynamic_cast<PlayParameters *>(sender());
Chris@298 103 if (!params) return;
Chris@298 104
Chris@298 105 std::cerr << "LayerTreeModel::playParametersAudibilityChanged("
Chris@298 106 << params << "," << a << ")" << std::endl;
Chris@298 107
Chris@298 108 for (int i = 0; i < m_stack->getPaneCount(); ++i) {
Chris@298 109 Pane *pane = m_stack->getPane(i);
Chris@298 110 if (!pane) continue;
Chris@298 111 for (int j = 0; j < pane->getLayerCount(); ++j) {
Chris@298 112 Layer *layer = pane->getLayer(j);
Chris@298 113 if (!layer) continue;
Chris@298 114 if (layer->getPlayParameters() == params) {
Chris@298 115 std::cerr << "LayerTreeModel::playParametersAudibilityChanged("
Chris@298 116 << params << "," << a << "): row " << pane->getLayerCount() - j - 1 << ", col " << 2 << std::endl;
Chris@298 117
Chris@298 118 emit dataChanged(createIndex(pane->getLayerCount() - j - 1,
Chris@298 119 2, pane),
Chris@298 120 createIndex(pane->getLayerCount() - j - 1,
Chris@298 121 2, pane));
Chris@298 122 }
Chris@298 123 }
Chris@298 124 }
Chris@298 125 }
Chris@298 126
Chris@43 127 QVariant
Chris@43 128 LayerTreeModel::data(const QModelIndex &index, int role) const
Chris@43 129 {
Chris@43 130 if (!index.isValid()) return QVariant();
Chris@56 131
Chris@43 132 QObject *obj = static_cast<QObject *>(index.internalPointer());
Chris@277 133 int row = index.row(), col = index.column();
Chris@277 134
Chris@277 135 Pane *pane = dynamic_cast<Pane *>(obj);
Chris@277 136 if (!pane) {
Chris@277 137 if (col == 0 && row < m_stack->getPaneCount()) {
Chris@277 138 switch (role) {
Chris@277 139 case Qt::DisplayRole:
Chris@277 140 return QVariant(QString("Pane %1").arg(row + 1));
Chris@277 141 case Qt::DecorationRole:
Chris@277 142 return QVariant(QIcon(QString(":/icons/pane.png")));
Chris@277 143 default: break;
Chris@277 144 }
Chris@277 145 }
Chris@43 146 }
Chris@43 147
Chris@277 148 if (pane && pane->getLayerCount() > row) {
Chris@298 149 Layer *layer = pane->getLayer(pane->getLayerCount() - row - 1);
Chris@277 150 if (layer) {
Chris@277 151 if (col == 0) {
Chris@277 152 switch (role) {
Chris@277 153 case Qt::DisplayRole:
Chris@277 154 return QVariant(layer->objectName());
Chris@277 155 case Qt::DecorationRole:
Chris@277 156 return QVariant
Chris@277 157 (QIcon(QString(":/icons/%1.png")
Chris@277 158 .arg(layer->getPropertyContainerIconName())));
Chris@277 159 default: break;
Chris@277 160 }
Chris@277 161 } else if (col == 1) {
Chris@298 162 if (role == Qt::CheckStateRole) {
Chris@298 163 return QVariant(layer->isLayerDormant(pane) ?
Chris@298 164 Qt::Unchecked : Qt::Checked);
Chris@298 165 } else if (role == Qt::TextAlignmentRole) {
Chris@298 166 return QVariant(Qt::AlignHCenter);
Chris@298 167 }
Chris@298 168 } else if (col == 2) {
Chris@298 169 if (role == Qt::CheckStateRole) {
Chris@298 170 PlayParameters *params = layer->getPlayParameters();
Chris@298 171 if (params) return QVariant(params->isPlayMuted() ?
Chris@298 172 Qt::Unchecked : Qt::Checked);
Chris@298 173 else return QVariant();
Chris@298 174 } else if (role == Qt::TextAlignmentRole) {
Chris@298 175 return QVariant(Qt::AlignHCenter);
Chris@298 176 }
Chris@298 177 } else if (col == 3) {
Chris@277 178 Model *model = layer->getModel();
Chris@277 179 if (model && role == Qt::DisplayRole) {
Chris@277 180 return QVariant(model->objectName());
Chris@277 181 }
Chris@277 182 }
Chris@277 183 }
Chris@43 184 }
Chris@43 185
Chris@43 186 return QVariant();
Chris@43 187 }
Chris@43 188
Chris@298 189 bool
Chris@298 190 LayerTreeModel::setData(const QModelIndex &index, const QVariant &value, int role)
Chris@298 191 {
Chris@298 192 if (!index.isValid()) return false;
Chris@298 193
Chris@298 194 QObject *obj = static_cast<QObject *>(index.internalPointer());
Chris@298 195 int row = index.row(), col = index.column();
Chris@298 196
Chris@298 197 Pane *pane = dynamic_cast<Pane *>(obj);
Chris@298 198 if (!pane || pane->getLayerCount() <= row) return false;
Chris@298 199
Chris@298 200 Layer *layer = pane->getLayer(pane->getLayerCount() - row - 1);
Chris@298 201 if (!layer) return false;
Chris@298 202
Chris@298 203 if (col == 1) {
Chris@298 204 if (role == Qt::CheckStateRole) {
Chris@298 205 layer->showLayer(pane, value.toInt() == Qt::Checked);
Chris@298 206 emit dataChanged(index, index);
Chris@298 207 return true;
Chris@298 208 }
Chris@298 209 } else if (col == 2) {
Chris@298 210 if (role == Qt::CheckStateRole) {
Chris@298 211 PlayParameters *params = layer->getPlayParameters();
Chris@298 212 if (params) {
Chris@298 213 params->setPlayMuted(value.toInt() == Qt::Unchecked);
Chris@298 214 emit dataChanged(index, index);
Chris@298 215 return true;
Chris@298 216 }
Chris@298 217 }
Chris@298 218 }
Chris@298 219
Chris@298 220 return false;
Chris@298 221 }
Chris@298 222
Chris@43 223 Qt::ItemFlags
Chris@43 224 LayerTreeModel::flags(const QModelIndex &index) const
Chris@43 225 {
Chris@298 226 Qt::ItemFlags flags = Qt::ItemIsEnabled;
Chris@298 227 if (!index.isValid()) return flags;
Chris@298 228
Chris@298 229 if (index.column() == 1 || index.column() == 2) {
Chris@298 230 flags |= Qt::ItemIsUserCheckable;
Chris@298 231 } else if (index.column() == 0) {
Chris@298 232 flags |= Qt::ItemIsSelectable;
Chris@298 233 }
Chris@298 234
Chris@298 235 return flags;
Chris@43 236 }
Chris@43 237
Chris@43 238 QVariant
Chris@56 239 LayerTreeModel::headerData(int section,
Chris@43 240 Qt::Orientation orientation,
Chris@43 241 int role) const
Chris@43 242 {
Chris@56 243 if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
Chris@56 244 if (section == 0) return QVariant(tr("Layer"));
Chris@298 245 else if (section == 1) return QVariant(tr("Shown"));
Chris@298 246 else if (section == 2) return QVariant(tr("Played"));
Chris@298 247 else if (section == 3) return QVariant(tr("Model"));
Chris@56 248 }
Chris@56 249
Chris@56 250 return QVariant();
Chris@43 251 }
Chris@43 252
Chris@43 253 QModelIndex
Chris@43 254 LayerTreeModel::index(int row, int column, const QModelIndex &parent) const
Chris@43 255 {
Chris@277 256 // cell for a pane contains row, column, pane stack
Chris@277 257 // -> its parent is the invalid cell
Chris@277 258
Chris@277 259 // cell for a layer contains row, column, pane
Chris@277 260 // -> its parent is row, column, pane stack (which identify the pane)
Chris@43 261
Chris@43 262 if (!parent.isValid()) {
Chris@277 263 if (row >= m_stack->getPaneCount() || column > 0) return QModelIndex();
Chris@43 264 return createIndex(row, column, m_stack);
Chris@43 265 }
Chris@43 266
Chris@43 267 QObject *obj = static_cast<QObject *>(parent.internalPointer());
Chris@277 268
Chris@277 269 if (obj == m_stack) {
Chris@277 270 Pane *pane = m_stack->getPane(parent.row());
Chris@277 271 if (!pane || parent.column() > 0) return QModelIndex();
Chris@277 272 return createIndex(row, column, pane);
Chris@43 273 }
Chris@43 274
Chris@43 275 return QModelIndex();
Chris@43 276 }
Chris@43 277
Chris@43 278 QModelIndex
Chris@43 279 LayerTreeModel::parent(const QModelIndex &index) const
Chris@43 280 {
Chris@43 281 QObject *obj = static_cast<QObject *>(index.internalPointer());
Chris@43 282
Chris@43 283 Pane *pane = dynamic_cast<Pane *>(obj);
Chris@43 284 if (pane) {
Chris@277 285 int index = m_stack->getPaneIndex(pane);
Chris@277 286 if (index >= 0) return createIndex(index, 0, m_stack);
Chris@43 287 }
Chris@43 288
Chris@43 289 return QModelIndex();
Chris@43 290 }
Chris@43 291
Chris@43 292 int
Chris@43 293 LayerTreeModel::rowCount(const QModelIndex &parent) const
Chris@43 294 {
Chris@277 295 if (!parent.isValid()) return m_stack->getPaneCount();
Chris@43 296
Chris@43 297 QObject *obj = static_cast<QObject *>(parent.internalPointer());
Chris@43 298
Chris@277 299 if (obj == m_stack) {
Chris@277 300 Pane *pane = m_stack->getPane(parent.row());
Chris@277 301 if (!pane || parent.column() > 0) return 0;
Chris@277 302 return pane->getLayerCount();
Chris@43 303 }
Chris@43 304
Chris@43 305 return 0;
Chris@43 306 }
Chris@43 307
Chris@43 308 int
Chris@43 309 LayerTreeModel::columnCount(const QModelIndex &parent) const
Chris@43 310 {
Chris@298 311 if (!parent.isValid()) return 4;
Chris@43 312
Chris@43 313 QObject *obj = static_cast<QObject *>(parent.internalPointer());
Chris@298 314 if (obj == m_stack) return 4; // row for a layer
Chris@56 315
Chris@43 316 return 1;
Chris@43 317 }
Chris@43 318