summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2021-11-19 11:38:58 +0000
committerCaolán McNamara <caolanm@redhat.com>2021-11-23 17:36:13 +0100
commit2acdb3e617658ca19de26e8928e42b4955622feb (patch)
treef543f678b1b72a7a9cff80b5dbed301cd21fbbaf
parentf5137ed5453661d21e85ecb94a08cfccae899ca1 (diff)
tdf#139460 improve autofilter sub-menu interaction under gtk
so the submenu pops down when the mouse moves back into its parent. This removes layer of InterimItemWindow and for gtk (under wayland) the autofilter and its submenu can use native GtkPopovers Change-Id: I4c8c3d2087566f508d75eda72e272d9f7fba2f00 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/125428 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-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