annotate widgets/PropertyStack.cpp @ 454:e2a40fdadd8c

Various fixes: * Fix handling of HTTP redirects (avoiding crashes... I hope) * Fix failure to delete FFT models when a feature extraction model transformer was abandoned (also a cause of crashes in the past) * Fix deadlock when said transform was abandoned before its source model was ready because the session was being cleared (and so the source model would never be ready)
author Chris Cannam
date Fri, 28 Nov 2008 13:36:13 +0000
parents 2c59b0cd176b
children 2e8194a30f40
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@0 83 std::cerr << "PropertyStack::repopulate" << std::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@242 115 }
Chris@242 116
Chris@242 117 shortName = QString("&%1 %2").arg(i + 1).arg(shortName);
Chris@242 118
Chris@242 119 QString iconName = container->getPropertyContainerIconName();
Chris@242 120
Chris@289 121 QIcon icon(IconLoader().load(iconName));
Chris@0 122 if (icon.isNull()) {
Chris@242 123 addTab(box, shortName);
Chris@0 124 } else {
Chris@0 125 addTab(box, icon, QString("&%1").arg(i + 1));
Chris@242 126 setTabToolTip(i, name);
Chris@0 127 }
Chris@0 128
Chris@0 129 m_boxes.push_back(box);
Chris@0 130 }
Chris@0 131
Chris@0 132 blockSignals(false);
Chris@0 133 }
Chris@0 134
Chris@0 135 bool
Chris@0 136 PropertyStack::containsContainer(PropertyContainer *pc) const
Chris@0 137 {
Chris@0 138 for (size_t i = 0; i < m_client->getPropertyContainerCount(); ++i) {
Chris@0 139 PropertyContainer *container = m_client->getPropertyContainer(i);
Chris@0 140 if (pc == container) return true;
Chris@0 141 }
Chris@0 142
Chris@0 143 return false;
Chris@0 144 }
Chris@0 145
Chris@19 146 int
Chris@19 147 PropertyStack::getContainerIndex(PropertyContainer *pc) const
Chris@19 148 {
Chris@19 149 for (size_t i = 0; i < m_client->getPropertyContainerCount(); ++i) {
Chris@19 150 PropertyContainer *container = m_client->getPropertyContainer(i);
Chris@19 151 if (pc == container) return i;
Chris@19 152 }
Chris@19 153
Chris@19 154 return false;
Chris@19 155 }
Chris@19 156
Chris@0 157 void
Chris@0 158 PropertyStack::propertyContainerAdded(PropertyContainer *)
Chris@0 159 {
Chris@0 160 if (sender() != m_client) return;
Chris@0 161 repopulate();
Chris@0 162 }
Chris@0 163
Chris@0 164 void
Chris@0 165 PropertyStack::propertyContainerRemoved(PropertyContainer *)
Chris@0 166 {
Chris@0 167 if (sender() != m_client) return;
Chris@0 168 repopulate();
Chris@0 169 }
Chris@0 170
Chris@0 171 void
Chris@0 172 PropertyStack::propertyContainerPropertyChanged(PropertyContainer *pc)
Chris@0 173 {
Chris@298 174 Layer *layer = dynamic_cast<Layer *>(pc);
Chris@0 175 for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@0 176 if (pc == m_boxes[i]->getContainer()) {
Chris@0 177 m_boxes[i]->propertyContainerPropertyChanged(pc);
Chris@298 178 if (layer) {
Chris@298 179 m_boxes[i]->layerVisibilityChanged
Chris@298 180 (!layer->isLayerDormant(m_client));
Chris@298 181 }
Chris@0 182 }
Chris@0 183 }
Chris@0 184 }
Chris@0 185
Chris@0 186 void
Chris@197 187 PropertyStack::propertyContainerPropertyRangeChanged(PropertyContainer *pc)
Chris@197 188 {
Chris@197 189 for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@197 190 if (pc == m_boxes[i]->getContainer()) {
Chris@197 191 m_boxes[i]->propertyContainerPropertyRangeChanged(pc);
Chris@197 192 }
Chris@197 193 }
Chris@197 194 }
Chris@197 195
Chris@197 196 void
Chris@249 197 PropertyStack::propertyContainerNameChanged(PropertyContainer *)
Chris@0 198 {
Chris@0 199 if (sender() != m_client) return;
Chris@0 200 repopulate();
Chris@0 201 }
Chris@0 202
Chris@377 203 class ShowLayerCommand : public QObject, public Command
Chris@377 204 {
Chris@377 205 public:
Chris@397 206 ShowLayerCommand(View *view, Layer *layer, bool show, QString name) :
Chris@397 207 m_view(view), m_layer(layer), m_show(show), m_name(name) { }
Chris@377 208 void execute() {
Chris@377 209 m_layer->showLayer(m_view, m_show);
Chris@377 210 }
Chris@377 211 void unexecute() {
Chris@377 212 m_layer->showLayer(m_view, !m_show);
Chris@377 213 }
Chris@377 214 QString getName() const {
Chris@397 215 return m_name;
Chris@377 216 }
Chris@377 217 protected:
Chris@377 218 View *m_view;
Chris@377 219 Layer *m_layer;
Chris@377 220 bool m_show;
Chris@397 221 QString m_name;
Chris@377 222 };
Chris@377 223
Chris@0 224 void
Chris@47 225 PropertyStack::showLayer(bool show)
Chris@47 226 {
Chris@47 227 QObject *obj = sender();
Chris@47 228
Chris@47 229 for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@47 230 if (obj == m_boxes[i]) {
Chris@47 231 Layer *layer = dynamic_cast<Layer *>(m_boxes[i]->getContainer());
Chris@47 232 if (layer) {
Chris@377 233 CommandHistory::getInstance()->addCommand
Chris@397 234 (new ShowLayerCommand(m_client, layer, show,
Chris@397 235 tr("Change Layer Visibility")));
Chris@47 236 return;
Chris@47 237 }
Chris@47 238 }
Chris@47 239 }
Chris@47 240 }
Chris@47 241
Chris@47 242 void
Chris@0 243 PropertyStack::selectedContainerChanged(int n)
Chris@0 244 {
Chris@0 245 if (n >= int(m_boxes.size())) return;
Chris@52 246 emit propertyContainerSelected(m_client, m_boxes[n]->getContainer());
Chris@0 247 }
Chris@0 248
Chris@190 249 void
Chris@190 250 PropertyStack::mouseEnteredTabBar()
Chris@190 251 {
Chris@190 252 emit contextHelpChanged(tr("Click to change the current active layer"));
Chris@190 253 }
Chris@190 254
Chris@190 255 void
Chris@190 256 PropertyStack::mouseLeftTabBar()
Chris@190 257 {
Chris@190 258 emit contextHelpChanged("");
Chris@190 259 }
Chris@190 260
Chris@190 261 void
Chris@190 262 PropertyStack::activeTabClicked()
Chris@190 263 {
Chris@190 264 emit viewSelected(m_client);
Chris@190 265 }
Chris@190 266