sc/inc/typedstrdata.hxx | 10 +++++ sc/qa/uitest/autofilter/autofilterBugs.py | 24 +++++++++++++ sc/source/core/data/documen3.cxx | 2 + sc/source/core/tool/typedstrdata.cxx | 54 +++++++++++++++++++++++++++--- 4 files changed, 86 insertions(+), 4 deletions(-)
New commits: commit bacf30464c601663c7c58020e7bf230cd3661768 Author: Andreas Heinisch <andreas.heini...@yahoo.de> AuthorDate: Tue Nov 28 18:24:52 2023 +0100 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Thu Feb 8 13:32:09 2024 +0100 tdf#158326 - Auto Filter: separate sorting and removing of duplicates Change-Id: Ide74895508af280f4b0c129689d852635e62dbff Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160052 Tested-by: Jenkins Reviewed-by: Andreas Heinisch <andreas.heini...@yahoo.de> (cherry picked from commit 6d0fddb697fd619d11da3469f4dd72782334f3bb) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162891 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sc/inc/typedstrdata.hxx b/sc/inc/typedstrdata.hxx index b4a9bc5d37c6..b6bed2dfc249 100644 --- a/sc/inc/typedstrdata.hxx +++ b/sc/inc/typedstrdata.hxx @@ -54,11 +54,21 @@ public: bool operator() (const ScTypedStrData& left, const ScTypedStrData& right) const; }; + struct LessSortCaseSensitive + { + bool operator() (const ScTypedStrData& left, const ScTypedStrData& right) const; + }; + struct LessCaseInsensitive { bool operator() (const ScTypedStrData& left, const ScTypedStrData& right) const; }; + struct LessSortCaseInsensitive + { + bool operator() (const ScTypedStrData& left, const ScTypedStrData& right) const; + }; + struct EqualCaseSensitive { bool operator() (const ScTypedStrData& left, const ScTypedStrData& right) const; diff --git a/sc/qa/uitest/autofilter/autofilterBugs.py b/sc/qa/uitest/autofilter/autofilterBugs.py index 6fa029985fcc..849351861d7f 100644 --- a/sc/qa/uitest/autofilter/autofilterBugs.py +++ b/sc/qa/uitest/autofilter/autofilterBugs.py @@ -73,6 +73,30 @@ class autofilter(UITestCase): self.assertEqual(get_state_as_dict(xTreeList.getChild("4"))["Text"], "vröude") self.assertEqual(get_state_as_dict(xTreeList.getChild("5"))["Text"], "vröudᵉ") + def test_tdf158326(self): + with self.ui_test.create_doc_in_start_center("calc"): + calcDoc = self.xUITest.getTopFocusWindow() + xGridWindow = calcDoc.getChild("grid_window") + enter_text_to_cell(xGridWindow, "A1", "vröude") + enter_text_to_cell(xGridWindow, "A2", "vröudᵉ") + enter_text_to_cell(xGridWindow, "A3", "vröude") + enter_text_to_cell(xGridWindow, "A4", "vröudᵉ") + enter_text_to_cell(xGridWindow, "A5", "vröude") + enter_text_to_cell(xGridWindow, "A6", "vröudᵉ") + xGridWindow.executeAction("SELECT", mkPropertyValues({"RANGE": "A1:A6"})) + + with self.ui_test.execute_dialog_through_command(".uno:DataFilterAutoFilter", close_button="no"): + pass + + xGridWindow.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"})) + xFloatWindow = self.xUITest.getFloatWindow() + xTreeList = xFloatWindow.getChild("check_list_box") + + # Without the fix in place, there would be 5 items since they will not be removed + self.assertEqual(2, len(xTreeList.getChildren())) + self.assertEqual(get_state_as_dict(xTreeList.getChild("0"))["Text"], "vröude") + self.assertEqual(get_state_as_dict(xTreeList.getChild("1"))["Text"], "vröudᵉ") + def test_tdf94055(self): with self.ui_test.create_doc_in_start_center("calc") as document: calcDoc = self.xUITest.getTopFocusWindow() diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index b42a8d36b582..8ae4ff6c4e87 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -89,6 +89,7 @@ void sortAndRemoveDuplicates(std::vector<ScTypedStrData>& rStrings, bool bCaseSe std::vector<ScTypedStrData>::iterator it = std::unique(rStrings.begin(), rStrings.end(), ScTypedStrData::EqualCaseSensitive()); rStrings.erase(it, rStrings.end()); + std::stable_sort(rStrings.begin(), rStrings.end(), ScTypedStrData::LessSortCaseSensitive()); } else { @@ -96,6 +97,7 @@ void sortAndRemoveDuplicates(std::vector<ScTypedStrData>& rStrings, bool bCaseSe std::vector<ScTypedStrData>::iterator it = std::unique(rStrings.begin(), rStrings.end(), ScTypedStrData::EqualCaseInsensitive()); rStrings.erase(it, rStrings.end()); + std::stable_sort(rStrings.begin(), rStrings.end(), ScTypedStrData::LessSortCaseInsensitive()); } if (std::any_of(rStrings.begin(), rStrings.end(), [](ScTypedStrData& rString) { return rString.IsHiddenByFilter(); })) { diff --git a/sc/source/core/tool/typedstrdata.cxx b/sc/source/core/tool/typedstrdata.cxx index e00c1bc18d91..4e3f862ae3a4 100644 --- a/sc/source/core/tool/typedstrdata.cxx +++ b/sc/source/core/tool/typedstrdata.cxx @@ -34,8 +34,31 @@ bool ScTypedStrData::LessCaseSensitive::operator() (const ScTypedStrData& left, if (left.mbIsDate != right.mbIsDate) return left.mbIsDate < right.mbIsDate; - sal_Int32 nEqual = ScGlobal::GetCaseCollator().compareString( - left.maStrValue, right.maStrValue); + sal_Int32 nEqual + = ScGlobal::GetCaseTransliteration().compareString(left.maStrValue, right.maStrValue); + + if (!nEqual) + return left.mbIsHiddenByFilter < right.mbIsHiddenByFilter; + + return nEqual < 0; +} + +bool ScTypedStrData::LessSortCaseSensitive::operator() (const ScTypedStrData& left, const ScTypedStrData& right) const +{ + if (left.meStrType != right.meStrType) + return left.meStrType < right.meStrType; + + if (left.meStrType == Value) + { + if (left.mfValue == right.mfValue) + return left.mbIsHiddenByFilter < right.mbIsHiddenByFilter; + return left.mfValue < right.mfValue; + } + + if (left.mbIsDate != right.mbIsDate) + return left.mbIsDate < right.mbIsDate; + + sal_Int32 nEqual = ScGlobal::GetCaseCollator().compareString(left.maStrValue, right.maStrValue); if (!nEqual) return left.mbIsHiddenByFilter < right.mbIsHiddenByFilter; @@ -58,8 +81,31 @@ bool ScTypedStrData::LessCaseInsensitive::operator() (const ScTypedStrData& left if (left.mbIsDate != right.mbIsDate) return left.mbIsDate < right.mbIsDate; - sal_Int32 nEqual = ScGlobal::GetCollator().compareString( - left.maStrValue, right.maStrValue); + sal_Int32 nEqual + = ScGlobal::GetTransliteration().compareString(left.maStrValue, right.maStrValue); + + if (!nEqual) + return left.mbIsHiddenByFilter < right.mbIsHiddenByFilter; + + return nEqual < 0; +} + +bool ScTypedStrData::LessSortCaseInsensitive::operator() (const ScTypedStrData& left, const ScTypedStrData& right) const +{ + if (left.meStrType != right.meStrType) + return left.meStrType < right.meStrType; + + if (left.meStrType == Value) + { + if (left.mfValue == right.mfValue) + return left.mbIsHiddenByFilter < right.mbIsHiddenByFilter; + return left.mfValue < right.mfValue; + } + + if (left.mbIsDate != right.mbIsDate) + return left.mbIsDate < right.mbIsDate; + + sal_Int32 nEqual = ScGlobal::GetCaseCollator().compareString(left.maStrValue, right.maStrValue); if (!nEqual) return left.mbIsHiddenByFilter < right.mbIsHiddenByFilter;