From c377e211785c799a56cd72a9ecba9611d5993311 Mon Sep 17 00:00:00 2001 From: Regina Henschel Date: Thu, 24 Oct 2024 22:12:25 +0200 Subject: [PATCH] tdf#162177 Adapt function EASTERSUNDAY to ODF 1.4 This includes writing ORG.OPENOFFICE.EASTERSUNDAY for ODF 1.3 and ODF 1.2. Change-Id: Ifa19021060f0d0223234c1ca1109300908e2dda1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175736 Tested-by: Jenkins Reviewed-by: Mike Kaganski Reviewed-by: Regina Henschel --- formula/inc/core_resource.hrc | 2 +- formula/source/core/api/FormulaCompiler.cxx | 10 + include/formula/FormulaCompiler.hxx | 5 + sc/inc/tokenstringcontext.hxx | 11 + .../data/fods/tdf162177_Eastersunday.fods | 303 ++++++++++++++++++ sc/qa/unit/subsequent_filters_test5.cxx | 27 ++ sc/source/core/tool/compiler.cxx | 3 +- sc/source/filter/xml/xmlexprt.cxx | 2 +- 8 files changed, 360 insertions(+), 3 deletions(-) create mode 100644 sc/qa/unit/data/fods/tdf162177_Eastersunday.fods diff --git a/formula/inc/core_resource.hrc b/formula/inc/core_resource.hrc index 45e0aa62507d..72acc083c14a 100644 --- a/formula/inc/core_resource.hrc +++ b/formula/inc/core_resource.hrc @@ -428,7 +428,7 @@ const std::pair RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF[] = { "WEEKNUM" , SC_OPCODE_WEEK }, { "ISOWEEKNUM" , SC_OPCODE_ISOWEEKNUM }, { "ORG.LIBREOFFICE.WEEKNUM_OOO" , SC_OPCODE_WEEKNUM_OOO }, - { "ORG.OPENOFFICE.EASTERSUNDAY" , SC_OPCODE_EASTERSUNDAY }, + { "EASTERSUNDAY" , SC_OPCODE_EASTERSUNDAY }, { "WEEKDAY" , SC_OPCODE_GET_DAY_OF_WEEK }, { "NETWORKDAYS" , SC_OPCODE_NETWORKDAYS }, { "COM.MICROSOFT.NETWORKDAYS.INTL" , SC_OPCODE_NETWORKDAYS_MS }, diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx index 2d192e0bd5f2..e67911f5e573 100644 --- a/formula/source/core/api/FormulaCompiler.cxx +++ b/formula/source/core/api/FormulaCompiler.cxx @@ -2609,6 +2609,16 @@ const FormulaToken* FormulaCompiler::CreateStringFromToken( OUStringBuffer& rBuf else rBuffer.append( mxSymbols->getSymbol( eOp)); } + else if ( eOp == ocEasterSunday) + { + // EASTERSUNDAY belongs to ODFF since ODF 1.4 + if (m_oODFSavingVersion.has_value() + && m_oODFSavingVersion.value() >= SvtSaveOptions::ODFSVER_012 + && m_oODFSavingVersion.value() < SvtSaveOptions::ODFSVER_014) + rBuffer.append(u"ORG.OPENOFFICE." + mxSymbols->getSymbol(eOp)); + else + rBuffer.append(mxSymbols->getSymbol(eOp)); + } else if( static_cast(eOp) < mxSymbols->getSymbolCount()) // Keyword: rBuffer.append( mxSymbols->getSymbol( eOp)); else diff --git a/include/formula/FormulaCompiler.hxx b/include/formula/FormulaCompiler.hxx index 7e4477b53d6d..793a87245cf0 100644 --- a/include/formula/FormulaCompiler.hxx +++ b/include/formula/FormulaCompiler.hxx @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -35,6 +36,7 @@ #include #include #include +#include #define FORMULA_MAXJUMPCOUNT 32 /* maximum number of jumps (ocChoose) */ #define FORMULA_MAXTOKENS 8192 /* maximum number of tokens in formula */ @@ -431,6 +433,9 @@ protected: std::unordered_set aNameSet; } m_aLambda; + // ODF version at time of saving. Set by ScXMLExport::WriteCell(). + std::optional< SvtSaveOptions::ODFSaneDefaultVersion > m_oODFSavingVersion; + public: enum InitSymbols { diff --git a/sc/inc/tokenstringcontext.hxx b/sc/inc/tokenstringcontext.hxx index d6292e5dcbb5..7421120dd2a6 100644 --- a/sc/inc/tokenstringcontext.hxx +++ b/sc/inc/tokenstringcontext.hxx @@ -50,6 +50,8 @@ class SC_DLLPUBLIC CompileFormulaContext ScDocument& mrDoc; formula::FormulaGrammar::Grammar meGram; std::vector maTabNames; + // Used in FormulaCompiler::CreateStringFromToken(), set by ScXMLExport::WriteCell() + std::optional m_oODFSavingVersion; void updateTabNames(); @@ -60,6 +62,15 @@ public: formula::FormulaGrammar::Grammar getGrammar() const { return meGram; } void setGrammar(formula::FormulaGrammar::Grammar eGram); + void setODFSavingVersion(SvtSaveOptions::ODFSaneDefaultVersion eDefaultVersion) + { + m_oODFSavingVersion = eDefaultVersion; + } + std::optional getODFSavingVersion() + { + return m_oODFSavingVersion; + } + const std::vector& getTabNames() const { return maTabNames; } ScDocument& getDoc() { return mrDoc; } diff --git a/sc/qa/unit/data/fods/tdf162177_Eastersunday.fods b/sc/qa/unit/data/fods/tdf162177_Eastersunday.fods new file mode 100644 index 000000000000..ed4a1bf6fe75 --- /dev/null +++ b/sc/qa/unit/data/fods/tdf162177_Eastersunday.fods @@ -0,0 +1,303 @@ + + + + Regina Henschel2024-10-29T11:43:18.6490000002024-10-29T11:45:07.934000000Regina HenschelPT1M49S1LibreOffice_7.6.7/7.6.7.2$Windows_X86_64 LibreOffice_project/dd47e4b30cb7dab30588d6c79c651f218165e3c5 + + + 0 + 0 + 2258 + 452 + + + view1 + + + 0 + 0 + 2 + 0 + 0 + 0 + 0 + 0 + 100 + 60 + true + false + false + false + false + + + Sheet1 + 1253 + 0 + 100 + 60 + false + true + true + false + true + 12632256 + true + 1 + true + true + false + false + false + 1000 + 1000 + 1 + 1 + true + false + false + false + false + + + + + true + true + true + 0 + true + true + false + true + false + 12632256 + true + true + 0 + false + false + true + true + false + 3 + false + + false + + false + 1000 + 1000 + 1 + 1 + true + false + false + true + true + true + true + 2 + true + + + Sheet1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + . + + . + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ??? + + + + + Page 1 + + + + + + + + ???(???) + + + 00.00.0000, 00:00:00 + + + + + + Page 1/ 99 + + + + + + + + + + + + + + + 31.03.24 + + + + + + + \ No newline at end of file diff --git a/sc/qa/unit/subsequent_filters_test5.cxx b/sc/qa/unit/subsequent_filters_test5.cxx index a4ff94307c6b..a49945bb1032 100644 --- a/sc/qa/unit/subsequent_filters_test5.cxx +++ b/sc/qa/unit/subsequent_filters_test5.cxx @@ -108,6 +108,33 @@ CPPUNIT_TEST_FIXTURE(ScFiltersTest5, testTdf162963_ODF) 0); } +CPPUNIT_TEST_FIXTURE(ScFiltersTest5, testTdf162177_EastersundayODF14) +{ + // EASTERSUNDAY was added to ODFF in ODF 1.4. LibreOffice has written it as + // ORG.OPENOFFICE.EASTERSUNDAY for ODF 1.2 and ODF 1.3. + Resetter resetter([]() { SetODFDefaultVersion(SvtSaveOptions::ODFVER_LATEST); }); + createScDoc("fods/tdf162177_Eastersunday.fods"); + + // File has it as ORG.OPENOFFICE.EASTERSUNDAY in ODF 1.3. Test, that it is read correctly. + ScDocument* pDoc = getScDoc(); + OUString aFormula = pDoc->GetFormula(0, 0, 0); + CPPUNIT_ASSERT_EQUAL(u"=EASTERSUNDAY(2024)"_ustr, aFormula); + + // Verify that saving to ODF1.3 produces ORG.OPENOFFICE.EASTERSUNDAY + SetODFDefaultVersion(SvtSaveOptions::ODFDefaultVersion::ODFVER_013); + save(u"calc8"_ustr); // this saves to .ods not to .fods + xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr); + const OString sPath = "/office:document-content/office:body/office:spreadsheet/table:table/" + "table:table-row/table:table-cell"_ostr; + assertXPath(pXmlDoc, sPath, "formula", u"of:=ORG.OPENOFFICE.EASTERSUNDAY(2024)"); + + // Verify that saving to ODF1.4 produces EASTERSUNDAY + SetODFDefaultVersion(SvtSaveOptions::ODFDefaultVersion::ODFVER_014); + save(u"calc8"_ustr); // this saves to .ods not to .fods + pXmlDoc = parseExport(u"content.xml"_ustr); + assertXPath(pXmlDoc, sPath, "formula", u"of:=EASTERSUNDAY(2024)"); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index b7b6e1e239aa..a80671e0b3a5 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -1883,6 +1883,7 @@ ScCompiler::ScCompiler( sc::CompileFormulaContext& rCxt, const ScAddress& rPos, maTabNames(rCxt.getTabNames()) { SetGrammar(rCxt.getGrammar()); + m_oODFSavingVersion = rCxt.getODFSavingVersion(); } ScCompiler::ScCompiler( ScDocument& rDocument, const ScAddress& rPos, ScTokenArray& rArr, @@ -3000,7 +3001,7 @@ bool ScCompiler::ParseOpCode( const OUString& rName, bool bInArray ) // Renamed old names, still accept them: { "B", ocB }, // B -> BINOM.DIST.RANGE { "TDIST", ocTDist }, // TDIST -> LEGACY.TDIST - { "EASTERSUNDAY", ocEasterSunday }, // EASTERSUNDAY -> ORG.OPENOFFICE.EASTERSUNDAY + { "ORG.OPENOFFICE.EASTERSUNDAY", ocEasterSunday }, // ORG.OPENOFFICE.EASTERSUNDAY -> EASTERSUNDAY { "ZGZ", ocRRI }, // ZGZ -> RRI { "COLOR", ocColor }, // COLOR -> ORG.LIBREOFFICE.COLOR { "GOALSEEK", ocBackSolver }, // GOALSEEK -> ORG.OPENOFFICE.GOALSEEK diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index 21ba6a6aed0c..c30254a9c703 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -3214,7 +3214,7 @@ void ScXMLExport::WriteCell(ScMyCell& aCell, sal_Int32 nEqualCellCount) const formula::FormulaGrammar::Grammar eGrammar = pDoc->GetStorageGrammar(); mpCompileFormulaCxt.reset(new sc::CompileFormulaContext(*pDoc, eGrammar)); } - + mpCompileFormulaCxt->setODFSavingVersion(getSaneDefaultVersion()); OUString aFormula = pFormulaCell->GetFormula(*mpCompileFormulaCxt); sal_uInt16 nNamespacePrefix = (mpCompileFormulaCxt->getGrammar() == formula::FormulaGrammar::GRAM_ODFF ? XML_NAMESPACE_OF : XML_NAMESPACE_OOOC);