annotate widgets/PropertyStack.cpp @ 352:25e72328a897

* Add wave file model method for reading more than one channel at once, avoiding ludicrously expensive backward seeks and double-reads when playing multi-channel files or using them as inputs to feature extraction plugins
author Chris Cannam
date Thu, 24 Jan 2008 14:35:43 +0000
parents 226cb289bdf4
children d58701996fae
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@0 24
Chris@0 25 #include <QIcon>
Chris@0 26 #include <QTabWidget>
Chris@0 27
Chris@0 28 #include <iostream>
Chris@0 29
Chris@36 30 //#define DEBUG_PROPERTY_STACK 1
Chris@0 31
Chris@0 32 PropertyStack::PropertyStack(QWidget *parent, View *client) :
Chris@0 33 QTabWidget(parent),
Chris@0 34 m_client(client)
Chris@0 35 {
Chris@190 36 NotifyingTabBar *bar = new NotifyingTabBar();
Chris@190 37 bar->setDrawBase(false);
Chris@190 38
Chris@190 39 connect(bar, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredTabBar()));
Chris@190 40 connect(bar, SIGNAL(mouseLeft()), this, SLOT(mouseLeftTabBar()));
Chris@190 41 connect(bar, SIGNAL(activeTabClicked()), this, SLOT(activeTabClicked()));
Chris@190 42
Chris@190 43 setTabBar(bar);
Chris@190 44
Chris@242 45 #if (QT_VERSION >= 0x0402)
Chris@242 46 setElideMode(Qt::ElideNone);
Chris@241 47 tabBar()->setUsesScrollButtons(true);
Chris@241 48 tabBar()->setIconSize(QSize(16, 16));
Chris@242 49 #endif
Chris@239 50
Chris@0 51 repopulate();
Chris@0 52
Chris@0 53 connect(this, SIGNAL(currentChanged(int)),
Chris@0 54 this, SLOT(selectedContainerChanged(int)));
Chris@0 55
Chris@0 56 connect(m_client, SIGNAL(propertyContainerAdded(PropertyContainer *)),
Chris@0 57 this, SLOT(propertyContainerAdded(PropertyContainer *)));
Chris@0 58
Chris@0 59 connect(m_client, SIGNAL(propertyContainerRemoved(PropertyContainer *)),
Chris@0 60 this, SLOT(propertyContainerRemoved(PropertyContainer *)));
Chris@0 61
Chris@0 62 connect(m_client, SIGNAL(propertyContainerPropertyChanged(PropertyContainer *)),
Chris@0 63 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
Chris@0 64
Chris@197 65 connect(m_client, SIGNAL(propertyContainerPropertyRangeChanged(PropertyContainer *)),
Chris@197 66 this, SLOT(propertyContainerPropertyRangeChanged(PropertyContainer *)));
Chris@197 67
Chris@0 68 connect(m_client, SIGNAL(propertyContainerNameChanged(PropertyContainer *)),
Chris@0 69 this, SLOT(propertyContainerNameChanged(PropertyContainer *)));
Chris@0 70
Chris@52 71 connect(this, SIGNAL(propertyContainerSelected(View *, PropertyContainer *)),
Chris@52 72 m_client, SLOT(propertyContainerSelected(View *, PropertyContainer *)));
Chris@0 73 }
Chris@0 74
Chris@0 75 void
Chris@0 76 PropertyStack::repopulate()
Chris@0 77 {
Chris@0 78 blockSignals(true);
Chris@0 79
Chris@0 80 #ifdef DEBUG_PROPERTY_STACK
Chris@0 81 std::cerr << "PropertyStack::repopulate" << std::endl;
Chris@0 82 #endif
Chris@0 83
Chris@0 84 while (count() > 0) {
Chris@0 85 removeTab(0);
Chris@0 86 }
Chris@0 87 for (size_t i = 0; i < m_boxes.size(); ++i) {
Chris@0 88 delete m_boxes[i];
Chris@0 89 }
Chris@0 90 m_boxes.clear();
Chris@0 91
Chris@0 92 for (size_t i = 0; i < m_client->getPropertyContainerCount(); ++i) {
Chris@0 93
Chris@0 94 PropertyContainer *container = m_client->getPropertyContainer(i);
Chris@0 95 QString name = container->getPropertyContainerName();
Chris@0 96
Chris@0 97 PropertyBox *box = new PropertyBox(container);
Chris@0 98
Chris@47 99 connect(box, SIGNAL(showLayer(bool)), this, SLOT(showLayer(bool)));
Chris@189 100 connect(box, SIGNAL(contextHelpChanged(const QString &)),
Chris@189 101 this, SIGNAL(contextHelpChanged(const QString &)));
Chris@47 102
Chris@185 103 Layer *layer = dynamic_cast<Layer *>(container);
Chris@185 104 if (layer) {
Chris@185 105 box->layerVisibilityChanged(!layer->isLayerDormant(m_client));
Chris@185 106 }
Chris@185 107
Chris@242 108 QString shortName = name;
Chris@242 109
Chris@242 110 if (layer) {
Chris@242 111 shortName = LayerFactory::getInstance()->getLayerPresentationName
Chris@242 112 (LayerFactory::getInstance()->getLayerType(layer));
Chris@242 113 }
Chris@242 114
Chris@242 115 shortName = QString("&%1 %2").arg(i + 1).arg(shortName);
Chris@242 116
Chris@352 117 //!!! We'll comment this out until it's been tested with Qt 4.3.3
Chris@352 118 #ifdef Q_WS_MAC___NOT_DEFINED
Chris@242 119
Chris@242 120 // Qt 4.2 on OS/X doesn't show the icons in the tab bar, and
Chris@242 121 // I'm not sure why -- use labels instead
Chris@242 122
Chris@242 123 addTab(box, shortName);
Chris@352 124
Chris@242 125 #else
Chris@242 126
Chris@242 127 // Icons on other platforms
Chris@242 128
Chris@242 129 QString iconName = container->getPropertyContainerIconName();
Chris@242 130
Chris@289 131 QIcon icon(IconLoader().load(iconName));
Chris@0 132 if (icon.isNull()) {
Chris@242 133 addTab(box, shortName);
Chris@0 134 } else {
Chris@0 135 addTab(box, icon, QString("&%1").arg(i + 1));
Chris@242 136 setTabToolTip(i, name);
Chris@0 137 }
Chris@0 138
Chris@242 139 #endif
Chris@242 140
Chris@0 141 m_boxes.push_back(box);
Chris@0 142 }
Chris@0 143
Chris@0 144 blockSignals(false);
Chris@0 145 }
Chris@0 146
Chris@0 147 bool
Chris@0 148 PropertyStack::containsContainer(PropertyContainer *pc) const
Chris@0 149 {
Chris@0 150 for (size_t i = 0; i < m_client->getPropertyContainerCount(); ++i) {
Chris@0 151 PropertyContainer *container = m_client->getPropertyContainer(i);
Chris@0 152 if (pc == container) return true;
Chris@0 153 }
Chris@0 154
Chris@0 155 return false;
Chris@0 156 }
Chris@0 157
Chris@19 158 int
Chris@19 159 PropertyStack::getContainerIndex(PropertyContainer *pc) const
Chris@19 160 {
Chris@19 161 for (size_t i = 0; i < m_client->getPropertyContainerCount(); ++i) {
Chris@19 162 PropertyContainer *container = m_client->getPropertyContainer(i);
Chris@19 163 if (pc == container) return i;
Chris@19 164 }
Chris@19 165
Chris@19 166 return false;
Chris@19 167 }
Chris@19 168
Chris@0 169 void
Chris@0 170 PropertyStack::propertyContainerAdded(PropertyContainer *)
Chris@0 171 {
Chris@0 172 if (sender() != m_client) return;
Chris@0 173 repopulate();
Chris@0 174 }
Chris@0 175
Chris@0 176 void
Chris@0 177 PropertyStack::propertyContainerRemoved(PropertyContainer *)
Chris@0 178 {
Chris@0 179 if (sender() != m_client) return;
Chris@0 180 repopulate();
Chris@0 181 }
Chris@0 182
Chris@0 183 void
Chris@0 184 PropertyStack::propertyContainerPropertyChanged(PropertyContainer *pc)
Chris@0 185 {
Chris@298 186 Layer *layer = dynamic_cast<Layer *>(pc);
Chris@0 187 for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@0 188 if (pc == m_boxes[i]->getContainer()) {
Chris@0 189 m_boxes[i]->propertyContainerPropertyChanged(pc);
Chris@298 190 if (layer) {
Chris@298 191 m_boxes[i]->layerVisibilityChanged
Chris@298 192 (!layer->isLayerDormant(m_client));
Chris@298 193 }
Chris@0 194 }
Chris@0 195 }
Chris@0 196 }
Chris@0 197
Chris@0 198 void
Chris@197 199 PropertyStack::propertyContainerPropertyRangeChanged(PropertyContainer *pc)
Chris@197 200 {
Chris@197 201 for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@197 202 if (pc == m_boxes[i]->getContainer()) {
Chris@197 203 m_boxes[i]->propertyContainerPropertyRangeChanged(pc);
Chris@197 204 }
Chris@197 205 }
Chris@197 206 }
Chris@197 207
Chris@197 208 void
Chris@249 209 PropertyStack::propertyContainerNameChanged(PropertyContainer *)
Chris@0 210 {
Chris@0 211 if (sender() != m_client) return;
Chris@0 212 repopulate();
Chris@0 213 }
Chris@0 214
Chris@0 215 void
Chris@47 216 PropertyStack::showLayer(bool show)
Chris@47 217 {
Chris@47 218 QObject *obj = sender();
Chris@47 219
Chris@47 220 for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@47 221 if (obj == m_boxes[i]) {
Chris@47 222 Layer *layer = dynamic_cast<Layer *>(m_boxes[i]->getContainer());
Chris@47 223 if (layer) {
Chris@47 224 layer->showLayer(m_client, show);
Chris@47 225 return;
Chris@47 226 }
Chris@47 227 }
Chris@47 228 }
Chris@47 229 }
Chris@47 230
Chris@47 231 void
Chris@0 232 PropertyStack::selectedContainerChanged(int n)
Chris@0 233 {
Chris@0 234 if (n >= int(m_boxes.size())) return;
Chris@52 235 emit propertyContainerSelected(m_client, m_boxes[n]->getContainer());
Chris@0 236 }
Chris@0 237
Chris@190 238 void
Chris@190 239 PropertyStack::mouseEnteredTabBar()
Chris@190 240 {
Chris@190 241 emit contextHelpChanged(tr("Click to change the current active layer"));
Chris@190 242 }
Chris@190 243
Chris@190 244 void
Chris@190 245 PropertyStack::mouseLeftTabBar()
Chris@190 246 {
Chris@190 247 emit contextHelpChanged("");
Chris@190 248 }
Chris@190 249
Chris@190 250 void
Chris@190 251 PropertyStack::activeTabClicked()
Chris@190 252 {
Chris@190 253 emit viewSelected(m_client);
Chris@190 254 }
Chris@190 255