changeset 199:1d789d688f59

* When adding a layer, make it the selected layer on that pane * More OSC support, including transforms
author Chris Cannam
date Fri, 10 Nov 2006 17:45:26 +0000
parents 4c5c62784211
children 2f2d282d45d0
files base/PropertyContainer.cpp base/PropertyContainer.h base/UnitDatabase.cpp base/UnitDatabase.h
diffstat 4 files changed, 185 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/base/PropertyContainer.cpp	Fri Nov 10 13:27:57 2006 +0000
+++ b/base/PropertyContainer.cpp	Fri Nov 10 17:45:26 2006 +0000
@@ -15,6 +15,10 @@
 
 #include "PropertyContainer.h"
 #include "CommandHistory.h"
+#include "RangeMapper.h"
+#include "UnitDatabase.h"
+
+#include <QColor>
 
 #include <iostream>
 
@@ -77,6 +81,151 @@
     CommandHistory::getInstance()->addCommand
 	(new SetPropertyCommand(this, name, value), true, true); // bundled
 }
+ 
+void
+PropertyContainer::setProperty(QString nameString, QString valueString)
+{
+    PropertyName name;
+    int value;
+    if (!convertPropertyStrings(nameString, valueString, name, value)) {
+        std::cerr << "WARNING: PropertyContainer::setProperty(\""
+                  << nameString.toStdString() << "\", \""
+                  << valueString.toStdString()
+                  << "\"): Name and value conversion failed" << std::endl;
+        return;
+    }
+    setProperty(name, value);
+}
+ 
+void
+PropertyContainer::setPropertyWithCommand(QString nameString, QString valueString)
+{
+    PropertyName name;
+    int value;
+    if (!convertPropertyStrings(nameString, valueString, name, value)) {
+        std::cerr << "WARNING: PropertyContainer::setPropertyWithCommand(\""
+                  << nameString.toStdString() << "\", \""
+                  << valueString.toStdString()
+                  << "\"): Name and value conversion failed" << std::endl;
+        return;
+    }
+    setPropertyWithCommand(name, value);
+}
+
+bool
+PropertyContainer::convertPropertyStrings(QString nameString, QString valueString,
+                                          PropertyName &name, int &value)
+{
+    PropertyList pl = getProperties();
+
+    QString adjusted = nameString.trimmed();
+    adjusted.replace('_', ' ');
+    adjusted.replace('-', ' ');
+    
+    name = "";
+
+    for (PropertyList::iterator pli = pl.begin(); pli != pl.end(); ++pli) {
+
+        QString label = getPropertyLabel(*pli);
+
+        if (label != "" && (nameString == label || adjusted == label)) {
+            name = *pli;
+            break;
+        } else if (nameString == *pli) {
+            name = *pli;
+            break;
+        }
+    }
+
+    if (name == "") {
+        std::cerr << "PropertyContainer::convertPropertyStrings: Unable to match name string \"" << nameString.toStdString() << "\"" << std::endl;
+        return false;
+    }
+
+    value = 0;
+    bool success = false;
+    
+    bool isDouble = false;
+    double dval = valueString.toDouble(&isDouble);
+
+    switch (getPropertyType(name)) {
+
+    case ToggleProperty:
+        if (valueString == tr("yes") || 
+            valueString == tr("on") ||
+            valueString == tr("true")) {
+            value = 1; success = true;
+        } else if (valueString == tr("no") ||
+                   valueString == tr("off") ||
+                   valueString == tr("false")) {
+            value = 0; success = true;
+        }
+        break;
+
+    case RangeProperty:
+        if (isDouble) {
+            RangeMapper *mapper = getNewPropertyRangeMapper(name);
+            if (mapper) {
+                value = mapper->getPositionForValue(dval);
+                delete mapper;
+                success = true;
+            }
+        }
+        break;
+
+    case ValueProperty:
+    {
+        int min, max;
+        getPropertyRangeAndValue(name, &min, &max);
+        for (int i = min; i <= max; ++i) {
+            if (valueString == getPropertyValueLabel(name, i)) {
+                value = i;
+                success = true;
+                break;
+            }
+        }
+        break;
+    }
+
+    case ColourProperty:
+    {
+        QColor c(valueString);
+        if (c.isValid()) {
+            value = c.rgb();
+            success = true;
+        }
+        break;
+    }
+        
+    case UnitsProperty:
+        value = UnitDatabase::getInstance()->getUnitId(valueString, false);
+        if (value >= 0) success = true;
+        else value = 0;
+        break;
+
+    case InvalidProperty:
+        std::cerr << "PropertyContainer::convertPropertyStrings: Invalid property name \"" << name.toStdString() << "\"" << std::endl;
+        return false;
+    }
+
+    if (success) return true;
+
+    int min, max;
+    getPropertyRangeAndValue(name, &min, &max);
+    
+    bool ok = false;
+    int i = valueString.toInt(&ok);
+    if (!ok) {
+        std::cerr << "PropertyContainer::convertPropertyStrings: Unable to parse value string \"" << valueString.toStdString() << "\"" << std::endl;
+        return false;
+    } else if (i < min || i > max) {
+        std::cerr << "PropertyContainer::convertPropertyStrings: Property value \"" << i << "\" outside valid range " << min << " to " << max << std::endl;
+        return false;
+    }
+
+    value = i;
+    return true;
+}
 
 PropertyContainer::SetPropertyCommand::SetPropertyCommand(PropertyContainer *pc,
 							  const PropertyName &pn,
--- a/base/PropertyContainer.h	Fri Nov 10 13:27:57 2006 +0000
+++ b/base/PropertyContainer.h	Fri Nov 10 17:45:26 2006 +0000
@@ -117,6 +117,28 @@
      */
     virtual void setPropertyWithCommand(const PropertyName &, int value);
 
+    /**
+     * Set a property using a fuzzy match.  Compare nameString with
+     * the property labels and underlying names, and if it matches one
+     * (with preference given to labels), try to convert valueString
+     * appropriately and set it.  The valueString should contain a
+     * value label for value properties, a mapped value for range
+     * properties, "on" or "off" for toggle properties, a colour or
+     * unit name, or the underlying integer value for the property.
+     *
+     * Note that as property and value labels may be translatable, the
+     * results of this function may vary by locale.  It is intended
+     * for handling user-originated strings, _not_ persistent storage.
+     *
+     * The default implementation should work for most subclasses.
+     */
+    virtual void setProperty(QString nameString, QString valueString);
+
+    /**
+     * As above, but using a command.
+     */
+    virtual void setPropertyWithCommand(QString nameString, QString valueString);
+
 protected:
 
     class SetPropertyCommand : public Command
@@ -135,6 +157,9 @@
 	int m_value;
 	int m_oldValue;
     };
