summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorBalazs Varga <balazs.varga.extern@allotropia.de>2023-01-31 14:21:31 +0100
committerBalazs Varga <balazs.varga.extern@allotropia.de>2023-02-05 10:31:26 +0000
commitd8ae6d1388f28c405c4de2dfe93dbfe2d8acd470 (patch)
tree3e16db426ad80959334064570195a9918fff984c /sc
parent90a043f2589a70f6e035ba350ff7f673ae677f2e (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.hxx4
-rw-r--r--sc/source/core/data/validat.cxx196
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.