PyObject* SketchObjectPy::setDatum(PyObject *args) { double Datum; int Index; PyObject* object; Base::Quantity Quantity; if (PyArg_ParseTuple(args,"iO!", &Index, &(Base::QuantityPy::Type), &object)) { Quantity = *(static_cast<Base::QuantityPy*>(object)->getQuantityPtr()); if (Quantity.getUnit() == Base::Unit::Angle) //Datum = Quantity.getValueAs(Base::Quantity::Radian); Datum = Base::toRadians<double>(Quantity.getValue()); else Datum = Quantity.getValue(); } else { PyErr_Clear(); if (!PyArg_ParseTuple(args, "id", &Index, &Datum)) return 0; Quantity.setValue(Datum); } int err=this->getSketchObjectPtr()->setDatum(Index, Datum); if (err) { std::stringstream str; if (err == -1) str << "Invalid constraint index: " << Index; else if (err == -3) str << "Cannot set the datum because the sketch contains conflicting constraints"; else if (err == -2) str << "Datum " << (const char*)Quantity.getUserString().toUtf8() << " for the constraint with index " << Index << " is invalid"; else if (err == -4) str << "Negative datum values are not valid for the constraint with index " << Index; else if (err == -5) str << "Zero is not a valid datum for the constraint with index " << Index; else str << "Unexpected problem at setting datum " << (const char*)Quantity.getUserString().toUtf8() << " for the constraint with index " << Index; PyErr_SetString(PyExc_ValueError, str.str().c_str()); return 0; } Py_Return; }
std::string DrawViewDimension::getFormatedValue() const { QString str = QString::fromUtf8(FormatSpec.getStrValue().c_str()); double val = std::abs(getDimValue()); //QLocale here(QLocale::German); //for testing //here.setNumberOptions(QLocale::OmitGroupSeparator); QLocale here = QLocale(); //system locale QString valText = here.toString(val, 'f',Precision.getValue()); Base::Quantity qVal; qVal.setValue(val); if (Type.isValue("Angle")) { qVal.setUnit(Base::Unit::Angle); } else { qVal.setUnit(Base::Unit::Length); } QString userStr = qVal.getUserString(); QStringList userSplit = userStr.split(QString::fromUtf8(" "),QString::SkipEmptyParts); //break userString into number + UoM QString displayText; if (!userSplit.isEmpty()) { QString unitText = userSplit.back(); displayText = valText + QString::fromUtf8(" ") + unitText; } QRegExp rx(QString::fromAscii("%(\\w+)%")); //any word bracketed by % QStringList list; int pos = 0; while ((pos = rx.indexIn(str, pos)) != -1) { list << rx.cap(0); pos += rx.matchedLength(); } for(QStringList::const_iterator it = list.begin(); it != list.end(); ++it) { if(*it == QString::fromAscii("%value%")){ str.replace(*it,displayText); } else { //insert additional placeholder replacement logic here str.replace(*it, QString::fromAscii("")); //maybe we should just leave what was there? } } return str.toStdString(); }
PyObject* SketchObjectPy::getDatum(PyObject *args) { const std::vector<Constraint*>& vals = this->getSketchObjectPtr()->Constraints.getValues(); Constraint* constr = 0; do { int index = 0; if (PyArg_ParseTuple(args,"i", &index)) { if (index < 0 || index >= static_cast<int>(vals.size())) { PyErr_SetString(PyExc_IndexError, "index out of range"); return 0; } constr = vals[index]; break; } PyErr_Clear(); char* name; if (PyArg_ParseTuple(args,"s", &name)) { int id = 0; for (std::vector<Constraint*>::const_iterator it = vals.begin(); it != vals.end(); ++it, ++id) { if (Sketcher::PropertyConstraintList::getConstraintName((*it)->Name, id) == name) { constr = *it; break; } } if (!constr) { std::stringstream str; str << "Invalid constraint name: '" << name << "'"; PyErr_SetString(PyExc_NameError, str.str().c_str()); return 0; } else { break; } } // error handling PyErr_SetString(PyExc_TypeError, "Wrong arguments"); return 0; } while (false); ConstraintType type = constr->Type; if (type != Distance && type != DistanceX && type != DistanceY && type != Radius && type != Angle) { PyErr_SetString(PyExc_TypeError, "Constraint is not a datum"); return 0; } Base::Quantity datum; datum.setValue(constr->getValue()); if (type == Angle) { datum.setValue(Base::toDegrees<double>(datum.getValue())); datum.setUnit(Base::Unit::Angle); } else { datum.setUnit(Base::Unit::Length); } return new Base::QuantityPy(new Base::Quantity(datum)); }
PyObject* SketchObjectPy::setDatum(PyObject *args) { double Datum; int Index; PyObject* object; Base::Quantity Quantity; do { // handle (int,Quantity) if (PyArg_ParseTuple(args,"iO!", &Index, &(Base::QuantityPy::Type), &object)) { Quantity = *(static_cast<Base::QuantityPy*>(object)->getQuantityPtr()); if (Quantity.getUnit() == Base::Unit::Angle) { Datum = Base::toRadians<double>(Quantity.getValue()); break; } else { Datum = Quantity.getValue(); break; } } // handle (int,double) PyErr_Clear(); if (PyArg_ParseTuple(args, "id", &Index, &Datum)) { Quantity.setValue(Datum); break; } // handle (string,Quantity) char* constrName; PyErr_Clear(); if (PyArg_ParseTuple(args,"sO!", &constrName, &(Base::QuantityPy::Type), &object)) { Quantity = *(static_cast<Base::QuantityPy*>(object)->getQuantityPtr()); if (Quantity.getUnit() == Base::Unit::Angle) { Datum = Base::toRadians<double>(Quantity.getValue()); } else { Datum = Quantity.getValue(); } int i = 0; Index = -1; const std::vector<Constraint*>& vals = this->getSketchObjectPtr()->Constraints.getValues(); for (std::vector<Constraint*>::const_iterator it = vals.begin(); it != vals.end(); ++it, ++i) { if ((*it)->Name == constrName) { Index = i; break; } } if (Index >= 0) { break; } else { std::stringstream str; str << "Invalid constraint name: '" << constrName << "'"; PyErr_SetString(PyExc_ValueError, str.str().c_str()); return 0; } } // handle (string,double) PyErr_Clear(); if (PyArg_ParseTuple(args, "sd", &constrName, &Datum)) { Quantity.setValue(Datum); int i = 0; Index = -1; const std::vector<Constraint*>& vals = this->getSketchObjectPtr()->Constraints.getValues(); for (std::vector<Constraint*>::const_iterator it = vals.begin(); it != vals.end(); ++it, ++i) { if ((*it)->Name == constrName) { Index = i; break; } } if (Index >= 0) { break; } else { std::stringstream str; str << "Invalid constraint name: '" << constrName << "'"; PyErr_SetString(PyExc_ValueError, str.str().c_str()); return 0; } } // error handling PyErr_SetString(PyExc_TypeError, "Wrong arguments"); return 0; } while (false); int err=this->getSketchObjectPtr()->setDatum(Index, Datum); if (err) { std::stringstream str; if (err == -1) str << "Invalid constraint index: " << Index; else if (err == -3) str << "Cannot set the datum because the sketch contains conflicting constraints"; else if (err == -2) str << "Datum " << (const char*)Quantity.getUserString().toUtf8() << " for the constraint with index " << Index << " is invalid"; else if (err == -4) str << "Negative datum values are not valid for the constraint with index " << Index; else if (err == -5) str << "Zero is not a valid datum for the constraint with index " << Index; else if (err == -6) str << "Cannot set the datum because of invalid geometry"; else str << "Unexpected problem at setting datum " << (const char*)Quantity.getUserString().toUtf8() << " for the constraint with index " << Index; PyErr_SetString(PyExc_ValueError, str.str().c_str()); return 0; } Py_Return; }
QVariant PropertyConstraintListItem::value(const App::Property* prop) const { assert(prop && prop->getTypeId().isDerivedFrom(Sketcher::PropertyConstraintList::getClassTypeId())); PropertyConstraintListItem* self = const_cast<PropertyConstraintListItem*>(this); int id = 1; QList<Base::Quantity> quantities; QList<Base::Quantity> subquantities; bool onlyNamed = true; const std::vector< Sketcher::Constraint * > &vals = static_cast<const Sketcher::PropertyConstraintList*>(prop)->getValues(); for (std::vector< Sketcher::Constraint* >::const_iterator it = vals.begin();it != vals.end(); ++it, ++id) { if ((*it)->Type == Sketcher::Distance || // Datum constraint (*it)->Type == Sketcher::DistanceX || (*it)->Type == Sketcher::DistanceY || (*it)->Type == Sketcher::Radius || (*it)->Type == Sketcher::Angle ) { Base::Quantity quant; if ((*it)->Type == Sketcher::Angle ) { double datum = Base::toDegrees<double>((*it)->getValue()); quant.setUnit(Base::Unit::Angle); quant.setValue(datum); } else { quant.setUnit(Base::Unit::Length); quant.setValue((*it)->getValue()); } quantities.append(quant); // Use a 7-bit ASCII string for the internal name. // See also comment in PropertyConstraintListItem::initialize() QString internalName = QString::fromLatin1("Constraint%1").arg(id); PropertyConstraintListItem* self = const_cast<PropertyConstraintListItem*>(this); self->blockEvent = true; if ((*it)->Name.empty() && !onlyUnnamed) { onlyNamed = false; subquantities.append(quant); PropertyConstraintListItem* unnamednode = static_cast<PropertyConstraintListItem*>(self->child(self->childCount()-1)); unnamednode->blockEvent = true; unnamednode->setProperty(internalName.toLatin1(), QVariant::fromValue<Base::Quantity>(quant)); unnamednode->blockEvent = false; } else { self->setProperty(internalName.toLatin1(), QVariant::fromValue<Base::Quantity>(quant)); } self->blockEvent = false; } } // The quantities of unnamed constraints are only needed for display purposes inside toString() if (!onlyUnnamed && !onlyNamed) { self->blockEvent = true; self->setProperty("Unnamed", QVariant::fromValue< QList<Base::Quantity> >(subquantities)); self->blockEvent = false; } return QVariant::fromValue< QList<Base::Quantity> >(quantities); }
Base::Quantity validateAndInterpret(QString& input, int& pos, QValidator::State& state) const { Base::Quantity res; const double max = this->maximum; const double min = this->minimum; QString copy = input; int len = copy.size(); const bool plus = max >= 0; const bool minus = min <= 0; switch (len) { case 0: state = max != min ? QValidator::Intermediate : QValidator::Invalid; goto end; case 1: if (copy.at(0) == locale.decimalPoint()) { state = QValidator::Intermediate; copy.prepend(QLatin1Char('0')); pos++; len++; goto end; } else if (copy.at(0) == QLatin1Char('+')) { // the quantity parser doesn't allow numbers of the form '+1.0' state = QValidator::Invalid; goto end; } else if (copy.at(0) == QLatin1Char('-')) { if (minus) state = QValidator::Intermediate; else state = QValidator::Invalid; goto end; } break; case 2: if (copy.at(1) == locale.decimalPoint() && (plus && copy.at(0) == QLatin1Char('+'))) { state = QValidator::Intermediate; goto end; } if (copy.at(1) == locale.decimalPoint() && (minus && copy.at(0) == QLatin1Char('-'))) { state = QValidator::Intermediate; copy.insert(1, QLatin1Char('0')); pos++; len++; goto end; } break; default: break; } { if (copy.at(0) == locale.groupSeparator()) { state = QValidator::Invalid; goto end; } else if (len > 1) { const int dec = copy.indexOf(locale.decimalPoint()); if (dec != -1) { if (dec + 1 < copy.size() && copy.at(dec + 1) == locale.decimalPoint() && pos == dec + 1) { copy.remove(dec + 1, 1); } else if (copy.indexOf(locale.decimalPoint(), dec + 1) != -1) { // trying to add a second decimal point is not allowed state = QValidator::Invalid; goto end; } for (int i=dec + 1; i<copy.size(); ++i) { // a group separator after the decimal point is not allowed if (copy.at(i) == locale.groupSeparator()) { state = QValidator::Invalid; goto end; } } } } bool ok = false; double value = min; if (locale.negativeSign() != QLatin1Char('-')) copy.replace(locale.negativeSign(), QLatin1Char('-')); if (locale.positiveSign() != QLatin1Char('+')) copy.replace(locale.positiveSign(), QLatin1Char('+')); try { QString copy2 = copy; copy2.remove(locale.groupSeparator()); res = Base::Quantity::parse(copy2); value = res.getValue(); ok = true; } catch (Base::Exception&) { } if (!ok) { // input may not be finished state = QValidator::Intermediate; } else if (value >= min && value <= max) { if (copy.endsWith(locale.decimalPoint())) { // input shouldn't end with a decimal point state = QValidator::Intermediate; } else if (res.getUnit().isEmpty() && !this->unit.isEmpty()) { // if not dimensionless the input should have a dimension state = QValidator::Intermediate; } else if (res.getUnit() != this->unit) { state = QValidator::Invalid; } else { state = QValidator::Acceptable; } } else if (max == min) { // when max and min is the same the only non-Invalid input is max (or min) state = QValidator::Invalid; } else { if ((value >= 0 && value > max) || (value < 0 && value < min)) { state = QValidator::Invalid; } else { state = QValidator::Intermediate; } } } end: if (state != QValidator::Acceptable) { res.setValue(max > 0 ? min : max); } input = copy; return res; }