Beispiel #1
0
void Gui::QuantitySpinBox::onChange() {
    
    Q_ASSERT(isBound());
    
    if (getExpression()) {
        std::unique_ptr<Expression> result(getExpression()->eval());
        NumberExpression * value = freecad_dynamic_cast<NumberExpression>(result.get());

        if (value) {
            std::stringstream s;
            s << value->getValue();

            lineEdit()->setText(value->getQuantity().getUserString());
            setReadOnly(true);
            QPixmap pixmap = getIcon(":/icons/bound-expression.svg", QSize(iconHeight, iconHeight));
            iconLabel->setPixmap(pixmap);

            QPalette p(lineEdit()->palette());
            p.setColor(QPalette::Text, Qt::lightGray);
            lineEdit()->setPalette(p);
        }
        iconLabel->setToolTip(QString());
        setToolTip(Base::Tools::fromStdString(getExpression()->toString()));
    }
    else {
        setReadOnly(false);
        QPixmap pixmap = getIcon(":/icons/bound-expression-unset.svg", QSize(iconHeight, iconHeight));
        iconLabel->setPixmap(pixmap);
        QPalette p(lineEdit()->palette());
        p.setColor(QPalette::Active, QPalette::Text, defaultPalette.color(QPalette::Text));
        lineEdit()->setPalette(p);
        iconLabel->setToolTip(QString());
    }
    iconLabel->setToolTip(QString());
}
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);
    }
}
void Gui::QuantitySpinBox::setExpression(boost::shared_ptr<Expression> expr)
{
    Q_ASSERT(isBound());

    try {
        ExpressionBinding::setExpression(expr);

        if (getExpression()) {
            std::auto_ptr<Expression> result(getExpression()->eval());
            NumberExpression * value = freecad_dynamic_cast<NumberExpression>(result.get());

            if (value) {
                updateText(value->getQuantity());
                setReadOnly(true);
                iconLabel->setPixmap(getIcon(":/icons/bound-expression.svg", QSize(iconHeight, iconHeight)));

                QPalette p(lineEdit()->palette());
                p.setColor(QPalette::Text, Qt::lightGray);
                lineEdit()->setPalette(p);
            }
            setToolTip(Base::Tools::fromStdString(getExpression()->toString()));
        }
        else {
            setReadOnly(false);
            iconLabel->setPixmap(getIcon(":/icons/bound-expression-unset.svg", QSize(iconHeight, iconHeight)));
            QPalette p(lineEdit()->palette());
            p.setColor(QPalette::Active, QPalette::Text, defaultPalette.color(QPalette::Text));
            lineEdit()->setPalette(p);

        }
        iconLabel->setToolTip(QString());
    }
    catch (const Base::Exception & e) {
        setReadOnly(true);
        QPalette p(lineEdit()->palette());
        p.setColor(QPalette::Active, QPalette::Text, Qt::red);
        lineEdit()->setPalette(p);
        iconLabel->setToolTip(QString::fromAscii(e.what()));
    }
}
UnitExpression * parseUnit(const App::DocumentObject *owner, const char* buffer)
{
    // parse from buffer
    ExpressionParser::YY_BUFFER_STATE my_string_buffer = ExpressionParser_scan_string (buffer);

    initParser(owner);

    // run the parser
    int result = ExpressionParser::ExpressionParser_yyparse ();

    // free the scan buffer
    ExpressionParser::ExpressionParser_delete_buffer (my_string_buffer);

    if (result != 0)
        throw Base::Exception("Failed to parse expression.");

    if (ScanResult == 0)
        throw Base::Exception("Unknown error in expression");

    // Simplify expression
    Expression * simplified = ScanResult->simplify();
    delete ScanResult;

    if (unitExpression) {
        NumberExpression * num = freecad_dynamic_cast<NumberExpression>(simplified);

        if (num) {
           simplified = new UnitExpression(num->getOwner(), num->getQuantity());
            delete num;
        }
        return freecad_dynamic_cast<UnitExpression>(simplified);
    }
    else {
        delete simplified;
        throw Expression::Exception("Expression is not a unit.");
        return 0;
    }
}