sc/qa/unit/data/xlsx/hiddenButton.xlsx    |binary
 sc/qa/unit/subsequent_export_test2.cxx    |   15 ++++++++
 sc/source/filter/excel/excrecds.cxx       |   54 ++++++++++++++++++++++++++----
 sc/source/filter/inc/autofilterbuffer.hxx |    1 
 sc/source/filter/inc/excrecds.hxx         |    5 ++
 sc/source/filter/oox/autofilterbuffer.cxx |   18 +++++++++-
 6 files changed, 85 insertions(+), 8 deletions(-)

New commits:
commit 2942fdc8dbda375622d0add8c36df2d6679e321a
Author:     offtkp <parisop...@gmail.com>
AuthorDate: Fri Nov 25 15:16:53 2022 +0200
Commit:     Tomaž Vajngerl <qui...@gmail.com>
CommitDate: Thu Dec 1 13:05:54 2022 +0100

    tdf#144786 Implement XML_hiddenButton functionality
    
    Now hides autofilter button when there's an XML_hiddenButton=true
    or a XML_showButton=false attribute
    
    Change-Id: I911ef23fb5e4feff8c7de0ec154bff871a29f2e8
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143300
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>

diff --git a/sc/qa/unit/data/xlsx/hiddenButton.xlsx 
b/sc/qa/unit/data/xlsx/hiddenButton.xlsx
new file mode 100644
index 000000000000..20019f4d181b
Binary files /dev/null and b/sc/qa/unit/data/xlsx/hiddenButton.xlsx differ
diff --git a/sc/qa/unit/subsequent_export_test2.cxx 
b/sc/qa/unit/subsequent_export_test2.cxx
index 628401167d5a..77b033d042a3 100644
--- a/sc/qa/unit/subsequent_export_test2.cxx
+++ b/sc/qa/unit/subsequent_export_test2.cxx
@@ -189,6 +189,7 @@ public:
     void testTdf148820();
     void testEmbeddedTextInDecimal();
     void testTotalsRowFunction();
+    void testAutofilterHiddenButton();
 
     CPPUNIT_TEST_SUITE(ScExportTest2);
 
@@ -315,6 +316,7 @@ public:
     CPPUNIT_TEST(testTdf148820);
     CPPUNIT_TEST(testEmbeddedTextInDecimal);
     CPPUNIT_TEST(testTotalsRowFunction);
+    CPPUNIT_TEST(testAutofilterHiddenButton);
 
     CPPUNIT_TEST_SUITE_END();
 };
@@ -2849,6 +2851,19 @@ void ScExportTest2::testTotalsRowFunction()
     }
 }
 
+void ScExportTest2::testAutofilterHiddenButton()
+{
+    createScDoc("xlsx/hiddenButton.xlsx");
+    saveAndReload("Calc Office Open XML");
+    xmlDocUniquePtr pDocXml = parseExport("xl/tables/table1.xml");
+    CPPUNIT_ASSERT(pDocXml);
+    for (int i = 1; i <= 5; i++)
+    {
+        auto sPath = "/x:table/x:autoFilter/x:filterColumn[" + 
std::to_string(i) + "]";
+        assertXPath(pDocXml, sPath.c_str(), "hiddenButton", "1");
+    }
+}
+
 CPPUNIT_TEST_SUITE_REGISTRATION(ScExportTest2);
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sc/source/filter/excel/excrecds.cxx 
b/sc/source/filter/excel/excrecds.cxx
index b175445bc388..3feac86be5a2 100644
--- a/sc/source/filter/excel/excrecds.cxx
+++ b/sc/source/filter/excel/excrecds.cxx
@@ -47,6 +47,8 @@
 
 #include <xcl97rec.hxx>
 #include <tabprotection.hxx>
+#include <scitems.hxx>
+#include <attrib.hxx>
 
 using namespace ::oox;
 
@@ -603,11 +605,12 @@ void ExcFilterCondition::SaveText( XclExpStream& rStrm )
     }
 }
 
-XclExpAutofilter::XclExpAutofilter( const XclExpRoot& rRoot, sal_uInt16 nC ) :
+XclExpAutofilter::XclExpAutofilter( const XclExpRoot& rRoot, sal_uInt16 nC, 
bool bIsEmpty ) :
     XclExpRecord( EXC_ID_AUTOFILTER, 24 ),
     XclExpRoot( rRoot ),
-    meType(FilterCondition),
+    meType(bIsEmpty ? Empty : FilterCondition),
     nCol( nC ),
