summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBalazs Varga <balazs.varga991@gmail.com>2021-03-11 14:44:49 +0100
committerLászló Németh <nemeth@numbertext.org>2021-03-25 15:00:31 +0100
commit4fd1333ba4bb4f2311e9098291154772bd310429 (patch)
treec5130c75d9f5c41854c32870ad6166586cff7b11
parent8940975262a98dc1087712e366f595289ac650b3 (diff)
tdf#140968 tdf#140978 XLSX import: fix lost rounded filters
if the stored filter values are in the visible cell format (e.g. rounded values) instead of the original (editing) values. Now AutoFilter popup window shows the items according to the visible cell format (e.g. 1.0 instead of 1.01 or 0.99), but still grouping them based on the "editing format" (e.g. not rounded values which visible during editing), i.e. there could be repeated values in the filtering conditions (e.g. two options "1.0" and "1.0" for 1.01 and 0.99). Note: Next step will be to group and filter based on the actual cell format, like MSO does, to simplify filtering of values rounded by the cell format (e.g. selecting the single AutoFilter condition "1.0" to filter both 1.01 and 0.99). Change-Id: I430da5e09794fc4ed8acf79b6485926f46b70277 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/112343 Tested-by: Jenkins Reviewed-by: László Németh <nemeth@numbertext.org>
-rw-r--r--include/svl/zforlist.hxx7
-rw-r--r--sc/inc/cellform.hxx2
-rw-r--r--sc/inc/column.hxx5
-rw-r--r--sc/inc/queryentry.hxx3
-rw-r--r--sc/inc/table.hxx2
-rw-r--r--sc/qa/uitest/autofilter/autofilter.py15
-rw-r--r--sc/qa/uitest/data/autofilter/time_value.xlsxbin0 -> 11303 bytes
-rw-r--r--sc/source/core/data/column.cxx3
-rw-r--r--sc/source/core/data/column3.cxx5
-rw-r--r--sc/source/core/data/documen3.cxx2
-rw-r--r--sc/source/core/data/table3.cxx13
-rw-r--r--sc/source/core/tool/cellform.cxx4
-rw-r--r--sc/source/core/tool/queryentry.cxx2
-rw-r--r--sc/source/ui/unoobj/datauno.cxx14
-rw-r--r--sc/source/ui/view/gridwin.cxx28
-rw-r--r--svl/source/numbers/zforlist.cxx6
16 files changed, 79 insertions, 32 deletions
diff --git a/include/svl/zforlist.hxx b/include/svl/zforlist.hxx
index fe148e978466..7a8703873460 100644
--- a/include/svl/zforlist.hxx
+++ b/include/svl/zforlist.hxx
@@ -560,9 +560,12 @@ public:
OUString& sOutString, const Color** ppColor, bool bUseStarFormat = false );
/** Format a number according to the standard default format matching
- the given format index */
+ the given format index. rOutString will be the real cell string (e.g.
+ a number rounded by the cell format, which rounded value is used
+ in the filtering condition now), instead of the EditFormat string
+ (e.g a not rounded value, which is visible during editing).*/
void GetInputLineString( const double& fOutNumber,
- sal_uInt32 nFIndex, OUString& rOutString );
+ sal_uInt32 nFIndex, OUString& rOutString, bool bFiltering = false );
/** Format a number according to a format code string to be scanned.
@return
diff --git a/sc/inc/cellform.hxx b/sc/inc/cellform.hxx
index afda8feea89a..02ea8b6e6347 100644
--- a/sc/inc/cellform.hxx
+++ b/sc/inc/cellform.hxx
@@ -44,7 +44,7 @@ public:
static void GetInputString(
const ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString, SvNumberFormatter& rFormatter,
- const ScDocument& rDoc );
+ const ScDocument& rDoc, bool bFiltering = false );
static OUString GetOutputString(
ScDocument& rDoc, const ScAddress& rPos, const ScRefCellValue& rCell );
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 1395d7ec7825..4f88f556e9eb 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -134,6 +134,8 @@ class ScColumn
SCCOL nCol;
SCTAB nTab;
+ bool mbFiltering; // it is true if there is a filtering in the column
+
friend class ScDocument; // for FillInfo
friend class ScTable;
friend class ScValueIterator;
@@ -181,6 +183,7 @@ public:
ScDocument& GetDoc() const { return pAttrArray->GetDoc(); }
SCTAB GetTab() const { return nTab; }
SCCOL GetCol() const { return nCol; }
+ bool HasFiltering() const { return mbFiltering; }
sc::CellStoreType& GetCellStore() { return maCells; }
const sc::CellStoreType& GetCellStore() const { return maCells; }
sc::CellTextAttrStoreType& GetCellAttrStore() { return maCellTextAttrs; }
@@ -534,7 +537,7 @@ public:
void GetFilterEntries(
sc::ColumnBlockConstPosition& rBlockPos, SCROW nStartRow, SCROW nEndRow,
- ScFilterEntries& rFilterEntries );
+ ScFilterEntries& rFilterEntries, bool bFiltering );
bool GetDataEntries( SCROW nRow, std::set<ScTypedStrData>& rStrings, bool bLimit ) const;
diff --git a/sc/inc/queryentry.hxx b/sc/inc/queryentry.hxx
index f00fb238dba2..ff6a6aff4f06 100644
--- a/sc/inc/queryentry.hxx
+++ b/sc/inc/queryentry.hxx
@@ -39,8 +39,9 @@ struct SC_DLLPUBLIC ScQueryEntry
double mfVal;
svl::SharedString maString;
bool mbMatchEmpty;
+ bool mbFormattedValue;
- Item() : meType(ByValue), mfVal(0.0), mbMatchEmpty(false) {}
+ Item() : meType(ByValue), mfVal(0.0), mbMatchEmpty(false), mbFormattedValue(false) {}
bool operator== (const Item& r) const;
};
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index e4602f5188d6..ddc859715b8e 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -953,7 +953,7 @@ public:
bool CreateQueryParam(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, ScQueryParam& rQueryParam);
void GetFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, ScFilterEntries& rFilterEntries );
- void GetFilteredFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, ScFilterEntries& rFilterEntries );
+ void GetFilteredFilterEntries(SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, ScFilterEntries& rFilterEntries, bool bFiltering );
[[nodiscard]]
bool GetDataEntries(SCCOL nCol, SCROW nRow, std::set<ScTypedStrData>& rStrings, bool bLimit);
diff --git a/sc/qa/uitest/autofilter/autofilter.py b/sc/qa/uitest/autofilter/autofilter.py
index 2c4f36947929..5d0a7036d314 100644
--- a/sc/qa/uitest/autofilter/autofilter.py
+++ b/sc/qa/uitest/autofilter/autofilter.py
@@ -324,4 +324,19 @@ class AutofilterTest(UITestCase):
xOkBtn.executeAction("CLICK", tuple())
self.ui_test.close_doc()
+
+ def test_time_value(self):
+ doc = self.ui_test.load_file(get_url_for_data_file("time_value.xlsx"))
+
+ xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
+
+ 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(2, len(xTreeList.getChildren()))
+ xOkBtn = xFloatWindow.getChild("cancel")
+ xOkBtn.executeAction("CLICK", tuple())
+
+ self.ui_test.close_doc()
# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sc/qa/uitest/data/autofilter/time_value.xlsx b/sc/qa/uitest/data/autofilter/time_value.xlsx
new file mode 100644
index 000000000000..4dc6cf85eb2e
--- /dev/null
+++ b/sc/qa/uitest/data/autofilter/time_value.xlsx
Binary files differ
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 791352304533..cf8231d4eca7 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -85,7 +85,8 @@ ScColumn::ScColumn(ScSheetLimits const & rSheetLimits) :
maCells(maCellsEvent),
mnBlkCountFormula(0),
nCol( 0 ),
- nTab( 0 )
+ nTab( 0 ),
+ mbFiltering( false )
{
maCells.resize(rSheetLimits.GetMaxRowCount());
}
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 2285a859d75b..924a8f18e839 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2420,7 +2420,7 @@ class FilterEntriesHandler
SvNumberFormatter* pFormatter = mrColumn.GetDoc().GetFormatTable();
OUString aStr;
sal_uLong nFormat = mrColumn.GetNumberFormat(mrColumn.GetDoc().GetNonThreadedContext(), nRow);
- ScCellFormat::GetInputString(rCell, nFormat, aStr, *pFormatter, mrColumn.GetDoc());
+ ScCellFormat::GetInputString(rCell, nFormat, aStr, *pFormatter, mrColumn.GetDoc(), mrColumn.HasFiltering());
if (rCell.hasString())
{
@@ -2532,8 +2532,9 @@ public:
void ScColumn::GetFilterEntries(
sc::ColumnBlockConstPosition& rBlockPos, SCROW nStartRow, SCROW nEndRow,
- ScFilterEntries& rFilterEntries )
+ ScFilterEntries& rFilterEntries, bool bFiltering )
{
+ mbFiltering = bFiltering;
FilterEntriesHandler aFunc(*this, rFilterEntries);
rBlockPos.miCellPos =
sc::ParseAll(rBlockPos.miCellPos, maCells, nStartRow, nEndRow, aFunc, aFunc);
diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx
index f7dfad201bd2..798fa467948b 100644
--- a/sc/source/core/data/documen3.cxx
+++ b/sc/source/core/data/documen3.cxx
@@ -1581,7 +1581,7 @@ void ScDocument::GetFilterEntries(
if ( bFilter )
{
- maTabs[nTab]->GetFilteredFilterEntries( nCol, nStartRow, nEndRow, aParam, rFilterEntries );
+ maTabs[nTab]->GetFilteredFilterEntries( nCol, nStartRow, nEndRow, aParam, rFilterEntries, bFilter );
}
else
{
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index fe2c2785d8f4..58a0594f63b8 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -2418,7 +2418,7 @@ public:
}
std::pair<bool,bool> compareByString(
- ScRefCellValue& rCell, SCROW nRow, const ScQueryEntry& rEntry, const ScQueryEntry::Item& rItem,
+ const ScRefCellValue& rCell, SCROW nRow, const ScQueryEntry& rEntry, const ScQueryEntry::Item& rItem,
const ScInterpreterContext* pContext)
{
if (!rCell.isEmpty())
@@ -2439,7 +2439,7 @@ public:
mrTab.GetNumberFormat( static_cast<SCCOL>(rEntry.nField), nRow );
OUString aStr;
SvNumberFormatter* pFormatter = pContext ? pContext->GetFormatTable() : mrDoc.GetFormatTable();
- ScCellFormat::GetInputString(rCell, nFormat, aStr, *pFormatter, mrDoc);
+ ScCellFormat::GetInputString(rCell, nFormat, aStr, *pFormatter, mrDoc, rEntry.bDoQuery);
return compareByStringComparator(rEntry, rItem, nullptr, &aStr);
}
}
@@ -3016,6 +3016,9 @@ public:
if (rItem.meType != ScQueryEntry::ByString && rItem.meType != ScQueryEntry::ByDate)
return;
+ if (rItem.mbFormattedValue)
+ return;
+
sal_uInt32 nIndex = 0;
bool bNumber = mrDoc.GetFormatTable()->
IsNumberFormat(rItem.maString.getString(), nIndex, rItem.mfVal);
@@ -3507,11 +3510,11 @@ void ScTable::GetFilterEntries( SCCOL nCol, SCROW nRow1, SCROW nRow2, ScFilterEn
{
sc::ColumnBlockConstPosition aBlockPos;
aCol[nCol].InitBlockPosition(aBlockPos);
- aCol[nCol].GetFilterEntries(aBlockPos, nRow1, nRow2, rFilterEntries);
+ aCol[nCol].GetFilterEntries(aBlockPos, nRow1, nRow2, rFilterEntries, false);
}
void ScTable::GetFilteredFilterEntries(
- SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, ScFilterEntries& rFilterEntries )
+ SCCOL nCol, SCROW nRow1, SCROW nRow2, const ScQueryParam& rParam, ScFilterEntries& rFilterEntries, bool bFiltering )
{
sc::ColumnBlockConstPosition aBlockPos;
aCol[nCol].InitBlockPosition(aBlockPos);
@@ -3525,7 +3528,7 @@ void ScTable::GetFilteredFilterEntries(
{
if (ValidQuery(j, aParam))
{
- aCol[nCol].GetFilterEntries(aBlockPos, j, j, rFilterEntries);
+ aCol[nCol].GetFilterEntries(aBlockPos, j, j, rFilterEntries, bFiltering);
}
}
}
diff --git a/sc/source/core/tool/cellform.cxx b/sc/source/core/tool/cellform.cxx
index 0f2daec655b1..c61207d60678 100644
--- a/sc/source/core/tool/cellform.cxx
+++ b/sc/source/core/tool/cellform.cxx
@@ -116,7 +116,7 @@ OUString ScCellFormat::GetString(
}
void ScCellFormat::GetInputString(
- const ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString, SvNumberFormatter& rFormatter, const ScDocument& rDoc )
+ const ScRefCellValue& rCell, sal_uInt32 nFormat, OUString& rString, SvNumberFormatter& rFormatter, const ScDocument& rDoc, bool bFiltering )
{
switch (rCell.meType)
{
@@ -125,7 +125,7 @@ void ScCellFormat::GetInputString(
rString = rCell.getString(&rDoc);
break;
case CELLTYPE_VALUE:
- rFormatter.GetInputLineString(rCell.mfValue, nFormat, rString );
+ rFormatter.GetInputLineString(rCell.mfValue, nFormat, rString, bFiltering);
break;
case CELLTYPE_FORMULA:
{
diff --git a/sc/source/core/tool/queryentry.cxx b/sc/source/core/tool/queryentry.cxx
index 6ebcf0003e9b..465bbd805e03 100644
--- a/sc/source/core/tool/queryentry.cxx
+++ b/sc/source/core/tool/queryentry.cxx
@@ -32,7 +32,7 @@
bool ScQueryEntry::Item::operator== (const Item& r) const
{
- return meType == r.meType && mfVal == r.mfVal && maString == r.maString && mbMatchEmpty == r.mbMatchEmpty;
+ return meType == r.meType && mfVal == r.mfVal && maString == r.maString && mbMatchEmpty == r.mbMatchEmpty && mbFormattedValue == r.mbFormattedValue;
}
ScQueryEntry::ScQueryEntry() :
diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
index af6f493934bd..f5b910d2f5b0 100644
--- a/sc/source/ui/unoobj/datauno.cxx
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -1128,7 +1128,19 @@ void fillQueryParam(
aItem.mfVal = rVal.NumericValue;
aItem.maString = rPool.intern(rVal.StringValue);
- if (aItem.meType == ScQueryEntry::ByValue)
+ if (aItem.meType == ScQueryEntry::ByString)
+ {
+ sal_uInt32 nIndex = 0;
+ aItem.mbFormattedValue = true;
+ bool bNumber = pDoc->GetFormatTable()->IsNumberFormat(rVal.StringValue, nIndex, aItem.mfVal);
+ if (bNumber)
+ {
+ OUString aStr;
+ pDoc->GetFormatTable()->GetInputLineString(aItem.mfVal, nIndex, aStr);
+ aItem.maString = rPool.intern(aStr);
+ }
+ }
+ else if (aItem.meType == ScQueryEntry::ByValue)
{
OUString aStr;
pDoc->GetFormatTable()->GetInputLineString(aItem.mfVal, 0, aStr);
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index de77ce84cb57..e9f0fde3f4df 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -544,14 +544,18 @@ public:
class AddSelectedItemString
{
- std::unordered_set<OUString>& mrSet;
+ std::unordered_set<OUString>& mrSetString;
+ std::unordered_set<double>& mrSetValue;
public:
- explicit AddSelectedItemString(std::unordered_set<OUString>& r) :
- mrSet(r) {}
+ explicit AddSelectedItemString(std::unordered_set<OUString>& rString, std::unordered_set<double>& rValue) :
+ mrSetString(rString), mrSetValue(rValue) {}
void operator() (const ScQueryEntry::Item& rItem)
{
- mrSet.insert(rItem.maString.getString());
+ if( rItem.meType == ScQueryEntry::QueryType::ByValue )
+ mrSetValue.insert(rItem.mfVal);
+ else
+ mrSetString.insert(rItem.maString.getString());
}
};
@@ -659,13 +663,14 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
ScQueryParam aParam;
pDBData->GetQueryParam(aParam);
std::vector<ScQueryEntry*> aEntries = aParam.FindAllEntriesByField(nCol);
- std::unordered_set<OUString> aSelected;
+ std::unordered_set<OUString> aSelectedString;
+ std::unordered_set<double> aSelectedValue;
for (ScQueryEntry* pEntry : aEntries)
{
if (pEntry && pEntry->bDoQuery && pEntry->eOp == SC_EQUAL)
{
ScQueryEntry::QueryItemsType& rItems = pEntry->GetQueryItems();
- std::for_each(rItems.begin(), rItems.end(), AddSelectedItemString(aSelected));
+ std::for_each(rItems.begin(), rItems.end(), AddSelectedItemString(aSelectedString, aSelectedValue));
}
}
@@ -673,14 +678,15 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
rControl.setMemberSize(aFilterEntries.size());
for (const auto& rEntry : aFilterEntries)
{
- const OUString& aVal = rEntry.GetString();
+ const OUString& aStringVal = rEntry.GetString();
+ const double aDoubleVal = rEntry.GetValue();
bool bSelected = true;
- if (!aSelected.empty())
- bSelected = aSelected.count(aVal) > 0;
+ if (!aSelectedValue.empty() || !aSelectedString.empty())
+ bSelected = aSelectedValue.count(aDoubleVal) > 0 || aSelectedString.count(aStringVal) > 0;
if ( rEntry.IsDate() )
- rControl.addDateMember( aVal, rEntry.GetValue(), bSelected );
+ rControl.addDateMember( aStringVal, rEntry.GetValue(), bSelected );
else
- rControl.addMember(aVal, bSelected);
+ rControl.addMember(aStringVal, bSelected);
}
// Populate the menu.
diff --git a/svl/source/numbers/zforlist.cxx b/svl/source/numbers/zforlist.cxx
index 0ccc14b7ff04..f1c45e04bec2 100644
--- a/svl/source/numbers/zforlist.cxx
+++ b/svl/source/numbers/zforlist.cxx
@@ -1589,7 +1589,8 @@ sal_uInt32 SvNumberFormatter::GetEditFormat( double fNumber, sal_uInt32 nFIndex,
void SvNumberFormatter::GetInputLineString(const double& fOutNumber,
sal_uInt32 nFIndex,
- OUString& sOutString)
+ OUString& sOutString,
+ bool bFiltering)
{
::osl::MutexGuard aGuard( GetInstanceMutex() );
const Color* pColor;
@@ -1630,7 +1631,8 @@ void SvNumberFormatter::GetInputLineString(const double& fOutNumber,
}
sal_uInt32 nKey = GetEditFormat( fOutNumber, nRealKey, eType, eLang, pFormat);
- if ( nKey != nRealKey )
+ // if bFiltering true keep the nRealKey format
+ if ( nKey != nRealKey && !bFiltering )
{
pFormat = GetFormatEntry( nKey );
}