QString UnitsSchemaMKS::schemaTranslate(Base::Quantity quant,double &factor,QString &unitString) { double UnitValue = std::abs(quant.getValue()); Unit unit = quant.getUnit(); // now do special treatment on all cases seams nececarry: if(unit == Unit::Length){ // Length handling ============================ if(UnitValue < 0.000000001){// smaller then 0.001 nm -> scientific notation unitString = QString::fromLatin1("mm"); factor = 1.0; }else if(UnitValue < 0.001){ unitString = QString::fromLatin1("nm"); factor = 0.000001; }else if(UnitValue < 0.1){ unitString = QString::fromUtf8("\xC2\xB5m"); factor = 0.001; }else if(UnitValue < 100.0){ unitString = QString::fromLatin1("mm"); factor = 1.0; }else if(UnitValue < 10000000.0){ unitString = QString::fromLatin1("m"); factor = 1000.0; }else if(UnitValue < 100000000000.0 ){ unitString = QString::fromLatin1("km"); factor = 1000000.0; }else{ // bigger then 1000 km -> scientific notation unitString = QString::fromLatin1("mm"); factor = 1.0; } }else if (unit == Unit::Area){ // TODO Cascade for the Areas // default action for all cases without special treatment: unitString = quant.getUnit().getString(); factor = 1.0; }else if (unit == Unit::Mass){ // TODO Cascade for the wights // default action for all cases without special treatment: unitString = quant.getUnit().getString(); factor = 1.0; }else if (unit == Unit::Pressure){ if(UnitValue < 10.0){// Pa is the smallest unitString = QString::fromLatin1("Pa"); factor = 0.001; }else if(UnitValue < 10000.0){ unitString = QString::fromLatin1("kPa"); factor = 1.0; }else if(UnitValue < 10000000.0){ unitString = QString::fromLatin1("GPa"); factor = 1000.0; }else{ // bigger then 1000 GPa -> scientific notation unitString = QString::fromLatin1("Pa"); factor = 1.0; } }else{ // default action for all cases without special treatment: unitString = quant.getUnit().getString(); factor = 1.0; } return QString::fromUtf8("%L1 %2").arg(quant.getValue() / factor).arg(unitString); }
QString UnitsSchemaImperialDecimal::schemaTranslate(Base::Quantity quant,double &factor,QString &unitString) { double UnitValue = std::abs(quant.getValue()); Unit unit = quant.getUnit(); // for imperial user/programmer mind; UnitValue is in internal system, that means // mm/kg/s. And all combined units have to be calculated from there! // now do special treatment on all cases seems necessary: if(unit == Unit::Length){ // Length handling ============================ if(UnitValue < 0.00000254){// smaller then 0.001 thou -> inch and scientific notation unitString = QString::fromLatin1("in"); factor = 25.4; //}else if(UnitValue < 2.54){ // smaller then 0.1 inch -> Thou (mil) // unitString = QString::fromLatin1("thou"); // factor = 0.0254; }else{ // bigger then 1000 mi -> scientific notation unitString = QString::fromLatin1("in"); factor = 25.4; } }else if (unit == Unit::Area){ // TODO Cascade for the Areas // default action for all cases without special treatment: unitString = QString::fromLatin1("in^2"); factor = 645.16; }else if (unit == Unit::Volume){ // TODO Cascade for the Volume // default action for all cases without special treatment: unitString = QString::fromLatin1("in^3"); factor = 16387.064; }else if (unit == Unit::Mass){ // TODO Cascade for the wights // default action for all cases without special treatment: unitString = QString::fromLatin1("lb"); factor = 0.45359237; }else if (unit == Unit::Pressure){ if(UnitValue < 145.038){// psi is the smallest unitString = QString::fromLatin1("psi"); factor = 0.145038; //}else if(UnitValue < 145038){ // unitString = QString::fromLatin1("ksi"); // factor = 145.038; }else{ // bigger then 1000 ksi -> psi + scientific notation unitString = QString::fromLatin1("psi"); factor = 0.145038; } }else{ // default action for all cases without special treatment: unitString = quant.getUnit().getString(); factor = 1.0; } //return QString::fromLatin1("%L1 %2").arg(quant.getValue() / factor).arg(unitString); QLocale Lc = QLocale::system(); Lc.setNumberOptions(Lc.OmitGroupSeparator | Lc.RejectGroupSeparator); QString Ln = Lc.toString((quant.getValue() / factor), 'f', Base::UnitsApi::getDecimals()); return QString::fromUtf8("%1 %2").arg(Ln).arg(unitString); }
/// sets the field with a quantity void InputField::setValue(const Base::Quantity& quant) { actQuantity = quant; if(!quant.getUnit().isEmpty()) actUnit = quant.getUnit(); double dFactor; setText(quant.getUserString(dFactor,actUnitStr)); actUnitValue = quant.getValue()/dFactor; }
void DlgExpressionInput::textChanged(const QString &text) { try { //resize the input field according to text size QFontMetrics fm(ui->expression->font()); int width = fm.width(text) + 15; if (width < minimumWidth) ui->expression->setMinimumWidth(minimumWidth); else ui->expression->setMinimumWidth(width); if(this->width() < ui->expression->minimumWidth()) setMinimumWidth(ui->expression->minimumWidth()); //now handle expression boost::shared_ptr<Expression> expr(ExpressionParser::parse(path.getDocumentObject(), text.toUtf8().constData())); if (expr) { std::string error = path.getDocumentObject()->ExpressionEngine.validateExpression(path, expr); if (error.size() > 0) throw Base::Exception(error.c_str()); std::unique_ptr<Expression> result(expr->eval()); expression = expr; ui->okBtn->setEnabled(true); ui->msg->clear(); NumberExpression * n = Base::freecad_dynamic_cast<NumberExpression>(result.get()); if (n) { Base::Quantity value = n->getQuantity(); if (!value.getUnit().isEmpty() && value.getUnit() != impliedUnit) throw Base::Exception("Unit mismatch between result and required unit"); value.setUnit(impliedUnit); ui->msg->setText(value.getUserString()); } else ui->msg->setText(Base::Tools::fromStdString(result->toString())); //set default palette as we may have read text right now ui->msg->setPalette(ui->okBtn->palette()); } } catch (Base::Exception & e) { ui->msg->setText(QString::fromUtf8(e.what())); QPalette p(ui->msg->palette()); p.setColor(QPalette::WindowText, Qt::red); ui->msg->setPalette(p); ui->okBtn->setDisabled(true); } }
QString UnitsSchemaInternal::schemaTranslate(Base::Quantity quant) { double UnitValue = quant.getValue(); Unit unit = quant.getUnit(); return QString::fromAscii("%1 %2").arg(UnitValue).arg(QString::fromAscii(unit.getString().c_str())); }
void QuantitySpinBox::setValue(const Base::Quantity& value) { Q_D(QuantitySpinBox); d->quantity = value; // check limits if (d->quantity.getValue() > d->maximum) d->quantity.setValue(d->maximum); if (d->quantity.getValue() < d->minimum) d->quantity.setValue(d->minimum); d->unit = value.getUnit(); updateText(value); }
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; }
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; }
// constructor method int ConstraintPy::PyInit(PyObject* args, PyObject* /*kwd*/) { if (PyArg_ParseTuple(args, "")) { return 0; } PyErr_Clear(); char *ConstraintType; int FirstIndex = Constraint::GeoUndef; int FirstPos = none; int SecondIndex= Constraint::GeoUndef; int SecondPos = none; int ThirdIndex = Constraint::GeoUndef; int ThirdPos = none; double Value = 0; int intArg1, intArg2, intArg3, intArg4, intArg5; // Note: In Python 2.x PyArg_ParseTuple prints a warning if a float is given but an integer is expected. // This means we must use a PyObject and check afterwards if it's a float or integer. PyObject* index_or_value; PyObject* oNumArg4; PyObject* oNumArg5; int any_index; // ConstraintType, GeoIndex if (PyArg_ParseTuple(args, "si", &ConstraintType, &FirstIndex)) { if (strcmp("Horizontal",ConstraintType) == 0) { this->getConstraintPtr()->Type = Horizontal; this->getConstraintPtr()->First = FirstIndex; return 0; } else if (strcmp("Vertical",ConstraintType) == 0) { this->getConstraintPtr()->Type = Vertical; this->getConstraintPtr()->First = FirstIndex; return 0; } } PyErr_Clear(); if (PyArg_ParseTuple(args, "siO", &ConstraintType, &FirstIndex, &index_or_value)) { // ConstraintType, GeoIndex1, GeoIndex2 if (PyInt_Check(index_or_value)) { SecondIndex = PyInt_AsLong(index_or_value); bool valid = false; if (strcmp("Tangent",ConstraintType) == 0) { this->getConstraintPtr()->Type = Tangent; valid = true; } else if (strcmp("Parallel",ConstraintType) == 0) { this->getConstraintPtr()->Type = Parallel; valid = true; } else if (strcmp("Perpendicular",ConstraintType) == 0) { this->getConstraintPtr()->Type = Perpendicular; valid = true; } else if (strcmp("Equal",ConstraintType) == 0) { this->getConstraintPtr()->Type = Equal; valid = true; } else if (strstr(ConstraintType,"InternalAlignment") != NULL) { this->getConstraintPtr()->Type = InternalAlignment; valid = true; if(strstr(ConstraintType,"EllipseMajorDiameter") != NULL) this->getConstraintPtr()->AlignmentType=EllipseMajorDiameter; else if(strstr(ConstraintType,"EllipseMinorDiameter") != NULL) this->getConstraintPtr()->AlignmentType=EllipseMinorDiameter; else { this->getConstraintPtr()->AlignmentType=Undef; valid = false; } } if (valid) { this->getConstraintPtr()->First = FirstIndex; this->getConstraintPtr()->Second = SecondIndex; return 0; } } // ConstraintType, GeoIndex, Value if (PyNumber_Check(index_or_value)) { // can be float or int Value = PyFloat_AsDouble(index_or_value); bool valid = false; if (strcmp("Distance",ConstraintType) == 0 ) { this->getConstraintPtr()->Type = Distance; valid = true; } else if (strcmp("Angle",ConstraintType) == 0 ) { if (PyObject_TypeCheck(index_or_value, &(Base::QuantityPy::Type))) { Base::Quantity q = *(static_cast<Base::QuantityPy*>(index_or_value)->getQuantityPtr()); if (q.getUnit() == Base::Unit::Angle) Value = q.getValueAs(Base::Quantity::Radian); } this->getConstraintPtr()->Type = Angle; valid = true; } else if (strcmp("DistanceX",ConstraintType) == 0) { this->getConstraintPtr()->Type = DistanceX; valid = true; } else if (strcmp("DistanceY",ConstraintType) == 0) { this->getConstraintPtr()->Type = DistanceY; valid = true; } else if (strcmp("Radius",ConstraintType) == 0) { this->getConstraintPtr()->Type = Radius; // set a value that is out of range of result of atan2 // this value is handled in ViewProviderSketch this->getConstraintPtr()->LabelPosition = 10; valid = true; } if (valid) { this->getConstraintPtr()->First = FirstIndex; this->getConstraintPtr()->setValue(Value); return 0; } } } PyErr_Clear(); if (PyArg_ParseTuple(args, "siiO", &ConstraintType, &FirstIndex, &any_index, &index_or_value)) { // ConstraintType, GeoIndex1, PosIndex1, GeoIndex2 if (PyInt_Check(index_or_value)) { FirstPos = any_index; SecondIndex = PyInt_AsLong(index_or_value); bool valid = false; if (strcmp("Perpendicular", ConstraintType) == 0) { this->getConstraintPtr()->Type = Perpendicular; valid = true; } else if (strcmp("Tangent", ConstraintType) == 0) { this->getConstraintPtr()->Type = Tangent; valid = true; } else if (strcmp("PointOnObject", ConstraintType) == 0) { this->getConstraintPtr()->Type = PointOnObject; valid = true; } else if (strstr(ConstraintType,"InternalAlignment") != NULL) { this->getConstraintPtr()->Type = InternalAlignment; valid = true; if(strstr(ConstraintType,"EllipseFocus1") != NULL) this->getConstraintPtr()->AlignmentType=EllipseFocus1; else if(strstr(ConstraintType,"EllipseFocus2") != NULL) this->getConstraintPtr()->AlignmentType=EllipseFocus2; else { this->getConstraintPtr()->AlignmentType=Undef; valid = false; } } if (valid) { this->getConstraintPtr()->First = FirstIndex; this->getConstraintPtr()->FirstPos = (Sketcher::PointPos) FirstPos; this->getConstraintPtr()->Second = SecondIndex; return 0; } } // ConstraintType, GeoIndex1, GeoIndex2, Value // ConstraintType, GeoIndex, PosIndex, Value if (PyNumber_Check(index_or_value)) { // can be float or int SecondIndex = any_index; Value = PyFloat_AsDouble(index_or_value); //if (strcmp("Distance",ConstraintType) == 0) { // this->getConstraintPtr()->Type = Distance; // this->getConstraintPtr()->First = FirstIndex; // this->getConstraintPtr()->Second = SecondIndex; // this->getConstraintPtr()->Value = Value; // return 0; //} //else if (strcmp("Angle",ConstraintType) == 0) { if (PyObject_TypeCheck(index_or_value, &(Base::QuantityPy::Type))) { Base::Quantity q = *(static_cast<Base::QuantityPy*>(index_or_value)->getQuantityPtr()); if (q.getUnit() == Base::Unit::Angle) Value = q.getValueAs(Base::Quantity::Radian); } this->getConstraintPtr()->Type = Angle; this->getConstraintPtr()->First = FirstIndex; this->getConstraintPtr()->Second = SecondIndex; this->getConstraintPtr()->setValue(Value); return 0; } else if (strcmp("DistanceX",ConstraintType) == 0) { FirstPos = SecondIndex; SecondIndex = -1; this->getConstraintPtr()->Type = DistanceX; this->getConstraintPtr()->First = FirstIndex; this->getConstraintPtr()->FirstPos = (Sketcher::PointPos) FirstPos; this->getConstraintPtr()->setValue(Value); return 0; } else if (strcmp("DistanceY",ConstraintType) == 0) { FirstPos = SecondIndex; SecondIndex = -1; this->getConstraintPtr()->Type = DistanceY; this->getConstraintPtr()->First = FirstIndex; this->getConstraintPtr()->FirstPos = (Sketcher::PointPos) FirstPos; this->getConstraintPtr()->setValue(Value); return 0; } } } PyErr_Clear(); if (PyArg_ParseTuple(args, "siiiO", &ConstraintType, &intArg1, &intArg2, &intArg3, &oNumArg4)) { // Value, ConstraintType, GeoIndex1, PosIndex1, GeoIndex2, PosIndex2 if (PyInt_Check(oNumArg4)) { intArg4 = PyInt_AsLong(oNumArg4); bool valid = false; if (strcmp("Coincident", ConstraintType) == 0) { this->getConstraintPtr()->Type = Coincident; valid = true; } else if (strcmp("Horizontal", ConstraintType) == 0) { this->getConstraintPtr()->Type = Horizontal; valid = true; } else if (strcmp("Vertical", ConstraintType) == 0) { this->getConstraintPtr()->Type = Vertical; valid = true; } else if (strcmp("Perpendicular", ConstraintType) == 0) { this->getConstraintPtr()->Type = Perpendicular; valid = true; } else if (strcmp("Tangent", ConstraintType) == 0) { this->getConstraintPtr()->Type = Tangent; valid = true; } else if (strcmp("TangentViaPoint", ConstraintType) == 0) { this->getConstraintPtr()->Type = Tangent; //valid = true;//non-standard assignment this->getConstraintPtr()->First = intArg1; this->getConstraintPtr()->FirstPos = Sketcher::none; this->getConstraintPtr()->Second = intArg2; this->getConstraintPtr()->SecondPos = Sketcher::none; this->getConstraintPtr()->Third = intArg3; this->getConstraintPtr()->ThirdPos = (Sketcher::PointPos) intArg4; return 0; } else if (strcmp("PerpendicularViaPoint", ConstraintType) == 0) { this->getConstraintPtr()->Type = Perpendicular; //valid = true;//non-standard assignment this->getConstraintPtr()->First = intArg1; this->getConstraintPtr()->FirstPos = Sketcher::none; this->getConstraintPtr()->Second = intArg2; this->getConstraintPtr()->SecondPos = Sketcher::none; this->getConstraintPtr()->Third = intArg3; this->getConstraintPtr()->ThirdPos = (Sketcher::PointPos) intArg4; return 0; } if (valid) { this->getConstraintPtr()->First = intArg1; this->getConstraintPtr()->FirstPos = (Sketcher::PointPos) intArg2; this->getConstraintPtr()->Second = intArg3; this->getConstraintPtr()->SecondPos = (Sketcher::PointPos) intArg4; return 0; } } // ConstraintType, GeoIndex1, PosIndex1, GeoIndex2, Value if (PyNumber_Check(oNumArg4)) { // can be float or int Value = PyFloat_AsDouble(oNumArg4); if (strcmp("Distance",ConstraintType) == 0 ) { this->getConstraintPtr()->Type = Distance; this->getConstraintPtr()->First = intArg1; this->getConstraintPtr()->FirstPos = (Sketcher::PointPos) intArg2; this->getConstraintPtr()->Second = intArg3; this->getConstraintPtr()->setValue(Value); return 0; } } } PyErr_Clear(); if (PyArg_ParseTuple(args, "siiiiO", &ConstraintType, &intArg1, &intArg2, &intArg3, &intArg4, &oNumArg5)) { // ConstraintType, GeoIndex1, PosIndex1, GeoIndex2, PosIndex2, GeoIndex3 if (PyInt_Check(oNumArg5)) { intArg5 = PyInt_AsLong(oNumArg5); if (strcmp("Symmetric",ConstraintType) == 0 ) { this->getConstraintPtr()->Type = Symmetric; this->getConstraintPtr()->First = intArg1; this->getConstraintPtr()->FirstPos = (Sketcher::PointPos) intArg2; this->getConstraintPtr()->Second = intArg3; this->getConstraintPtr()->SecondPos = (Sketcher::PointPos) intArg4; this->getConstraintPtr()->Third = intArg5; return 0; } } // ConstraintType, GeoIndex1, PosIndex1, GeoIndex2, PosIndex2, Value if (PyNumber_Check(oNumArg5)) { // can be float or int Value = PyFloat_AsDouble(oNumArg5); bool valid=false; if (strcmp("Distance",ConstraintType) == 0 ) { this->getConstraintPtr()->Type = Distance; valid = true; } else if (strcmp("DistanceX",ConstraintType) == 0) { this->getConstraintPtr()->Type = DistanceX; valid = true; } else if (strcmp("DistanceY",ConstraintType) == 0) { this->getConstraintPtr()->Type = DistanceY; valid = true; } else if (strcmp("Angle",ConstraintType) == 0 ) { if (PyObject_TypeCheck(oNumArg5, &(Base::QuantityPy::Type))) { Base::Quantity q = *(static_cast<Base::QuantityPy*>(oNumArg5)->getQuantityPtr()); if (q.getUnit() == Base::Unit::Angle) Value = q.getValueAs(Base::Quantity::Radian); } this->getConstraintPtr()->Type = Angle; valid = true; } else if (strcmp("AngleViaPoint",ConstraintType) == 0 ) { if (PyObject_TypeCheck(oNumArg5, &(Base::QuantityPy::Type))) { Base::Quantity q = *(static_cast<Base::QuantityPy*>(oNumArg5)->getQuantityPtr()); if (q.getUnit() == Base::Unit::Angle) Value = q.getValueAs(Base::Quantity::Radian); } this->getConstraintPtr()->Type = Angle; //valid = true;//non-standard assignment this->getConstraintPtr()->First = intArg1; this->getConstraintPtr()->FirstPos = Sketcher::none; this->getConstraintPtr()->Second = intArg2; //let's goof up all the terminology =) this->getConstraintPtr()->SecondPos = Sketcher::none; this->getConstraintPtr()->Third = intArg3; this->getConstraintPtr()->ThirdPos = (Sketcher::PointPos) intArg4; this->getConstraintPtr()->setValue(Value); return 0; } if (valid) { this->getConstraintPtr()->First = intArg1; this->getConstraintPtr()->FirstPos = (Sketcher::PointPos) intArg2; this->getConstraintPtr()->Second = intArg3; this->getConstraintPtr()->SecondPos = (Sketcher::PointPos) intArg4; this->getConstraintPtr()->setValue(Value); return 0; } } } PyErr_Clear(); if (PyArg_ParseTuple(args, "siiiiiO", &ConstraintType, &FirstIndex, &FirstPos, &SecondIndex, &SecondPos, &ThirdIndex, &index_or_value)) { if (PyInt_Check(index_or_value)) { ThirdPos = PyInt_AsLong(index_or_value); // ConstraintType, GeoIndex1, PosIndex1, GeoIndex2, PosIndex2, GeoIndex3, PosIndex3 if (strcmp("Symmetric",ConstraintType) == 0 ) { this->getConstraintPtr()->Type = Symmetric; this->getConstraintPtr()->First = FirstIndex; this->getConstraintPtr()->FirstPos = (Sketcher::PointPos) FirstPos; this->getConstraintPtr()->Second = SecondIndex; this->getConstraintPtr()->SecondPos = (Sketcher::PointPos) SecondPos; this->getConstraintPtr()->Third = ThirdIndex; this->getConstraintPtr()->ThirdPos = (Sketcher::PointPos) ThirdPos; return 0; } } if (PyNumber_Check(index_or_value)) { // can be float or int Value = PyFloat_AsDouble(index_or_value); if (strcmp("SnellsLaw",ConstraintType) == 0 ) { this->getConstraintPtr()->Type = SnellsLaw; this->getConstraintPtr()->First = FirstIndex; this->getConstraintPtr()->FirstPos = (Sketcher::PointPos) FirstPos; this->getConstraintPtr()->Second = SecondIndex; this->getConstraintPtr()->SecondPos = (Sketcher::PointPos) SecondPos; this->getConstraintPtr()->Third = ThirdIndex; this->getConstraintPtr()->ThirdPos = none; this->getConstraintPtr()->setValue(Value); return 0; } } } std::stringstream str; str << "Invalid parameters: "; Py::Tuple tuple(args); str << tuple.as_string() << std::endl; str << "Constraint constructor accepts:" << std::endl << "-- empty parameter list" << std::endl << "-- Constraint type and index" << std::endl; PyErr_SetString(PyExc_TypeError, str.str().c_str()); return -1; }
QString UnitsSchemaImperialBuilding::schemaTranslate(Base::Quantity quant,double &factor,QString &unitString) { // this schema expresses distances in feet + inches + fractions // ex: 3'- 4 1/4" Unit unit = quant.getUnit(); if(unit == Unit::Length){ unitString = QString::fromLatin1("in"); factor = 25.4; double inchValue = std::abs(quant.getValue())/25.4; int feet = inchValue/12; double inchPart = inchValue - (double)feet*12; int inches = (int)inchPart; double fraction = inchPart - (int)inchPart; if (fraction > 0.9375) { inches++; fraction = 0.0; } // if the quantity is too small it is rounded to zero if (std::abs(quant.getValue()) <= 1.5875) return QString::fromLatin1("0"); // build representation std::stringstream output; if (quant.getValue() < 0) output << "-"; // feet if (feet > 0) { output << feet << "'"; if ( (inches > 0) || (fraction > 0.0625) ) output << " "; } // inches if (inches > 0) { output << inches; if (fraction > 0.0625) output << "+"; else output << "\""; } // fraction if (fraction <= 0.0625) {} else if (fraction > 0.8125) output << "7/8\""; else if (fraction > 0.6875) output << "3/4\""; else if (fraction > 0.5625) output << "5/8\""; else if (fraction > 0.4375) output << "1/2\""; else if (fraction > 0.3125) output << "3/8\""; else if (fraction > 0.1875) output << "1/4\""; else output << "1/8\""; return QString::fromLatin1(output.str().c_str()); }else if (unit == Unit::Area){ unitString = QString::fromLatin1("sqft"); factor = 92903.04; }else if (unit == Unit::Volume){ unitString = QString::fromLatin1("cuft"); factor = 28316846.592; }else{ unitString = quant.getUnit().getString(); factor = 1.0; } QLocale Lc = QLocale::system(); Lc.setNumberOptions(Lc.OmitGroupSeparator | Lc.RejectGroupSeparator); QString Ln = Lc.toString((quant.getValue() / factor), 'f', Base::UnitsApi::getDecimals()); return QString::fromUtf8("%1 %2").arg(Ln).arg(unitString); }
void EditDatumDialog::exec(bool atCursor) { // Return if constraint doesn't have editable value if (Constr->Type == Sketcher::Distance || Constr->Type == Sketcher::DistanceX || Constr->Type == Sketcher::DistanceY || Constr->Type == Sketcher::Radius || Constr->Type == Sketcher::Angle) { if (sketch->hasConflicts()) { QMessageBox::critical(qApp->activeWindow(), QObject::tr("Distance constraint"), QObject::tr("Not allowed to edit the datum because the sketch contains conflicting constraints")); return; } Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView(); Gui::View3DInventorViewer *viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer(); QDialog dlg(viewer->getGLWidget()); Ui::InsertDatum ui_ins_datum; ui_ins_datum.setupUi(&dlg); double datum = Constr->Value; Base::Quantity init_val; if (Constr->Type == Sketcher::Angle) { datum = Base::toDegrees<double>(datum); dlg.setWindowTitle(tr("Insert angle")); init_val.setUnit(Base::Unit::Angle); ui_ins_datum.label->setText(tr("Angle:")); ui_ins_datum.labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherAngle")); } else if (Constr->Type == Sketcher::Radius) { dlg.setWindowTitle(tr("Insert radius")); init_val.setUnit(Base::Unit::Length); ui_ins_datum.label->setText(tr("Radius:")); ui_ins_datum.labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherLength")); } else { dlg.setWindowTitle(tr("Insert length")); init_val.setUnit(Base::Unit::Length); ui_ins_datum.label->setText(tr("Length:")); ui_ins_datum.labelEdit->setParamGrpPath(QByteArray("User parameter:BaseApp/History/SketcherLength")); } //ui_ins_datum.lineEdit->setParamGrpPath("User parameter:History/Sketcher/SetDatum"); if (Constr->Type == Sketcher::Angle || ((Constr->Type == Sketcher::DistanceX || Constr->Type == Sketcher::DistanceY) && Constr->FirstPos == Sketcher::none || Constr->Second != Sketcher::Constraint::GeoUndef)) // hide negative sign init_val.setValue(std::abs(datum)); else // show negative sign init_val.setValue(datum); ui_ins_datum.labelEdit->setValue(init_val); ui_ins_datum.labelEdit->selectNumber(); if (atCursor) dlg.setGeometry(QCursor::pos().x() - dlg.geometry().width() / 2, QCursor::pos().y(), dlg.geometry().width(), dlg.geometry().height()); if (dlg.exec()) { Base::Quantity newQuant = ui_ins_datum.labelEdit->getQuantity(); if (newQuant.isQuantity()) { // save the value for the history ui_ins_datum.labelEdit->pushToHistory(); double newDatum = newQuant.getValue(); if (Constr->Type == Sketcher::Angle || ((Constr->Type == Sketcher::DistanceX || Constr->Type == Sketcher::DistanceY) && Constr->FirstPos == Sketcher::none || Constr->Second != Sketcher::Constraint::GeoUndef)) { // Permit negative values to flip the sign of the constraint if (newDatum >= 0) // keep the old sign newDatum = ((datum >= 0) ? 1 : -1) * std::abs(newDatum); else // flip sign newDatum = ((datum >= 0) ? -1 : 1) * std::abs(newDatum); } try { Gui::Command::openCommand("Modify sketch constraints"); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.setDatum(%i,App.Units.Quantity('%f %s'))", sketch->getNameInDocument(), ConstrNbr, newDatum, (const char*)newQuant.getUnit().getString().toUtf8()); Gui::Command::commitCommand(); Gui::Command::updateActive(); } catch (const Base::Exception& e) { QMessageBox::critical(qApp->activeWindow(), QObject::tr("Dimensional constraint"), QString::fromUtf8(e.what())); Gui::Command::abortCommand(); } } } } }
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; }
void QuantitySpinBox::setUnitText(const QString& str) { Base::Quantity quant = Base::Quantity::parse(str); setUnit(quant.getUnit()); }
QString UnitsSchemaImperialDecimal::schemaTranslate(const Base::Quantity& quant, double &factor, QString &unitString) { double UnitValue = std::abs(quant.getValue()); Unit unit = quant.getUnit(); // for imperial user/programmer mind; UnitValue is in internal system, that means // mm/kg/s. And all combined units have to be calculated from there! // now do special treatment on all cases seems necessary: if (unit == Unit::Length) { // Length handling ============================ if (UnitValue < 0.00000254) {// smaller then 0.001 thou -> inch and scientific notation unitString = QString::fromLatin1("in"); factor = 25.4; //}else if(UnitValue < 2.54){ // smaller then 0.1 inch -> Thou (mil) // unitString = QString::fromLatin1("thou"); // factor = 0.0254; } else { // bigger then 1000 mi -> scientific notation unitString = QString::fromLatin1("in"); factor = 25.4; } } else if (unit == Unit::Area) { // TODO Cascade for the Areas // default action for all cases without special treatment: unitString = QString::fromLatin1("in^2"); factor = 645.16; } else if (unit == Unit::Volume) { // TODO Cascade for the Volume // default action for all cases without special treatment: unitString = QString::fromLatin1("in^3"); factor = 16387.064; } else if (unit == Unit::Mass) { // TODO Cascade for the weights // default action for all cases without special treatment: unitString = QString::fromLatin1("lb"); factor = 0.45359237; } else if (unit == Unit::Pressure) { if (UnitValue < 6894.744) {// psi is the smallest unitString = QString::fromLatin1("psi"); factor = 6.894744825494; } else { // bigger then 1000 ksi -> psi + scientific notation unitString = QString::fromLatin1("psi"); factor = 6.894744825494; } } else if (unit == Unit::Velocity) { unitString = QString::fromLatin1("in/min"); factor = 25.4/60; } else { // default action for all cases without special treatment: unitString = quant.getUnit().getString(); factor = 1.0; } return toLocale(quant, factor, unitString); }
QString UnitsSchemaImperial1::schemaTranslate(Base::Quantity quant,double &factor,QString &unitString) { double UnitValue = std::abs(quant.getValue()); Unit unit = quant.getUnit(); // for imperial user/programmer mind; UnitValue is in internal system, that means // mm/kg/s. And all combined units have to be calculated from there! // now do special treatment on all cases seems necessary: if(unit == Unit::Length){ // Length handling ============================ if(UnitValue < 0.00000254){// smaller then 0.001 thou -> inch and scientific notation unitString = QString::fromLatin1("in"); factor = 25.4; }else if(UnitValue < 2.54){ // smaller then 0.1 inch -> Thou (mil) unitString = QString::fromLatin1("thou"); factor = 0.0254; }else if(UnitValue < 304.8){ unitString = QString::fromLatin1("\""); factor = 25.4; }else if(UnitValue < 914.4){ unitString = QString::fromLatin1("\'"); factor = 304.8; }else if(UnitValue < 1609344.0){ unitString = QString::fromLatin1("yd"); factor = 914.4; }else if(UnitValue < 1609344000.0 ){ unitString = QString::fromLatin1("mi"); factor = 1609344.0; }else{ // bigger then 1000 mi -> scientific notation unitString = QString::fromLatin1("in"); factor = 25.4; } }else if (unit == Unit::Area){ // TODO Cascade for the Areas // default action for all cases without special treatment: unitString = QString::fromLatin1("in^2"); factor = 645.16; }else if (unit == Unit::Volume){ // TODO Cascade for the Volume // default action for all cases without special treatment: unitString = QString::fromLatin1("in^3"); factor = 16387.064; }else if (unit == Unit::Mass){ // TODO Cascade for the wights // default action for all cases without special treatment: unitString = QString::fromLatin1("lb"); factor = 0.45359237; }else if (unit == Unit::Pressure){ if(UnitValue < 145.038){// psi is the smallest unitString = QString::fromLatin1("psi"); factor = 0.145038; }else if(UnitValue < 145038){ unitString = QString::fromLatin1("ksi"); factor = 145.038; }else{ // bigger then 1000 ksi -> psi + scientific notation unitString = QString::fromLatin1("psi"); factor = 0.145038; } }else{ // default action for all cases without special treatment: unitString = quant.getUnit().getString(); factor = 1.0; } return QString::fromLatin1("%L1 %2").arg(quant.getValue() / factor).arg(unitString); }