00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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);
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