Refactored PropertyEnumeration
This commit is contained in:
@@ -147,6 +147,7 @@ SET(FreeCADApp_CPP_SRCS
|
||||
ColorModel.cpp
|
||||
ComplexGeoData.cpp
|
||||
ComplexGeoDataPyImp.cpp
|
||||
Enumeration.cpp
|
||||
Material.cpp
|
||||
MaterialPyImp.cpp
|
||||
)
|
||||
@@ -157,6 +158,7 @@ SET(FreeCADApp_HPP_SRCS
|
||||
Application.h
|
||||
ColorModel.h
|
||||
ComplexGeoData.h
|
||||
Enumeration.h
|
||||
Material.h
|
||||
)
|
||||
|
||||
|
||||
331
src/App/Enumeration.cpp
Normal file
331
src/App/Enumeration.cpp
Normal file
@@ -0,0 +1,331 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) Ian Rees (ian.rees@gmail.com) 2015 *
|
||||
* *
|
||||
* 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"
|
||||
|
||||
#include <Base/Exception.h>
|
||||
|
||||
#include "Enumeration.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
using namespace App;
|
||||
|
||||
Enumeration::Enumeration()
|
||||
: _EnumArray(NULL), _ownEnumArray(false), _index(0), _maxVal(-1)
|
||||
{
|
||||
}
|
||||
|
||||
Enumeration::Enumeration(const Enumeration &other)
|
||||
{
|
||||
if (other._ownEnumArray) {
|
||||
setEnums(other.getEnumVector());
|
||||
} else {
|
||||
_EnumArray = other._EnumArray;
|
||||
}
|
||||
|
||||
_ownEnumArray = other._ownEnumArray;
|
||||
_index = other._index;
|
||||
_maxVal = other._maxVal;
|
||||
}
|
||||
|
||||
Enumeration::Enumeration(const char *valStr)
|
||||
: _ownEnumArray(true), _index(0), _maxVal(0)
|
||||
{
|
||||
_EnumArray = new const char*[2];
|
||||
#if defined (_MSC_VER)
|
||||
_EnumArray[0] = _strdup(valStr);
|
||||
#else
|
||||
_EnumArray[0] = strdup(valStr);
|
||||
#endif
|
||||
_EnumArray[1] = NULL;
|
||||
}
|
||||
|
||||
Enumeration::Enumeration(const char **list, const char *valStr)
|
||||
: _EnumArray(list), _ownEnumArray(false)
|
||||
{
|
||||
findMaxVal();
|
||||
setValue(valStr);
|
||||
}
|
||||
|
||||
Enumeration::~Enumeration()
|
||||
{
|
||||
if (_ownEnumArray) {
|
||||
if (_EnumArray != NULL) {
|
||||
tearDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Enumeration::tearDown(void)
|
||||
{
|
||||
// Ugly...
|
||||
char **plEnums = (char **)_EnumArray;
|
||||
|
||||
// Delete C Strings first
|
||||
while (*(plEnums++) != NULL) {
|
||||
free(*plEnums);
|
||||
}
|
||||
|
||||
delete [] _EnumArray;
|
||||
|
||||
_EnumArray = NULL;
|
||||
_ownEnumArray = false;
|
||||
_maxVal = -1;
|
||||
}
|
||||
|
||||
void Enumeration::setEnums(const char **plEnums)
|
||||
{
|
||||
std::string oldValue;
|
||||
bool preserve = (isValid() && plEnums != NULL);
|
||||
if (preserve) {
|
||||
oldValue = getCStr();
|
||||
}
|
||||
|
||||
// set _ownEnumArray
|
||||
if (isValid() && _ownEnumArray) {
|
||||
tearDown();
|
||||
}
|
||||
|
||||
// set...
|
||||
_EnumArray = plEnums;
|
||||
|
||||
// set _maxVal
|
||||
findMaxVal();
|
||||
|
||||
// set _index
|
||||
_index = 0;
|
||||
if (preserve) {
|
||||
setValue(oldValue);
|
||||
}
|
||||
}
|
||||
|
||||
void Enumeration::setEnums(const std::vector<std::string> &values)
|
||||
{
|
||||
std::string oldValue;
|
||||
bool preserve = isValid();
|
||||
if (preserve) {
|
||||
oldValue = getCStr();
|
||||
}
|
||||
|
||||
if (isValid() && _ownEnumArray) {
|
||||
tearDown();
|
||||
}
|
||||
|
||||
_EnumArray = new const char*[values.size() + 1];
|
||||
int i = 0;
|
||||
for (std::vector<std::string>::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
|
||||
|
||||
// Other state variables
|
||||
_maxVal = values.size() - 1;
|
||||
_ownEnumArray = true;
|
||||
_index = 0;
|
||||
|
||||
if (preserve) {
|
||||
setValue(oldValue);
|
||||
}
|
||||
}
|
||||
|
||||
void Enumeration::setValue(const char *value)
|
||||
{
|
||||
// using string methods without set, use setEnums(const char** plEnums) first!
|
||||
assert(_EnumArray);
|
||||
|
||||
if (!_EnumArray) {
|
||||
_index = 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) {
|
||||
_index = 0;
|
||||
break;
|
||||
}
|
||||
if (strcmp(*plEnums, value) == 0) {
|
||||
_index = i;
|
||||
break;
|
||||
}
|
||||
++plEnums;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
void Enumeration::setValue(long value, bool checkRange)
|
||||
{
|
||||
if (value >= 0 && value <= _maxVal) {
|
||||
_index = value;
|
||||
} else {
|
||||
if (checkRange) {
|
||||
throw Base::ValueError("Out of range");
|
||||
} else {
|
||||
_index = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Enumeration::isValue(const char *value) const
|
||||
{
|
||||
// using string methods without set, use setEnums(const char** plEnums) first!
|
||||
assert(_EnumArray);
|
||||
|
||||
int i = getInt();
|
||||
|
||||
if (i == -1) {
|
||||
return false;
|
||||
} else {
|
||||
return strcmp(_EnumArray[i], value) == 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool Enumeration::contains(const char *value) const
|
||||
{
|
||||
// using string methods without set, use setEnums(const char** plEnums) first!
|
||||
assert(_EnumArray);
|
||||
|
||||
if (!isValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
const char * Enumeration::getCStr(void) const
|
||||
{
|
||||
// using string methods without set, use setEnums(const char** plEnums) first!
|
||||
assert(_EnumArray);
|
||||
|
||||
if (!isValid() || _index < 0 || _index > _maxVal) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return _EnumArray[_index];
|
||||
}
|
||||
|
||||
int Enumeration::getInt(void) const
|
||||
{
|
||||
if (!isValid() || _index < 0 || _index > _maxVal) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _index;
|
||||
}
|
||||
|
||||
std::vector<std::string> Enumeration::getEnumVector(void) const
|
||||
{
|
||||
// using string methods without set, use setEnums(const char** plEnums) first!
|
||||
assert(_EnumArray);
|
||||
|
||||
std::vector<std::string> result;
|
||||
const char **plEnums = _EnumArray;
|
||||
|
||||
// end of list?
|
||||
while (*plEnums != NULL) {
|
||||
result.push_back(*plEnums);
|
||||
++plEnums;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
const char ** Enumeration::getEnums(void) const
|
||||
{
|
||||
return _EnumArray;
|
||||
}
|
||||
|
||||
bool Enumeration::isValid(void) const
|
||||
{
|
||||
return (_EnumArray != NULL && _index >= 0 && _index <= _maxVal);
|
||||
}
|
||||
|
||||
Enumeration & Enumeration::operator=(const Enumeration &other)
|
||||
{
|
||||
if (other._ownEnumArray) {
|
||||
setEnums(other.getEnumVector());
|
||||
} else {
|
||||
_EnumArray = other._EnumArray;
|
||||
}
|
||||
|
||||
_ownEnumArray = other._ownEnumArray;
|
||||
_index = other._index;
|
||||
_maxVal = other._maxVal;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Enumeration::operator==(const Enumeration &other) const
|
||||
{
|
||||
if (getCStr() == NULL || other.getCStr() == NULL) {
|
||||
return false;
|
||||
}
|
||||
return (strcmp(getCStr(), other.getCStr()) == 0);
|
||||
}
|
||||
|
||||
bool Enumeration::operator==(const char *other) const
|
||||
{
|
||||
if (getCStr() == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (strcmp(getCStr(), other) == 0);
|
||||
}
|
||||
|
||||
void Enumeration::findMaxVal(void)
|
||||
{
|
||||
if (_EnumArray == NULL) {
|
||||
_maxVal = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
const char **plEnums = _EnumArray;
|
||||
long i = 0;
|
||||
while (*(plEnums++) != NULL) {
|
||||
++i;
|
||||
// very unlikely to have enums with more then 5000 entries!
|
||||
assert(i < 5000);
|
||||
}
|
||||
|
||||
_maxVal = i;
|
||||
}
|
||||
|
||||
197
src/App/Enumeration.h
Normal file
197
src/App/Enumeration.h
Normal file
@@ -0,0 +1,197 @@
|
||||
/***************************************************************************
|
||||
* Copyright (c) Ian Rees (ian.rees@gmail.com) 2015 *
|
||||
* *
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#ifndef BASE_ENUMERATION_H
|
||||
#define BASE_ENUMERATION_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//#include <App/PropertyStandard.h>
|
||||
|
||||
namespace App
|
||||
{
|
||||
class PropertyEnumeration;
|
||||
|
||||
/// A bidirectional string-integer mapping
|
||||
/*!
|
||||
* This is mainly intended for two purposes: working around the difficulty
|
||||
* in C++ of sharing enumerations between different source files,
|
||||
* namespaces, etc. and as the data type stored by App::PropertyEnumeration
|
||||
*
|
||||
* Internally, Enumeration maintains
|
||||
* -# Either a const pointer to an array of C-style strings, or a vector
|
||||
* of C++ std::strings
|
||||
* -# An integer index into that array/vector representing the string
|
||||
* representing the instance's value.
|
||||
*
|
||||
* If built with FC_DEBUG defined, some boundaries of passed in pointers
|
||||
* will be checked. Otherwise, the caller has the responsibility of
|
||||
* checking the limits of given indices.
|
||||
*
|
||||
* \todo Implement lazy copy
|
||||
*/
|
||||
class Enumeration
|
||||
{
|
||||
friend class App::PropertyEnumeration;
|
||||
public:
|
||||
/// Constructs an empty Enumeration object
|
||||
Enumeration();
|
||||
|
||||
/// Standard copy constructor
|
||||
Enumeration(const Enumeration& other);
|
||||
|
||||
/// Constructs an Enumeration with a single element
|
||||
Enumeration(const char *valStr);
|
||||
|
||||
/// Constructs an Enumeration using val within list
|
||||
Enumeration(const char **list, const char *valStr);
|
||||
|
||||
/// Standard destructor
|
||||
~Enumeration();
|
||||
|
||||
/** Sets the enumeration string list
|
||||
* The list is a NULL terminated array of pointers to const
|
||||
* char* strings.
|
||||
* \code
|
||||
* const char enums[] = {"Black","White","Other",NULL}
|
||||
* \endcode
|
||||
*
|
||||
* If Enumeration was already valid, will attempt to preserve
|
||||
* the string-representation value of the Enumeration
|
||||
*
|
||||
* Enumeration does not take ownership of the passed object
|
||||
*/
|
||||
void setEnums(const char **plEnums);
|
||||
|
||||
/// Set all enum values as vector of strings
|
||||
/*!
|
||||
* This method causes the Enumeration to dynamically allocate
|
||||
* it's own array of C Strings, which will be deleted by the
|
||||
* destructor or subsequent calls to setEnums(). So, it is
|
||||
* important to make sure the Enumeration stays in scope as
|
||||
* long as values returned by getCStr are in use.
|
||||
*
|
||||
* If Enumeration was already valid, will attempt to preserve
|
||||
* the string-representation value of the Enumeration
|
||||
*/
|
||||
void setEnums(const std::vector<std::string> &values);
|
||||
|
||||
/// Set the enum using a C string
|
||||
void setValue(const char *value);
|
||||
|
||||
/// Overload of setValue(const char *value)
|
||||
void setValue(const std::string &value) {setValue(value.c_str());}
|
||||
|
||||
/// Set the enum using a long
|
||||
/*!
|
||||
* if checkRange is set to true, throws Base::ValueError when
|
||||
* values are set out of range
|
||||
*
|
||||
* Checks for boundaries via assert()
|
||||
*/
|
||||
void setValue(long value, bool checkRange = false);
|
||||
|
||||
/// Checks if the property is set to a certain string value
|
||||
bool isValue(const char *value) const;
|
||||
|
||||
/// Checks if a string is included in the enumeration
|
||||
bool contains(const char *value) const;
|
||||
|
||||
/// Return the value as C string
|
||||
/*!
|
||||
* Returns NULL if the enumeration is invalid.
|
||||
*/
|
||||
const char * getCStr(void) const;
|
||||
|
||||
/// Return value as integer
|
||||
/*!
|
||||
* Returns -1 if the Enumeration isn't valid
|
||||
*/
|
||||
int getInt(void) const;
|
||||
|
||||
/// get all possible enum values as vector of strings
|
||||
std::vector<std::string> getEnumVector(void) const;
|
||||
|
||||
/// get pointer to the enum list
|
||||
const char ** getEnums(void) const;
|
||||
|
||||
/// Returns true if the instance is in a usable state
|
||||
bool isValid(void) const;
|
||||
|
||||
/// Returns the highest usable integer value for this enum
|
||||
/*!
|
||||
* Returns -1 if the enumeration is not valid according to isValid()
|
||||
*/
|
||||
int maxValue(void) const {return _maxVal;};
|
||||
|
||||
/// Assignment operator
|
||||
Enumeration & operator=(const Enumeration &other);
|
||||
|
||||
/// true iff our string representation matches other's
|
||||
/*!
|
||||
* Returns false if either Enumeration is not valid.
|
||||
*/
|
||||
bool operator==(const Enumeration &other) const;
|
||||
|
||||
/// true iff our string representation matches other
|
||||
/*!
|
||||
* Returns false if Enumeration is not valid.
|
||||
*/
|
||||
bool operator==(const char *other) const;
|
||||
protected:
|
||||
/// Returns true if instance was not initialized via static string list
|
||||
bool isCustom(void) const {return _ownEnumArray;};
|
||||
|
||||
/// Updates _maxVal
|
||||
void findMaxVal(void);
|
||||
|
||||
/// De-allocates memory used in _EnumArray
|
||||
/*!
|
||||
* Important to not call this unless this Enumeration owns array.
|
||||
*/
|
||||
void tearDown(void);
|
||||
|
||||
private:
|
||||
/// Handle to C Strings of possible enumeration values
|
||||
const char **_EnumArray;
|
||||
|
||||
/// Whether instance owns _EnumArray
|
||||
bool _ownEnumArray;
|
||||
|
||||
/// Integer value of the enumeration
|
||||
/*!
|
||||
* This serves as an index into _EnumArray to get the string
|
||||
* representation.
|
||||
*/
|
||||
int _index;
|
||||
|
||||
/*! Cached result from findMaxVal()
|
||||
* Value should either be the maximum allowable integer value for
|
||||
* the Enumeration, or -1 if not initialized
|
||||
*/
|
||||
int _maxVal;
|
||||
}; // class Enumeration
|
||||
} // namespace App
|
||||
|
||||
#endif // #ifndef BASE_ENUMERATION_H
|
||||
@@ -160,8 +160,9 @@ private:
|
||||
std::vector<Base::Vector3d> _lValueList;
|
||||
};
|
||||
|
||||
/** Vector properties
|
||||
* This is the father of all properties handling Integers.
|
||||
/// Property representing a 4x4 matrix
|
||||
/*!
|
||||
* Encapsulates a Base::Matrix4D in a Property
|
||||
*/
|
||||
class AppExport PropertyMatrix: public Property
|
||||
{
|
||||
@@ -170,7 +171,7 @@ class AppExport PropertyMatrix: public Property
|
||||
public:
|
||||
/**
|
||||
* A constructor.
|
||||
* A more elaborate description of the constructor.
|
||||
* Intitialises to an identity matrix
|
||||
*/
|
||||
PropertyMatrix();
|
||||
|
||||
|
||||
@@ -265,158 +265,82 @@ TYPESYSTEM_SOURCE(App::PropertyEnumeration, App::PropertyInteger);
|
||||
|
||||
|
||||
PropertyEnumeration::PropertyEnumeration()
|
||||
: _CustomEnum(false), _EnumArray(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
PropertyEnumeration::PropertyEnumeration(const App::Enumeration &e)
|
||||
{
|
||||
_enum = e;
|
||||
}
|
||||
|
||||
PropertyEnumeration::~PropertyEnumeration()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PropertyEnumeration::setEnums(const char** plEnums)
|
||||
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++) != 0)i++;
|
||||
// very unlikely to have enums with more then 5000 entries!
|
||||
assert(i<5000);
|
||||
}
|
||||
# endif
|
||||
_enum.setEnums(plEnums);
|
||||
}
|
||||
|
||||
void PropertyEnumeration::setValue(const char* value)
|
||||
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++;
|
||||
}
|
||||
_enum.setValue(value);
|
||||
}
|
||||
|
||||
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);
|
||||
_enum.setValue(value);
|
||||
}
|
||||
|
||||
/// checks if the property is set to a certain string value
|
||||
bool PropertyEnumeration::isValue(const char* value) const
|
||||
void PropertyEnumeration::setValue(const Enumeration &source)
|
||||
{
|
||||
// using string methods without set, use setEnums(const char** plEnums) first!
|
||||
assert(_EnumArray);
|
||||
return strcmp(_EnumArray[getValue()],value)==0;
|
||||
_enum = source;
|
||||
}
|
||||
|
||||
/// checks if a string is included in the enumeration
|
||||
bool PropertyEnumeration::isPartOf(const char* value) const
|
||||
long PropertyEnumeration::getValue(void) 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++;
|
||||
}
|
||||
return _enum.getInt();
|
||||
}
|
||||
|
||||
/// get the value as string
|
||||
const char* PropertyEnumeration::getValueAsString(void) const
|
||||
bool PropertyEnumeration::isValue(const char *value) const
|
||||
{
|
||||
// using string methods without set, use setEnums(const char** plEnums) first!
|
||||
assert(_EnumArray);
|
||||
return _EnumArray[getValue()];
|
||||
return _enum.isValue(value);
|
||||
}
|
||||
|
||||
bool PropertyEnumeration::isPartOf(const char *value) const
|
||||
{
|
||||
return _enum.contains(value);
|
||||
}
|
||||
|
||||
const char * PropertyEnumeration::getValueAsString(void) const
|
||||
{
|
||||
return _enum.getCStr();
|
||||
}
|
||||
|
||||
Enumeration PropertyEnumeration::getEnum(void) const
|
||||
{
|
||||
return _enum;
|
||||
}
|
||||
|
||||
std::vector<std::string> PropertyEnumeration::getEnumVector(void) const
|
||||
{
|
||||
// using string methods without set, use setEnums(const char** plEnums) first!
|
||||
assert(_EnumArray);
|
||||
|
||||
std::vector<std::string> result;
|
||||
const char** plEnums = _EnumArray;
|
||||
|
||||
// end of list?
|
||||
while(*plEnums!=NULL){
|
||||
result.push_back(*plEnums);
|
||||
plEnums++;
|
||||
}
|
||||
|
||||
return result;
|
||||
return _enum.getEnumVector();
|
||||
}
|
||||
|
||||
void PropertyEnumeration::setEnumVector(const std::vector<std::string>& values)
|
||||
const char ** PropertyEnumeration::getEnums(void) const
|
||||
{
|
||||
delete [] _EnumArray;
|
||||
_EnumArray = new const char*[values.size()+1];
|
||||
int i=0;
|
||||
for (std::vector<std::string>::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;
|
||||
return _enum.getEnums();
|
||||
}
|
||||
|
||||
void PropertyEnumeration::Save(Base::Writer &writer) const
|
||||
{
|
||||
writer.Stream() << writer.ind() << "<Integer value=\"" << _lValue <<"\"";
|
||||
if (_CustomEnum)
|
||||
writer.Stream() << writer.ind() << "<Integer value=\"" << _enum.getInt() <<"\"";
|
||||
if (_enum.isCustom())
|
||||
writer.Stream() << " CustomEnum=\"true\"";
|
||||
writer.Stream() << "/>" << std::endl;
|
||||
if (_CustomEnum) {
|
||||
if (_enum.isCustom()) {
|
||||
std::vector<std::string> items = getEnumVector();
|
||||
writer.Stream() << writer.ind() << "<CustomEnumList count=\"" << items.size() <<"\">" << endl;
|
||||
writer.incInd();
|
||||
@@ -440,6 +364,7 @@ void PropertyEnumeration::Restore(Base::XMLReader &reader)
|
||||
reader.readElement("CustomEnumList");
|
||||
int count = reader.getAttributeAsInteger("count");
|
||||
std::vector<std::string> values(count);
|
||||
|
||||
for(int i = 0; i < count; i++) {
|
||||
reader.readElement("Enum");
|
||||
values[i] = reader.getAttribute("value");
|
||||
@@ -447,16 +372,15 @@ void PropertyEnumeration::Restore(Base::XMLReader &reader)
|
||||
|
||||
reader.readEndElement("CustomEnumList");
|
||||
|
||||
_CustomEnum = true;
|
||||
setEnumVector(values);
|
||||
_enum.setEnums(values);
|
||||
}
|
||||
|
||||
setValue(val);
|
||||
}
|
||||
|
||||
PyObject *PropertyEnumeration::getPyObject(void)
|
||||
PyObject * PropertyEnumeration::getPyObject(void)
|
||||
{
|
||||
if (!_EnumArray) {
|
||||
if (!_enum.isValid()) {
|
||||
PyErr_SetString(PyExc_AssertionError, "The enum is empty");
|
||||
return 0;
|
||||
}
|
||||
@@ -468,19 +392,14 @@ 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 Base::ValueError("Out of range");
|
||||
PropertyInteger::setValue(val);
|
||||
if (_enum.isValid()) {
|
||||
_enum.setValue(val, true);
|
||||
}
|
||||
}
|
||||
else if (PyString_Check(value)) {
|
||||
const char* str = PyString_AsString (value);
|
||||
if (_EnumArray && isPartOf(str)) {
|
||||
setValue(PyString_AsString (value));
|
||||
if (_enum.contains(str)) {
|
||||
_enum.setValue(PyString_AsString (value));
|
||||
}
|
||||
else {
|
||||
std::stringstream out;
|
||||
@@ -493,47 +412,38 @@ void PropertyEnumeration::setPyObject(PyObject *value)
|
||||
std::vector<std::string> values;
|
||||
values.resize(nSize);
|
||||
|
||||
for (Py_ssize_t i=0; i<nSize;++i) {
|
||||
PyObject* item = PyList_GetItem(value, i);
|
||||
if (!PyString_Check(item)) {
|
||||
for (Py_ssize_t i = 0; i < nSize; ++i) {
|
||||
PyObject *item = PyList_GetItem(value, i);
|
||||
|
||||
if ( !PyString_Check(item) ) {
|
||||
std::string error = std::string("type in list must be str, not ");
|
||||
error += item->ob_type->tp_name;
|
||||
throw Base::TypeError(error);
|
||||
throw Base::TypeError(error + item->ob_type->tp_name);
|
||||
}
|
||||
|
||||
values[i] = PyString_AsString(item);
|
||||
}
|
||||
|
||||
_CustomEnum = true;
|
||||
setEnumVector(values);
|
||||
_enum.setEnums(values);
|
||||
setValue((long)0);
|
||||
}
|
||||
else {
|
||||
std::string error = std::string("type must be int or str, not ");
|
||||
error += value->ob_type->tp_name;
|
||||
throw Base::TypeError(error);
|
||||
throw Base::TypeError(error + value->ob_type->tp_name);
|
||||
}
|
||||
}
|
||||
|
||||
Property *PropertyEnumeration::Copy(void) const
|
||||
Property * PropertyEnumeration::Copy(void) const
|
||||
{
|
||||
PropertyEnumeration *p= new PropertyEnumeration();
|
||||
p->_lValue = _lValue;
|
||||
if (_CustomEnum) {
|
||||
p->_CustomEnum = true;
|
||||
p->setEnumVector(getEnumVector());
|
||||
}
|
||||
return p;
|
||||
return new PropertyEnumeration(_enum);
|
||||
}
|
||||
|
||||
void PropertyEnumeration::Paste(const Property &from)
|
||||
{
|
||||
aboutToSetValue();
|
||||
|
||||
const PropertyEnumeration& prop = dynamic_cast<const PropertyEnumeration&>(from);
|
||||
_lValue = prop._lValue;
|
||||
if (prop._CustomEnum) {
|
||||
this->_CustomEnum = true;
|
||||
this->setEnumVector(prop.getEnumVector());
|
||||
}
|
||||
_enum = prop._enum;
|
||||
|
||||
hasSetValue();
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#include <Base/Uuid.h>
|
||||
#include "Enumeration.h"
|
||||
#include "Property.h"
|
||||
#include "Material.h"
|
||||
|
||||
@@ -121,30 +122,25 @@ protected:
|
||||
boost::filesystem::path _cValue;
|
||||
};
|
||||
|
||||
/** Enum properties
|
||||
* This property fullfill the need of enumarations. It holds basicly a
|
||||
* state (integer) and a list of valid state names. If the valid state
|
||||
* list is not set it act basicly like a IntegerProperty and do no checking.
|
||||
* If the list is set it checks on the range and if you set the state with
|
||||
* a string if its included in the enumarations.
|
||||
* In DEBUG the boundaries get checked, otherwise the caller of setValue()
|
||||
* has the responsebility to check the correctnes.
|
||||
* This mean if you set by setValue(const char*) with an not included value
|
||||
* and not using isPartOf() before,
|
||||
* in DEBUG you get an assert() in release its set to 0.
|
||||
*/
|
||||
class AppExport PropertyEnumeration: public PropertyInteger
|
||||
/// Property wrapper around an Enumeration object.
|
||||
class AppExport PropertyEnumeration: public Property
|
||||
{
|
||||
TYPESYSTEM_HEADER();
|
||||
|
||||
public:
|
||||
/// Standard constructor
|
||||
PropertyEnumeration();
|
||||
|
||||
/// Obvious constructor
|
||||
PropertyEnumeration(const Enumeration &e);
|
||||
|
||||
/// destructor
|
||||
virtual ~PropertyEnumeration();
|
||||
|
||||
/// Enumeration methods
|
||||
/*!
|
||||
* These all function as per documentation in Enumeration
|
||||
*/
|
||||
//@{
|
||||
/** setting the enumaration string list
|
||||
* The list is a NULL terminated array of pointers to a const char* string
|
||||
@@ -162,34 +158,45 @@ public:
|
||||
* Is faster then using setValue(const char*).
|
||||
*/
|
||||
void setValue(long);
|
||||
|
||||
/// Setter using Enumeration
|
||||
void setValue(const Enumeration &source);
|
||||
|
||||
/// Returns current value of the enumeration as an integer
|
||||
long getValue(void) const;
|
||||
|
||||
/// checks if the property is set to a certain string value
|
||||
bool isValue(const char* value) const;
|
||||
|
||||
/// checks if a string is included in the enumeration
|
||||
bool isPartOf(const char* value) const;
|
||||
|
||||
/// get the value as string
|
||||
const char* getValueAsString(void) const;
|
||||
const char * getValueAsString(void) const;
|
||||
|
||||
/// Returns Enumeration object
|
||||
Enumeration getEnum(void) const;
|
||||
|
||||
/// get all possible enum values as vector of strings
|
||||
std::vector<std::string> getEnumVector(void) const;
|
||||
/// set all enum values as vector of strings
|
||||
void setEnumVector(const std::vector<std::string>&);
|
||||
|
||||
/// get the pointer to the enum list
|
||||
const char** getEnums(void) const;
|
||||
const char ** getEnums(void) const;
|
||||
//@}
|
||||
|
||||
virtual const char* getEditorName(void) const { return "Gui::PropertyEditor::PropertyEnumItem"; }
|
||||
virtual const char * getEditorName(void) const { return "Gui::PropertyEditor::PropertyEnumItem"; }
|
||||
|
||||
virtual PyObject *getPyObject(void);
|
||||
virtual PyObject * getPyObject(void);
|
||||
virtual void setPyObject(PyObject *);
|
||||
|
||||
virtual void Save (Base::Writer &writer) const;
|
||||
virtual void Save(Base::Writer &writer) const;
|
||||
virtual void Restore(Base::XMLReader &reader);
|
||||
|
||||
virtual Property *Copy(void) const;
|
||||
virtual Property * Copy(void) const;
|
||||
virtual void Paste(const Property &from);
|
||||
|
||||
private:
|
||||
bool _CustomEnum;
|
||||
const char** _EnumArray;
|
||||
Enumeration _enum;
|
||||
};
|
||||
|
||||
/** Constraint integer properties
|
||||
|
||||
@@ -42,13 +42,18 @@ class BaseExport Matrix4D
|
||||
typedef float_traits<double> traits_type;
|
||||
|
||||
public:
|
||||
/// default constructor
|
||||
/// Default constructor
|
||||
/*!
|
||||
* Initialises to an identity matrix
|
||||
*/
|
||||
Matrix4D(void);
|
||||
|
||||
/// Construction
|
||||
Matrix4D (float a11, float a12, float a13, float a14,
|
||||
float a21, float a22, float a23, float a24,
|
||||
float a31, float a32, float a33, float a34,
|
||||
float a41, float a42, float a43, float a44 );
|
||||
/// Construction
|
||||
Matrix4D (double a11, double a12, double a13, double a14,
|
||||
double a21, double a22, double a23, double a24,
|
||||
double a31, double a32, double a33, double a34,
|
||||
@@ -123,17 +128,19 @@ public:
|
||||
/// scale for the x,y,z value
|
||||
void scale (const Vector3f& rclVct);
|
||||
void scale (const Vector3d& rclVct);
|
||||
/// rotate around the X axis for the given value
|
||||
/// Rotate around the X axis (in transformed space) for the given value in radians
|
||||
void rotX (double fAngle);
|
||||
/// rotate around the Y axis for the given value
|
||||
/// Rotate around the Y axis (in transformed space) for the given value in radians
|
||||
void rotY (double fAngle);
|
||||
/// rotate around the Z axis for the given value
|
||||
/// Rotate around the Z axis (in transformed space) for the given value in radians
|
||||
void rotZ (double fAngle);
|
||||
/// Rotation around an arbitrary axis passing the origin.
|
||||
/// Rotate around an arbitrary axis passing the origin in radians
|
||||
void rotLine (const Vector3f& rclVct, float fAngle);
|
||||
/// Rotate around an arbitrary axis passing the origin in radians
|
||||
void rotLine (const Vector3d& rclVct, double fAngle);
|
||||
/// Rotation around an arbitrary axis that needn't necessarily pass the origin.
|
||||
/// Rotate around an arbitrary axis that needn't necessarily pass the origin in radians
|
||||
void rotLine (const Vector3f& rclBase, const Vector3f& rclDir, float fAngle);
|
||||
/// Rotate around an arbitrary axis that needn't necessarily pass the origin in radians
|
||||
void rotLine (const Vector3d& rclBase, const Vector3d& rclDir, double fAngle);
|
||||
/// Extract the rotation axis and angle. Therefore the 3x3 submatrix must be orthogonal.
|
||||
bool toAxisAngle (Vector3f& rclBase, Vector3f& rclDir, float& fAngle, float& fTranslation) const;
|
||||
|
||||
Reference in New Issue
Block a user