void DoubleSpinBox::onChange() { if (getExpression()) { std::unique_ptr<Expression> result(getExpression()->eval()); NumberExpression * value = freecad_dynamic_cast<NumberExpression>(result.get()); if (value) { setValue(boost::math::round(value->getValue())); 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()); }
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); } }
///Cleans and minimizes the expression BaseExpression* DivideExpression::clean() { NumberExpression* lNumPart = dynamic_cast<NumberExpression*>(mRight->clean()); if(lNumPart && lNumPart->isOne()) return mLeft->clean(); lNumPart = dynamic_cast<NumberExpression*>(mLeft->clean()); if(lNumPart && lNumPart->isZero()) return new NumberExpression(0.0); return new DivideExpression(mLeft->clean(), mRight->clean()); }
Expression *ConditionalExpression::eval() const { std::auto_ptr<Expression> e(condition->eval()); NumberExpression * v = freecad_dynamic_cast<NumberExpression>(e.get()); if (v == 0) throw ExpressionError("Invalid expression"); if (fabs(v->getValue()) > 0.5) return trueExpr->eval(); else return falseExpr->eval(); }
Expression *ConditionalExpression::simplify() const { std::auto_ptr<Expression> e(condition->simplify()); NumberExpression * v = freecad_dynamic_cast<NumberExpression>(e.get()); if (v == 0) return new ConditionalExpression(owner, condition->simplify(), trueExpr->simplify(), falseExpr->simplify()); else { if (fabs(v->getValue()) > 0.5) return trueExpr->simplify(); else return falseExpr->simplify(); } }
void Sheet::updateProperty(CellAddress key) { const Property * prop; Cell * cell = getCell(key); if (cell != 0) { Expression * output; const Expression * input = cell->getExpression(); if (input) { output = input->eval(); } else { std::string s; if (cell->getStringContent(s)) output = new StringExpression(this, s); else output = new StringExpression(this, ""); } /* Eval returns either NumberExpression or StringExpression objects */ if (freecad_dynamic_cast<NumberExpression>(output)) { NumberExpression * number = static_cast<NumberExpression*>(output); if (number->getUnit().isEmpty()) prop = setFloatProperty(key, number->getValue()); else prop = setQuantityProperty(key, number->getValue(), number->getUnit()); } else prop = setStringProperty(key, freecad_dynamic_cast<StringExpression>(output)->getText().c_str()); delete output; } else clear(key); cellUpdated(key); }
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; } }