/*************************************************************************** * Copyright (c) Jürgen Riegel (juergen.riegel@web.de) 2002 * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include "PreCompiled.h" #ifndef _PreComp_ # include # include #endif /// Here the FreeCAD includes sorted by Base,App,Gui...... #include #include #include #include #include "PropertyStandard.h" #include "MaterialPy.h" #define new DEBUG_CLIENTBLOCK using namespace App; using namespace Base; using namespace std; //************************************************************************** //************************************************************************** // PropertyInteger //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyInteger , App::Property); //************************************************************************** // Construction/Destruction PropertyInteger::PropertyInteger() { _lValue = 0; } PropertyInteger::~PropertyInteger() { } //************************************************************************** // Base class implementer void PropertyInteger::setValue(long lValue) { aboutToSetValue(); _lValue=lValue; hasSetValue(); } long PropertyInteger::getValue(void) const { return _lValue; } PyObject *PropertyInteger::getPyObject(void) { return Py_BuildValue("l", _lValue); } void PropertyInteger::setPyObject(PyObject *value) { if (PyInt_Check(value)) { aboutToSetValue(); _lValue = PyInt_AsLong(value); hasSetValue(); } else { std::string error = std::string("type must be int, not "); error += value->ob_type->tp_name; throw Py::TypeError(error); } } void PropertyInteger::Save (Base::Writer &writer) const { writer.Stream() << writer.ind() << "" << std::endl; } void PropertyInteger::Restore(Base::XMLReader &reader) { // read my Element reader.readElement("Integer"); // get the value of my Attribute setValue(reader.getAttributeAsInteger("value")); } Property *PropertyInteger::Copy(void) const { PropertyInteger *p= new PropertyInteger(); p->_lValue = _lValue; return p; } void PropertyInteger::Paste(const Property &from) { aboutToSetValue(); _lValue = dynamic_cast(from)._lValue; hasSetValue(); } //************************************************************************** //************************************************************************** // PropertyPath //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyPath , App::Property); //************************************************************************** // Construction/Destruction PropertyPath::PropertyPath() { } PropertyPath::~PropertyPath() { } //************************************************************************** // Base class implementer //************************************************************************** // Setter/getter for the property void PropertyPath::setValue(const boost::filesystem::path &Path) { aboutToSetValue(); _cValue = Path; hasSetValue(); } void PropertyPath::setValue(const char * Path) { aboutToSetValue(); #if (BOOST_VERSION < 104600) || (BOOST_FILESYSTEM_VERSION == 2) _cValue = boost::filesystem::path(Path,boost::filesystem::no_check ); //_cValue = boost::filesystem::path(Path,boost::filesystem::native ); //_cValue = boost::filesystem::path(Path,boost::filesystem::windows_name ); #else _cValue = boost::filesystem::path(Path); #endif hasSetValue(); } boost::filesystem::path PropertyPath::getValue(void) const { return _cValue; } PyObject *PropertyPath::getPyObject(void) { #if (BOOST_VERSION < 104600) || (BOOST_FILESYSTEM_VERSION == 2) std::string str = _cValue.native_file_string(); #else std::string str = _cValue.string(); #endif // Returns a new reference, don't increment it! PyObject *p = PyUnicode_DecodeUTF8(str.c_str(),str.size(),0); if (!p) throw Base::Exception("UTF8 conversion failure at PropertyPath::getPyObject()"); return p; } void PropertyPath::setPyObject(PyObject *value) { std::string path; if (PyUnicode_Check(value)) { PyObject* unicode = PyUnicode_AsUTF8String(value); path = PyString_AsString(unicode); Py_DECREF(unicode); } else if (PyString_Check(value)) { path = PyString_AsString(value); } else { std::string error = std::string("type must be str or unicode, not "); error += value->ob_type->tp_name; throw Py::TypeError(error); } // assign the path setValue(path.c_str()); } void PropertyPath::Save (Base::Writer &writer) const { std::string val = encodeAttribute(_cValue.string()); writer.Stream() << writer.ind() << "" << std::endl; } void PropertyPath::Restore(Base::XMLReader &reader) { // read my Element reader.readElement("Path"); // get the value of my Attribute setValue(reader.getAttribute("value")); } Property *PropertyPath::Copy(void) const { PropertyPath *p= new PropertyPath(); p->_cValue = _cValue; return p; } void PropertyPath::Paste(const Property &from) { aboutToSetValue(); _cValue = dynamic_cast(from)._cValue; hasSetValue(); } unsigned int PropertyPath::getMemSize (void) const { return static_cast(_cValue.string().size()); } //************************************************************************** //************************************************************************** // PropertyEnumeration //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyEnumeration, App::PropertyInteger); //************************************************************************** // Construction/Destruction PropertyEnumeration::PropertyEnumeration() : _CustomEnum(false), _EnumArray(0) { } PropertyEnumeration::~PropertyEnumeration() { } void PropertyEnumeration::setEnums(const char** plEnums) { _EnumArray = plEnums; # ifdef FC_DEBUG if (_EnumArray) { // check for NULL termination const char* p = *_EnumArray; unsigned int i=0; while(*(p++) != NULL)i++; // very unlikely to have enums with more then 5000 entries! assert(i<5000); } # endif } void PropertyEnumeration::setValue(const char* value) { // using string methods without set, use setEnums(const char** plEnums) first! assert(_EnumArray); // set zero if there is no enum array if(!_EnumArray){ PropertyInteger::setValue(0); return; } unsigned int i=0; const char** plEnums = _EnumArray; // search for the right entry while(1){ // end of list? set zero if(*plEnums==NULL){ PropertyInteger::setValue(0); break; } if(strcmp(*plEnums,value)==0){ PropertyInteger::setValue(i); break; } plEnums++; i++; } } void PropertyEnumeration::setValue(long value) { # ifdef FC_DEBUG assert(value>=0 && value<5000); if(_EnumArray){ const char** plEnums = _EnumArray; long i=0; while(*(plEnums++) != NULL)i++; // very unlikely to have enums with more then 5000 entries! // Note: Do NOT call assert() because this code might be executed from Python console! if ( value < 0 || i <= value ) throw Base::Exception("Out of range"); } # endif PropertyInteger::setValue(value); } /// checks if the property is set to a certain string value bool PropertyEnumeration::isValue(const char* value) const { // using string methods without set, use setEnums(const char** plEnums) first! assert(_EnumArray); return strcmp(_EnumArray[getValue()],value)==0; } /// checks if a string is included in the enumeration bool PropertyEnumeration::isPartOf(const char* value) const { // using string methods without set, use setEnums(const char** plEnums) first! assert(_EnumArray); const char** plEnums = _EnumArray; // search for the right entry while(1){ // end of list? if(*plEnums==NULL) return false; if(strcmp(*plEnums,value)==0) return true; plEnums++; } } /// get the value as string const char* PropertyEnumeration::getValueAsString(void) const { // using string methods without set, use setEnums(const char** plEnums) first! assert(_EnumArray); return _EnumArray[getValue()]; } std::vector PropertyEnumeration::getEnumVector(void) const { // using string methods without set, use setEnums(const char** plEnums) first! assert(_EnumArray); std::vector result; const char** plEnums = _EnumArray; // end of list? while(*plEnums!=NULL){ result.push_back(*plEnums); plEnums++; } return result; } void PropertyEnumeration::setEnumVector(const std::vector& values) { delete [] _EnumArray; _EnumArray = new const char*[values.size()+1]; int i=0; for (std::vector::const_iterator it = values.begin(); it != values.end(); ++it) { #if defined (_MSC_VER) _EnumArray[i++] = _strdup(it->c_str()); #else _EnumArray[i++] = strdup(it->c_str()); #endif } _EnumArray[i] = 0; // null termination } const char** PropertyEnumeration::getEnums(void) const { return _EnumArray; } void PropertyEnumeration::Save(Base::Writer &writer) const { writer.Stream() << writer.ind() << "" << std::endl; if (_CustomEnum) { std::vector items = getEnumVector(); writer.Stream() << writer.ind() << "" << endl; writer.incInd(); for(std::vector::iterator it = items.begin(); it != items.end(); ++it) { std::string val = encodeAttribute(*it); writer.Stream() << writer.ind() << "" << endl; } writer.decInd(); writer.Stream() << writer.ind() << "" << endl; } } void PropertyEnumeration::Restore(Base::XMLReader &reader) { // read my Element reader.readElement("Integer"); // get the value of my Attribute long val = reader.getAttributeAsInteger("value"); if (reader.hasAttribute("CustomEnum")) { reader.readElement("CustomEnumList"); int count = reader.getAttributeAsInteger("count"); std::vector values(count); for(int i = 0; i < count; i++) { reader.readElement("Enum"); values[i] = reader.getAttribute("value"); } reader.readEndElement("CustomEnumList"); _CustomEnum = true; setEnumVector(values); } setValue(val); } PyObject *PropertyEnumeration::getPyObject(void) { if (!_EnumArray) { PyErr_SetString(PyExc_AssertionError, "The enum is empty"); return 0; } return Py_BuildValue("s", getValueAsString()); } void PropertyEnumeration::setPyObject(PyObject *value) { if (PyInt_Check(value)) { long val = PyInt_AsLong(value); if(_EnumArray){ const char** plEnums = _EnumArray; long i=0; while(*(plEnums++) != NULL)i++; if (val < 0 || i <= val) throw Py::ValueError("Out of range"); PropertyInteger::setValue(val); } } else if (PyString_Check(value)) { const char* str = PyString_AsString (value); if (isPartOf(str)) setValue(PyString_AsString (value)); else throw Py::ValueError("not a member of the enum"); } else if (PyList_Check(value)) { Py_ssize_t nSize = PyList_Size(value); std::vector values; values.resize(nSize); for (Py_ssize_t i=0; iob_type->tp_name; throw Py::TypeError(error); } values[i] = PyString_AsString(item); } _CustomEnum = true; setEnumVector(values); setValue((long)0); } else { std::string error = std::string("type must be int or str, not "); error += value->ob_type->tp_name; throw Py::TypeError(error); } } //************************************************************************** //************************************************************************** // PropertyIntegerConstraint //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyIntegerConstraint, App::PropertyInteger); //************************************************************************** // Construction/Destruction PropertyIntegerConstraint::PropertyIntegerConstraint() : _ConstStruct(0) { } PropertyIntegerConstraint::~PropertyIntegerConstraint() { } void PropertyIntegerConstraint::setConstraints(const Constraints* sConstrain) { _ConstStruct = sConstrain; } const PropertyIntegerConstraint::Constraints* PropertyIntegerConstraint::getConstraints(void) const { return _ConstStruct; } void PropertyIntegerConstraint::setPyObject(PyObject *value) { if (PyInt_Check(value)) { long temp = PyInt_AsLong(value); if (_ConstStruct) { if (temp > _ConstStruct->UpperBound) temp = _ConstStruct->UpperBound; else if(temp < _ConstStruct->LowerBound) temp = _ConstStruct->LowerBound; } aboutToSetValue(); _lValue = temp; hasSetValue(); } else { std::string error = std::string("type must be int, not "); error += value->ob_type->tp_name; throw Py::TypeError(error); } } //************************************************************************** //************************************************************************** // PropertyPercent //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyPercent , App::PropertyIntegerConstraint); const PropertyIntegerConstraint::Constraints percent = {0,100,1}; //************************************************************************** // Construction/Destruction PropertyPercent::PropertyPercent() { _ConstStruct = &percent; } PropertyPercent::~PropertyPercent() { } //************************************************************************** //************************************************************************** // PropertyIntegerList //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyIntegerList , App::PropertyLists); //************************************************************************** // Construction/Destruction PropertyIntegerList::PropertyIntegerList() { } PropertyIntegerList::~PropertyIntegerList() { } void PropertyIntegerList::setSize(int newSize) { _lValueList.resize(newSize); } int PropertyIntegerList::getSize(void) const { return static_cast(_lValueList.size()); } //************************************************************************** // Base class implementer void PropertyIntegerList::setValue(long lValue) { aboutToSetValue(); _lValueList.resize(1); _lValueList[0]=lValue; hasSetValue(); } void PropertyIntegerList::setValues(const std::vector& values) { aboutToSetValue(); _lValueList = values; hasSetValue(); } PyObject *PropertyIntegerList::getPyObject(void) { PyObject* list = PyList_New(getSize()); for(int i = 0;i values; values.resize(nSize); for (Py_ssize_t i=0; iob_type->tp_name; throw Py::TypeError(error); } values[i] = PyInt_AsLong(item); } setValues(values); } else if (PyInt_Check(value)) { setValue(PyInt_AsLong(value)); } else { std::string error = std::string("type must be int or list of int, not "); error += value->ob_type->tp_name; throw Py::TypeError(error); } } void PropertyIntegerList::Save (Base::Writer &writer) const { writer.Stream() << writer.ind() << "" << endl; writer.incInd(); for(int i = 0;i" << endl; ; writer.decInd(); writer.Stream() << writer.ind() << "" << endl ; } void PropertyIntegerList::Restore(Base::XMLReader &reader) { // read my Element reader.readElement("IntegerList"); // get the value of my Attribute int count = reader.getAttributeAsInteger("count"); std::vector values(count); for(int i = 0; i < count; i++) { reader.readElement("I"); values[i] = reader.getAttributeAsInteger("v"); } reader.readEndElement("IntegerList"); //assignment setValues(values); } Property *PropertyIntegerList::Copy(void) const { PropertyIntegerList *p= new PropertyIntegerList(); p->_lValueList = _lValueList; return p; } void PropertyIntegerList::Paste(const Property &from) { aboutToSetValue(); _lValueList = dynamic_cast(from)._lValueList; hasSetValue(); } unsigned int PropertyIntegerList::getMemSize (void) const { return static_cast(_lValueList.size() * sizeof(long)); } //************************************************************************** //************************************************************************** // PropertyFloat //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyFloat , App::Property); //************************************************************************** // Construction/Destruction PropertyFloat::PropertyFloat() { _dValue = 0.0; } PropertyFloat::~PropertyFloat() { } //************************************************************************** // Base class implementer void PropertyFloat::setValue(float lValue) { aboutToSetValue(); _dValue=lValue; hasSetValue(); } float PropertyFloat::getValue(void) const { return _dValue; } PyObject *PropertyFloat::getPyObject(void) { return Py_BuildValue("d", _dValue); } void PropertyFloat::setPyObject(PyObject *value) { if (PyFloat_Check(value)) { aboutToSetValue(); _dValue = (float) PyFloat_AsDouble(value); hasSetValue(); } else if(PyInt_Check(value)) { aboutToSetValue(); _dValue = (float) PyInt_AsLong(value); hasSetValue(); } else { std::string error = std::string("type must be float or int, not "); error += value->ob_type->tp_name; throw Py::TypeError(error); } } void PropertyFloat::Save (Base::Writer &writer) const { writer.Stream() << writer.ind() << "" << std::endl; } void PropertyFloat::Restore(Base::XMLReader &reader) { // read my Element reader.readElement("Float"); // get the value of my Attribute setValue((float)reader.getAttributeAsFloat("value")); } Property *PropertyFloat::Copy(void) const { PropertyFloat *p= new PropertyFloat(); p->_dValue = _dValue; return p; } void PropertyFloat::Paste(const Property &from) { aboutToSetValue(); _dValue = dynamic_cast(from)._dValue; hasSetValue(); } //************************************************************************** //************************************************************************** // PropertyFloatConstraint //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyFloatConstraint, App::PropertyFloat); //************************************************************************** // Construction/Destruction PropertyFloatConstraint::PropertyFloatConstraint() : _ConstStruct(0) { } PropertyFloatConstraint::~PropertyFloatConstraint() { } void PropertyFloatConstraint::setConstraints(const Constraints* sConstrain) { _ConstStruct = sConstrain; } const PropertyFloatConstraint::Constraints* PropertyFloatConstraint::getConstraints(void) const { return _ConstStruct; } void PropertyFloatConstraint::setPyObject(PyObject *value) { if (PyFloat_Check(value)) { float temp = (float)PyFloat_AsDouble(value); if (_ConstStruct) { if (temp > _ConstStruct->UpperBound) temp = _ConstStruct->UpperBound; else if (temp < _ConstStruct->LowerBound) temp = _ConstStruct->LowerBound; } aboutToSetValue(); _dValue = temp; hasSetValue(); } else if (PyInt_Check(value)) { float temp = (float)PyInt_AsLong(value); if (_ConstStruct) { if (temp > _ConstStruct->UpperBound) temp = _ConstStruct->UpperBound; else if (temp < _ConstStruct->LowerBound) temp = _ConstStruct->LowerBound; } aboutToSetValue(); _dValue = temp; hasSetValue(); } else { std::string error = std::string("type must be float, not "); error += value->ob_type->tp_name; throw Py::TypeError(error); } } //************************************************************************** // PropertyFloatList //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyFloatList , App::PropertyLists); //************************************************************************** // Construction/Destruction PropertyFloatList::PropertyFloatList() { } PropertyFloatList::~PropertyFloatList() { } //************************************************************************** // Base class implementer void PropertyFloatList::setSize(int newSize) { _lValueList.resize(newSize); } int PropertyFloatList::getSize(void) const { return static_cast(_lValueList.size()); } void PropertyFloatList::setValue(float lValue) { aboutToSetValue(); _lValueList.resize(1); _lValueList[0]=lValue; hasSetValue(); } void PropertyFloatList::setValues(const std::vector& values) { aboutToSetValue(); _lValueList = values; hasSetValue(); } PyObject *PropertyFloatList::getPyObject(void) { PyObject* list = PyList_New(getSize()); for (int i = 0;i values; values.resize(nSize); for (Py_ssize_t i=0; iob_type->tp_name; throw Py::TypeError(error); } values[i] = (float) PyFloat_AsDouble(item); } setValues(values); } else if (PyFloat_Check(value)) { setValue((float) PyFloat_AsDouble(value)); } else { std::string error = std::string("type must be float or list of float, not "); error += value->ob_type->tp_name; throw Py::TypeError(error); } } void PropertyFloatList::Save (Base::Writer &writer) const { if (writer.isForceXML()) { writer.Stream() << writer.ind() << "" << endl; writer.incInd(); for(int i = 0;i" << endl; ; writer.decInd(); writer.Stream() << writer.ind() <<"" << endl ; } else { writer.Stream() << writer.ind() << "" << std::endl; } } void PropertyFloatList::Restore(Base::XMLReader &reader) { reader.readElement("FloatList"); string file (reader.getAttribute("file") ); if (!file.empty()) { // initate a file read reader.addFile(file.c_str(),this); } } void PropertyFloatList::SaveDocFile (Base::Writer &writer) const { Base::OutputStream str(writer.Stream()); uint32_t uCt = (uint32_t)getSize(); str << uCt; for (std::vector::const_iterator it = _lValueList.begin(); it != _lValueList.end(); ++it) { str << *it; } } void PropertyFloatList::RestoreDocFile(Base::Reader &reader) { Base::InputStream str(reader); uint32_t uCt=0; str >> uCt; std::vector values(uCt); for (std::vector::iterator it = values.begin(); it != values.end(); ++it) { str >> *it; } setValues(values); } Property *PropertyFloatList::Copy(void) const { PropertyFloatList *p= new PropertyFloatList(); p->_lValueList = _lValueList; return p; } void PropertyFloatList::Paste(const Property &from) { aboutToSetValue(); _lValueList = dynamic_cast(from)._lValueList; hasSetValue(); } unsigned int PropertyFloatList::getMemSize (void) const { return static_cast(_lValueList.size() * sizeof(float)); } //************************************************************************** //************************************************************************** // PropertyString //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyString , App::Property); PropertyString::PropertyString() { } PropertyString::~PropertyString() { } void PropertyString::setValue(const char* sString) { if (sString) { aboutToSetValue(); _cValue = sString; hasSetValue(); } } void PropertyString::setValue(const std::string &sString) { aboutToSetValue(); _cValue = sString; hasSetValue(); } const char* PropertyString::getValue(void) const { return _cValue.c_str(); } PyObject *PropertyString::getPyObject(void) { PyObject *p = PyUnicode_DecodeUTF8(_cValue.c_str(),_cValue.size(),0); if (!p) throw Base::Exception("UTF8 conversion failure at PropertyString::getPyObject()"); return p; } void PropertyString::setPyObject(PyObject *value) { std::string string; if (PyUnicode_Check(value)) { PyObject* unicode = PyUnicode_AsUTF8String(value); string = PyString_AsString(unicode); Py_DECREF(unicode); } else if (PyString_Check(value)) { string = PyString_AsString(value); } else { std::string error = std::string("type must be str or unicode, not "); error += value->ob_type->tp_name; throw Py::TypeError(error); } // assign the string setValue(string); } void PropertyString::Save (Base::Writer &writer) const { std::string val = encodeAttribute(_cValue); writer.Stream() << writer.ind() << "" << std::endl; } void PropertyString::Restore(Base::XMLReader &reader) { // read my Element reader.readElement("String"); // get the value of my Attribute setValue(reader.getAttribute("value")); } Property *PropertyString::Copy(void) const { PropertyString *p= new PropertyString(); p->_cValue = _cValue; return p; } void PropertyString::Paste(const Property &from) { aboutToSetValue(); _cValue = dynamic_cast(from)._cValue; hasSetValue(); } unsigned int PropertyString::getMemSize (void) const { return static_cast(_cValue.size()); } //************************************************************************** // PropertyFont //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyFont , App::PropertyString); PropertyFont::PropertyFont() { } PropertyFont::~PropertyFont() { } //************************************************************************** // PropertyStringList //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyStringList , App::PropertyLists); PropertyStringList::PropertyStringList() { } PropertyStringList::~PropertyStringList() { } //************************************************************************** // Base class implementer void PropertyStringList::setSize(int newSize) { _lValueList.resize(newSize); } int PropertyStringList::getSize(void) const { return static_cast(_lValueList.size()); } void PropertyStringList::setValue(const std::string& lValue) { aboutToSetValue(); _lValueList.resize(1); _lValueList[0]=lValue; hasSetValue(); } void PropertyStringList::setValues(const std::vector& lValue) { aboutToSetValue(); _lValueList=lValue; hasSetValue(); } void PropertyStringList::setValues(const std::list& lValue) { aboutToSetValue(); _lValueList.resize(lValue.size()); std::copy(lValue.begin(), lValue.end(), _lValueList.begin()); hasSetValue(); } PyObject *PropertyStringList::getPyObject(void) { PyObject* list = PyList_New(getSize()); for (int i = 0;i values; values.resize(nSize); for (Py_ssize_t i=0; iob_type->tp_name; throw Py::TypeError(error); } } setValues(values); } else if (PyString_Check(value)) { setValue(PyString_AsString(value)); } else { std::string error = std::string("type must be str or list of str, not "); error += value->ob_type->tp_name; throw Py::TypeError(error); } } unsigned int PropertyStringList::getMemSize (void) const { size_t size=0; for(int i = 0;i(size); } void PropertyStringList::Save (Base::Writer &writer) const { writer.Stream() << writer.ind() << "" << endl; writer.incInd(); for(int i = 0;i" << endl; } writer.decInd(); writer.Stream() << writer.ind() << "" << endl ; } void PropertyStringList::Restore(Base::XMLReader &reader) { // read my Element reader.readElement("StringList"); // get the value of my Attribute int count = reader.getAttributeAsInteger("count"); std::vector values(count); for(int i = 0; i < count; i++) { reader.readElement("String"); values[i] = reader.getAttribute("value"); } reader.readEndElement("StringList"); // assignment setValues(values); } Property *PropertyStringList::Copy(void) const { PropertyStringList *p= new PropertyStringList(); p->_lValueList = _lValueList; return p; } void PropertyStringList::Paste(const Property &from) { aboutToSetValue(); _lValueList = dynamic_cast(from)._lValueList; hasSetValue(); } //************************************************************************** //************************************************************************** // PropertyBool //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyBool , App::Property); //************************************************************************** // Construction/Destruction PropertyBool::PropertyBool() { _lValue = false; } PropertyBool::~PropertyBool() { } //************************************************************************** // Setter/getter for the property void PropertyBool::setValue(bool lValue) { aboutToSetValue(); _lValue=lValue; hasSetValue(); } bool PropertyBool::getValue(void) const { return _lValue; } PyObject *PropertyBool::getPyObject(void) { if (_lValue) {Py_INCREF(Py_True); return Py_True;} else {Py_INCREF(Py_False); return Py_False;} } void PropertyBool::setPyObject(PyObject *value) { if (PyBool_Check(value)) setValue(PyObject_IsTrue(value)!=0); else if(PyInt_Check(value)) setValue(PyInt_AsLong(value)!=0); else { std::string error = std::string("type must be bool, not "); error += value->ob_type->tp_name; throw Py::TypeError(error); } } void PropertyBool::Save (Base::Writer &writer) const { writer.Stream() << writer.ind() << "" ; else writer.Stream() << "false" <<"\"/>" ; writer.Stream() << std::endl; } void PropertyBool::Restore(Base::XMLReader &reader) { // read my Element reader.readElement("Bool"); // get the value of my Attribute string b = reader.getAttribute("value"); (b == "true") ? setValue(true) : setValue(false); } Property *PropertyBool::Copy(void) const { PropertyBool *p= new PropertyBool(); p->_lValue = _lValue; return p; } void PropertyBool::Paste(const Property &from) { aboutToSetValue(); _lValue = dynamic_cast(from)._lValue; hasSetValue(); } //************************************************************************** //************************************************************************** // PropertyColor //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyColor , App::Property); //************************************************************************** // Construction/Destruction PropertyColor::PropertyColor() { } PropertyColor::~PropertyColor() { } //************************************************************************** // Base class implementer void PropertyColor::setValue(const Color &col) { aboutToSetValue(); _cCol=col; hasSetValue(); } void PropertyColor::setValue(uint32_t rgba) { aboutToSetValue(); _cCol.setPackedValue(rgba); hasSetValue(); } void PropertyColor::setValue(float r, float g, float b, float a) { aboutToSetValue(); _cCol.set(r,g,b,a); hasSetValue(); } const Color& PropertyColor::getValue(void) const { return _cCol; } PyObject *PropertyColor::getPyObject(void) { PyObject* rgba = PyTuple_New(4); PyObject* r = PyFloat_FromDouble(_cCol.r); PyObject* g = PyFloat_FromDouble(_cCol.g); PyObject* b = PyFloat_FromDouble(_cCol.b); PyObject* a = PyFloat_FromDouble(_cCol.a); PyTuple_SetItem(rgba, 0, r); PyTuple_SetItem(rgba, 1, g); PyTuple_SetItem(rgba, 2, b); PyTuple_SetItem(rgba, 3, a); return rgba; } void PropertyColor::setPyObject(PyObject *value) { App::Color cCol; if (PyTuple_Check(value) && PyTuple_Size(value) == 3) { PyObject* item; item = PyTuple_GetItem(value,0); if (PyFloat_Check(item)) cCol.r = (float)PyFloat_AsDouble(item); else throw Base::Exception("Type in tuple must be float"); item = PyTuple_GetItem(value,1); if (PyFloat_Check(item)) cCol.g = (float)PyFloat_AsDouble(item); else throw Base::Exception("Type in tuple must be float"); item = PyTuple_GetItem(value,2); if (PyFloat_Check(item)) cCol.b = (float)PyFloat_AsDouble(item); else throw Base::Exception("Type in tuple must be float"); } else if (PyTuple_Check(value) && PyTuple_Size(value) == 4) { PyObject* item; item = PyTuple_GetItem(value,0); if (PyFloat_Check(item)) cCol.r = (float)PyFloat_AsDouble(item); else throw Base::Exception("Type in tuple must be float"); item = PyTuple_GetItem(value,1); if (PyFloat_Check(item)) cCol.g = (float)PyFloat_AsDouble(item); else throw Base::Exception("Type in tuple must be float"); item = PyTuple_GetItem(value,2); if (PyFloat_Check(item)) cCol.b = (float)PyFloat_AsDouble(item); else throw Base::Exception("Type in tuple must be float"); item = PyTuple_GetItem(value,3); if (PyFloat_Check(item)) cCol.a = (float)PyFloat_AsDouble(item); else throw Base::Exception("Type in tuple must be float"); } else if (PyLong_Check(value)) { cCol.setPackedValue(PyLong_AsUnsignedLong(value)); } else { std::string error = std::string("type must be int or tuple of float, not "); error += value->ob_type->tp_name; throw Py::TypeError(error); } setValue( cCol ); } void PropertyColor::Save (Base::Writer &writer) const { writer.Stream() << writer.ind() << "" << endl; } void PropertyColor::Restore(Base::XMLReader &reader) { // read my Element reader.readElement("PropertyColor"); // get the value of my Attribute unsigned long rgba = reader.getAttributeAsUnsigned("value"); setValue(rgba); } Property *PropertyColor::Copy(void) const { PropertyColor *p= new PropertyColor(); p->_cCol = _cCol; return p; } void PropertyColor::Paste(const Property &from) { aboutToSetValue(); _cCol = dynamic_cast(from)._cCol; hasSetValue(); } //************************************************************************** // PropertyColorList //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyColorList , App::PropertyLists); //************************************************************************** // Construction/Destruction PropertyColorList::PropertyColorList() { } PropertyColorList::~PropertyColorList() { } //************************************************************************** // Base class implementer void PropertyColorList::setSize(int newSize) { _lValueList.resize(newSize); } int PropertyColorList::getSize(void) const { return static_cast(_lValueList.size()); } void PropertyColorList::setValue(const Color& lValue) { aboutToSetValue(); _lValueList.resize(1); _lValueList[0]=lValue; hasSetValue(); } void PropertyColorList::setValues (const std::vector& values) { aboutToSetValue(); _lValueList=values; hasSetValue(); } PyObject *PropertyColorList::getPyObject(void) { PyObject* list = PyList_New(getSize()); for(int i = 0;i values; values.resize(nSize); for (Py_ssize_t i=0; iob_type->tp_name; throw Py::TypeError(error); } } void PropertyColorList::Save (Base::Writer &writer) const { if (!writer.isForceXML()) { writer.Stream() << writer.ind() << "" << std::endl; } } void PropertyColorList::Restore(Base::XMLReader &reader) { reader.readElement("ColorList"); if (reader.hasAttribute("file")) { std::string file (reader.getAttribute("file")); if (!file.empty()) { // initate a file read reader.addFile(file.c_str(),this); } } } void PropertyColorList::SaveDocFile (Base::Writer &writer) const { Base::OutputStream str(writer.Stream()); uint32_t uCt = (uint32_t)getSize(); str << uCt; for (std::vector::const_iterator it = _lValueList.begin(); it != _lValueList.end(); ++it) { str << it->getPackedValue(); } } void PropertyColorList::RestoreDocFile(Base::Reader &reader) { Base::InputStream str(reader); uint32_t uCt=0; str >> uCt; std::vector values(uCt); uint32_t value; // must be 32 bit long for (std::vector::iterator it = values.begin(); it != values.end(); ++it) { str >> value; it->setPackedValue(value); } setValues(values); } Property *PropertyColorList::Copy(void) const { PropertyColorList *p= new PropertyColorList(); p->_lValueList = _lValueList; return p; } void PropertyColorList::Paste(const Property &from) { aboutToSetValue(); _lValueList = dynamic_cast(from)._lValueList; hasSetValue(); } unsigned int PropertyColorList::getMemSize (void) const { return static_cast(_lValueList.size() * sizeof(Color)); } //************************************************************************** //************************************************************************** // PropertyMaterial //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ TYPESYSTEM_SOURCE(App::PropertyMaterial , App::Property); PropertyMaterial::PropertyMaterial() { } PropertyMaterial::~PropertyMaterial() { } void PropertyMaterial::setValue(const Material &mat) { aboutToSetValue(); _cMat=mat; hasSetValue(); } const Material& PropertyMaterial::getValue(void) const { return _cMat; } void PropertyMaterial::setAmbientColor(const Color& col) { aboutToSetValue(); _cMat.ambientColor = col; hasSetValue(); } void PropertyMaterial::setDiffuseColor(const Color& col) { aboutToSetValue(); _cMat.diffuseColor = col; hasSetValue(); } void PropertyMaterial::setSpecularColor(const Color& col) { aboutToSetValue(); _cMat.specularColor = col; hasSetValue(); } void PropertyMaterial::setEmissiveColor(const Color& col) { aboutToSetValue(); _cMat.emissiveColor = col; hasSetValue(); } void PropertyMaterial::setShininess(float val) { aboutToSetValue(); _cMat.shininess = val; hasSetValue(); } void PropertyMaterial::setTransparency(float val) { aboutToSetValue(); _cMat.transparency = val; hasSetValue(); } PyObject *PropertyMaterial::getPyObject(void) { return new MaterialPy(new Material(_cMat)); } void PropertyMaterial::setPyObject(PyObject *value) { if (PyObject_TypeCheck(value, &(MaterialPy::Type))) { setValue(*static_cast(value)->getMaterialPtr()); } else { std::string error = std::string("type must be 'Material', not "); error += value->ob_type->tp_name; throw Py::TypeError(error); } } void PropertyMaterial::Save (Base::Writer &writer) const { writer.Stream() << writer.ind() << "" << endl; } void PropertyMaterial::Restore(Base::XMLReader &reader) { // read my Element reader.readElement("PropertyMaterial"); // get the value of my Attribute aboutToSetValue(); _cMat.ambientColor.setPackedValue(reader.getAttributeAsUnsigned("ambientColor")); _cMat.diffuseColor.setPackedValue(reader.getAttributeAsUnsigned("diffuseColor")); _cMat.specularColor.setPackedValue(reader.getAttributeAsUnsigned("specularColor")); _cMat.emissiveColor.setPackedValue(reader.getAttributeAsUnsigned("emissiveColor")); _cMat.shininess = (float)reader.getAttributeAsFloat("shininess"); _cMat.transparency = (float)reader.getAttributeAsFloat("transparency"); hasSetValue(); } Property *PropertyMaterial::Copy(void) const { PropertyMaterial *p= new PropertyMaterial(); p->_cMat = _cMat; return p; } void PropertyMaterial::Paste(const Property &from) { aboutToSetValue(); _cMat = dynamic_cast(from)._cMat; hasSetValue(); }