sc/inc/conditio.hxx | 18 ++- sc/qa/unit/data/xlsx/condFormat_cellis.xlsx |binary sc/qa/unit/subsequent_export-test.cxx | 38 +++++++ sc/qa/unit/subsequent_filters-test.cxx | 36 +++++++ sc/source/core/data/conditio.cxx | 39 +++++-- sc/source/core/data/table2.cxx | 6 - sc/source/filter/excel/xecontent.cxx | 9 + sc/source/filter/excel/xeextlst.cxx | 138 ++++++++++++++++++++++++++- sc/source/filter/excel/xestyle.cxx | 21 ++++ sc/source/filter/inc/extlstcontext.hxx | 9 + sc/source/filter/inc/stylesbuffer.hxx | 4 sc/source/filter/inc/stylesfragment.hxx | 3 sc/source/filter/inc/xeextlst.hxx | 12 ++ sc/source/filter/inc/xestyle.hxx | 5 sc/source/filter/oox/condformatbuffer.cxx | 3 sc/source/filter/oox/extlstcontext.cxx | 69 +++++++++++-- sc/source/filter/oox/stylesbuffer.cxx | 35 ++++++ sc/source/filter/oox/stylesfragment.cxx | 13 ++ sc/source/ui/condformat/condformatdlg.cxx | 1 sc/source/ui/condformat/condformathelper.cxx | 1 sc/source/ui/unoobj/condformatuno.cxx | 1 sc/source/ui/unoobj/fmtuno.cxx | 3 22 files changed, 429 insertions(+), 35 deletions(-)
New commits: commit d034fdbb364142e37d0cf2028c426f4052066c68 Author: Gülşah Köse <gulsah.k...@collabora.com> AuthorDate: Mon Mar 25 21:08:22 2019 +0300 Commit: Andras Timar <andras.ti...@collabora.com> CommitDate: Fri May 10 08:23:58 2019 +0200 tdf#122590 Import and export xlsx x14:cfRule element for type = cellis. Reviewed-on: https://gerrit.libreoffice.org/69713 Tested-by: Jenkins Reviewed-by: Andras Timar <andras.ti...@collabora.com> (cherry picked from commit 8c637b47d9de4b3a64c33a9c2ffe7ed220be2467) Change-Id: I3d940269ec25657b64c714400a2828781dd9dd3e Reviewed-on: https://gerrit.libreoffice.org/72002 Reviewed-by: Andras Timar <andras.ti...@collabora.com> Tested-by: Andras Timar <andras.ti...@collabora.com> diff --git a/sc/inc/conditio.hxx b/sc/inc/conditio.hxx index 327b8367dce9..86a066d64913 100644 --- a/sc/inc/conditio.hxx +++ b/sc/inc/conditio.hxx @@ -25,6 +25,7 @@ #include <formula/grammar.hxx> #include "scdllapi.h" #include "rangelst.hxx" +#include "tokenarray.hxx" #include <svl/hint.hxx> #include <svl/listener.hxx> @@ -227,6 +228,7 @@ public: enum class Type { Condition, + ExtCondition, Colorscale, Databar, Iconset, @@ -261,6 +263,9 @@ inline std::basic_ostream<charT, traits> & operator <<(std::basic_ostream<charT, case ScFormatEntry::Type::Condition: stream << "Condition"; break; + case ScFormatEntry::Type::ExtCondition: + stream << "ExtCondition"; + break; case ScFormatEntry::Type::Colorscale: stream << "Colorscale"; break; @@ -318,6 +323,7 @@ class SC_DLLPUBLIC ScConditionEntry : public ScFormatEntry bool bRelRef2; bool bFirstRun; std::unique_ptr<ScFormulaListener> mpListener; + Type eConditionType; //It can be Condition or ExtCondition void SimplifyCompiledFormula( ScTokenArray*& rFormula, double& rVal, @@ -342,7 +348,8 @@ public: ScDocument* pDocument, const ScAddress& rPos, const OUString& rExprNmsp1, const OUString& rExprNmsp2, formula::FormulaGrammar::Grammar eGrammar1, - formula::FormulaGrammar::Grammar eGrammar2 ); + formula::FormulaGrammar::Grammar eGrammar2, + Type eType = Type::Condition ); ScConditionEntry( ScConditionMode eOper, const ScTokenArray* pArr1, const ScTokenArray* pArr2, ScDocument* pDocument, const ScAddress& rPos ); @@ -387,7 +394,7 @@ public: bool MarkUsedExternalReferences() const; - virtual Type GetType() const override { return Type::Condition; } + virtual Type GetType() const override { return eConditionType; } virtual ScFormatEntry* Clone(ScDocument* pDoc) const override; @@ -437,7 +444,8 @@ private: // single condition entry for conditional formatting class SC_DLLPUBLIC ScCondFormatEntry : public ScConditionEntry { - OUString aStyleName; + OUString aStyleName; + Type eCondFormatType = Type::Condition; public: ScCondFormatEntry( ScConditionMode eOper, @@ -447,7 +455,8 @@ public: const OUString& rExprNmsp1 = EMPTY_OUSTRING, const OUString& rExprNmsp2 = EMPTY_OUSTRING, formula::FormulaGrammar::Grammar eGrammar1 = formula::FormulaGrammar::GRAM_DEFAULT, - formula::FormulaGrammar::Grammar eGrammar2 = formula::FormulaGrammar::GRAM_DEFAULT ); + formula::FormulaGrammar::Grammar eGrammar2 = formula::FormulaGrammar::GRAM_DEFAULT, + Type eType = Type::Condition); ScCondFormatEntry( ScConditionMode eOper, const ScTokenArray* pArr1, const ScTokenArray* pArr2, ScDocument* pDocument, const ScAddress& rPos, @@ -461,6 +470,7 @@ public: const OUString& GetStyle() const { return aStyleName; } void UpdateStyleName(const OUString& rNew) { aStyleName=rNew; } virtual ScFormatEntry* Clone(ScDocument* pDoc) const override; + virtual Type GetType() const override { return eCondFormatType; } protected: virtual void DataChanged() const override; diff --git a/sc/qa/unit/data/xlsx/condFormat_cellis.xlsx b/sc/qa/unit/data/xlsx/condFormat_cellis.xlsx new file mode 100644 index 000000000000..6bbd0b5e33f5 Binary files /dev/null and b/sc/qa/unit/data/xlsx/condFormat_cellis.xlsx differ diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index fd3b6c3eaa04..ab51e7575033 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -98,6 +98,7 @@ public: void testPasswordExportODS(); void testConditionalFormatExportODS(); void testConditionalFormatExportXLSX(); + void testCondFormatExportCellIs(); void testTdf99856_dataValidationTest(); void testProtectionKeyODS_UTF16LErtlSHA1(); void testProtectionKeyODS_UTF8SHA1(); @@ -222,6 +223,7 @@ public: CPPUNIT_TEST(testTdf111876); CPPUNIT_TEST(testPasswordExportODS); CPPUNIT_TEST(testConditionalFormatExportODS); + CPPUNIT_TEST(testCondFormatExportCellIs); CPPUNIT_TEST(testConditionalFormatExportXLSX); CPPUNIT_TEST(testTdf99856_dataValidationTest); CPPUNIT_TEST(testProtectionKeyODS_UTF16LErtlSHA1); @@ -485,6 +487,42 @@ void ScExportTest::testConditionalFormatExportODS() xDocSh->DoClose(); } +void ScExportTest::testCondFormatExportCellIs() +{ + ScDocShellRef xShell = loadDoc("condFormat_cellis.", FORMAT_XLSX); + CPPUNIT_ASSERT(xShell.is()); + ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX); + CPPUNIT_ASSERT(xDocSh.is()); + + ScDocument& rDoc = xDocSh->GetDocument(); + CPPUNIT_ASSERT_EQUAL(size_t(1), rDoc.GetCondFormList(0)->size()); + + ScConditionalFormat* pFormat = rDoc.GetCondFormat(0, 0, 0); + CPPUNIT_ASSERT(pFormat); + + const ScFormatEntry* pEntry = pFormat->GetEntry(0); + CPPUNIT_ASSERT(pEntry); + CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType()); + + const ScCondFormatEntry* pCondition = static_cast<const ScCondFormatEntry*>(pEntry); + CPPUNIT_ASSERT_EQUAL( ScConditionMode::Equal, pCondition->GetOperation()); + + OUString aStr = pCondition->GetExpression(ScAddress(0, 0, 0), 0); + CPPUNIT_ASSERT_EQUAL( OUString("$Sheet2.$A$1"), aStr ); + + pEntry = pFormat->GetEntry(1); + CPPUNIT_ASSERT(pEntry); + CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType()); + + pCondition = static_cast<const ScCondFormatEntry*>(pEntry); + CPPUNIT_ASSERT_EQUAL( ScConditionMode::Equal, pCondition->GetOperation()); + + aStr = pCondition->GetExpression(ScAddress(0, 0, 0), 0); + CPPUNIT_ASSERT_EQUAL( OUString("$Sheet2.$A$2"), aStr ); + + xDocSh->DoClose(); +} + void ScExportTest::testConditionalFormatExportXLSX() { ScDocShellRef xShell = loadDoc("new_cond_format_test_export.", FORMAT_XLSX); diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index cc6309e63afb..0900ad06ef03 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -148,6 +148,7 @@ public: void testNewCondFormatODS(); void testNewCondFormatXLSX(); void testCondFormatThemeColorXLSX(); + void testCondFormatImportCellIs(); void testCondFormatThemeColor2XLSX(); // negative bar color and axis color void testCondFormatThemeColor3XLSX(); // theme index 2 and 3 are switched void testComplexIconSetsXLSX(); @@ -291,6 +292,7 @@ public: CPPUNIT_TEST(testNewCondFormatODS); CPPUNIT_TEST(testNewCondFormatXLSX); CPPUNIT_TEST(testCondFormatThemeColorXLSX); + CPPUNIT_TEST(testCondFormatImportCellIs); CPPUNIT_TEST(testCondFormatThemeColor2XLSX); CPPUNIT_TEST(testCondFormatThemeColor3XLSX); CPPUNIT_TEST(testComplexIconSetsXLSX); @@ -2264,6 +2266,40 @@ void ScFiltersTest::testNewCondFormatXLSX() xDocSh->DoClose(); } +void ScFiltersTest::testCondFormatImportCellIs() +{ + ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc("condFormat_cellis.", FORMAT_XLSX); + CPPUNIT_ASSERT_MESSAGE("Failed to load condFormat_cellis.xlsx", xDocSh.is()); + + ScDocument& rDoc = xDocSh->GetDocument(); + CPPUNIT_ASSERT_EQUAL(size_t(1), rDoc.GetCondFormList(0)->size()); + + ScConditionalFormat* pFormat = rDoc.GetCondFormat(0, 0, 0); + CPPUNIT_ASSERT(pFormat); + + const ScFormatEntry* pEntry = pFormat->GetEntry(0); + CPPUNIT_ASSERT(pEntry); + CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType()); + + const ScCondFormatEntry* pCondition = static_cast<const ScCondFormatEntry*>(pEntry); + CPPUNIT_ASSERT_EQUAL( ScConditionMode::Equal, pCondition->GetOperation()); + + OUString aStr = pCondition->GetExpression(ScAddress(0, 0, 0), 0); + CPPUNIT_ASSERT_EQUAL( OUString("$Sheet2.$A$1"), aStr ); + + pEntry = pFormat->GetEntry(1); + CPPUNIT_ASSERT(pEntry); + CPPUNIT_ASSERT_EQUAL(ScFormatEntry::Type::ExtCondition, pEntry->GetType()); + + pCondition = static_cast<const ScCondFormatEntry*>(pEntry); + CPPUNIT_ASSERT_EQUAL( ScConditionMode::Equal, pCondition->GetOperation()); + + aStr = pCondition->GetExpression(ScAddress(0, 0, 0), 0); + CPPUNIT_ASSERT_EQUAL( OUString("$Sheet2.$A$2"), aStr ); + + xDocSh->DoClose(); +} + void ScFiltersTest::testCondFormatThemeColorXLSX() { ScDocShellRef xDocSh = ScBootstrapFixture::loadDoc("condformat_theme_color.", FORMAT_XLSX); diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx index 0ff379f1f0ab..e71c050d1d9a 100644 --- a/sc/source/core/data/conditio.cxx +++ b/sc/source/core/data/conditio.cxx @@ -199,6 +199,7 @@ ScConditionEntry::ScConditionEntry( const ScConditionEntry& r ) : bRelRef2(r.bRelRef2), bFirstRun(true), mpListener(new ScFormulaListener(r.mpDoc)), + eConditionType( r.eConditionType ), pCondFormat(r.pCondFormat) { // ScTokenArray copy ctor creates a flat copy @@ -235,6 +236,7 @@ ScConditionEntry::ScConditionEntry( ScDocument* pDocument, const ScConditionEntr bRelRef2(r.bRelRef2), bFirstRun(true), mpListener(new ScFormulaListener(pDocument)), + eConditionType( r.eConditionType), pCondFormat(r.pCondFormat) { // Real copy of the formulas (for Ref Undo) @@ -250,7 +252,8 @@ ScConditionEntry::ScConditionEntry( ScDocument* pDocument, const ScConditionEntr ScConditionEntry::ScConditionEntry( ScConditionMode eOper, const OUString& rExpr1, const OUString& rExpr2, ScDocument* pDocument, const ScAddress& rPos, const OUString& rExprNmsp1, const OUString& rExprNmsp2, - FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2 ) : + FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2, + Type eType ) : ScFormatEntry(pDocument), eOp(eOper), nOptions(0), @@ -271,6 +274,7 @@ ScConditionEntry::ScConditionEntry( ScConditionMode eOper, bRelRef2(false), bFirstRun(true), mpListener(new ScFormulaListener(pDocument)), + eConditionType(eType), pCondFormat(nullptr) { Compile( rExpr1, rExpr2, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2, false ); @@ -1492,9 +1496,11 @@ ScCondFormatEntry::ScCondFormatEntry( ScConditionMode eOper, const OUString& rStyle, const OUString& rExprNmsp1, const OUString& rExprNmsp2, FormulaGrammar::Grammar eGrammar1, - FormulaGrammar::Grammar eGrammar2 ) : - ScConditionEntry( eOper, rExpr1, rExpr2, pDocument, rPos, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2 ), - aStyleName( rStyle ) + FormulaGrammar::Grammar eGrammar2, + ScFormatEntry::Type eType ) : + ScConditionEntry( eOper, rExpr1, rExpr2, pDocument, rPos, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2, eType ), + aStyleName( rStyle ), + eCondFormatType( eType ) { } @@ -1509,13 +1515,15 @@ ScCondFormatEntry::ScCondFormatEntry( ScConditionMode eOper, ScCondFormatEntry::ScCondFormatEntry( const ScCondFormatEntry& r ) : ScConditionEntry( r ), - aStyleName( r.aStyleName ) + aStyleName( r.aStyleName ), + eCondFormatType( r.eCondFormatType) { } ScCondFormatEntry::ScCondFormatEntry( ScDocument* pDocument, const ScCondFormatEntry& r ) : ScConditionEntry( pDocument, r ), - aStyleName( r.aStyleName ) + aStyleName( r.aStyleName ), + eCondFormatType( r.eCondFormatType) { } @@ -1803,7 +1811,8 @@ const OUString& ScConditionalFormat::GetCellStyle( ScRefCellValue& rCell, const { for (auto itr = maEntries.cbegin(); itr != maEntries.cend(); ++itr) { - if((*itr)->GetType() == ScFormatEntry::Type::Condition) + if((*itr)->GetType() == ScFormatEntry::Type::Condition || + (*itr)->GetType() == ScFormatEntry::Type::ExtCondition) { const ScCondFormatEntry& rEntry = static_cast<const ScCondFormatEntry&>(**itr); if (rEntry.IsCellValid(rCell, rPos)) @@ -1825,7 +1834,9 @@ ScCondFormatData ScConditionalFormat::GetData( ScRefCellValue& rCell, const ScAd ScCondFormatData aData; for(auto itr = maEntries.cbegin(); itr != maEntries.cend(); ++itr) { - if((*itr)->GetType() == ScFormatEntry::Type::Condition && aData.aStyleName.isEmpty()) + if( ((*itr)->GetType() == ScFormatEntry::Type::Condition || + (*itr)->GetType() == ScFormatEntry::Type::ExtCondition) && + aData.aStyleName.isEmpty()) { const ScCondFormatEntry& rEntry = static_cast<const ScCondFormatEntry&>(**itr); if (rEntry.IsCellValid(rCell, rPos)) @@ -1865,14 +1876,16 @@ void ScConditionalFormat::DoRepaint() void ScConditionalFormat::CompileAll() { for(auto itr = maEntries.cbegin(); itr != maEntries.cend(); ++itr) - if((*itr)->GetType() == ScFormatEntry::Type::Condition) + if((*itr)->GetType() == ScFormatEntry::Type::Condition || + (*itr)->GetType() == ScFormatEntry::Type::ExtCondition) static_cast<ScCondFormatEntry&>(**itr).CompileAll(); } void ScConditionalFormat::CompileXML() { for(auto itr = maEntries.cbegin(); itr != maEntries.cend(); ++itr) - if((*itr)->GetType() == ScFormatEntry::Type::Condition) + if((*itr)->GetType() == ScFormatEntry::Type::Condition || + (*itr)->GetType() == ScFormatEntry::Type::ExtCondition) static_cast<ScCondFormatEntry&>(**itr).CompileXML(); } @@ -1995,7 +2008,8 @@ void ScConditionalFormat::DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCR void ScConditionalFormat::RenameCellStyle(const OUString& rOld, const OUString& rNew) { for(auto itr = maEntries.cbegin(); itr != maEntries.cend(); ++itr) - if((*itr)->GetType() == ScFormatEntry::Type::Condition) + if((*itr)->GetType() == ScFormatEntry::Type::Condition || + (*itr)->GetType() == ScFormatEntry::Type::ExtCondition) { ScCondFormatEntry& rFormat = static_cast<ScCondFormatEntry&>(**itr); if(rFormat.GetStyle() == rOld) @@ -2007,7 +2021,8 @@ bool ScConditionalFormat::MarkUsedExternalReferences() const { bool bAllMarked = false; for(auto itr = maEntries.cbegin(); itr != maEntries.cend() && !bAllMarked; ++itr) - if((*itr)->GetType() == ScFormatEntry::Type::Condition) + if((*itr)->GetType() == ScFormatEntry::Type::Condition || + (*itr)->GetType() == ScFormatEntry::Type::ExtCondition) { const ScCondFormatEntry& rFormat = static_cast<const ScCondFormatEntry&>(**itr); bAllMarked = rFormat.MarkUsedExternalReferences(); diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 715ed11dbc49..632f53d43d99 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -635,7 +635,8 @@ void ScTable::CopyConditionalFormat( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCRO { OUString aStyleName; const ScFormatEntry* pEntry = pNewFormat->GetEntry(i); - if(pEntry->GetType() == ScFormatEntry::Type::Condition) + if(pEntry->GetType() == ScFormatEntry::Type::Condition || + pEntry->GetType() == ScFormatEntry::Type::ExtCondition) aStyleName = static_cast<const ScCondFormatEntry*>(pEntry)->GetStyle(); else if(pEntry->GetType() == ScFormatEntry::Type::Date) aStyleName = static_cast<const ScCondDateFormatEntry*>(pEntry)->GetStyleName(); @@ -2159,7 +2160,8 @@ void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCC for (size_t nEntry=0; nEntry<nEntryCount; nEntry++) { const ScFormatEntry* pEntry = pFormat->GetEntry(nEntry); - if(pEntry->GetType() != ScFormatEntry::Type::Condition) + if(pEntry->GetType() != ScFormatEntry::Type::Condition || + pEntry->GetType() != ScFormatEntry::Type::ExtCondition) continue; OUString aStyleName = static_cast<const ScCondFormatEntry*>(pEntry)->GetStyle(); diff --git a/sc/source/filter/excel/xecontent.cxx b/sc/source/filter/excel/xecontent.cxx index e40a02a64cf3..d99607a1e0c2 100644 --- a/sc/source/filter/excel/xecontent.cxx +++ b/sc/source/filter/excel/xecontent.cxx @@ -1221,6 +1221,15 @@ XclExpCondfmt::XclExpCondfmt( const XclExpRoot& rRoot, const ScConditionalFormat { if(pFormatEntry->GetType() == ScFormatEntry::Type::Condition) maCFList.AppendNewRecord( new XclExpCF( GetRoot(), static_cast<const ScCondFormatEntry&>(*pFormatEntry), ++rIndex ) ); + else if(pFormatEntry->GetType() == ScFormatEntry::Type::ExtCondition) + { + const ScCondFormatEntry& rFormat = static_cast<const ScCondFormatEntry&>(*pFormatEntry); + XclExpExtCondFormatData aExtEntry; + aExtEntry.nPriority = ++rIndex; + aExtEntry.aGUID = generateGUIDString(); + aExtEntry.pEntry = &rFormat; + aExtEntries.push_back(aExtEntry); + } else if(pFormatEntry->GetType() == ScFormatEntry::Type::Colorscale) maCFList.AppendNewRecord( new XclExpColorScale( GetRoot(), static_cast<const ScColorScaleFormat&>(*pFormatEntry), ++rIndex ) ); else if(pFormatEntry->GetType() == ScFormatEntry::Type::Databar) diff --git a/sc/source/filter/excel/xeextlst.cxx b/sc/source/filter/excel/xeextlst.cxx index 31814141ef89..a338639a4801 100644 --- a/sc/source/filter/excel/xeextlst.cxx +++ b/sc/source/filter/excel/xeextlst.cxx @@ -10,13 +10,20 @@ #include <xeextlst.hxx> #include <xeroot.hxx> #include <xehelper.hxx> +#include <stlsheet.hxx> +#include <ftools.hxx> #include <xestyle.hxx> +#include <stlpool.hxx> +#include <scitems.hxx> +#include <svl/itemset.hxx> +#include <svl/intitem.hxx> #include <xename.hxx> #include <xecontent.hxx> #include <tokenarray.hxx> #include <oox/export/utils.hxx> #include <oox/token/namespaces.hxx> +#include <comphelper/processfactory.hxx> using namespace ::oox; @@ -145,6 +152,65 @@ void XclExpExtCfvo::SaveXml( XclExpXmlStream& rStrm ) rWorksheet->endElementNS(XML_x14, XML_cfvo); } +XclExpExtCF::XclExpExtCF( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormat ): + XclExpRoot(rRoot), + mrFormat(rFormat) +{ +} + +void XclExpExtCF::SaveXml( XclExpXmlStream& rStrm ) +{ + OUString aStyleName = mrFormat.GetStyle(); + SfxStyleSheetBase* pStyle = GetDoc().GetStyleSheetPool()->Find(aStyleName); + SfxItemSet& rSet = pStyle->GetItemSet(); + + std::unique_ptr<ScTokenArray> pTokenArray(mrFormat.CreateFlatCopiedTokenArray(0)); + aFormula = XclXmlUtils::ToOUString( GetCompileFormulaContext(), mrFormat.GetValidSrcPos(), pTokenArray.get()); + + std::unique_ptr<XclExpColor> pColor(new XclExpColor); + if(!pColor->FillFromItemSet( rSet )) + pColor.reset(); + + std::unique_ptr<XclExpCellBorder> pBorder(new XclExpCellBorder); + if (!pBorder->FillFromItemSet( rSet, GetPalette(), GetBiff()) ) + pBorder.reset(); + + std::unique_ptr<XclExpCellAlign> pAlign(new XclExpCellAlign); + if (!pAlign->FillFromItemSet( rSet, false, GetBiff())) + pAlign.reset(); + + std::unique_ptr<XclExpCellProt> pCellProt(new XclExpCellProt); + if (!pCellProt->FillFromItemSet( rSet )) + pCellProt.reset(); + + std::unique_ptr<XclExpDxfFont> pFont(new XclExpDxfFont(GetRoot(), rSet)); + + std::unique_ptr<XclExpNumFmt> pNumFormat; + const SfxPoolItem *pPoolItem = nullptr; + if( rSet.GetItemState( ATTR_VALUE_FORMAT, true, &pPoolItem ) == SfxItemState::SET ) + { + sal_uInt32 nScNumFmt = static_cast< const SfxUInt32Item* >(pPoolItem)->GetValue(); + XclExpNumFmtBuffer& rNumFmtBuffer = GetRoot().GetNumFmtBuffer(); + sal_uInt32 nXclNumFmt = rNumFmtBuffer.Insert(nScNumFmt); + pNumFormat.reset(new XclExpNumFmt(nScNumFmt, nXclNumFmt, rNumFmtBuffer.GetFormatCode(nScNumFmt))); + } + + XclExpDxf rDxf( GetRoot(), + pAlign.release(), + pBorder.release(), + pFont.release(), + pNumFormat.release(), + pCellProt.release(), + pColor.release() ); + + sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream(); + + rWorksheet->startElementNS( XML_xm, XML_f, FSEND ); + rWorksheet->writeEscaped( aFormula ); + rWorksheet->endElementNS( XML_xm, XML_f ); + rDxf.SaveXmlExt( rStrm ); +} + XclExpExtDataBar::XclExpExtDataBar( const XclExpRoot& rRoot, const ScDataBarFormat& rFormat, const ScAddress& rPos ): XclExpRoot(rRoot) { @@ -179,6 +245,62 @@ const char* getAxisPosition(databar::ScAxisPosition eAxisPosition) return ""; } +const char* GetOperatorString(ScConditionMode eMode) +{ + const char* pRet = nullptr; + switch(eMode) + { + case ScConditionMode::Equal: + pRet = "equal"; + break; + case ScConditionMode::Less: + pRet = "lessThan"; + break; + case ScConditionMode::Greater: + pRet = "greaterThan"; + break; + case ScConditionMode::EqLess: + pRet = "lessThanOrEqual"; + break; + case ScConditionMode::EqGreater: + pRet = "greaterThanOrEqual"; + break; + case ScConditionMode::NotEqual: + pRet = "notEqual"; + break; + case ScConditionMode::Between: + pRet = "between"; + break; + case ScConditionMode::NotBetween: + pRet = "notBetween"; + break; + case ScConditionMode::Duplicate: + pRet = nullptr; + break; + case ScConditionMode::NotDuplicate: + pRet = nullptr; + break; + case ScConditionMode::BeginsWith: + pRet = "beginsWith"; + break; + case ScConditionMode::EndsWith: + pRet = "endsWith"; + break; + case ScConditionMode::ContainsText: + pRet = "containsText"; + break; + case ScConditionMode::NotContainsText: + pRet = "notContains"; + break; + case ScConditionMode::Direct: + break; + case ScConditionMode::NONE: + default: + break; + } + return pRet; +} + } void XclExpExtDataBar::SaveXml( XclExpXmlStream& rStrm ) @@ -246,7 +368,8 @@ XclExpExtCfRule::XclExpExtCfRule( const XclExpRoot& rRoot, const ScFormatEntry& XclExpRoot(rRoot), maId(rId), pType(nullptr), - mnPriority(nPriority) + mnPriority(nPriority), + mOperator(nullptr) { switch (rFormat.GetType()) { @@ -264,6 +387,14 @@ XclExpExtCfRule::XclExpExtCfRule( const XclExpRoot& rRoot, const ScFormatEntry& pType = "iconSet"; } break; + case ScFormatEntry::Type::ExtCondition: + { + const ScCondFormatEntry& rCondFormat = static_cast<const ScCondFormatEntry&>(rFormat); + mxEntry.reset(new XclExpExtCF(*this, rCondFormat)); + pType = "cellIs"; + mOperator = GetOperatorString( rCondFormat.GetOperation() ); + } + break; default: break; } @@ -278,6 +409,7 @@ void XclExpExtCfRule::SaveXml( XclExpXmlStream& rStrm ) rWorksheet->startElementNS( XML_x14, XML_cfRule, XML_type, pType, XML_priority, mnPriority == -1 ? nullptr : OString::number(mnPriority).getStr(), + XML_operator, mOperator, XML_id, maId.getStr(), FSEND ); @@ -327,6 +459,9 @@ XclExpExtConditionalFormatting::XclExpExtConditionalFormatting( const XclExpRoot case ScFormatEntry::Type::Databar: maCfRules.AppendNewRecord(new XclExpExtCfRule( *this, *pEntry, aAddr, itr->aGUID, itr->nPriority)); break; + case ScFormatEntry::Type::ExtCondition: + maCfRules.AppendNewRecord(new XclExpExtCfRule( *this, *pEntry, aAddr, itr->aGUID, itr->nPriority)); + break; default: break; } @@ -453,4 +588,5 @@ XclExpExtRef XclExtLst::GetItem( XclExpExtType eType ) return XclExpExtRef(); } + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/filter/excel/xestyle.cxx b/sc/source/filter/excel/xestyle.cxx index 8d882ed5a061..91b08673f936 100644 --- a/sc/source/filter/excel/xestyle.cxx +++ b/sc/source/filter/excel/xestyle.cxx @@ -3133,6 +3133,27 @@ void XclExpDxf::SaveXml( XclExpXmlStream& rStrm ) rStyleSheet->endElement( XML_dxf ); } +void XclExpDxf::SaveXmlExt( XclExpXmlStream& rStrm ) +{ + sax_fastparser::FSHelperPtr& rStyleSheet = rStrm.GetCurrentStream(); + rStyleSheet->startElementNS( XML_x14, XML_dxf, FSEND ); + + if (mpFont) + mpFont->SaveXml(rStrm); + if (mpNumberFmt) + mpNumberFmt->SaveXml(rStrm); + if (mpColor) + mpColor->SaveXml(rStrm); + if (mpAlign) + mpAlign->SaveXml(rStrm); + if (mpBorder) + mpBorder->SaveXml(rStrm); + if (mpProt) + mpProt->SaveXml(rStrm); + rStyleSheet->endElementNS( XML_x14, XML_dxf );; +} + + XclExpXmlStyleSheet::XclExpXmlStyleSheet( const XclExpRoot& rRoot ) : XclExpRoot( rRoot ) { diff --git a/sc/source/filter/inc/extlstcontext.hxx b/sc/source/filter/inc/extlstcontext.hxx index fc2e6af035a0..6785b3d6690a 100644 --- a/sc/source/filter/inc/extlstcontext.hxx +++ b/sc/source/filter/inc/extlstcontext.hxx @@ -13,10 +13,13 @@ #include "excelhandlers.hxx" #include "worksheetfragment.hxx" #include "workbookfragment.hxx" +#include "conditio.hxx" #include <vector> #include <memory> +extern sal_Int32 rStyleIdx; // Holds index of the <extlst> <cfRule> style (Will be reseted finalize import) + struct ScDataBarFormatData; class ScFormatEntry; @@ -50,8 +53,12 @@ public: virtual void onEndElement() override; private: - OUString aChars; + OUString aChars; // Characters of between xml elements. + OUString rStyle; // Style of the corresponding condition + ScConditionMode eOperator; // Used only when cfRule type is "cellIs" + bool isPreviousElementF; // Used to distinguish alone <sqref> from <f> and <sqref> std::vector<std::unique_ptr<ScFormatEntry> > maEntries; + std::vector< OUString > rFormulas; // It holds formulas for a range, there can be more formula for same range. IconSetRule* mpCurrentRule; }; diff --git a/sc/source/filter/inc/stylesbuffer.hxx b/sc/source/filter/inc/stylesbuffer.hxx index 66319f8b981d..81dc809ed5a8 100644 --- a/sc/source/filter/inc/stylesbuffer.hxx +++ b/sc/source/filter/inc/stylesbuffer.hxx @@ -802,6 +802,7 @@ public: XfRef createStyleXf(); /** Creates a new empty differential formatting object. */ DxfRef createDxf(); + DxfRef createExtDxf(); /** Appends a new color to the color palette. */ void importPaletteColor( const AttributeList& rAttribs ); @@ -850,6 +851,7 @@ public: ::ScStyleSheet* getCellStyleSheet( sal_Int32 nXfId ) const; /** Creates the style sheet described by the DXF with the passed identifier. */ OUString createDxfStyle( sal_Int32 nDxfId ) const; + OUString createExtDxfStyle( sal_Int32 nDxfId ) const; void writeFontToItemSet( SfxItemSet& rItemSet, sal_Int32 nFontId, bool bSkipPoolDefs ) const; sal_uInt32 writeNumFmtToItemSet( SfxItemSet& rItemSet, sal_uInt32 nNumFmtId, bool bSkipPoolDefs ) const; @@ -860,6 +862,7 @@ public: /** Writes the cell formatting attributes of the specified XF to the passed property set. */ void writeCellXfToDoc( ScDocumentImport& rDoc, const ScRange& rRange, sal_Int32 nXfId ) const; + RefVector< Dxf > getExtDxfs() { return maExtDxfs; } private: typedef RefVector< Font > FontVector; @@ -878,6 +881,7 @@ private: XfVector maStyleXfs; /// List of cell styles. CellStyleBuffer maCellStyles; /// All built-in and user defined cell styles. DxfVector maDxfs; /// List of differential cell styles. + DxfVector maExtDxfs; /// List of differential extlst cell styles. mutable DxfStyleMap maDxfStyles; /// Maps DXF identifiers to Calc style sheet names. }; diff --git a/sc/source/filter/inc/stylesfragment.hxx b/sc/source/filter/inc/stylesfragment.hxx index a5fbc55bc6bf..c6e19dd3f723 100644 --- a/sc/source/filter/inc/stylesfragment.hxx +++ b/sc/source/filter/inc/stylesfragment.hxx @@ -101,13 +101,14 @@ class DxfContext : public WorkbookContextBase public: template< typename ParentType > explicit DxfContext( ParentType& rParent, const DxfRef& rxDxf ) : - WorkbookContextBase( rParent ), mxDxf( rxDxf ) {} + WorkbookContextBase( rParent ), mxDxf( rxDxf ), mxExtDxf( rxDxf ) {} protected: virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ) override; private: DxfRef mxDxf; + DxfRef mxExtDxf; }; class StylesFragment : public WorkbookFragmentBase diff --git a/sc/source/filter/inc/xeextlst.hxx b/sc/source/filter/inc/xeextlst.hxx index bde914c87d07..e3cd8e676bf3 100644 --- a/sc/source/filter/inc/xeextlst.hxx +++ b/sc/source/filter/inc/xeextlst.hxx @@ -88,6 +88,17 @@ private: sal_Int32 nIndex; }; +class XclExpExtCF : public XclExpRecordBase, protected XclExpRoot +{ +public: + explicit XclExpExtCF( const XclExpRoot& rRoot, const ScCondFormatEntry& rFormat ); + virtual void SaveXml( XclExpXmlStream& rStrm ) override; + +private: + OUString aFormula; + const ScCondFormatEntry mrFormat; +}; + class XclExpExtDataBar : public XclExpRecordBase, protected XclExpRoot { public: @@ -134,6 +145,7 @@ private: OString maId; const char* pType; sal_Int32 mnPriority; + const char* mOperator; }; typedef std::shared_ptr<XclExpExt> XclExpExtRef; diff --git a/sc/source/filter/inc/xestyle.hxx b/sc/source/filter/inc/xestyle.hxx index dc12247b418f..3d1af30096f8 100644 --- a/sc/source/filter/inc/xestyle.hxx +++ b/sc/source/filter/inc/xestyle.hxx @@ -289,14 +289,14 @@ public: virtual void Save( XclExpStream& rStrm ) override; virtual void SaveXml( XclExpXmlStream& rStrm ) override; + OUString GetFormatCode ( sal_uInt32 nScNumFmt ); + private: /** Writes the FORMAT record with index nXclIx and format string rFormatStr. */ void WriteFormatRecord( XclExpStream& rStrm, sal_uInt16 nXclNumFmt, const OUString& rFormatStr ); /** Writes the FORMAT record represented by rFormat. */ void WriteFormatRecord( XclExpStream& rStrm, const XclExpNumFmt& rFormat ); - OUString GetFormatCode ( sal_uInt32 nScNumFmt ); - private: typedef ::std::vector< XclExpNumFmt > XclExpNumFmtVec; @@ -704,6 +704,7 @@ public: virtual ~XclExpDxf() override; virtual void SaveXml( XclExpXmlStream& rStrm ) override; + virtual void SaveXmlExt( XclExpXmlStream& rStrm); private: std::unique_ptr<XclExpCellAlign> mpAlign; diff --git a/sc/source/filter/oox/condformatbuffer.cxx b/sc/source/filter/oox/condformatbuffer.cxx index 55a57a4c710b..750bb19ee793 100644 --- a/sc/source/filter/oox/condformatbuffer.cxx +++ b/sc/source/filter/oox/condformatbuffer.cxx @@ -42,6 +42,7 @@ #include <docfunc.hxx> #include <tokenarray.hxx> #include <tokenuno.hxx> +#include <extlstcontext.hxx> namespace oox { namespace xls { @@ -1146,6 +1147,8 @@ void CondFormatBuffer::finalizeImport() pFormat->AddEntry((*i)->Clone(pDoc)); } } + + rStyleIdx = 0; // Resets <extlst> <cfRule> style index. } CondFormatRef CondFormatBuffer::importCondFormatting( SequenceInputStream& rStrm ) diff --git a/sc/source/filter/oox/extlstcontext.cxx b/sc/source/filter/oox/extlstcontext.cxx index 3f29d5256688..e180d95928ba 100644 --- a/sc/source/filter/oox/extlstcontext.cxx +++ b/sc/source/filter/oox/extlstcontext.cxx @@ -18,11 +18,16 @@ #include <condformatbuffer.hxx> #include <condformatcontext.hxx> #include <document.hxx> +#include <stylesbuffer.hxx> +#include <stylesfragment.hxx> #include <rangeutl.hxx> #include <o3tl/make_unique.hxx> using ::oox::core::ContextHandlerRef; +using ::oox::xls::CondFormatBuffer; + +sal_Int32 rStyleIdx = 0; namespace oox { namespace xls { @@ -78,6 +83,7 @@ ExtConditionalFormattingContext::ExtConditionalFormattingContext(WorksheetContex WorksheetContextBase(rFragment), mpCurrentRule(nullptr) { + isPreviousElementF = false; } ContextHandlerRef ExtConditionalFormattingContext::onCreateContext(sal_Int32 nElement, const AttributeList& rAttribs) @@ -98,6 +104,7 @@ ContextHandlerRef ExtConditionalFormattingContext::onCreateContext(sal_Int32 nEl { OUString aType = rAttribs.getString(XML_type, OUString()); OUString aId = rAttribs.getString(XML_id, OUString()); + if (aType == "dataBar") { // an ext entry does not need to have an existing corresponding entry @@ -119,12 +126,22 @@ ContextHandlerRef ExtConditionalFormattingContext::onCreateContext(sal_Int32 nEl maEntries.push_back(o3tl::make_unique<ScIconSetFormat>(pDoc)); return new IconSetContext(*this, mpCurrentRule); } + else if (aType == "cellIs") + { + sal_Int32 aToken = rAttribs.getToken( XML_operator, XML_TOKEN_INVALID ); + eOperator = CondFormatBuffer::convertToInternalOperator(aToken); + return this; + } else { SAL_WARN("sc", "unhandled XLS14_TOKEN(cfRule) with type: " << aType); } } - else if (nElement == XM_TOKEN(sqref)) + else if (nElement == XLS14_TOKEN( dxf )) + { + return new DxfContext( *this, getStyles().createExtDxf() ); + } + else if (nElement == XM_TOKEN( sqref ) || nElement == XM_TOKEN( f )) { return this; } @@ -132,26 +149,43 @@ ContextHandlerRef ExtConditionalFormattingContext::onCreateContext(sal_Int32 nEl return nullptr; } -void ExtConditionalFormattingContext::onStartElement(const AttributeList& /*rAttribs*/) +void ExtConditionalFormattingContext::onStartElement(const AttributeList& /*Attribs*/) +{ +} + +void ExtConditionalFormattingContext::onCharacters(const OUString& rCharacters) { switch (getCurrentElement()) { + case XM_TOKEN(f): + { + aChars = rCharacters; + isPreviousElementF = true; + } + break; case XM_TOKEN(sqref): { + aChars = rCharacters; } break; } -} -void ExtConditionalFormattingContext::onCharacters(const OUString& rCharacters) -{ - aChars = rCharacters; } void ExtConditionalFormattingContext::onEndElement() { switch (getCurrentElement()) { + case XM_TOKEN(f): + { + rFormulas.push_back(aChars); + } + break; + case XLS14_TOKEN( cfRule ): + { + getStyles().getExtDxfs().forEachMem( &Dxf::finalizeImport ); + } + break; case XM_TOKEN(sqref): { ScRangeList aRange; @@ -167,15 +201,28 @@ void ExtConditionalFormattingContext::onEndElement() aRange[i]->aEnd.SetTab(nTab); } + if(isPreviousElementF) // sqref can be alone in some cases. + { + for(const OUString& rFormula : rFormulas) + { + ScAddress rPos = aRange.GetTopLeftCorner(); + rStyle = getStyles().createExtDxfStyle(rStyleIdx); + ScCondFormatEntry* pEntry = new ScCondFormatEntry(eOperator, rFormula, "", pDoc, + rPos, rStyle, "", "", + formula::FormulaGrammar::GRAM_OOXML , + formula::FormulaGrammar::GRAM_OOXML, + ScFormatEntry::Type::ExtCondition ); + maEntries.push_back(std::unique_ptr<ScFormatEntry>(pEntry)); + rStyleIdx++; + } + rFormulas.clear(); + } + std::vector< std::unique_ptr<ExtCfCondFormat> >& rExtFormats = getCondFormats().importExtCondFormat(); rExtFormats.push_back(o3tl::make_unique<ExtCfCondFormat>(aRange, maEntries)); + isPreviousElementF = false; } break; - case XLS14_TOKEN(cfRule): - if (mpCurrentRule) - { - } - break; default: break; } diff --git a/sc/source/filter/oox/stylesbuffer.cxx b/sc/source/filter/oox/stylesbuffer.cxx index 15f1093b03a6..7707a6f8b24c 100644 --- a/sc/source/filter/oox/stylesbuffer.cxx +++ b/sc/source/filter/oox/stylesbuffer.cxx @@ -2735,6 +2735,13 @@ DxfRef StylesBuffer::createDxf() return xDxf; } +DxfRef StylesBuffer::createExtDxf() +{ + DxfRef xDxf( new Dxf( *this ) ); + maExtDxfs.push_back( xDxf ); + return xDxf; +} + void StylesBuffer::importPaletteColor( const AttributeList& rAttribs ) { maPalette.importPaletteColor( rAttribs ); @@ -2891,6 +2898,34 @@ OUString StylesBuffer::createDxfStyle( sal_Int32 nDxfId ) const rStyleSheet.GetItemSet(); pDxf->fillToItemSet(rStyleItemSet); + + } + + // on error: fallback to default style + if (rStyleName.isEmpty()) + rStyleName = maCellStyles.getDefaultStyleName(); + + return rStyleName; +} + +OUString StylesBuffer::createExtDxfStyle( sal_Int32 nDxfId ) const +{ + OUString rStyleName; + + if (Dxf* pDxf = maExtDxfs.get(nDxfId).get()) + { + rStyleName = "ExtConditionalStyle_" + OUString::number(nDxfId + 1); + + // Create a cell style. This may overwrite an existing style if + // one with the same name exists. + ScStyleSheet& rStyleSheet = ScfTools::MakeCellStyleSheet( + *getScDocument().GetStyleSheetPool(), rStyleName, true); + + rStyleSheet.ResetParent(); + SfxItemSet& rStyleItemSet = + rStyleSheet.GetItemSet(); + + pDxf->fillToItemSet(rStyleItemSet); } // on error: fallback to default style diff --git a/sc/source/filter/oox/stylesfragment.cxx b/sc/source/filter/oox/stylesfragment.cxx index a9423ac8d792..97e0a88b9681 100644 --- a/sc/source/filter/oox/stylesfragment.cxx +++ b/sc/source/filter/oox/stylesfragment.cxx @@ -156,6 +156,19 @@ ContextHandlerRef DxfContext::onCreateContext( sal_Int32 nElement, const Attribu } break; } + + if( mxExtDxf.get() ) switch( getCurrentElement() ) + { + case XLS14_TOKEN( dxf ): + switch( nElement ) + { + case XLS_TOKEN( font ): return new FontContext( *this, mxExtDxf->createFont() ); + case XLS_TOKEN( border ): return new BorderContext( *this, mxExtDxf->createBorder() ); + case XLS_TOKEN( fill ): return new FillContext( *this, mxExtDxf->createFill() ); + case XLS_TOKEN( numFmt ): mxExtDxf->importNumFmt( rAttribs ); break; + } + break; + } return nullptr; } diff --git a/sc/source/ui/condformat/condformatdlg.cxx b/sc/source/ui/condformat/condformatdlg.cxx index 00adeac4e296..25cb49e83fc7 100644 --- a/sc/source/ui/condformat/condformatdlg.cxx +++ b/sc/source/ui/condformat/condformatdlg.cxx @@ -86,6 +86,7 @@ void ScCondFormatList::init(ScDocument* pDoc, ScCondFormatDlg* pDialogParent, switch(pEntry->GetType()) { case ScFormatEntry::Type::Condition: + case ScFormatEntry::Type::ExtCondition: { const ScCondFormatEntry* pConditionEntry = static_cast<const ScCondFormatEntry*>( pEntry ); if(pConditionEntry->GetOperation() != ScConditionMode::Direct) diff --git a/sc/source/ui/condformat/condformathelper.cxx b/sc/source/ui/condformat/condformathelper.cxx index 804811b0a925..e7389acef016 100644 --- a/sc/source/ui/condformat/condformathelper.cxx +++ b/sc/source/ui/condformat/condformathelper.cxx @@ -131,6 +131,7 @@ OUString ScCondFormatHelper::GetExpression(const ScConditionalFormat& rFormat, c switch(rFormat.GetEntry(0)->GetType()) { case ScFormatEntry::Type::Condition: + case ScFormatEntry::Type::ExtCondition: { const ScConditionEntry* pEntry = static_cast<const ScConditionEntry*>(rFormat.GetEntry(0)); ScConditionMode eMode = pEntry->GetOperation(); diff --git a/sc/source/ui/unoobj/condformatuno.cxx b/sc/source/ui/unoobj/condformatuno.cxx index f841f075790e..2427116d8bf3 100644 --- a/sc/source/ui/unoobj/condformatuno.cxx +++ b/sc/source/ui/unoobj/condformatuno.cxx @@ -410,6 +410,7 @@ uno::Reference<beans::XPropertySet> createConditionEntry(const ScFormatEntry* pE switch (pEntry->GetType()) { case ScFormatEntry::Type::Condition: + case ScFormatEntry::Type::ExtCondition: return new ScConditionEntryObj(xParent, static_cast<const ScCondFormatEntry*>(pEntry)); break; diff --git a/sc/source/ui/unoobj/fmtuno.cxx b/sc/source/ui/unoobj/fmtuno.cxx index 731154e4e13e..22dda7d06faf 100644 --- a/sc/source/ui/unoobj/fmtuno.cxx +++ b/sc/source/ui/unoobj/fmtuno.cxx @@ -159,7 +159,8 @@ ScTableConditionalFormat::ScTableConditionalFormat( { ScCondFormatEntryItem aItem; const ScFormatEntry* pFrmtEntry = pFormat->GetEntry(i); - if(pFrmtEntry->GetType() != ScFormatEntry::Type::Condition) + if(pFrmtEntry->GetType() != ScFormatEntry::Type::Condition || + pFrmtEntry->GetType() != ScFormatEntry::Type::ExtCondition) continue; const ScCondFormatEntry* pFormatEntry = static_cast<const ScCondFormatEntry*>(pFrmtEntry); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits