diff options
author | Balazs Varga <balazs.varga.extern@allotropia.de> | 2023-01-31 14:21:31 +0100 |
---|---|---|
committer | Balazs Varga <balazs.varga.extern@allotropia.de> | 2023-02-05 10:31:26 +0000 |
commit | d8ae6d1388f28c405c4de2dfe93dbfe2d8acd470 (patch) | |
tree | 3e16db426ad80959334064570195a9918fff984c /sc | |
parent | 90a043f2589a70f6e035ba350ff7f673ae677f2e (diff) |
Related: tdf#150098 sc validation: allowing formulas for validity test
Clean-up and a little optimization.
Change-Id: Ib56d959188912f4b18acb5466ce55bc7b5b4ee4b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146391
Tested-by: Jenkins
Reviewed-by: Balazs Varga <balazs.varga.extern@allotropia.de>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/validat.hxx | 4 | ||||
-rw-r--r-- | sc/source/core/data/validat.cxx | 196 |
2 files changed, 79 insertions, 121 deletions
diff --git a/sc/inc/validat.hxx b/sc/inc/validat.hxx index f28da4a1c50b..af43e37cc123 100644 --- a/sc/inc/validat.hxx +++ b/sc/inc/validat.hxx @@ -156,6 +156,10 @@ public: bool IsDataValid( ScRefCellValue& rCell, const ScAddress& rPos ) const; + /** Test, if formula is valid. */ + bool isFormulaResultsValidatable(const OUString& rTest, const ScAddress& rPos, SvNumberFormatter* pFormatter, + OUString& rStrResult, double& nVal, sal_uInt32& nFormat, bool& bIsVal) const; + // TRUE -> break bool DoError(weld::Window* pParent, const OUString& rInput, const ScAddress& rPos) const; void DoCalcError( ScFormulaCell* pCell ) const; diff --git a/sc/source/core/data/validat.cxx b/sc/source/core/data/validat.cxx index 2cdafa132594..8fb0f9f7924a 100644 --- a/sc/source/core/data/validat.cxx +++ b/sc/source/core/data/validat.cxx @@ -447,67 +447,12 @@ bool ScValidationData::IsDataValidCustom( if (rTest[0] == '=') { - std::optional<ScSimpleFormulaCalculator> pFCell(std::in_place, *mpDoc, rPos, rTest, true); - pFCell->SetLimitString(true); - - bool bColRowName = pFCell->HasColRowName(); - if (bColRowName) - { - // ColRowName from RPN-Code? - if (pFCell->GetCode()->GetCodeLen() <= 1) - { // ==1: area - // ==0: would be an area if... - OUString aBraced = "(" + rTest + ")"; - pFCell.emplace(*mpDoc, rPos, aBraced, true); - pFCell->SetLimitString(true); - } - else - bColRowName = false; - } - - FormulaError nErrCode = pFCell->GetErrCode(); - if (nErrCode == FormulaError::NONE || pFCell->IsMatrix()) - { - pFormatter = mpDoc->GetFormatTable(); - const Color* pColor; - if (pFCell->IsMatrix()) - { - rStrResult = pFCell->GetString().getString(); - } - else if (pFCell->IsValue()) - { - nVal = pFCell->GetValue(); - nFormat = pFormatter->GetStandardFormat(nVal, 0, - pFCell->GetFormatType(), ScGlobal::eLnge); - pFormatter->GetOutputString(nVal, nFormat, rStrResult, &pColor); - bIsVal = true; - } - else - { - nFormat = pFormatter->GetStandardFormat( - pFCell->GetFormatType(), ScGlobal::eLnge); - pFormatter->GetOutputString(pFCell->GetString().getString(), nFormat, - rStrResult, &pColor); - // Indicate it's a string, so a number string doesn't look numeric. - // Escape embedded quotation marks first by doubling them, as - // usual. Actually the result can be copy-pasted from the result - // box as literal into a formula expression. - rStrResult = "\"" + rStrResult.replaceAll("\"", "\"\"") + "\""; - } - - ScRange aTestRange; - if (bColRowName || (aTestRange.Parse(rTest, *mpDoc) & ScRefFlags::VALID)) - rStrResult += " ..."; - // area - - // check whether empty cells are allowed - if (rStrResult.isEmpty()) - return IsIgnoreBlank(); - } - else - { + if (!isFormulaResultsValidatable(rTest, rPos, pFormatter, rStrResult, nVal, nFormat, bIsVal)) return false; - } + + // check whether empty cells are allowed + if (rStrResult.isEmpty()) + return IsIgnoreBlank(); } else { @@ -602,69 +547,14 @@ bool ScValidationData::IsDataValid( OUString rStrResult = ""; bool bIsVal = false; - if (rTest[0] == '=') // formulas do not pass the validity test + if (rTest[0] == '=') { - std::optional<ScSimpleFormulaCalculator> pFCell(std::in_place, *mpDoc, rPos, rTest, true); - pFCell->SetLimitString(true); - - bool bColRowName = pFCell->HasColRowName(); - if (bColRowName) - { - // ColRowName from RPN-Code? - if (pFCell->GetCode()->GetCodeLen() <= 1) - { // ==1: area - // ==0: would be an area if... - OUString aBraced = "(" + rTest + ")"; - pFCell.emplace(*mpDoc, rPos, aBraced, true); - pFCell->SetLimitString(true); - } - else - bColRowName = false; - } - - FormulaError nErrCode = pFCell->GetErrCode(); - if (nErrCode == FormulaError::NONE || pFCell->IsMatrix()) - { - pFormatter = mpDoc->GetFormatTable(); - const Color* pColor; - if (pFCell->IsMatrix()) - { - rStrResult = pFCell->GetString().getString(); - } - else if (pFCell->IsValue()) - { - nVal = pFCell->GetValue(); - nFormat = pFormatter->GetStandardFormat(nVal, 0, - pFCell->GetFormatType(), ScGlobal::eLnge); - pFormatter->GetOutputString(nVal, nFormat, rStrResult, &pColor); - bIsVal = true; - } - else - { - nFormat = pFormatter->GetStandardFormat( - pFCell->GetFormatType(), ScGlobal::eLnge); - pFormatter->GetOutputString(pFCell->GetString().getString(), nFormat, - rStrResult, &pColor); - // Indicate it's a string, so a number string doesn't look numeric. - // Escape embedded quotation marks first by doubling them, as - // usual. Actually the result can be copy-pasted from the result - // box as literal into a formula expression. - rStrResult = "\"" + rStrResult.replaceAll("\"", "\"\"") + "\""; - } - - ScRange aTestRange; - if (bColRowName || (aTestRange.Parse(rTest, *mpDoc) & ScRefFlags::VALID)) - rStrResult += " ..."; - // area - - // check whether empty cells are allowed - if (rStrResult.isEmpty()) - return IsIgnoreBlank(); - } - else - { + if (!isFormulaResultsValidatable(rTest, rPos, pFormatter, rStrResult, nVal, nFormat, bIsVal)) return false; - } + + // check whether empty cells are allowed + if (rStrResult.isEmpty()) + return IsIgnoreBlank(); } else { @@ -779,6 +669,70 @@ bool ScValidationData::IsDataValid( ScRefCellValue& rCell, const ScAddress& rPos return bOk; } +bool ScValidationData::isFormulaResultsValidatable(const OUString& rTest, const ScAddress& rPos, SvNumberFormatter* pFormatter, + OUString& rStrResult, double& nVal, sal_uInt32& nFormat, bool& bIsVal) const +{ + std::optional<ScSimpleFormulaCalculator> pFCell(std::in_place, *mpDoc, rPos, rTest, true); + pFCell->SetLimitString(true); + + bool bColRowName = pFCell->HasColRowName(); + if (bColRowName) + { + // ColRowName from RPN-Code? + if (pFCell->GetCode()->GetCodeLen() <= 1) + { // ==1: area + // ==0: would be an area if... + OUString aBraced = "(" + rTest + ")"; + pFCell.emplace(*mpDoc, rPos, aBraced, true); + pFCell->SetLimitString(true); + } + else + bColRowName = false; + } + + FormulaError nErrCode = pFCell->GetErrCode(); + if (nErrCode == FormulaError::NONE || pFCell->IsMatrix()) + { + pFormatter = mpDoc->GetFormatTable(); + const Color* pColor; + if (pFCell->IsMatrix()) + { + rStrResult = pFCell->GetString().getString(); + } + else if (pFCell->IsValue()) + { + nVal = pFCell->GetValue(); + nFormat = pFormatter->GetStandardFormat(nVal, 0, + pFCell->GetFormatType(), ScGlobal::eLnge); + pFormatter->GetOutputString(nVal, nFormat, rStrResult, &pColor); + bIsVal = true; + } + else + { + nFormat = pFormatter->GetStandardFormat( + pFCell->GetFormatType(), ScGlobal::eLnge); + pFormatter->GetOutputString(pFCell->GetString().getString(), nFormat, + rStrResult, &pColor); + // Indicate it's a string, so a number string doesn't look numeric. + // Escape embedded quotation marks first by doubling them, as + // usual. Actually the result can be copy-pasted from the result + // box as literal into a formula expression. + rStrResult = "\"" + rStrResult.replaceAll("\"", "\"\"") + "\""; + } + + ScRange aTestRange; + if (bColRowName || (aTestRange.Parse(rTest, *mpDoc) & ScRefFlags::VALID)) + rStrResult += " ..."; + // area + + return true; + } + else + { + return false; + } +} + namespace { /** Token array helper. Iterates over all string tokens. |