annotate widgets/PropertyStack.cpp @ 735:1640a7c753cc tonioni

Short-circuit test for enough space for label -- drastically reduces lag on os/x with qt4
author Chris Cannam
date Thu, 06 Mar 2014 09:43:18 +0000
parents 558c71a802d4
children b6dc57688c72
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@732 26 #include "layer/ShowLayerCommand.h"
Chris@0 27
Chris@0 28 #include <QIcon>
Chris@0 29 #include <QTabWidget>
Chris@0 30
Chris@0 31 #include <iostream>
Chris@0 32
Chris@36 33 //#define DEBUG_PROPERTY_STACK 1
Chris@0 34
Chris@0 35 PropertyStack::PropertyStack(QWidget *parent, View *client) :
Chris@0 36 QTabWidget(parent),
Chris@0 37 m_client(client)
Chris@0 38 {
Chris@190 39 NotifyingTabBar *bar = new NotifyingTabBar();
Chris@190 40 bar->setDrawBase(false);
Chris@190 41
Chris@190 42 connect(bar, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredTabBar()));
Chris@190 43 connect(bar, SIGNAL(mouseLeft()), this, SLOT(mouseLeftTabBar()));
Chris@190 44 connect(bar, SIGNAL(activeTabClicked()), this, SLOT(activeTabClicked()));
Chris@190 45
Chris@190 46 setTabBar(bar);
Chris@190 47
Chris@242 48 #if (QT_VERSION >= 0x0402)
Chris@242 49 setElideMode(Qt::ElideNone);
Chris@241 50 tabBar()->setUsesScrollButtons(true);
Chris@241 51 tabBar()->setIconSize(QSize(16, 16));
Chris@242 52 #endif
Chris@239 53
Chris@0 54 repopulate();
Chris@0 55
Chris@0 56 connect(this, SIGNAL(currentChanged(int)),
Chris@0 57 this, SLOT(selectedContainerChanged(int)));
Chris@0 58
Chris@0 59 connect(m_client, SIGNAL(propertyContainerAdded(PropertyContainer *)),
Chris@0 60 this, SLOT(propertyContainerAdded(PropertyContainer *)));
Chris@0 61
Chris@0 62 connect(m_client, SIGNAL(propertyContainerRemoved(PropertyContainer *)),
Chris@0 63 this, SLOT(propertyContainerRemoved(PropertyContainer *)));
Chris@0 64
Chris@0 65 connect(m_client, SIGNAL(propertyContainerPropertyChanged(PropertyContainer *)),
Chris@0 66 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
Chris@0 67
Chris@197 68 connect(m_client, SIGNAL(propertyContainerPropertyRangeChanged(PropertyContainer *)),
Chris@197 69 this, SLOT(propertyContainerPropertyRangeChanged(PropertyContainer *)));
Chris@197 70
Chris@0 71 connect(m_client, SIGNAL(propertyContainerNameChanged(PropertyContainer *)),
Chris@0 72 this, SLOT(propertyContainerNameChanged(PropertyContainer *)));
Chris@0 73
Chris@52 74 connect(this, SIGNAL(propertyContainerSelected(View *, PropertyContainer *)),
Chris@52 75 m_client, SLOT(propertyContainerSelected(View *, PropertyContainer *)));
Chris@0 76 }
Chris@0 77
Chris@728 78 PropertyStack::~PropertyStack()
Chris@728 79 {
Chris@728 80 }
Chris@728 81
Chris@0 82 void
Chris@0 83 PropertyStack::repopulate()
Chris@0 84 {
Chris@0 85 blockSignals(true);
Chris@0 86
Chris@0 87 #ifdef DEBUG_PROPERTY_STACK
Chris@587 88 SVDEBUG << "PropertyStack::repopulate" << endl;
Chris@0 89 #endif
Chris@0 90
Chris@0 91 while (count() > 0) {
Chris@0 92 removeTab(0);
Chris@0 93 }
Chris@0 94 for (size_t i = 0; i < m_boxes.size(); ++i) {
Chris@0 95 delete m_boxes[i];
Chris@0 96 }
Chris@0 97 m_boxes.clear();
Chris@0 98
Chris@0 99 for (size_t i = 0; i < m_client->getPropertyContainerCount(); ++i) {
Chris@0 100
Chris@0 101 PropertyContainer *container = m_client->getPropertyContainer(i);
Chris@0 102 QString name = container->getPropertyContainerName();
Chris@0 103
Chris@0 104 PropertyBox *box = new PropertyBox(container);
Chris@0 105
Chris@47 106 connect(box, SIGNAL(showLayer(bool)), this, SLOT(showLayer(bool)));
Chris@189 107 connect(box, SIGNAL(contextHelpChanged(const QString &)),
Chris@189 108 this, SIGNAL(contextHelpChanged(const QString &)));
Chris@47 109
Chris@185 110 Layer *layer = dynamic_cast<Layer *>(container);
Chris@185 111 if (layer) {
Chris@185 112 box->layerVisibilityChanged(!layer->isLayerDormant(m_client));
Chris@185 113 }
Chris@185 114
Chris@242 115 QString shortName = name;
Chris@242 116
Chris@242 117 if (layer) {
Chris@242 118 shortName = LayerFactory::getInstance()->getLayerPresentationName
Chris@242 119 (LayerFactory::getInstance()->getLayerType(layer));
Chris@552 120 if (layer->getLayerPresentationName() != "") {
Chris@552 121 name = layer->getLayerPresentationName();
Chris@552 122 }
Chris@242 123 }
Chris@242 124
Chris@552 125 bool nameDiffers = (name != shortName);
Chris@242 126 shortName = QString("&%1 %2").arg(i + 1).arg(shortName);
Chris@242 127
Chris@242 128 QString iconName = container->getPropertyContainerIconName();
Chris@242 129
Chris@289 130 QIcon icon(IconLoader().load(iconName));
Chris@0 131 if (icon.isNull()) {
Chris@242 132 addTab(box, shortName);
Chris@552 133 if (nameDiffers) {
Chris@552 134 setTabToolTip(i, name);
Chris@552 135 }
Chris@0 136 } else {
Chris@0 137 addTab(box, icon, QString("&%1").arg(i + 1));
Chris@242 138 setTabToolTip(i, name);
Chris@0 139 }
Chris@0 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@723 161 // This is used to obtain an index to be passed to setCurrentIndex
Chris@723 162 // -- which is the index of the property container's box in our
Chris@723 163 // stack of boxes. That is not the same thing as the index of the
Chris@723 164 // container (i.e. the layer) in the view: the view reorders its
Chris@723 165 // containers whenever one is raised to the top, while our boxes
Chris@723 166 // remain in the same order. So we must find this container in the
Chris@723 167 // box list, not in the view.
Chris@723 168
Chris@723 169 for (size_t i = 0; i < m_boxes.size(); ++i) {
Chris@723 170 PropertyContainer *container = m_boxes[i]->getContainer();
Chris@723 171 if (pc == container) {
Chris@723 172 return i;
Chris@723 173 }
Chris@19 174 }
Chris@19 175
Chris@19 176 return false;
Chris@19 177 }
Chris@19 178
Chris@0 179 void
Chris@0 180 PropertyStack::propertyContainerAdded(PropertyContainer *)
Chris@0 181 {
Chris@0 182 if (sender() != m_client) return;
Chris@0 183 repopulate();
Chris@0 184 }
Chris@0 185
Chris@0 186 void
Chris@0 187 PropertyStack::propertyContainerRemoved(PropertyContainer *)
Chris@0 188 {
Chris@0 189 if (sender() != m_client) return;
Chris@0 190 repopulate();
Chris@0 191 }
Chris@0 192
Chris@0 193 void
Chris@0 194 PropertyStack::propertyContainerPropertyChanged(PropertyContainer *pc)
Chris@0 195 {
Chris@298 196 Layer *layer = dynamic_cast<Layer *>(pc);
Chris@0 197 for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@0 198 if (pc == m_boxes[i]->getContainer()) {
Chris@0 199 m_boxes[i]->propertyContainerPropertyChanged(pc);
Chris@298 200 if (layer) {
Chris@298 201 m_boxes[i]->layerVisibilityChanged
Chris@298 202 (!layer->isLayerDormant(m_client));
Chris@298 203 }
Chris@0 204 }
Chris@0 205 }
Chris@0 206 }
Chris@0 207
Chris@0 208 void
Chris@197 209 PropertyStack::propertyContainerPropertyRangeChanged(PropertyContainer *pc)
Chris@197 210 {
Chris@197 211 for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@197 212 if (pc == m_boxes[i]->getContainer()) {
Chris@197 213 m_boxes[i]->propertyContainerPropertyRangeChanged(pc);
Chris@197 214 }
Chris@197 215 }
Chris@197 216 }
Chris@197 217
Chris@197 218 void
Chris@249 219 PropertyStack::propertyContainerNameChanged(PropertyContainer *)
Chris@0 220 {
Chris@0 221 if (sender() != m_client) return;
Chris@0 222 repopulate();
Chris@0 223 }
Chris@0 224
Chris@0 225 void
Chris@47 226 PropertyStack::showLayer(bool show)
Chris@47 227 {
Chris@47 228 QObject *obj = sender();
Chris@47 229
Chris@47 230 for (unsigned int i = 0; i < m_boxes.size(); ++i) {
Chris@47 231 if (obj == m_boxes[i]) {
Chris@47 232 Layer *layer = dynamic_cast<Layer *>(m_boxes[i]->getContainer());
Chris@47 233 if (layer) {
Chris@377 234 CommandHistory::getInstance()->addCommand
Chris@397 235 (new ShowLayerCommand(m_client, layer, show,
Chris@397 236 tr("Change Layer Visibility")));
Chris@47 237 return;
Chris@47 238 }
Chris@47 239 }
Chris@47 240 }
Chris@47 241 }
Chris@47 242
Chris@47 243 void
Chris@0 244 PropertyStack::selectedContainerChanged(int n)
Chris@0 245 {
Chris@0 246 if (n >= int(m_boxes.size())) return;
Chris@52 247 emit propertyContainerSelected(m_client, m_boxes[n]->getContainer());
Chris@0 248 }
Chris@0 249
Chris@190 250 void
Chris@190 251 PropertyStack::mouseEnteredTabBar()
Chris@190 252 {
Chris@190 253 emit contextHelpChanged(tr("Click to change the current active layer"));
Chris@190 254 }
Chris@190 255
Chris@190 256 void
Chris@190 257 PropertyStack::mouseLeftTabBar()
Chris@190 258 {
Chris@190 259 emit contextHelpChanged("");
Chris@190 260 }
Chris@190 261
Chris@190 262 void
Chris@190 263 PropertyStack::activeTabClicked()
Chris@190 264 {
Chris@190 265 emit viewSelected(m_client);
Chris@190 266 }
Chris@190 267