[Libreoffice-commits] core.git: Branch 'distro/lhm/libreoffice-6-4+backports' - 2 commits - sc/qa sc/source
Caolán McNamara (via logerrit)
logerrit at kemper.freedesktop.org
Mon Jun 28 08:57:10 UTC 2021
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 <caolanm at redhat.com>
AuthorDate: Sun May 30 17:18:01 2021 +0100
Commit: Thorsten Behrens <thorsten.behrens at 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 <caolanm at redhat.com>
(cherry picked from commit 156fad36377ba369065bacad863a31c808314069)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116606
Reviewed-by: Thorsten Behrens <thorsten.behrens at allotropia.de>
Tested-by: Thorsten Behrens <thorsten.behrens at 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.mehrbrodt at allotropia.de>
AuthorDate: Wed May 19 11:05:27 2021 +0200
Commit: Thorsten Behrens <thorsten.behrens at 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.mehrbrodt at allotropia.de>
(cherry picked from commit b8cfea65ddcba33572e9687022de3c813711e298)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116605
Tested-by: Thorsten Behrens <thorsten.behrens at allotropia.de>
Reviewed-by: Thorsten Behrens <thorsten.behrens at 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;
More information about the Libreoffice-commits
mailing list