tdf#116818 sc,offapi,XLSX import: fix autofiltered date columns

by importing dateGroupItem.

Add property IsDateValue to com::sun::sheet::FilterFieldValue.

Note: ODS import/export and XLSX export haven't been supported, yet.

To check/show the fix manually, run the test with

$ (cd sc && make -srj8 UITest_autofilter UITEST_TEST_NAME="autofilter.AutofilterTest.test_tdf116818" SAL_USE_VCLPLUGIN=gen)

Change-Id: I033f1915c710589ff11fe97e9b39e45251976dfc
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/109233
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
This commit is contained in:
Balazs Varga
2021-01-13 16:17:30 +01:00
committed by László Németh
parent d62ad3efe3
commit 0e751d0cb8
7 changed files with 98 additions and 12 deletions

View File

@@ -29,6 +29,13 @@ struct FilterFieldValue
/** specifies a string value for the condition.
*/
string StringValue;
/** specifies whether the TableFilterFieldValue::StringValue
is a string value or a date value.
@since LibreOffice 7.2
*/
boolean IsDateValue;
};
}; }; }; };

View File

@@ -200,5 +200,36 @@ class AutofilterTest(UITestCase):
self.assertTrue(is_row_hidden(document, 1))
self.assertFalse(is_row_hidden(document, 2))
self.ui_test.close_doc()
def test_tdf116818(self):
doc = self.ui_test.load_file(get_url_for_data_file("tdf116818.xlsx"))
xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
xCheckListMenu = xFloatWindow.getChild("check_list_menu")
xTreeList = xCheckListMenu.getChild("check_tree_box")
self.assertEqual(3, len(xTreeList.getChildren()))
xOkBtn = xFloatWindow.getChild("cancel")
xOkBtn.executeAction("CLICK", tuple())
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
xCheckListMenu = xFloatWindow.getChild("check_list_menu")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(5, len(xTreeList.getChildren()))
xOkBtn = xFloatWindow.getChild("cancel")
xOkBtn.executeAction("CLICK", tuple())
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "2", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
xCheckListMenu = xFloatWindow.getChild("check_list_menu")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(3, len(xTreeList.getChildren()))
xOkBtn = xFloatWindow.getChild("cancel")
xOkBtn.executeAction("CLICK", tuple())
self.ui_test.close_doc()
# vim: set shiftwidth=4 softtabstop=4 expandtab:

Binary file not shown.

View File

@@ -48,7 +48,7 @@ struct ApiFilterSettings
void appendField( bool bAnd, sal_Int32 nOperator, double fValue );
void appendField( bool bAnd, sal_Int32 nOperator, const OUString& rValue );
void appendField( bool bAnd, const std::vector<OUString>& rValues );
void appendField( bool bAnd, const std::vector<std::pair<OUString, bool>>& rValues );
};
/** Base class for specific filter settings for a column in a filtered range.
@@ -86,7 +86,7 @@ public:
private:
std::vector< OUString > maValues;
std::vector<std::pair<OUString, bool>> maValues; // first->values, second->bDatefFormat
sal_Int32 mnCalendarType;
bool mbShowBlank;
};

View File

@@ -175,18 +175,20 @@ void ApiFilterSettings::appendField( bool bAnd, sal_Int32 nOperator, const OUStr
rFilterField.Values[0].StringValue = rValue;
}
void ApiFilterSettings::appendField( bool bAnd, const std::vector<OUString>& rValues )
void ApiFilterSettings::appendField( bool bAnd, const std::vector<std::pair<OUString, bool>>& rValues )
{
maFilterFields.emplace_back();
TableFilterField3& rFilterField = maFilterFields.back();
rFilterField.Connection = bAnd ? FilterConnection_AND : FilterConnection_OR;
rFilterField.Operator = FilterOperator2::EQUAL;
size_t n = rValues.size();
rFilterField.Values.realloc(n);
for (size_t i = 0; i < n; ++i)
rFilterField.Values.realloc(rValues.size());
size_t i = 0;
for( auto const& it : rValues )
{
rFilterField.Values[i].IsNumeric = false;
rFilterField.Values[i].StringValue = rValues[i];
rFilterField.Values[i].StringValue = it.first;
rFilterField.Values[i++].IsDateValue = it.second;
}
}
@@ -228,7 +230,36 @@ void DiscreteFilter::importAttribs( sal_Int32 nElement, const AttributeList& rAt
{
OUString aValue = rAttribs.getXString( XML_val, OUString() );
if( !aValue.isEmpty() )
maValues.push_back( aValue );
maValues.push_back( std::make_pair(aValue, false) );
}
break;
case XLS_TOKEN( dateGroupItem ):
{
OUString aDateValue;
sal_uInt16 nToken = rAttribs.getToken(XML_dateTimeGrouping, XML_day);
if( nToken == XML_year || nToken == XML_month || nToken == XML_day )
{
aDateValue = rAttribs.getString(XML_year, OUString());
if( nToken == XML_month || nToken == XML_day )
{
OUString aMonthName = rAttribs.getString(XML_month, OUString());
if( aMonthName.getLength() == 1 )
aMonthName = "0" + aMonthName;
aDateValue += "-" + aMonthName;
if( nToken == XML_day )
{
OUString aDayName = rAttribs.getString(XML_day, OUString());
if( aDayName.getLength() == 1 )
aDayName = "0" + aDayName;
aDateValue += "-" + aDayName;
}
}
}
if( !aDateValue.isEmpty() )
maValues.push_back( std::make_pair(aDateValue, true) );
}
break;
}
@@ -256,7 +287,7 @@ void DiscreteFilter::importRecord( sal_Int32 nRecId, SequenceInputStream& rStrm
{
OUString aValue = BiffHelper::readString( rStrm );
if( !aValue.isEmpty() )
maValues.push_back( aValue );
maValues.push_back( std::make_pair(aValue, false) );
}
break;
}

View File

@@ -38,7 +38,7 @@ ContextHandlerRef FilterSettingsContext::onCreateContext( sal_Int32 nElement, co
switch( getCurrentElement() )
{
case XLS_TOKEN( filters ):
if( nElement == XLS_TOKEN( filter ) ) return this;
if( nElement == XLS_TOKEN( filter ) || nElement == XLS_TOKEN( dateGroupItem )) return this;
break;
case XLS_TOKEN( customFilters ):
if( nElement == XLS_TOKEN( customFilter ) ) return this;

View File

@@ -55,6 +55,7 @@
#include <dputil.hxx>
#include <sortparam.hxx>
#include <dpobject.hxx>
#include <filterentries.hxx>
#include <comphelper/extract.hxx>
#include <cppuhelper/supportsservice.hxx>
@@ -1122,7 +1123,7 @@ void fillQueryParam(
for (const auto& rVal : rVals)
{
ScQueryEntry::Item aItem;
aItem.meType = rVal.IsNumeric ? ScQueryEntry::ByValue : ScQueryEntry::ByString;
aItem.meType = rVal.IsNumeric ? ScQueryEntry::ByValue : (rVal.IsDateValue ? ScQueryEntry::ByDate : ScQueryEntry::ByString);
aItem.mfVal = rVal.NumericValue;
aItem.maString = rPool.intern(rVal.StringValue);
@@ -1133,7 +1134,23 @@ void fillQueryParam(
aItem.maString = rPool.intern(aStr);
}
rItems.push_back(aItem);
if( aItem.meType == ScQueryEntry::ByDate && aItem.maString.getLength() < 10 )
{
ScFilterEntries aFilterEntries;
pDoc->GetFilterEntries(rEntry.nField, rParam.nRow1, rParam.nTab, aFilterEntries);
for( const auto& rFilter : aFilterEntries )
{
if( rFilter.GetString().startsWith(rVal.StringValue) )
{
aItem.maString = rPool.intern(rFilter.GetString());
rItems.push_back(aItem);
}
}
}
else
{
rItems.push_back(aItem);
}
}
}
}