summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorofftkp <parisoplop@gmail.com>2022-11-25 15:16:53 +0200
committerTomaž Vajngerl <quikee@gmail.com>2022-12-01 13:05:54 +0100
commit2942fdc8dbda375622d0add8c36df2d6679e321a (patch)
tree06fc7fe7a7ef00af4c9b40d0100cde1a18266b6e
parent85fc28d328d7e53e6f263ac6d4ccbbf19d4db3c0 (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.xlsxbin0 -> 9692 bytes
-rw-r--r--sc/qa/unit/subsequent_export_test2.cxx15
-rw-r--r--sc/source/filter/excel/excrecds.cxx54
-rw-r--r--sc/source/filter/inc/autofilterbuffer.hxx1
-rw-r--r--sc/source/filter/inc/excrecds.hxx5
-rw-r--r--sc/source/filter/oox/autofilterbuffer.cxx18
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
new file mode 100644
index 000000000000..20019f4d181b
--- /dev/null
+++ b/sc/qa/unit/data/xlsx/hiddenButton.xlsx
Binary files 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(),