tdf#140745 sc AutoFilter: fix placing of "(empty)"

Show entry "(empty)" on top of the checkbox list
in the Autofilter dropdown (instead of between the
numerical and string values).

Change-Id: I5b6d339d07b886bd52d24c7d900b53c6f921c2ec
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116439
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sc/qa/uitest/autofilter/autofilter.py b/sc/qa/uitest/autofilter/autofilter.py
index 70c6b3c..060ada7 100644
--- a/sc/qa/uitest/autofilter/autofilter.py
+++ b/sc/qa/uitest/autofilter/autofilter.py
@@ -409,7 +409,14 @@ class AutofilterTest(UITestCase):
        xFloatWindow = self.xUITest.getFloatWindow()
        xCheckListMenu = xFloatWindow.getChild("check_list_menu")
        xList = xCheckListMenu.getChild("check_list_box")
        xEntry = xList.getChild("2")

        # tdf140745 show (empty) entry on top of the checkbox list
        self.assertEqual(3, len(xList.getChildren()))
        self.assertEqual("(empty)", get_state_as_dict(xList.getChild('0'))['Text'])
        self.assertEqual("0", get_state_as_dict(xList.getChild('1'))['Text'])
        self.assertEqual("1", get_state_as_dict(xList.getChild('2'))['Text'])

        xEntry = xList.getChild("0")
        xEntry.executeAction("CLICK", tuple())

        xOkButton = xFloatWindow.getChild("ok")
@@ -424,9 +431,9 @@ class AutofilterTest(UITestCase):
        xCheckListMenu = xFloatWindow.getChild("check_list_menu")
        xList = xCheckListMenu.getChild("check_list_box")
        self.assertEqual(3, len(xList.getChildren()))
        self.assertEqual('true', get_state_as_dict(xList.getChild('0'))['IsChecked'])
        self.assertEqual('false', get_state_as_dict(xList.getChild('0'))['IsChecked'])
        self.assertEqual('true', get_state_as_dict(xList.getChild('1'))['IsChecked'])
        self.assertEqual('false', get_state_as_dict(xList.getChild('2'))['IsChecked'])
        self.assertEqual('true', get_state_as_dict(xList.getChild('2'))['IsChecked'])
        xCloseButton = xFloatWindow.getChild("cancel")
        xCloseButton.executeAction("CLICK", tuple())

diff --git a/sc/qa/uitest/autofilter/autofilterBugs.py b/sc/qa/uitest/autofilter/autofilterBugs.py
index 9eb45d8..fabde9a 100644
--- a/sc/qa/uitest/autofilter/autofilterBugs.py
+++ b/sc/qa/uitest/autofilter/autofilterBugs.py
@@ -220,15 +220,15 @@ class autofilter(UITestCase):
        x8Entry = xTreeList.getChild("7")
        x9Entry = xTreeList.getChild("8")

        self.assertEqual(get_state_as_dict(x1Entry)["Text"], "0")
        self.assertEqual(get_state_as_dict(x2Entry)["Text"], "0.1")
        self.assertEqual(get_state_as_dict(x3Entry)["Text"], "0.2")
        self.assertEqual(get_state_as_dict(x4Entry)["Text"], "0.3")
        self.assertEqual(get_state_as_dict(x5Entry)["Text"], "0.5")
        self.assertEqual(get_state_as_dict(x6Entry)["Text"], "0.8")
        self.assertEqual(get_state_as_dict(x7Entry)["Text"], "0.9")
        self.assertEqual(get_state_as_dict(x8Entry)["Text"], "1")
        self.assertEqual(get_state_as_dict(x9Entry)["Text"], "(empty)")
        self.assertEqual(get_state_as_dict(x1Entry)["Text"], "(empty)")
        self.assertEqual(get_state_as_dict(x2Entry)["Text"], "0")
        self.assertEqual(get_state_as_dict(x3Entry)["Text"], "0.1")
        self.assertEqual(get_state_as_dict(x4Entry)["Text"], "0.2")
        self.assertEqual(get_state_as_dict(x5Entry)["Text"], "0.3")
        self.assertEqual(get_state_as_dict(x6Entry)["Text"], "0.5")
        self.assertEqual(get_state_as_dict(x7Entry)["Text"], "0.8")
        self.assertEqual(get_state_as_dict(x8Entry)["Text"], "0.9")
        self.assertEqual(get_state_as_dict(x9Entry)["Text"], "1")
        self.assertEqual(get_state_as_dict(xTreeList)["Children"], "9")

        xCancel = xFloatWindow.getChild("cancel")