+
+    virtual bool convertPropertyStrings(QString nameString, QString valueString,
+                                        PropertyName &name, int &value);
 };
 
 #endif
--- a/base/UnitDatabase.cpp	Fri Nov 10 13:27:57 2006 +0000
+++ b/base/UnitDatabase.cpp	Fri Nov 10 17:45:26 2006 +0000
@@ -49,10 +49,11 @@
 }
 
 int
-UnitDatabase::getUnitId(QString unit)
+UnitDatabase::getUnitId(QString unit, bool registerNew)
 {
     if (m_units.find(unit) == m_units.end()) {
-        registerUnit(unit);
+        if (registerNew) registerUnit(unit);
+        else return -1;
     }
     return m_units[unit];
 }
--- a/base/UnitDatabase.h	Fri Nov 10 13:27:57 2006 +0000
+++ b/base/UnitDatabase.h	Fri Nov 10 17:45:26 2006 +0000
@@ -35,8 +35,14 @@
 
     QStringList getKnownUnits() const;
     void registerUnit(QString unit);
-    
-    int getUnitId(QString unit);
+
+    /**
+     * Return the reference id for a given unit name.  If registerNew is
+     * true and the unit is not known, register it and return its new
+     * id.  If register is false and the unit is not known, return -1.
+     */
+    int getUnitId(QString unit, bool registerNew = true);
+
     QString getUnitById(int id);
 
 signals: