diff options
author | offtkp <parisoplop@gmail.com> | 2022-11-25 15:16:53 +0200 |
---|---|---|
committer | Tomaž Vajngerl <quikee@gmail.com> | 2022-12-01 13:05:54 +0100 |
commit | 2942fdc8dbda375622d0add8c36df2d6679e321a (patch) | |
tree | 06fc7fe7a7ef00af4c9b40d0100cde1a18266b6e | |
parent | 85fc28d328d7e53e6f263ac6d4ccbbf19d4db3c0 (diff) |
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 <quikee@gmail.com>
-rw-r--r-- | sc/qa/unit/data/xlsx/hiddenButton.xlsx | bin | 0 -> 9692 bytes | |||
-rw-r--r-- | sc/qa/unit/subsequent_export_test2.cxx | 15 | ||||
-rw-r--r-- | sc/source/filter/excel/excrecds.cxx | 54 | ||||
-rw-r--r-- | sc/source/filter/inc/autofilterbuffer.hxx | 1 | ||||
-rw-r--r-- | sc/source/filter/inc/excrecds.hxx | 5 | ||||
-rw-r--r-- | sc/source/filter/oox/autofilterbuffer.cxx | 18 |
6 files changed, 85 insertions, 8 deletions
diff --git a/sc/qa/unit/data/xlsx/hiddenButton.xlsx b/sc/qa/unit/data/xlsx/hiddenButton.xlsx Binary files differnew file mode 100644 index 000000000000..20019f4d181b --- /dev/null +++ b/sc/qa/unit/data/xlsx/hiddenButton.xlsx 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(), |