lbajardsilogic@0: /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ lbajardsilogic@0: lbajardsilogic@0: /* lbajardsilogic@0: Sonic Visualiser lbajardsilogic@0: An audio file viewer and annotation editor. lbajardsilogic@0: Centre for Digital Music, Queen Mary, University of London. lbajardsilogic@0: This file copyright 2006 Chris Cannam and QMUL. lbajardsilogic@0: lbajardsilogic@0: This program is free software; you can redistribute it and/or lbajardsilogic@0: modify it under the terms of the GNU General Public License as lbajardsilogic@0: published by the Free Software Foundation; either version 2 of the lbajardsilogic@0: License, or (at your option) any later version. See the file lbajardsilogic@0: COPYING included with this distribution for more information. lbajardsilogic@0: */ lbajardsilogic@0: lbajardsilogic@0: #include "PropertyContainer.h" lbajardsilogic@0: #include "CommandHistory.h" lbajardsilogic@0: #include "RangeMapper.h" lbajardsilogic@0: #include "UnitDatabase.h" lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: #include lbajardsilogic@0: lbajardsilogic@0: PropertyContainer::PropertyList lbajardsilogic@0: PropertyContainer::getProperties() const lbajardsilogic@0: { lbajardsilogic@0: return PropertyList(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: //QString lbajardsilogic@0: //PropertyContainer::getPropertyLabel(const PropertyName &) const lbajardsilogic@0: //{ lbajardsilogic@0: // return ""; lbajardsilogic@0: //} lbajardsilogic@0: lbajardsilogic@0: PropertyContainer::PropertyType lbajardsilogic@0: PropertyContainer::getPropertyType(const PropertyName &) const lbajardsilogic@0: { lbajardsilogic@0: return InvalidProperty; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: QString lbajardsilogic@0: PropertyContainer::getPropertyGroupName(const PropertyName &) const lbajardsilogic@0: { lbajardsilogic@0: return QString(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: int lbajardsilogic@0: PropertyContainer::getPropertyRangeAndValue(const PropertyName &, lbajardsilogic@0: int *min, int *max, int *deflt) const lbajardsilogic@0: { lbajardsilogic@0: if (min) *min = 0; lbajardsilogic@0: if (max) *max = 0; lbajardsilogic@0: if (deflt) *deflt = 0; lbajardsilogic@0: return 0; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: QString lbajardsilogic@0: PropertyContainer::getPropertyValueLabel(const PropertyName &, int) const lbajardsilogic@0: { lbajardsilogic@0: return QString(); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: RangeMapper * lbajardsilogic@0: PropertyContainer::getNewPropertyRangeMapper(const PropertyName &) const lbajardsilogic@0: { lbajardsilogic@0: return 0; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: PropertyContainer::setProperty(const PropertyName &name, int) lbajardsilogic@0: { lbajardsilogic@0: std::cerr << "WARNING: PropertyContainer[" << getPropertyContainerName().toStdString() << "]::setProperty(" << name.toStdString() << "): no implementation in subclass!" << std::endl; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: PropertyContainer::setPropertyWithCommand(const PropertyName &name, int value) lbajardsilogic@0: { lbajardsilogic@0: int currentValue = getPropertyRangeAndValue(name, 0, 0, 0); lbajardsilogic@0: if (value == currentValue) return; lbajardsilogic@0: lbajardsilogic@0: CommandHistory::getInstance()->addCommand lbajardsilogic@0: (new SetPropertyCommand(this, name, value), true, true); // bundled lbajardsilogic@0: } lbajardsilogic@229: lbajardsilogic@0: void lbajardsilogic@0: PropertyContainer::setProperty(QString nameString, QString valueString) lbajardsilogic@0: { lbajardsilogic@0: PropertyName name; lbajardsilogic@0: int value; lbajardsilogic@0: if (!convertPropertyStrings(nameString, valueString, name, value)) { lbajardsilogic@0: std::cerr << "WARNING: PropertyContainer::setProperty(\"" lbajardsilogic@0: << nameString.toStdString() << "\", \"" lbajardsilogic@0: << valueString.toStdString() lbajardsilogic@0: << "\"): Name and value conversion failed" << std::endl; lbajardsilogic@0: return; lbajardsilogic@0: } lbajardsilogic@0: setProperty(name, value); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: PropertyContainer::setPropertyWithCommand(QString nameString, QString valueString) lbajardsilogic@0: { lbajardsilogic@0: PropertyName name; lbajardsilogic@0: int value; lbajardsilogic@0: if (!convertPropertyStrings(nameString, valueString, name, value)) { lbajardsilogic@0: std::cerr << "WARNING: PropertyContainer::setPropertyWithCommand(\"" lbajardsilogic@0: << nameString.toStdString() << "\", \"" lbajardsilogic@0: << valueString.toStdString() lbajardsilogic@0: << "\"): Name and value conversion failed" << std::endl; lbajardsilogic@0: return; lbajardsilogic@0: } lbajardsilogic@0: setPropertyWithCommand(name, value); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: bool lbajardsilogic@0: PropertyContainer::convertPropertyStrings(QString nameString, QString valueString, lbajardsilogic@0: PropertyName &name, int &value) lbajardsilogic@0: { lbajardsilogic@0: PropertyList pl = getProperties(); lbajardsilogic@0: lbajardsilogic@0: QString adjusted = nameString.trimmed(); lbajardsilogic@0: adjusted.replace('_', ' '); lbajardsilogic@0: adjusted.replace('-', ' '); lbajardsilogic@0: lbajardsilogic@0: name = ""; lbajardsilogic@0: lbajardsilogic@0: for (PropertyList::iterator pli = pl.begin(); pli != pl.end(); ++pli) { lbajardsilogic@0: lbajardsilogic@0: QString label = getPropertyLabel(*pli); lbajardsilogic@0: lbajardsilogic@0: if (label != "" && (nameString == label || adjusted == label)) { lbajardsilogic@0: name = *pli; lbajardsilogic@0: break; lbajardsilogic@0: } else if (nameString == *pli) { lbajardsilogic@0: name = *pli; lbajardsilogic@0: break; lbajardsilogic@0: } lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: if (name == "") { lbajardsilogic@0: std::cerr << "PropertyContainer::convertPropertyStrings: Unable to match name string \"" << nameString.toStdString() << "\"" << std::endl; lbajardsilogic@0: return false; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: value = 0; lbajardsilogic@0: bool success = false; lbajardsilogic@0: lbajardsilogic@0: bool isDouble = false; lbajardsilogic@0: double dval = valueString.toDouble(&isDouble); lbajardsilogic@0: lbajardsilogic@0: switch (getPropertyType(name)) { lbajardsilogic@0: lbajardsilogic@0: case ToggleProperty: lbajardsilogic@0: if (valueString == tr("yes") || lbajardsilogic@0: valueString == tr("on") || lbajardsilogic@0: valueString == tr("true")) { lbajardsilogic@0: value = 1; success = true; lbajardsilogic@0: } else if (valueString == tr("no") || lbajardsilogic@0: valueString == tr("off") || lbajardsilogic@0: valueString == tr("false")) { lbajardsilogic@0: value = 0; success = true; lbajardsilogic@0: } lbajardsilogic@0: break; lbajardsilogic@0: lbajardsilogic@0: case RangeProperty: benoitrigolleau@276: case RangePropertyWithLabel: lbajardsilogic@0: if (isDouble) { lbajardsilogic@0: RangeMapper *mapper = getNewPropertyRangeMapper(name); lbajardsilogic@0: if (mapper) { lbajardsilogic@0: value = mapper->getPositionForValue(dval); lbajardsilogic@0: delete mapper; lbajardsilogic@0: success = true; lbajardsilogic@0: } lbajardsilogic@0: } lbajardsilogic@0: break; lbajardsilogic@0: benoitrigolleau@276: lbajardsilogic@0: case ValueProperty: lbajardsilogic@0: { lbajardsilogic@0: int min, max; lbajardsilogic@0: getPropertyRangeAndValue(name, &min, &max, 0); lbajardsilogic@0: for (int i = min; i <= max; ++i) { lbajardsilogic@0: if (valueString == getPropertyValueLabel(name, i)) { lbajardsilogic@0: value = i; lbajardsilogic@0: success = true; lbajardsilogic@0: break; lbajardsilogic@0: } lbajardsilogic@0: } lbajardsilogic@0: break; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: case ColourProperty: lbajardsilogic@0: { lbajardsilogic@0: QColor c(valueString); lbajardsilogic@0: if (c.isValid()) { lbajardsilogic@0: value = c.rgb(); lbajardsilogic@0: success = true; lbajardsilogic@0: } lbajardsilogic@0: break; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: case UnitsProperty: lbajardsilogic@0: value = UnitDatabase::getInstance()->getUnitId(valueString, false); lbajardsilogic@0: if (value >= 0) success = true; lbajardsilogic@0: else value = 0; lbajardsilogic@0: break; lbajardsilogic@0: lbajardsilogic@0: case InvalidProperty: lbajardsilogic@0: std::cerr << "PropertyContainer::convertPropertyStrings: Invalid property name \"" << name.toStdString() << "\"" << std::endl; lbajardsilogic@0: return false; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: if (success) return true; lbajardsilogic@0: lbajardsilogic@0: int min, max; lbajardsilogic@0: getPropertyRangeAndValue(name, &min, &max, 0); lbajardsilogic@0: lbajardsilogic@0: bool ok = false; lbajardsilogic@0: int i = valueString.toInt(&ok); lbajardsilogic@0: if (!ok) { lbajardsilogic@0: std::cerr << "PropertyContainer::convertPropertyStrings: Unable to parse value string \"" << valueString.toStdString() << "\"" << std::endl; lbajardsilogic@0: return false; lbajardsilogic@0: } else if (i < min || i > max) { lbajardsilogic@0: std::cerr << "PropertyContainer::convertPropertyStrings: Property value \"" << i << "\" outside valid range " << min << " to " << max << std::endl; lbajardsilogic@0: return false; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: value = i; lbajardsilogic@0: return true; lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: PropertyContainer::SetPropertyCommand::SetPropertyCommand(PropertyContainer *pc, lbajardsilogic@0: const PropertyName &pn, lbajardsilogic@0: int value) : lbajardsilogic@0: m_pc(pc), lbajardsilogic@0: m_pn(pn), lbajardsilogic@0: m_value(value), lbajardsilogic@0: m_oldValue(0) lbajardsilogic@0: { lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: PropertyContainer::SetPropertyCommand::execute() lbajardsilogic@0: { lbajardsilogic@0: m_oldValue = m_pc->getPropertyRangeAndValue(m_pn, 0, 0, 0); lbajardsilogic@0: m_pc->setProperty(m_pn, m_value); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: void lbajardsilogic@0: PropertyContainer::SetPropertyCommand::unexecute() lbajardsilogic@0: { lbajardsilogic@0: m_pc->setProperty(m_pn, m_oldValue); lbajardsilogic@0: } lbajardsilogic@0: lbajardsilogic@0: QString lbajardsilogic@0: PropertyContainer::SetPropertyCommand::getName() const lbajardsilogic@0: { lbajardsilogic@0: return tr("Set %1 Property").arg(m_pn); lbajardsilogic@0: }