tdf#148820 sc: fix conditional formatted cell color

Store foreground color for color filtering, because in OOXML
the foreground color is used for color filtering and we overwrote
it with the background color which is used for conditional formatted cells too.

Regression from commit: 6f908b48373b71d45c8119b296b0504fb586f6f8
(tdf#143104 Fix xlsx import/export of color filter colors)

Change-Id: I737e6f1170851822a2689fa477db59e62f0d47fa
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136055
Tested-by: Jenkins
Tested-by: Gabor Kelemen <kelemeng@ubuntu.com>
Reviewed-by: Thorsten Behrens <thorsten.behrens@allotropia.de>
diff --git a/editeng/source/items/frmitems.cxx b/editeng/source/items/frmitems.cxx
index 4bbca9a..c4c79dc 100644
--- a/editeng/source/items/frmitems.cxx
+++ b/editeng/source/items/frmitems.cxx
@@ -2832,6 +2832,7 @@ void SvxLineItem::SetLine( const SvxBorderLine* pNew )
SvxBrushItem::SvxBrushItem(sal_uInt16 _nWhich)
    : SfxPoolItem(_nWhich)
    , aColor(COL_TRANSPARENT)
    , aFilterColor(COL_TRANSPARENT)
    , nShadingValue(ShadingPattern::CLEAR)
    , nGraphicTransparency(0)
    , eGraphicPos(GPOS_NONE)
@@ -2842,6 +2843,7 @@ SvxBrushItem::SvxBrushItem(sal_uInt16 _nWhich)
SvxBrushItem::SvxBrushItem(const Color& rColor, sal_uInt16 _nWhich)
    : SfxPoolItem(_nWhich)
    , aColor(rColor)
    , aFilterColor(COL_TRANSPARENT)
    , nShadingValue(ShadingPattern::CLEAR)
    , nGraphicTransparency(0)
    , eGraphicPos(GPOS_NONE)
@@ -2852,6 +2854,7 @@ SvxBrushItem::SvxBrushItem(const Color& rColor, sal_uInt16 _nWhich)
SvxBrushItem::SvxBrushItem(const Graphic& rGraphic, SvxGraphicPosition ePos, sal_uInt16 _nWhich)
    : SfxPoolItem(_nWhich)
    , aColor(COL_TRANSPARENT)
    , aFilterColor(COL_TRANSPARENT)
    , nShadingValue(ShadingPattern::CLEAR)
    , xGraphicObject(new GraphicObject(rGraphic))
    , nGraphicTransparency(0)
@@ -2864,6 +2867,7 @@ SvxBrushItem::SvxBrushItem(const Graphic& rGraphic, SvxGraphicPosition ePos, sal
SvxBrushItem::SvxBrushItem(const GraphicObject& rGraphicObj, SvxGraphicPosition ePos, sal_uInt16 _nWhich)
    : SfxPoolItem(_nWhich)
    , aColor(COL_TRANSPARENT)
    , aFilterColor(COL_TRANSPARENT)
    , nShadingValue(ShadingPattern::CLEAR)
    , xGraphicObject(new GraphicObject(rGraphicObj))
    , nGraphicTransparency(0)
@@ -2877,6 +2881,7 @@ SvxBrushItem::SvxBrushItem(OUString aLink, OUString aFilter,
                           SvxGraphicPosition ePos, sal_uInt16 _nWhich)
    : SfxPoolItem(_nWhich)
    , aColor(COL_TRANSPARENT)
    , aFilterColor(COL_TRANSPARENT)
    , nShadingValue(ShadingPattern::CLEAR)
    , nGraphicTransparency(0)
    , maStrLink(std::move(aLink))
@@ -2890,6 +2895,7 @@ SvxBrushItem::SvxBrushItem(OUString aLink, OUString aFilter,
SvxBrushItem::SvxBrushItem(const SvxBrushItem& rItem)
    : SfxPoolItem(rItem)
    , aColor(rItem.aColor)
    , aFilterColor(rItem.aFilterColor)
    , nShadingValue(rItem.nShadingValue)
    , xGraphicObject(rItem.xGraphicObject ? new GraphicObject(*rItem.xGraphicObject) : nullptr)
    , nGraphicTransparency(rItem.nGraphicTransparency)
@@ -2903,6 +2909,7 @@ SvxBrushItem::SvxBrushItem(const SvxBrushItem& rItem)
SvxBrushItem::SvxBrushItem(SvxBrushItem&& rItem)
    : SfxPoolItem(std::move(rItem))
    , aColor(std::move(rItem.aColor))
    , aFilterColor(std::move(rItem.aFilterColor))
    , nShadingValue(std::move(rItem.nShadingValue))
    , xGraphicObject(std::move(rItem.xGraphicObject))
    , nGraphicTransparency(std::move(rItem.nGraphicTransparency))
@@ -3157,8 +3164,8 @@ bool SvxBrushItem::operator==( const SfxPoolItem& rAttr ) const
    assert(SfxPoolItem::operator==(rAttr));

    const SvxBrushItem& rCmp = static_cast<const SvxBrushItem&>(rAttr);
    bool bEqual = ( aColor == rCmp.aColor && eGraphicPos == rCmp.eGraphicPos &&
        nGraphicTransparency == rCmp.nGraphicTransparency);
    bool bEqual = ( aColor == rCmp.aColor && aFilterColor == rCmp.aFilterColor &&
        eGraphicPos == rCmp.eGraphicPos && nGraphicTransparency == rCmp.nGraphicTransparency);

    if ( bEqual )
    {
@@ -3366,6 +3373,7 @@ void SvxBrushItem::dumpAsXml(xmlTextWriterPtr pWriter) const
    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxBrushItem"));
    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("color"), BAD_CAST(aColor.AsRGBHexString().toUtf8().getStr()));
    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("filtercolor"), BAD_CAST(aFilterColor.AsRGBHexString().toUtf8().getStr()));
    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("shadingValue"), BAD_CAST(OString::number(nShadingValue).getStr()));
    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("link"), BAD_CAST(maStrLink.toUtf8().getStr()));
    (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("filter"), BAD_CAST(maStrFilter.toUtf8().getStr()));
diff --git a/include/editeng/brushitem.hxx b/include/editeng/brushitem.hxx
index 310ae7c..850ff7d 100644
--- a/include/editeng/brushitem.hxx
+++ b/include/editeng/brushitem.hxx
@@ -43,6 +43,7 @@ enum SvxGraphicPosition
class EDITENG_DLLPUBLIC SvxBrushItem final : public SfxPoolItem
{
    Color               aColor;
    Color               aFilterColor;
    sal_Int32           nShadingValue;
    mutable std::unique_ptr<GraphicObject> xGraphicObject;
    sal_Int8            nGraphicTransparency; //contains a percentage value which is
@@ -90,6 +91,10 @@ public:
    Color&          GetColor()                      { return aColor; }
    void            SetColor( const Color& rCol)    { aColor = rCol; }

    const Color&    GetFiltColor() const             { return aFilterColor; }
    Color&          GetFiltColor()                   { return aFilterColor; }
    void            SetFiltColor( const Color& rCol) { aFilterColor = rCol; }

    SvxGraphicPosition  GetGraphicPos() const       { return eGraphicPos; }

    sal_Int32               GetShadingValue() const     { return nShadingValue; }
diff --git a/sc/qa/unit/data/xlsx/tdf148820.xlsx b/sc/qa/unit/data/xlsx/tdf148820.xlsx
new file mode 100644
index 0000000..89c6488
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/tdf148820.xlsx
Binary files differ
diff --git a/sc/qa/unit/subsequent_export_test2.cxx b/sc/qa/unit/subsequent_export_test2.cxx
index fa55acd..6cdb985 100644
--- a/sc/qa/unit/subsequent_export_test2.cxx
+++ b/sc/qa/unit/subsequent_export_test2.cxx
@@ -189,6 +189,7 @@ public:
    void testWholeRowBold();
    void testXlsxRowsOrder();
    void testTdf91286();
    void testTdf148820();

    CPPUNIT_TEST_SUITE(ScExportTest2);

@@ -310,6 +311,7 @@ public:
    CPPUNIT_TEST(testWholeRowBold);
    CPPUNIT_TEST(testXlsxRowsOrder);
    CPPUNIT_TEST(testTdf91286);
    CPPUNIT_TEST(testTdf148820);

    CPPUNIT_TEST_SUITE_END();

@@ -3062,6 +3064,36 @@ void ScExportTest2::testTdf91286()
    CPPUNIT_ASSERT_EQUAL(1, nImageFiles);
}

void ScExportTest2::testTdf148820()
{
    ScDocShellRef xDocSh = loadDoc(u"tdf148820.", FORMAT_XLSX);
    std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(*xDocSh, FORMAT_XLSX);
    xmlDocUniquePtr pSheet
        = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
    CPPUNIT_ASSERT(pSheet);

    sal_Int32 nDxfIdCondFormatFirst
        = getXPath(pSheet, "/x:worksheet/x:conditionalFormatting[1]/x:cfRule", "dxfId").toInt32()
          + 1;
    sal_Int32 nDxfIdCondFormatLast
        = getXPath(pSheet, "/x:worksheet/x:conditionalFormatting[20]/x:cfRule", "dxfId").toInt32()
          + 1;

    xmlDocUniquePtr pStyles = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/styles.xml");
    CPPUNIT_ASSERT(pStyles);

    OString sDxfCondFormatXPath("/x:styleSheet/x:dxfs/x:dxf["
                                + OString::number(nDxfIdCondFormatFirst)
                                + "]/x:fill/x:patternFill/x:bgColor");
    assertXPath(pStyles, sDxfCondFormatXPath, "rgb", "FF53B5A9");
    sDxfCondFormatXPath
        = OString("/x:styleSheet/x:dxfs/x:dxf[" + OString::number(nDxfIdCondFormatLast)
                  + "]/x:fill/x:patternFill/x:bgColor");
    assertXPath(pStyles, sDxfCondFormatXPath, "rgb", "FFA30000");

    xDocSh->DoClose();
}

CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest2);

CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/filter/inc/stylesbuffer.hxx b/sc/source/filter/inc/stylesbuffer.hxx
index d0a32d5..4d9e7ae 100644
--- a/sc/source/filter/inc/stylesbuffer.hxx
+++ b/sc/source/filter/inc/stylesbuffer.hxx
@@ -466,6 +466,7 @@ typedef std::shared_ptr< Border > BorderRef;
struct PatternFillModel
{
    Color               maPatternColor;     /// Pattern foreground color.
    Color               maFilterPatternColor; /// Pattern foreground for color filter.
    Color               maFillColor;        /// Background fill color.
    sal_Int32           mnPattern;          /// Pattern identifier (e.g. solid).
    bool                mbPattColorUsed;    /// True = pattern foreground color used.
@@ -503,6 +504,7 @@ struct GradientFillModel
struct ApiSolidFillData
{
    ::Color             mnColor;            /// Fill color.
    ::Color             mnFilterColor;        /// Fill color filtering.
    bool                mbTransparent;      /// True = transparent area.
    bool                mbUsed;             /// True = fill data is valid.

diff --git a/sc/source/filter/oox/autofilterbuffer.cxx b/sc/source/filter/oox/autofilterbuffer.cxx
index e53a4db..703de7b 100644
--- a/sc/source/filter/oox/autofilterbuffer.cxx
+++ b/sc/source/filter/oox/autofilterbuffer.cxx
@@ -441,7 +441,7 @@ ApiFilterSettings ColorFilter::finalizeImport()
    const SfxItemSet& rItemSet = pStyleSheet->GetItemSet();
    // Color (whether text or background color) is always stored in ATTR_BACKGROUND
    const SvxBrushItem* pItem = rItemSet.GetItem<SvxBrushItem>(ATTR_BACKGROUND);
    ::Color aColor = pItem->GetColor();
    ::Color aColor = pItem->GetFiltColor();
    util::Color nColor(aColor);
    aSettings.appendField(true, nColor, mbIsBackgroundColor);
    return aSettings;
diff --git a/sc/source/filter/oox/stylesbuffer.cxx b/sc/source/filter/oox/stylesbuffer.cxx
index 962de02..2e594a3 100644
--- a/sc/source/filter/oox/stylesbuffer.cxx
+++ b/sc/source/filter/oox/stylesbuffer.cxx
@@ -1616,6 +1616,7 @@ PatternFillModel::PatternFillModel( bool bDxf ) :
    mbPatternUsed( !bDxf )
{
    maPatternColor.setIndexed( OOX_COLOR_WINDOWTEXT );
    maFilterPatternColor.setIndexed( OOX_COLOR_WINDOWTEXT );
    maFillColor.setIndexed( OOX_COLOR_WINDOWBACK );
}

@@ -1674,6 +1675,7 @@ void GradientFillModel::readGradientStop( SequenceInputStream& rStrm, bool bDxf 

ApiSolidFillData::ApiSolidFillData() :
    mnColor( API_RGB_TRANSPARENT ),
    mnFilterColor( API_RGB_TRANSPARENT ),
    mbTransparent( true ),
    mbUsed( false )
{
@@ -1825,8 +1827,8 @@ void Fill::finalizeImport()
        {
            if( rModel.mbFillColorUsed && (!rModel.mbPatternUsed || (rModel.mnPattern == XML_solid)) )
            {
                if (!rModel.mbPatternUsed)
                    rModel.maPatternColor = rModel.maFillColor;
                rModel.maFilterPatternColor = rModel.maPatternColor;
                rModel.maPatternColor = rModel.maFillColor;
                rModel.mnPattern = XML_solid;
                rModel.mbPattColorUsed = rModel.mbPatternUsed = true;
            }
@@ -1836,6 +1838,8 @@ void Fill::finalizeImport()
            {
                rModel.mbPatternUsed = false;
            }
            else
                rModel.maFilterPatternColor = rModel.maPatternColor;
        }

        // convert to API fill settings
@@ -1873,15 +1877,20 @@ void Fill::finalizeImport()
            ::Color nWinTextColor = rGraphicHelper.getSystemColor( XML_windowText );
            ::Color nWinColor = rGraphicHelper.getSystemColor( XML_window );

            if( !rModel.mbPattColorUsed )
            if (!rModel.mbPattColorUsed)
            {
                rModel.maPatternColor.setAuto();
                rModel.maFilterPatternColor.setAuto();
            }
            ::Color nPattColor = rModel.maPatternColor.getColor( rGraphicHelper, nWinTextColor );
            ::Color nFiltPattColor = rModel.maFilterPatternColor.getColor( rGraphicHelper, nWinTextColor );

            if( !rModel.mbFillColorUsed )
                rModel.maFillColor.setAuto();
            ::Color nFillColor = rModel.maFillColor.getColor( rGraphicHelper, nWinColor );

            maApiData.mnColor = lclGetMixedColor( nPattColor, nFillColor, nAlpha );
            maApiData.mnFilterColor = lclGetMixedColor( nFiltPattColor, nFillColor, nAlpha );
            maApiData.mbTransparent = false;
        }
    }
@@ -1911,10 +1920,12 @@ void Fill::fillToItemSet( SfxItemSet& rItemSet, bool bSkipPoolDefs ) const
    if ( maApiData.mbTransparent )
    {
        aBrushItem.SetColor( COL_TRANSPARENT );
        aBrushItem.SetFiltColor( COL_TRANSPARENT );
    }
    else
    {
        aBrushItem.SetColor( maApiData.mnColor  );
        aBrushItem.SetFiltColor( maApiData.mnFilterColor  );
    }
    ScfTools::PutItem( rItemSet, aBrushItem, bSkipPoolDefs );
}