! * \sa FunctionValuesDialog::generate() */
| 2494 | * \sa FunctionValuesDialog::generate() |
| 2495 | */ |
| 2496 | void ColumnPrivate::updateFormula() { |
| 2497 | if (m_formula.isEmpty()) |
| 2498 | return; |
| 2499 | DEBUG(Q_FUNC_INFO) |
| 2500 | // determine variable names and the data vectors of the specified columns |
| 2501 | QVector<QVector<double>*> xVectors; |
| 2502 | |
| 2503 | bool valid = true; |
| 2504 | QStringList formulaVariableNames; |
| 2505 | int maxRowCount = 0; |
| 2506 | |
| 2507 | auto numberLocale = QLocale(); |
| 2508 | // need to disable group separator since parser can't handle it |
| 2509 | numberLocale.setNumberOptions(QLocale::OmitGroupSeparator); |
| 2510 | |
| 2511 | for (const auto& formulaData : m_formulaData) { |
| 2512 | auto* column = formulaData.column(); |
| 2513 | if (!column) { |
| 2514 | valid = false; |
| 2515 | break; |
| 2516 | } |
| 2517 | formulaVariableNames << formulaData.variableName(); |
| 2518 | |
| 2519 | if (column->columnMode() == AbstractColumn::ColumnMode::Double) |
| 2520 | xVectors << static_cast<QVector<double>*>(column->data()); |
| 2521 | else { |
| 2522 | // convert integers to doubles first |
| 2523 | auto* xVector = new QVector<double>(column->rowCount()); |
| 2524 | for (int i = 0; i < column->rowCount(); ++i) |
| 2525 | (*xVector)[i] = column->valueAt(i); |
| 2526 | |
| 2527 | xVectors << xVector; |
| 2528 | } |
| 2529 | |
| 2530 | if (column->rowCount() > maxRowCount) |
| 2531 | maxRowCount = column->rowCount(); |
| 2532 | } |
| 2533 | |
| 2534 | if (valid) { |
| 2535 | // resize the spreadsheet if one of the data vectors from |
| 2536 | // other spreadsheet(s) has more elements than the parent spreadsheet |
| 2537 | // and if the option "auto resize" is activated |
| 2538 | if (m_formulaAutoResize && rowCount() < maxRowCount) { |
| 2539 | auto* spreadsheet = static_cast<Spreadsheet*>(q->parentAspect()); |
| 2540 | // In the tests spreadsheet might not exist, because directly the column was created |
| 2541 | if (spreadsheet) |
| 2542 | spreadsheet->setRowCount(maxRowCount); |
| 2543 | } |
| 2544 | |
| 2545 | // create new vector for storing the calculated values |
| 2546 | // the vectors with the variable data can be smaller then the result vector. So, not all values in the result vector might get initialized. |
| 2547 | //->"clean" the result vector first |
| 2548 | QVector<double> new_data(rowCount(), NAN); |
| 2549 | |
| 2550 | const auto payload = std::make_shared<PayloadColumn>(m_formulaData, new_data); |
| 2551 | |
| 2552 | // evaluate the expression for f(x_1, x_2, ...) and write the calculated values into a new vector. |
| 2553 | auto* parser = ExpressionParser::getInstance(); |
nothing calls this directly
no test coverage detected