+    bIsButtonHidden( false ),
     nFlags( 0 ),
     bHasBlankValue( false )
 {
@@ -818,10 +821,13 @@ void XclExpAutofilter::SaveXml( XclExpXmlStream& rStrm )
 
     sax_fastparser::FSHelperPtr& rWorksheet = rStrm.GetCurrentStream();
 
+    std::optional<OString> sHiddenButtonValue;
+    if (bIsButtonHidden)
+        sHiddenButtonValue = "1";
+
     rWorksheet->startElement( XML_filterColumn,
-            XML_colId, OString::number(nCol)
-            // OOXTODO: XML_hiddenButton,   AutoFilter12 fHideArrow?
-            // OOXTODO: XML_showButton
+            XML_colId, OString::number(nCol),
+            XML_hiddenButton, sHiddenButtonValue
     );
 
     switch (meType)
@@ -911,6 +917,8 @@ void XclExpAutofilter::SaveXml( XclExpXmlStream& rStrm )
             rWorksheet->endElement(XML_filters);
         }
         break;
+        // Used for constructing an empty filterColumn element for exporting 
the XML_hiddenButton attribute
+        case Empty: break;
     }
     rWorksheet->endElement( XML_filterColumn );
 }
@@ -971,6 +979,8 @@ ExcAutoFilterRecs::ExcAutoFilterRecs( const XclExpRoot& 
rRoot, SCTAB nTab, const
         bool    bContLoop   = true;
         bool        bHasOr      = false;
         SCCOLROW nFirstField = aParam.GetEntry( 0 ).nField;
+        ScDocument& rDoc = rRoot.GetDoc();
+        SCROW nRow = aRange.aStart.Row();
 
         // create AUTOFILTER records for filtered columns
         for( SCSIZE nEntry = 0; !bConflict && bContLoop && (nEntry < 
aParam.GetEntryCount()); nEntry++ )
@@ -980,7 +990,11 @@ ExcAutoFilterRecs::ExcAutoFilterRecs( const XclExpRoot& 
rRoot, SCTAB nTab, const
             bContLoop = rEntry.bDoQuery;
             if( bContLoop )
             {
-                XclExpAutofilter* pFilter = GetByCol( 
static_cast<SCCOL>(rEntry.nField) - aRange.aStart.Col() );
+                SCCOL nCol = static_cast<SCCOL>( rEntry.nField ) - 
aRange.aStart.Col();
+                auto nFlag = rDoc.GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG 
)->GetValue();
+                bool bIsButtonHidden = !( nFlag & ScMF::Auto );
+                XclExpAutofilter* pFilter = GetByCol( nCol );
+                pFilter->SetButtonHidden( bIsButtonHidden );
 
                 if( nEntry > 0 )
                     bHasOr |= (rEntry.eConnect == SC_OR);
@@ -994,6 +1008,34 @@ ExcAutoFilterRecs::ExcAutoFilterRecs( const XclExpRoot& 
rRoot, SCTAB nTab, const
             }
         }
 
+        sal_uInt16 nColId = 0;
+        for ( auto nCol = aRange.aStart.Col(); nCol <= aRange.aEnd.Col(); 
nCol++, nColId++ )
+        {
+            auto nFlag = rDoc.GetAttr( nCol, nRow, nTab, ATTR_MERGE_FLAG 
)->GetValue();
+            bool bIsButtonHidden = !( nFlag & ScMF::Auto );
+            if ( bIsButtonHidden )
+            {
+                // Create filter column with hiddenButton=1 attribute if it 
doesn't exist
+                XclExpAutofilterRef xFilter;
+                bool bFilterFound = false;
+                for( size_t nPos = 0, nSize = maFilterList.GetSize(); nPos < 
nSize; ++nPos )
+                {
+                    xFilter = maFilterList.GetRecord( nPos );
+                    if( xFilter->GetCol() == static_cast<sal_uInt16>(nCol) )
+                    {
+                        bFilterFound = true;
+                        break;
+                    }
+                }
+                if ( !bFilterFound )
+                {
+                    xFilter = new XclExpAutofilter( GetRoot(), nColId, 
/*bIsEmpty*/true );
+                    xFilter->SetButtonHidden( true );
+                    maFilterList.AppendRecord( xFilter );
+                }
+            }
+        }
+
         // additional tests for conflicts
         for( size_t nPos = 0, nSize = maFilterList.GetSize(); !bConflict && 
(nPos < nSize); ++nPos )
         {
diff --git a/sc/source/filter/inc/autofilterbuffer.hxx 
b/sc/source/filter/inc/autofilterbuffer.hxx
index 6721c185f403..fad4de53bf09 100644
--- a/sc/source/filter/inc/autofilterbuffer.hxx
+++ b/sc/source/filter/inc/autofilterbuffer.hxx
@@ -197,6 +197,7 @@ public:
     /** Returns converted UNO API filter settings representing all filter
         settings of this column. */
     ApiFilterSettings   finalizeImport();
+    bool                isButtonHidden();
 
 private:
     std::shared_ptr< FilterSettingsBase >
diff --git a/sc/source/filter/inc/excrecds.hxx 
b/sc/source/filter/inc/excrecds.hxx
index 2e4885a8856d..c7ab0aa96bd2 100644
--- a/sc/source/filter/inc/excrecds.hxx
+++ b/sc/source/filter/inc/excrecds.hxx
@@ -361,6 +361,7 @@ class XclExpAutofilter : public XclExpRecord, protected 
XclExpRoot
 private:
     enum FilterType
     {
+        Empty,
         FilterCondition,
         MultiValue,
         BlankValue,
@@ -368,6 +369,7 @@ private:
     };
     FilterType              meType;
     sal_uInt16              nCol;
+    bool                    bIsButtonHidden;
     sal_uInt16              nFlags;
     bool                    bHasBlankValue;
     ExcFilterCondition      aCond[ 2 ];
@@ -380,7 +382,7 @@ private:
     virtual void            WriteBody( XclExpStream& rStrm ) override;
 
 public:
-                            XclExpAutofilter( const XclExpRoot& rRoot, 
sal_uInt16 nC );
+                            XclExpAutofilter( const XclExpRoot& rRoot, 
sal_uInt16 nC, bool bIsEmpty = false );
 
     sal_uInt16       GetCol() const          { return nCol; }
     bool             HasTop10() const        { return ::get_flag( nFlags, 
EXC_AFFLAG_TOP10 ); }
@@ -388,6 +390,7 @@ public:
     bool                    HasCondition() const;
     bool                    AddEntry( const ScQueryEntry& rEntry );
     void                    AddMultiValueEntry( const ScQueryEntry& rEntry );
+    void                    SetButtonHidden(bool bValue) { bIsButtonHidden = 
bValue; }
     void AddColorEntry( const ScQueryEntry& rEntry );
 
     virtual void            SaveXml( XclExpXmlStream& rStrm ) override;
diff --git a/sc/source/filter/oox/autofilterbuffer.cxx 
b/sc/source/filter/oox/autofilterbuffer.cxx
index 3295087d0c7d..b7f14d8a2fb2 100644
--- a/sc/source/filter/oox/autofilterbuffer.cxx
+++ b/sc/source/filter/oox/autofilterbuffer.cxx
@@ -656,6 +656,11 @@ ApiFilterSettings FilterColumn::finalizeImport()
     return aSettings;
 }
 
+bool FilterColumn::isButtonHidden()
+{
+    return (mbShowButton == false) || (mbHiddenButton == true);
+}
+
 // SortCondition
 
 SortCondition::SortCondition( const WorkbookHelper& rHelper ) :
@@ -743,6 +748,11 @@ void AutoFilter::finalizeImport( const Reference< 
XDatabaseRange >& rxDatabaseRa
         '(A1 and B1) or (B2 and C1)'. */
     bool bHasOrConnection = false;
 
+    ScDocument& rDoc = getScDocument();
+    SCCOL nCol = maRange.aStart.Col();
+    SCROW nRow = maRange.aStart.Row();
+    SCTAB nTab = maRange.aStart.Tab();
+
     // process all filter column objects, exit when 'or' connection exists
     for( const auto& rxFilterColumn : maFilterColumns )
     {
@@ -750,6 +760,13 @@ void AutoFilter::finalizeImport( const Reference< 
XDatabaseRange >& rxDatabaseRa
         ApiFilterSettings aSettings = rxFilterColumn->finalizeImport();
         ApiFilterSettings::FilterFieldVector& rColumnFields = 
aSettings.maFilterFields;
 
+        if (rxFilterColumn->isButtonHidden())
+        {
+            auto nFlag = rDoc.GetAttr(nCol, nRow, nTab, 
ATTR_MERGE_FLAG)->GetValue();
+            rDoc.ApplyAttr(nCol, nRow, nTab, ScMergeFlagAttr(nFlag & 
~ScMF::Auto));
+        }
+        nCol++;
+
         /*  Check whether mode for regular expressions is compatible with
             the global mode in obNeedsRegExp. If either one is still in
             don't-care state, all is fine. If both are set, they must be
@@ -838,7 +855,6 @@ void AutoFilter::finalizeImport( const Reference< 
XDatabaseRange >& rxDatabaseRa
         aParam.maKeyState[0].nField += nStartPos;
     }
 
-    ScDocument& rDoc = getScDocument();
     ScDBData* pDBData = rDoc.GetDBAtArea(
         nSheet,
         maRange.aStart.Col(), maRange.aStart.Row(),

Reply via email to