summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sc/UIConfig_scalc.mk1
-rw-r--r--sc/qa/uitest/autofilter/autofilter.py48
-rw-r--r--sc/qa/uitest/autofilter2/tdf117276.py8
-rw-r--r--sc/qa/uitest/autofilter2/tdf117276_autofilter_reset.py6
-rw-r--r--sc/qa/uitest/autofilter2/tdf122260.py4
-rw-r--r--sc/qa/uitest/autofilter2/tdf140754.py4
-rw-r--r--sc/qa/uitest/autofilter2/tdf141946.py8
-rw-r--r--sc/qa/uitest/autofilter2/tdf46062.py2
-rwxr-xr-xsc/qa/uitest/autofilter2/tdf46184.py2
-rw-r--r--sc/qa/uitest/autofilter2/tdf48025.py6
-rw-r--r--sc/qa/uitest/autofilter2/tdf68113.py4
-rw-r--r--sc/qa/uitest/autofilter2/tdf97340.py2
-rw-r--r--sc/qa/uitest/calc_tests9/pivotTable.py2
-rw-r--r--sc/source/ui/cctrl/checklistmenu.cxx370
-rw-r--r--sc/source/ui/inc/checklistmenu.hxx95
-rw-r--r--sc/source/ui/inc/gridwin.hxx4
-rw-r--r--sc/source/ui/view/gridwin.cxx93
-rw-r--r--sc/source/ui/view/gridwin2.cxx45
-rw-r--r--sc/uiconfig/scalc/ui/filterdropdown.ui367
-rw-r--r--sc/uiconfig/scalc/ui/filtersubdropdown.ui79
-rw-r--r--vcl/unx/gtk3/gtkinst.cxx52
21 files changed, 693 insertions, 509 deletions
diff --git a/sc/UIConfig_scalc.mk b/sc/UIConfig_scalc.mk
index c1bd1b075926..336e1710958d 100644
--- a/sc/UIConfig_scalc.mk
+++ b/sc/UIConfig_scalc.mk
@@ -129,6 +129,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/scalc,\
sc/uiconfig/scalc/ui/filldlg \
sc/uiconfig/scalc/ui/filterlist \
sc/uiconfig/scalc/ui/filterdropdown \
+ sc/uiconfig/scalc/ui/filtersubdropdown \
sc/uiconfig/scalc/ui/footerdialog \
sc/uiconfig/scalc/ui/formatcellsdialog \
sc/uiconfig/scalc/ui/formulacalculationoptions \
diff --git a/sc/qa/uitest/autofilter/autofilter.py b/sc/qa/uitest/autofilter/autofilter.py
index 847aa8dcf8b6..eede08073388 100644
--- a/sc/qa/uitest/autofilter/autofilter.py
+++ b/sc/qa/uitest/autofilter/autofilter.py
@@ -20,7 +20,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_tree_box")
xFirstEntry = xTreeList.getChild("0")
@@ -42,7 +42,7 @@ class AutofilterTest(UITestCase):
xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "2", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
xFirstEntry = xTreeList.getChild("1")
@@ -64,7 +64,7 @@ class AutofilterTest(UITestCase):
xGridWin = self.xUITest.getTopFocusWindow().getChild("grid_window")
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "3"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
size1 = int(get_state_as_dict(xTreeList)["Size"].split('x')[0])
xOkBtn = xFloatWindow.getChild("cancel")
@@ -72,7 +72,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "2", "ROW": "3"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
size2 = int(get_state_as_dict(xTreeList)["Size"].split('x')[0])
xOkBtn = xFloatWindow.getChild("cancel")
@@ -80,7 +80,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "3", "ROW": "3"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
size3 = int(get_state_as_dict(xTreeList)["Size"].split('x')[0])
xOkBtn = xFloatWindow.getChild("cancel")
@@ -88,7 +88,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "4", "ROW": "3"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
size4 = int(get_state_as_dict(xTreeList)["Size"].split('x')[0])
@@ -107,7 +107,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_tree_box")
@@ -141,7 +141,7 @@ class AutofilterTest(UITestCase):
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
@@ -166,7 +166,7 @@ class AutofilterTest(UITestCase):
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
@@ -206,7 +206,7 @@ class AutofilterTest(UITestCase):
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
@@ -225,7 +225,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_tree_box")
self.assertEqual(3, len(xTreeList.getChildren()))
xOkBtn = xFloatWindow.getChild("cancel")
@@ -233,7 +233,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(5, len(xTreeList.getChildren()))
xOkBtn = xFloatWindow.getChild("cancel")
@@ -241,7 +241,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "2", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(3, len(xTreeList.getChildren()))
xOkBtn = xFloatWindow.getChild("cancel")
@@ -254,7 +254,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(9, len(xTreeList.getChildren()))
xOkBtn = xFloatWindow.getChild("cancel")
@@ -267,7 +267,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_tree_box")
self.assertEqual(3, len(xTreeList.getChildren()))
xOkBtn = xFloatWindow.getChild("cancel")
@@ -275,7 +275,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(3, len(xTreeList.getChildren()))
xOkBtn = xFloatWindow.getChild("cancel")
@@ -283,7 +283,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "2", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(4, len(xTreeList.getChildren()))
xOkBtn = xFloatWindow.getChild("cancel")
@@ -296,7 +296,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(3, len(xTreeList.getChildren()))
xOkBtn = xFloatWindow.getChild("cancel")
@@ -309,7 +309,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(5, len(xTreeList.getChildren()))
self.assertEqual('true', get_state_as_dict(xTreeList.getChild('0'))['IsChecked'])
@@ -322,7 +322,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(2, len(xTreeList.getChildren()))
xOkBtn = xFloatWindow.getChild("cancel")
@@ -335,7 +335,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(5, len(xTreeList.getChildren()))
self.assertEqual("0.000", get_state_as_dict(xTreeList.getChild('0'))['Text'])
@@ -383,7 +383,7 @@ class AutofilterTest(UITestCase):
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
# tdf140745 show (empty) entry on top of the checkbox list
@@ -404,7 +404,7 @@ class AutofilterTest(UITestCase):
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(3, len(xList.getChildren()))
self.assertEqual('false', get_state_as_dict(xList.getChild('0'))['IsChecked'])
@@ -512,7 +512,7 @@ class AutofilterTest(UITestCase):
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "4", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(2, len(xTreeList.getChildren()))
self.assertEqual("65.43", get_state_as_dict(xTreeList.getChild('0'))['Text'])
diff --git a/sc/qa/uitest/autofilter2/tdf117276.py b/sc/qa/uitest/autofilter2/tdf117276.py
index 2c5a44be4bd3..259ad4786592 100644
--- a/sc/qa/uitest/autofilter2/tdf117276.py
+++ b/sc/qa/uitest/autofilter2/tdf117276.py
@@ -20,7 +20,7 @@ class tdf117276(UITestCase):
# 2. open filter of column B (Fabrikat) and deselect (Citroen, Fiat, Ford, Opel, Peugeot, Renault, Tesla)
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
xCitroenEntry = xTreeList.getChild("2")
@@ -48,7 +48,7 @@ class tdf117276(UITestCase):
# 3. open filter of column I (Wert) and deselect 8000 (Values 7000 and 9000 are not shown)
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "8", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
xCitroenEntry = xTreeList.getChild("0")
@@ -64,7 +64,7 @@ class tdf117276(UITestCase):
# 4. open filter of column B and select Tesla
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
xTeslaEntry = xTreeList.getChild("4")
xTeslaEntry.executeAction("CLICK", tuple()) #Tesla
@@ -79,7 +79,7 @@ class tdf117276(UITestCase):
#(which strings to show and which to hide, when multiple filters are in used).
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "8", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
x8000Entry = xTreeList.getChild("1") # check "8000"
diff --git a/sc/qa/uitest/autofilter2/tdf117276_autofilter_reset.py b/sc/qa/uitest/autofilter2/tdf117276_autofilter_reset.py
index c2c94d69df45..f9a26c8e5468 100644
--- a/sc/qa/uitest/autofilter2/tdf117276_autofilter_reset.py
+++ b/sc/qa/uitest/autofilter2/tdf117276_autofilter_reset.py
@@ -19,7 +19,7 @@ class tdf117276_autofilter_reset(UITestCase):
self.assertIsNotNone(xFloatWindow)
# get check list
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
self.assertIsNotNone(xCheckListMenu)
xTreeList = xCheckListMenu.getChild("check_list_box")
@@ -105,7 +105,7 @@ class tdf117276_autofilter_reset(UITestCase):
# 3. open filter of column A and deselect first 3 entries (Unique a2, Unique a3, Unique a4)
xGridWindow.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
xEntry1 = xTreeList.getChild("0")
@@ -138,7 +138,7 @@ class tdf117276_autofilter_reset(UITestCase):
# 4. open filter of column B and deselect "Unique b5"
xGridWindow.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
xEntry = xTreeList.getChild("0")
diff --git a/sc/qa/uitest/autofilter2/tdf122260.py b/sc/qa/uitest/autofilter2/tdf122260.py
index fb2c905e3844..981dd6965d6c 100644
--- a/sc/qa/uitest/autofilter2/tdf122260.py
+++ b/sc/qa/uitest/autofilter2/tdf122260.py
@@ -19,7 +19,7 @@ class tdf122260(UITestCase):
self.assertIsNotNone(xFloatWindow)
# get check list
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
self.assertIsNotNone(xCheckListMenu)
xTreeList = xCheckListMenu.getChild("check_list_box")
@@ -43,7 +43,7 @@ class tdf122260(UITestCase):
self.assertIsNotNone(xFloatWindow)
# get check list
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
self.assertIsNotNone(xCheckListMenu)
xTreeList = xCheckListMenu.getChild("check_list_box")
diff --git a/sc/qa/uitest/autofilter2/tdf140754.py b/sc/qa/uitest/autofilter2/tdf140754.py
index 1e539e93c5e8..60d9ade24ff7 100644
--- a/sc/qa/uitest/autofilter2/tdf140754.py
+++ b/sc/qa/uitest/autofilter2/tdf140754.py
@@ -42,7 +42,7 @@ class tdf140754(UITestCase):
xAll = xFloatWindow.getChild("toggle_all")
xAll.executeAction("CLICK", tuple())
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(25, len(xList.getChildren()))
@@ -61,7 +61,7 @@ class tdf140754(UITestCase):
xAll = xFloatWindow.getChild("toggle_all")
xAll.executeAction("CLICK", tuple())
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(10, len(xList.getChildren()))
diff --git a/sc/qa/uitest/autofilter2/tdf141946.py b/sc/qa/uitest/autofilter2/tdf141946.py
index 4e0de348ee10..4415ec13a61b 100644
--- a/sc/qa/uitest/autofilter2/tdf141946.py
+++ b/sc/qa/uitest/autofilter2/tdf141946.py
@@ -32,7 +32,7 @@ class tdf141946(UITestCase):
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
xEntry = xList.getChild("1")
xEntry.executeAction("CLICK", tuple())
@@ -46,7 +46,7 @@ class tdf141946(UITestCase):
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(2, len(xList.getChildren()))
xCloseBtn = xFloatWindow.getChild("cancel")
@@ -54,7 +54,7 @@ class tdf141946(UITestCase):
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(1, len(xList.getChildren()))
xCloseBtn = xFloatWindow.getChild("cancel")
@@ -62,7 +62,7 @@ class tdf141946(UITestCase):
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "2", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(3, len(xList.getChildren()))
xCloseBtn = xFloatWindow.getChild("cancel")
diff --git a/sc/qa/uitest/autofilter2/tdf46062.py b/sc/qa/uitest/autofilter2/tdf46062.py
index f0d16a358c9d..4d9c7b662aef 100644
--- a/sc/qa/uitest/autofilter2/tdf46062.py
+++ b/sc/qa/uitest/autofilter2/tdf46062.py
@@ -29,7 +29,7 @@ class tdf46062(UITestCase):
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(3, len(xList.getChildren()))
diff --git a/sc/qa/uitest/autofilter2/tdf46184.py b/sc/qa/uitest/autofilter2/tdf46184.py
index 08dfc520b640..8607a202d60a 100755
--- a/sc/qa/uitest/autofilter2/tdf46184.py
+++ b/sc/qa/uitest/autofilter2/tdf46184.py
@@ -70,7 +70,7 @@ class tdf46184(UITestCase):
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
xEntry = xTreeList.getChild("1")
xEntry.executeAction("CLICK", tuple())
diff --git a/sc/qa/uitest/autofilter2/tdf48025.py b/sc/qa/uitest/autofilter2/tdf48025.py
index f5e3e7836a2a..22fdfba0d006 100644
--- a/sc/qa/uitest/autofilter2/tdf48025.py
+++ b/sc/qa/uitest/autofilter2/tdf48025.py
@@ -37,7 +37,7 @@ class tdf48025(UITestCase):
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
xEntry = xList.getChild("1")
xEntry.executeAction("CLICK", tuple())
@@ -51,7 +51,7 @@ class tdf48025(UITestCase):
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(3, len(xList.getChildren()))
xCloseBtn = xFloatWindow.getChild("cancel")
@@ -59,7 +59,7 @@ class tdf48025(UITestCase):
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "1", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(2, len(xList.getChildren()))
xCloseBtn = xFloatWindow.getChild("cancel")
diff --git a/sc/qa/uitest/autofilter2/tdf68113.py b/sc/qa/uitest/autofilter2/tdf68113.py
index e6b98db0162d..cccc8e75cf76 100644
--- a/sc/qa/uitest/autofilter2/tdf68113.py
+++ b/sc/qa/uitest/autofilter2/tdf68113.py
@@ -39,7 +39,7 @@ class tdf68113(UITestCase):
# Checkbox elements
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(5, len(xTreeList.getChildren()))
self.assertEqual('true', get_state_as_dict(xTreeList.getChild('0'))['IsChecked'])
@@ -61,7 +61,7 @@ class tdf68113(UITestCase):
# Checkbox elements
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
self.assertEqual(5, len(xTreeList.getChildren()))
self.assertEqual('false', get_state_as_dict(xTreeList.getChild('0'))['IsChecked'])
diff --git a/sc/qa/uitest/autofilter2/tdf97340.py b/sc/qa/uitest/autofilter2/tdf97340.py
index d7e7f0c2afa3..922dd809d98d 100644
--- a/sc/qa/uitest/autofilter2/tdf97340.py
+++ b/sc/qa/uitest/autofilter2/tdf97340.py
@@ -19,7 +19,7 @@ class tdf97340(UITestCase):
gridwin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_tree_box")
self.assertEqual(2, len(xTreeList.getChildren()))
self.assertEqual("2016", get_state_as_dict(xTreeList.getChild('0'))['Text'])
diff --git a/sc/qa/uitest/calc_tests9/pivotTable.py b/sc/qa/uitest/calc_tests9/pivotTable.py
index 559073ab0507..09f81fa975fe 100644
--- a/sc/qa/uitest/calc_tests9/pivotTable.py
+++ b/sc/qa/uitest/calc_tests9/pivotTable.py
@@ -76,7 +76,7 @@ class pivotTable(UITestCase):
gridwin.executeAction("LAUNCH", mkPropertyValues({"PIVOTTABLE": "", "COL": "3", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xCheckListMenu = xFloatWindow.getChild("check_list_menu")
+ xCheckListMenu = xFloatWindow.getChild("FilterDropDown")
xTreeList = xCheckListMenu.getChild("check_list_box")
xFirstEntry = xTreeList.getChild("0")
diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx
index 7dfb572d0182..05bd1cc15a0e 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -81,13 +81,6 @@ IMPL_LINK(ScCheckListMenuControl, MenuKeyInputHdl, const KeyEvent&, rKEvt, bool)
switch (rKeyCode.GetCode())
{
- case KEY_LEFT:
- {
- ScCheckListMenuWindow* pParentMenu = mxFrame->GetParentMenu();
- if (pParentMenu)
- pParentMenu->get_widget().endSubMenu(*this);
- break;
- }
case KEY_RIGHT:
{
if (mnSelectedMenu >= maMenuItems.size() || mnSelectedMenu == MENU_NOT_SELECTED)
@@ -99,7 +92,7 @@ IMPL_LINK(ScCheckListMenuControl, MenuKeyInputHdl, const KeyEvent&, rKEvt, bool)
maOpenTimer.mnMenuPos = mnSelectedMenu;
maOpenTimer.mpSubMenu = rMenu.mxSubMenuWin.get();
- launchSubMenu(true);
+ launchSubMenu();
}
}
@@ -112,7 +105,7 @@ IMPL_LINK_NOARG(ScCheckListMenuControl, SelectHdl, weld::TreeView&, void)
if (!mxMenu->get_selected(mxScratchIter.get()))
{
// reselect current item if its submenu is up and the launching item
- // became unselected
+ // became unselected by mouse moving out of the top level menu
if (mnSelectedMenu < maMenuItems.size() &&
maMenuItems[mnSelectedMenu].mxSubMenuWin &&
maMenuItems[mnSelectedMenu].mxSubMenuWin->IsVisible())
@@ -168,21 +161,14 @@ void ScCheckListMenuControl::CreateDropDown()
DrawSymbolFlags::NONE);
}
-ScCheckListMenuWindow* ScCheckListMenuControl::addSubMenuItem(const OUString& rText, bool bEnabled)
+ScListSubMenuControl* ScCheckListMenuControl::addSubMenuItem(const OUString& rText, bool bEnabled)
{
assert(mbCanHaveSubMenu);
MenuItemData aItem;
aItem.mbEnabled = bEnabled;
- vcl::Window *pContainer = mxFrame->GetWindow(GetWindowType::FirstChild);
- vcl::ILibreOfficeKitNotifier* pNotifier = nullptr;
- if (comphelper::LibreOfficeKit::isActive())
- pNotifier = SfxViewShell::Current();
-
- aItem.mxSubMenuWin.reset(VclPtr<ScCheckListMenuWindow>::Create(pContainer, mpDoc, false,
- false, -1, mxFrame.get(),
- pNotifier));
+ aItem.mxSubMenuWin.reset(new ScListSubMenuControl(mxMenu.get(), *this, mpNotifier));
maMenuItems.emplace_back(std::move(aItem));
mxMenu->show();
@@ -223,12 +209,12 @@ void ScCheckListMenuControl::handleMenuTimeout(const SubMenuItemData* pTimer)
// Close any open submenu immediately.
if (maCloseTimer.mpSubMenu)
{
- vcl::Window::GetDockingManager()->EndPopupMode(maCloseTimer.mpSubMenu);
+ maCloseTimer.mpSubMenu->EndPopupMode();
maCloseTimer.mpSubMenu = nullptr;
maCloseTimer.maTimer.Stop();
}
- launchSubMenu(false);
+ launchSubMenu();
}
else if (pTimer == &maCloseTimer)
{
@@ -237,15 +223,19 @@ void ScCheckListMenuControl::handleMenuTimeout(const SubMenuItemData* pTimer)
{
maOpenTimer.mpSubMenu = nullptr;
- vcl::Window::GetDockingManager()->EndPopupMode(maCloseTimer.mpSubMenu);
+ maCloseTimer.mpSubMenu->EndPopupMode();
maCloseTimer.mpSubMenu = nullptr;
+ // EndPopup sends a user event, and we want this focus to be set after that has done its conflicting focus-setting work
+ if (!mnAsyncPostPopdownId)
+ mnAsyncPostPopdownId = Application::PostUserEvent(LINK(this, ScCheckListMenuControl, PostPopdownHdl));
+
maOpenTimer.mnMenuPos = MENU_NOT_SELECTED;
}
}
}
-void ScCheckListMenuControl::queueLaunchSubMenu(size_t nPos, ScCheckListMenuWindow* pMenu)
+void ScCheckListMenuControl::queueLaunchSubMenu(size_t nPos, ScListSubMenuControl* pMenu)
{
if (!pMenu)
return;
@@ -253,15 +243,16 @@ void ScCheckListMenuControl::queueLaunchSubMenu(size_t nPos, ScCheckListMenuWind
// Set the submenu on launch queue.
if (maOpenTimer.mpSubMenu)
{
- if (maOpenTimer.mpSubMenu == pMenu)
+ if (maOpenTimer.mpSubMenu != pMenu)
+ {
+ // new submenu is being requested.
+ queueCloseSubMenu();
+ }
+ else
{
if (pMenu == maCloseTimer.mpSubMenu)
maCloseTimer.reset();
- return;
}
-
- // new submenu is being requested.
- queueCloseSubMenu();
}
maOpenTimer.mpSubMenu = pMenu;
@@ -295,9 +286,9 @@ sal_Int32 ScCheckListMenuControl::ExecuteMenu(weld::Menu& rMenu)
return rMenu.popup_at_rect(mxMenu.get(), GetSubMenuParentRect(), weld::Placement::End).toInt32();
}
-void ScCheckListMenuControl::launchSubMenu(bool bSetMenuPos)
+void ScCheckListMenuControl::launchSubMenu()
{
- ScCheckListMenuWindow* pSubMenu = maOpenTimer.mpSubMenu;
+ ScListSubMenuControl* pSubMenu = maOpenTimer.mpSubMenu;
if (!pSubMenu)
return;
@@ -305,16 +296,10 @@ void ScCheckListMenuControl::launchSubMenu(bool bSetMenuPos)
return;
tools::Rectangle aRect = GetSubMenuParentRect();
- ScCheckListMenuControl& rSubMenuControl = pSubMenu->get_widget();
- rSubMenuControl.StartPopupMode(aRect, FloatWinPopupFlags::Right);
- if (bSetMenuPos)
- rSubMenuControl.setSelectedMenuItem(0, false); // select menu item after the popup becomes fully visible.
+ pSubMenu->StartPopupMode(mxMenu.get(), aRect);
mxMenu->select(*mxScratchIter);
- rSubMenuControl.GrabFocus();
-
- if (comphelper::LibreOfficeKit::isActive())
- jsdialog::SendFullUpdate(pSubMenu->GetLOKWindowId(), "toggle_all");
+ pSubMenu->GrabFocus();
}
IMPL_LINK_NOARG(ScCheckListMenuControl, PostPopdownHdl, void*, void)
@@ -323,7 +308,15 @@ IMPL_LINK_NOARG(ScCheckListMenuControl, PostPopdownHdl, void*, void)
mxMenu->grab_focus();
}
-void ScCheckListMenuControl::endSubMenu(ScCheckListMenuControl& rSubMenu)
+IMPL_LINK(ScCheckListMenuControl, MouseEnterHdl, const MouseEvent&, rMEvt, bool)
+{
+ if (!rMEvt.IsEnterWindow())
+ return false;
+ selectMenuItem(MENU_NOT_SELECTED, true);
+ return false;
+}
+
+void ScCheckListMenuControl::endSubMenu(ScListSubMenuControl& rSubMenu)
{
rSubMenu.EndPopupMode();
maOpenTimer.reset();
@@ -362,15 +355,11 @@ void ScCheckListMenuControl::selectMenuItem(size_t nPos, bool bSubMenuTimer)
return;
}
- ScCheckListMenuWindow* pParentMenu = mxFrame->GetParentMenu();
- if (pParentMenu)
- pParentMenu->get_widget().setSubMenuFocused(this);
-
if (bSubMenuTimer)
{
if (maMenuItems[nPos].mxSubMenuWin)
{
- ScCheckListMenuWindow* pSubMenu = maMenuItems[nPos].mxSubMenuWin.get();
+ ScListSubMenuControl* pSubMenu = maMenuItems[nPos].mxSubMenuWin.get();
queueLaunchSubMenu(nPos, pSubMenu);
}
else
@@ -383,20 +372,18 @@ void ScCheckListMenuControl::clearSelectedMenuItem()
selectMenuItem(MENU_NOT_SELECTED, false);
}
-size_t ScCheckListMenuControl::getSubMenuPos(const ScCheckListMenuControl* pSubMenu)
+size_t ScCheckListMenuControl::getSubMenuPos(const ScListSubMenuControl* pSubMenu)
{
size_t n = maMenuItems.size();
for (size_t i = 0; i < n; ++i)
{
- if (!maMenuItems[i].mxSubMenuWin)
- continue;
- if (&maMenuItems[i].mxSubMenuWin->get_widget() == pSubMenu)
+ if (maMenuItems[i].mxSubMenuWin.get() == pSubMenu)
return i;
}
return MENU_NOT_SELECTED;
}
-void ScCheckListMenuControl::setSubMenuFocused(const ScCheckListMenuControl* pSubMenu)
+void ScCheckListMenuControl::setSubMenuFocused(const ScListSubMenuControl* pSubMenu)
{
maCloseTimer.reset();
size_t nMenuPos = getSubMenuPos(pSubMenu);
@@ -409,16 +396,14 @@ void ScCheckListMenuControl::setSubMenuFocused(const ScCheckListMenuControl* pSu
void ScCheckListMenuControl::EndPopupMode()
{
- vcl::Window::GetDockingManager()->EndPopupMode(mxFrame);
- mxFrame->EnableDocking(false);
+ mxPopover->popdown();
}
-void ScCheckListMenuControl::StartPopupMode(const tools::Rectangle& rRect, FloatWinPopupFlags eFlags)
+void ScCheckListMenuControl::StartPopupMode(weld::Widget* pParent, const tools::Rectangle& rRect)
{
- mxFrame->EnableDocking(true);
- DockingManager* pDockingManager = vcl::Window::GetDockingManager();
- pDockingManager->SetPopupModeEndHdl(mxFrame, LINK(this, ScCheckListMenuControl, PopupModeEndHdl));
- pDockingManager->StartPopupMode(mxFrame, rRect, (eFlags | FloatWinPopupFlags::GrabFocus));
+ mxPopover->connect_closed(LINK(this, ScCheckListMenuControl, PopupModeEndHdl));
+ mxPopover->popup_at_rect(pParent, rRect);
+ GrabFocus();
}
void ScCheckListMenuControl::terminateAllPopupMenus()
@@ -427,9 +412,6 @@ void ScCheckListMenuControl::terminateAllPopupMenus()
NotifyCloseLOK();
EndPopupMode();
- ScCheckListMenuWindow* pParentMenu = mxFrame->GetParentMenu();
- if (pParentMenu)
- pParentMenu->get_widget().terminateAllPopupMenus();
}
ScCheckListMenuControl::Config::Config() :
@@ -447,14 +429,18 @@ ScCheckListMember::ScCheckListMember()
{
}
-ScCheckListMenuControl::ScCheckListMenuControl(ScCheckListMenuWindow* pParent, vcl::Window* pContainer,
+// the value of border-width of FilterDropDown
+constexpr int nBorderWidth = 4;
+
+ScCheckListMenuControl::ScCheckListMenuControl(weld::Widget* pParent,
ScDocument* pDoc, bool bCanHaveSubMenu,
- bool bHasDates, int nWidth)
- : mxFrame(pParent)
- , mxBuilder(Application::CreateInterimBuilder(pContainer, "modules/scalc/ui/filterdropdown.ui", false))
- , mxContainer(mxBuilder->weld_container("FilterDropDown"))
+ bool bHasDates, int nWidth, vcl::ILibreOfficeKitNotifier* pNotifier)
+ : mxBuilder(Application::CreateBuilder(pParent, "modules/scalc/ui/filterdropdown.ui"))
+ , mxPopover(mxBuilder->weld_popover("FilterDropDown"))
+ , mxContainer(mxBuilder->weld_container("container"))
, mxMenu(mxBuilder->weld_tree_view("menu"))
, mxScratchIter(mxMenu->make_iterator())
+ , mxNonMenu(mxBuilder->weld_widget("nonmenu"))
, mxEdSearch(mxBuilder->weld_entry("search_edit"))
, mxBox(mxBuilder->weld_widget("box"))
, mxListChecks(mxBuilder->weld_tree_view("check_list_box"))
@@ -472,6 +458,7 @@ ScCheckListMenuControl::ScCheckListMenuControl(ScCheckListMenuWindow* pParent, v
, mnSelectedMenu(MENU_NOT_SELECTED)
, mpDoc(pDoc)
, mnAsyncPostPopdownId(nullptr)
+ , mpNotifier(pNotifier)
, mbHasDates(bHasDates)
, mbCanHaveSubMenu(bCanHaveSubMenu)
, maOpenTimer(this)
@@ -479,7 +466,16 @@ ScCheckListMenuControl::ScCheckListMenuControl(ScCheckListMenuWindow* pParent, v
{
mxTreeChecks->set_clicks_to_toggle(1);
mxListChecks->set_clicks_to_toggle(1);
- mxMenu->hide(); // show only when has items
+
+ mxNonMenu->connect_mouse_move(LINK(this, ScCheckListMenuControl, MouseEnterHdl));
+ mxEdSearch->connect_mouse_move(LINK(this, ScCheckListMenuControl, MouseEnterHdl));
+ mxListChecks->connect_mouse_move(LINK(this, ScCheckListMenuControl, MouseEnterHdl));
+ mxTreeChecks->connect_mouse_move(LINK(this, ScCheckListMenuControl, MouseEnterHdl));
+ mxChkToggleAll->connect_mouse_move(LINK(this, ScCheckListMenuControl, MouseEnterHdl));
+ mxBtnSelectSingle->connect_mouse_move(LINK(this, ScCheckListMenuControl, MouseEnterHdl));
+ mxBtnUnselectSingle->connect_mouse_move(LINK(this, ScCheckListMenuControl, MouseEnterHdl));
+ mxBtnOk->connect_mouse_move(LINK(this, ScCheckListMenuControl, MouseEnterHdl));
+ mxBtnCancel->connect_mouse_move(LINK(this, ScCheckListMenuControl, MouseEnterHdl));
/*
tdf#136559 If we have no dates we don't need a tree
@@ -497,12 +493,10 @@ ScCheckListMenuControl::ScCheckListMenuControl(ScCheckListMenuWindow* pParent, v
mpChecks = mxListChecks.get();
}
- bool bIsSubMenu = pParent->GetParentMenu();
-
int nChecksHeight = mxTreeChecks->get_height_rows(9);
- if (!bIsSubMenu && nWidth != -1)
+ if (nWidth != -1)
{
- mnCheckWidthReq = nWidth - mxFrame->get_border_width() * 2 - 4;
+ mnCheckWidthReq = nWidth - nBorderWidth * 2 - 4;
mxTreeChecks->set_size_request(mnCheckWidthReq, nChecksHeight);
mxListChecks->set_size_request(mnCheckWidthReq, nChecksHeight);
}
@@ -511,35 +505,28 @@ ScCheckListMenuControl::ScCheckListMenuControl(ScCheckListMenuWindow* pParent, v
// popup isn't a true dialog
mxButtonBox->sort_native_button_order();
- if (!bIsSubMenu)
- {
- mxTreeChecks->enable_toggle_buttons(weld::ColumnToggleType::Check);
- mxListChecks->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ mxTreeChecks->enable_toggle_buttons(weld::ColumnToggleType::Check);
+ mxListChecks->enable_toggle_buttons(weld::ColumnToggleType::Check);
- mxBox->show();
- mxEdSearch->show();
- mxButtonBox->show();
- }
+ mxBox->show();
+ mxEdSearch->show();
+ mxButtonBox->show();
- mxContainer->connect_focus_in(LINK(this, ScCheckListMenuControl, FocusHdl));
mxMenu->connect_row_activated(LINK(this, ScCheckListMenuControl, RowActivatedHdl));
mxMenu->connect_changed(LINK(this, ScCheckListMenuControl, SelectHdl));
mxMenu->connect_key_press(LINK(this, ScCheckListMenuControl, MenuKeyInputHdl));
- if (!bIsSubMenu)
- {
- mxBtnOk->connect_clicked(LINK(this, ScCheckListMenuControl, ButtonHdl));
- mxBtnCancel->connect_clicked(LINK(this, ScCheckListMenuControl, ButtonHdl));
- mxEdSearch->connect_changed(LINK(this, ScCheckListMenuControl, EdModifyHdl));
- mxEdSearch->connect_activate(LINK(this, ScCheckListMenuControl, EdActivateHdl));
- mxTreeChecks->connect_toggled(LINK(this, ScCheckListMenuControl, CheckHdl));
- mxTreeChecks->connect_key_press(LINK(this, ScCheckListMenuControl, KeyInputHdl));
- mxListChecks->connect_toggled(LINK(this, ScCheckListMenuControl, CheckHdl));
- mxListChecks->connect_key_press(LINK(this, ScCheckListMenuControl, KeyInputHdl));
- mxChkToggleAll->connect_toggled(LINK(this, ScCheckListMenuControl, TriStateHdl));
- mxBtnSelectSingle->connect_clicked(LINK(this, ScCheckListMenuControl, ButtonHdl));
- mxBtnUnselectSingle->connect_clicked(LINK(this, ScCheckListMenuControl, ButtonHdl));
- }
+ mxBtnOk->connect_clicked(LINK(this, ScCheckListMenuControl, ButtonHdl));
+ mxBtnCancel->connect_clicked(LINK(this, ScCheckListMenuControl, ButtonHdl));
+ mxEdSearch->connect_changed(LINK(this, ScCheckListMenuControl, EdModifyHdl));
+ mxEdSearch->connect_activate(LINK(this, ScCheckListMenuControl, EdActivateHdl));
+ mxTreeChecks->connect_toggled(LINK(this, ScCheckListMenuControl, CheckHdl));
+ mxTreeChecks->connect_key_press(LINK(this, ScCheckListMenuControl, KeyInputHdl));
+ mxListChecks->connect_toggled(LINK(this, ScCheckListMenuControl, CheckHdl));
+ mxListChecks->connect_key_press(LINK(this, ScCheckListMenuControl, KeyInputHdl));
+ mxChkToggleAll->connect_toggled(LINK(this, ScCheckListMenuControl, TriStateHdl));
+ mxBtnSelectSingle->connect_clicked(LINK(this, ScCheckListMenuControl, ButtonHdl));
+ mxBtnUnselectSingle->connect_clicked(LINK(this, ScCheckListMenuControl, ButtonHdl));
if (mbCanHaveSubMenu)
{
@@ -547,20 +534,12 @@ ScCheckListMenuControl::ScCheckListMenuControl(ScCheckListMenuWindow* pParent, v
mxMenu->connect_size_allocate(LINK(this, ScCheckListMenuControl, TreeSizeAllocHdl));
}
- if (!bIsSubMenu)
- {
- // determine what width the checklist will end up with
- mnCheckWidthReq = mxContainer->get_preferred_size().Width();
- // make that size fixed now, we can now use mnCheckWidthReq to speed up
- // bulk_insert_for_each
- mxTreeChecks->set_size_request(mnCheckWidthReq, nChecksHeight);
- mxListChecks->set_size_request(mnCheckWidthReq, nChecksHeight);
- }
-}
-
-IMPL_LINK_NOARG(ScCheckListMenuControl, FocusHdl, weld::Widget&, void)
-{
- GrabFocus();
+ // determine what width the checklist will end up with
+ mnCheckWidthReq = mxContainer->get_preferred_size().Width();
+ // make that size fixed now, we can now use mnCheckWidthReq to speed up
+ // bulk_insert_for_each
+ mxTreeChecks->set_size_request(mnCheckWidthReq, nChecksHeight);
+ mxListChecks->set_size_request(mnCheckWidthReq, nChecksHeight);
}
void ScCheckListMenuControl::GrabFocus()
@@ -578,7 +557,7 @@ ScCheckListMenuControl::~ScCheckListMenuControl()
{
EndPopupMode();
for (auto& rMenuItem : maMenuItems)
- rMenuItem.mxSubMenuWin.disposeAndClear();
+ rMenuItem.mxSubMenuWin.reset();
if (mnAsyncPostPopdownId)
{
Application::RemoveUserEvent(mnAsyncPostPopdownId);
@@ -586,51 +565,6 @@ ScCheckListMenuControl::~ScCheckListMenuControl()
}
}
-ScCheckListMenuWindow::ScCheckListMenuWindow(vcl::Window* pParent, ScDocument* pDoc, bool bCanHaveSubMenu,
- bool bTreeMode, int nWidth, ScCheckListMenuWindow* pParentMenu,
- const vcl::ILibreOfficeKitNotifier* pNotifier)
- : DropdownDockingWindow(pParent)
- , mxParentMenu(pParentMenu)
-{
- if (pNotifier)
- SetLOKNotifier(pNotifier);
- setDeferredProperties();
- mxControl.reset(new ScCheckListMenuControl(this, m_xBox.get(), pDoc, bCanHaveSubMenu, bTreeMode, nWidth));
- SetBackground(Application::GetSettings().GetStyleSettings().GetMenuColor());
- set_id("check_list_menu");
-}
-
-bool ScCheckListMenuWindow::EventNotify(NotifyEvent& rNEvt)
-{
- if (rNEvt.GetType() == MouseNotifyEvent::MOUSEMOVE)
- {
- ScCheckListMenuControl& rMenuControl = get_widget();
- rMenuControl.queueCloseSubMenu();
- rMenuControl.clearSelectedMenuItem();
- }
- return DropdownDockingWindow::EventNotify(rNEvt);
-}
-
-ScCheckListMenuWindow::~ScCheckListMenuWindow()
-{
- disposeOnce();
-}
-
-void ScCheckListMenuWindow::dispose()
-{
- mxControl.reset();
- mxParentMenu.clear();
- DropdownDockingWindow::dispose();
-}
-
-void ScCheckListMenuWindow::GetFocus()
-{
- DropdownDockingWindow::GetFocus();
- if (!mxControl)
- return;
- mxControl->GrabFocus();
-}
-
void ScCheckListMenuControl::prepWindow()
{
mxMenu->set_size_request(-1, mxMenu->get_preferred_size().Height() + 2);
@@ -641,7 +575,7 @@ void ScCheckListMenuControl::prepWindow()
mxMenu->unselect_all();
}
- mnWndWidth = mxContainer->get_preferred_size().Width() + mxFrame->get_border_width() * 2 + 4;
+ mnWndWidth = mxContainer->get_preferred_size().Width() + nBorderWidth * 2 + 4;
}
void ScCheckListMenuControl::setAllMemberState(bool bSet)
@@ -1395,7 +1329,7 @@ void ScCheckListMenuControl::getResult(ResultType& rResult)
rResult.swap(aResult);
}
-void ScCheckListMenuControl::launch(const tools::Rectangle& rRect)
+void ScCheckListMenuControl::launch(weld::Widget* pWidget, const tools::Rectangle& rRect)
{
prepWindow();
if (!maConfig.mbAllowEmptySet)
@@ -1418,24 +1352,19 @@ void ScCheckListMenuControl::launch(const tools::Rectangle& rRect)
aRect.AdjustLeft(nDiff );
}
- StartPopupMode(aRect, FloatWinPopupFlags::Down);
+ StartPopupMode(pWidget, aRect);
}
void ScCheckListMenuControl::NotifyCloseLOK()
{
- VclPtr<vcl::Window> aNotifierWindow = mxFrame->GetParentWithLOKNotifier();
- if (!aNotifierWindow)
- return;
-
- const vcl::ILibreOfficeKitNotifier* pNotifier = aNotifierWindow->GetLOKNotifier();
- if (pNotifier)
+ if (mpNotifier)
{
tools::JsonWriter aJsonWriter;
aJsonWriter.put("jsontype", "autofilter");
aJsonWriter.put("action", "close");
const std::string message = aJsonWriter.extractAsStdString();
- pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, message.c_str());
+ mpNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, message.c_str());
}
}
@@ -1469,7 +1398,7 @@ void ScCheckListMenuControl::setPopupEndAction(Action* p)
mxPopupEndAction.reset(p);
}
-IMPL_LINK_NOARG(ScCheckListMenuControl, PopupModeEndHdl, FloatingWindow*, void)
+IMPL_LINK_NOARG(ScCheckListMenuControl, PopupModeEndHdl, weld::Popover&, void)
{
clearSelectedMenuItem();
if (mxPopupEndAction)
@@ -1486,7 +1415,7 @@ int ScCheckListMenuControl::GetTextWidth(const OUString& rsName) const
int ScCheckListMenuControl::IncreaseWindowWidthToFitText(int nMaxTextWidth)
{
- int nBorder = mxFrame->get_border_width() * 2 + 4;
+ int nBorder = nBorderWidth * 2 + 4;
int nNewWidth = nMaxTextWidth - nBorder;
if (nNewWidth > mnCheckWidthReq)
{
@@ -1497,4 +1426,119 @@ int ScCheckListMenuControl::IncreaseWindowWidthToFitText(int nMaxTextWidth)
return mnCheckWidthReq + nBorder;
}
+ScListSubMenuControl::ScListSubMenuControl(weld::Widget* pParent, ScCheckListMenuControl& rParentControl, vcl::ILibreOfficeKitNotifier* pNotifier)
+ : mxBuilder(Application::CreateBuilder(pParent, "modules/scalc/ui/filtersubdropdown.ui"))
+ , mxPopover(mxBuilder->weld_popover("FilterSubDropDown"))
+ , mxContainer(mxBuilder->weld_container("container"))
+ , mxMenu(mxBuilder->weld_tree_view("menu"))
+ , mxScratchIter(mxMenu->make_iterator())
+ , mrParentControl(rParentControl)
+ , mpNotifier(pNotifier)
+{
+ mxMenu->connect_row_activated(LINK(this, ScListSubMenuControl, RowActivatedHdl));
+ mxMenu->connect_key_press(LINK(this, ScListSubMenuControl, MenuKeyInputHdl));
+}
+
+void ScListSubMenuControl::StartPopupMode(weld::Widget* pParent, const tools::Rectangle& rRect)
+{
+ mxPopover->popup_at_rect(pParent, rRect, weld::Placement::End);
+
+ mxMenu->set_cursor(0);
+ mxMenu->select(0);
+
+ mrParentControl.setSubMenuFocused(this);
+}
+
+void ScListSubMenuControl::EndPopupMode()
+{
+ mxPopover->popdown();
+}
+
+void ScListSubMenuControl::GrabFocus()
+{
+ mxMenu->grab_focus();
+}
+
+bool ScListSubMenuControl::IsVisible() const
+{
+ return mxPopover->get_visible();
+}
+
+void ScListSubMenuControl::resizeToFitMenuItems()
+{
+ mxMenu->set_size_request(-1, mxMenu->get_preferred_size().Height() + 2);
+}
+
+void ScListSubMenuControl::addMenuItem(const OUString& rText, ScCheckListMenuControl::Action* pAction)
+{
+ ScCheckListMenuControl::MenuItemData aItem;
+ aItem.mbEnabled = true;
+ aItem.mxAction.reset(pAction);
+ maMenuItems.emplace_back(std::move(aItem));
+
+ mxMenu->show();
+ mxMenu->append_text(rText);
+}
+
+IMPL_LINK(ScListSubMenuControl, MenuKeyInputHdl, const KeyEvent&, rKEvt, bool)
+{
+ bool bConsumed = false;
+ const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
+
+ switch (rKeyCode.GetCode())
+ {
+ case KEY_ESCAPE:
+ case KEY_LEFT:
+ {
+ mrParentControl.endSubMenu(*this);
+ bConsumed = true;
+ break;
+ }
+ }
+
+ return bConsumed;
+}
+
+IMPL_LINK_NOARG(ScListSubMenuControl, RowActivatedHdl, weld::TreeView&, bool)
+{
+ executeMenuItem(mxMenu->get_selected_index());
+ return true;
+}
+
+void ScListSubMenuControl::executeMenuItem(size_t nPos)
+{
+ if (nPos >= maMenuItems.size())
+ return;
+
+ if (!maMenuItems[nPos].mxAction)
+ // no action is defined.
+ return;
+
+ const bool bClosePopup = maMenuItems[nPos].mxAction->execute();
+ if (bClosePopup)
+ terminateAllPopupMenus();
+}
+
+void ScListSubMenuControl::terminateAllPopupMenus()
+{
+ if (comphelper::LibreOfficeKit::isActive())
+ NotifyCloseLOK();
+
+ EndPopupMode();
+ mrParentControl.terminateAllPopupMenus();
+}
+
+void ScListSubMenuControl::NotifyCloseLOK()
+{
+ if (mpNotifier)
+ {
+ tools::JsonWriter aJsonWriter;
+ aJsonWriter.put("jsontype", "autofilter");
+ aJsonWriter.put("action", "close");
+
+ const std::string message = aJsonWriter.extractAsStdString();
+ mpNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, message.c_str());
+ }
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/checklistmenu.hxx b/sc/source/ui/inc/checklistmenu.hxx
index c9ca6466dff7..dd398dd9f651 100644
--- a/sc/source/ui/inc/checklistmenu.hxx
+++ b/sc/source/ui/inc/checklistmenu.hxx
@@ -48,7 +48,11 @@ struct ScCheckListMember
};
class ScCheckListMenuWindow;
+class ScListSubMenuControl;
+/**
+ * This class implements a popup window for the auto filter dropdown.
+ */
class ScCheckListMenuControl final
{
public:
@@ -94,7 +98,7 @@ public:
{
bool mbEnabled:1;
std::shared_ptr<Action> mxAction;
- VclPtr<ScCheckListMenuWindow> mxSubMenuWin;
+ std::unique_ptr<ScListSubMenuControl> mxSubMenuWin;
MenuItemData();
};
@@ -119,17 +123,18 @@ public:
Config();
};
- ScCheckListMenuControl(ScCheckListMenuWindow* pParent, vcl::Window* pContainer, ScDocument* pDoc,
- bool bCanHaveSubMenu, bool bTreeMode, int nWidth);
+ ScCheckListMenuControl(weld::Widget* pParent, ScDocument* pDoc,
+ bool bCanHaveSubMenu, bool bTreeMode, int nWidth,
+ vcl::ILibreOfficeKitNotifier* pNotifier);
~ScCheckListMenuControl();
void addMenuItem(const OUString& rText, Action* pAction);
void addSeparator();
- ScCheckListMenuWindow* addSubMenuItem(const OUString& rText, bool bEnabled);
+ ScListSubMenuControl* addSubMenuItem(const OUString& rText, bool bEnabled);
void resizeToFitMenuItems();
void selectMenuItem(size_t nPos, bool bSubMenuTimer);
- void queueLaunchSubMenu(size_t nPos, ScCheckListMenuWindow* pMenu);
+ void queueLaunchSubMenu(size_t nPos, ScListSubMenuControl* pMenu);
void setMemberSize(size_t n);
void addDateMember(const OUString& rName, double nVal, bool bVisible);
@@ -140,14 +145,14 @@ public:
bool isAllSelected() const;
void getResult(ResultType& rResult);
- void launch(const tools::Rectangle& rRect);
+ void launch(weld::Widget* pWidget, const tools::Rectangle& rRect);
void close(bool bOK);
- void StartPopupMode(const tools::Rectangle& rRect, FloatWinPopupFlags eFlags);
+ void StartPopupMode(weld::Widget* pParent, const tools::Rectangle& rRect);
void EndPopupMode();
- size_t getSubMenuPos(const ScCheckListMenuControl* pSubMenu);
- void setSubMenuFocused(const ScCheckListMenuControl* pSubMenu);
+ size_t getSubMenuPos(const ScListSubMenuControl* pSubMenu);
+ void setSubMenuFocused(const ScListSubMenuControl* pSubMenu);
void queueCloseSubMenu();
void clearSelectedMenuItem();
@@ -177,12 +182,9 @@ public:
*/
void terminateAllPopupMenus();
- /**
- * Get the area of the active row. Suitable as the parent rectangle
- * argument for Executing a popup
- */
- tools::Rectangle GetSubMenuParentRect();
sal_Int32 ExecuteMenu(weld::Menu& rMenu);
+
+ void endSubMenu(ScListSubMenuControl& rSubMenu);
private:
std::vector<MenuItemData> maMenuItems;
@@ -210,13 +212,17 @@ private:
void executeMenuItem(size_t nPos);
- void endSubMenu(ScCheckListMenuControl& rSubMenu);
+ /**
+ * Get the area of the active row. Suitable as the parent rectangle
+ * argument for Executing a popup
+ */
+ tools::Rectangle GetSubMenuParentRect();
struct SubMenuItemData;
void handleMenuTimeout(const SubMenuItemData* pTimer);
- void launchSubMenu(bool bSetMenuPos);
+ void launchSubMenu();
void CreateDropDown();
@@ -229,26 +235,27 @@ private:
DECL_LINK(CheckHdl, const weld::TreeView::iter_col&, void);
- DECL_LINK(PopupModeEndHdl, FloatingWindow*, void);
+ DECL_LINK(PopupModeEndHdl, weld::Popover&, void);
DECL_LINK(EdModifyHdl, weld::Entry&, void);
DECL_LINK(EdActivateHdl, weld::Entry&, bool);
- DECL_LINK(FocusHdl, weld::Widget&, void);
DECL_LINK(RowActivatedHdl, weld::TreeView& rMEvt, bool);
DECL_LINK(SelectHdl, weld::TreeView&, void);
DECL_LINK(TreeSizeAllocHdl, const Size&, void);
DECL_LINK(KeyInputHdl, const KeyEvent&, bool);
DECL_LINK(MenuKeyInputHdl, const KeyEvent&, bool);
+ DECL_LINK(MouseEnterHdl, const MouseEvent&, bool);
DECL_LINK(PostPopdownHdl, void*, void);
private:
- VclPtr<ScCheckListMenuWindow> mxFrame;
std::unique_ptr<weld::Builder> mxBuilder;
+ std::unique_ptr<weld::Popover> mxPopover;
std::unique_ptr<weld::Container> mxContainer;
std::unique_ptr<weld::TreeView> mxMenu;
std::unique_ptr<weld::TreeIter> mxScratchIter;
+ std::unique_ptr<weld::Widget> mxNonMenu;
std::unique_ptr<weld::Entry> mxEdSearch;
std::unique_ptr<weld::Widget> mxBox;
std::unique_ptr<weld::TreeView> mxListChecks;
@@ -283,6 +290,7 @@ private:
ScDocument* mpDoc;
ImplSVEvent* mnAsyncPostPopdownId;
+ vcl::ILibreOfficeKitNotifier* mpNotifier;
bool mbHasDates;
bool mbCanHaveSubMenu;
@@ -290,7 +298,7 @@ private:
struct SubMenuItemData
{
Timer maTimer;
- VclPtr<ScCheckListMenuWindow> mpSubMenu;
+ ScListSubMenuControl* mpSubMenu;
size_t mnMenuPos;
DECL_LINK( TimeoutHdl, Timer*, void );
@@ -306,28 +314,43 @@ private:
SubMenuItemData maCloseTimer;
};
-/**
- * This class implements a popup window for the auto filter dropdown.
- */
-class ScCheckListMenuWindow : public DropdownDockingWindow
+class ScListSubMenuControl final
{
public:
- explicit ScCheckListMenuWindow(vcl::Window* pParent, ScDocument* pDoc,
- bool bCanHaveSubMenu, bool bTreeMode, int nWidth = -1,
- ScCheckListMenuWindow* pParentMenu = nullptr,
- const vcl::ILibreOfficeKitNotifier* pNotifier = nullptr);
- virtual void dispose() override;
- virtual ~ScCheckListMenuWindow() override;
+ ScListSubMenuControl(weld::Widget* pParent, ScCheckListMenuControl& rParentControl, vcl::ILibreOfficeKitNotifier* pNotifier);
+
+ void GrabFocus();
+ bool IsVisible() const;
- virtual void GetFocus() override;
- virtual bool EventNotify(NotifyEvent& rNEvt) override;
+ void StartPopupMode(weld::Widget* pParent, const tools::Rectangle& rRect);
+ void EndPopupMode();
+
+ void addMenuItem(const OUString& rText, ScCheckListMenuControl::Action* pAction);
+ void resizeToFitMenuItems();
- ScCheckListMenuWindow* GetParentMenu() { return mxParentMenu; }
- ScCheckListMenuControl& get_widget() { return *mxControl; }
+ void setSelectedMenuItem(size_t nPos);
+
+ /**
+ * Dismiss all visible popup menus and set focus back to the application
+ * window. This method is called e.g. when a menu action is fired.
+ */
+ void terminateAllPopupMenus();
private:
- VclPtr<ScCheckListMenuWindow> mxParentMenu;
- std::unique_ptr<ScCheckListMenuControl, o3tl::default_delete<ScCheckListMenuControl>> mxControl;
+ std::unique_ptr<weld::Builder> mxBuilder;
+ std::unique_ptr<weld::Popover> mxPopover;
+ std::unique_ptr<weld::Container> mxContainer;
+ std::unique_ptr<weld::TreeView> mxMenu;
+ std::unique_ptr<weld::TreeIter> mxScratchIter;
+ std::vector<ScCheckListMenuControl::MenuItemData> maMenuItems;
+ ScCheckListMenuControl& mrParentControl;
+ vcl::ILibreOfficeKitNotifier* mpNotifier;
+
+ DECL_LINK(RowActivatedHdl, weld::TreeView& rMEvt, bool);
+ DECL_LINK(MenuKeyInputHdl, const KeyEvent&, bool);
+
+ void NotifyCloseLOK();
+ void executeMenuItem(size_t nPos);
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index 0bf9fb7ce006..2f8ac0deacfc 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -152,8 +152,8 @@ class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::Window, public DropTargetHel
std::unique_ptr<ScNoteMarker, o3tl::default_delete<ScNoteMarker>> mpNoteMarker;
std::shared_ptr<ScFilterListBox> mpFilterBox;
- VclPtr<ScCheckListMenuWindow> mpAutoFilterPopup;
- VclPtr<ScCheckListMenuWindow> mpDPFieldPopup;
+ std::unique_ptr<ScCheckListMenuControl> mpAutoFilterPopup;
+ std::unique_ptr<ScCheckListMenuControl> mpDPFieldPopup;
std::unique_ptr<ScDPFieldButton> mpFilterButton;
ScCheckListMenuControl::ResultType aSaveAutoFilterResult;
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 5b203addbb12..3116dfb9ac13 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -434,8 +434,8 @@ void ScGridWindow::dispose()
mpFilterBox.reset();
mpNoteMarker.reset();
- mpAutoFilterPopup.disposeAndClear();
- mpDPFieldPopup.disposeAndClear();
+ mpAutoFilterPopup.reset();
+ mpDPFieldPopup.reset();
aComboButton.SetOutputDevice(nullptr);
if (mpSpellCheckCxt)
@@ -458,8 +458,8 @@ void ScGridWindow::ClickExtern()
if (mpDPFieldPopup)
{
- mpDPFieldPopup->get_widget().close(false);
- mpDPFieldPopup.disposeAndClear();
+ mpDPFieldPopup->close(false);
+ mpDPFieldPopup.reset();
}
}
@@ -582,7 +582,7 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
ScDocument& rDoc = mrViewData.GetDocument();
bool bLOKActive = comphelper::LibreOfficeKit::isActive();
- mpAutoFilterPopup.disposeAndClear();
+ mpAutoFilterPopup.reset();
// Estimate the width (in pixels) of the longest text in the list
ScFilterEntries aFilterEntries;
@@ -592,11 +592,10 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
if (bLOKActive)
pNotifier = SfxViewShell::Current();
+ weld::Window* pPopupParent = GetFrameWeld();
int nColWidth = ScViewData::ToPixel(rDoc.GetColWidth(nCol, nTab), mrViewData.GetPPTX());
- mpAutoFilterPopup.reset(VclPtr<ScCheckListMenuWindow>::Create(this, &rDoc, false,
- aFilterEntries.mbHasDates, nColWidth,
- nullptr, pNotifier));
- ScCheckListMenuControl& rControl = mpAutoFilterPopup->get_widget();
+ mpAutoFilterPopup.reset(new ScCheckListMenuControl(pPopupParent, &rDoc, false,
+ aFilterEntries.mbHasDates, nColWidth, pNotifier));
int nMaxTextWidth = 0;
if (aFilterEntries.size() <= 10)
@@ -605,7 +604,7 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
for (const auto& rEntry : aFilterEntries)
{
const OUString& aText = rEntry.GetString();
- nMaxTextWidth = std::max<int>(nMaxTextWidth, rControl.GetTextWidth(aText) + aText.getLength() * 2);
+ nMaxTextWidth = std::max<int>(nMaxTextWidth, mpAutoFilterPopup->GetTextWidth(aText) + aText.getLength() * 2);
}
}
else
@@ -622,17 +621,17 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
itMax = it;
}
}
- nMaxTextWidth = rControl.GetTextWidth(itMax->GetString()) + nMaxTextWidth * 2;
+ nMaxTextWidth = mpAutoFilterPopup->GetTextWidth(itMax->GetString()) + nMaxTextWidth * 2;
}
// window should be at least as wide as the column, or the longest text + checkbox, scrollbar ... (it is estimated with 70 pixel now)
// window should be maximum 1024 pixel wide.
int nWindowWidth = std::min<int>(1024, nMaxTextWidth + 70);
- nWindowWidth = rControl.IncreaseWindowWidthToFitText(nWindowWidth);
+ nWindowWidth = mpAutoFilterPopup->IncreaseWindowWidthToFitText(nWindowWidth);
nMaxTextWidth = std::max<int>(nMaxTextWidth, nWindowWidth - 70);
- rControl.setOKAction(new AutoFilterAction(this, AutoFilterMode::Normal));
- rControl.setPopupEndAction(
+ mpAutoFilterPopup->setOKAction(new AutoFilterAction(this, AutoFilterMode::Normal));
+ mpAutoFilterPopup->setPopupEndAction(
new AutoFilterPopupEndAction(this, ScAddress(nCol, nRow, nTab)));
std::unique_ptr<AutoFilterData> pData(new AutoFilterData);
pData->maPos = ScAddress(nCol, nRow, nTab);
@@ -660,7 +659,7 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
return;
pData->mpData = pDBData;
- rControl.setExtendedData(std::move(pData));
+ mpAutoFilterPopup->setExtendedData(std::move(pData));
ScQueryParam aParam;
pDBData->GetQueryParam(aParam);
@@ -682,7 +681,7 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
}
// Populate the check box list.
- rControl.setMemberSize(aFilterEntries.size());
+ mpAutoFilterPopup->setMemberSize(aFilterEntries.size());
for (auto it = aFilterEntries.begin(); it != aFilterEntries.end(); ++it)
{
// tdf#140745 show (empty) entry on top of the checkbox list
@@ -695,7 +694,7 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
bSelected = aSelectedString.count(aStringVal) > 0;
else if (bQueryByNonEmpty)
bSelected = false;
- rControl.addMember(aStringVal, aDoubleVal, bSelected);
+ mpAutoFilterPopup->addMember(aStringVal, aDoubleVal, bSelected);
aFilterEntries.maStrData.erase(it);
break;
}
@@ -716,49 +715,49 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
}
if ( rEntry.IsDate() )
- rControl.addDateMember( aStringVal, rEntry.GetValue(), bSelected );
+ mpAutoFilterPopup->addDateMember( aStringVal, rEntry.GetValue(), bSelected );
else
- rControl.addMember( aStringVal, aRDoubleVal, bSelected, rEntry.GetStringType() == ScTypedStrData::Value );
+ mpAutoFilterPopup->addMember( aStringVal, aRDoubleVal, bSelected, rEntry.GetStringType() == ScTypedStrData::Value );
}
// Populate the menu.
- rControl.addMenuItem(
+ mpAutoFilterPopup->addMenuItem(
ScResId(STR_MENU_SORT_ASC),
new AutoFilterAction(this, AutoFilterMode::SortAscending));
- rControl.addMenuItem(
+ mpAutoFilterPopup->addMenuItem(
ScResId(STR_MENU_SORT_DESC),
new AutoFilterAction(this, AutoFilterMode::SortDescending));
- rControl.addSeparator();
- rControl.addMenuItem(
+ mpAutoFilterPopup->addSeparator();
+ mpAutoFilterPopup->addMenuItem(
ScResId(SCSTR_TOP10FILTER), new AutoFilterAction(this, AutoFilterMode::Top10));
- rControl.addMenuItem(
+ mpAutoFilterPopup->addMenuItem(
ScResId(SCSTR_FILTER_EMPTY), new AutoFilterAction(this, AutoFilterMode::Empty));
- rControl.addMenuItem(
+ mpAutoFilterPopup->addMenuItem(
ScResId(SCSTR_FILTER_NOTEMPTY), new AutoFilterAction(this, AutoFilterMode::NonEmpty));
- rControl.addSeparator();
- rControl.addMenuItem(
+ mpAutoFilterPopup->addSeparator();
+ mpAutoFilterPopup->addMenuItem(
ScResId(SCSTR_FILTER_TEXT_COLOR), new AutoFilterAction(this, AutoFilterMode::TextColor));
- rControl.addMenuItem(
+ mpAutoFilterPopup->addMenuItem(
ScResId(SCSTR_FILTER_BACKGROUND_COLOR), new AutoFilterAction(this, AutoFilterMode::BackgroundColor));
- rControl.addSeparator();
- rControl.addMenuItem(
+ mpAutoFilterPopup->addSeparator();
+ mpAutoFilterPopup->addMenuItem(
ScResId(SCSTR_STDFILTER), new AutoFilterAction(this, AutoFilterMode::Custom));
if (aEntries.size())
- rControl.addMenuItem(
+ mpAutoFilterPopup->addMenuItem(
ScResId(SCSTR_CLEAR_FILTER), new AutoFilterAction(this, AutoFilterMode::Clear));
- rControl.initMembers(nMaxTextWidth + 20); // 20 pixel estimated for the checkbox
+ mpAutoFilterPopup->initMembers(nMaxTextWidth + 20); // 20 pixel estimated for the checkbox
ScCheckListMenuControl::Config aConfig;
aConfig.mbAllowEmptySet = false;
aConfig.mbRTL = mrViewData.GetDocument().IsLayoutRTL(mrViewData.GetTabNo());
- rControl.setConfig(aConfig);
+ mpAutoFilterPopup->setConfig(aConfig);
if (IsMouseCaptured())
ReleaseMouse();
- rControl.launch(aCellRect);
+ mpAutoFilterPopup->launch(pPopupParent, aCellRect);
// remember filter rules before modification
- rControl.getResult(aSaveAutoFilterResult);
+ mpAutoFilterPopup->getResult(aSaveAutoFilterResult);
collectUIInformation(OUString::number(nRow), OUString::number(nCol),"AUTOFILTER");
}
@@ -776,15 +775,13 @@ void ScGridWindow::RefreshAutoFilterButton(const ScAddress& rPos)
void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
{
- ScCheckListMenuControl& rControl = mpAutoFilterPopup->get_widget();
-
// Terminate autofilter popup now when there is no further user input needed
bool bColorMode = eMode == AutoFilterMode::TextColor || eMode == AutoFilterMode::BackgroundColor;
if (!bColorMode)
- rControl.terminateAllPopupMenus();
+ mpAutoFilterPopup->terminateAllPopupMenus();
const AutoFilterData* pData =
- static_cast<const AutoFilterData*>(rControl.getExtendedData());
+ static_cast<const AutoFilterData*>(mpAutoFilterPopup->getExtendedData());
if (!pData)
return;
@@ -848,13 +845,13 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
{
// Do not recreate autofilter rules if there are no changes from the user
ScCheckListMenuControl::ResultType aResult;
- rControl.getResult(aResult);
+ mpAutoFilterPopup->getResult(aResult);
if (aResult == aSaveAutoFilterResult)
{
SAL_INFO("sc.ui", "Apply autofilter to data when entries are the same");
- if (!rControl.isAllSelected())
+ if (!mpAutoFilterPopup->isAllSelected())
{
// Apply autofilter to data
ScQueryEntry* pEntry = aParam.FindEntryByField(rPos.Col(), true);
@@ -882,7 +879,7 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
}
if (eMode != AutoFilterMode::Clear
- && !(eMode == AutoFilterMode::Normal && rControl.isAllSelected()))
+ && !(eMode == AutoFilterMode::Normal && mpAutoFilterPopup->isAllSelected()))
{
// Try to use the existing entry for the column (if one exists).
ScQueryEntry* pEntry = aParam.FindEntryByField(rPos.Col(), true);
@@ -905,7 +902,7 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
pEntry->eOp = SC_EQUAL;
ScCheckListMenuControl::ResultType aResult;
- rControl.getResult(aResult);
+ mpAutoFilterPopup->getResult(aResult);
ScQueryEntry::QueryItemsType& rItems = pEntry->GetQueryItems();
rItems.clear();
@@ -929,8 +926,8 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
ScFilterEntries aFilterEntries;
rDoc.GetFilterEntries(rPos.Col(), rPos.Row(), rPos.Tab(), aFilterEntries);
- weld::Window* pPopupParent = mpAutoFilterPopup->GetFrameWeld();
- std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pPopupParent, "modules/scalc/ui/colormenu.ui"));
+ weld::Window* pWindow = GetFrameWeld();
+ std::unique_ptr<weld::Builder> xBuilder(Application::CreateBuilder(pWindow, "modules/scalc/ui/colormenu.ui"));
std::unique_ptr<weld::Menu> xColorMenu(xBuilder->weld_menu("menu"));
std::set<Color> aColors = eMode == AutoFilterMode::TextColor
@@ -951,7 +948,7 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
else
{
// ColorListBox::ShowPreview is similar
- ScopedVclPtr<VirtualDevice> xDev(pPopupParent->create_virtual_device());
+ ScopedVclPtr<VirtualDevice> xDev(pWindow->create_virtual_device());
const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
Size aImageSize(rStyleSettings.GetListBoxPreviewDefaultPixelSize());
xDev->SetOutputSize(aImageSize);
@@ -976,13 +973,13 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
i++;
}
- sal_Int32 nSelected = rControl.ExecuteMenu(*xColorMenu);
+ sal_Int32 nSelected = mpAutoFilterPopup->ExecuteMenu(*xColorMenu);
xColorMenu.reset();
if (nSelected == 0)
return;
- rControl.terminateAllPopupMenus();
+ mpAutoFilterPopup->terminateAllPopupMenus();
// Disable color filter when active color was selected
if (nSelected == nActive)
diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx
index db6c8c6066d3..8050310b107d 100644
--- a/sc/source/ui/view/gridwin2.cxx
+++ b/sc/source/ui/view/gridwin2.cxx
@@ -467,32 +467,31 @@ void ScGridWindow::DPLaunchFieldPopupMenu(const Point& rScrPos, const Size& rScr
const ScDPLabelData& rLabelData = pDPData->maLabels;
- mpDPFieldPopup.disposeAndClear();
+ mpDPFieldPopup.reset();
vcl::ILibreOfficeKitNotifier* pNotifier = nullptr;
if (comphelper::LibreOfficeKit::isActive())
pNotifier = SfxViewShell::Current();
- mpDPFieldPopup.reset(VclPtr<ScCheckListMenuWindow>::Create(this, &mrViewData.GetDocument(),
- bDimOrientNotPage, false, -1,
- nullptr, pNotifier));
+ weld::Window* pPopupParent = GetFrameWeld();
+ mpDPFieldPopup.reset(new ScCheckListMenuControl(pPopupParent, &mrViewData.GetDocument(),
+ bDimOrientNotPage, false, -1, pNotifier));
- ScCheckListMenuControl& rControl = mpDPFieldPopup->get_widget();
- rControl.setExtendedData(std::move(pDPData));
- rControl.setOKAction(new DPFieldPopupOKAction(this));
+ mpDPFieldPopup->setExtendedData(std::move(pDPData));
+ mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this));
{
// Populate field members.
size_t n = rLabelData.maMembers.size();
- rControl.setMemberSize(n);
+ mpDPFieldPopup->setMemberSize(n);
for (size_t i = 0; i < n; ++i)
{
const ScDPLabelData::Member& rMem = rLabelData.maMembers[i];
OUString aName = rMem.getDisplayName();
if (aName.isEmpty())
// Use special string for an empty name.
- rControl.addMember(ScResId(STR_EMPTYDATA), 0.0, rMem.mbVisible);
+ mpDPFieldPopup->addMember(ScResId(STR_EMPTYDATA), 0.0, rMem.mbVisible);
else
- rControl.addMember(rMem.getDisplayName(), 0.0, rMem.mbVisible);
+ mpDPFieldPopup->addMember(rMem.getDisplayName(), 0.0, rMem.mbVisible);
}
}
@@ -513,38 +512,36 @@ void ScGridWindow::DPLaunchFieldPopupMenu(const Point& rScrPos, const Size& rScr
// Populate the menus.
ScTabViewShell* pViewShell = mrViewData.GetViewShell();
- rControl.addMenuItem(
+ mpDPFieldPopup->addMenuItem(
ScResId(STR_MENU_SORT_ASC),
new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::ASCENDING, 0, pViewShell));
- rControl.addMenuItem(
+ mpDPFieldPopup->addMenuItem(
ScResId(STR_MENU_SORT_DESC),
new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::DESCENDING, 0, pViewShell));
- ScCheckListMenuWindow* pSubMenu = rControl.addSubMenuItem(ScResId(STR_MENU_SORT_CUSTOM), !aUserSortNames.empty());
+ ScListSubMenuControl* pSubMenu = mpDPFieldPopup->addSubMenuItem(ScResId(STR_MENU_SORT_CUSTOM), !aUserSortNames.empty());
if (pSubMenu)
{
- ScCheckListMenuControl& rSubMenu = pSubMenu->get_widget();
size_t n = aUserSortNames.size();
for (size_t i = 0; i < n; ++i)
{
- rSubMenu.addMenuItem(aUserSortNames[i],
- new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::CUSTOM, sal_uInt16(i), pViewShell));
+ pSubMenu->addMenuItem(aUserSortNames[i],
+ new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::CUSTOM, sal_uInt16(i), pViewShell));
}
- rSubMenu.resizeToFitMenuItems();
+ pSubMenu->resizeToFitMenuItems();
}
}
- rControl.initMembers();
+ mpDPFieldPopup->initMembers();
tools::Rectangle aCellRect(rScrPos, rScrSize);
-
ScCheckListMenuControl::Config aConfig;
aConfig.mbAllowEmptySet = false;
aConfig.mbRTL = mrViewData.GetDocument().IsLayoutRTL(mrViewData.GetTabNo());
- rControl.setConfig(aConfig);
+ mpDPFieldPopup->setConfig(aConfig);
if (IsMouseCaptured())
ReleaseMouse();
- rControl.launch(aCellRect);
+ mpDPFieldPopup->launch(pPopupParent, aCellRect);
}
void ScGridWindow::UpdateDPFromFieldPopupMenu()
@@ -554,9 +551,7 @@ void ScGridWindow::UpdateDPFromFieldPopupMenu()
if (!mpDPFieldPopup)
return;
- ScCheckListMenuControl& rControl = mpDPFieldPopup->get_widget();
-
- DPFieldPopupData* pDPData = static_cast<DPFieldPopupData*>(rControl.getExtendedData());
+ DPFieldPopupData* pDPData = static_cast<DPFieldPopupData*>(mpDPFieldPopup->getExtendedData());
if (!pDPData)
return;
@@ -577,7 +572,7 @@ void ScGridWindow::UpdateDPFromFieldPopupMenu()
// The raw result may contain a mixture of layout names and original names.
ScCheckListMenuControl::ResultType aRawResult;
- rControl.getResult(aRawResult);
+ mpDPFieldPopup->getResult(aRawResult);
std::unordered_map<OUString, bool> aResult;
for (const auto& rItem : aRawResult)
diff --git a/sc/uiconfig/scalc/ui/filterdropdown.ui b/sc/uiconfig/scalc/ui/filterdropdown.ui
index 17bca296d8ef..a6f025acfeaa 100644
--- a/sc/uiconfig/scalc/ui/filterdropdown.ui
+++ b/sc/uiconfig/scalc/ui/filterdropdown.ui
@@ -50,14 +50,14 @@
<column type="gboolean"/>
</columns>
</object>
- <object class="GtkBox" id="FilterDropDown">
- <property name="visible">True</property>
+ <object class="GtkPopover" id="FilterDropDown">
<property name="can-focus">False</property>
- <property name="hexpand">True</property>
- <property name="vexpand">True</property>
- <property name="orientation">vertical</property>
+ <property name="no-show-all">True</property>
+ <property name="border-width">4</property>
+ <property name="position">bottom</property>
+ <property name="constrain-to">none</property>
<child>
- <object class="GtkBox">
+ <object class="GtkBox" id="container">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="hexpand">True</property>
@@ -66,15 +66,15 @@
<property name="spacing">6</property>
<child>
<object class="GtkScrolledWindow">
- <property name="visible">True</property>
<property name="can-focus">True</property>
+ <property name="no-show-all">True</property>
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">never</property>
<property name="shadow-type">in</property>
<child>
<object class="GtkTreeView" id="menu">
- <property name="visible">True</property>
<property name="can-focus">True</property>
+ <property name="no-show-all">True</property>
<property name="model">liststore1</property>
<property name="headers-visible">False</property>
<property name="headers-clickable">False</property>
@@ -115,31 +115,20 @@
</packing>
</child>
<child>
- <object class="GtkEntry" id="search_edit">
- <property name="can-focus">True</property>
- <property name="no-show-all">True</property>
- <property name="tooltip-text" translatable="yes" context="filterdropdown|STR_EDIT_SEARCH_ITEMS">Search items...</property>
- <property name="activates-default">True</property>
- <property name="truncate-multiline">True</property>
- <property name="placeholder-text" translatable="yes" context="filterdropdown|STR_EDIT_SEARCH_ITEMS">Search items...</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox" id="box">
+ <object class="GtkBox" id="nonmenu">
+ <property name="visible">True</property>
<property name="can-focus">False</property>
- <property name="no-show-all">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
+ <property name="spacing">6</property>
<child>
- <object class="GtkSeparator">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
+ <object class="GtkEntry" id="search_edit">
+ <property name="can-focus">True</property>
+ <property name="no-show-all">True</property>
+ <property name="activates-default">True</property>
+ <property name="truncate-multiline">True</property>
+ <property name="placeholder-text" translatable="yes" context="filterdropdown|STR_EDIT_SEARCH_ITEMS">Search items...</property>
</object>
<packing>
<property name="expand">False</property>
@@ -148,20 +137,16 @@
</packing>
</child>
<child>
- <object class="GtkBox">
- <property name="visible">True</property>
+ <object class="GtkBox" id="box">
<property name="can-focus">False</property>
- <property name="border-width">3</property>
- <property name="spacing">6</property>
+ <property name="no-show-all">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
<child>
- <object class="GtkCheckButton" id="toggle_all">
- <property name="label" translatable="yes" context="filterdropdown|STR_BTN_TOGGLE_ALL">All</property>
+ <object class="GtkSeparator">
<property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">False</property>
- <property name="hexpand">True</property>
- <property name="use-underline">True</property>
- <property name="draw-indicator">True</property>
+ <property name="can-focus">False</property>
</object>
<packing>
<property name="expand">False</property>
@@ -170,13 +155,57 @@
</packing>
</child>
<child>
- <object class="GtkButton" id="select_current">
+ <object class="GtkBox">
<property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">True</property>
- <property name="tooltip-text" translatable="yes" context="filterdropdown|STR_BTN_SELECT_CURRENT">Show only the current item.</property>
- <property name="image">image1</property>
- <property name="always-show-image">True</property>
+ <property name="can-focus">False</property>
+ <property name="border-width">3</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkCheckButton" id="toggle_all">
+ <property name="label" translatable="yes" context="filterdropdown|STR_BTN_TOGGLE_ALL">All</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">False</property>
+ <property name="hexpand">True</property>
+ <property name="use-underline">True</property>
+ <property name="draw-indicator">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="select_current">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="tooltip-text" translatable="yes" context="filterdropdown|STR_BTN_SELECT_CURRENT">Show only the current item.</property>
+ <property name="image">image1</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="unselect_current">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="tooltip-text" translatable="yes" context="filterdropdown|STR_BTN_UNSELECT_CURRENT">Hide only the current item.</property>
+ <property name="image">image2</property>
+ <property name="always-show-image">True</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
</object>
<packing>
<property name="expand">False</property>
@@ -185,193 +214,173 @@
</packing>
</child>
<child>
- <object class="GtkButton" id="unselect_current">
+ <object class="GtkBox">
<property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">True</property>
- <property name="tooltip-text" translatable="yes" context="filterdropdown|STR_BTN_UNSELECT_CURRENT">Hide only the current item.</property>
- <property name="image">image2</property>
- <property name="always-show-image">True</property>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">1</property>
- </packing>
- </child>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="can-focus">False</property>
- <property name="hexpand">True</property>
- <property name="vexpand">True</property>
- <child>
- <object class="GtkScrolledWindow">
- <property name="can-focus">True</property>
+ <property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
- <property name="shadow-type">in</property>
<child>
- <object class="GtkTreeView" id="check_list_box">
+ <object class="GtkScrolledWindow">
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
- <property name="model">liststore2</property>
- <property name="headers-visible">False</property>
- <property name="headers-clickable">False</property>
- <property name="search-column">1</property>
- <property name="show-expanders">False</property>
- <child internal-child="selection">
- <object class="GtkTreeSelection"/>
- </child>
+ <property name="shadow-type">in</property>
<child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn4">
- <property name="resizable">True</property>
- <property name="spacing">6</property>
- <property name="alignment">0.5</property>
- <child>
- <object class="GtkCellRendererToggle" id="cellrenderer5"/>
- <attributes>
- <attribute name="visible">3</attribute>
- <attribute name="active">0</attribute>
- </attributes>
+ <object class="GtkTreeView" id="check_list_box">
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">liststore2</property>
+ <property name="headers-visible">False</property>
+ <property name="headers-clickable">False</property>
+ <property name="search-column">1</property>
+ <property name="show-expanders">False</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
</child>
<child>
- <object class="GtkCellRendererText" id="cellrenderer4"/>
- <attributes>
- <attribute name="text">1</attribute>
- </attributes>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn4">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer5"/>
+ <attributes>
+ <attribute name="visible">3</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer4"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
</child>
</object>
</child>
</object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
</child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkScrolledWindow">
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="hexpand">True</property>
- <property name="vexpand">True</property>
- <property name="shadow-type">in</property>
<child>
- <object class="GtkTreeView" id="check_tree_box">
+ <object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
- <property name="model">treestore2</property>
- <property name="headers-visible">False</property>
- <property name="headers-clickable">False</property>
- <property name="search-column">1</property>
- <property name="enable-tree-lines">True</property>
- <child internal-child="selection">
- <object class="GtkTreeSelection"/>
- </child>
+ <property name="shadow-type">in</property>
<child>
- <object class="GtkTreeViewColumn" id="treeviewcolumn2">
- <property name="resizable">True</property>
- <property name="spacing">6</property>
- <property name="alignment">0.5</property>
- <child>
- <object class="GtkCellRendererToggle" id="cellrenderer1"/>
- <attributes>
- <attribute name="visible">3</attribute>
- <attribute name="active">0</attribute>
- </attributes>
+ <object class="GtkTreeView" id="check_tree_box">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="model">treestore2</property>
+ <property name="headers-visible">False</property>
+ <property name="headers-clickable">False</property>
+ <property name="search-column">1</property>
+ <property name="enable-tree-lines">True</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
</child>
<child>
- <object class="GtkCellRendererText" id="cellrenderer2"/>
- <attributes>
- <attribute name="text">1</attribute>
- </attributes>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <property name="resizable">True</property>
+ <property name="spacing">6</property>
+ <property name="alignment">0.5</property>
+ <child>
+ <object class="GtkCellRendererToggle" id="cellrenderer1"/>
+ <attributes>
+ <attribute name="visible">3</attribute>
+ <attribute name="active">0</attribute>
+ </attributes>
+ </child>
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderer2"/>
+ <attributes>
+ <attribute name="text">1</attribute>
+ </attributes>
+ </child>
+ </object>
</child>
</object>
</child>
</object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- </object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkButtonBox" id="buttonbox">
- <property name="can-focus">False</property>
- <property name="no-show-all">True</property>
- <property name="spacing">6</property>
- <property name="layout-style">spread</property>
- <child>
- <object class="GtkButton" id="ok">
- <property name="label" translatable="yes" context="stock">_OK</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="can-default">True</property>
- <property name="receives-default">True</property>
- <property name="use-underline">True</property>
- </object>
- <packing>
- <property name="expand">True</property>
- <property name="fill">True</property>
- <property name="position">0</property>
+ <property name="position">1</property>
</packing>
</child>
<child>
- <object class="GtkButton" id="cancel">
- <property name="label" translatable="yes" context="stock">_Cancel</property>
- <property name="visible">True</property>
- <property name="can-focus">True</property>
- <property name="receives-default">True</property>
- <property name="use-underline">True</property>
+ <object class="GtkButtonBox" id="buttonbox">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="spacing">6</property>
+ <property name="layout-style">spread</property>
+ <child>
+ <object class="GtkButton" id="ok">
+ <property name="label" translatable="yes" context="stock">_OK</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="can-default">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkButton" id="cancel">
+ <property name="label" translatable="yes" context="stock">_Cancel</property>
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="receives-default">True</property>
+ <property name="use-underline">True</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ <property name="fill">True</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
</object>
<packing>
- <property name="expand">True</property>
+ <property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
- <property name="position">3</property>
+ <property name="position">1</property>
</packing>
</child>
</object>
- <packing>
- <property name="expand">False</property>
- <property name="fill">True</property>
- <property name="position">0</property>
- </packing>
</child>
</object>
</interface>
diff --git a/sc/uiconfig/scalc/ui/filtersubdropdown.ui b/sc/uiconfig/scalc/ui/filtersubdropdown.ui
new file mode 100644
index 000000000000..942cc4b9f75f
--- /dev/null
+++ b/sc/uiconfig/scalc/ui/filtersubdropdown.ui
@@ -0,0 +1,79 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.38.2 -->
+<interface domain="sc">
+ <requires lib="gtk+" version="3.20"/>
+ <object class="GtkTreeStore" id="liststore1">
+ <columns>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name image1 -->
+ <column type="GdkPixbuf"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ </columns>
+ </object>
+ <object class="GtkPopover" id="FilterSubDropDown">
+ <property name="can-focus">False</property>
+ <property name="no-show-all">True</property>
+ <property name="position">right</property>
+ <property name="modal">False</property>
+ <property name="constrain-to">none</property>
+ <child>
+ <object class="GtkBox" id="container">
+ <property name="visible">True</property>
+ <property name="can-focus">False</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="hscrollbar-policy">never</property>
+ <property name="vscrollbar-policy">never</property>
+ <property name="shadow-type">in</property>
+ <child>
+ <object class="GtkTreeView" id="menu">
+ <property name="visible">True</property>
+ <property name="can-focus">True</property>
+ <property name="model">liststore1</property>
+ <property name="headers-visible">False</property>
+ <property name="headers-clickable">False</property>
+ <property name="search-column">0</property>
+ <property name="hover-selection">True</property>
+ <property name="show-expanders">False</property>
+ <property name="activate-on-single-click">True</property>
+ <child internal-child="selection">
+ <object class="GtkTreeSelection"/>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn1">
+ <child>
+ <object class="GtkCellRendererText" id="cellrenderertext1"/>
+ <attributes>
+ <attribute name="text">0</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkTreeViewColumn" id="treeviewcolumn2">
+ <child>
+ <object class="GtkCellRendererPixbuf" id="cellrenderertext55"/>
+ <attributes>
+ <attribute name="pixbuf">1</attribute>
+ </attributes>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ </object>
+ </child>
+ </object>
+</interface>
diff --git a/vcl/unx/gtk3/gtkinst.cxx b/vcl/unx/gtk3/gtkinst.cxx
index 0fc8ffd9366c..0d7ff1985619 100644
--- a/vcl/unx/gtk3/gtkinst.cxx
+++ b/vcl/unx/gtk3/gtkinst.cxx
@@ -9665,6 +9665,8 @@ GtkPositionType show_menu_older_gtk(GtkWidget* pMenuButton, GtkWindow* pMenu, co
else
x += nButtonWidth;
+ gtk_window_set_attached_to(pMenu, pMenuButton);
+
gtk_window_group_add_window(gtk_window_get_group(GTK_WINDOW(pToplevel)), pMenu);
gtk_window_set_transient_for(pMenu, GTK_WINDOW(pToplevel));
@@ -9783,19 +9785,19 @@ bool show_menu_newer_gtk(GtkWidget* pComboBox, GtkWindow* pMenu, const GdkRectan
if (!window_move_to_rect)
return false;
-#if defined(GDK_WINDOWING_X11)
// under wayland gdk_window_move_to_rect works great for me, but in my current
// gtk 3.24 under X it leaves part of long menus outside the work area
GdkDisplay *pDisplay = gtk_widget_get_display(pComboBox);
if (DLSYM_GDK_IS_X11_DISPLAY(pDisplay))
return false;
-#endif
//place the toplevel just below its launcher button
GtkWidget* pToplevel = widget_get_toplevel(pComboBox);
gtk_coord x, y;
gtk_widget_translate_coordinates(pComboBox, pToplevel, rAnchor.x, rAnchor.y, &x, &y);
+ gtk_window_set_attached_to(pMenu, pComboBox);
+
gtk_widget_realize(GTK_WIDGET(pMenu));
gtk_window_group_add_window(gtk_window_get_group(GTK_WINDOW(pToplevel)), pMenu);
gtk_window_set_transient_for(pMenu, GTK_WINDOW(pToplevel));
@@ -9903,6 +9905,8 @@ GtkPositionType MovePopoverContentsToWindow(GtkWidget* pPopover, GtkWindow* pMen
GtkPositionType eRet = show_menu(pAnchor, pMenuHack, rAnchor, ePlace);
+ gtk_grab_add(GTK_WIDGET(pMenuHack));
+
GdkSurface* pSurface = widget_get_surface(GTK_WIDGET(pMenuHack));
g_object_set_data(G_OBJECT(pSurface), "g-lo-InstancePopup", GINT_TO_POINTER(true));
@@ -9915,6 +9919,8 @@ void MoveWindowContentsToPopover(GtkWindow* pMenuHack, GtkWidget* pPopover, GtkW
do_ungrab(GTK_WIDGET(pMenuHack));
+ gtk_grab_remove(GTK_WIDGET(pMenuHack));
+
gtk_widget_hide(GTK_WIDGET(pMenuHack));
//put contents back from where the came from
GtkWidget* pChild = gtk_bin_get_child(GTK_BIN(pMenuHack));
@@ -9938,13 +9944,7 @@ void MoveWindowContentsToPopover(GtkWindow* pMenuHack, GtkWidget* pPopover, GtkW
pFrame->UnblockTooltip();
if (bHadFocus)
- {
- GdkSurface* pParentSurface = pParent ? widget_get_surface(pParent) : nullptr;
- void* pParentIsPopover = pParentSurface ? g_object_get_data(G_OBJECT(pParentSurface), "g-lo-InstancePopup") : nullptr;
- if (pParentIsPopover)
- do_grab(pAnchor);
gtk_widget_grab_focus(pAnchor);
- }
}
#endif
@@ -22047,6 +22047,34 @@ private:
return false;
}
+ bool forward_event_if_popup_under_mouse(GdkEvent* pEvent)
+ {
+ GtkWidget* pEventWidget = gtk_get_event_widget(pEvent);
+ GtkWidget* pTopLevel = widget_get_toplevel(pEventWidget);
+
+ if (pTopLevel == GTK_WIDGET(m_pMenuHack))
+ return false;
+
+ GdkSurface* pSurface = widget_get_surface(pTopLevel);
+ void* pMouseEnteredAnotherPopup = g_object_get_data(G_OBJECT(pSurface), "g-lo-InstancePopup");
+ if (!pMouseEnteredAnotherPopup)
+ return false;
+
+ return gtk_widget_event(pEventWidget, reinterpret_cast<GdkEvent*>(pEvent));
+ }
+
+ static gboolean signalButtonCrossing(GtkWidget*, GdkEvent* pEvent, gpointer widget)
+ {
+ GtkInstancePopover* pThis = static_cast<GtkInstancePopover*>(widget);
+ return pThis->forward_event_if_popup_under_mouse(pEvent);
+ }
+
+ static gboolean signalMotion(GtkWidget*, GdkEvent* pEvent, gpointer widget)
+ {
+ GtkInstancePopover* pThis = static_cast<GtkInstancePopover*>(widget);
+ return pThis->forward_event_if_popup_under_mouse(pEvent);
+ }
+
static void signalGrabBroken(GtkWidget*, GdkEventGrabBroken *pEvent, gpointer widget)
{
GtkInstancePopover* pThis = static_cast<GtkInstancePopover*>(widget);
@@ -22098,6 +22126,14 @@ public:
g_signal_connect(m_pMenuHack, "grab-broken-event", G_CALLBACK(signalGrabBroken), this);
g_signal_connect(m_pMenuHack, "button-press-event", G_CALLBACK(signalButtonPress), this);
g_signal_connect(m_pMenuHack, "button-release-event", G_CALLBACK(signalButtonRelease), this);
+ // to emulate a modeless popover we forward the leave/enter/motion events to the widgets
+ // they would have gone to a if we were really modeless
+ if (!gtk_popover_get_modal(m_pPopover))
+ {
+ g_signal_connect(m_pMenuHack, "leave-notify-event", G_CALLBACK(signalButtonCrossing), this);
+ g_signal_connect(m_pMenuHack, "enter-notify-event", G_CALLBACK(signalButtonCrossing), this);
+ g_signal_connect(m_pMenuHack, "motion-notify-event", G_CALLBACK(signalMotion), this);
+ }
}
#endif
#endif