tdf#140098 sc ooxml: fix export of blank filter in non empty filters

Export blank filter value in non empty filters, as the OOXML standard required.

Change-Id: I4e1e3d8e1e2e784d1b4adc5e385f200af86d18ab
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/110762
Tested-by: Jenkins
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sc/qa/unit/data/ods/tdf140098.ods b/sc/qa/unit/data/ods/tdf140098.ods
new file mode 100644
index 0000000..ea7f753
--- /dev/null
+++ b/sc/qa/unit/data/ods/tdf140098.ods
Binary files differ
diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx
index 57d4cc4..a313ee4 100644
--- a/sc/qa/unit/subsequent_export-test.cxx
+++ b/sc/qa/unit/subsequent_export-test.cxx
@@ -269,6 +269,7 @@ public:
    void testHeaderFontStyleXLSX();
    void testTdf135828_Shape_Rect();
    void testTdf123353();
    void testTdf140098();
    void testTdf133688_precedents();
    void testTdf91251_missingOverflowRoundtrip();
    void testTdf137000_handle_upright();
@@ -449,6 +450,7 @@ public:
    CPPUNIT_TEST(testHeaderFontStyleXLSX);
    CPPUNIT_TEST(testTdf135828_Shape_Rect);
    CPPUNIT_TEST(testTdf123353);
    CPPUNIT_TEST(testTdf140098);
    CPPUNIT_TEST(testTdf133688_precedents);
    CPPUNIT_TEST(testTdf91251_missingOverflowRoundtrip);
    CPPUNIT_TEST(testTdf137000_handle_upright);
@@ -5576,6 +5578,24 @@ void ScExportTest::testTdf123353()
    xShell->DoClose();
}

void ScExportTest::testTdf140098()
{
    ScDocShellRef xShell = loadDoc(u"tdf140098.", FORMAT_ODS);
    CPPUNIT_ASSERT(xShell.is());

    ScDocShellRef xDocSh = saveAndReload(&(*xShell), FORMAT_XLSX);
    CPPUNIT_ASSERT(xDocSh.is());

    std::shared_ptr<utl::TempFile> pXPathFile = ScBootstrapFixture::exportTo(&(*xDocSh), FORMAT_XLSX);

    xmlDocUniquePtr pDoc = XPathHelper::parseExport(pXPathFile, m_xSFactory, "xl/worksheets/sheet1.xml");
    CPPUNIT_ASSERT(pDoc);

    assertXPath(pDoc, "/x:worksheet/x:autoFilter/x:filterColumn/x:filters", "blank", "1");

    xShell->DoClose();
}

void ScExportTest::testTdf133688_precedents()
{
    // tdf#133688 Check that we do not export detective shapes.
diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx
index 4457aee..7a215c8 100644
--- a/sc/source/filter/excel/excrecds.cxx
+++ b/sc/source/filter/excel/excrecds.cxx
@@ -620,7 +620,8 @@ XclExpAutofilter::XclExpAutofilter( const XclExpRoot& rRoot, sal_uInt16 nC ) :
    XclExpRoot( rRoot ),
    meType(FilterCondition),
    nCol( nC ),
    nFlags( 0 )
    nFlags( 0 ),
    bHasBlankValue( false )
{
}

@@ -704,7 +705,10 @@ bool XclExpAutofilter::AddEntry( const ScQueryEntry& rEntry )

    // empty/nonempty fields
    if (rEntry.IsQueryByEmpty())
        bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_EMPTY, EXC_AFOPER_NONE, 0.0, nullptr, true );
    {
        bConflict = !AddCondition(rEntry.eConnect, EXC_AFTYPE_EMPTY, EXC_AFOPER_NONE, 0.0, nullptr, true);
        bHasBlankValue = true;
    }
    else if(rEntry.IsQueryByNonEmpty())
        bConflict = !AddCondition( rEntry.eConnect, EXC_AFTYPE_NOTEMPTY, EXC_AFOPER_NONE, 0.0, nullptr, true );
    // other conditions
@@ -782,7 +786,12 @@ void XclExpAutofilter::AddMultiValueEntry( const ScQueryEntry& rEntry )
    meType = MultiValue;
    const ScQueryEntry::QueryItemsType& rItems = rEntry.GetQueryItems();
    for (const auto& rItem : rItems)
        maMultiValues.push_back( std::make_pair(rItem.maString.getString(), rItem.meType == ScQueryEntry::ByDate) );
    {
        if( rItem.maString.isEmpty() )
            bHasBlankValue = true;
        else
            maMultiValues.push_back(std::make_pair(rItem.maString.getString(), rItem.meType == ScQueryEntry::ByDate));
    }
}

void XclExpAutofilter::WriteBody( XclExpStream& rStrm )
@@ -837,7 +846,11 @@ void XclExpAutofilter::SaveXml( XclExpXmlStream& rStrm )
        break;
        case MultiValue:
        {
            rWorksheet->startElement(XML_filters);
            if( bHasBlankValue )
                rWorksheet->startElement(XML_filters, XML_blank, "1");
            else
                rWorksheet->startElement(XML_filters);

            for (const auto& rMultiValue : maMultiValues)
            {
                OString aStr = OUStringToOString(rMultiValue.first, RTL_TEXTENCODING_UTF8);
diff --git a/sc/source/filter/inc/excrecds.hxx b/sc/source/filter/inc/excrecds.hxx
index 0a4c65d..5501672 100644
--- a/sc/source/filter/inc/excrecds.hxx
+++ b/sc/source/filter/inc/excrecds.hxx
@@ -365,6 +365,7 @@ private:
    FilterType              meType;
    sal_uInt16              nCol;
    sal_uInt16              nFlags;
    bool                    bHasBlankValue;
    ExcFilterCondition      aCond[ 2 ];
    std::vector<std::pair<OUString, bool>> maMultiValues; // first->values, second->bDateFormat