annotate base/PropertyContainer.cpp @ 1563:175ef02c7864

Merge
author Chris Cannam
date Fri, 02 Nov 2018 14:41:00 +0000
parents 48e9f538e6e9
children 70e172e6cc59
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@199 17 #include "RangeMapper.h"
Chris@199 18 #include "UnitDatabase.h"
Chris@46 19
Chris@46 20 #include <iostream>
Chris@0 21
Chris@0 22 PropertyContainer::PropertyList
Chris@0 23 PropertyContainer::getProperties() const
Chris@0 24 {
Chris@0 25 return PropertyList();
Chris@0 26 }
Chris@0 27
Chris@0 28 PropertyContainer::PropertyType
Chris@0 29 PropertyContainer::getPropertyType(const PropertyName &) const
Chris@0 30 {
Chris@0 31 return InvalidProperty;
Chris@0 32 }
Chris@0 33
Chris@0 34 QString
Chris@340 35 PropertyContainer::getPropertyIconName(const PropertyName &) const
Chris@340 36 {
Chris@340 37 return QString();
Chris@340 38 }
Chris@340 39
Chris@340 40 QString
Chris@0 41 PropertyContainer::getPropertyGroupName(const PropertyName &) const
Chris@0 42 {
Chris@0 43 return QString();
Chris@0 44 }
Chris@0 45
Chris@0 46 int
Chris@245 47 PropertyContainer::getPropertyRangeAndValue(const PropertyName &,
Chris@245 48 int *min, int *max, int *deflt) const
Chris@0 49 {
Chris@0 50 if (min) *min = 0;
Chris@0 51 if (max) *max = 0;
Chris@245 52 if (deflt) *deflt = 0;
Chris@0 53 return 0;
Chris@0 54 }
Chris@0 55
Chris@0 56 QString
Chris@928 57 PropertyContainer::getPropertyValueLabel(const PropertyName &, int) const
Chris@0 58 {
Chris@0 59 return QString();
Chris@0 60 }
Chris@0 61
Chris@984 62 QString
Chris@984 63 PropertyContainer::getPropertyValueIconName(const PropertyName &, int) const
Chris@984 64 {
Chris@984 65 return QString();
Chris@984 66 }
Chris@984 67
Chris@190 68 RangeMapper *
Chris@190 69 PropertyContainer::getNewPropertyRangeMapper(const PropertyName &) const
Chris@190 70 {
Chris@190 71 return 0;
Chris@190 72 }
Chris@190 73
Chris@0 74 void
Chris@46 75 PropertyContainer::setProperty(const PropertyName &name, int)
Chris@46 76 {
Chris@843 77 cerr << "WARNING: PropertyContainer[" << getPropertyContainerName() << "]::setProperty(" << name << "): no implementation in subclass!" << endl;
Chris@46 78 }
Chris@46 79
Chris@387 80 Command *
Chris@387 81 PropertyContainer::getSetPropertyCommand(const PropertyName &name, int value)
Chris@46 82 {
Chris@245 83 int currentValue = getPropertyRangeAndValue(name, 0, 0, 0);
Chris@387 84 if (value == currentValue) return 0;
Chris@387 85 return new SetPropertyCommand(this, name, value);
Chris@46 86 }
Chris@199 87
Chris@199 88 void
Chris@528 89 PropertyContainer::setPropertyFuzzy(QString nameString, QString valueString)
Chris@199 90 {
Chris@199 91 PropertyName name;
Chris@199 92 int value;
Chris@199 93 if (!convertPropertyStrings(nameString, valueString, name, value)) {
Chris@843 94 cerr << "WARNING: PropertyContainer::setProperty(\""
Chris@686 95 << nameString << "\", \""
Chris@844 96 << valueString
Chris@843 97 << "\"): Name and value conversion failed" << endl;
Chris@199 98 return;
Chris@199 99 }
Chris@199 100 setProperty(name, value);
Chris@199 101 }
Chris@199 102
Chris@387 103 Command *
Chris@387 104 PropertyContainer::getSetPropertyCommand(QString nameString, QString valueString)
Chris@199 105 {
Chris@199 106 PropertyName name;
Chris@199 107 int value;
Chris@199 108 if (!convertPropertyStrings(nameString, valueString, name, value)) {
Chris@843 109 cerr << "WARNING: PropertyContainer::getSetPropertyCommand(\""
Chris@686 110 << nameString << "\", \""
Chris@844 111 << valueString
Chris@843 112 << "\"): Name and value conversion failed" << endl;
Chris@387 113 return 0;
Chris@199 114 }
Chris@387 115 return getSetPropertyCommand(name, value);
Chris@199 116 }
Chris@199 117
Chris@199 118 bool
Chris@199 119 PropertyContainer::convertPropertyStrings(QString nameString, QString valueString,
Chris@199 120 PropertyName &name, int &value)
Chris@199 121 {
Chris@199 122 PropertyList pl = getProperties();
Chris@199 123
Chris@199 124 QString adjusted = nameString.trimmed();
Chris@199 125 adjusted.replace('_', ' ');
Chris@199 126 adjusted.replace('-', ' ');
Chris@199 127
Chris@199 128 name = "";
Chris@199 129
Chris@199 130 for (PropertyList::iterator pli = pl.begin(); pli != pl.end(); ++pli) {
Chris@199 131
Chris@199 132 QString label = getPropertyLabel(*pli);
Chris@199 133
Chris@199 134 if (label != "" && (nameString == label || adjusted == label)) {
Chris@199 135 name = *pli;
Chris@199 136 break;
Chris@199 137 } else if (nameString == *pli) {
Chris@199 138 name = *pli;
Chris@199 139 break;
Chris@199 140 }
Chris@199 141 }
Chris@199 142
Chris@199 143 if (name == "") {
Chris@843 144 cerr << "PropertyContainer::convertPropertyStrings: Unable to match name string \"" << nameString << "\"" << endl;
Chris@199 145 return false;
Chris@199 146 }
Chris@199 147
Chris@199 148 value = 0;
Chris@199 149 bool success = false;
Chris@199 150
Chris@199 151 bool isDouble = false;
Chris@199 152 double dval = valueString.toDouble(&isDouble);
Chris@199 153
Chris@199 154 switch (getPropertyType(name)) {
Chris@199 155
Chris@199 156 case ToggleProperty:
Chris@199 157 if (valueString == tr("yes") ||
Chris@199 158 valueString == tr("on") ||
Chris@199 159 valueString == tr("true")) {
Chris@199 160 value = 1; success = true;
Chris@199 161 } else if (valueString == tr("no") ||
Chris@199 162 valueString == tr("off") ||
Chris@199 163 valueString == tr("false")) {
Chris@199 164 value = 0; success = true;
Chris@199 165 }
Chris@199 166 break;
Chris@199 167
Chris@199 168 case RangeProperty:
Chris@199 169 if (isDouble) {
Chris@199 170 RangeMapper *mapper = getNewPropertyRangeMapper(name);
Chris@199 171 if (mapper) {
Chris@199 172 value = mapper->getPositionForValue(dval);
Chris@199 173 delete mapper;
Chris@199 174 success = true;
Chris@199 175 }
Chris@199 176 }
Chris@199 177 break;
Chris@199 178
Chris@199 179 case ValueProperty:
Chris@387 180 case ColourProperty:
Chris@1331 181 case ColourMapProperty:
Chris@199 182 {
Chris@199 183 int min, max;
Chris@245 184 getPropertyRangeAndValue(name, &min, &max, 0);
Chris@199 185 for (int i = min; i <= max; ++i) {
Chris@199 186 if (valueString == getPropertyValueLabel(name, i)) {
Chris@199 187 value = i;
Chris@199 188 success = true;
Chris@199 189 break;
Chris@199 190 }
Chris@199 191 }
Chris@199 192 break;
Chris@199 193 }
Chris@199 194
Chris@199 195 case UnitsProperty:
Chris@199 196 value = UnitDatabase::getInstance()->getUnitId(valueString, false);
Chris@199 197 if (value >= 0) success = true;
Chris@199 198 else value = 0;
Chris@199 199 break;
Chris@199 200
Chris@199 201 case InvalidProperty:
Chris@690 202 SVDEBUG << "PropertyContainer::convertPropertyStrings: Invalid property name \"" << name << "\"" << endl;
Chris@199 203 return false;
Chris@199 204 }
Chris@199 205
Chris@199 206 if (success) return true;
Chris@199 207
Chris@199 208 int min, max;
Chris@245 209 getPropertyRangeAndValue(name, &min, &max, 0);
Chris@199 210
Chris@199 211 bool ok = false;
Chris@199 212 int i = valueString.toInt(&ok);
Chris@199 213 if (!ok) {
Chris@843 214 cerr << "PropertyContainer::convertPropertyStrings: Unable to parse value string \"" << valueString << "\"" << endl;
Chris@199 215 return false;
Chris@199 216 } else if (i < min || i > max) {
Chris@690 217 SVDEBUG << "PropertyContainer::convertPropertyStrings: Property value \"" << i << "\" outside valid range " << min << " to " << max << endl;
Chris@199 218 return false;
Chris@199 219 }
Chris@199 220
Chris@199 221 value = i;
Chris@199 222 return true;
Chris@199 223 }
Chris@46 224
Chris@46 225 PropertyContainer::SetPropertyCommand::SetPropertyCommand(PropertyContainer *pc,
Chris@1429 226 const PropertyName &pn,
Chris@1429 227 int value) :
Chris@46 228 m_pc(pc),
Chris@46 229 m_pn(pn),
Chris@46 230 m_value(value),
Chris@46 231 m_oldValue(0)
Chris@0 232 {
Chris@0 233 }
Chris@0 234
Chris@46 235 void
Chris@46 236 PropertyContainer::SetPropertyCommand::execute()
Chris@46 237 {
Chris@245 238 m_oldValue = m_pc->getPropertyRangeAndValue(m_pn, 0, 0, 0);
Chris@46 239 m_pc->setProperty(m_pn, m_value);
Chris@46 240 }
Chris@46 241
Chris@46 242 void
Chris@46 243 PropertyContainer::SetPropertyCommand::unexecute()
Chris@46 244 {
Chris@46 245 m_pc->setProperty(m_pn, m_oldValue);
Chris@46 246 }
Chris@46 247
Chris@46 248 QString
Chris@46 249 PropertyContainer::SetPropertyCommand::getName() const
Chris@46 250 {
Chris@247 251 return tr("Set %1 Property").arg(m_pn);
Chris@46 252 }
Chris@46 253