annotate widgets/PropertyStack.cpp @ 378:22b72f0f6a4e

* More work to abstract out interactive components used in the data library, so that it does not need to depend on QtGui.
author Chris Cannam
date Fri, 14 Mar 2008 17:14:21 +0000
parents 0bcb449d15f4
children 2c59b0cd176b
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@377 206 ShowLayerCommand(View *view, Layer *layer, bool show) :
Chris@377 207 m_view(view), m_layer(layer), m_show(show) { }
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@377 215 return tr("Change Layer Visibility");
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@377 221 };
Chris@377 222
Chris@0 223 void
Chris@47 224 PropertyStack::showLayer(bool show)
Chris@47 225 {
Chris@47 226 QObject *obj = sender();
Chris@47 227
Chris@47 228 for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@47 229 if (obj == m_boxes[i]) {
Chris@47 230 Layer *layer = dynamic_cast<Layer *>(m_boxes[i]->getContainer());
Chris@47 231 if (layer) {
Chris@377 232 CommandHistory::getInstance()->addCommand
Chris@377 233 (new ShowLayerCommand(m_client, layer, show));
Chris@47 234 return;
Chris@47 235 }
Chris@47 236 }
Chris@47 237 }
Chris@47 238 }
Chris@47 239
Chris@47 240 void
Chris@0 241 PropertyStack::selectedContainerChanged(int n)
Chris@0 242 {
Chris@0 243 if (n >= int(m_boxes.size())) return;
Chris@52 244 emit propertyContainerSelected(m_client, m_boxes[n]->getContainer());
Chris@0 245 }
Chris@0 246
Chris@190 247 void
Chris@190 248 PropertyStack::mouseEnteredTabBar()
Chris@190 249 {
Chris@190 250 emit contextHelpChanged(tr("Click to change the current active layer"));
Chris@190 251 }
Chris@190 252
Chris@190 253 void
Chris@190 254 PropertyStack::mouseLeftTabBar()
Chris@190 255 {
Chris@190 256 emit contextHelpChanged("");
Chris@190 257 }
Chris@190 258
Chris@190 259 void
Chris@190 260 PropertyStack::activeTabClicked()
Chris@190 261 {
Chris@190 262 emit viewSelected(m_client);
Chris@190 263 }
Chris@190 264