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>
This commit is contained in:
Balazs Varga
2023-02-05 10:31:26 +00:00
parent 90a043f258
commit d8ae6d1388
2 changed files with 79 additions and 121 deletions
+4
View File
@@ -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;
+75 -121
View File
@@ -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.