annotate widgets/PropertyStack.cpp @ 723:d1c0abfb11be tonioni

Fix bug in choosing which layer to bring to the front when asked programmatically
author Chris Cannam
date Tue, 04 Feb 2014 14:35:59 +0000
parents 4806715f7a19
children 596414d20ef0
rev   line source
Chris@58 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@59 4 Sonic Visualiser
Chris@59 5 An audio file viewer and annotation editor.
Chris@59 6 Centre for Digital Music, Queen Mary, University of London.
Chris@59 7 This file copyright 2006 Chris Cannam.
Chris@0 8
Chris@59 9 This program is free software; you can redistribute it and/or
Chris@59 10 modify it under the terms of the GNU General Public License as
Chris@59 11 published by the Free Software Foundation; either version 2 of the
Chris@59 12 License, or (at your option) any later version. See the file
Chris@59 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@0 16 #include "PropertyStack.h"
Chris@0 17 #include "PropertyBox.h"
Chris@0 18 #include "base/PropertyContainer.h"
Chris@128 19 #include "view/View.h"
Chris@128 20 #include "layer/Layer.h"
Chris@242 21 #include "layer/LayerFactory.h"
Chris@190 22 #include "widgets/NotifyingTabBar.h"
Chris@289 23 #include "widgets/IconLoader.h"
Chris@377 24 #include "base/Command.h"
Chris@377 25 #include "widgets/CommandHistory.h"
Chris@0 26
Chris@0 27 #include <QIcon>
Chris@0 28 #include <QTabWidget>
Chris@0 29
Chris@0 30 #include <iostream>
Chris@0 31
Chris@36 32 //#define DEBUG_PROPERTY_STACK 1
Chris@0 33
Chris@0 34 PropertyStack::PropertyStack(QWidget *parent, View *client) :
Chris@0 35 QTabWidget(parent),
Chris@0 36 m_client(client)
Chris@0 37 {
Chris@190 38 NotifyingTabBar *bar = new NotifyingTabBar();
Chris@190 39 bar->setDrawBase(false);
Chris@190 40
Chris@190 41 connect(bar, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredTabBar()));
Chris@190 42 connect(bar, SIGNAL(mouseLeft()), this, SLOT(mouseLeftTabBar()));
Chris@190 43 connect(bar, SIGNAL(activeTabClicked()), this, SLOT(activeTabClicked()));
Chris@190 44
Chris@190 45 setTabBar(bar);
Chris@190 46
Chris@242 47 #if (QT_VERSION >= 0x0402)
Chris@242 48 setElideMode(Qt::ElideNone);
Chris@241 49 tabBar()->setUsesScrollButtons(true);
Chris@241 50 tabBar()->setIconSize(QSize(16, 16));
Chris@242 51 #endif
Chris@239 52
Chris@0 53 repopulate();
Chris@0 54
Chris@0 55 connect(this, SIGNAL(currentChanged(int)),
Chris@0 56 this, SLOT(selectedContainerChanged(int)));
Chris@0 57
Chris@0 58 connect(m_client, SIGNAL(propertyContainerAdded(PropertyContainer *)),
Chris@0 59 this, SLOT(propertyContainerAdded(PropertyContainer *)));
Chris@0 60
Chris@0 61 connect(m_client, SIGNAL(propertyContainerRemoved(PropertyContainer *)),
Chris@0 62 this, SLOT(propertyContainerRemoved(PropertyContainer *)));
Chris@0 63
Chris@0 64 connect(m_client, SIGNAL(propertyContainerPropertyChanged(PropertyContainer *)),
Chris@0 65 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
Chris@0 66
Chris@197 67 connect(m_client, SIGNAL(propertyContainerPropertyRangeChanged(PropertyContainer *)),
Chris@197 68 this, SLOT(propertyContainerPropertyRangeChanged(PropertyContainer *)));
Chris@197 69
Chris@0 70 connect(m_client, SIGNAL(propertyContainerNameChanged(PropertyContainer *)),
Chris@0 71 this, SLOT(propertyContainerNameChanged(PropertyContainer *)));
Chris@0 72
Chris@52 73 connect(this, SIGNAL(propertyContainerSelected(View *, PropertyContainer *)),
Chris@52 74 m_client, SLOT(propertyContainerSelected(View *, PropertyContainer *)));
Chris@0 75 }
Chris@0 76
Chris@0 77 void
Chris@0 78 PropertyStack::repopulate()
Chris@0 79 {
Chris@0 80 blockSignals(true);
Chris@0 81
Chris@0 82 #ifdef DEBUG_PROPERTY_STACK
Chris@587 83 SVDEBUG << "PropertyStack::repopulate" << endl;
Chris@0 84 #endif
Chris@0 85
Chris@0 86 while (count() > 0) {
Chris@0 87 removeTab(0);
Chris@0 88 }
Chris@0 89 for (size_t i = 0; i < m_boxes.size(); ++i) {
Chris@0 90 delete m_boxes[i];
Chris@0 91 }
Chris@0 92 m_boxes.clear();
Chris@0 93
Chris@0 94 for (size_t i = 0; i < m_client->getPropertyContainerCount(); ++i) {
Chris@0 95
Chris@0 96 PropertyContainer *container = m_client->getPropertyContainer(i);
Chris@0 97 QString name = container->getPropertyContainerName();
Chris@0 98
Chris@0 99 PropertyBox *box = new PropertyBox(container);
Chris@0 100
Chris@47 101 connect(box, SIGNAL(showLayer(bool)), this, SLOT(showLayer(bool)));
Chris@189 102 connect(box, SIGNAL(contextHelpChanged(const QString &)),
Chris@189 103 this, SIGNAL(contextHelpChanged(const QString &)));
Chris@47 104
Chris@185 105 Layer *layer = dynamic_cast<Layer *>(container);
Chris@185 106 if (layer) {
Chris@185 107 box->layerVisibilityChanged(!layer->isLayerDormant(m_client));
Chris@185 108 }
Chris@185 109
Chris@242 110 QString shortName = name;
Chris@242 111
Chris@242 112 if (layer) {
Chris@242 113 shortName = LayerFactory::getInstance()->getLayerPresentationName
Chris@242 114 (LayerFactory::getInstance()->getLayerType(layer));
Chris@552 115 if (layer->getLayerPresentationName() != "") {
Chris@552 116 name = layer->getLayerPresentationName();
Chris@552 117 }
Chris@242 118 }
Chris@242 119
Chris@552 120 bool nameDiffers = (name != shortName);
Chris@242 121 shortName = QString("&%1 %2").arg(i + 1).arg(shortName);
Chris@242 122
Chris@242 123 QString iconName = container->getPropertyContainerIconName();
Chris@242 124
Chris@289 125 QIcon icon(IconLoader().load(iconName));
Chris@0 126 if (icon.isNull()) {
Chris@242 127 addTab(box, shortName);
Chris@552 128 if (nameDiffers) {
Chris@552 129 setTabToolTip(i, name);
Chris@552 130 }
Chris@0 131 } else {
Chris@0 132 addTab(box, icon, QString("&%1").arg(i + 1));
Chris@242 133 setTabToolTip(i, name);
Chris@0 134 }
Chris@0 135
Chris@0 136 m_boxes.push_back(box);
Chris@0 137 }
Chris@0 138
Chris@0 139 blockSignals(false);
Chris@0 140 }
Chris@0 141
Chris@0 142 bool
Chris@0 143 PropertyStack::containsContainer(PropertyContainer *pc) const
Chris@0 144 {
Chris@0 145 for (size_t i = 0; i < m_client->getPropertyContainerCount(); ++i) {
Chris@0 146 PropertyContainer *container = m_client->getPropertyContainer(i);
Chris@0 147 if (pc == container) return true;
Chris@0 148 }
Chris@0 149
Chris@0 150 return false;
Chris@0 151 }
Chris@0 152
Chris@19 153 int
Chris@19 154 PropertyStack::getContainerIndex(PropertyContainer *pc) const
Chris@19 155 {
Chris@723 156 // This is used to obtain an index to be passed to setCurrentIndex
Chris@723 157 // -- which is the index of the property container's box in our
Chris@723 158 // stack of boxes. That is not the same thing as the index of the
Chris@723 159 // container (i.e. the layer) in the view: the view reorders its
Chris@723 160 // containers whenever one is raised to the top, while our boxes
Chris@723 161 // remain in the same order. So we must find this container in the
Chris@723 162 // box list, not in the view.
Chris@723 163
Chris@723 164 for (size_t i = 0; i < m_boxes.size(); ++i) {
Chris@723 165 PropertyContainer *container = m_boxes[i]->getContainer();
Chris@723 166 if (pc == container) {
Chris@723 167 return i;
Chris@723 168 }
Chris@19 169 }
Chris@19 170
Chris@19 171 return false;
Chris@19 172 }
Chris@19 173
Chris@0 174 void
Chris@0 175 PropertyStack::propertyContainerAdded(PropertyContainer *)
Chris@0 176 {
Chris@0 177 if (sender() != m_client) return;
Chris@0 178 repopulate();
Chris@0 179 }
Chris@0 180
Chris@0 181 void
Chris@0 182 PropertyStack::propertyContainerRemoved(PropertyContainer *)
Chris@0 183 {
Chris@0 184 if (sender() != m_client) return;
Chris@0 185 repopulate();
Chris@0 186 }
Chris@0 187
Chris@0 188 void
Chris@0 189 PropertyStack::propertyContainerPropertyChanged(PropertyContainer *pc)
Chris@0 190 {
Chris@298 191 Layer *layer = dynamic_cast<Layer *>(pc);
Chris@0 192 for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@0 193 if (pc == m_boxes[i]->getContainer()) {
Chris@0 194 m_boxes[i]->propertyContainerPropertyChanged(pc);
Chris@298 195 if (layer) {
Chris@298 196 m_boxes[i]->layerVisibilityChanged
Chris@298 197 (!layer->isLayerDormant(m_client));
Chris@298 198 }
Chris@0 199 }
Chris@0 200 }
Chris@0 201 }
Chris@0 202
Chris@0 203 void
Chris@197 204 PropertyStack::propertyContainerPropertyRangeChanged(PropertyContainer *pc)
Chris@197 205 {
Chris@197 206 for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@197 207 if (pc == m_boxes[i]->getContainer()) {
Chris@197 208 m_boxes[i]->propertyContainerPropertyRangeChanged(pc);
Chris@197 209 }
Chris@197 210 }
Chris@197 211 }
Chris@197 212
Chris@197 213 void
Chris@249 214 PropertyStack::propertyContainerNameChanged(PropertyContainer *)
Chris@0 215 {
Chris@0 216 if (sender() != m_client) return;
Chris@0 217 repopulate();
Chris@0 218 }
Chris@0 219
Chris@377 220 class ShowLayerCommand : public QObject, public Command
Chris@377 221 {
Chris@377 222 public:
Chris@397 223 ShowLayerCommand(View *view, Layer *layer, bool show, QString name) :
Chris@397 224 m_view(view), m_layer(layer), m_show(show), m_name(name) { }
Chris@377 225 void execute() {
Chris@377 226 m_layer->showLayer(m_view, m_show);
Chris@377 227 }
Chris@377 228 void unexecute() {
Chris@377 229 m_layer->showLayer(m_view, !m_show);
Chris@377 230 }
Chris@377 231 QString getName() const {
Chris@397 232 return m_name;
Chris@377 233 }
Chris@377 234 protected:
Chris@377 235 View *m_view;
Chris@377 236 Layer *m_layer;
Chris@377 237 bool m_show;
Chris@397 238 QString m_name;
Chris@377 239 };
Chris@377 240
Chris@0 241 void
Chris@47 242 PropertyStack::showLayer(bool show)
Chris@47 243 {
Chris@47 244 QObject *obj = sender();
Chris@47 245
Chris@47 246 for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@47 247 if (obj == m_boxes[i]) {
Chris@47 248 Layer *layer = dynamic_cast<Layer *>(m_boxes[i]->getContainer());
Chris@47 249 if (layer) {
Chris@377 250 CommandHistory::getInstance()->addCommand
Chris@397 251 (new ShowLayerCommand(m_client, layer, show,
Chris@397 252 tr("Change Layer Visibility")));
Chris@47 253 return;
Chris@47 254 }
Chris@47 255 }
Chris@47 256 }
Chris@47 257 }
Chris@47 258
Chris@47 259 void
Chris@0 260 PropertyStack::selectedContainerChanged(int n)
Chris@0 261 {
Chris@0 262 if (n >= int(m_boxes.size())) return;
Chris@52 263 emit propertyContainerSelected(m_client, m_boxes[n]->getContainer());
Chris@0 264 }
Chris@0 265
Chris@190 266 void
Chris@190 267 PropertyStack::mouseEnteredTabBar()
Chris@190 268 {
Chris@190 269 emit contextHelpChanged(tr("Click to change the current active layer"));
Chris@190 270 }
Chris@190 271
Chris@190 272 void
Chris@190 273 PropertyStack::mouseLeftTabBar()
Chris@190 274 {
Chris@190 275 emit contextHelpChanged("");
Chris@190 276 }
Chris@190 277
Chris@190 278 void
Chris@190 279 PropertyStack::activeTabClicked()
Chris@190 280 {
Chris@190 281 emit viewSelected(m_client);
Chris@190 282 }
Chris@190 283