svcore  1.9
PropertyContainer.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 and QMUL.
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 "PropertyContainer.h"
17 #include "RangeMapper.h"
18 #include "UnitDatabase.h"
19 
20 #include <iostream>
21 
24 {
25  return PropertyList();
26 }
27 
30 {
31  return InvalidProperty;
32 }
33 
34 QString
36 {
37  return QString();
38 }
39 
40 QString
42 {
43  return QString();
44 }
45 
46 int
48  int *min, int *max, int *deflt) const
49 {
50  if (min) *min = 0;
51  if (max) *max = 0;
52  if (deflt) *deflt = 0;
53  return 0;
54 }
55 
56 QString
58 {
59  return QString();
60 }
61 
64 {
65  return 0;
66 }
67 
68 void
70 {
71  cerr << "WARNING: PropertyContainer[" << getPropertyContainerName() << "]::setProperty(" << name << "): no implementation in subclass!" << endl;
72 }
73 
74 Command *
76 {
77  int currentValue = getPropertyRangeAndValue(name, 0, 0, 0);
78  if (value == currentValue) return 0;
79  return new SetPropertyCommand(this, name, value);
80 }
81 
82 void
83 PropertyContainer::setPropertyFuzzy(QString nameString, QString valueString)
84 {
85  PropertyName name;
86  int value;
87  if (!convertPropertyStrings(nameString, valueString, name, value)) {
88  cerr << "WARNING: PropertyContainer::setProperty(\""
89  << nameString << "\", \""
90  << valueString
91  << "\"): Name and value conversion failed" << endl;
92  return;
93  }
94  setProperty(name, value);
95 }
96 
97 Command *
98 PropertyContainer::getSetPropertyCommand(QString nameString, QString valueString)
99 {
100  PropertyName name;
101  int value;
102  if (!convertPropertyStrings(nameString, valueString, name, value)) {
103  cerr << "WARNING: PropertyContainer::getSetPropertyCommand(\""
104  << nameString << "\", \""
105  << valueString
106  << "\"): Name and value conversion failed" << endl;
107  return 0;
108  }
109  return getSetPropertyCommand(name, value);
110 }
111 
112 bool
113 PropertyContainer::convertPropertyStrings(QString nameString, QString valueString,
114  PropertyName &name, int &value)
115 {
117 
118  QString adjusted = nameString.trimmed();
119  adjusted.replace('_', ' ');
120  adjusted.replace('-', ' ');
121 
122  name = "";
123 
124  for (PropertyList::iterator pli = pl.begin(); pli != pl.end(); ++pli) {
125 
126  QString label = getPropertyLabel(*pli);
127 
128  if (label != "" && (nameString == label || adjusted == label)) {
129  name = *pli;
130  break;
131  } else if (nameString == *pli) {
132  name = *pli;
133  break;
134  }
135  }
136 
137  if (name == "") {
138  cerr << "PropertyContainer::convertPropertyStrings: Unable to match name string \"" << nameString << "\"" << endl;
139  return false;
140  }
141 
142  value = 0;
143  bool success = false;
144 
145  bool isDouble = false;
146  double dval = valueString.toDouble(&isDouble);
147 
148  switch (getPropertyType(name)) {
149 
150  case ToggleProperty:
151  if (valueString == tr("yes") ||
152  valueString == tr("on") ||
153  valueString == tr("true")) {
154  value = 1; success = true;
155  } else if (valueString == tr("no") ||
156  valueString == tr("off") ||
157  valueString == tr("false")) {
158  value = 0; success = true;
159  }
160  break;
161 
162  case RangeProperty:
163  if (isDouble) {
164  RangeMapper *mapper = getNewPropertyRangeMapper(name);
165  if (mapper) {
166  value = mapper->getPositionForValue(dval);
167  delete mapper;
168  success = true;
169  }
170  }
171  break;
172 
173  case ValueProperty:
174  case ColourProperty:
175  {
176  int min, max;
177  getPropertyRangeAndValue(name, &min, &max, 0);
178  for (int i = min; i <= max; ++i) {
179  if (valueString == getPropertyValueLabel(name, i)) {
180  value = i;
181  success = true;
182  break;
183  }
184  }
185  break;
186  }
187 
188  case UnitsProperty:
189  value = UnitDatabase::getInstance()->getUnitId(valueString, false);
190  if (value >= 0) success = true;
191  else value = 0;
192  break;
193 
194  case InvalidProperty:
195  SVDEBUG << "PropertyContainer::convertPropertyStrings: Invalid property name \"" << name << "\"" << endl;
196  return false;
197  }
198 
199  if (success) return true;
200 
201  int min, max;
202  getPropertyRangeAndValue(name, &min, &max, 0);
203 
204  bool ok = false;
205  int i = valueString.toInt(&ok);
206  if (!ok) {
207  cerr << "PropertyContainer::convertPropertyStrings: Unable to parse value string \"" << valueString << "\"" << endl;
208  return false;
209  } else if (i < min || i > max) {
210  SVDEBUG << "PropertyContainer::convertPropertyStrings: Property value \"" << i << "\" outside valid range " << min << " to " << max << endl;
211  return false;
212  }
213 
214  value = i;
215  return true;
216 }
217 
219  const PropertyName &pn,
220  int value) :
221  m_pc(pc),
222  m_pn(pn),
223  m_value(value),
224  m_oldValue(0)
225 {
226 }
227 
228 void
230 {
231  m_oldValue = m_pc->getPropertyRangeAndValue(m_pn, 0, 0, 0);
232  m_pc->setProperty(m_pn, m_value);
233 }
234 
235 void
237 {
238  m_pc->setProperty(m_pn, m_oldValue);
239 }
240 
241 QString
243 {
244  return tr("Set %1 Property").arg(m_pn);
245 }
246 
int getUnitId(QString unit, bool registerNew=true)
Return the reference id for a given unit name.
virtual PropertyType getPropertyType(const PropertyName &) const
Return the type of the given property, or InvalidProperty if the property is not supported on this co...
virtual bool convertPropertyStrings(QString nameString, QString valueString, PropertyName &name, int &value)
virtual RangeMapper * getNewPropertyRangeMapper(const PropertyName &) const
If the given property is a RangeProperty, return a new RangeMapper object mapping its integer range o...
virtual QString getPropertyValueLabel(const PropertyName &, int value) const
If the given property is a ValueProperty, return the display label to be used for the given value for...
virtual QString getPropertyContainerName() const =0
virtual PropertyList getProperties() const
Get a list of the names of all the supported properties on this container.
virtual void setPropertyFuzzy(QString nameString, QString valueString)
Set a property using a fuzzy match.
static UnitDatabase * getInstance()
virtual QString getPropertyLabel(const PropertyName &) const =0
Return the human-readable (and i18n'ised) name of a property.
virtual QString getPropertyGroupName(const PropertyName &) const
If this property has something in common with other properties on this container, return a name that ...
virtual Command * getSetPropertyCommand(const PropertyName &, int value)
Obtain a command that sets the given property, which can be added to the command history for undo/red...
virtual QString getPropertyIconName(const PropertyName &) const
Return an icon for the property, if any.
#define SVDEBUG
Definition: Debug.h:42
SetPropertyCommand(PropertyContainer *pc, const PropertyName &pn, int)
virtual int getPositionForValue(float value) const =0
Return the position that maps to the given value, rounding to the nearest position and clamping to th...
virtual int getPropertyRangeAndValue(const PropertyName &, int *min, int *max, int *deflt) const
Return the minimum and maximum values for the given property and its current value in this container.
virtual void setProperty(const PropertyName &, int value)
Set a property.
std::vector< PropertyName > PropertyList