svcore
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 and QMUL. 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 "PropertyContainer.h" 00017 #include "RangeMapper.h" 00018 #include "UnitDatabase.h" 00019 00020 #include <iostream> 00021 00022 PropertyContainer::PropertyList 00023 PropertyContainer::getProperties() const 00024 { 00025 return PropertyList(); 00026 } 00027 00028 PropertyContainer::PropertyType 00029 PropertyContainer::getPropertyType(const PropertyName &) const 00030 { 00031 return InvalidProperty; 00032 } 00033 00034 QString 00035 PropertyContainer::getPropertyIconName(const PropertyName &) const 00036 { 00037 return QString(); 00038 } 00039 00040 QString 00041 PropertyContainer::getPropertyGroupName(const PropertyName &) const 00042 { 00043 return QString(); 00044 } 00045 00046 int 00047 PropertyContainer::getPropertyRangeAndValue(const PropertyName &, 00048 int *min, int *max, int *deflt) const 00049 { 00050 if (min) *min = 0; 00051 if (max) *max = 0; 00052 if (deflt) *deflt = 0; 00053 return 0; 00054 } 00055 00056 QString 00057 PropertyContainer::getPropertyValueLabel(const PropertyName &, int) const 00058 { 00059 return QString(); 00060 } 00061 00062 RangeMapper * 00063 PropertyContainer::getNewPropertyRangeMapper(const PropertyName &) const 00064 { 00065 return 0; 00066 } 00067 00068 void 00069 PropertyContainer::setProperty(const PropertyName &name, int) 00070 { 00071 cerr << "WARNING: PropertyContainer[" << getPropertyContainerName() << "]::setProperty(" << name << "): no implementation in subclass!" << endl; 00072 } 00073 00074 Command * 00075 PropertyContainer::getSetPropertyCommand(const PropertyName &name, int value) 00076 { 00077 int currentValue = getPropertyRangeAndValue(name, 0, 0, 0); 00078 if (value == currentValue) return 0; 00079 return new SetPropertyCommand(this, name, value); 00080 } 00081 00082 void 00083 PropertyContainer::setPropertyFuzzy(QString nameString, QString valueString) 00084 { 00085 PropertyName name; 00086 int value; 00087 if (!convertPropertyStrings(nameString, valueString, name, value)) { 00088 cerr << "WARNING: PropertyContainer::setProperty(\"" 00089 << nameString << "\", \"" 00090 << valueString 00091 << "\"): Name and value conversion failed" << endl; 00092 return; 00093 } 00094 setProperty(name, value); 00095 } 00096 00097 Command * 00098 PropertyContainer::getSetPropertyCommand(QString nameString, QString valueString) 00099 { 00100 PropertyName name; 00101 int value; 00102 if (!convertPropertyStrings(nameString, valueString, name, value)) { 00103 cerr << "WARNING: PropertyContainer::getSetPropertyCommand(\"" 00104 << nameString << "\", \"" 00105 << valueString 00106 << "\"): Name and value conversion failed" << endl; 00107 return 0; 00108 } 00109 return getSetPropertyCommand(name, value); 00110 } 00111 00112 bool 00113 PropertyContainer::convertPropertyStrings(QString nameString, QString valueString, 00114 PropertyName &name, int &value) 00115 { 00116 PropertyList pl = getProperties(); 00117 00118 QString adjusted = nameString.trimmed(); 00119 adjusted.replace('_', ' '); 00120 adjusted.replace('-', ' '); 00121 00122 name = ""; 00123 00124 for (PropertyList::iterator pli = pl.begin(); pli != pl.end(); ++pli) { 00125 00126 QString label = getPropertyLabel(*pli); 00127 00128 if (label != "" && (nameString == label || adjusted == label)) { 00129 name = *pli; 00130 break; 00131 } else if (nameString == *pli) { 00132 name = *pli; 00133 break; 00134 } 00135 } 00136 00137 if (name == "") { 00138 cerr << "PropertyContainer::convertPropertyStrings: Unable to match name string \"" << nameString << "\"" << endl; 00139 return false; 00140 } 00141 00142 value = 0; 00143 bool success = false; 00144 00145 bool isDouble = false; 00146 double dval = valueString.toDouble(&isDouble); 00147 00148 switch (getPropertyType(name)) { 00149 00150 case ToggleProperty: 00151 if (valueString == tr("yes") || 00152 valueString == tr("on") || 00153 valueString == tr("true")) { 00154 value = 1; success = true; 00155 } else if (valueString == tr("no") || 00156 valueString == tr("off") || 00157 valueString == tr("false")) { 00158 value = 0; success = true; 00159 } 00160 break; 00161 00162 case RangeProperty: 00163 if (isDouble) { 00164 RangeMapper *mapper = getNewPropertyRangeMapper(name); 00165 if (mapper) { 00166 value = mapper->getPositionForValue(dval); 00167 delete mapper; 00168 success = true; 00169 } 00170 } 00171 break; 00172 00173 case ValueProperty: 00174 case ColourProperty: 00175 { 00176 int min, max; 00177 getPropertyRangeAndValue(name, &min, &max, 0); 00178 for (int i = min; i <= max; ++i) { 00179 if (valueString == getPropertyValueLabel(name, i)) { 00180 value = i; 00181 success = true; 00182 break; 00183 } 00184 } 00185 break; 00186 } 00187 00188 case UnitsProperty: 00189 value = UnitDatabase::getInstance()->getUnitId(valueString, false); 00190 if (value >= 0) success = true; 00191 else value = 0; 00192 break; 00193 00194 case InvalidProperty: 00195 SVDEBUG << "PropertyContainer::convertPropertyStrings: Invalid property name \"" << name << "\"" << endl; 00196 return false; 00197 } 00198 00199 if (success) return true; 00200 00201 int min, max; 00202 getPropertyRangeAndValue(name, &min, &max, 0); 00203 00204 bool ok = false; 00205 int i = valueString.toInt(&ok); 00206 if (!ok) { 00207 cerr << "PropertyContainer::convertPropertyStrings: Unable to parse value string \"" << valueString << "\"" << endl; 00208 return false; 00209 } else if (i < min || i > max) { 00210 SVDEBUG << "PropertyContainer::convertPropertyStrings: Property value \"" << i << "\" outside valid range " << min << " to " << max << endl; 00211 return false; 00212 } 00213 00214 value = i; 00215 return true; 00216 } 00217 00218 PropertyContainer::SetPropertyCommand::SetPropertyCommand(PropertyContainer *pc, 00219 const PropertyName &pn, 00220 int value) : 00221 m_pc(pc), 00222 m_pn(pn), 00223 m_value(value), 00224 m_oldValue(0) 00225 { 00226 } 00227 00228 void 00229 PropertyContainer::SetPropertyCommand::execute() 00230 { 00231 m_oldValue = m_pc->getPropertyRangeAndValue(m_pn, 0, 0, 0); 00232 m_pc->setProperty(m_pn, m_value); 00233 } 00234 00235 void 00236 PropertyContainer::SetPropertyCommand::unexecute() 00237 { 00238 m_pc->setProperty(m_pn, m_oldValue); 00239 } 00240 00241 QString 00242 PropertyContainer::SetPropertyCommand::getName() const 00243 { 00244 return tr("Set %1 Property").arg(m_pn); 00245 } 00246