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);
}
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()));
}
/// 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;
}
Пример #5
0
QString QuantitySpinBox::textFromValue(const Base::Quantity& value) const
{
    double factor;
    QString unitStr;
    QString str = value.getUserString(factor, unitStr);
    if (qAbs(value.getValue()) >= 1000.0) {
        str.remove(locale().groupSeparator());
    }
    return str;
}
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;
}
Пример #7
0
// Gets called after call of 'validateAndInterpret'
void QuantitySpinBox::userInput(const QString & text)
{
    Q_D(QuantitySpinBox);

    QString tmp = text;
    int pos = 0;
    QValidator::State state;
    Base::Quantity res = d->validateAndInterpret(tmp, pos, state);
    if (state == QValidator::Acceptable) {
        d->validInput = true;
        d->validStr = text;
    }
    else if (state == QValidator::Intermediate) {
        tmp = tmp.trimmed();
        tmp += QLatin1Char(' ');
        tmp += d->unitStr;
        Base::Quantity res2 = d->validateAndInterpret(tmp, pos, state);
        if (state == QValidator::Acceptable) {
            d->validInput = true;
            d->validStr = tmp;
            res = res2;
        }
        else {
            d->validInput = false;
            return;
        }
    }
    else {
        d->validInput = false;
        return;
    }

    double factor;
    res.getUserString(factor,d->unitStr);
    d->unitValue = res.getValue()/factor;
    d->quantity = res;

    // signaling
    valueChanged(res);
    valueChanged(res.getValue());
}
Пример #8
0
QString UnitsSchema::toLocale(const Base::Quantity& quant, double factor, const QString& unitString) const
{
    //return QString::fromUtf8("%L1 %2").arg(quant.getValue() / factor).arg(unitString);
    QLocale Lc = QLocale::system();
    const QuantityFormat& format = quant.getFormat();
    if (format.option != QuantityFormat::None) {
        uint opt = static_cast<uint>(format.option);
        Lc.setNumberOptions(static_cast<QLocale::NumberOptions>(opt));
    }

    QString Ln = Lc.toString((quant.getValue() / factor), format.toFormat(), format.precision);
    return QString::fromUtf8("%1 %2").arg(Ln, unitString);
}
bool PropertyConstraintListItem::event (QEvent* ev)
{
    if (ev->type() == QEvent::DynamicPropertyChange) {
        if (!blockEvent) {
            QDynamicPropertyChangeEvent* ce = static_cast<QDynamicPropertyChangeEvent*>(ev);
            // Get property via internal name of a PropertyUnit
            QVariant prop = property(ce->propertyName());
            QString propName = QString::fromLatin1(ce->propertyName());
            Base::Quantity quant = prop.value<Base::Quantity>();

            Sketcher::PropertyConstraintList* item;

            int id = 0;
            if (this->parent()->getTypeId() == SketcherGui::PropertyConstraintListItem::getClassTypeId()) {
                item = static_cast<Sketcher::PropertyConstraintList*>(this->parent()->getFirstProperty());
            }
            else {
                item = static_cast<Sketcher::PropertyConstraintList*>(getFirstProperty());
            }

            const std::vector< Sketcher::Constraint * > &vals = item->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 ) {

                    // Get the internal name
                    QString internalName = QString::fromLatin1("Constraint%1").arg(id+1);
                    if (internalName == propName) {
                        double datum = quant.getValue();
                        if ((*it)->Type == Sketcher::Angle)
                            datum = Base::toRadians<double>(datum);
                        const_cast<Sketcher::Constraint *>((*it))->setValue(datum);
                        item->set1Value(id,(*it));
                        break;
                    }
                }
            }
        }
    }

    return PropertyItem::event(ev);
}
Пример #10
0
App::DocumentObjectExecReturn * DrawSVGTemplate::execute(void)
{
    std::string templValue = Template.getValue();
    if (templValue.empty())
        return App::DocumentObject::StdReturn;

    Base::FileInfo fi(templValue);
    if (!fi.isReadable()) {
        // non-empty template value, but can't read file
        // if there is a old absolute template file set use a redirect
        fi.setFile(App::Application::getResourceDir() + "Mod/Drawing/Templates/" + fi.fileName());
        // try the redirect
        if (!fi.isReadable()) {
            Base::Console().Log("DrawPage::execute() not able to open %s!\n",Template.getValue());
            std::string error = std::string("Cannot open file ") + Template.getValue();
            return new App::DocumentObjectExecReturn(error);
        }
    }

    if (std::string(PageResult.getValue()).empty())                    //first time through?
        PageResult.setValue(fi.filePath().c_str());

    // open Template file
    string line;
    ifstream inTemplate (fi.filePath().c_str());

    ostringstream copyTemplate;
    string tempendl = "--endOfLine--";

    //inTemplate to copyTemplate
    //remove DrawingContent comment line
    //change line endings
    //capture TitleBlock dimensions
    while (getline(inTemplate,line))
    {
        // copy every line except the DrawingContent comment?
        if(line.find("<!-- DrawingContent -->") == string::npos) {
            // if not -  write through
            copyTemplate << line << tempendl;
        }

        //double t0, t1,t2,t3;
        float t0, t1,t2,t3;
        if(line.find("<!-- Title block") != std::string::npos) {
            (void) sscanf(line.c_str(), "%*s %*s %*s %f %f %f %f", &t0, &t1, &t2, &t3);    //eg "    <!-- Working space 10 10 410 287 -->"
                                                                                           //coverity 151677
            blockDimensions = QRectF(t0, t1, t2 - t0, t3 - t1);
        }

    }
    inTemplate.close();

    string outfragment(copyTemplate.str());
    std::string newfragment = outfragment;

    // update EditableText SVG clauses with Property values
    std::map<std::string, std::string> subs = EditableTexts.getValues();

    if (subs.size() > 0) {
        boost::regex e1 ("<text.*?freecad:editable=\"(.*?)\".*?<tspan.*?>(.*?)</tspan>");
        string::const_iterator begin, end;
        begin = outfragment.begin();
        end = outfragment.end();
        boost::match_results<std::string::const_iterator> what;

        // Find editable texts
        while (boost::regex_search(begin, end, what, e1)) {            //search in outfragment
            // if we have a replacement value for the text we've found
            if (subs.count(what[1].str())) {
                 // change it to specified value
                 boost::regex e2 ("(<text.*?freecad:editable=\"" + what[1].str() + "\".*?<tspan.*?)>(.*?)(</tspan>)");
                 newfragment = boost::regex_replace(newfragment, e2, "$1>" + subs[what[1].str()] + "$3");   //replace in newfragment
            }
            begin = what[0].second;
        }
    }


    // restoring linebreaks and saving the file
    boost::regex e3 ("--endOfLine--");
    string fmt = "\\n";
    outfragment = boost::regex_replace(newfragment, e3, fmt);

    const QString qsOut = QString::fromStdString(outfragment);
    QDomDocument doc(QString::fromLatin1("mydocument"));

    //if (!doc.setContent(&resultFile)) {
    if (!doc.setContent(qsOut)) {
        //setError(); //???? how/when does this get reset?
        std::string errMsg = std::string("Invalid SVG syntax in ") + getNameInDocument() + std::string(" - Check EditableTexts");
        return new App::DocumentObjectExecReturn(errMsg);
    } else {
        // make a temp file for FileIncluded Property
        string tempName = PageResult.getExchangeTempFile();
        ofstream outfinal(tempName.c_str());
        outfinal << outfragment;
        outfinal.close();
        PageResult.setValue(tempName.c_str());
    }

    // Calculate the dimensions of the page and store for retrieval
    // Parse the document XML
    QDomElement docElem = doc.documentElement();

    // Obtain the size of the SVG document by reading the document attributes
    Base::Quantity quantity;

    // Obtain the width
    QString str = docElem.attribute(QString::fromLatin1("width"));
    quantity = Base::Quantity::parse(str);
    quantity.setUnit(Base::Unit::Length);

    Width.setValue(quantity.getValue());

    str = docElem.attribute(QString::fromLatin1("height"));
    quantity = Base::Quantity::parse(str);
    quantity.setUnit(Base::Unit::Length);

    Height.setValue(quantity.getValue());

    bool isLandscape = getWidth() / getHeight() >= 1.;

    Orientation.setValue(isLandscape ? 1 : 0);

    return TechDraw::DrawTemplate::execute();
}
Пример #11
0
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));
}
Пример #12
0
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;
}
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);
}
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);
}
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();
                }
            }
        }
    }
}
Пример #16
0
    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;
    }
