[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