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>
diff --git a/sc/UIConfig_scalc.mk b/sc/UIConfig_scalc.mk
index c1bd1b0..336e171 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 847aa8d..eede080 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 2c5a44b..259ad47 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 c2c94d6..f9a26c8 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 fb2c905..981dd69 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 1e539e9..60d9ade 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 4e0de34..4415ec1 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 f0d16a3..4d9c7b6 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 08dfc52..8607a20 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 f5e3e78..22fdfba 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 e6b98db..cccc8e7 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 d7e7f0c..922dd80 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 559073a..09f81fa 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 7dfb572..05bd1cc 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 c9ca646..dd398dd 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);
virtual void GetFocus() override;
virtual bool EventNotify(NotifyEvent& rNEvt) override;
void GrabFocus();
bool IsVisible() const;
ScCheckListMenuWindow* GetParentMenu() { return mxParentMenu; }
ScCheckListMenuControl& get_widget() { return *mxControl; }
void StartPopupMode(weld::Widget* pParent, const tools::Rectangle& rRect);
void EndPopupMode();
void addMenuItem(const OUString& rText, ScCheckListMenuControl::Action* pAction);
void resizeToFitMenuItems();
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 0bf9fb7..2f8ac0d 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 5b203ad..3116dfb 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 db6c8c6..8050310 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 17bca29..a6f025a 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,13 +214,109 @@
</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>
<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="hexpand">True</property>
<property name="vexpand">True</property>
<property name="shadow-type">in</property>
<child>
<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="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>
<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">
<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="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>
@@ -207,105 +332,36 @@
</packing>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<object class="GtkButtonBox" id="buttonbox">
<property name="can-focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="no-show-all">True</property>
<property name="spacing">6</property>
<property name="layout-style">spread</property>
<child>
<object class="GtkScrolledWindow">
<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="hexpand">True</property>
<property name="vexpand">True</property>
<property name="shadow-type">in</property>
<child>
<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="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>
<property name="can-default">True</property>
<property name="receives-default">True</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkScrolledWindow">
<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="hexpand">True</property>
<property name="vexpand">True</property>
<property name="shadow-type">in</property>
<child>
<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="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>
<property name="receives-default">True</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
@@ -321,57 +377,10 @@
<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>
</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">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 0000000..942cc4b
--- /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 0fc8ffd..0d7ff19 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