annotate base/PropertyContainer.cpp @ 263:71dfc6ab3b54

* Threaded mp3/ogg file reading. Not activated yet, as it doesn't work in context (SV needs to know the duration of its main model at the outset)
author Chris Cannam
date Thu, 24 May 2007 16:20:22 +0000
parents 21b9b25bff48
children 3b8008d09541
rev   line source
Chris@49 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@0 2
Chris@0 3 /*
Chris@52 4 Sonic Visualiser
Chris@52 5 An audio file viewer and annotation editor.
Chris@52 6 Centre for Digital Music, Queen Mary, University of London.
Chris@202 7 This file copyright 2006 Chris Cannam and QMUL.
Chris@0 8
Chris@52 9 This program is free software; you can redistribute it and/or
Chris@52 10 modify it under the terms of the GNU General Public License as
Chris@52 11 published by the Free Software Foundation; either version 2 of the
Chris@52 12 License, or (at your option) any later version. See the file
Chris@52 13 COPYING included with this distribution for more information.
Chris@0 14 */
Chris@0 15
Chris@0 16 #include "PropertyContainer.h"
Chris@46 17 #include "CommandHistory.h"
Chris@199 18 #include "RangeMapper.h"
Chris@199 19 #include "UnitDatabase.h"
Chris@199 20
Chris@199 21 #include <QColor>
Chris@46 22
Chris@46 23 #include <iostream>
Chris@0 24
Chris@0 25 PropertyContainer::PropertyList
Chris@0 26 PropertyContainer::getProperties() const
Chris@0 27 {
Chris@0 28 return PropertyList();
Chris@0 29 }
Chris@0 30
Chris@94 31 //QString
Chris@94 32 //PropertyContainer::getPropertyLabel(const PropertyName &) const
Chris@94 33 //{
Chris@94 34 // return "";
Chris@94 35 //}
Chris@94 36
Chris@0 37 PropertyContainer::PropertyType
Chris@0 38 PropertyContainer::getPropertyType(const PropertyName &) const
Chris@0 39 {
Chris@0 40 return InvalidProperty;
Chris@0 41 }
Chris@0 42
Chris@0 43 QString
Chris@0 44 PropertyContainer::getPropertyGroupName(const PropertyName &) const
Chris@0 45 {
Chris@0 46 return QString();
Chris@0 47 }
Chris@0 48
Chris@0 49 int
Chris@245 50 PropertyContainer::getPropertyRangeAndValue(const PropertyName &,
Chris@245 51 int *min, int *max, int *deflt) const
Chris@0 52 {
Chris@0 53 if (min) *min = 0;
Chris@0 54 if (max) *max = 0;
Chris@245 55 if (deflt) *deflt = 0;
Chris@0 56 return 0;
Chris@0 57 }
Chris@0 58
Chris@0 59 QString
Chris@0 60 PropertyContainer::getPropertyValueLabel(const PropertyName &, int) const
Chris@0 61 {
Chris@0 62 return QString();
Chris@0 63 }
Chris@0 64
Chris@190 65 RangeMapper *
Chris@190 66 PropertyContainer::getNewPropertyRangeMapper(const PropertyName &) const
Chris@190 67 {
Chris@190 68 return 0;
Chris@190 69 }
Chris@190 70
Chris@0 71 void
Chris@46 72 PropertyContainer::setProperty(const PropertyName &name, int)
Chris@46 73 {
Chris@46 74 std::cerr << "WARNING: PropertyContainer[" << getPropertyContainerName().toStdString() << "]::setProperty(" << name.toStdString() << "): no implementation in subclass!" << std::endl;
Chris@46 75 }
Chris@46 76
Chris@46 77 void
Chris@46 78 PropertyContainer::setPropertyWithCommand(const PropertyName &name, int value)
Chris@46 79 {
Chris@245 80 int currentValue = getPropertyRangeAndValue(name, 0, 0, 0);
Chris@46 81 if (value == currentValue) return;
Chris@46 82
Chris@46 83 CommandHistory::getInstance()->addCommand
Chris@47 84 (new SetPropertyCommand(this, name, value), true, true); // bundled
Chris@46 85 }
Chris@199 86
Chris@199 87 void
Chris@199 88 PropertyContainer::setProperty(QString nameString, QString valueString)
Chris@199 89 {
Chris@199 90 PropertyName name;
Chris@199 91 int value;
Chris@199 92 if (!convertPropertyStrings(nameString, valueString, name, value)) {
Chris@199 93 std::cerr << "WARNING: PropertyContainer::setProperty(\""
Chris@199 94 << nameString.toStdString() << "\", \""
Chris@199 95 << valueString.toStdString()
Chris@199 96 << "\"): Name and value conversion failed" << std::endl;
Chris@199 97 return;
Chris@199 98 }
Chris@199 99 setProperty(name, value);
Chris@199 100 }
Chris@199 101
Chris@199 102 void
Chris@199 103 PropertyContainer::setPropertyWithCommand(QString nameString, QString valueString)
Chris@199 104 {
Chris@199 105 PropertyName name;
Chris@199 106 int value;
Chris@199 107 if (!convertPropertyStrings(nameString, valueString, name, value)) {
Chris@199 108 std::cerr << "WARNING: PropertyContainer::setPropertyWithCommand(\""
Chris@199 109 << nameString.toStdString() << "\", \""
Chris@199 110 << valueString.toStdString()
Chris@199 111 << "\"): Name and value conversion failed" << std::endl;
Chris@199 112 return;
Chris@199 113 }
Chris@199 114 setPropertyWithCommand(name, value);
Chris@199 115 }
Chris@199 116
Chris@199 117 bool
Chris@199 118 PropertyContainer::convertPropertyStrings(QString nameString, QString valueString,
Chris@199 119 PropertyName &name, int &value)
Chris@199 120 {
Chris@199 121 PropertyList pl = getProperties();
Chris@199 122
Chris@199 123 QString adjusted = nameString.trimmed();
Chris@199 124 adjusted.replace('_', ' ');
Chris@199 125 adjusted.replace('-', ' ');
Chris@199 126
Chris@199 127 name = "";
Chris@199 128
Chris@199 129 for (PropertyList::iterator pli = pl.begin(); pli != pl.end(); ++pli) {
Chris@199 130
Chris@199 131 QString label = getPropertyLabel(*pli);
Chris@199 132
Chris@199 133 if (label != "" && (nameString == label || adjusted == label)) {
Chris@199 134 name = *pli;
Chris@199 135 break;
Chris@199 136 } else if (nameString == *pli) {
Chris@199 137 name = *pli;
Chris@199 138 break;
Chris@199 139 }
Chris@199 140 }
Chris@199 141
Chris@199 142 if (name == "") {
Chris@199 143 std::cerr << "PropertyContainer::convertPropertyStrings: Unable to match name string \"" << nameString.toStdString() << "\"" << std::endl;
Chris@199 144 return false;
Chris@199 145 }
Chris@199 146
Chris@199 147 value = 0;
Chris@199 148 bool success = false;
Chris@199 149
Chris@199 150 bool isDouble = false;
Chris@199 151 double dval = valueString.toDouble(&isDouble);
Chris@199 152
Chris@199 153 switch (getPropertyType(name)) {
Chris@199 154
Chris@199 155 case ToggleProperty:
Chris@199 156 if (valueString == tr("yes") ||
Chris@199 157 valueString == tr("on") ||
Chris@199 158 valueString == tr("true")) {
Chris@199 159 value = 1; success = true;
Chris@199 160 } else if (valueString == tr("no") ||
Chris@199 161 valueString == tr("off") ||
Chris@199 162 valueString == tr("false")) {
Chris@199 163 value = 0; success = true;
Chris@199 164 }
Chris@199 165 break;
Chris@199 166
Chris@199 167 case RangeProperty:
Chris@199 168 if (isDouble) {
Chris@199 169 RangeMapper *mapper = getNewPropertyRangeMapper(name);
Chris@199 170 if (mapper) {
Chris@199 171 value = mapper->getPositionForValue(dval);
Chris@199 172 delete mapper;
Chris@199 173 success = true;
Chris@199 174 }
Chris@199 175 }
Chris@199 176 break;
Chris@199 177
Chris@199 178 case ValueProperty:
Chris@199 179 {
Chris@199 180 int min, max;
Chris@245 181 getPropertyRangeAndValue(name, &min, &max, 0);
Chris@199 182 for (int i = min; i <= max; ++i) {
Chris@199 183 if (valueString == getPropertyValueLabel(name, i)) {
Chris@199 184 value = i;
Chris@199 185 success = true;
Chris@199 186 break;
Chris@199 187 }
Chris@199 188 }
Chris@199 189 break;
Chris@199 190 }
Chris@199 191
Chris@199 192 case ColourProperty:
Chris@199 193 {
Chris@199 194 QColor c(valueString);
Chris@199 195 if (c.isValid()) {
Chris@199 196 value = c.rgb();
Chris@199 197 success = true;
Chris@199 198 }
Chris@199 199 break;
Chris@199 200 }
Chris@199 201
Chris@199 202 case UnitsProperty:
Chris@199 203 value = UnitDatabase::getInstance()->getUnitId(valueString, false);
Chris@199 204 if (value >= 0) success = true;
Chris@199 205 else value = 0;
Chris@199 206 break;
Chris@199 207
Chris@199 208 case InvalidProperty:
Chris@199 209 std::cerr << "PropertyContainer::convertPropertyStrings: Invalid property name \"" << name.toStdString() << "\"" << std::endl;
Chris@199 210 return false;
Chris@199 211 }
Chris@199 212
Chris@199 213 if (success) return true;
Chris@199 214
Chris@199 215 int min, max;
Chris@245 216 getPropertyRangeAndValue(name, &min, &max, 0);
Chris@199 217
Chris@199 218 bool ok = false;
Chris@199 219 int i = valueString.toInt(&ok);
Chris@199 220 if (!ok) {
Chris@199 221 std::cerr << "PropertyContainer::convertPropertyStrings: Unable to parse value string \"" << valueString.toStdString() << "\"" << std::endl;
Chris@199 222 return false;
Chris@199 223 } else if (i < min || i > max) {
Chris@199 224 std::cerr << "PropertyContainer::convertPropertyStrings: Property value \"" << i << "\" outside valid range " << min << " to " << max << std::endl;
Chris@199 225 return false;
Chris@199 226 }
Chris@199 227
Chris@199 228 value = i;
Chris@199 229 return true;
Chris@199 230 }
Chris@46 231
Chris@46 232 PropertyContainer::SetPropertyCommand::SetPropertyCommand(PropertyContainer *pc,
Chris@46 233 const PropertyName &pn,
Chris@46 234 int value) :
Chris@46 235 m_pc(pc),
Chris@46 236 m_pn(pn),
Chris@46 237 m_value(value),
Chris@46 238 m_oldValue(0)
Chris@0 239 {
Chris@0 240 }
Chris@0 241
Chris@46 242 void
Chris@46 243 PropertyContainer::SetPropertyCommand::execute()
Chris@46 244 {
Chris@245 245 m_oldValue = m_pc->getPropertyRangeAndValue(m_pn, 0, 0, 0);
Chris@46 246 m_pc->setProperty(m_pn, m_value);
Chris@46 247 }
Chris@46 248
Chris@46 249 void
Chris@46 250 PropertyContainer::SetPropertyCommand::unexecute()
Chris@46 251 {
Chris@46 252 m_pc->setProperty(m_pn, m_oldValue);
Chris@46 253 }
Chris@46 254
Chris@46 255 QString
Chris@46 256 PropertyContainer::SetPropertyCommand::getName() const
Chris@46 257 {
Chris@247 258 return tr("Set %1 Property").arg(m_pn);
Chris@46 259 }
Chris@46 260