sc/inc/filterentries.hxx              |    7 +
 sc/qa/uitest/autofilter2/tdf159420.py |  126 ++++++++++++++++++++++++++++++++++
 sc/source/core/data/column3.cxx       |   17 +++-
 3 files changed, 145 insertions(+), 5 deletions(-)

New commits:
commit 0ddfc1c31b7d9d2a3977e0e9cbf59b9dcf2044ee
Author:     Xisco Fauli <xiscofa...@libreoffice.org>
AuthorDate: Tue Jan 30 13:57:18 2024 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Thu Feb 29 15:47:53 2024 +0100

    tdf#159420: Show empty option even if empty is filtered out
    
    in other columns
    
    Regression from 89e032e9c4c51f52680c7d8bacf59ab2a34f2180
    "tdf#158314: show Empty and Error entries as non-selected and inactive...
    ...when hidden by autofilter."
    
    The mbHasEmpties variable was added in
    9c1826d98065c30411cbf2e731560165ca2b7668
    "sc-perf: do not add a million empty filter entries just to sort and
    discard"
    
    Change-Id: Ie0d81fd57f68038fac62cb6a3442e93ed547167a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162752
    Tested-by: Jenkins
    Reviewed-by: Kevin Suo <suokunl...@126.com>
    (cherry picked from commit 98b4ba33a0a698e738db46d5916063de6e74fb96)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164120

