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 +++++++++- 4 files changed, 70 insertions(+), 8 deletions(-)
New commits: commit 12b76270cecfebe90eeb991f4046b2925236a4b5 Author: offtkp <parisop...@gmail.com> AuthorDate: Fri Nov 25 15:16:53 2022 +0200 Commit: Tomaž Vajngerl <qui...@gmail.com> CommitDate: Sat Jan 7 12:07:53 2023 +0000 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> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/144328 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> diff --git a/sc/source/filter/excel/excrecds.cxx b/sc/source/filter/excel/excrecds.cxx index 570167b8014b..14ff3aff85b7 100644 --- a/sc/source/filter/excel/excrecds.cxx +++ b/sc/source/filter/excel/excrecds.cxx @@ -48,6 +48,8 @@ #include <xcl97rec.hxx> #include <tabprotection.hxx> +#include <scitems.hxx> +#include <attrib.hxx> using namespace ::oox; @@ -604,11 +606,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 ) { @@ -819,10 +822,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) @@ -912,6 +918,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 ); } @@ -972,6 +980,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++ ) @@ -981,7 +991,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); @@ -995,6 +1009,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 788be95615c1..2cf03d3aa92f 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 fc2ecb22030e..2bc869287e0d 100644 --- a/sc/source/filter/oox/autofilterbuffer.cxx +++ b/sc/source/filter/oox/autofilterbuffer.cxx @@ -658,6 +658,11 @@ ApiFilterSettings FilterColumn::finalizeImport() return aSettings; } +bool FilterColumn::isButtonHidden() +{ + return (mbShowButton == false) || (mbHiddenButton == true); +} + // SortCondition SortCondition::SortCondition( const WorkbookHelper& rHelper ) : @@ -745,6 +750,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 ) { @@ -752,6 +762,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 @@ -840,7 +857,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(),