PropertyContainer.cpp

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

Generated on Wed Feb 20 15:45:27 2008 for SonicVisualiser by  doxygen 1.5.1