diff --git a/sc/inc/filterentries.hxx b/sc/inc/filterentries.hxx
index 02110c879b03..1ec3f22a324b 100644
--- a/sc/inc/filterentries.hxx
+++ b/sc/inc/filterentries.hxx
@@ -18,11 +18,14 @@ struct ScFilterEntries
 {
     std::vector<ScTypedStrData> maStrData;
     bool                        mbHasDates;
-    bool                        mbHasEmpties;
+    bool                        mbHasHiddenEmpties;
+    bool                        mbHasUnHiddenEmpties;
     std::set<Color>             maTextColors;
     std::set<Color>             maBackgroundColors;
 
-    ScFilterEntries() : mbHasDates(false), mbHasEmpties(false) {}
+    ScFilterEntries() : mbHasDates(false),
+                        mbHasHiddenEmpties(false),
+                        mbHasUnHiddenEmpties(false) {}
 
     std::vector<ScTypedStrData>::iterator       begin()         { return 
maStrData.begin(); }
     std::vector<ScTypedStrData>::iterator       end()           { return 
maStrData.end(); }
diff --git a/sc/qa/uitest/autofilter2/tdf159420.py 
b/sc/qa/uitest/autofilter2/tdf159420.py
new file mode 100644
index 000000000000..87ee159d2223
--- /dev/null
+++ b/sc/qa/uitest/autofilter2/tdf159420.py
@@ -0,0 +1,126 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+from uitest.framework import UITestCase
+from uitest.uihelper.calc import enter_text_to_cell
+from uitest.uihelper.common import get_state_as_dict
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from libreoffice.calc.document import is_row_hidden
+
+class tdf159420(UITestCase):
+
+    def testTdf159420(self):
+        with self.ui_test.create_doc_in_start_center("calc") as calcDoc:
+            xCalcDoc = self.xUITest.getTopFocusWindow()
+            xGridWin = xCalcDoc.getChild("grid_window")
+
+            # Fill the sheet with test data
+            enter_text_to_cell(xGridWin, "A1", "a")
+            enter_text_to_cell(xGridWin, "A2", "2")
+            enter_text_to_cell(xGridWin, "A3", "2")
+            enter_text_to_cell(xGridWin, "A4", "2")
+            enter_text_to_cell(xGridWin, "A5", "4")
+
+            enter_text_to_cell(xGridWin, "B1", "b")
+            enter_text_to_cell(xGridWin, "B2", "")
+            enter_text_to_cell(xGridWin, "B3", "")
+            enter_text_to_cell(xGridWin, "B4", "8")
+            enter_text_to_cell(xGridWin, "B5", "8")
+
+            enter_text_to_cell(xGridWin, "C1", "c")
+
+            # Select the data range and set autofilter
+            xGridWin.executeAction("SELECT", mkPropertyValues({"RANGE": 
"A1:C5"}))
+            self.xUITest.executeCommand(".uno:DataFilterAutoFilter")
+
+            # Click the autofilter dropdown in column A
+            xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": 
"", "COL": "0", "ROW": "0"}))
+            xFloatWindow = self.xUITest.getFloatWindow()
+            xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
+            xTreeList = xCheckListMenu.getChild("check_list_box")
+
+            self.assertEqual(2, len(xTreeList.getChildren()))
+
+            xEntry1 = xTreeList.getChild(0)
+            self.assertEqual("2", get_state_as_dict(xEntry1)['Text'])
+            self.assertEqual("true", get_state_as_dict(xEntry1)['IsChecked'])
+            self.assertEqual("false", 
get_state_as_dict(xEntry1)['IsSemiTransparent'])
+
+            xEntry2 = xTreeList.getChild(1)
+            self.assertEqual("4", get_state_as_dict(xEntry2)['Text'])
+            self.assertEqual("true", get_state_as_dict(xEntry2)['IsChecked'])
+            self.assertEqual("false", 
get_state_as_dict(xEntry2)['IsSemiTransparent'])
+
+            #  Uncheck the second entry
+            xEntry2.executeAction("CLICK", tuple())
+
+            xOkButton = xFloatWindow.getChild("ok")
+            xOkButton.executeAction("CLICK", tuple())
+
+            # Check that only row#2 is visible
+            self.assertFalse(is_row_hidden(calcDoc, 1))
+            self.assertFalse(is_row_hidden(calcDoc, 2))
+            self.assertFalse(is_row_hidden(calcDoc, 3))
+            self.assertTrue(is_row_hidden(calcDoc, 4))
+
+            # Click the autofilter dropdown in column B
+            xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": 
"", "COL": "1", "ROW": "0"}))
+            xFloatWindow = self.xUITest.getFloatWindow()
+            xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
+            xTreeList = xCheckListMenu.getChild("check_list_box")
+
+            self.assertEqual(2, len(xTreeList.getChildren()))
+
+            xEntry1 = xTreeList.getChild(0)
+            self.assertEqual("(empty)", get_state_as_dict(xEntry1)['Text'])
+            self.assertEqual("true", get_state_as_dict(xEntry1)['IsChecked'])
+            self.assertEqual("false", 
get_state_as_dict(xEntry1)['IsSemiTransparent'])
+
+            xEntry2 = xTreeList.getChild(1)
+            self.assertEqual("8", get_state_as_dict(xEntry2)['Text'])
+            self.assertEqual("true", get_state_as_dict(xEntry2)['IsChecked'])
+            self.assertEqual("false", 
get_state_as_dict(xEntry2)['IsSemiTransparent'])
+
+            #  Uncheck the first entry
+            xEntry1.executeAction("CLICK", tuple())
+
+            # Close the popup window
+            xOkButton = xFloatWindow.getChild("ok")
+            xOkButton.executeAction("CLICK", tuple())
+
+            self.assertTrue(is_row_hidden(calcDoc, 1))
+            self.assertTrue(is_row_hidden(calcDoc, 2))
+            self.assertFalse(is_row_hidden(calcDoc, 3))
+            self.assertTrue(is_row_hidden(calcDoc, 4))
+
+            # Click the autofilter dropdown in column C
+            xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": 
"", "COL": "2", "ROW": "0"}))
+            xFloatWindow = self.xUITest.getFloatWindow()
+            xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
+            xTreeList = xCheckListMenu.getChild("check_list_box")
+
+            self.assertEqual(1, len(xTreeList.getChildren()))
+
+            xEntry1 = xTreeList.getChild(0)
+            self.assertEqual("(empty)", get_state_as_dict(xEntry1)['Text'])
+
+            # Without the fix in place, this test would have failed with
+            # AssertionError: 'true' != 'false'
+            self.assertEqual("true", get_state_as_dict(xEntry1)['IsChecked'])
+            self.assertEqual("false", 
get_state_as_dict(xEntry1)['IsSemiTransparent'])
+
+            # Close the popup window
+            xOkButton = xFloatWindow.getChild("ok")
+            xOkButton.executeAction("CLICK", tuple())
+
+            self.assertTrue(is_row_hidden(calcDoc, 1))
+            self.assertTrue(is_row_hidden(calcDoc, 2))
+            self.assertFalse(is_row_hidden(calcDoc, 3))
+            self.assertTrue(is_row_hidden(calcDoc, 4))
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index 79027226387e..f0f4cc83263b 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -2582,10 +2582,21 @@ class FilterEntriesHandler
 
         if (bIsEmptyCell)
         {
-            if (!mrFilterEntries.mbHasEmpties)
+            if (mbFilteredRow)
             {
-                mrFilterEntries.push_back(ScTypedStrData(OUString(), 0.0, 0.0, 
ScTypedStrData::Standard, false, mbFilteredRow));
-                mrFilterEntries.mbHasEmpties = true;
+                if (!mrFilterEntries.mbHasHiddenEmpties)
+                {
+                    mrFilterEntries.push_back(ScTypedStrData(OUString(), 0.0, 
0.0, ScTypedStrData::Standard, false, true));
+                    mrFilterEntries.mbHasHiddenEmpties = true;
+                }
+            }
+            else
+            {
+                if (!mrFilterEntries.mbHasUnHiddenEmpties)
+                {
+                    mrFilterEntries.push_back(ScTypedStrData(OUString(), 0.0, 
0.0, ScTypedStrData::Standard, false, false));
+                    mrFilterEntries.mbHasUnHiddenEmpties = true;
+                }
             }
             return;
         }

Reply via email to