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 
62 QString
64 {
65  return QString();
66 }
67 
70 {
71  return nullptr;
72 }
73 
74 void
76 {
77  cerr << "WARNING: PropertyContainer[" << getPropertyContainerName() << "]::setProperty(" << name << "): no implementation in subclass!" << endl;
78 }
79 
80 Command *
82 {
83  int currentValue = getPropertyRangeAndValue(name, nullptr, nullptr, nullptr);
84  if (value == currentValue) return nullptr;
85  return new SetPropertyCommand(this, name, value);
86 }
87 
88 void
89 PropertyContainer::setPropertyFuzzy(QString nameString, QString valueString)
90 {
91  PropertyName name;
92  int value;
93  if (!convertPropertyStrings(nameString, valueString, name, value)) {
94  cerr << "WARNING: PropertyContainer::setProperty(\""
95  << nameString << "\", \""
96  << valueString
97  << "\"): Name and value conversion failed" << endl;
98  return;
99  }
100  setProperty(name, value);
101 }
102 
103 Command *
104 PropertyContainer::getSetPropertyCommand(QString nameString, QString valueString)
105 {
106  PropertyName name;
107  int value;
108  if (!convertPropertyStrings(nameString, valueString, name, value)) {
109  cerr << "WARNING: PropertyContainer::getSetPropertyCommand(\""
110  << nameString << "\", \""
111  << valueString
112  << "\"): Name and value conversion failed" << endl;
113  return nullptr;
114  }
115  return getSetPropertyCommand(name, value);
116 }
117 
118 bool
119 PropertyContainer::convertPropertyStrings(QString nameString, QString valueString,
120  PropertyName &name, int &value)
121 {
123 
124  QString adjusted = nameString.trimmed();
125  adjusted.replace('_', ' ');
126  adjusted.replace('-', ' ');
127 
128  name = "";
129 
130  for (PropertyList::iterator pli = pl.begin(); pli != pl.end(); ++pli) {
131 
132  QString label = getPropertyLabel(*pli);
133 
134  if (label != "" && (nameString == label || adjusted == label)) {
135  name = *pli;
136  break;
137  } else if (nameString == *pli) {
138  name = *pli;
139  break;
140  }
141  }
142 
143  if (name == "") {
144  cerr << "PropertyContainer::convertPropertyStrings: Unable to match name string \"" << nameString << "\"" << endl;
145  return false;
146  }
147 
148  value = 0;
149  bool success = false;
150 
151  bool isDouble = false;
152  double dval = valueString.toDouble(&isDouble);
153 
154  switch (getPropertyType(name)) {
155 
156  case ToggleProperty:
157  if (valueString == tr("yes") ||
158  valueString == tr("on") ||
159  valueString == tr("true")) {
160  value = 1; success = true;
161  } else if (valueString == tr("no") ||
162  valueString == tr("off") ||
163  valueString == tr("false")) {
164  value = 0; success = true;
165  }
166  break;
167 
168  case RangeProperty:
169  if (isDouble) {
170  RangeMapper *mapper = getNewPropertyRangeMapper(name);
171  if (mapper) {
172  value = mapper->getPositionForValue(dval);
173  delete mapper;
174  success = true;
175  }
176  }
177  break;
178 
179  case ValueProperty:
180  case ColourProperty:
181  case ColourMapProperty:
182  {
183  int min, max;
184  getPropertyRangeAndValue(name, &min, &max, nullptr);
185  for (int i = min; i <= max; ++i) {
186  if (valueString == getPropertyValueLabel(name, i)) {
187  value = i;
188  success = true;
189  break;
190  }
191  }
192  break;
193  }
194 
195  case UnitsProperty:
196  value = UnitDatabase::getInstance()->getUnitId(valueString, false);
197  if (value >= 0) success = true;
198  else value = 0;
199  break;
200 
201  case InvalidProperty:
202  SVDEBUG << "PropertyContainer::convertPropertyStrings: Invalid property name \"" << name << "\"" << endl;
203  return false;
204  }
205 
206  if (success) return true;
207 
208  int min, max;
209  getPropertyRangeAndValue(name, &min, &max, nullptr);
210 
211  bool ok = false;
212  int i = valueString.toInt(&ok);
213  if (!ok) {
214  cerr << "PropertyContainer::convertPropertyStrings: Unable to parse value string \"" << valueString << "\"" << endl;
215  return false;
216  } else if (i < min || i > max) {
217  SVDEBUG << "PropertyContainer::convertPropertyStrings: Property value \"" << i << "\" outside valid range " << min << " to " << max << endl;
218  return false;
219  }
220 
221  value = i;
222  return true;
223 }
224 
226  const PropertyName &pn,
227  int value) :
228  m_pc(pc),
229  m_pn(pn),
230  m_value(value),
231  m_oldValue(0)
232 {
233 }
234 
235 void
237 {
238  m_oldValue = m_pc->getPropertyRangeAndValue(m_pn, nullptr, nullptr, nullptr);
240 }
241 
242 void
244 {
246 }
247 
248 QString
250 {
251  return tr("Set %1 Property").arg(m_pn);
252 }
253 
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 int getPositionForValue(double value) const =0
Return the position that maps to the given value, rounding to the nearest position and clamping to th...
virtual QString getPropertyGroupName(const PropertyName &) const
If this property has something in common with other properties on this container, return a name that ...
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 bool convertPropertyStrings(QString nameString, QString valueString, PropertyName &name, int &value)
virtual QString getPropertyValueIconName(const PropertyName &, int value) const
If the given property is a ValueProperty, return the icon to be used for the given value for that pro...
virtual RangeMapper * getNewPropertyRangeMapper(const PropertyName &) const
If the given property is a RangeProperty, return a new RangeMapper object mapping its integer range o...
virtual PropertyList getProperties() const
Get a list of the names of all the supported properties on this container.
virtual QString getPropertyContainerName() const =0
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&#39;ised) name of a property.
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 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...
#define SVDEBUG
Definition: Debug.h:106
SetPropertyCommand(PropertyContainer *pc, const PropertyName &pn, int)
virtual void setProperty(const PropertyName &, int value)
Set a property.
std::vector< PropertyName > PropertyList
virtual QString getPropertyIconName(const PropertyName &) const
Return an icon for the property, if any.