diff --git a/sc/qa/uitest/autofilter/tdf68113.py b/sc/qa/uitest/autofilter/tdf68113.py
index dd21166..f62ac9c 100644
--- a/sc/qa/uitest/autofilter/tdf68113.py
+++ b/sc/qa/uitest/autofilter/tdf68113.py
@@ -44,9 +44,9 @@ class tdf68113(UITestCase):
        xCheckListMenu = xFloatWindow.getChild("check_list_menu")
        xTreeList = xCheckListMenu.getChild("check_list_box")
        self.assertEqual(5, len(xTreeList.getChildren()))
        self.assertEqual('false', get_state_as_dict(xTreeList.getChild('0'))['IsChecked'])
        self.assertEqual('true', get_state_as_dict(xTreeList.getChild('0'))['IsChecked'])
        self.assertEqual('false', get_state_as_dict(xTreeList.getChild('2'))['IsChecked'])
        self.assertEqual('true', get_state_as_dict(xTreeList.getChild('4'))['IsChecked'])
        self.assertEqual('false', get_state_as_dict(xTreeList.getChild('4'))['IsChecked'])
        xCancelBtn = xFloatWindow.getChild("cancel")
        xCancelBtn.executeAction("CLICK", tuple())

@@ -66,9 +66,9 @@ class tdf68113(UITestCase):
        xCheckListMenu = xFloatWindow.getChild("check_list_menu")
        xTreeList = xCheckListMenu.getChild("check_list_box")
        self.assertEqual(5, len(xTreeList.getChildren()))
        self.assertEqual('true', get_state_as_dict(xTreeList.getChild('0'))['IsChecked'])
        self.assertEqual('false', get_state_as_dict(xTreeList.getChild('0'))['IsChecked'])
        self.assertEqual('true', get_state_as_dict(xTreeList.getChild('2'))['IsChecked'])
        self.assertEqual('false', get_state_as_dict(xTreeList.getChild('4'))['IsChecked'])
        self.assertEqual('true', get_state_as_dict(xTreeList.getChild('4'))['IsChecked'])
        xCancelBtn = xFloatWindow.getChild("cancel")
        xCancelBtn.executeAction("CLICK", tuple())

diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index ca1dd4d..bc4d100 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -683,22 +683,31 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)

    // Populate the check box list.
    rControl.setMemberSize(aFilterEntries.size());
    for (auto it = aFilterEntries.begin(); it != aFilterEntries.end(); ++it)
    {
        // tdf#140745 show (empty) entry on top of the checkbox list
        if (it->GetString().isEmpty())
        {
            const OUString& aStringVal = it->GetString();
            const double aDoubleVal = it->GetValue();
            bool bSelected = true;
            if (!aSelectedValue.empty() || !aSelectedString.empty())
                bSelected = aSelectedString.count(aStringVal) > 0;
            else if (bQueryByNonEmpty)
                bSelected = false;
            rControl.addMember(aStringVal, aDoubleVal, bSelected, false, it->IsDuplicated());
            aFilterEntries.maStrData.erase(it);
            break;
        }
    }
    for (const auto& rEntry : aFilterEntries)
    {
        const OUString& aStringVal = rEntry.GetString();
        const double aDoubleVal = rEntry.GetValue();
        bool bSelected = true;
        if (!aSelectedValue.empty() || !aSelectedString.empty())
        {
            if (aStringVal.isEmpty())
                bSelected = aSelectedString.count(aStringVal) > 0;
            else
                bSelected
                    = aSelectedValue.count(aDoubleVal) > 0 || aSelectedString.count(aStringVal) > 0;
        }
        else if (bQueryByNonEmpty)
            bSelected = !aStringVal.isEmpty();

            bSelected
                = aSelectedValue.count(aDoubleVal) > 0 || aSelectedString.count(aStringVal) > 0;
        if ( rEntry.IsDate() )
            rControl.addDateMember( aStringVal, rEntry.GetValue(), bSelected );
        else