svgui
1.9
|
00001 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ 00002 00003 /* 00004 Sonic Visualiser 00005 An audio file viewer and annotation editor. 00006 Centre for Digital Music, Queen Mary, University of London. 00007 This file copyright 2006 Chris Cannam. 00008 00009 This program is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU General Public License as 00011 published by the Free Software Foundation; either version 2 of the 00012 License, or (at your option) any later version. See the file 00013 COPYING included with this distribution for more information. 00014 */ 00015 00016 #include "PropertyStack.h" 00017 #include "PropertyBox.h" 00018 #include "base/PropertyContainer.h" 00019 #include "view/View.h" 00020 #include "layer/Layer.h" 00021 #include "layer/LayerFactory.h" 00022 #include "widgets/NotifyingTabBar.h" 00023 #include "widgets/IconLoader.h" 00024 #include "base/Command.h" 00025 #include "widgets/CommandHistory.h" 00026 #include "layer/ShowLayerCommand.h" 00027 00028 #include <QIcon> 00029 #include <QTabWidget> 00030 00031 #include <iostream> 00032 00033 #define DEBUG_PROPERTY_STACK 1 00034 00035 PropertyStack::PropertyStack(QWidget *parent, View *client) : 00036 QTabWidget(parent), 00037 m_client(client) 00038 { 00039 NotifyingTabBar *bar = new NotifyingTabBar(); 00040 bar->setDrawBase(false); 00041 00042 connect(bar, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredTabBar())); 00043 connect(bar, SIGNAL(mouseLeft()), this, SLOT(mouseLeftTabBar())); 00044 connect(bar, SIGNAL(activeTabClicked()), this, SLOT(activeTabClicked())); 00045 00046 setTabBar(bar); 00047 00048 #if (QT_VERSION >= 0x0402) 00049 setElideMode(Qt::ElideNone); 00050 tabBar()->setUsesScrollButtons(true); 00051 tabBar()->setIconSize(QSize(16, 16)); 00052 #endif 00053 00054 repopulate(); 00055 00056 connect(this, SIGNAL(currentChanged(int)), 00057 this, SLOT(selectedContainerChanged(int))); 00058 00059 connect(m_client, SIGNAL(propertyContainerAdded(PropertyContainer *)), 00060 this, SLOT(propertyContainerAdded(PropertyContainer *))); 00061 00062 connect(m_client, SIGNAL(propertyContainerRemoved(PropertyContainer *)), 00063 this, SLOT(propertyContainerRemoved(PropertyContainer *))); 00064 00065 connect(m_client, SIGNAL(propertyContainerPropertyChanged(PropertyContainer *)), 00066 this, SLOT(propertyContainerPropertyChanged(PropertyContainer *))); 00067 00068 connect(m_client, SIGNAL(propertyContainerPropertyRangeChanged(PropertyContainer *)), 00069 this, SLOT(propertyContainerPropertyRangeChanged(PropertyContainer *))); 00070 00071 connect(m_client, SIGNAL(propertyContainerNameChanged(PropertyContainer *)), 00072 this, SLOT(propertyContainerNameChanged(PropertyContainer *))); 00073 00074 connect(this, SIGNAL(propertyContainerSelected(View *, PropertyContainer *)), 00075 m_client, SLOT(propertyContainerSelected(View *, PropertyContainer *))); 00076 } 00077 00078 PropertyStack::~PropertyStack() 00079 { 00080 } 00081 00082 void 00083 PropertyStack::repopulate() 00084 { 00085 blockSignals(true); 00086 00087 #ifdef DEBUG_PROPERTY_STACK 00088 cerr << "PropertyStack[" << this << "]::repopulate" << endl; 00089 #endif 00090 00091 while (count() > 0) { 00092 removeTab(0); 00093 } 00094 for (size_t i = 0; i < m_boxes.size(); ++i) { 00095 delete m_boxes[i]; 00096 } 00097 m_boxes.clear(); 00098 00099 for (int i = 0; i < m_client->getPropertyContainerCount(); ++i) { 00100 00101 PropertyContainer *container = m_client->getPropertyContainer(i); 00102 QString name = container->getPropertyContainerName(); 00103 00104 #ifdef DEBUG_PROPERTY_STACK 00105 cerr << "PropertyStack[" << this << "]::repopulate: client " << m_client 00106 << " returns container " << container << " (name " << name 00107 << ") at position " << i << endl; 00108 #endif 00109 00110 PropertyBox *box = new PropertyBox(container); 00111 00112 connect(box, SIGNAL(showLayer(bool)), this, SLOT(showLayer(bool))); 00113 connect(box, SIGNAL(contextHelpChanged(const QString &)), 00114 this, SIGNAL(contextHelpChanged(const QString &))); 00115 00116 Layer *layer = dynamic_cast<Layer *>(container); 00117 if (layer) { 00118 box->layerVisibilityChanged(!layer->isLayerDormant(m_client)); 00119 } 00120 00121 QString shortName = name; 00122 00123 if (layer) { 00124 shortName = LayerFactory::getInstance()->getLayerPresentationName 00125 (LayerFactory::getInstance()->getLayerType(layer)); 00126 if (layer->getLayerPresentationName() != "") { 00127 name = layer->getLayerPresentationName(); 00128 } 00129 } 00130 00131 bool nameDiffers = (name != shortName); 00132 shortName = QString("&%1 %2").arg(i + 1).arg(shortName); 00133 00134 QString iconName = container->getPropertyContainerIconName(); 00135 00136 QIcon icon(IconLoader().load(iconName)); 00137 if (icon.isNull()) { 00138 addTab(box, shortName); 00139 if (nameDiffers) { 00140 setTabToolTip(i, name); 00141 } 00142 } else { 00143 addTab(box, icon, QString("&%1").arg(i + 1)); 00144 setTabToolTip(i, name); 00145 } 00146 00147 m_boxes.push_back(box); 00148 } 00149 00150 blockSignals(false); 00151 } 00152 00153 bool 00154 PropertyStack::containsContainer(PropertyContainer *pc) const 00155 { 00156 for (int i = 0; i < m_client->getPropertyContainerCount(); ++i) { 00157 PropertyContainer *container = m_client->getPropertyContainer(i); 00158 if (pc == container) return true; 00159 } 00160 00161 return false; 00162 } 00163 00164 int 00165 PropertyStack::getContainerIndex(PropertyContainer *pc) const 00166 { 00167 // This is used to obtain an index to be passed to setCurrentIndex 00168 // -- which is the index of the property container's box in our 00169 // stack of boxes. That is not the same thing as the index of the 00170 // container (i.e. the layer) in the view: the view reorders its 00171 // containers whenever one is raised to the top, while our boxes 00172 // remain in the same order. So we must find this container in the 00173 // box list, not in the view. 00174 00175 for (size_t i = 0; i < m_boxes.size(); ++i) { 00176 PropertyContainer *container = m_boxes[i]->getContainer(); 00177 if (pc == container) { 00178 return i; 00179 } 00180 } 00181 00182 return false; 00183 } 00184 00185 void 00186 PropertyStack::propertyContainerAdded(PropertyContainer *) 00187 { 00188 if (sender() != m_client) return; 00189 repopulate(); 00190 } 00191 00192 void 00193 PropertyStack::propertyContainerRemoved(PropertyContainer *) 00194 { 00195 if (sender() != m_client) return; 00196 repopulate(); 00197 } 00198 00199 void 00200 PropertyStack::propertyContainerPropertyChanged(PropertyContainer *pc) 00201 { 00202 Layer *layer = dynamic_cast<Layer *>(pc); 00203 for (unsigned int i = 0; i < m_boxes.size(); ++i) { 00204 if (pc == m_boxes[i]->getContainer()) { 00205 m_boxes[i]->propertyContainerPropertyChanged(pc); 00206 if (layer) { 00207 m_boxes[i]->layerVisibilityChanged 00208 (!layer->isLayerDormant(m_client)); 00209 } 00210 } 00211 } 00212 } 00213 00214 void 00215 PropertyStack::propertyContainerPropertyRangeChanged(PropertyContainer *pc) 00216 { 00217 for (unsigned int i = 0; i < m_boxes.size(); ++i) { 00218 if (pc == m_boxes[i]->getContainer()) { 00219 m_boxes[i]->propertyContainerPropertyRangeChanged(pc); 00220 } 00221 } 00222 } 00223 00224 void 00225 PropertyStack::propertyContainerNameChanged(PropertyContainer *) 00226 { 00227 if (sender() != m_client) return; 00228 repopulate(); 00229 } 00230 00231 void 00232 PropertyStack::showLayer(bool show) 00233 { 00234 QObject *obj = sender(); 00235 00236 for (unsigned int i = 0; i < m_boxes.size(); ++i) { 00237 if (obj == m_boxes[i]) { 00238 Layer *layer = dynamic_cast<Layer *>(m_boxes[i]->getContainer()); 00239 if (layer) { 00240 CommandHistory::getInstance()->addCommand 00241 (new ShowLayerCommand(m_client, layer, show, 00242 tr("Change Layer Visibility"))); 00243 return; 00244 } 00245 } 00246 } 00247 } 00248 00249 void 00250 PropertyStack::selectedContainerChanged(int n) 00251 { 00252 if (n >= int(m_boxes.size())) return; 00253 emit propertyContainerSelected(m_client, m_boxes[n]->getContainer()); 00254 } 00255 00256 void 00257 PropertyStack::mouseEnteredTabBar() 00258 { 00259 emit contextHelpChanged(tr("Click to change the current active layer")); 00260 } 00261 00262 void 00263 PropertyStack::mouseLeftTabBar() 00264 { 00265 emit contextHelpChanged(""); 00266 } 00267 00268 void 00269 PropertyStack::activeTabClicked() 00270 { 00271 emit viewSelected(m_client); 00272 } 00273