Пример #17
0
DocumentObjectExecReturn *App::PropertyExpressionEngine::execute()
{
    DocumentObject * docObj = freecad_dynamic_cast<DocumentObject>(getContainer());

    if (!docObj)
        throw Base::Exception("PropertyExpressionEngine must be owned by a DocumentObject.");

    if (running)
        return DocumentObject::StdReturn;

    /* Resetter class, to ensure that the "running" variable gets set to false, even if
     * an exception is thrown.
     */

    class resetter {
    public:
        resetter(bool & b) : _b(b) { _b = true; }
        ~resetter() { _b = false; }

    private:
        bool & _b;
    };

    resetter r(running);

    // Compute evaluation order
    std::vector<App::ObjectIdentifier> evaluationOrder = computeEvaluationOrder();
    std::vector<ObjectIdentifier>::const_iterator it = evaluationOrder.begin();

#ifdef FC_PROPERTYEXPRESSIONENGINE_LOG
    std::clog << "Computing expressions for " << getName() << std::endl;
#endif

    /* Evaluate the expressions, and update properties */
    while (it != evaluationOrder.end()) {

        // Get property to update
        Property * prop = it->getProperty();

        if (!prop)
            throw Base::Exception("Path does not resolve to a property.");

        DocumentObject* parent = freecad_dynamic_cast<DocumentObject>(prop->getContainer());

        /* Make sure property belongs to the same container as this PropertyExpressionEngine */
        if (parent != docObj)
            throw Base::Exception("Invalid property owner.");

        // Evaluate expression
        std::auto_ptr<Expression> e(expressions[*it].expression->eval());

#ifdef FC_PROPERTYEXPRESSIONENGINE_LOG
        {
            Base::Quantity q;
            boost::any value = e->getValueAsAny();

            if (value.type() == typeid(Base::Quantity))
                q = boost::any_cast<Base::Quantity>(value);
            else if (value.type() == typeid(double))
                q = boost::any_cast<double>(value);
            else {
                std::clog << "Unknown return value for expression.";
                q = 0;
            }

            std::clog << "Assigning value " << q.getValue() << " to " << (*it).toString().c_str() << " (" << prop->getName() <<  ")" << std::endl;
        }
#endif

        /* Set value of property */
        prop->setPathValue(*it, e->getValueAsAny());

        ++it;
    }
    return DocumentObject::StdReturn;
}
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);
}