svgui  1.9
PropertyStack.cpp
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7  This file copyright 2006 Chris Cannam.
8 
9  This program is free software; you can redistribute it and/or
10  modify it under the terms of the GNU General Public License as
11  published by the Free Software Foundation; either version 2 of the
12  License, or (at your option) any later version. See the file
13  COPYING included with this distribution for more information.
14 */
15 
16 #include "PropertyStack.h"
17 #include "PropertyBox.h"
18 #include "base/PropertyContainer.h"
19 #include "view/View.h"
20 #include "layer/Layer.h"
21 #include "layer/LayerFactory.h"
23 #include "widgets/IconLoader.h"
24 #include "base/Command.h"
25 #include "widgets/CommandHistory.h"
26 #include "layer/ShowLayerCommand.h"
27 
28 #include <QIcon>
29 #include <QTabWidget>
30 
31 #include <iostream>
32 
33 #define DEBUG_PROPERTY_STACK 1
34 
35 PropertyStack::PropertyStack(QWidget *parent, View *client) :
36  QTabWidget(parent),
37  m_client(client)
38 {
39  NotifyingTabBar *bar = new NotifyingTabBar();
40  bar->setDrawBase(false);
41 
42  connect(bar, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredTabBar()));
43  connect(bar, SIGNAL(mouseLeft()), this, SLOT(mouseLeftTabBar()));
44  connect(bar, SIGNAL(activeTabClicked()), this, SLOT(activeTabClicked()));
45 
46  setTabBar(bar);
47 
48 #if (QT_VERSION >= 0x0402)
49  setElideMode(Qt::ElideNone);
50  tabBar()->setUsesScrollButtons(true);
51  tabBar()->setIconSize(QSize(16, 16));
52 #endif
53 
54  repopulate();
55 
56  connect(this, SIGNAL(currentChanged(int)),
57  this, SLOT(selectedContainerChanged(int)));
58 
59  connect(m_client, SIGNAL(propertyContainerAdded(PropertyContainer *)),
60  this, SLOT(propertyContainerAdded(PropertyContainer *)));
61 
62  connect(m_client, SIGNAL(propertyContainerRemoved(PropertyContainer *)),
63  this, SLOT(propertyContainerRemoved(PropertyContainer *)));
64 
65  connect(m_client, SIGNAL(propertyContainerPropertyChanged(PropertyContainer *)),
66  this, SLOT(propertyContainerPropertyChanged(PropertyContainer *)));
67 
68  connect(m_client, SIGNAL(propertyContainerPropertyRangeChanged(PropertyContainer *)),
69  this, SLOT(propertyContainerPropertyRangeChanged(PropertyContainer *)));
70 
71  connect(m_client, SIGNAL(propertyContainerNameChanged(PropertyContainer *)),
72  this, SLOT(propertyContainerNameChanged(PropertyContainer *)));
73 
74  connect(this, SIGNAL(propertyContainerSelected(View *, PropertyContainer *)),
75  m_client, SLOT(propertyContainerSelected(View *, PropertyContainer *)));
76 }
77 
79 {
80 }
81 
82 void
84 {
85  blockSignals(true);
86 
87 #ifdef DEBUG_PROPERTY_STACK
88  cerr << "PropertyStack[" << this << "]::repopulate" << endl;
89 #endif
90 
91  while (count() > 0) {
92  removeTab(0);
93  }
94  for (size_t i = 0; i < m_boxes.size(); ++i) {
95  delete m_boxes[i];
96  }
97  m_boxes.clear();
98 
99  for (int i = 0; i < m_client->getPropertyContainerCount(); ++i) {
100 
101  PropertyContainer *container = m_client->getPropertyContainer(i);
102  QString name = container->getPropertyContainerName();
103 
104 #ifdef DEBUG_PROPERTY_STACK
105  cerr << "PropertyStack[" << this << "]::repopulate: client " << m_client
106  << " returns container " << container << " (name " << name
107  << ") at position " << i << endl;
108 #endif
109 
110  PropertyBox *box = new PropertyBox(container);
111 
112  connect(box, SIGNAL(showLayer(bool)), this, SLOT(showLayer(bool)));
113  connect(box, SIGNAL(contextHelpChanged(const QString &)),
114  this, SIGNAL(contextHelpChanged(const QString &)));
115 
116  Layer *layer = dynamic_cast<Layer *>(container);
117  if (layer) {
119  }
120 
121  QString shortName = name;
122 
123  if (layer) {
125  (LayerFactory::getInstance()->getLayerType(layer));
126  if (layer->getLayerPresentationName() != "") {
127  name = layer->getLayerPresentationName();
128  }
129  }
130 
131  bool nameDiffers = (name != shortName);
132  shortName = QString("&%1 %2").arg(i + 1).arg(shortName);
133 
134  QString iconName = container->getPropertyContainerIconName();
135 
136  QIcon icon(IconLoader().load(iconName));
137  if (icon.isNull()) {
138  addTab(box, shortName);
139  if (nameDiffers) {
140  setTabToolTip(i, name);
141  }
142  } else {
143  addTab(box, icon, QString("&%1").arg(i + 1));
144  setTabToolTip(i, name);
145  }
146 
147  m_boxes.push_back(box);
148  }
149 
150  blockSignals(false);
151 }
152 
153 bool
154 PropertyStack::containsContainer(PropertyContainer *pc) const
155 {
156  for (int i = 0; i < m_client->getPropertyContainerCount(); ++i) {
157  PropertyContainer *container = m_client->getPropertyContainer(i);
158  if (pc == container) return true;
159  }
160 
161  return false;
162 }
163 
164 int
165 PropertyStack::getContainerIndex(PropertyContainer *pc) const
166 {
167  // This is used to obtain an index to be passed to setCurrentIndex
168  // -- which is the index of the property container's box in our
169  // stack of boxes. That is not the same thing as the index of the
170  // container (i.e. the layer) in the view: the view reorders its
171  // containers whenever one is raised to the top, while our boxes
172  // remain in the same order. So we must find this container in the
173  // box list, not in the view.
174 
175  for (size_t i = 0; i < m_boxes.size(); ++i) {
176  PropertyContainer *container = m_boxes[i]->getContainer();
177  if (pc == container) {
178  return i;
179  }
180  }
181 
182  return false;
183 }
184 
185 void
187 {
188  if (sender() != m_client) return;
189  repopulate();
190 }
191 
192 void
194 {
195  if (sender() != m_client) return;
196  repopulate();
197 }
198 
199 void
201 {
202  Layer *layer = dynamic_cast<Layer *>(pc);
203  for (unsigned int i = 0; i < m_boxes.size(); ++i) {
204  if (pc == m_boxes[i]->getContainer()) {
205  m_boxes[i]->propertyContainerPropertyChanged(pc);
206  if (layer) {
207  m_boxes[i]->layerVisibilityChanged
208  (!layer->isLayerDormant(m_client));
209  }
210  }
211  }
212 }
213 
214 void
216 {
217  for (unsigned int i = 0; i < m_boxes.size(); ++i) {
218  if (pc == m_boxes[i]->getContainer()) {
219  m_boxes[i]->propertyContainerPropertyRangeChanged(pc);
220  }
221  }
222 }
223 
224 void
226 {
227  if (sender() != m_client) return;
228  repopulate();
229 }
230 
231 void
233 {
234  QObject *obj = sender();
235 
236  for (unsigned int i = 0; i < m_boxes.size(); ++i) {
237  if (obj == m_boxes[i]) {
238  Layer *layer = dynamic_cast<Layer *>(m_boxes[i]->getContainer());
239  if (layer) {
241  (new ShowLayerCommand(m_client, layer, show,
242  tr("Change Layer Visibility")));
243  return;
244  }
245  }
246  }
247 }
248 
249 void
251 {
252  if (n >= int(m_boxes.size())) return;
253  emit propertyContainerSelected(m_client, m_boxes[n]->getContainer());
254 }
255 
256 void
258 {
259  emit contextHelpChanged(tr("Click to change the current active layer"));
260 }
261 
262 void
264 {
265  emit contextHelpChanged("");
266 }
267 
268 void
270 {
271  emit viewSelected(m_client);
272 }
273 
static LayerFactory * getInstance()
void propertyContainerPropertyChanged(PropertyContainer *)
virtual const PropertyContainer * getPropertyContainer(int i) const
Definition: View.cpp:171
The base class for visual representations of the data found in a Model.
Definition: Layer.h:52
void mouseLeftTabBar()
void propertyContainerAdded(PropertyContainer *)
void activeTabClicked()
std::vector< PropertyBox * > m_boxes
Definition: PropertyStack.h:63
void viewSelected(View *client)
void showLayer(bool)
void addCommand(Command *command)
Add a command to the command history.
void selectedContainerChanged(int)
PropertyStack(QWidget *parent, View *client)
QString getLayerPresentationName(LayerType type)
void layerVisibilityChanged(bool)
void contextHelpChanged(const QString &)
virtual int getPropertyContainerCount() const
Definition: View.cpp:165
void propertyContainerRemoved(PropertyContainer *)
static CommandHistory * getInstance()
void propertyContainerPropertyRangeChanged(PropertyContainer *)
int getContainerIndex(PropertyContainer *container) const
void propertyContainerNameChanged(PropertyContainer *)
bool containsContainer(PropertyContainer *container) const
View is the base class of widgets that display one or more overlaid views of data against a horizonta...
Definition: View.h:50
virtual QString getLayerPresentationName() const
Definition: Layer.cpp:78
void mouseEnteredTabBar()
virtual bool isLayerDormant(const View *v) const
Return whether the layer is dormant (i.e.
Definition: Layer.cpp:126
void propertyContainerSelected(View *client, PropertyContainer *container)
virtual ~PropertyStack()