sc/qa/unit/data/xlsx/autofilter-colors.xlsx |binary sc/qa/unit/subsequent_export-test.cxx | 29 +++++++ sc/source/core/data/table3.cxx | 6 + sc/source/filter/excel/excrecds.cxx | 33 +++++++- sc/source/filter/excel/xestyle.cxx | 115 +++++++++++++++++++++++++--- sc/source/filter/excel/xlstyle.cxx | 7 + sc/source/filter/inc/excrecds.hxx | 4 sc/source/filter/inc/xestyle.hxx | 9 ++ sc/source/filter/inc/xlstyle.hxx | 1 9 files changed, 192 insertions(+), 12 deletions(-)
New commits: commit 11a12f3237e240ea4c2b403f0ca25d25fca3b121 Author: Caolán McNamara <caol...@redhat.com> AuthorDate: Sun May 30 17:18:01 2021 +0100 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Mon Jun 28 10:56:51 2021 +0200 crashtesting: on export of fdo84621-4.ods to xls Change-Id: I0553a7584347e0fc3ebcba6f99e974b9b1d341a3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116412 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caol...@redhat.com> (cherry picked from commit 156fad36377ba369065bacad863a31c808314069) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116606 Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> Tested-by: Thorsten Behrens <thorsten.behr...@allotropia.de> diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 8c9153f302d9..481d74e83f6e 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -3488,6 +3488,9 @@ bool ScTable::HasRowHeader( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCR void ScTable::GetFilterEntries( SCCOL nCol, SCROW nRow1, SCROW nRow2, ScFilterEntries& rFilterEntries ) { + if (nCol >= aCol.size()) + return; + sc::ColumnBlockConstPosition aBlockPos; aCol[nCol].InitBlockPosition(aBlockPos); aCol[nCol].GetFilterEntries(aBlockPos, nRow1, nRow2, rFilterEntries); @@ -3496,6 +3499,9 @@ void ScTable::GetFilterEntries( SCCOL nCol, SCROW nRow1, SCROW nRow2, ScFilterEn void ScTable::GetFilteredFilterEntries( SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, ScFilterEntries& rFilterEntries ) { + if (nCol >= aCol.size()) + return; + sc::ColumnBlockConstPosition aBlockPos; aCol[nCol].InitBlockPosition(aBlockPos); commit c178cf53c10944d84dfe63d15f0703db4a5eb5b6 Author: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> AuthorDate: Wed May 19 11:05:27 2021 +0200 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Mon Jun 28 10:56:36 2021 +0200 tdf#76258 Add OOXML export for color filter Change-Id: I4c0e2fbe27de6d48a33aba230c35d3b74854e27e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/115789 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> (cherry picked from commit b8cfea65ddcba33572e9687022de3c813711e298) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116605 Tested-by: Thorsten Behrens <thorsten.behr...@allotropia.de> Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> diff --git a/sc/qa/unit/data/xlsx/autofilter-colors.xlsx b/sc/qa/unit/data/xlsx/autofilter-colors.xlsx new file mode 100644 index 000000000000..e4f8e67b202d Binary files /dev/null and b/sc/qa/unit/data/xlsx/autofilter-colors.xlsx differ diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index d2e1087acf55..ff2a2613d466 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -202,6 +202,8 @@ public: void testTdf95640_ods_to_xlsx_with_standard_list(); void testTdf95640_xlsx_to_xlsx(); void testAutofilterColorsODF(); + void testAutofilterColorsOOXML(); + void testAutofilterColorsStyleOOXML(); void testRefStringXLSX(); void testRefStringConfigXLSX(); @@ -339,6 +341,8 @@ public: CPPUNIT_TEST(testTdf95640_ods_to_xlsx_with_standard_list); CPPUNIT_TEST(testTdf95640_xlsx_to_xlsx); CPPUNIT_TEST(testAutofilterColorsODF); + CPPUNIT_TEST(testAutofilterColorsOOXML); + CPPUNIT_TEST(testAutofilterColorsStyleOOXML); CPPUNIT_TEST(testRefStringXLSX); CPPUNIT_TEST(testRefStringConfigXLSX); @@ -4070,6 +4074,31 @@ void ScExportTest::testAutofilterColorsODF() assertXPath(pDoc, "//table:filter/table:filter-and/table:filter-condition[2][@loext:data-type='text-color']"); } +void ScExportTest::testAutofilterColorsOOXML() +{ + ScDocShellRef xDocSh = loadDoc(u"autofilter-colors.", FORMAT_XLSX); + CPPUNIT_ASSERT(xDocSh.is()); + + xmlDocPtr pDoc = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, + "xl/tables/table1.xml", FORMAT_XLSX); + CPPUNIT_ASSERT(pDoc); + + assertXPath(pDoc, "/x:table/x:autoFilter/x:filterColumn/x:colorFilter", "dxfId", "4"); +} + +void ScExportTest::testAutofilterColorsStyleOOXML() +{ + ScDocShellRef xDocSh = loadDoc(u"autofilter-colors.", FORMAT_XLSX); + CPPUNIT_ASSERT(xDocSh.is()); + + xmlDocPtr pDoc + = XPathHelper::parseExport2(*this, *xDocSh, m_xSFactory, "xl/styles.xml", FORMAT_XLSX); + CPPUNIT_ASSERT(pDoc); + + assertXPath(pDoc, "/x:styleSheet/x:dxfs/x:dxf[5]/x:fill/x:patternFill/x:bgColor", "rgb", + "FFFFD7D7"); +} + void ScExportTest::testConditionalFormatPriorityCheckXLSX() { ScDocShellRef xDocSh = loadDoc("conditional_fmt_checkpriority.", FORMAT_XLSX); diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx index 920955a6540d..23c106524704 100644 --- a/sc/source/filter/excel/excrecds.cxx +++ b/sc/source/filter/excel/excrecds.cxx @@ -42,6 +42,7 @@ #include <xelink.hxx> #include <xename.hxx> #include <xlname.hxx> +#include <xestyle.hxx> #include <xcl97rec.hxx> #include <tabprotection.hxx> @@ -696,6 +697,10 @@ bool XclExpAutofilter::AddEntry( const ScQueryEntry& rEntry ) bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_EMPTY, EXC_AFOPER_NONE, 0.0, nullptr, true ); else if(rEntry.IsQueryByNonEmpty()) bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_NOTEMPTY, EXC_AFOPER_NONE, 0.0, nullptr, true ); + else if (rEntry.IsQueryByTextColor() || rEntry.IsQueryByBackgroundColor()) + { + AddColorEntry(rEntry); + } // other conditions else { @@ -774,6 +779,17 @@ void XclExpAutofilter::AddMultiValueEntry( const ScQueryEntry& rEntry ) maMultiValues.push_back(rItem.maString.getString()); } +void XclExpAutofilter::AddColorEntry(const ScQueryEntry& rEntry) +{ + meType = ColorValue; + const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems(); + for (const auto& rItem : rItems) + { + maColorValues.push_back( + std::make_pair(rItem.maColor, rItem.meType == ScQueryEntry::ByBackgroundColor)); + } +} + void XclExpAutofilter::WriteBody( XclExpStream& rStrm ) { rStrm << nCol << nFlags; @@ -815,8 +831,21 @@ void XclExpAutofilter::SaveXml( XclExpXmlStream& rStrm ) aCond[ 0 ].SaveXml( rStrm ); aCond[ 1 ].SaveXml( rStrm ); rWorksheet->endElement( XML_customFilters ); - // OOXTODO: XLM_colorFilter, XML_dynamicFilter, - // XML_extLst, XML_filters, XML_iconFilter, XML_top10 + // OOXTODO: XML_dynamicFilter, XML_extLst, XML_filters, XML_iconFilter + } + break; + case ColorValue: + { + if (!maColorValues.empty()) + { + Color color = maColorValues[0].first; + sal_Int32 nDxfId; + if (maColorValues[0].second) // is background color + nDxfId = GetDxfs().GetDxfByBackColor(color); + else + nDxfId = GetDxfs().GetDxfByForeColor(color); + rWorksheet->singleElement(XML_colorFilter, XML_dxfId, OString::number(nDxfId)); + } } break; case MultiValue: diff --git a/sc/source/filter/excel/xestyle.cxx b/sc/source/filter/excel/xestyle.cxx index 32078b75d3c1..65f73bb6b1f5 100644 --- a/sc/source/filter/excel/xestyle.cxx +++ b/sc/source/filter/excel/xestyle.cxx @@ -46,6 +46,8 @@ #include <xestring.hxx> #include <xltools.hxx> #include <conditio.hxx> +#include <dbdata.hxx> +#include <filterentries.hxx> #include <oox/export/utils.hxx> #include <oox/token/tokens.hxx> @@ -1861,7 +1863,18 @@ void XclExpCellBorder::SaveXml( XclExpXmlStream& rStrm ) const XclExpCellArea::XclExpCellArea() : mnForeColorId( XclExpPalette::GetColorIdFromIndex( mnForeColor ) ), - mnBackColorId( XclExpPalette::GetColorIdFromIndex( mnBackColor ) ) + mnBackColorId( XclExpPalette::GetColorIdFromIndex( mnBackColor ) ), + maForeColor(0), + maBackColor(0) +{ +} + +XclExpCellArea::XclExpCellArea(Color aForeColor, Color aBackColor) + : XclCellArea(EXC_PATT_SOLID) + , mnForeColorId(0) + , mnBackColorId(0) + , maForeColor(aForeColor) + , maBackColor(aBackColor) { } @@ -1938,15 +1951,42 @@ void XclExpCellArea::SaveXml( XclExpXmlStream& rStrm ) const XclExpPalette& rPalette = rStrm.GetRoot().GetPalette(); - if( mnPattern == EXC_PATT_NONE || ( mnForeColor == 0 && mnBackColor == 0 ) ) + if (mnPattern == EXC_PATT_NONE + || (mnForeColor == 0 && mnBackColor == 0 && maForeColor == 0 && maBackColor == 0)) + { rStyleSheet->singleElement(XML_patternFill, XML_patternType, ToPatternType(mnPattern)); + } else { rStyleSheet->startElement(XML_patternFill, XML_patternType, ToPatternType(mnPattern)); - rStyleSheet->singleElement( XML_fgColor, - XML_rgb, XclXmlUtils::ToOString(rPalette.GetColor(mnForeColor)) ); - rStyleSheet->singleElement( XML_bgColor, - XML_rgb, XclXmlUtils::ToOString(rPalette.GetColor(mnBackColor)) ); + if (maForeColor != 0 || maBackColor != 0) + { + if (maForeColor != 0) + { + rStyleSheet->singleElement(XML_fgColor, XML_rgb, + XclXmlUtils::ToOString(maForeColor)); + } + + if (maBackColor != 0) + { + rStyleSheet->singleElement(XML_bgColor, XML_rgb, + XclXmlUtils::ToOString(maBackColor)); + } + } + else + { + if (mnForeColor != 0) + { + rStyleSheet->singleElement(XML_fgColor, XML_rgb, + XclXmlUtils::ToOString(rPalette.GetColor(mnForeColor))); + } + if (mnBackColor != 0) + { + rStyleSheet->singleElement(XML_bgColor, XML_rgb, + XclXmlUtils::ToOString(rPalette.GetColor(mnBackColor))); + } + } + rStyleSheet->endElement( XML_patternFill ); } @@ -3001,9 +3041,42 @@ XclExpDxfs::XclExpDxfs( const XclExpRoot& rRoot ) xFormatter->FillKeywordTableForExcel( *mpKeywordTable ); SCTAB nTables = rRoot.GetDoc().GetTableCount(); - sal_Int32 nIndex = 0; + sal_Int32 nForeColorIndex = 0; + sal_Int32 nBackColorIndex = 0; + sal_Int32 nCondFormattingIndex = 0; for(SCTAB nTab = 0; nTab < nTables; ++nTab) { + // Color filters + const ScDBData* pData = rRoot.GetDoc().GetDBCollection()->GetDBNearCursor(0, 0, 0); + if (pData) + { + ScRange aRange; + pData->GetArea(aRange); + ScFilterEntries aFilterEntries; + rRoot.GetDoc().GetFilterEntriesArea(aRange.aStart.Col(), aRange.aStart.Row(), + aRange.aEnd.Row(), nTab, true, aFilterEntries); + + for (auto& rColor : aFilterEntries.getBackgroundColors()) + { + if (!maBackColorToDxfId.emplace(rColor, nBackColorIndex).second) + continue; + + std::unique_ptr<XclExpCellArea> pExpCellArea(new XclExpCellArea(0, rColor)); + maDxf.push_back(std::make_unique<XclExpDxf>(rRoot, std::move(pExpCellArea))); + nBackColorIndex++; + } + for (auto& rColor : aFilterEntries.getTextColors()) + { + if (!maForeColorToDxfId.emplace(rColor, nForeColorIndex).second) + continue; + + std::unique_ptr<XclExpCellArea> pExpCellArea(new XclExpCellArea(rColor, 0)); + maDxf.push_back(std::make_unique<XclExpDxf>(rRoot, std::move(pExpCellArea))); + nForeColorIndex++; + } + } + + // Conditional formatting ScConditionalFormatList* pList = rRoot.GetDoc().GetCondFormList(nTab); if (pList) { @@ -3029,7 +3102,7 @@ XclExpDxfs::XclExpDxfs( const XclExpRoot& rRoot ) aStyleName = pEntry->GetStyleName(); } - if (maStyleNameToDxfId.emplace(aStyleName, nIndex).second) + if (maStyleNameToDxfId.emplace(aStyleName, nCondFormattingIndex).second) { SfxStyleSheetBase* pStyle = rRoot.GetDoc().GetStyleSheetPool()->Find(aStyleName, SfxStyleFamily::Para); if(!pStyle) @@ -3074,7 +3147,7 @@ XclExpDxfs::XclExpDxfs( const XclExpRoot& rRoot ) maDxf.push_back(std::make_unique<XclExpDxf>( rRoot, std::move(pAlign), std::move(pBorder), std::move(pFont), std::move(pNumFormat), std::move(pCellProt), std::move(pColor) )); - ++nIndex; + ++nCondFormattingIndex; } } @@ -3091,6 +3164,22 @@ sal_Int32 XclExpDxfs::GetDxfId( const OUString& rStyleName ) return -1; } +sal_Int32 XclExpDxfs::GetDxfByBackColor(Color& aColor) +{ + std::map<Color, sal_Int32>::iterator itr = maBackColorToDxfId.find(aColor); + if (itr != maBackColorToDxfId.end()) + return itr->second; + return -1; +} + +sal_Int32 XclExpDxfs::GetDxfByForeColor(Color& aColor) +{ + std::map<Color, sal_Int32>::iterator itr = maForeColorToDxfId.find(aColor); + if (itr != maForeColorToDxfId.end()) + return itr->second; + return -1; +} + void XclExpDxfs::SaveXml( XclExpXmlStream& rStrm ) { if(maDxf.empty()) @@ -3120,6 +3209,12 @@ XclExpDxf::XclExpDxf( const XclExpRoot& rRoot, std::unique_ptr<XclExpCellAlign> { } +XclExpDxf::XclExpDxf(const XclExpRoot& rRoot, std::unique_ptr<XclExpCellArea> pCellArea) + : XclExpRoot(rRoot) + , mpCellArea(std::move(pCellArea)) +{ +} + XclExpDxf::~XclExpDxf() { } @@ -3141,6 +3236,8 @@ void XclExpDxf::SaveXml( XclExpXmlStream& rStrm ) mpBorder->SaveXml(rStrm); if (mpProt) mpProt->SaveXml(rStrm); + if (mpCellArea) + mpCellArea->SaveXml(rStrm); rStyleSheet->endElement( XML_dxf ); } diff --git a/sc/source/filter/excel/xlstyle.cxx b/sc/source/filter/excel/xlstyle.cxx index 8d769042642a..2debd508b563 100644 --- a/sc/source/filter/excel/xlstyle.cxx +++ b/sc/source/filter/excel/xlstyle.cxx @@ -1693,6 +1693,13 @@ XclCellArea::XclCellArea() : { } +XclCellArea::XclCellArea(sal_uInt8 nPattern) : + mnForeColor( EXC_COLOR_WINDOWTEXT ), + mnBackColor( EXC_COLOR_WINDOWBACK ), + mnPattern( nPattern ) +{ +} + bool XclCellArea::IsTransparent() const { return (mnPattern == EXC_PATT_NONE) && (mnBackColor == EXC_COLOR_WINDOWBACK); diff --git a/sc/source/filter/inc/excrecds.hxx b/sc/source/filter/inc/excrecds.hxx index a0abbf9410cd..8b9e0cae87e9 100644 --- a/sc/source/filter/inc/excrecds.hxx +++ b/sc/source/filter/inc/excrecds.hxx @@ -361,12 +361,13 @@ public: class XclExpAutofilter : public XclExpRecord, protected XclExpRoot { private: - enum FilterType { FilterCondition, MultiValue }; + enum FilterType { FilterCondition, MultiValue, ColorValue }; FilterType meType; sal_uInt16 nCol; sal_uInt16 nFlags; ExcFilterCondition aCond[ 2 ]; std::vector<OUString> maMultiValues; + std::vector<std::pair<::Color, bool>> maColorValues; // first->Color, second->bIsBackgroundColor (vs. TextColor) bool AddCondition( ScQueryConnect eConn, sal_uInt8 nType, sal_uInt8 nOp, double fVal, const OUString* pText, @@ -383,6 +384,7 @@ public: bool HasCondition() const; bool AddEntry( const ScQueryEntry& rEntry ); void AddMultiValueEntry( const ScQueryEntry& rEntry ); + void AddColorEntry( const ScQueryEntry& rEntry ); virtual void SaveXml( XclExpXmlStream& rStrm ) override; }; diff --git a/sc/source/filter/inc/xestyle.hxx b/sc/source/filter/inc/xestyle.hxx index ae960530e80c..96e21b95a171 100644 --- a/sc/source/filter/inc/xestyle.hxx +++ b/sc/source/filter/inc/xestyle.hxx @@ -375,8 +375,11 @@ struct XclExpCellArea : public XclCellArea { sal_uInt32 mnForeColorId; /// Foreground color ID. sal_uInt32 mnBackColorId; /// Background color ID. + Color maForeColor; // Actual foreground color + Color maBackColor; // Actual background color explicit XclExpCellArea(); + explicit XclExpCellArea(Color aForeColor, Color aBackColor); /** Fills the area attributes from the passed item set. @return true = At least one area item is set. */ @@ -726,6 +729,7 @@ public: XclExpDxf( const XclExpRoot& rRoot, std::unique_ptr<XclExpCellAlign> pAlign, std::unique_ptr<XclExpCellBorder> pBorder, std::unique_ptr<XclExpDxfFont> pFont, std::unique_ptr<XclExpNumFmt> pNumberFmt, std::unique_ptr<XclExpCellProt> pProt, std::unique_ptr<XclExpColor> pColor); + XclExpDxf( const XclExpRoot& rRoot, std::unique_ptr<XclExpCellArea> pCellArea); virtual ~XclExpDxf() override; virtual void SaveXml( XclExpXmlStream& rStrm ) override; @@ -738,6 +742,7 @@ private: std::unique_ptr<XclExpNumFmt> mpNumberFmt; std::unique_ptr<XclExpCellProt> mpProt; std::unique_ptr<XclExpColor> mpColor; + std::unique_ptr<XclExpCellArea> mpCellArea; }; class XclExpDxfs : public XclExpRecordBase, protected XclExpRoot @@ -746,11 +751,15 @@ public: XclExpDxfs( const XclExpRoot& rRoot ); sal_Int32 GetDxfId(const OUString& rName); + sal_Int32 GetDxfByBackColor(Color& aColor); + sal_Int32 GetDxfByForeColor(Color& aColor); virtual void SaveXml( XclExpXmlStream& rStrm) override; private: typedef std::vector< std::unique_ptr<XclExpDxf> > DxfContainer; std::map<OUString, sal_Int32> maStyleNameToDxfId; + std::map<Color, sal_Int32> maBackColorToDxfId; + std::map<Color, sal_Int32> maForeColorToDxfId; DxfContainer maDxf; std::unique_ptr<NfKeywordTable> mpKeywordTable; /// Replacement table. }; diff --git a/sc/source/filter/inc/xlstyle.hxx b/sc/source/filter/inc/xlstyle.hxx index 70fd39121c3e..4d39ed033970 100644 --- a/sc/source/filter/inc/xlstyle.hxx +++ b/sc/source/filter/inc/xlstyle.hxx @@ -548,6 +548,7 @@ struct XclCellArea sal_uInt8 mnPattern; /// Fill pattern. explicit XclCellArea(); + explicit XclCellArea(sal_uInt8 nPattern); /** Returns true, if the area represents transparent state. */ bool IsTransparent() const; _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits