tdf#123354 DOCX import: fix ABS formula

Convert ABS(x) to the equivalent, but
working Writer formula SQRT(x POW 2).

Note: this is a temporary conversion, which
supports only 1-level nesting of function calls.

Change-Id: I96ad01dc5ac26160792e6a4cb050e103c2ad7bca
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/100898
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
This commit is contained in:
László Németh
2020-08-18 10:54:57 +02:00
parent 3a7a06067e
commit e1aea22f3f
3 changed files with 31 additions and 4 deletions

Binary file not shown.

View File

@@ -16,6 +16,8 @@
#include <com/sun/star/text/XTextColumns.hpp>
#include <com/sun/star/text/XTextTable.hpp>
#include <com/sun/star/text/XTextTablesSupplier.hpp>
#include <com/sun/star/text/XTextFieldsSupplier.hpp>
#include <com/sun/star/text/XTextField.hpp>
char const DATA_DIRECTORY[] = "/sw/qa/extras/ooxmlexport/data/";
@@ -69,6 +71,26 @@ DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf118701, "tdf118701.docx")
assertXPath(pXmlDoc, "/w:document/w:body/w:p[10]/w:pPr[1]/w:numPr", 1);
}
DECLARE_OOXMLEXPORT_TEST(testTdf123354, "tdf123354.docx")
{
// Tests cell formula ABS(x) to SQRT(x POW 2) conversion
uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
uno::Reference<container::XEnumerationAccess> xFieldsAccess(xTextFieldsSupplier->getTextFields());
uno::Reference<container::XEnumeration> xFields(xFieldsAccess->createEnumeration());
uno::Reference<text::XTextField> xEnumerationAccess1(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(OUString("SQRT((-234) POW 2)"), xEnumerationAccess1->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(OUString("234"), xEnumerationAccess1->getPresentation(false).trim());
uno::Reference<text::XTextField> xEnumerationAccess2(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(OUString("SQRT((SUM(<A1:B1>)-SUM(<A2>)*2) POW 2)"), xEnumerationAccess2->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(OUString("700035"), xEnumerationAccess2->getPresentation(false).trim());
uno::Reference<text::XTextField> xEnumerationAccess3(xFields->nextElement(), uno::UNO_QUERY);
CPPUNIT_ASSERT_EQUAL(OUString("SQRT((<A1>) POW 2)"), xEnumerationAccess3->getPresentation(true).trim());
CPPUNIT_ASSERT_EQUAL(OUString("233423"), xEnumerationAccess3->getPresentation(false).trim());
}
DECLARE_OOXMLEXPORT_TEST(testTdf98000_changePageStyle, "tdf98000_changePageStyle.odt")
{
uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);

View File

@@ -4259,9 +4259,13 @@ OUString DomainMapper_Impl::convertFieldFormula(const OUString& input) {
usInput = rmatch4.replaceAll(icu::UnicodeString("<$1:$2>"), status);
/* Fix up user defined names */
icu::RegexMatcher rmatch5("DEFINED\\s*\\(<([A-Z]+[0-9]+)>\\)", usInput, rMatcherFlags, status);
icu::RegexMatcher rmatch5("\\bDEFINED\\s*\\(<([A-Z]+[0-9]+)>\\)", usInput, rMatcherFlags, status);
usInput = rmatch5.replaceAll(icu::UnicodeString("DEFINED($1)"), status);
/* Fix up ABS(x) using SQRT(x POW 2) - it supports only 1-level nesting */
icu::RegexMatcher rmatch6("\\bABS\\s*(\\(([^()]*|([^()])*\\([^()]*\\)[^()]*)*\\))", usInput, rMatcherFlags, status);
usInput = rmatch6.replaceAll(icu::UnicodeString("SQRT($1 POW 2)"), status);
return OUString(usInput.getTerminatedBuffer());
}
@@ -4286,6 +4290,10 @@ void DomainMapper_Impl::handleFieldFormula
// we don't copy the = symbol from the command
OUString formula = convertFieldFormula(command.copy(1));
xFieldProperties->setPropertyValue(getPropertyName(PROP_CONTENT), uno::makeAny(formula));
xFieldProperties->setPropertyValue(getPropertyName(PROP_NUMBER_FORMAT), uno::makeAny(sal_Int32(0)));
xFieldProperties->setPropertyValue("IsShowFormula", uno::makeAny(false));
// grab-bag the original and converted formula
if (getTableManager().isInTable())
{
@@ -4294,9 +4302,6 @@ void DomainMapper_Impl::handleFieldFormula
pPropMap->Insert(PROP_CELL_FORMULA_CONVERTED, uno::makeAny(formula), true, CELL_GRAB_BAG);
getTableManager().cellProps(pPropMap);
}
xFieldProperties->setPropertyValue(getPropertyName(PROP_CONTENT), uno::makeAny(formula));
xFieldProperties->setPropertyValue(getPropertyName(PROP_NUMBER_FORMAT), uno::makeAny(sal_Int32(0)));
xFieldProperties->setPropertyValue("IsShowFormula", uno::makeAny(false));
}
void DomainMapper_Impl::handleRubyEQField( const FieldContextPtr& pContext)