summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2020-05-28 15:24:29 +0100
committerCaolán McNamara <caolanm@redhat.com>2020-06-12 20:03:54 +0200
commita16e6122dc62f545df90b9ea4d1f4723c46336b6 (patch)
treeb6dfbe06f36d715292fe88821f33f141645b1ad2
parenta5b181df04e4688256bda19e1bece7bf9fd3fa02 (diff)
weld checklistmenu
rework the "menu" to be a treeview using hover selection instead of a custom set of widgetry, and drop the newly unused custom a11y code Change-Id: Ie7d9b7875ce00843b3f262882816cebb472bf681 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95223 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--compilerplugins/clang/constantparam.numbers.results4
-rw-r--r--include/vcl/dockwin.hxx5
-rw-r--r--sc/IwyuFilter_sc.yaml6
-rw-r--r--sc/Library_sc.mk3
-rw-r--r--sc/UIConfig_scalc.mk2
-rw-r--r--sc/inc/AccessibleFilterMenu.hxx139
-rw-r--r--sc/inc/AccessibleFilterMenuItem.hxx95
-rw-r--r--sc/inc/AccessibleFilterTopWindow.hxx81
-rw-r--r--sc/inc/strings.hrc4
-rw-r--r--sc/qa/uitest/autofilter/tdf126306.py41
-rw-r--r--sc/source/ui/Accessibility/AccessibleFilterMenu.cxx331
-rw-r--r--sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx166
-rw-r--r--sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx118
-rw-r--r--sc/source/ui/app/inputwin.cxx1
-rw-r--r--sc/source/ui/cctrl/checklistmenu.cxx1862
-rw-r--r--sc/source/ui/docshell/docsh4.cxx1
-rw-r--r--sc/source/ui/inc/checklistmenu.hxx472
-rw-r--r--sc/source/ui/inc/gridwin.hxx2
-rw-r--r--sc/source/ui/view/gridwin.cxx74
-rw-r--r--sc/source/ui/view/gridwin2.cxx62
-rw-r--r--sc/uiconfig/scalc/ui/filterdropdown.ui304
-rw-r--r--sc/uiconfig/scalc/ui/listmenu.ui9
-rw-r--r--solenv/clang-format/blacklist6
-rw-r--r--svtools/source/control/toolbarmenu.cxx2
-rw-r--r--vcl/source/window/dockmgr.cxx9
25 files changed, 1172 insertions, 2627 deletions
diff --git a/compilerplugins/clang/constantparam.numbers.results b/compilerplugins/clang/constantparam.numbers.results
index dd73f620e594..49da62a78ecf 100644
--- a/compilerplugins/clang/constantparam.numbers.results
+++ b/compilerplugins/clang/constantparam.numbers.results
@@ -1826,10 +1826,6 @@ sax/source/tools/converter.cxx:994
enum sax::(anonymous namespace)::Result readUnsignedNumberMaxDigits(int,const class rtl::OUString &,int &,int &)
int maxDigits
9
-sc/inc/AccessibleFilterMenu.hxx:41
- void ScAccessibleFilterMenu::ScAccessibleFilterMenu(const class com::sun::star::uno::Reference<class com::sun::star::accessibility::XAccessible> &,class ScMenuFloatingWindow *,const class rtl::OUString &,unsigned long)
- unsigned long nMenuPos
- 999
sc/inc/address.hxx:334
void ScAddress::Format(class rtl::OStringBuffer &,enum ScRefFlags,const class ScDocument *,const struct ScAddress::Details &) const
enum ScRefFlags nFlags
diff --git a/include/vcl/dockwin.hxx b/include/vcl/dockwin.hxx
index f0f0ee5d60f5..689a2f4c60c3 100644
--- a/include/vcl/dockwin.hxx
+++ b/include/vcl/dockwin.hxx
@@ -83,6 +83,7 @@ private:
VclPtr<FloatingWindow> mpFloatWin;
VclPtr<vcl::Window> mpOldBorderWin;
VclPtr<vcl::Window> mpParent;
+ Link<FloatingWindow*,void> maPopupModeEndHdl;
Point maFloatPos;
Point maDockPos;
Point maMouseOff;
@@ -138,6 +139,8 @@ public:
void StartPopupMode( ToolBox* pParentToolBox, FloatWinPopupFlags nPopupModeFlags );
bool IsInPopupMode() const;
+ void SetPopupModeEndHdl( const Link<FloatingWindow*,void>& rLink ) { maPopupModeEndHdl = rLink; }
+
void TitleButtonClick( TitleButton nButton );
void Resizing( Size& rSize );
void Tracking( const TrackingEvent& rTEvt );
@@ -193,6 +196,8 @@ public:
void StartPopupMode( ToolBox *pParentToolBox, const vcl::Window *pWin );
void StartPopupMode( ToolBox *pParentToolBox, const vcl::Window *pWin, FloatWinPopupFlags nPopupModeFlags );
+ void SetPopupModeEndHdl( const vcl::Window *pWindow, const Link<FloatingWindow*,void>& rLink );
+
bool IsInPopupMode( const vcl::Window *pWin );
void EndPopupMode( const vcl::Window *pWin );
diff --git a/sc/IwyuFilter_sc.yaml b/sc/IwyuFilter_sc.yaml
index 03e98182ac73..ee2301087b23 100644
--- a/sc/IwyuFilter_sc.yaml
+++ b/sc/IwyuFilter_sc.yaml
@@ -4,12 +4,6 @@ blacklist:
sc/inc/AccessibleGlobal.hxx:
# base class has to be a complete type
- com/sun/star/accessibility/XAccessibleStateSet.hpp
- sc/inc/AccessibleFilterMenu.hxx:
- # base class has to be a complete type
- - com/sun/star/accessibility/XAccessibleSelection.hpp
- sc/inc/AccessibleFilterMenuItem.hxx:
- # base class has to be a complete type
- - com/sun/star/accessibility/XAccessibleAction.hpp
sc/inc/addruno.hxx:
# base class has to be a complete type
- com/sun/star/beans/XPropertySet.hpp
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 997b14c0add9..47b801f799c4 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -363,9 +363,6 @@ $(eval $(call gb_Library_add_exception_objects,sc,\
sc/source/ui/Accessibility/AccessibleDocumentBase \
sc/source/ui/Accessibility/AccessibleDocumentPagePreview \
sc/source/ui/Accessibility/AccessibleEditObject \
- sc/source/ui/Accessibility/AccessibleFilterMenu \
- sc/source/ui/Accessibility/AccessibleFilterMenuItem \
- sc/source/ui/Accessibility/AccessibleFilterTopWindow \
sc/source/ui/Accessibility/AccessibleGlobal \
sc/source/ui/Accessibility/AccessiblePageHeader \
sc/source/ui/Accessibility/AccessiblePageHeaderArea \
diff --git a/sc/UIConfig_scalc.mk b/sc/UIConfig_scalc.mk
index 8e3de9629a7f..38b6acaf0f0d 100644
--- a/sc/UIConfig_scalc.mk
+++ b/sc/UIConfig_scalc.mk
@@ -127,6 +127,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/scalc,\
sc/uiconfig/scalc/ui/exponentialsmoothingdialog \
sc/uiconfig/scalc/ui/filldlg \
sc/uiconfig/scalc/ui/filterlist \
+ sc/uiconfig/scalc/ui/filterdropdown \
sc/uiconfig/scalc/ui/footerdialog \
sc/uiconfig/scalc/ui/formatcellsdialog \
sc/uiconfig/scalc/ui/formulacalculationoptions \
@@ -149,6 +150,7 @@ $(eval $(call gb_UIConfig_add_uifiles,modules/scalc,\
sc/uiconfig/scalc/ui/integerdialog \
sc/uiconfig/scalc/ui/leftfooterdialog \
sc/uiconfig/scalc/ui/leftheaderdialog \
+ sc/uiconfig/scalc/ui/listmenu \
sc/uiconfig/scalc/ui/namerangesdialog \
sc/uiconfig/scalc/ui/notebookbar \
sc/uiconfig/scalc/ui/notebookbar_compact \
diff --git a/sc/inc/AccessibleFilterMenu.hxx b/sc/inc/AccessibleFilterMenu.hxx
deleted file mode 100644
index 878c27a637c3..000000000000
--- a/sc/inc/AccessibleFilterMenu.hxx
+++ /dev/null
@@ -1,139 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifndef INCLUDED_SC_INC_ACCESSIBLEFILTERMENU_HXX
-#define INCLUDED_SC_INC_ACCESSIBLEFILTERMENU_HXX
-
-#include <AccessibleContextBase.hxx>
-#include <cppuhelper/implbase1.hxx>
-
-#include <com/sun/star/accessibility/XAccessibleSelection.hpp>
-#include <vcl/vclptr.hxx>
-
-#include <vector>
-
-class ScMenuFloatingWindow;
-
-typedef ::cppu::ImplHelper1<
- css::accessibility::XAccessibleSelection > ScAccessibleFilterMenu_BASE;
-
-class ScAccessibleFilterMenu :
- public ScAccessibleContextBase,
- public ScAccessibleFilterMenu_BASE
-{
-public:
- explicit ScAccessibleFilterMenu(
- const css::uno::Reference< css::accessibility::XAccessible>& rxParent,
- ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos);
- virtual ~ScAccessibleFilterMenu() override;
-
- virtual bool isVisible() override;
-
- /// XAccessibleComponent
-
- virtual css::uno::Reference< css::accessibility::XAccessible >
- SAL_CALL getAccessibleAtPoint( const css::awt::Point& rPoint ) override;
-
- virtual void SAL_CALL grabFocus() override;
-
- virtual sal_Int32 SAL_CALL getForeground() override;
-
- virtual sal_Int32 SAL_CALL getBackground() override;
-
- /// XAccessibleContext
-
- virtual sal_Int32 SAL_CALL getAccessibleChildCount() override;
-
- virtual css::uno::Reference< css::accessibility::XAccessible> SAL_CALL
- getAccessibleChild(sal_Int32 nIndex) override;
-
- virtual css::uno::Reference<
- css::accessibility::XAccessibleStateSet> SAL_CALL
- getAccessibleStateSet() override;
-
- virtual OUString SAL_CALL getImplementationName() override;
-
- /// XAccessibleEventBroadcaster
- virtual void SAL_CALL
- addAccessibleEventListener(
- const css::uno::Reference< css::accessibility::XAccessibleEventListener>& xListener) override;
-
- /// Remove an existing event listener.
- virtual void SAL_CALL
- removeAccessibleEventListener(
- const css::uno::Reference< css::accessibility::XAccessibleEventListener>& xListener) override;
-
- /// XAccessibleSelection
-
- virtual void SAL_CALL selectAccessibleChild(sal_Int32 nChildIndex) override;
-
- virtual sal_Bool SAL_CALL isAccessibleChildSelected(sal_Int32 nChildIndex) override;
-
- virtual void SAL_CALL clearAccessibleSelection() override;
-
- virtual void SAL_CALL selectAllAccessibleChildren() override;
-
- virtual ::sal_Int32 SAL_CALL getSelectedAccessibleChildCount() override;
-
- virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
- getSelectedAccessibleChild(sal_Int32 nChildIndex) override;
-
- virtual void SAL_CALL deselectAccessibleChild(sal_Int32 nChildIndex) override;
-
- /// XInterface
-
- virtual css::uno::Any SAL_CALL queryInterface(
- css::uno::Type const & rType ) override;
-
- virtual void SAL_CALL acquire() throw () override;
- virtual void SAL_CALL release() throw () override;
-
- /// XTypeProvider
-
- virtual css::uno::Sequence<sal_Int8> SAL_CALL getImplementationId() override;
-
- /// non-UNO methods
-
- void appendMenuItem(const OUString& rName, size_t nMenuPos);
- void setMenuPos(size_t nMenuPos);
-
-protected:
-
- sal_Int32 getMenuItemCount() const;
-
- virtual tools::Rectangle GetBoundingBoxOnScreen() const override;
-
- virtual tools::Rectangle GetBoundingBox() const override;
-
-private:
- bool isSelected() const;
-
- void updateStates();
-
-private:
- ::std::vector< css::uno::Reference< css::accessibility::XAccessible > > maMenuItems;
- css::uno::Reference< css::accessibility::XAccessibleStateSet > mxStateSet;
-
- size_t mnMenuPos;
- VclPtr<ScMenuFloatingWindow> mpWindow;
-};
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/AccessibleFilterMenuItem.hxx b/sc/inc/AccessibleFilterMenuItem.hxx
deleted file mode 100644
index d45b4c2890e2..000000000000
--- a/sc/inc/AccessibleFilterMenuItem.hxx
+++ /dev/null
@@ -1,95 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifndef INCLUDED_SC_INC_ACCESSIBLEFILTERMENUITEM_HXX
-#define INCLUDED_SC_INC_ACCESSIBLEFILTERMENUITEM_HXX
-
-#include <AccessibleContextBase.hxx>
-#include <cppuhelper/implbase1.hxx>
-
-#include <com/sun/star/accessibility/XAccessibleAction.hpp>
-#include <vcl/vclptr.hxx>
-
-class ScMenuFloatingWindow;
-
-typedef ::cppu::ImplHelper1<
- css::accessibility::XAccessibleAction > ScAccessibleFilterMenuItem_BASE;
-
-class ScAccessibleFilterMenuItem final :
- public ScAccessibleContextBase,
- public ScAccessibleFilterMenuItem_BASE
-{
-public:
- explicit ScAccessibleFilterMenuItem(
- const css::uno::Reference< css::accessibility::XAccessible>& rxParent,
- ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos);
-
- virtual ~ScAccessibleFilterMenuItem() override;
-
- /// XAccessibleContext
-
- virtual sal_Int32 SAL_CALL getAccessibleChildCount() override;
-
- virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL
- getAccessibleChild(sal_Int32 nIndex) override;
-
- virtual css::uno::Reference< css::accessibility::XAccessibleStateSet> SAL_CALL
- getAccessibleStateSet() override;
-
- virtual OUString SAL_CALL getImplementationName() override;
-
- /// XAccessibleAction
-
- virtual ::sal_Int32 SAL_CALL getAccessibleActionCount() override;
-
- virtual sal_Bool SAL_CALL doAccessibleAction(sal_Int32 nIndex) override;
-
- virtual OUString SAL_CALL getAccessibleActionDescription(sal_Int32 nIndex) override;
-
- virtual css::uno::Reference< css::accessibility::XAccessibleKeyBinding > SAL_CALL
- getAccessibleActionKeyBinding(sal_Int32 nIndex) override;
-
- /// XInterface
-
- virtual css::uno::Any SAL_CALL queryInterface(
- css::uno::Type const & rType ) override;
-
- virtual void SAL_CALL acquire() throw () override;
- virtual void SAL_CALL release() throw () override;
-
- /// Non-UNO Methods
-
-private:
-
- virtual tools::Rectangle GetBoundingBoxOnScreen() const override;
-
- virtual tools::Rectangle GetBoundingBox() const override;
-
- bool isSelected() const;
- void updateStateSet();
-
- css::uno::Reference< css::accessibility::XAccessibleStateSet > mxStateSet;
-
- VclPtr<ScMenuFloatingWindow> mpWindow;
- size_t mnMenuPos;
-};
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/AccessibleFilterTopWindow.hxx b/sc/inc/AccessibleFilterTopWindow.hxx
deleted file mode 100644
index 90dd9bbbfd30..000000000000
--- a/sc/inc/AccessibleFilterTopWindow.hxx
+++ /dev/null
@@ -1,81 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifndef INCLUDED_SC_INC_ACCESSIBLEFILTERTOPWINDOW_HXX
-#define INCLUDED_SC_INC_ACCESSIBLEFILTERTOPWINDOW_HXX
-
-#include "AccessibleFilterMenu.hxx"
-
-class ScCheckListMenuWindow;
-
-class ScAccessibleFilterTopWindow final : public ScAccessibleFilterMenu
-{
-public:
- ScAccessibleFilterTopWindow(
- const css::uno::Reference< css::accessibility::XAccessible>& rxParent,
- ScCheckListMenuWindow* pWin,
- const OUString& rName);
- virtual ~ScAccessibleFilterTopWindow() override;
-
- // XAccessibleContext
-
- virtual sal_Int32 SAL_CALL getAccessibleChildCount() override;
-
- virtual css::uno::Reference< css::accessibility::XAccessible> SAL_CALL
- getAccessibleChild(sal_Int32 nIndex) override;
-
- virtual OUString SAL_CALL getImplementationName() override;
-
- // Non-UNO Methods
-
- enum ChildControlType {
- EDIT_SEARCH_BOX, LISTBOX, TOGGLE_ALL, SINGLE_ON_BTN, SINGLE_OFF_BTN, OK_BTN, CANCEL_BTN
- };
- void setAccessibleChild(
- const css::uno::Reference< css::accessibility::XAccessible >& rAccessible,
- ChildControlType eType);
-
-private:
- /** Edit search box for searching field members */
- css::uno::Reference< css::accessibility::XAccessible >
- mxAccEditSearchBox;
- /** check list box for field member visibility */
- css::uno::Reference< css::accessibility::XAccessible >
- mxAccListBox;
-
- /** check box for toggling all field member's visibility. */
- css::uno::Reference< css::accessibility::XAccessible >
- mxAccToggleAll;
-
- css::uno::Reference< css::accessibility::XAccessible >
- mxAccSingleOnBtn;
-
- css::uno::Reference< css::accessibility::XAccessible >
- mxAccSingleOffBtn;
-
- css::uno::Reference< css::accessibility::XAccessible >
- mxAccOkBtn;
-
- css::uno::Reference< css::accessibility::XAccessible >
- mxAccCancelBtn;
-};
-
-#endif
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/strings.hrc b/sc/inc/strings.hrc
index a685c1ef9d28..6f6b0299c28a 100644
--- a/sc/inc/strings.hrc
+++ b/sc/inc/strings.hrc
@@ -164,10 +164,6 @@
#define STR_MENU_SORT_ASC NC_("STR_MENU_SORT_ASC", "Sort Ascending")
#define STR_MENU_SORT_DESC NC_("STR_MENU_SORT_DESC", "Sort Descending")
#define STR_MENU_SORT_CUSTOM NC_("STR_MENU_SORT_CUSTOM", "Custom Sort")
-#define STR_BTN_TOGGLE_ALL NC_("STR_BTN_TOGGLE_ALL", "All")
-#define STR_BTN_SELECT_CURRENT NC_("STR_BTN_SELECT_CURRENT", "Show only the current item.")
-#define STR_BTN_UNSELECT_CURRENT NC_("STR_BTN_UNSELECT_CURRENT", "Hide only the current item.")
-#define STR_EDIT_SEARCH_ITEMS NC_("STR_EDIT_SEARCH_ITEMS", "Search items...")
#define SCSTR_QHELP_POSWND NC_("SCSTR_QHELP_POSWND", "Name Box")
#define SCSTR_QHELP_INPUTWND NC_("SCSTR_QHELP_INPUTWND", "Input line")
diff --git a/sc/qa/uitest/autofilter/tdf126306.py b/sc/qa/uitest/autofilter/tdf126306.py
index 5446d3337049..5a1a6ab7b053 100644
--- a/sc/qa/uitest/autofilter/tdf126306.py
+++ b/sc/qa/uitest/autofilter/tdf126306.py
@@ -48,8 +48,9 @@ class tdf126306(UITestCase):
# Sort ascending button
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"SHIFT+TAB"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"RETURN"}))
+ xMenu = xFloatWindow.getChild("menu")
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"SPACE"}))
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"RETURN"}))
sort_asc_values = [0, 3, 8, 9, 17, 19, 25, 25, 33, 89, 107, 204, 453, 1023]
self.check_values(document, sort_asc_values)
@@ -63,9 +64,9 @@ class tdf126306(UITestCase):
# Sort descending button
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"SHIFT+TAB"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"RETURN"}))
+ xMenu = xFloatWindow.getChild("menu")
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"RETURN"}))
sort_des_values = [1023, 453, 204, 107, 89, 33, 25, 25, 19, 17, 9, 8, 3, 0]
self.check_values(document, sort_des_values)
@@ -79,10 +80,10 @@ class tdf126306(UITestCase):
# Top 10 button
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"SHIFT+TAB"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"RETURN"}))
+ xMenu = xFloatWindow.getChild("menu")
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"RETURN"}))
top10_hidden_values = [True, True, True, False, True, False, True,
True, False, True, True, False, True, True]
@@ -99,11 +100,11 @@ class tdf126306(UITestCase):
# Empty button
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"SHIFT+TAB"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"RETURN"}))
+ xMenu = xFloatWindow.getChild("menu")
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"RETURN"}))
empty_values = [False] * 14
#Values are the same
@@ -118,12 +119,12 @@ class tdf126306(UITestCase):
# Not Empty button
xGridWin.executeAction("LAUNCH", mkPropertyValues({"AUTOFILTER": "", "COL": "0", "ROW": "0"}))
xFloatWindow = self.xUITest.getFloatWindow()
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"SHIFT+TAB"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
- xFloatWindow.executeAction("TYPE", mkPropertyValues({"KEYCODE":"RETURN"}))
+ xMenu = xFloatWindow.getChild("menu")
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"DOWN"}))
+ xMenu.executeAction("TYPE", mkPropertyValues({"KEYCODE":"RETURN"}))
#Nothing should change
self.check_values(document, default_values)
diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx
deleted file mode 100644
index 48149e53d69c..000000000000
--- a/sc/source/ui/Accessibility/AccessibleFilterMenu.cxx
+++ /dev/null
@@ -1,331 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <AccessibleGlobal.hxx>
-#include <AccessibleFilterMenu.hxx>
-#include <AccessibleFilterMenuItem.hxx>
-
-#include <o3tl/safeint.hxx>
-#include <tools/gen.hxx>
-#include <checklistmenu.hxx>
-
-#include <com/sun/star/accessibility/AccessibleRole.hpp>
-#include <com/sun/star/accessibility/AccessibleStateType.hpp>
-#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
-
-using namespace ::com::sun::star;
-using namespace ::com::sun::star::accessibility;
-using namespace ::com::sun::star::accessibility::AccessibleStateType;
-
-using ::com::sun::star::uno::Any;
-using ::com::sun::star::uno::Reference;
-using ::com::sun::star::uno::Sequence;
-using ::com::sun::star::uno::UNO_QUERY;
-using ::com::sun::star::lang::IndexOutOfBoundsException;
-using ::std::for_each;
-
-namespace {
-
-class AddRemoveEventListener
-{
-public:
- explicit AddRemoveEventListener(const Reference<XAccessibleEventListener>& rListener, bool bAdd) :
- mxListener(rListener), mbAdd(bAdd) {}
-
- void operator() (const Reference<XAccessible>& xAccessible) const
- {
- if (!xAccessible.is())
- return;
-
- Reference<XAccessibleEventBroadcaster> xBc(xAccessible, UNO_QUERY);
- if (xBc.is())
- {
- if (mbAdd)
- xBc->addAccessibleEventListener(mxListener);
- else
- xBc->removeAccessibleEventListener(mxListener);
- }
- }
-private:
- Reference<XAccessibleEventListener> mxListener;
- bool mbAdd;
-};
-
-}
-
-ScAccessibleFilterMenu::ScAccessibleFilterMenu(const Reference<XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos) :
- ScAccessibleContextBase(rxParent, AccessibleRole::MENU),
- mnMenuPos(nMenuPos),
- mpWindow(pWin)
-{
- SetName(rName);
-}
-
-ScAccessibleFilterMenu::~ScAccessibleFilterMenu()
-{
-}
-
-// XAccessibleComponent
-
-Reference<XAccessible> ScAccessibleFilterMenu::getAccessibleAtPoint( const css::awt::Point& /*rPoint*/ )
-{
- return this;
-}
-
-bool ScAccessibleFilterMenu::isVisible()
-{
- return mpWindow->IsVisible();
-}
-
-void ScAccessibleFilterMenu::grabFocus()
-{
-}
-
-sal_Int32 ScAccessibleFilterMenu::getForeground()
-{
- return 0;
-}
-
-sal_Int32 ScAccessibleFilterMenu::getBackground()
-{
- return 0;
-}
-
-// XAccessibleContext
-
-sal_Int32 ScAccessibleFilterMenu::getAccessibleChildCount()
-{
- return getMenuItemCount();
-}
-
-Reference<XAccessible> ScAccessibleFilterMenu::getAccessibleChild(sal_Int32 nIndex)
-{
- if (maMenuItems.size() <= o3tl::make_unsigned(nIndex))
- throw IndexOutOfBoundsException();
-
- return maMenuItems[nIndex];
-}
-
-Reference<XAccessibleStateSet> ScAccessibleFilterMenu::getAccessibleStateSet()
-{
- updateStates();
- return mxStateSet;
-}
-
-OUString ScAccessibleFilterMenu::getImplementationName()
-{
- return "ScAccessibleFilterMenu";
-}
-
-// XAccessibleEventBroadcaster
-
-void ScAccessibleFilterMenu::addAccessibleEventListener(
- const css::uno::Reference<css::accessibility::XAccessibleEventListener>& xListener)
-{
- ScAccessibleContextBase::addAccessibleEventListener(xListener);
- for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, true));
-}
-
-void ScAccessibleFilterMenu::removeAccessibleEventListener(
- const css::uno::Reference<css::accessibility::XAccessibleEventListener>& xListener)
-{
- ScAccessibleContextBase::removeAccessibleEventListener(xListener);
- for_each(maMenuItems.begin(), maMenuItems.end(), AddRemoveEventListener(xListener, false));
-}
-
-// XAccessibleSelection
-
-void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex)
-{
- if (o3tl::make_unsigned(nChildIndex) >= maMenuItems.size())
- throw IndexOutOfBoundsException();
-
- mpWindow->setSelectedMenuItem(nChildIndex, false, true);
-}
-
-sal_Bool ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex)
-{
- if (o3tl::make_unsigned(nChildIndex) >= maMenuItems.size())
- throw IndexOutOfBoundsException();
-
- return mpWindow->isMenuItemSelected(static_cast<size_t>(nChildIndex));
-}
-
-void ScAccessibleFilterMenu::clearAccessibleSelection()
-{
- mpWindow->clearSelectedMenuItem();
-}
-
-void ScAccessibleFilterMenu::selectAllAccessibleChildren()
-{
- // not supported - this is a menu, you can't select all menu items.
-}
-
-sal_Int32 ScAccessibleFilterMenu::getSelectedAccessibleChildCount()
-{
- // Since this is a menu, either one menu item is selected, or none at all.
- return mpWindow->getSelectedMenuItem() == ScMenuFloatingWindow::MENU_NOT_SELECTED ? 0 : 1;
-}
-
-Reference<XAccessible> ScAccessibleFilterMenu::getSelectedAccessibleChild(sal_Int32 nChildIndex)
-{
- if (o3tl::make_unsigned(nChildIndex) >= maMenuItems.size())
- throw IndexOutOfBoundsException();
-
- return maMenuItems[nChildIndex];
-}
-
-void ScAccessibleFilterMenu::deselectAccessibleChild(sal_Int32 nChildIndex)
-{
- if (o3tl::make_unsigned(nChildIndex) >= maMenuItems.size())
- throw IndexOutOfBoundsException();
-
- mpWindow->selectMenuItem(nChildIndex, false, false);
-}
-
-// XInterface
-
-uno::Any SAL_CALL ScAccessibleFilterMenu::queryInterface( uno::Type const & rType )
-{
- Any any = ScAccessibleContextBase::queryInterface(rType);
- if (any.hasValue())
- return any;
-
- return ScAccessibleFilterMenu_BASE::queryInterface(rType);
-}
-
-void SAL_CALL ScAccessibleFilterMenu::acquire() throw ()
-{
- ScAccessibleContextBase::acquire();
-}
-
-void SAL_CALL ScAccessibleFilterMenu::release() throw ()
-{
- ScAccessibleContextBase::release();
-}
-
-// XTypeProvider
-
-Sequence<sal_Int8> ScAccessibleFilterMenu::getImplementationId()
-{
- return css::uno::Sequence<sal_Int8>();
-}
-
-tools::Rectangle ScAccessibleFilterMenu::GetBoundingBoxOnScreen() const
-{
- if (mnMenuPos == ScMenuFloatingWindow::MENU_NOT_SELECTED)
- return tools::Rectangle();
-
- // Menu object's bounding box is the bounding box of the menu item that
- // launches the menu, which belongs to the parent window.
- ScMenuFloatingWindow* pParentWin = mpWindow->getParentMenuWindow();
- if (!pParentWin)
- return tools::Rectangle();
-
- if (!pParentWin->IsVisible())
- return tools::Rectangle();
-
- Point aPos = pParentWin->OutputToAbsoluteScreenPixel(Point(0,0));
- Point aMenuPos;
- Size aMenuSize;
- pParentWin->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
- tools::Rectangle aRect(aPos + aMenuPos, aMenuSize);
- return aRect;
-}
-
-tools::Rectangle ScAccessibleFilterMenu::GetBoundingBox() const
-{
- if (mnMenuPos == ScMenuFloatingWindow::MENU_NOT_SELECTED)
- return tools::Rectangle();
-
- // Menu object's bounding box is the bounding box of the menu item that
- // launches the menu, which belongs to the parent window.
- ScMenuFloatingWindow* pParentWin = mpWindow->getParentMenuWindow();
- if (!pParentWin)
- return tools::Rectangle();
-
- if (!pParentWin->IsVisible())
- return tools::Rectangle();
-
- Point aMenuPos;
- Size aMenuSize;
- pParentWin->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
- tools::Rectangle aRect(aMenuPos, aMenuSize);
- return aRect;
-}
-
-void ScAccessibleFilterMenu::appendMenuItem(const OUString& rName, size_t nMenuPos)
-{
- // Check whether this menu item is a sub menu or a regular menu item.
- ScMenuFloatingWindow* pSubMenu = mpWindow->getSubMenuWindow(nMenuPos);
- Reference<XAccessible> xAccessible;
- if (pSubMenu)
- {
- xAccessible = pSubMenu->CreateAccessible();
- ScAccessibleFilterMenu* p =
- static_cast<ScAccessibleFilterMenu*>(xAccessible.get());
- p->setMenuPos(nMenuPos);
- }
- else
- {
- xAccessible.set(new ScAccessibleFilterMenuItem(this, mpWindow, rName, nMenuPos));
- }
- maMenuItems.push_back(xAccessible);
-}
-
-void ScAccessibleFilterMenu::setMenuPos(size_t nMenuPos)
-{
- mnMenuPos = nMenuPos;
-}
-
-sal_Int32 ScAccessibleFilterMenu::getMenuItemCount() const
-{
- return maMenuItems.size();
-}
-
-bool ScAccessibleFilterMenu::isSelected() const
-{
- // Check to see if any of the child menu items is selected.
- return mpWindow->isMenuItemSelected(mnMenuPos);
-}
-
-void ScAccessibleFilterMenu::updateStates()
-{
- if (!mxStateSet.is())
- mxStateSet.set(new ScAccessibleStateSet);
-
- ScAccessibleStateSet* p = static_cast<ScAccessibleStateSet*>(
- mxStateSet.get());
-
- p->clear();
-
- p->insert(ENABLED);
- p->insert(FOCUSABLE);
- p->insert(SELECTABLE);
- p->insert(SENSITIVE);
- p->insert(OPAQUE);
-
- if (isSelected())
- p->insert(FOCUSED);
-
- if (isSelected())
- p->insert(SELECTED);
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx b/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx
deleted file mode 100644
index 71b63fb76a70..000000000000
--- a/sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx
+++ /dev/null
@@ -1,166 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <AccessibleGlobal.hxx>
-#include <AccessibleFilterMenuItem.hxx>
-#include <checklistmenu.hxx>
-
-#include <com/sun/star/accessibility/AccessibleRole.hpp>
-#include <com/sun/star/accessibility/AccessibleStateType.hpp>
-#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
-
-using namespace ::com::sun::star;
-using namespace ::com::sun::star::accessibility;
-using namespace ::com::sun::star::accessibility::AccessibleStateType;
-
-using ::com::sun::star::uno::Any;
-using ::com::sun::star::uno::Reference;
-using ::com::sun::star::lang::IndexOutOfBoundsException;
-
-ScAccessibleFilterMenuItem::ScAccessibleFilterMenuItem(
- const Reference<XAccessible>& rxParent, ScMenuFloatingWindow* pWin, const OUString& rName, size_t nMenuPos) :
- ScAccessibleContextBase(rxParent, AccessibleRole::MENU_ITEM),
- mpWindow(pWin),
- mnMenuPos(nMenuPos)
-{
- SetName(rName);
-}
-
-ScAccessibleFilterMenuItem::~ScAccessibleFilterMenuItem()
-{
-}
-
-sal_Int32 ScAccessibleFilterMenuItem::getAccessibleChildCount()
-{
- return 0;
-}
-
-Reference<XAccessible> ScAccessibleFilterMenuItem::getAccessibleChild(sal_Int32 /*nIndex*/)
-{
- throw IndexOutOfBoundsException();
-}
-
-Reference<XAccessibleStateSet> ScAccessibleFilterMenuItem::getAccessibleStateSet()
-{
- updateStateSet();
- return mxStateSet;
-}
-
-OUString ScAccessibleFilterMenuItem::getImplementationName()
-{
- return "ScAccessibleFilterMenuItem";
-}
-
-// XAccessibleAction
-
-sal_Int32 ScAccessibleFilterMenuItem::getAccessibleActionCount()
-{
- return 1;
-}
-
-sal_Bool ScAccessibleFilterMenuItem::doAccessibleAction(sal_Int32 /*nIndex*/)
-{
- mpWindow->executeMenuItem(mnMenuPos);
- return true;
-}
-
-OUString ScAccessibleFilterMenuItem::getAccessibleActionDescription(sal_Int32 /*nIndex*/)
-{
- return "click";
-}
-
-Reference<XAccessibleKeyBinding> ScAccessibleFilterMenuItem::getAccessibleActionKeyBinding(
- sal_Int32 /*nIndex*/)
-{
- return Reference<XAccessibleKeyBinding>();
-}
-
-Any SAL_CALL ScAccessibleFilterMenuItem::queryInterface( uno::Type const & rType )
-{
- Any any = ScAccessibleContextBase::queryInterface(rType);
- if (any.hasValue())
- return any;
-
- return ScAccessibleFilterMenuItem_BASE::queryInterface(rType);
-}
-
-void SAL_CALL ScAccessibleFilterMenuItem::acquire() throw ()
-{
- ScAccessibleContextBase::acquire();
-}
-
-void SAL_CALL ScAccessibleFilterMenuItem::release() throw ()
-{
- ScAccessibleContextBase::release();
-}
-
-bool ScAccessibleFilterMenuItem::isSelected() const
-{
- return mpWindow->isMenuItemSelected(mnMenuPos);
-}
-
-tools::Rectangle ScAccessibleFilterMenuItem::GetBoundingBoxOnScreen() const
-{
- if (!mpWindow->IsVisible())
- return tools::Rectangle();
-
- Point aPos = mpWindow->OutputToAbsoluteScreenPixel(Point(0,0));
- Point aMenuPos;
- Size aMenuSize;
- mpWindow->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
- tools::Rectangle aRect(aPos + aMenuPos, aMenuSize);
- return aRect;
-}
-
-tools::Rectangle ScAccessibleFilterMenuItem::GetBoundingBox() const
-{
- if (!mpWindow->IsVisible())
- return tools::Rectangle();
-
- Point aMenuPos;
- Size aMenuSize;
- mpWindow->getMenuItemPosSize(mnMenuPos, aMenuPos, aMenuSize);
- tools::Rectangle aRect(aMenuPos, aMenuSize);
- return aRect;
-}
-
-void ScAccessibleFilterMenuItem::updateStateSet()
-{
- if (!mxStateSet.is())
- mxStateSet.set(new ScAccessibleStateSet);
-
- ScAccessibleStateSet* p = static_cast<ScAccessibleStateSet*>(
- mxStateSet.get());
-
- p->clear();
-
- p->insert(ENABLED);
- p->insert(FOCUSABLE);
- p->insert(SELECTABLE);
- p->insert(SENSITIVE);
- p->insert(OPAQUE);
-
- if (isSelected())
- p->insert(FOCUSED);
-
- if (isSelected())
- p->insert(SELECTED);
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx
deleted file mode 100644
index da8cefdb04c2..000000000000
--- a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx
+++ /dev/null
@@ -1,118 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed
- * with this work for additional information regarding copyright
- * ownership. The ASF licenses this file to you under the Apache
- * License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#include <AccessibleFilterTopWindow.hxx>
-#include <AccessibleFilterMenu.hxx>
-#include <checklistmenu.hxx>
-
-#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
-
-using namespace ::com::sun::star;
-using namespace ::com::sun::star::accessibility;
-using ::com::sun::star::lang::IndexOutOfBoundsException;
-using ::com::sun::star::uno::Reference;
-
-ScAccessibleFilterTopWindow::ScAccessibleFilterTopWindow(
- const Reference<XAccessible>& rxParent, ScCheckListMenuWindow* pWin, const OUString& rName) :
- ScAccessibleFilterMenu(rxParent, pWin, rName, ScMenuFloatingWindow::MENU_NOT_SELECTED)
-{
- SetName(rName);
-}
-
-ScAccessibleFilterTopWindow::~ScAccessibleFilterTopWindow()
-{
-}
-
-// XAccessibleContext
-
-sal_Int32 ScAccessibleFilterTopWindow::getAccessibleChildCount()
-{
- sal_Int32 nMenuCount = getMenuItemCount();
- return nMenuCount + 6;
-}
-
-Reference<XAccessible> ScAccessibleFilterTopWindow::getAccessibleChild(
- sal_Int32 nIndex)
-{
- if (nIndex >= getAccessibleChildCount())
- throw IndexOutOfBoundsException();
-
- sal_Int32 nMenuCount = getMenuItemCount();
- if (nIndex < nMenuCount)
- return ScAccessibleFilterMenu::getAccessibleChild(nIndex);
-
- nIndex -= nMenuCount;
- switch (nIndex)
- {
- case 0:
- return mxAccEditSearchBox;
- case 1:
- return mxAccListBox;
- case 2:
- return mxAccToggleAll;
- case 3:
- return mxAccSingleOnBtn;
- case 4:
- return mxAccSingleOffBtn;
- case 5:
- return mxAccOkBtn;
- case 6:
- return mxAccCancelBtn;
- default:
- ;
- }
-
- return Reference<XAccessible>();
-}
-
-OUString ScAccessibleFilterTopWindow::getImplementationName()
-{
- return "ScAccessibleFilterTopWindow";
-}
-
-void ScAccessibleFilterTopWindow::setAccessibleChild(
- const Reference<XAccessible>& rAccessible, ChildControlType eType)
-{
- switch (eType)
- {
- case EDIT_SEARCH_BOX:
- mxAccEditSearchBox = rAccessible;
- break;
- case LISTBOX:
- mxAccListBox = rAccessible;
- break;
- case TOGGLE_ALL:
- mxAccToggleAll = rAccessible;
- break;
- case SINGLE_ON_BTN:
- mxAccSingleOnBtn = rAccessible;
- break;
- case SINGLE_OFF_BTN:
- mxAccSingleOffBtn = rAccessible;
- break;
- case OK_BTN:
- mxAccOkBtn = rAccessible;
- break;
- case CANCEL_BTN:
- mxAccCancelBtn = rAccessible;
- break;
- }
-}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx
index cb2b00b51d58..58a8a9e861d1 100644
--- a/sc/source/ui/app/inputwin.cxx
+++ b/sc/source/ui/app/inputwin.cxx
@@ -39,6 +39,7 @@
#include <editeng/scriptspaceitem.hxx>
#include <vcl/commandevent.hxx>
#include <vcl/cursor.hxx>
+#include <vcl/edit.hxx>
#include <vcl/help.hxx>
#include <vcl/settings.hxx>
#include <svl/stritem.hxx>
diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx
index 27976641e37d..0739b81457db 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -25,438 +25,177 @@
#include <vcl/decoview.hxx>
#include <vcl/event.hxx>
+#include <vcl/floatwin.hxx>
#include <vcl/settings.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/virdev.hxx>
#include <rtl/math.hxx>
#include <tools/wintypes.hxx>
#include <unotools/charclass.hxx>
-#include <AccessibleFilterMenu.hxx>
-#include <AccessibleFilterTopWindow.hxx>
-
-#include <com/sun/star/accessibility/XAccessible.hpp>
-#include <com/sun/star/accessibility/XAccessibleContext.hpp>
-#include <vcl/svlbitm.hxx>
-#include <vcl/treelistentry.hxx>
#include <document.hxx>
using namespace com::sun::star;
using ::com::sun::star::uno::Reference;
-using ::com::sun::star::accessibility::XAccessible;
-using ::com::sun::star::accessibility::XAccessibleContext;
-ScMenuFloatingWindow::MenuItemData::MenuItemData() :
- mbEnabled(true), mbSeparator(false),
- mpSubMenuWin(static_cast<ScMenuFloatingWindow*>(nullptr))
+ScCheckListMenuControl::MenuItemData::MenuItemData()
+ : mbEnabled(true)
+ , mbSeparator(false)
{
}
-ScMenuFloatingWindow::SubMenuItemData::SubMenuItemData(ScMenuFloatingWindow* pParent) :
- mpSubMenu(nullptr),
- mnMenuPos(MENU_NOT_SELECTED),
- mpParent(pParent)
+ScCheckListMenuControl::SubMenuItemData::SubMenuItemData(ScCheckListMenuControl* pParent)
+ : mpSubMenu(nullptr)
+ , mnMenuPos(MENU_NOT_SELECTED)
+ , mpParent(pParent)
{
- maTimer.SetInvokeHandler( LINK(this, ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl) );
- maTimer.SetTimeout(mpParent->GetSettings().GetMouseSettings().GetMenuDelay());
+ maTimer.SetInvokeHandler(LINK(this, ScCheckListMenuControl::SubMenuItemData, TimeoutHdl));
+ maTimer.SetTimeout(Application::GetSettings().GetMouseSettings().GetMenuDelay());
}
-void ScMenuFloatingWindow::SubMenuItemData::reset()
+void ScCheckListMenuControl::SubMenuItemData::reset()
{
mpSubMenu = nullptr;
mnMenuPos = MENU_NOT_SELECTED;
maTimer.Stop();
}
-IMPL_LINK_NOARG(ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl, Timer *, void)
+IMPL_LINK_NOARG(ScCheckListMenuControl::SubMenuItemData, TimeoutHdl, Timer *, void)
{
mpParent->handleMenuTimeout(this);
}
-ScMenuFloatingWindow::ScMenuFloatingWindow(vcl::Window* pParent, ScDocument* pDoc, sal_uInt16 nMenuStackLevel) :
- PopupMenuFloatingWindow(pParent),
- maOpenTimer(this),
- maCloseTimer(this),
- maName("ScMenuFloatingWindow"),
- mnSelectedMenu(MENU_NOT_SELECTED),
- mnClickedMenu(MENU_NOT_SELECTED),
- mpDoc(pDoc),
- mpParentMenu(dynamic_cast<ScMenuFloatingWindow*>(pParent))
-{
- SetMenuStackLevel(nMenuStackLevel);
- SetText("ScMenuFloatingWindow");
-
- const StyleSettings& rStyle = GetSettings().GetStyleSettings();
-
- const sal_uInt16 nPopupFontHeight = 12 * GetDPIScaleFactor();
- maLabelFont = rStyle.GetLabelFont();
- maLabelFont.SetFontHeight(nPopupFontHeight);
-}
-
-ScMenuFloatingWindow::~ScMenuFloatingWindow()
-{
- disposeOnce();
-}
-
-void ScMenuFloatingWindow::dispose()
-{
- EndPopupMode();
- for (auto& rMenuItem : maMenuItems)
- rMenuItem.mpSubMenuWin.disposeAndClear();
- mpParentMenu.clear();
- PopupMenuFloatingWindow::dispose();
-}
-
-void ScMenuFloatingWindow::PopupModeEnd()
-{
- handlePopupEnd();
-}
-
-void ScMenuFloatingWindow::MouseMove(const MouseEvent& rMEvt)
-{
- const Point& rPos = rMEvt.GetPosPixel();
- size_t nSelectedMenu = getEnclosingMenuItem(rPos);
- setSelectedMenuItem(nSelectedMenu, true, false);
-
- Window::MouseMove(rMEvt);
-}
-
-void ScMenuFloatingWindow::MouseButtonDown(const MouseEvent& rMEvt)
+IMPL_LINK_NOARG(ScCheckListMenuControl, RowActivatedHdl, weld::TreeView&, bool)
{
- const Point& rPos = rMEvt.GetPosPixel();
- mnClickedMenu = getEnclosingMenuItem(rPos);
- Window::MouseButtonDown(rMEvt);
+ executeMenuItem(mxMenu->get_selected_index());
+ return true;
}
-void ScMenuFloatingWindow::MouseButtonUp(const MouseEvent& rMEvt)
+IMPL_LINK(ScCheckListMenuControl, MenuKeyInputHdl, const KeyEvent&, rKEvt, bool)
{
- executeMenuItem(mnClickedMenu);
- mnClickedMenu = MENU_NOT_SELECTED;
- Window::MouseButtonUp(rMEvt);
-}
-
-void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt)
-{
- if (maMenuItems.empty())
- {
- Window::KeyInput(rKEvt);
- return;
- }
-
const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
- bool bHandled = true;
- size_t nSelectedMenu = mnSelectedMenu;
- size_t nLastMenuPos = maMenuItems.size() - 1;
+
switch (rKeyCode.GetCode())
{
- case KEY_UP:
+ case KEY_LEFT:
{
- if (nLastMenuPos == 0)
- // There is only one menu item. Do nothing.
- break;
-
- size_t nOldPos = nSelectedMenu;
-
- if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == 0)
- nSelectedMenu = nLastMenuPos;
- else
- --nSelectedMenu;
-
- // Loop until a non-separator menu item is found.
- while (nSelectedMenu != nOldPos)
- {
- if (maMenuItems[nSelectedMenu].mbSeparator)
- {
- if (nSelectedMenu)
- --nSelectedMenu;
- else
- nSelectedMenu = nLastMenuPos;
- }
- else
- break;
- }
-
- setSelectedMenuItem(nSelectedMenu, false, false);
+ ScCheckListMenuWindow* pParentMenu = mxFrame->GetParentMenu();
+ if (pParentMenu)
+ pParentMenu->get_widget().endSubMenu(*this);
+ break;
}
- break;
- case KEY_DOWN:
- {
- if (nLastMenuPos == 0)
- // There is only one menu item. Do nothing.
- break;
-
- size_t nOldPos = nSelectedMenu;
-
- if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == nLastMenuPos)
- nSelectedMenu = 0;
- else
- ++nSelectedMenu;
-
- // Loop until a non-separator menu item is found.
- while (nSelectedMenu != nOldPos)
- {
- if (maMenuItems[nSelectedMenu].mbSeparator)
- {
- if (nSelectedMenu == nLastMenuPos)
- nSelectedMenu = 0;
- else
- ++nSelectedMenu;
- }
- else
- break;
- }
-
- setSelectedMenuItem(nSelectedMenu, false, false);
- }
- break;
- case KEY_LEFT:
- if (mpParentMenu)
- mpParentMenu->endSubMenu(this);
- break;
case KEY_RIGHT:
{
if (mnSelectedMenu >= maMenuItems.size() || mnSelectedMenu == MENU_NOT_SELECTED)
break;
const MenuItemData& rMenu = maMenuItems[mnSelectedMenu];
- if (!rMenu.mbEnabled || !rMenu.mpSubMenuWin)
+ if (!rMenu.mbEnabled || !rMenu.mxSubMenuWin)
break;
maOpenTimer.mnMenuPos = mnSelectedMenu;
- maOpenTimer.mpSubMenu = rMenu.mpSubMenuWin.get();
+ maOpenTimer.mpSubMenu = rMenu.mxSubMenuWin.get();
launchSubMenu(true);
}
- break;
- case KEY_RETURN:
- if (nSelectedMenu != MENU_NOT_SELECTED)
- executeMenuItem(nSelectedMenu);
- break;
- default:
- bHandled = false;
}
- if (!bHandled)
- Window::KeyInput(rKEvt);
+ return false;
}
-void ScMenuFloatingWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& /*rRect*/)
+IMPL_LINK_NOARG(ScCheckListMenuControl, SelectHdl, weld::TreeView&, void)
{
- const StyleSettings& rStyle = GetSettings().GetStyleSettings();
-
- SetFont(maLabelFont);
-
- Color aBackColor = rStyle.GetMenuColor();
- Color aBorderColor = rStyle.GetShadowColor();
-
- tools::Rectangle aCtrlRect(Point(0, 0), GetOutputSizePixel());
-
- // Window background
- bool bNativeDrawn = true;
- if (rRenderContext.IsNativeControlSupported(ControlType::MenuPopup, ControlPart::Entire))
+ sal_uInt32 nSelectedMenu = MENU_NOT_SELECTED;
+ if (!mxMenu->get_selected(mxScratchIter.get()))
{
- rRenderContext.SetClipRegion();
- bNativeDrawn = rRenderContext.DrawNativeControl(ControlType::MenuPopup, ControlPart::Entire, aCtrlRect,
- ControlState::ENABLED, ImplControlValue(), OUString());
- }
- else
- bNativeDrawn = false;
-
- if (!bNativeDrawn)
- {
- rRenderContext.SetFillColor(aBackColor);
- rRenderContext.SetLineColor(aBorderColor);
- rRenderContext.DrawRect(aCtrlRect);
- }
-
- // Menu items
- rRenderContext.SetTextColor(rStyle.GetMenuTextColor());
- drawAllMenuItems(rRenderContext);
-}
-
-Reference<XAccessible> ScMenuFloatingWindow::CreateAccessible()
-{
- if (!mxAccessible.is())
- {
- Reference<XAccessible> xAccParent = mpParentMenu ?
- mpParentMenu->GetAccessible() : GetAccessibleParentWindow()->GetAccessible();
-
- mxAccessible.set(new ScAccessibleFilterMenu(xAccParent, this, maName, 999));
- ScAccessibleFilterMenu* p = static_cast<ScAccessibleFilterMenu*>(
- mxAccessible.get());
-
- size_t nPos = 0;
- for (const auto& rMenuItem : maMenuItems)
+ // reselect current item if its submenu is up and the launching item
+ // became unselected
+ if (mnSelectedMenu < maMenuItems.size() &&
+ maMenuItems[mnSelectedMenu].mxSubMenuWin &&
+ maMenuItems[mnSelectedMenu].mxSubMenuWin->IsVisible())
{
- p->appendMenuItem(rMenuItem.maText, nPos);
- ++nPos;
+ mxMenu->select(mnSelectedMenu);
+ return;
}
}
+ else
+ nSelectedMenu = mxMenu->get_iter_index_in_parent(*mxScratchIter);
- return mxAccessible;
+ setSelectedMenuItem(nSelectedMenu, true, false);
}
-void ScMenuFloatingWindow::addMenuItem(const OUString& rText, Action* pAction)
+void ScCheckListMenuControl::addMenuItem(const OUString& rText, Action* pAction)
{
MenuItemData aItem;
aItem.maText = rText;
aItem.mbEnabled = true;
- aItem.mpAction.reset(pAction);
- maMenuItems.push_back(aItem);
+ aItem.mxAction.reset(pAction);
+ maMenuItems.emplace_back(std::move(aItem));
+
+ mxMenu->append_text(rText);
+ if (mbCanHaveSubMenu)
+ mxMenu->set_image(mxMenu->n_children() - 1, css::uno::Reference<css::graphic::XGraphic>(), 1);
}
-void ScMenuFloatingWindow::addSeparator()
+void ScCheckListMenuControl::addSeparator()
{
MenuItemData aItem;
aItem.mbSeparator = true;
- maMenuItems.push_back(aItem);
-}
+ maMenuItems.emplace_back(std::move(aItem));
-ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText, bool bEnabled)
-{
- MenuItemData aItem;
- aItem.maText = rText;
- aItem.mbEnabled = bEnabled;
- aItem.mpSubMenuWin.reset(VclPtr<ScMenuFloatingWindow>::Create(this, mpDoc, GetMenuStackLevel()+1));
- aItem.mpSubMenuWin->setName(rText);
- maMenuItems.push_back(aItem);
- return aItem.mpSubMenuWin.get();
+ mxMenu->append_separator("seperator" + OUString::number(maMenuItems.size()));
}
-void ScMenuFloatingWindow::handlePopupEnd()
+IMPL_LINK(ScCheckListMenuControl, TreeSizeAllocHdl, const Size&, rSize, void)
{
- clearSelectedMenuItem();
+ assert(mbCanHaveSubMenu);
+ std::vector<int> aWidths;
+ aWidths.push_back(rSize.Width() - (mxMenu->get_text_height() * 3) / 4 - 6);
+ mxMenu->set_column_fixed_widths(aWidths);
}
-Size ScMenuFloatingWindow::getMenuSize() const
+void ScCheckListMenuControl::CreateDropDown()
{
- if (maMenuItems.empty())
- return Size();
-
- auto itr = std::max_element(maMenuItems.begin(), maMenuItems.end(),
- [this](const MenuItemData& a, const MenuItemData& b) {
- long aTextWidth = a.mbSeparator ? 0 : GetTextWidth(a.maText);
- long bTextWidth = b.mbSeparator ? 0 : GetTextWidth(b.maText);
- return aTextWidth < bTextWidth;
- });
- long nTextWidth = itr->mbSeparator ? 0 : GetTextWidth(itr->maText);
-
- size_t nLastPos = maMenuItems.size()-1;
- Point aPos;
- Size aSize;
- getMenuItemPosSize(nLastPos, aPos, aSize);
- aPos.AdjustX(nTextWidth + 15 );
- aPos.AdjustY(aSize.Height() + 5 );
- return Size(aPos.X(), aPos.Y());
+ int nWidth = (mxMenu->get_text_height() * 3) / 4;
+ mxDropDown->SetOutputSizePixel(Size(nWidth, nWidth));
+ DecorationView aDecoView(mxDropDown.get());
+ aDecoView.DrawSymbol(tools::Rectangle(Point(0, 0), Size(nWidth, nWidth)),
+ SymbolType::SPIN_RIGHT, mxDropDown->GetTextColor(),
+ DrawSymbolFlags::NONE);
}
-void ScMenuFloatingWindow::drawMenuItem(vcl::RenderContext& rRenderContext, size_t nPos)
+ScCheckListMenuWindow* ScCheckListMenuControl::addSubMenuItem(const OUString& rText, bool bEnabled)
{
- if (nPos >= maMenuItems.size())
- return;
-
- Point aPos;
- Size aSize;
- getMenuItemPosSize(nPos, aPos, aSize);
-
- DecorationView aDecoView(&rRenderContext);
- long const nXOffset = 5;
- long nYOffset = (aSize.Height() - maLabelFont.GetFontHeight())/2;
-
- // Make sure the label font is used for the menu item text.
- rRenderContext.Push(PushFlags::FONT);
- rRenderContext.SetFont(maLabelFont);
- rRenderContext. DrawCtrlText(Point(aPos.X()+nXOffset, aPos.Y() + nYOffset), maMenuItems[nPos].maText, 0,
- maMenuItems[nPos].maText.getLength(),
- maMenuItems[nPos].mbEnabled ? DrawTextFlags::Mnemonic : DrawTextFlags::Disable);
- rRenderContext.Pop();
-
- if (maMenuItems[nPos].mpSubMenuWin)
- {
- long nFontHeight = maLabelFont.GetFontHeight();
- Point aMarkerPos = aPos;
- aMarkerPos.AdjustY(aSize.Height() / 2 - nFontHeight / 4 + 1 );
- aMarkerPos.AdjustX(aSize.Width() - nFontHeight + nFontHeight / 4 );
- Size aMarkerSize(nFontHeight / 2, nFontHeight / 2);
- aDecoView.DrawSymbol(tools::Rectangle(aMarkerPos, aMarkerSize), SymbolType::SPIN_RIGHT, GetTextColor());
- }
-}
-
-void ScMenuFloatingWindow::drawSeparator(vcl::RenderContext& rRenderContext, size_t nPos)
-{
- Point aPos;
- Size aSize;
- getMenuItemPosSize(nPos, aPos, aSize);
- tools::Rectangle aRegion(aPos,aSize);
-
- if (rRenderContext.IsNativeControlSupported(ControlType::MenuPopup, ControlPart::Entire))
- {
- rRenderContext.Push(PushFlags::CLIPREGION);
- rRenderContext.IntersectClipRegion(aRegion);
- tools::Rectangle aCtrlRect(Point(0,0), GetOutputSizePixel());
- rRenderContext.DrawNativeControl(ControlType::MenuPopup, ControlPart::Entire, aCtrlRect,
- ControlState::ENABLED, ImplControlValue(), OUString());
-
- rRenderContext.Pop();
- }
+ assert(mbCanHaveSubMenu);
- bool bNativeDrawn = false;
- if (rRenderContext.IsNativeControlSupported(ControlType::MenuPopup, ControlPart::Separator))
- {
- ControlState nState = ControlState::NONE;
- const MenuItemData& rData = maMenuItems[nPos];
- if (rData.mbEnabled)
- nState |= ControlState::ENABLED;
-
- bNativeDrawn = rRenderContext.DrawNativeControl(ControlType::MenuPopup, ControlPart::Separator,
- aRegion, nState, ImplControlValue(), OUString());
- }
-
- if (!bNativeDrawn)
- {
- const StyleSettings& rStyle = rRenderContext.GetSettings().GetStyleSettings();
- Point aTmpPos = aPos;
- aTmpPos.AdjustY(aSize.Height() / 2 );
- rRenderContext.SetLineColor(rStyle.GetShadowColor());
- rRenderContext.DrawLine(aTmpPos, Point(aSize.Width() + aTmpPos.X(), aTmpPos.Y()));
- aTmpPos.AdjustY( 1 );
- rRenderContext.SetLineColor(rStyle.GetLightColor());
- rRenderContext.DrawLine(aTmpPos, Point(aSize.Width() + aTmpPos.X(), aTmpPos.Y()));
- rRenderContext.SetLineColor();
- }
-}
+ MenuItemData aItem;
+ aItem.maText = rText;
+ aItem.mbEnabled = bEnabled;
+ vcl::Window *pContainer = mxFrame->GetWindow(GetWindowType::FirstChild);
+ aItem.mxSubMenuWin.reset(VclPtr<ScCheckListMenuWindow>::Create(pContainer, mpDoc, false, -1, mxFrame->GetMenuStackLevel()+1, mxFrame.get()));
+ maMenuItems.emplace_back(std::move(aItem));
-void ScMenuFloatingWindow::drawAllMenuItems(vcl::RenderContext& rRenderContext)
-{
- size_t n = maMenuItems.size();
+ mxMenu->append_text(rText);
+ if (mbCanHaveSubMenu)
+ mxMenu->set_image(mxMenu->n_children() - 1, *mxDropDown, 1);
- for (size_t i = 0; i < n; ++i)
- {
- if (maMenuItems[i].mbSeparator)
- {
- // Separator
- drawSeparator(rRenderContext, i);
- }
- else
- {
- // Normal menu item
- highlightMenuItem(rRenderContext, i, i == mnSelectedMenu);
- }
- }
+ return maMenuItems.back().mxSubMenuWin.get();
}
-void ScMenuFloatingWindow::executeMenuItem(size_t nPos)
+void ScCheckListMenuControl::executeMenuItem(size_t nPos)
{
if (nPos >= maMenuItems.size())
return;
- if (!maMenuItems[nPos].mpAction)
+ if (!maMenuItems[nPos].mxAction)
// no action is defined.
return;
terminateAllPopupMenus();
- maMenuItems[nPos].mpAction->execute();
+ maMenuItems[nPos].mxAction->execute();
}
-void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu)
+void ScCheckListMenuControl::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu)
{
if (mnSelectedMenu == nPos)
// nothing to do.
@@ -466,34 +205,24 @@ void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer,
{
// Dismiss any child popup menu windows.
if (mnSelectedMenu < maMenuItems.size() &&
- maMenuItems[mnSelectedMenu].mpSubMenuWin &&
- maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
+ maMenuItems[mnSelectedMenu].mxSubMenuWin &&
+ maMenuItems[mnSelectedMenu].mxSubMenuWin->IsVisible())
{
- maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
+ maMenuItems[mnSelectedMenu].mxSubMenuWin->get_widget().ensureSubMenuNotVisible();
}
-
- // The popup is not visible, yet a menu item is selected. The request
- // most likely comes from the accessible object. Make sure this
- // window, as well as all its parent windows are visible.
- if (!IsVisible() && mpParentMenu)
- mpParentMenu->ensureSubMenuVisible(this);
}
- selectMenuItem(mnSelectedMenu, false, bSubMenuTimer);
- selectMenuItem(nPos, true, bSubMenuTimer);
- mnSelectedMenu = nPos;
-
- fireMenuHighlightedEvent();
+ selectMenuItem(nPos, bSubMenuTimer);
}
-void ScMenuFloatingWindow::handleMenuTimeout(const SubMenuItemData* pTimer)
+void ScCheckListMenuControl::handleMenuTimeout(const SubMenuItemData* pTimer)
{
if (pTimer == &maOpenTimer)
{
// Close any open submenu immediately.
if (maCloseTimer.mpSubMenu)
{
- maCloseTimer.mpSubMenu->EndPopupMode();
+ vcl::Window::GetDockingManager()->EndPopupMode(maCloseTimer.mpSubMenu);
maCloseTimer.mpSubMenu = nullptr;
maCloseTimer.maTimer.Stop();
}
@@ -507,16 +236,15 @@ void ScMenuFloatingWindow::handleMenuTimeout(const SubMenuItemData* pTimer)
{
maOpenTimer.mpSubMenu = nullptr;
- maCloseTimer.mpSubMenu->EndPopupMode();
+ vcl::Window::GetDockingManager()->EndPopupMode(maCloseTimer.mpSubMenu);
maCloseTimer.mpSubMenu = nullptr;
- Invalidate();
maOpenTimer.mnMenuPos = MENU_NOT_SELECTED;
}
}
}
-void ScMenuFloatingWindow::queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu)
+void ScCheckListMenuControl::queueLaunchSubMenu(size_t nPos, ScCheckListMenuWindow* pMenu)
{
if (!pMenu)
return;
@@ -540,7 +268,7 @@ void ScMenuFloatingWindow::queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow*
maOpenTimer.maTimer.Start();
}
-void ScMenuFloatingWindow::queueCloseSubMenu()
+void ScCheckListMenuControl::queueCloseSubMenu()
{
if (!maOpenTimer.mpSubMenu)
// There is no submenu to close.
@@ -554,61 +282,58 @@ void ScMenuFloatingWindow::queueCloseSubMenu()
maCloseTimer.maTimer.Start();
}
-void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos)
+void ScCheckListMenuControl::launchSubMenu(bool bSetMenuPos)
{
- Point aPos;
- Size aSize;
- getMenuItemPosSize(maOpenTimer.mnMenuPos, aPos, aSize);
- ScMenuFloatingWindow* pSubMenu = maOpenTimer.mpSubMenu;
-
+ ScCheckListMenuWindow* pSubMenu = maOpenTimer.mpSubMenu;
if (!pSubMenu)
return;
- FloatWinPopupFlags nOldFlags = GetPopupModeFlags();
- SetPopupModeFlags(nOldFlags | FloatWinPopupFlags::NoAppFocusClose);
- pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
- pSubMenu->StartPopupMode(
- tools::Rectangle(aPos,aSize), (FloatWinPopupFlags::Right | FloatWinPopupFlags::GrabFocus));
- pSubMenu->AddPopupModeWindow(this);
+ if (!mxMenu->get_selected(mxScratchIter.get()))
+ return;
+
+ tools::Rectangle aRect = mxMenu->get_row_area(*mxScratchIter);
+ ScCheckListMenuControl& rSubMenuControl = pSubMenu->get_widget();
+ rSubMenuControl.StartPopupMode(aRect, (FloatWinPopupFlags::Right | FloatWinPopupFlags::GrabFocus));
if (bSetMenuPos)
- pSubMenu->setSelectedMenuItem(0, false, false); // select menu item after the popup becomes fully visible.
- SetPopupModeFlags(nOldFlags);
+ rSubMenuControl.setSelectedMenuItem(0, false, false); // select menu item after the popup becomes fully visible.
+
+ mxMenu->select(*mxScratchIter);
+ rSubMenuControl.GrabFocus();
}
-void ScMenuFloatingWindow::endSubMenu(ScMenuFloatingWindow* pSubMenu)
+IMPL_LINK_NOARG(ScCheckListMenuControl, PostPopdownHdl, void*, void)
{
- if (!pSubMenu)
- return;
+ mnAsyncPostPopdownId = nullptr;
+ mxMenu->grab_focus();
+}
- pSubMenu->EndPopupMode();
+void ScCheckListMenuControl::endSubMenu(ScCheckListMenuControl& rSubMenu)
+{
+ rSubMenu.EndPopupMode();
maOpenTimer.reset();
- size_t nMenuPos = getSubMenuPos(pSubMenu);
+ // 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));
+
+ size_t nMenuPos = getSubMenuPos(&rSubMenu);
if (nMenuPos != MENU_NOT_SELECTED)
{
mnSelectedMenu = nMenuPos;
- Invalidate();
- fireMenuHighlightedEvent();
+ mxMenu->select(mnSelectedMenu);
}
}
-void ScMenuFloatingWindow::fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const
+void ScCheckListMenuControl::resizeToFitMenuItems()
{
- size_t nPos = 0;
- for (const auto& rMenuItem : maMenuItems)
- {
- pAccMenu->appendMenuItem(rMenuItem.maText, nPos);
- ++nPos;
- }
+ mxMenu->set_size_request(-1, mxMenu->get_preferred_size().Height() + 2);
}
-void ScMenuFloatingWindow::resizeToFitMenuItems()
+void ScCheckListMenuControl::selectMenuItem(size_t nPos, bool bSubMenuTimer)
{
- SetOutputSizePixel(getMenuSize());
-}
+ mxMenu->select(nPos == MENU_NOT_SELECTED ? -1 : nPos);
+ mnSelectedMenu = nPos;
-void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer)
-{
if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED)
{
queueCloseSubMenu();
@@ -621,18 +346,18 @@ void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSub
return;
}
- Invalidate();
- if (bSelected)
+ if (nPos != MENU_NOT_SELECTED)
{
- if (mpParentMenu)
- mpParentMenu->setSubMenuFocused(this);
+ ScCheckListMenuWindow* pParentMenu = mxFrame->GetParentMenu();
+ if (pParentMenu)
+ pParentMenu->get_widget().setSubMenuFocused(this);
if (bSubMenuTimer)
{
- if (maMenuItems[nPos].mpSubMenuWin)
+ if (maMenuItems[nPos].mxSubMenuWin)
{
- ScMenuFloatingWindow* pSubMenu = maMenuItems[nPos].mpSubMenuWin.get();
+ ScCheckListMenuWindow* pSubMenu = maMenuItems[nPos].mxSubMenuWin.get();
queueLaunchSubMenu(nPos, pSubMenu);
}
else
@@ -641,209 +366,70 @@ void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSub
}
}
-void ScMenuFloatingWindow::clearSelectedMenuItem()
+void ScCheckListMenuControl::clearSelectedMenuItem()
{
- selectMenuItem(mnSelectedMenu, false, false);
- mnSelectedMenu = MENU_NOT_SELECTED;
-}
-
-ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const
-{
- if (maMenuItems.size() <= nPos)
- return nullptr;
-
- return maMenuItems[nPos].mpSubMenuWin.get();
+ selectMenuItem(MENU_NOT_SELECTED, false);
}
-bool ScMenuFloatingWindow::isMenuItemSelected(size_t nPos) const
-{
- return nPos == mnSelectedMenu;
-}
-
-void ScMenuFloatingWindow::setName(const OUString& rName)
-{
- maName = rName;
-}
-
-void ScMenuFloatingWindow::highlightMenuItem(vcl::RenderContext& rRenderContext, size_t nPos, bool bSelected)
-{
- if (nPos == MENU_NOT_SELECTED)
- return;
-
- const StyleSettings& rStyle = rRenderContext.GetSettings().GetStyleSettings();
- Color aBackColor = rStyle.GetMenuColor();
- rRenderContext.SetFillColor(aBackColor);
- rRenderContext.SetLineColor(aBackColor);
-
- Point aPos;
- Size aSize;
- getMenuItemPosSize(nPos, aPos, aSize);
- tools::Rectangle aRegion(aPos,aSize);
-
- if (rRenderContext.IsNativeControlSupported(ControlType::MenuPopup, ControlPart::Entire))
- {
- rRenderContext.Push(PushFlags::CLIPREGION);
- rRenderContext.IntersectClipRegion(tools::Rectangle(aPos, aSize));
- tools::Rectangle aCtrlRect(Point(0,0), GetOutputSizePixel());
- rRenderContext.DrawNativeControl(ControlType::MenuPopup, ControlPart::Entire, aCtrlRect, ControlState::ENABLED,
- ImplControlValue(), OUString());
- rRenderContext.Pop();
- }
-
- bool bNativeDrawn = true;
- if (rRenderContext.IsNativeControlSupported(ControlType::MenuPopup, ControlPart::MenuItem))
- {
- ControlState nState = bSelected ? ControlState::SELECTED : ControlState::NONE;
- if (maMenuItems[nPos].mbEnabled)
- nState |= ControlState::ENABLED;
- bNativeDrawn = rRenderContext.DrawNativeControl(ControlType::MenuPopup, ControlPart::MenuItem,
- aRegion, nState, ImplControlValue(), OUString());
- }
- else
- bNativeDrawn = false;
-
- if (!bNativeDrawn)
- {
- if (bSelected)
- {
- aBackColor = rStyle.GetMenuHighlightColor();
- rRenderContext.SetFillColor(aBackColor);
- rRenderContext.SetLineColor(aBackColor);
- }
- rRenderContext.DrawRect(tools::Rectangle(aPos,aSize));
- }
-
- Color aTextColor = bSelected ? rStyle.GetMenuHighlightTextColor() : rStyle.GetMenuTextColor();
- rRenderContext.SetTextColor(aTextColor);
- drawMenuItem(rRenderContext, nPos);
-}
-
-void ScMenuFloatingWindow::getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const
-{
- size_t nCount = maMenuItems.size();
- if (nPos >= nCount)
- return;
-
- const sal_uInt16 nLeftMargin = 5;
- const sal_uInt16 nTopMargin = 5;
- const sal_uInt16 nMenuItemHeight = static_cast<sal_uInt16>(maLabelFont.GetFontHeight()*1.8);
- const sal_uInt16 nSepHeight = static_cast<sal_uInt16>(maLabelFont.GetFontHeight()*0.8);
-
- Point aPos1(nLeftMargin, nTopMargin);
- rPos = aPos1;
- for (size_t i = 0; i < nPos; ++i)
- rPos.AdjustY(maMenuItems[i].mbSeparator ? nSepHeight : nMenuItemHeight );
-
- Size aWndSize = GetSizePixel();
- sal_uInt16 nH = maMenuItems[nPos].mbSeparator ? nSepHeight : nMenuItemHeight;
- rSize = Size(aWndSize.Width() - nLeftMargin*2, nH);
-}
-
-size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const
-{
- size_t n = maMenuItems.size();
- for (size_t i = 0; i < n; ++i)
- {
- Point aPos;
- Size aSize;
- getMenuItemPosSize(i, aPos, aSize);
- tools::Rectangle aRect(aPos, aSize);
- if (aRect.IsInside(rPos))
- return maMenuItems[i].mbSeparator ? MENU_NOT_SELECTED : i;
- }
- return MENU_NOT_SELECTED;
-}
-
-size_t ScMenuFloatingWindow::getSubMenuPos(const ScMenuFloatingWindow* pSubMenu)
+size_t ScCheckListMenuControl::getSubMenuPos(const ScCheckListMenuControl* pSubMenu)
{
size_t n = maMenuItems.size();
for (size_t i = 0; i < n; ++i)
{
- if (maMenuItems[i].mpSubMenuWin.get() == pSubMenu)
+ if (!maMenuItems[i].mxSubMenuWin)
+ continue;
+ if (&maMenuItems[i].mxSubMenuWin->get_widget() == pSubMenu)
return i;
}
return MENU_NOT_SELECTED;
}
-void ScMenuFloatingWindow::fireMenuHighlightedEvent()
-{
- if (mnSelectedMenu == MENU_NOT_SELECTED)
- return;
-
- if (!mxAccessible.is())
- return;
-
- Reference<XAccessibleContext> xAccCxt = mxAccessible->getAccessibleContext();
- if (!xAccCxt.is())
- return;
-
- Reference<XAccessible> xAccMenu = xAccCxt->getAccessibleChild(mnSelectedMenu);
- if (!xAccMenu.is())
- return;
-
- VclAccessibleEvent aEvent(VclEventId::MenuHighlight, xAccMenu);
- FireVclEvent(aEvent);
-}
-
-void ScMenuFloatingWindow::setSubMenuFocused(const ScMenuFloatingWindow* pSubMenu)
+void ScCheckListMenuControl::setSubMenuFocused(const ScCheckListMenuControl* pSubMenu)
{
maCloseTimer.reset();
size_t nMenuPos = getSubMenuPos(pSubMenu);
if (mnSelectedMenu != nMenuPos)
{
mnSelectedMenu = nMenuPos;
- Invalidate();
+ mxMenu->select(mnSelectedMenu);
}
}
-void ScMenuFloatingWindow::ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu)
+void ScCheckListMenuControl::EndPopupMode()
{
- if (mpParentMenu)
- mpParentMenu->ensureSubMenuVisible(this);
-
- if (pSubMenu->IsVisible())
- return;
+ vcl::Window::GetDockingManager()->EndPopupMode(mxFrame);
+ mxFrame->EnableDocking(false);
+}
- // Find the menu position of the submenu.
- size_t nMenuPos = getSubMenuPos(pSubMenu);
- if (nMenuPos != MENU_NOT_SELECTED)
- {
- setSelectedMenuItem(nMenuPos, false, false);
-
- Point aPos;
- Size aSize;
- getMenuItemPosSize(nMenuPos, aPos, aSize);
-
- FloatWinPopupFlags nOldFlags = GetPopupModeFlags();
- SetPopupModeFlags(nOldFlags | FloatWinPopupFlags::NoAppFocusClose);
- pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
- pSubMenu->StartPopupMode(
- tools::Rectangle(aPos,aSize), (FloatWinPopupFlags::Right | FloatWinPopupFlags::GrabFocus));
- pSubMenu->AddPopupModeWindow(this);
- SetPopupModeFlags(nOldFlags);
- }
+void ScCheckListMenuControl::StartPopupMode(const tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags)
+{
+ mxFrame->EnableDocking(true);
+ DockingManager* pDockingManager = vcl::Window::GetDockingManager();
+ pDockingManager->SetPopupModeEndHdl(mxFrame, LINK(this, ScCheckListMenuControl, PopupModeEndHdl));
+ pDockingManager->StartPopupMode(mxFrame, rRect, nPopupModeFlags);
}
-void ScMenuFloatingWindow::ensureSubMenuNotVisible()
+void ScCheckListMenuControl::ensureSubMenuNotVisible()
{
if (mnSelectedMenu < maMenuItems.size() &&
- maMenuItems[mnSelectedMenu].mpSubMenuWin &&
- maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
+ maMenuItems[mnSelectedMenu].mxSubMenuWin &&
+ maMenuItems[mnSelectedMenu].mxSubMenuWin->IsVisible())
{
- maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
+ maMenuItems[mnSelectedMenu].mxSubMenuWin->get_widget().ensureSubMenuNotVisible();
}
EndPopupMode();
}
-void ScMenuFloatingWindow::terminateAllPopupMenus()
+void ScCheckListMenuControl::terminateAllPopupMenus()
{
EndPopupMode();
- if (mpParentMenu)
- mpParentMenu->terminateAllPopupMenus();
+ ScCheckListMenuWindow* pParentMenu = mxFrame->GetParentMenu();
+ if (pParentMenu)
+ pParentMenu->get_widget().terminateAllPopupMenus();
}
-ScCheckListMenuWindow::Config::Config() :
+ScCheckListMenuControl::Config::Config() :
mbAllowEmptySet(true), mbRTL(false)
{
}
@@ -853,67 +439,104 @@ ScCheckListMember::ScCheckListMember()
, mbDate(false)
, mbLeaf(false)
, meDatePartType(YEAR)
- , mpParent(nullptr)
{
}
-ScCheckListMenuWindow::CancelButton::CancelButton(ScCheckListMenuWindow* pParent) :
- ::CancelButton(pParent), mpParent(pParent) {}
-
-ScCheckListMenuWindow::CancelButton::~CancelButton()
+ScCheckListMenuControl::ScCheckListMenuControl(ScCheckListMenuWindow* pParent, vcl::Window* pContainer,
+ ScDocument* pDoc, bool bCanHaveSubMenu, int nWidth)
+ : mxFrame(pParent)
+ , mxBuilder(Application::CreateInterimBuilder(pContainer, "modules/scalc/ui/filterdropdown.ui"))
+ , mxContainer(mxBuilder->weld_container("FilterDropDown"))
+ , mxMenu(mxBuilder->weld_tree_view("menu"))
+ , mxScratchIter(mxMenu->make_iterator())
+ , mxEdSearch(mxBuilder->weld_entry("search_edit"))
+ , mxBox(mxBuilder->weld_widget("box"))
+ , mxChecks(mxBuilder->weld_tree_view("check_list_box"))
+ , mxChkToggleAll(mxBuilder->weld_check_button("toggle_all"))
+ , mxBtnSelectSingle(mxBuilder->weld_button("select_current"))
+ , mxBtnUnselectSingle(mxBuilder->weld_button("unselect_current"))
+ , mxButtonBox(mxBuilder->weld_box("buttonbox"))
+ , mxBtnOk(mxBuilder->weld_button("ok"))
+ , mxBtnCancel(mxBuilder->weld_button("cancel"))
+ , mxDropDown(mxMenu->create_virtual_device())
+ , mnWidthHint(nWidth)
+ , maWndSize()
+ , mePrevToggleAllState(TRISTATE_INDET)
+ , mnSelectedMenu(MENU_NOT_SELECTED)
+ , mpDoc(pDoc)
+ , mnAsyncPostPopdownId(nullptr)
+ , mbHasDates(false)
+ , mbCanHaveSubMenu(bCanHaveSubMenu)
+ , maOpenTimer(this)
+ , maCloseTimer(this)
{
- disposeOnce();
+ // sort ok/cancel into native order, if this was a dialog they would be auto-sorted, but this
+ // popup isn't a true dialog
+ mxButtonBox->sort_native_button_order();
+
+ mxChecks->enable_toggle_buttons(weld::ColumnToggleType::Check);
+
+ 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 (mbCanHaveSubMenu)
+ {
+ CreateDropDown();
+ mxMenu->connect_size_allocate(LINK(this, ScCheckListMenuControl, TreeSizeAllocHdl));
+ }
}
-void ScCheckListMenuWindow::CancelButton::dispose()
+IMPL_LINK_NOARG(ScCheckListMenuControl, FocusHdl, weld::Widget&, void)
{
- mpParent.clear();
- ::CancelButton::dispose();
+ GrabFocus();
}
-void ScCheckListMenuWindow::CancelButton::Click()
+void ScCheckListMenuControl::GrabFocus()
{
- mpParent->EndPopupMode();
- ::CancelButton::Click();
+ if (mxEdSearch->get_visible())
+ mxEdSearch->grab_focus();
+ else
+ {
+ mxMenu->set_cursor(0);
+ mxMenu->grab_focus();
+ }
}
-ScCheckListMenuWindow::ScCheckListMenuWindow(vcl::Window* pParent, ScDocument* pDoc, int nWidth) :
- ScMenuFloatingWindow(pParent, pDoc),
- maEdSearch(VclPtr<ScSearchEdit>::Create(this)),
- maChecks(VclPtr<ScCheckListBox>::Create(this)),
- maChkToggleAll(VclPtr<CheckBox>::Create(this, 0)),
- maBtnSelectSingle(VclPtr<ImageButton>::Create(this, 0)),
- maBtnUnselectSingle(VclPtr<ImageButton>::Create(this, 0)),
- maBtnOk(VclPtr<OKButton>::Create(this)),
- maBtnCancel(VclPtr<CancelButton>::Create(this)),
- maWndSize(),
- mePrevToggleAllState(TRISTATE_INDET),
- maTabStops(this),
- mbHasDates(false)
+ScCheckListMenuControl::~ScCheckListMenuControl()
{
- maChkToggleAll->EnableTriState(true);
-
- float fScaleFactor = GetDPIScaleFactor();
-
- nWidth = std::max<int>(nWidth, 200 * fScaleFactor);
- maWndSize = Size(nWidth, 330 * fScaleFactor);
-
- maTabStops.AddTabStop( this );
- maTabStops.AddTabStop( maEdSearch.get() );
- maTabStops.AddTabStop( maChecks.get() );
- maTabStops.AddTabStop( maChkToggleAll.get() );
- maTabStops.AddTabStop( maBtnSelectSingle.get() );
- maTabStops.AddTabStop( maBtnUnselectSingle.get() );
- maTabStops.AddTabStop( maBtnOk.get() );
- maTabStops.AddTabStop( maBtnCancel.get() );
-
- maEdSearch->SetTabStopsContainer( &maTabStops );
- maChecks->SetTabStopsContainer( &maTabStops );
+ EndPopupMode();
+ for (auto& rMenuItem : maMenuItems)
+ rMenuItem.mxSubMenuWin.disposeAndClear();
+ if (mnAsyncPostPopdownId)
+ {
+ Application::RemoveUserEvent(mnAsyncPostPopdownId);
+ mnAsyncPostPopdownId = nullptr;
+ }
+}
+ScCheckListMenuWindow::ScCheckListMenuWindow(vcl::Window* pParent, ScDocument* pDoc, bool bCanHaveSubMenu,
+ int nWidth, sal_uInt16 nMenuStackLevel, ScCheckListMenuWindow* pParentMenu)
+ : DockingWindow(pParent, "InterimDockParent", "svx/ui/interimdockparent.ui")
+ , mxParentMenu(pParentMenu)
+ , mxBox(get("box"))
+ , mxControl(new ScCheckListMenuControl(this, mxBox.get(), pDoc, bCanHaveSubMenu, nWidth))
+ , mnMenuStackLevel(nMenuStackLevel)
+{
+ SetBackground(Application::GetSettings().GetStyleSettings().GetMenuColor());
set_id("check_list_menu");
- maChkToggleAll->set_id("toggle_all");
- maBtnSelectSingle->set_id("select_current");
- maBtnUnselectSingle->set_id("unselect_current");
+}
+
+bool ScCheckListMenuWindow::EventNotify(NotifyEvent& rNEvt)
+{
+ if (rNEvt.GetType() == MouseNotifyEvent::MOUSEMOVE)
+ {
+ ScCheckListMenuControl& rMenuControl = get_widget();
+ rMenuControl.queueCloseSubMenu();
+ rMenuControl.clearSelectedMenuItem();
+ }
+ return DockingWindow::EventNotify(rNEvt);
}
ScCheckListMenuWindow::~ScCheckListMenuWindow()
@@ -923,315 +546,123 @@ ScCheckListMenuWindow::~ScCheckListMenuWindow()
void ScCheckListMenuWindow::dispose()
{
- maTabStops.clear();
- maEdSearch.disposeAndClear();
- maChecks.disposeAndClear();
- maChkToggleAll.disposeAndClear();
- maBtnSelectSingle.disposeAndClear();
- maBtnUnselectSingle.disposeAndClear();
- maBtnOk.disposeAndClear();
- maBtnCancel.disposeAndClear();
- ScMenuFloatingWindow::dispose();
-}
-
-void ScCheckListMenuWindow::getSectionPosSize(
- Point& rPos, Size& rSize, SectionType eType) const
-{
- float fScaleFactor = GetDPIScaleFactor();
-
- // constant parameters.
- const long nSearchBoxMargin = 10 *fScaleFactor;
- const long nListBoxMargin = 5 * fScaleFactor; // horizontal distance from the side of the dialog to the listbox border.
- const long nListBoxInnerPadding = 5 * fScaleFactor;
- const long nTopMargin = 5 * fScaleFactor;
- const long nMenuHeight = maMenuSize.getHeight();
- const long nSingleItemBtnAreaHeight = 32 * fScaleFactor; // height of the middle area below the list box where the single-action buttons are.
- const long nBottomBtnAreaHeight = 50 * fScaleFactor; // height of the bottom area where the OK and Cancel buttons are.
- const long nBtnWidth = 90 * fScaleFactor;
- const long nLabelHeight = getLabelFont().GetFontHeight();
- const long nBtnHeight = nLabelHeight * 2;
- const long nBottomMargin = 10 * fScaleFactor;
- const long nMenuListMargin = 5 * fScaleFactor;
- const long nSearchBoxHeight = nLabelHeight * 2;
-
- // parameters calculated from constants.
- const long nListBoxWidth = maWndSize.Width() - nListBoxMargin*2;
- const long nListBoxHeight = maWndSize.Height() - nTopMargin - nMenuHeight -
- nMenuListMargin - nSearchBoxHeight - nSearchBoxMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight;
-
- const long nSingleBtnAreaY = nTopMargin + nMenuHeight + nMenuListMargin + nSearchBoxHeight + nSearchBoxMargin;
-
- switch (eType)
- {
- case WHOLE:
- {
- rPos = Point(0, 0);
- rSize = maWndSize;
- }
- break;
- case EDIT_SEARCH:
- {
- rPos = Point(nSearchBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
- rSize = Size(maWndSize.Width() - 2*nSearchBoxMargin, nSearchBoxHeight);
- }
- break;
- case SINGLE_BTN_AREA:
- {
- rPos = Point(nListBoxMargin, nSingleBtnAreaY);
- rSize = Size(nListBoxWidth, nSingleItemBtnAreaHeight);
- }
- break;
- case CHECK_TOGGLE_ALL:
- {
- long h = std::min(maChkToggleAll->CalcMinimumSize().Height(), 26L);
- rPos = Point(nListBoxMargin, nSingleBtnAreaY);
- rPos.AdjustX(5 );
- rPos.AdjustY((nSingleItemBtnAreaHeight - h)/2 );
- rSize = Size(70, h);
- }
- break;
- case BTN_SINGLE_SELECT:
- {
- long h = 26 * fScaleFactor;
- rPos = Point(nListBoxMargin, nSingleBtnAreaY);
- rPos.AdjustX(nListBoxWidth - h - 10 - h - 10 );
- rPos.AdjustY((nSingleItemBtnAreaHeight - h)/2 );
- rSize = Size(h, h);
- }
- break;
- case BTN_SINGLE_UNSELECT:
- {
- long h = 26 * fScaleFactor;
- rPos = Point(nListBoxMargin, nSingleBtnAreaY);
- rPos.AdjustX(nListBoxWidth - h - 10 );
- rPos.AdjustY((nSingleItemBtnAreaHeight - h)/2 );
- rSize = Size(h, h);
- }
- break;
- case LISTBOX_AREA_OUTER:
- {
- rPos = Point(nListBoxMargin, nSingleBtnAreaY + nSingleItemBtnAreaHeight-1);
- rSize = Size(nListBoxWidth, nListBoxHeight);
- }
- break;
- case LISTBOX_AREA_INNER:
- {
- rPos = Point(nListBoxMargin, nSingleBtnAreaY + nSingleItemBtnAreaHeight-1);
- rPos.AdjustX(nListBoxInnerPadding );
- rPos.AdjustY(nListBoxInnerPadding );
-
- rSize = Size(nListBoxWidth, nListBoxHeight);
- rSize.AdjustWidth( -(nListBoxInnerPadding*2) );
- rSize.AdjustHeight( -(nListBoxInnerPadding*2) );
- }
- break;
- case BTN_OK:
- {
- long x = (maWndSize.Width() - nBtnWidth*2)/3;
- long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
- rPos = Point(x, y);
- rSize = Size(nBtnWidth, nBtnHeight);
- }
- break;
- case BTN_CANCEL:
- {
- long x = (maWndSize.Width() - nBtnWidth*2)/3*2 + nBtnWidth;
- long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
- rPos = Point(x, y);
- rSize = Size(nBtnWidth, nBtnHeight);
- }
- break;
- default:
- ;
- }
+ mxControl.reset();
+ mxBox.disposeAndClear();
+ mxParentMenu.clear();
+ DockingWindow::dispose();
}
-void ScCheckListMenuWindow::packWindow()
+void ScCheckListMenuWindow::GetFocus()
{
- maMenuSize = getMenuSize();
-
- if (maWndSize.Width() < maMenuSize.Width())
- // Widen the window to fit the menu items.
- maWndSize.setWidth( maMenuSize.Width() );
-
- // Set proper window height based on the number of menu items.
- if (maWndSize.Height() < maMenuSize.Height()*2.8)
- maWndSize.setHeight( maMenuSize.Height()*2.8 );
-
- // TODO: Make sure the window height never exceeds the height of the
- // screen. Also do adjustment based on the number of check box items.
-
- SetOutputSizePixel(maWndSize);
-
- const StyleSettings& rStyle = GetSettings().GetStyleSettings();
-
- Point aPos;
- Size aSize;
- getSectionPosSize(aPos, aSize, WHOLE);
- SetOutputSizePixel(aSize);
-
- getSectionPosSize(aPos, aSize, BTN_OK);
- maBtnOk->SetPosSizePixel(aPos, aSize);
- maBtnOk->SetFont(getLabelFont());
- maBtnOk->SetClickHdl( LINK(this, ScCheckListMenuWindow, ButtonHdl) );
- maBtnOk->Show();
-
- getSectionPosSize(aPos, aSize, BTN_CANCEL);
- maBtnCancel->SetPosSizePixel(aPos, aSize);
- maBtnCancel->SetFont(getLabelFont());
- maBtnCancel->Show();
-
- getSectionPosSize(aPos, aSize, EDIT_SEARCH);
- maEdSearch->SetPosSizePixel(aPos, aSize);
- maEdSearch->SetFont(getLabelFont());
- maEdSearch->SetControlBackground(rStyle.GetFieldColor());
- maEdSearch->SetPlaceholderText(ScResId(STR_EDIT_SEARCH_ITEMS));
- maEdSearch->SetModifyHdl( LINK(this, ScCheckListMenuWindow, EdModifyHdl) );
- maEdSearch->Show();
-
- getSectionPosSize(aPos, aSize, LISTBOX_AREA_INNER);
- maChecks->SetPosSizePixel(aPos, aSize);
- maChecks->SetFont(getLabelFont());
- maChecks->SetCheckButtonHdl( LINK(this, ScCheckListMenuWindow, CheckHdl) );
- maChecks->Show();
-
- getSectionPosSize(aPos, aSize, CHECK_TOGGLE_ALL);
- maChkToggleAll->SetPosSizePixel(aPos, aSize);
- maChkToggleAll->SetFont(getLabelFont());
- maChkToggleAll->SetText(ScResId(STR_BTN_TOGGLE_ALL));
- maChkToggleAll->SetTextColor(rStyle.GetMenuTextColor());
- maChkToggleAll->SetControlBackground(rStyle.GetMenuColor());
- maChkToggleAll->SetClickHdl( LINK(this, ScCheckListMenuWindow, TriStateHdl) );
- maChkToggleAll->Show();
-
- float fScaleFactor = GetDPIScaleFactor();
-
- ;
+ DockingWindow::GetFocus();
+ if (!mxControl)
+ return;
+ mxControl->GrabFocus();
+}
- getSectionPosSize(aPos, aSize, BTN_SINGLE_SELECT);
- maBtnSelectSingle->SetPosSizePixel(aPos, aSize);
- maBtnSelectSingle->SetQuickHelpText(ScResId(STR_BTN_SELECT_CURRENT));
- maBtnSelectSingle->SetModeImage(Image(StockImage::Yes, RID_BMP_SELECT_CURRENT));
- maBtnSelectSingle->SetClickHdl( LINK(this, ScCheckListMenuWindow, ButtonHdl) );
- maBtnSelectSingle->Show();
+void ScCheckListMenuControl::packWindow()
+{
+ mxBox->show();
+ mxEdSearch->show();
+ mxButtonBox->show();
- BitmapEx aSingleUnselectBmp(RID_BMP_UNSELECT_CURRENT);
- if (fScaleFactor > 1)
- aSingleUnselectBmp.Scale(fScaleFactor, fScaleFactor, BmpScaleFlag::Fast);
- Image aSingleUnselect(aSingleUnselectBmp);
+ 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));
+ mxChecks->connect_toggled(LINK(this, ScCheckListMenuControl, CheckHdl));
+ mxChecks->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));
- getSectionPosSize(aPos, aSize, BTN_SINGLE_UNSELECT);
- maBtnUnselectSingle->SetPosSizePixel(aPos, aSize);
- maBtnUnselectSingle->SetQuickHelpText(ScResId(STR_BTN_UNSELECT_CURRENT));
- maBtnUnselectSingle->SetModeImage(aSingleUnselect);
- maBtnUnselectSingle->SetClickHdl( LINK(this, ScCheckListMenuWindow, ButtonHdl) );
- maBtnUnselectSingle->Show();
-}
+ mxChecks->set_size_request(-1, mxChecks->get_height_rows(9));
+ mxMenu->set_size_request(-1, mxMenu->get_preferred_size().Height() + 2);
+ mnSelectedMenu = 0;
+ mxMenu->set_cursor(mnSelectedMenu);
+ mxMenu->unselect_all();
-void ScCheckListMenuWindow::setAllMemberState(bool bSet)
-{
- size_t n = maMembers.size();
- std::set<SvTreeListEntry*> aParents;
- for (size_t i = 0; i < n; ++i)
+ maWndSize = mxContainer->get_preferred_size();
+ if (maWndSize.Width() < mnWidthHint)
{
- aParents.insert(maMembers[i].mpParent);
+ mxContainer->set_size_request(mnWidthHint, -1);
+ maWndSize.setWidth(mnWidthHint);
}
+}
- for (const auto& pParent : aParents)
- {
- if (!pParent)
- {
- sal_uInt32 nCount = maChecks->GetEntryCount();
- for( sal_uInt32 i = 0; i < nCount; ++i)
- {
- SvTreeListEntry* pEntry = maChecks->GetEntry(i);
- if (!pEntry)
- continue;
-
- maChecks->CheckEntry(pEntry, bSet);
- }
- }
- else
- {
- SvTreeListEntries& rEntries = pParent->GetChildEntries();
- for (const auto& rxEntry : rEntries)
- {
- maChecks->CheckEntry(rxEntry.get(), bSet);
- }
- }
- }
+void ScCheckListMenuControl::setAllMemberState(bool bSet)
+{
+ CheckAllChildren(nullptr, bSet);
if (!maConfig.mbAllowEmptySet)
+ {
// We need to have at least one member selected.
- maBtnOk->Enable(maChecks->GetCheckedEntryCount() != 0);
+ mxBtnOk->set_sensitive(GetCheckedEntryCount() != 0);
+ }
}
-void ScCheckListMenuWindow::selectCurrentMemberOnly(bool bSet)
+void ScCheckListMenuControl::selectCurrentMemberOnly(bool bSet)
{
setAllMemberState(!bSet);
- SvTreeListEntry* pEntry = maChecks->GetCurEntry();
- if (!pEntry)
+ std::unique_ptr<weld::TreeIter> xEntry = mxChecks->make_iterator();
+ if (!mxChecks->get_cursor(xEntry.get()))
return;
- maChecks->CheckEntry(pEntry, bSet );
-
- // Make sure all checkboxes are invalidated.
- Invalidate();
+ mxChecks->set_toggle(*xEntry, bSet ? TRISTATE_TRUE : TRISTATE_FALSE);
}
-IMPL_LINK( ScCheckListMenuWindow, ButtonHdl, Button*, pBtn, void )
+IMPL_LINK(ScCheckListMenuControl, ButtonHdl, weld::Button&, rBtn, void)
{
- if (pBtn == maBtnOk.get())
+ if (&rBtn == mxBtnOk.get())
close(true);
- else if (pBtn == maBtnSelectSingle.get())
- {
- selectCurrentMemberOnly(true);
- CheckHdl(maChecks.get());
- }
- else if (pBtn == maBtnUnselectSingle.get())
+ else if (&rBtn == mxBtnCancel.get())
+ close(false);
+ else if (&rBtn == mxBtnSelectSingle.get() || &rBtn == mxBtnUnselectSingle.get())
{
- selectCurrentMemberOnly(false);
- CheckHdl(maChecks.get());
+ selectCurrentMemberOnly(&rBtn == mxBtnSelectSingle.get());
+ std::unique_ptr<weld::TreeIter> xEntry = mxChecks->make_iterator();
+ if (!mxChecks->get_cursor(xEntry.get()))
+ xEntry.reset();
+ Check(xEntry.get());
}
}
-IMPL_LINK_NOARG(ScCheckListMenuWindow, TriStateHdl, Button*, void)
+IMPL_LINK_NOARG(ScCheckListMenuControl, TriStateHdl, weld::ToggleButton&, void)
{
switch (mePrevToggleAllState)
{
case TRISTATE_FALSE:
- maChkToggleAll->SetState(TRISTATE_TRUE);
+ mxChkToggleAll->set_state(TRISTATE_TRUE);
setAllMemberState(true);
break;
case TRISTATE_TRUE:
- maChkToggleAll->SetState(TRISTATE_FALSE);
+ mxChkToggleAll->set_state(TRISTATE_FALSE);
setAllMemberState(false);
break;
case TRISTATE_INDET:
default:
- maChkToggleAll->SetState(TRISTATE_TRUE);
+ mxChkToggleAll->set_state(TRISTATE_TRUE);
setAllMemberState(true);
break;
}
- mePrevToggleAllState = maChkToggleAll->GetState();
- maTabStops.SetTabStop(maChkToggleAll); // Needed for when accelerator is used
+ mePrevToggleAllState = mxChkToggleAll->get_state();
}
-IMPL_LINK_NOARG(ScCheckListMenuWindow, EdModifyHdl, Edit&, void)
+IMPL_LINK_NOARG(ScCheckListMenuControl, EdModifyHdl, weld::Entry&, void)
{
- OUString aSearchText = maEdSearch->GetText();
+ OUString aSearchText = mxEdSearch->get_text();
aSearchText = ScGlobal::getCharClassPtr()->lowercase( aSearchText );
bool bSearchTextEmpty = aSearchText.isEmpty();
size_t n = maMembers.size();
size_t nSelCount = 0;
bool bSomeDateDeletes = false;
- maChecks->SetUpdateMode(false);
+ mxChecks->freeze();
if (bSearchTextEmpty && !mbHasDates)
{
// when there are a lot of rows, it is cheaper to simply clear the tree and re-initialise
- maChecks->Clear();
+ mxChecks->clear();
nSelCount = initMembers();
}
else
@@ -1260,8 +691,8 @@ IMPL_LINK_NOARG(ScCheckListMenuWindow, EdModifyHdl, Edit&, void)
if ( bSearchTextEmpty )
{
- SvTreeListEntry* pLeaf = maChecks->ShowCheckEntry( aLabelDisp, maMembers[i], true, maMembers[i].mbVisible );
- updateMemberParents( pLeaf, i );
+ auto xLeaf = ShowCheckEntry(aLabelDisp, maMembers[i], true, maMembers[i].mbVisible);
+ updateMemberParents(xLeaf.get(), i);
if ( maMembers[i].mbVisible )
++nSelCount;
continue;
@@ -1269,13 +700,13 @@ IMPL_LINK_NOARG(ScCheckListMenuWindow, EdModifyHdl, Edit&, void)
if ( bPartialMatch )
{
- SvTreeListEntry* pLeaf = maChecks->ShowCheckEntry( aLabelDisp, maMembers[i] );
- updateMemberParents( pLeaf, i );
+ auto xLeaf = ShowCheckEntry(aLabelDisp, maMembers[i]);
+ updateMemberParents(xLeaf.get(), i);
++nSelCount;
}
else
{
- maChecks->ShowCheckEntry( aLabelDisp, maMembers[i], false, false );
+ ShowCheckEntry(aLabelDisp, maMembers[i], false, false);
if( bIsDate )
bSomeDateDeletes = true;
}
@@ -1286,115 +717,69 @@ IMPL_LINK_NOARG(ScCheckListMenuWindow, EdModifyHdl, Edit&, void)
{
for (size_t i = 0; i < n; ++i)
{
- if ( !maMembers[i].mbDate ) continue;
- if ( maMembers[i].meDatePartType != ScCheckListMember::DAY ) continue;
- updateMemberParents( nullptr, i );
+ if (!maMembers[i].mbDate)
+ continue;
+ if (maMembers[i].meDatePartType != ScCheckListMember::DAY)
+ continue;
+ updateMemberParents(nullptr, i);
}
}
- maChecks->SetUpdateMode(true);
+ mxChecks->thaw();
if ( nSelCount == n )
- maChkToggleAll->SetState( TRISTATE_TRUE );
+ mxChkToggleAll->set_state( TRISTATE_TRUE );
else if ( nSelCount == 0 )
- maChkToggleAll->SetState( TRISTATE_FALSE );
+ mxChkToggleAll->set_state( TRISTATE_FALSE );
else
- maChkToggleAll->SetState( TRISTATE_INDET );
+ mxChkToggleAll->set_state( TRISTATE_INDET );
if ( !maConfig.mbAllowEmptySet )
{
const bool bEmptySet( nSelCount == 0 );
- maChecks->Enable( !bEmptySet );
- maChkToggleAll->Enable( !bEmptySet );
- maBtnSelectSingle->Enable( !bEmptySet );
- maBtnUnselectSingle->Enable( !bEmptySet );
- maBtnOk->Enable( !bEmptySet );
+ mxChecks->set_sensitive(!bEmptySet);
+ mxChkToggleAll->set_sensitive(!bEmptySet);
+ mxBtnSelectSingle->set_sensitive(!bEmptySet);
+ mxBtnUnselectSingle->set_sensitive(!bEmptySet);
+ mxBtnOk->set_sensitive(!bEmptySet);
}
}
-IMPL_LINK( ScCheckListMenuWindow, CheckHdl, SvTreeListBox*, pChecks, void )
+IMPL_LINK_NOARG(ScCheckListMenuControl, EdActivateHdl, weld::Entry&, bool)
{
- if (pChecks != maChecks.get())
- return;
- SvTreeListEntry* pEntry = pChecks->GetHdlEntry();
- if ( pEntry )
- maChecks->CheckEntry( pEntry, ( pChecks->GetCheckButtonState( pEntry ) == SvButtonState::Checked ) );
- size_t nNumChecked = maChecks->GetCheckedEntryCount();
+ if (mxBtnOk->get_sensitive())
+ close(true);
+ return true;
+}
+
+IMPL_LINK( ScCheckListMenuControl, CheckHdl, const weld::TreeView::iter_col&, rRowCol, void )
+{
+ Check(&rRowCol.first);
+}
+
+void ScCheckListMenuControl::Check(const weld::TreeIter* pEntry)
+{
+ if (pEntry)
+ CheckEntry(pEntry, mxChecks->get_toggle(*pEntry) == TRISTATE_TRUE);
+ size_t nNumChecked = GetCheckedEntryCount();
if (nNumChecked == maMembers.size())
// all members visible
- maChkToggleAll->SetState(TRISTATE_TRUE);
+ mxChkToggleAll->set_state(TRISTATE_TRUE);
else if (nNumChecked == 0)
// no members visible
- maChkToggleAll->SetState(TRISTATE_FALSE);
+ mxChkToggleAll->set_state(TRISTATE_FALSE);
else
- maChkToggleAll->SetState(TRISTATE_INDET);
+ mxChkToggleAll->set_state(TRISTATE_INDET);
if (!maConfig.mbAllowEmptySet)
// We need to have at least one member selected.
- maBtnOk->Enable(nNumChecked != 0);
-
- mePrevToggleAllState = maChkToggleAll->GetState();
-}
-
-void ScCheckListMenuWindow::MouseMove(const MouseEvent& rMEvt)
-{
- ScMenuFloatingWindow::MouseMove(rMEvt);
-
- size_t nSelectedMenu = getSelectedMenuItem();
- if (nSelectedMenu == MENU_NOT_SELECTED)
- queueCloseSubMenu();
-}
+ mxBtnOk->set_sensitive(nNumChecked != 0);
-bool ScCheckListMenuWindow::EventNotify(NotifyEvent& rNEvt)
-{
- MouseNotifyEvent nType = rNEvt.GetType();
- if (HasFocus() && nType == MouseNotifyEvent::GETFOCUS)
- {
- setSelectedMenuItem( 0 , false, false );
- return true;
- }
- if (nType == MouseNotifyEvent::KEYINPUT)
- {
- const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
- const vcl::KeyCode& rCode = pKeyEvent->GetKeyCode();
- const sal_uInt16 nCode = rCode.GetCode();
- if (nCode != KEY_RETURN)
- {
- bool bShift = rCode.IsShift();
- if (nCode == KEY_TAB)
- maTabStops.CycleFocus(bShift);
- return true;
- }
- }
- return ScMenuFloatingWindow::EventNotify(rNEvt);
-}
-
-void ScCheckListMenuWindow::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
-{
- ScMenuFloatingWindow::Paint(rRenderContext, rRect);
-
- const StyleSettings& rStyle = GetSettings().GetStyleSettings();
- Color aMemberBackColor = rStyle.GetFieldColor();
- Color aBorderColor = rStyle.GetShadowColor();
-
- Point aPos;
- Size aSize;
- getSectionPosSize(aPos, aSize, LISTBOX_AREA_OUTER);
-
- // Member list box background
- rRenderContext.SetFillColor(aMemberBackColor);
- rRenderContext.SetLineColor(aBorderColor);
- rRenderContext.DrawRect(tools::Rectangle(aPos,aSize));
-
- // Single-action button box
- getSectionPosSize(aPos, aSize, SINGLE_BTN_AREA);
- rRenderContext.SetFillColor(rStyle.GetMenuColor());
- rRenderContext.DrawRect(tools::Rectangle(aPos,aSize));
+ mePrevToggleAllState = mxChkToggleAll->get_state();
}
-void ScCheckListMenuWindow::updateMemberParents( const SvTreeListEntry* pLeaf, size_t nIdx )
+void ScCheckListMenuControl::updateMemberParents(const weld::TreeIter* pLeaf, size_t nIdx)
{
-
if ( !maMembers[nIdx].mbDate || maMembers[nIdx].meDatePartType != ScCheckListMember::DAY )
return;
@@ -1404,67 +789,46 @@ void ScCheckListMenuWindow::updateMemberParents( const SvTreeListEntry* pLeaf, s
if ( pLeaf )
{
- SvTreeListEntry* pMonthEntry = pLeaf->GetParent();
- SvTreeListEntry* pYearEntry = pMonthEntry ? pMonthEntry->GetParent() : nullptr;
+ std::unique_ptr<weld::TreeIter> xYearEntry;
+ std::unique_ptr<weld::TreeIter> xMonthEntry = mxChecks->make_iterator(pLeaf);
+ if (!mxChecks->iter_parent(*xMonthEntry))
+ xMonthEntry.reset();
+ else
+ {
+ xYearEntry = mxChecks->make_iterator(xMonthEntry.get());
+ if (!mxChecks->iter_parent(*xYearEntry))
+ xYearEntry.reset();
+ }
- maMembers[nIdx].mpParent = pMonthEntry;
+ maMembers[nIdx].mxParent = std::move(xMonthEntry);
if ( aItr != maYearMonthMap.end() )
{
size_t nMonthIdx = aItr->second;
- maMembers[nMonthIdx].mpParent = pYearEntry;
+ maMembers[nMonthIdx].mxParent = std::move(xYearEntry);
}
}
else
{
- SvTreeListEntry* pYearEntry = maChecks->FindEntry( nullptr, aYearName );
- if ( aItr != maYearMonthMap.end() && !pYearEntry )
+ std::unique_ptr<weld::TreeIter> xYearEntry = FindEntry(nullptr, aYearName);
+ if (aItr != maYearMonthMap.end() && !xYearEntry)
{
size_t nMonthIdx = aItr->second;
- maMembers[nMonthIdx].mpParent = nullptr;
- maMembers[nIdx].mpParent = nullptr;
+ maMembers[nMonthIdx].mxParent.reset();
+ maMembers[nIdx].mxParent.reset();
}
- else if ( pYearEntry && !maChecks->FindEntry( pYearEntry, aMonthName ) )
- maMembers[nIdx].mpParent = nullptr;
- }
-}
-
-Reference<XAccessible> ScCheckListMenuWindow::CreateAccessible()
-{
- if (!mxAccessible.is() && maEdSearch)
- {
- mxAccessible.set(new ScAccessibleFilterTopWindow(
- GetAccessibleParentWindow()->GetAccessible(), this, getName()));
- ScAccessibleFilterTopWindow* pAccTop = static_cast<ScAccessibleFilterTopWindow*>(mxAccessible.get());
- fillMenuItemsToAccessible(pAccTop);
-
- pAccTop->setAccessibleChild(
- maEdSearch->CreateAccessible(), ScAccessibleFilterTopWindow::EDIT_SEARCH_BOX);
- pAccTop->setAccessibleChild(
- maChecks->CreateAccessible(), ScAccessibleFilterTopWindow::LISTBOX);
- pAccTop->setAccessibleChild(
- maChkToggleAll->CreateAccessible(), ScAccessibleFilterTopWindow::TOGGLE_ALL);
- pAccTop->setAccessibleChild(
- maBtnSelectSingle->CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_ON_BTN);
- pAccTop->setAccessibleChild(
- maBtnUnselectSingle->CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_OFF_BTN);
- pAccTop->setAccessibleChild(
- maBtnOk->CreateAccessible(), ScAccessibleFilterTopWindow::OK_BTN);
- pAccTop->setAccessibleChild(
- maBtnCancel->CreateAccessible(), ScAccessibleFilterTopWindow::CANCEL_BTN);
+ else if (xYearEntry && !FindEntry(xYearEntry.get(), aMonthName))
+ maMembers[nIdx].mxParent.reset();
}
-
- return mxAccessible;
}
-void ScCheckListMenuWindow::setMemberSize(size_t n)
+void ScCheckListMenuControl::setMemberSize(size_t n)
{
maMembers.reserve(n);
}
-void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, bool bVisible)
+void ScCheckListMenuControl::addDateMember(const OUString& rsName, double nVal, bool bVisible)
{
- ScDocument* pDoc = getDoc();
- SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+ SvNumberFormatter* pFormatter = mpDoc->GetFormatTable();
// Convert the numeric date value to a date object.
Date aDate = pFormatter->GetNullDate();
@@ -1487,43 +851,52 @@ void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, b
if ( aDayName.getLength() == 1 )
aDayName = "0" + aDayName;
- maChecks->SetUpdateMode(false);
+ mxChecks->freeze();
- SvTreeListEntry* pYearEntry = maChecks->FindEntry(nullptr, aYearName);
- if (!pYearEntry)
+ std::unique_ptr<weld::TreeIter> xYearEntry = FindEntry(nullptr, aYearName);
+ if (!xYearEntry)
{
- pYearEntry = maChecks->InsertEntry(aYearName, nullptr, true);
+ xYearEntry = mxChecks->make_iterator();
+ mxChecks->insert(nullptr, -1, nullptr, nullptr, nullptr, nullptr, false, xYearEntry.get());
+ mxChecks->set_toggle(*xYearEntry, TRISTATE_FALSE);
+ mxChecks->set_text(*xYearEntry, aYearName, 0);
ScCheckListMember aMemYear;
aMemYear.maName = aYearName;
aMemYear.maRealName = rsName;
aMemYear.mbDate = true;
aMemYear.mbLeaf = false;
aMemYear.mbVisible = bVisible;
- aMemYear.mpParent = nullptr;
+ aMemYear.mxParent.reset();
aMemYear.meDatePartType = ScCheckListMember::YEAR;
- maMembers.push_back(aMemYear);
+ maMembers.emplace_back(std::move(aMemYear));
}
- SvTreeListEntry* pMonthEntry = maChecks->FindEntry(pYearEntry, aMonthName);
- if (!pMonthEntry)
+ std::unique_ptr<weld::TreeIter> xMonthEntry = FindEntry(xYearEntry.get(), aMonthName);
+ if (!xMonthEntry)
{
- pMonthEntry = maChecks->InsertEntry(aMonthName, pYearEntry, true);
+ xMonthEntry = mxChecks->make_iterator();
+ mxChecks->insert(xYearEntry.get(), -1, nullptr, nullptr, nullptr, nullptr, false, xMonthEntry.get());
+ mxChecks->set_toggle(*xMonthEntry, TRISTATE_FALSE);
+ mxChecks->set_text(*xMonthEntry, aMonthName, 0);
ScCheckListMember aMemMonth;
aMemMonth.maName = aMonthName;
aMemMonth.maRealName = rsName;
aMemMonth.mbDate = true;
aMemMonth.mbLeaf = false;
aMemMonth.mbVisible = bVisible;
- aMemMonth.mpParent = pYearEntry;
+ aMemMonth.mxParent = std::move(xYearEntry);
aMemMonth.meDatePartType = ScCheckListMember::MONTH;
- maMembers.push_back(aMemMonth);
+ maMembers.emplace_back(std::move(aMemMonth));
maYearMonthMap[aYearName + aMonthName] = maMembers.size() - 1;
}
- SvTreeListEntry* pDayEntry = maChecks->FindEntry(pMonthEntry, aDayName);
- if (!pDayEntry)
+ std::unique_ptr<weld::TreeIter> xDayEntry = FindEntry(xMonthEntry.get(), aDayName);
+ if (!xDayEntry)
{
- maChecks->InsertEntry(aDayName, pMonthEntry);
+ xDayEntry = mxChecks->make_iterator();
+ mxChecks->insert(xMonthEntry.get(), -1, nullptr, nullptr, nullptr, nullptr, false, xDayEntry.get());
+ mxChecks->set_toggle(*xDayEntry, TRISTATE_FALSE);
+ mxChecks->set_text(*xDayEntry, aDayName, 0);
ScCheckListMember aMemDay;
aMemDay.maName = aDayName;
aMemDay.maRealName = rsName;
@@ -1533,168 +906,65 @@ void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, b
aMemDay.mbDate = true;
aMemDay.mbLeaf = true;
aMemDay.mbVisible = bVisible;
- aMemDay.mpParent = pMonthEntry;
+ aMemDay.mxParent = std::move(xMonthEntry);
aMemDay.meDatePartType = ScCheckListMember::DAY;
- maMembers.push_back(aMemDay);
+ maMembers.emplace_back(std::move(aMemDay));
}
- maChecks->SetUpdateMode(true);
+ mxChecks->thaw();
}
-void ScCheckListMenuWindow::addMember(const OUString& rName, bool bVisible)
+void ScCheckListMenuControl::addMember(const OUString& rName, bool bVisible)
{
ScCheckListMember aMember;
aMember.maName = rName;
aMember.mbDate = false;
aMember.mbLeaf = true;
aMember.mbVisible = bVisible;
- aMember.mpParent = nullptr;
- maMembers.push_back(aMember);
+ aMember.mxParent.reset();
+ maMembers.emplace_back(std::move(aMember));
}
-ScTabStops::ScTabStops( ScCheckListMenuWindow* pMenuWin ) :
- mpMenuWindow( pMenuWin ),
- maControlToPos( ControlToPosMap() ),
- mnCurTabStop(0)
+std::unique_ptr<weld::TreeIter> ScCheckListMenuControl::FindEntry(const weld::TreeIter* pParent, const OUString& sNode)
{
- maControls.reserve( 8 );
-}
-
-ScTabStops::~ScTabStops()
-{}
-
-void ScTabStops::AddTabStop( vcl::Window* pWin )
-{
- maControls.emplace_back(pWin );
- maControlToPos[pWin] = maControls.size() - 1;
-}
-
-void ScTabStops::SetTabStop( vcl::Window* pWin )
-{
- if ( maControls.empty() )
- return;
- ControlToPosMap::const_iterator aIter = maControlToPos.find( pWin );
- if ( aIter == maControlToPos.end() )
- return;
- if ( aIter->second == mnCurTabStop )
- return;
- if ( mnCurTabStop < maControls.size() )
- {
- maControls[mnCurTabStop]->SetFakeFocus( false );
- maControls[mnCurTabStop]->LoseFocus();
- }
- mnCurTabStop = aIter->second;
- maControls[mnCurTabStop]->SetFakeFocus( true );
- maControls[mnCurTabStop]->GrabFocus();
-}
-
-void ScTabStops::CycleFocus( bool bReverse )
-{
- if (maControls.empty())
- return;
- if ( mnCurTabStop < maControls.size() )
+ std::unique_ptr<weld::TreeIter> xEntry = mxChecks->make_iterator(pParent);
+ bool bEntry = pParent ? mxChecks->iter_children(*xEntry) : mxChecks->get_iter_first(*xEntry);
+ while (bEntry)
{
- maControls[mnCurTabStop]->SetFakeFocus( false );
- maControls[mnCurTabStop]->LoseFocus();
- }
- else
- mnCurTabStop = 0;
-
- if ( mpMenuWindow && mnCurTabStop == 0 )
- mpMenuWindow->clearSelectedMenuItem();
-
- size_t nIterCount = 0;
-
- if ( bReverse )
- {
- do
- {
- if ( mnCurTabStop > 0 )
- --mnCurTabStop;
- else
- mnCurTabStop = maControls.size() - 1;
- ++nIterCount;
- } while ( nIterCount <= maControls.size() && !maControls[mnCurTabStop]->IsEnabled() );
- }
- else
- {
- do
- {
- ++mnCurTabStop;
- if ( mnCurTabStop >= maControls.size() )
- mnCurTabStop = 0;
- ++nIterCount;
- } while ( nIterCount <= maControls.size() && !maControls[mnCurTabStop]->IsEnabled() );
- }
-
- if ( nIterCount <= maControls.size() )
- {
- maControls[mnCurTabStop]->SetFakeFocus( true );
- maControls[mnCurTabStop]->GrabFocus();
- }
- // else : all controls are disabled, so can't do anything
-}
-
-void ScTabStops::clear()
-{
- mnCurTabStop = 0;
- maControlToPos.clear();
- maControls.clear();
-}
-
-ScCheckListBox::ScCheckListBox( vcl::Window* pParent )
- : SvTreeListBox( pParent, 0 ), mbSeenMouseButtonDown( false )
-{
- Init();
- set_id("check_list_box");
-}
-
-SvTreeListEntry* ScCheckListBox::FindEntry( SvTreeListEntry* pParent, const OUString& sNode )
-{
- sal_uInt32 nRootPos = 0;
- SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : GetEntry( nRootPos );
- while ( pEntry )
- {
- if ( sNode == GetEntryText( pEntry ) )
- return pEntry;
-
- pEntry = pParent ? pEntry->NextSibling() : GetEntry( ++nRootPos );
+ if (sNode == mxChecks->get_text(*xEntry, 0))
+ return xEntry;
+ bEntry = mxChecks->iter_next_sibling(*xEntry);
}
return nullptr;
}
-void ScCheckListBox::Init()
+void ScCheckListMenuControl::GetRecursiveChecked(const weld::TreeIter* pEntry, std::unordered_set<OUString>& vOut,
+ OUString& rLabel)
{
- mpCheckButton.reset( new SvLBoxButtonData( this ) );
- EnableCheckButton( mpCheckButton.get() );
- SetNodeDefaultImages();
-}
-
-void ScCheckListBox::GetRecursiveChecked( SvTreeListEntry* pEntry, std::unordered_set<OUString>& vOut,
- OUString& rLabel )
-{
- if (GetCheckButtonState(pEntry) == SvButtonState::Checked)
+ if (mxChecks->get_toggle(*pEntry) == TRISTATE_TRUE)
{
// We have to hash parents and children together.
// Per convention for easy access in getResult()
// "child;parent;grandparent" while descending.
if (rLabel.isEmpty())
- rLabel = GetEntryText(pEntry);
+ rLabel = mxChecks->get_text(*pEntry, 0);
else
- rLabel = GetEntryText(pEntry) + ";" + rLabel;
+ rLabel = mxChecks->get_text(*pEntry, 0) + ";" + rLabel;
// Prerequisite: the selection mechanism guarantees that if a child is
// selected then also the parent is selected, so we only have to
// inspect the children in case the parent is selected.
- if (pEntry->HasChildren())
+ if (mxChecks->iter_has_child(*pEntry))
{
- const SvTreeListEntries& rChildren = pEntry->GetChildEntries();
- for (auto& rChild : rChildren)
+ std::unique_ptr<weld::TreeIter> xChild(mxChecks->make_iterator(pEntry));
+ bool bChild = mxChecks->iter_children(*xChild);
+ while (bChild)
{
OUString aLabel = rLabel;
- GetRecursiveChecked( rChild.get(), vOut, aLabel);
+ GetRecursiveChecked(xChild.get(), vOut, aLabel);
if (!aLabel.isEmpty() && aLabel != rLabel)
- vOut.insert( aLabel);
+ vOut.insert(aLabel);
+ bChild = mxChecks->iter_next_sibling(*xChild);
}
// Let the caller not add the parent alone.
rLabel.clear();
@@ -1702,228 +972,215 @@ void ScCheckListBox::GetRecursiveChecked( SvTreeListEntry* pEntry, std::unordere
}
}
-std::unordered_set<OUString> ScCheckListBox::GetAllChecked()
+std::unordered_set<OUString> ScCheckListMenuControl::GetAllChecked()
{
std::unordered_set<OUString> vResults(0);
- sal_uInt32 nRootPos = 0;
- SvTreeListEntry* pEntry = GetEntry(nRootPos);
- while (pEntry)
+
+ std::unique_ptr<weld::TreeIter> xEntry = mxChecks->make_iterator();
+ bool bEntry = mxChecks->get_iter_first(*xEntry);
+ while (bEntry)
{
OUString aLabel;
- GetRecursiveChecked( pEntry, vResults, aLabel);
+ GetRecursiveChecked(xEntry.get(), vResults, aLabel);
if (!aLabel.isEmpty())
- vResults.insert( aLabel);
- pEntry = GetEntry(++nRootPos);
+ vResults.insert(aLabel);
+ bEntry = mxChecks->iter_next_sibling(*xEntry);
}
return vResults;
}
-bool ScCheckListBox::IsChecked( const OUString& sName, SvTreeListEntry* pParent )
+bool ScCheckListMenuControl::IsChecked(const OUString& sName, const weld::TreeIter* pParent)
{
- SvTreeListEntry* pEntry = FindEntry( pParent, sName );
- return pEntry && GetCheckButtonState( pEntry ) == SvButtonState::Checked;
+ std::unique_ptr<weld::TreeIter> xEntry = FindEntry(pParent, sName);
+ return xEntry && mxChecks->get_toggle(*xEntry) == TRISTATE_TRUE;
}
-void ScCheckListBox::CheckEntry( const OUString& sName, SvTreeListEntry* pParent, bool bCheck )
+void ScCheckListMenuControl::CheckEntry(const OUString& sName, const weld::TreeIter* pParent, bool bCheck)
{
- SvTreeListEntry* pEntry = FindEntry( pParent, sName );
- if ( pEntry )
- CheckEntry( pEntry, bCheck );
+ std::unique_ptr<weld::TreeIter> xEntry = FindEntry(pParent, sName);
+ if (xEntry)
+ CheckEntry(xEntry.get(), bCheck);
}
// Recursively check all children of pParent
-void ScCheckListBox::CheckAllChildren( SvTreeListEntry* pParent, bool bCheck )
+void ScCheckListMenuControl::CheckAllChildren(const weld::TreeIter* pParent, bool bCheck)
{
- if ( pParent )
+ if (pParent)
+ mxChecks->set_toggle(*pParent, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
+ std::unique_ptr<weld::TreeIter> xEntry = mxChecks->make_iterator(pParent);
+ bool bEntry = pParent ? mxChecks->iter_children(*xEntry) : mxChecks->get_iter_first(*xEntry);
+ while (bEntry)
{
- SetCheckButtonState(
- pParent, bCheck ? SvButtonState::Checked : SvButtonState::Unchecked );
- }
- SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : First();
- while ( pEntry )
- {
- CheckAllChildren( pEntry, bCheck );
- pEntry = pEntry->NextSibling();
+ CheckAllChildren(xEntry.get(), bCheck);
+ bEntry = mxChecks->iter_next_sibling(*xEntry);
}
}
-void ScCheckListBox::CheckEntry( SvTreeListEntry* pParent, bool bCheck )
+void ScCheckListMenuControl::CheckEntry(const weld::TreeIter* pParent, bool bCheck)
{
// recursively check all items below pParent
- CheckAllChildren( pParent, bCheck );
+ CheckAllChildren(pParent, bCheck);
// checking pParent can affect ancestors, e.g. if ancestor is unchecked and pParent is
// now checked then the ancestor needs to be checked also
- SvTreeListEntry* pAncestor = GetParent(pParent);
- if ( pAncestor )
+ if (pParent && mxChecks->get_iter_depth(*pParent))
{
- while ( pAncestor )
+ std::unique_ptr<weld::TreeIter> xAncestor(mxChecks->make_iterator(pParent));
+ bool bAncestor = mxChecks->iter_parent(*xAncestor);
+ while (bAncestor)
{
// if any first level children checked then ancestor
// needs to be checked, similarly if no first level children
// checked then ancestor needs to be unchecked
- SvTreeListEntry* pChild = FirstChild( pAncestor );
+ std::unique_ptr<weld::TreeIter> xChild(mxChecks->make_iterator(xAncestor.get()));
+ bool bChild = mxChecks->iter_children(*xChild);
bool bChildChecked = false;
- while ( pChild )
+ while (bChild)
{
- if ( GetCheckButtonState( pChild ) == SvButtonState::Checked )
+ if (mxChecks->get_toggle(*xChild) == TRISTATE_TRUE)
{
bChildChecked = true;
break;
}
- pChild = pChild->NextSibling();
+ bChild = mxChecks->iter_next_sibling(*xChild);
}
- SetCheckButtonState( pAncestor, bChildChecked ? SvButtonState::Checked : SvButtonState::Unchecked );
- pAncestor = GetParent(pAncestor);
+ mxChecks->set_toggle(*xAncestor, bChildChecked ? TRISTATE_TRUE : TRISTATE_FALSE);
+ bAncestor = mxChecks->iter_parent(*xAncestor);
}
}
}
-SvTreeListEntry* ScCheckListBox::ShowCheckEntry( const OUString& sName, ScCheckListMember& rMember, bool bShow, bool bCheck )
+std::unique_ptr<weld::TreeIter> ScCheckListMenuControl::ShowCheckEntry(const OUString& sName, ScCheckListMember& rMember, bool bShow, bool bCheck)
{
- SvTreeListEntry* pEntry = nullptr;
- if (!rMember.mbDate || rMember.mpParent)
- pEntry = FindEntry( rMember.mpParent, sName );
+ std::unique_ptr<weld::TreeIter> xEntry;
+ if (!rMember.mbDate || rMember.mxParent)
+ xEntry = FindEntry(rMember.mxParent.get(), sName);
if ( bShow )
{
- if ( !pEntry )
+ if (!xEntry)
{
if (rMember.mbDate)
{
if (rMember.maDateParts.empty())
return nullptr;
- SvTreeListEntry* pYearEntry = FindEntry( nullptr, rMember.maDateParts[0] );
- if ( !pYearEntry )
- pYearEntry = InsertEntry( rMember.maDateParts[0], nullptr, true );
- SvTreeListEntry* pMonthEntry = FindEntry( pYearEntry, rMember.maDateParts[1] );
- if ( !pMonthEntry )
- pMonthEntry = InsertEntry( rMember.maDateParts[1], pYearEntry, true );
- SvTreeListEntry* pDayEntry = FindEntry( pMonthEntry, rMember.maName );
- if ( !pDayEntry )
- pDayEntry = InsertEntry( rMember.maName, pMonthEntry );
-
- return pDayEntry; // Return leaf node
+ std::unique_ptr<weld::TreeIter> xYearEntry = FindEntry(nullptr, rMember.maDateParts[0]);
+ if (!xYearEntry)
+ {
+ xYearEntry = mxChecks->make_iterator();
+ mxChecks->insert(nullptr, -1, nullptr, nullptr, nullptr, nullptr, false, xYearEntry.get());
+ mxChecks->set_toggle(*xYearEntry, TRISTATE_FALSE);
+ mxChecks->set_text(*xYearEntry, rMember.maDateParts[0], 0);
+ }
+ std::unique_ptr<weld::TreeIter> xMonthEntry = FindEntry(xYearEntry.get(), rMember.maDateParts[1]);
+ if (!xMonthEntry)
+ {
+ xMonthEntry = mxChecks->make_iterator();
+ mxChecks->insert(xYearEntry.get(), -1, nullptr, nullptr, nullptr, nullptr, false, xMonthEntry.get());
+ mxChecks->set_toggle(*xMonthEntry, TRISTATE_FALSE);
+ mxChecks->set_text(*xMonthEntry, rMember.maDateParts[1], 0);
+ }
+ std::unique_ptr<weld::TreeIter> xDayEntry = FindEntry(xMonthEntry.get(), rMember.maName);
+ if (!xDayEntry)
+ {
+ xDayEntry = mxChecks->make_iterator();
+ mxChecks->insert(xMonthEntry.get(), -1, nullptr, nullptr, nullptr, nullptr, false, xDayEntry.get());
+ mxChecks->set_toggle(*xDayEntry, TRISTATE_FALSE);
+ mxChecks->set_text(*xDayEntry, rMember.maName, 0);
+ }
+ return xDayEntry; // Return leaf node
}
- pEntry = InsertEntry(
- sName);
-
- SetCheckButtonState(
- pEntry, bCheck ? SvButtonState::Checked : SvButtonState::Unchecked);
+ xEntry = mxChecks->make_iterator();
+ mxChecks->append(xEntry.get());
+ mxChecks->set_toggle(*xEntry, bCheck ? TRISTATE_TRUE : TRISTATE_FALSE);
+ mxChecks->set_text(*xEntry, sName, 0);
}
else
- CheckEntry( pEntry, bCheck );
+ CheckEntry(xEntry.get(), bCheck);
}
- else if ( pEntry )
+ else if (xEntry)
{
- GetModel()->Remove( pEntry );
- SvTreeListEntry* pParent = rMember.mpParent;
- while ( pParent && !pParent->HasChildren() )
+ mxChecks->remove(*xEntry);
+ if (rMember.mxParent)
{
- SvTreeListEntry* pTmp = pParent;
- pParent = pTmp->GetParent();
- GetModel()->Remove( pTmp );
+ std::unique_ptr<weld::TreeIter> xParent(mxChecks->make_iterator(rMember.mxParent.get()));
+ while (xParent && !mxChecks->iter_has_child(*xParent))
+ {
+ std::unique_ptr<weld::TreeIter> xTmp(mxChecks->make_iterator(xParent.get()));
+ if (!mxChecks->iter_parent(*xParent))
+ xParent.reset();
+ mxChecks->remove(*xTmp);
+ }
}
}
return nullptr;
}
-void ScCheckListBox::CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const
+int ScCheckListMenuControl::GetCheckedEntryCount() const
{
- if ( pParent && GetCheckButtonState( pParent ) == SvButtonState::Checked )
- nCount++;
- // Iterate over the children
- SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : First();
- while ( pEntry )
- {
- CountCheckedEntries( pEntry, nCount );
- pEntry = pEntry->NextSibling();
- }
-}
+ int nRet = 0;
-sal_uInt16 ScCheckListBox::GetCheckedEntryCount() const
-{
- sal_uLong nCount = 0;
- CountCheckedEntries( nullptr, nCount );
- return nCount;
+ mxChecks->all_foreach([this, &nRet](weld::TreeIter& rEntry){
+ if (mxChecks->get_toggle(rEntry) == TRISTATE_TRUE)
+ ++nRet;
+ return false;
+ });
+
+ return nRet;
}
-void ScCheckListBox::KeyInput( const KeyEvent& rKEvt )
+IMPL_LINK(ScCheckListMenuControl, KeyInputHdl, const KeyEvent&, rKEvt, bool)
{
const vcl::KeyCode& rKey = rKEvt.GetKeyCode();
if ( rKey.GetCode() == KEY_RETURN || rKey.GetCode() == KEY_SPACE )
{
- SvTreeListEntry* pEntry = GetCurEntry();
- if ( pEntry )
+ std::unique_ptr<weld::TreeIter> xEntry = mxChecks->make_iterator();
+ bool bEntry = mxChecks->get_cursor(xEntry.get());
+ if (bEntry)
{
- bool bCheck = ( GetCheckButtonState( pEntry ) == SvButtonState::Checked );
- CheckEntry( pEntry, !bCheck );
- if ( bCheck != ( GetCheckButtonState( pEntry ) == SvButtonState::Checked ) )
- CheckButtonHdl();
+ bool bOldCheck = mxChecks->get_toggle(*xEntry) == TRISTATE_TRUE;
+ CheckEntry(xEntry.get(), !bOldCheck);
+ bool bNewCheck = mxChecks->get_toggle(*xEntry) == TRISTATE_TRUE;
+ if (bOldCheck != bNewCheck)
+ Check(xEntry.get());
}
+ return true;
}
- else if ( GetEntryCount() )
- SvTreeListBox::KeyInput( rKEvt );
-}
-
-void ScCheckListBox::MouseButtonDown(const MouseEvent& rMEvt)
-{
- SvTreeListBox::MouseButtonDown( rMEvt );
- if ( rMEvt.IsLeft() )
- mbSeenMouseButtonDown = true;
-}
-
-void ScCheckListBox::MouseButtonUp(const MouseEvent& rMEvt)
-{
- SvTreeListBox::MouseButtonUp( rMEvt );
- if ( mpTabStops && mbSeenMouseButtonDown && rMEvt.IsLeft() )
- {
- mpTabStops->SetTabStop( this );
- mbSeenMouseButtonDown = false;
- }
-}
-void ScSearchEdit::MouseButtonDown(const MouseEvent& rMEvt)
-{
- Edit::MouseButtonDown( rMEvt );
- if ( mpTabStops && rMEvt.IsLeft() && rMEvt.GetClicks() >= 1 )
- mpTabStops->SetTabStop( this );
+ return false;
}
-void ScCheckListMenuWindow::setHasDates(bool bHasDates)
+void ScCheckListMenuControl::setHasDates(bool bHasDates)
{
mbHasDates = bHasDates;
- // Enables type-ahead search in the check list box.
- maChecks->SetQuickSearch(true);
- if (mbHasDates)
- maChecks->SetStyle(WB_HASBUTTONS | WB_HASLINES | WB_HASLINESATROOT | WB_HASBUTTONSATROOT);
- else
- maChecks->SetStyle(WB_HASBUTTONS);
+ mxChecks->set_show_expanders(mbHasDates);
}
-size_t ScCheckListMenuWindow::initMembers()
+size_t ScCheckListMenuControl::initMembers()
{
size_t n = maMembers.size();
size_t nVisMemCount = 0;
- maChecks->SetUpdateMode(false);
- maChecks->GetModel()->EnableInvalidate(false);
+ mxChecks->freeze();
+
+ std::unique_ptr<weld::TreeIter> xEntry = mxChecks->make_iterator();
+ std::vector<std::unique_ptr<weld::TreeIter>> aExpandRows;
for (size_t i = 0; i < n; ++i)
{
if (maMembers[i].mbDate)
{
- maChecks->CheckEntry(maMembers[i].maName, maMembers[i].mpParent, maMembers[i].mbVisible);
+ CheckEntry(maMembers[i].maName, maMembers[i].mxParent.get(), maMembers[i].mbVisible);
// Expand first node of checked dates
- if (!maMembers[i].mpParent && maChecks->IsChecked(maMembers[i].maName, maMembers[i].mpParent))
+ if (!maMembers[i].mxParent && IsChecked(maMembers[i].maName, maMembers[i].mxParent.get()))
{
- SvTreeListEntry* pEntry = maChecks->FindEntry(nullptr, maMembers[i].maName);
- if (pEntry)
- maChecks->Expand(pEntry);
+ std::unique_ptr<weld::TreeIter> xDateEntry = FindEntry(nullptr, maMembers[i].maName);
+ if (xDateEntry)
+ aExpandRows.emplace_back(std::move(xDateEntry));
}
}
else
@@ -1931,11 +1188,10 @@ size_t ScCheckListMenuWindow::initMembers()
OUString aLabel = maMembers[i].maName;
if (aLabel.isEmpty())
aLabel = ScResId(STR_EMPTYDATA);
- SvTreeListEntry* pEntry = maChecks->InsertEntry(
- aLabel);
- maChecks->SetCheckButtonState(
- pEntry, maMembers[i].mbVisible ? SvButtonState::Checked : SvButtonState::Unchecked);
+ mxChecks->append(xEntry.get());
+ mxChecks->set_toggle(*xEntry, maMembers[i].mbVisible ? TRISTATE_TRUE : TRISTATE_FALSE);
+ mxChecks->set_text(*xEntry, aLabel, 0);
}
if (maMembers[i].mbVisible)
@@ -1944,40 +1200,46 @@ size_t ScCheckListMenuWindow::initMembers()
if (nVisMemCount == n)
{
// all members visible
- maChkToggleAll->SetState(TRISTATE_TRUE);
+ mxChkToggleAll->set_state(TRISTATE_TRUE);
mePrevToggleAllState = TRISTATE_TRUE;
}
else if (nVisMemCount == 0)
{
// no members visible
- maChkToggleAll->SetState(TRISTATE_FALSE);
+ mxChkToggleAll->set_state(TRISTATE_FALSE);
mePrevToggleAllState = TRISTATE_FALSE;
}
else
{
- maChkToggleAll->SetState(TRISTATE_INDET);
+ mxChkToggleAll->set_state(TRISTATE_INDET);
mePrevToggleAllState = TRISTATE_INDET;
}
- maChecks->GetModel()->EnableInvalidate(true);
- maChecks->SetUpdateMode(true);
+ mxChecks->thaw();
+
+ for (auto& rRow : aExpandRows)
+ mxChecks->expand_row(*rRow);
+
+ if (nVisMemCount)
+ mxChecks->select(0);
+
return nVisMemCount;
}
-void ScCheckListMenuWindow::setConfig(const Config& rConfig)
+void ScCheckListMenuControl::setConfig(const Config& rConfig)
{
maConfig = rConfig;
}
-bool ScCheckListMenuWindow::isAllSelected() const
+bool ScCheckListMenuControl::isAllSelected() const
{
- return maChkToggleAll->IsChecked();
+ return mxChkToggleAll->get_state() == TRISTATE_TRUE;
}
-void ScCheckListMenuWindow::getResult(ResultType& rResult)
+void ScCheckListMenuControl::getResult(ResultType& rResult)
{
ResultType aResult;
- std::unordered_set<OUString> vCheckeds = maChecks->GetAllChecked();
+ std::unordered_set<OUString> vCheckeds = GetAllChecked();
size_t n = maMembers.size();
for (size_t i = 0; i < n; ++i)
{
@@ -1990,12 +1252,16 @@ void ScCheckListMenuWindow::getResult(ResultType& rResult)
/* TODO: performance-wise this looks suspicious, concatenating to
* do the lookup for each leaf item seems wasteful. */
// Checked labels are in the form "child;parent;grandparent".
- for (SvTreeListEntry* pParent = maMembers[i].mpParent;
- pParent && pParent->GetFirstItem( SvLBoxItemType::String);
- pParent = pParent->GetParent())
+ if (maMembers[i].mxParent)
{
- aLabel.append(";").append(maChecks->GetEntryText( pParent));
+ std::unique_ptr<weld::TreeIter> xIter(mxChecks->make_iterator(maMembers[i].mxParent.get()));
+ do
+ {
+ aLabel.append(";").append(mxChecks->get_text(*xIter));
+ }
+ while (mxChecks->iter_parent(*xIter));
}
+
bool bState = vCheckeds.find(aLabel.makeStringAndClear()) != vCheckeds.end();
ResultEntry aResultEntry;
@@ -2011,12 +1277,12 @@ void ScCheckListMenuWindow::getResult(ResultType& rResult)
rResult.swap(aResult);
}
-void ScCheckListMenuWindow::launch(const tools::Rectangle& rRect)
+void ScCheckListMenuControl::launch(const tools::Rectangle& rRect)
{
packWindow();
if (!maConfig.mbAllowEmptySet)
// We need to have at least one member selected.
- maBtnOk->Enable(maChecks->GetCheckedEntryCount() != 0);
+ mxBtnOk->set_sensitive(GetCheckedEntryCount() != 0);
tools::Rectangle aRect(rRect);
if (maConfig.mbRTL)
@@ -2035,42 +1301,40 @@ void ScCheckListMenuWindow::launch(const tools::Rectangle& rRect)
}
StartPopupMode(aRect, (FloatWinPopupFlags::Down | FloatWinPopupFlags::GrabFocus));
- maTabStops.CycleFocus(); // Set initial focus to the search box ( index = 1 )
}
-void ScCheckListMenuWindow::close(bool bOK)
+void ScCheckListMenuControl::close(bool bOK)
{
- if (bOK && mpOKAction)
- mpOKAction->execute();
-
+ if (bOK && mxOKAction)
+ mxOKAction->execute();
EndPopupMode();
}
-void ScCheckListMenuWindow::setExtendedData(std::unique_ptr<ExtendedData> p)
+void ScCheckListMenuControl::setExtendedData(std::unique_ptr<ExtendedData> p)
{
- mpExtendedData = std::move(p);
+ mxExtendedData = std::move(p);
}
-ScCheckListMenuWindow::ExtendedData* ScCheckListMenuWindow::getExtendedData()
+ScCheckListMenuControl::ExtendedData* ScCheckListMenuControl::getExtendedData()
{
- return mpExtendedData.get();
+ return mxExtendedData.get();
}
-void ScCheckListMenuWindow::setOKAction(Action* p)
+void ScCheckListMenuControl::setOKAction(Action* p)
{
- mpOKAction.reset(p);
+ mxOKAction.reset(p);
}
-void ScCheckListMenuWindow::setPopupEndAction(Action* p)
+void ScCheckListMenuControl::setPopupEndAction(Action* p)
{
- mpPopupEndAction.reset(p);
+ mxPopupEndAction.reset(p);
}
-void ScCheckListMenuWindow::handlePopupEnd()
+IMPL_LINK_NOARG(ScCheckListMenuControl, PopupModeEndHdl, FloatingWindow*, void)
{
clearSelectedMenuItem();
- if (mpPopupEndAction)
- mpPopupEndAction->execute();
+ if (mxPopupEndAction)
+ mxPopupEndAction->execute();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx
index 9b948fb94575..c021ee40da3d 100644
--- a/sc/source/ui/docshell/docsh4.cxx
+++ b/sc/source/ui/docshell/docsh4.cxx
@@ -40,6 +40,7 @@ using namespace ::com::sun::star;
#include <svx/ofaitem.hxx>
#include <svl/stritem.hxx>
#include <svl/whiter.hxx>
+#include <vcl/button.hxx>
#include <vcl/svapp.hxx>
#include <vcl/weld.hxx>
#include <svx/dataaccessdescriptor.hxx>
diff --git a/sc/source/ui/inc/checklistmenu.hxx b/sc/source/ui/inc/checklistmenu.hxx
index 5e988e31e3d7..02c966d8f13d 100644
--- a/sc/source/ui/inc/checklistmenu.hxx
+++ b/sc/source/ui/inc/checklistmenu.hxx
@@ -10,11 +10,10 @@
#ifndef INCLUDED_SC_SOURCE_UI_INC_CHECKLISTMENU_HXX
#define INCLUDED_SC_SOURCE_UI_INC_CHECKLISTMENU_HXX
-#include <vcl/popupmenuwindow.hxx>
-#include <vcl/button.hxx>
-#include <vcl/edit.hxx>
+#include <vcl/InterimItemWindow.hxx>
+#include <vcl/dockwin.hxx>
#include <vcl/timer.hxx>
-#include <vcl/svlbitm.hxx>
+#include <vcl/weld.hxx>
#include <memory>
#include <unordered_set>
@@ -22,249 +21,12 @@
#include <map>
#include <set>
-namespace com::sun::star {
- namespace accessibility {
- class XAccessible;
- }
-}
-
class ScDocument;
-class ScAccessibleFilterMenu;
-
-class ScMenuFloatingWindow : public PopupMenuFloatingWindow
-{
-public:
- static constexpr size_t MENU_NOT_SELECTED = 999;
-
- /**
- * Action to perform when an event takes place. Create a sub-class of
- * this to implement the desired action.
- */
- class Action
- {
- public:
- virtual ~Action() {}
- virtual void execute() = 0;
- };
-
- explicit ScMenuFloatingWindow(vcl::Window* pParent, ScDocument* pDoc, sal_uInt16 nMenuStackLevel = 0);
- virtual ~ScMenuFloatingWindow() override;
- void dispose() override;
-
- virtual void PopupModeEnd() override;
- virtual void MouseMove(const MouseEvent& rMEvt) override;
- virtual void MouseButtonDown(const MouseEvent& rMEvt) override;
- virtual void MouseButtonUp(const MouseEvent& rMEvt) override;
- virtual void KeyInput(const KeyEvent& rKEvt) override;
- virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
- virtual css::uno::Reference<css::accessibility::XAccessible> CreateAccessible() override;
-
- void addMenuItem(const OUString& rText, Action* pAction);
- void addSeparator();
-
- ScMenuFloatingWindow* addSubMenuItem(const OUString& rText, bool bEnabled);
- void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu);
- void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer);
- void clearSelectedMenuItem();
- ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const;
- bool isMenuItemSelected(size_t nPos) const;
- size_t getSelectedMenuItem() const { return mnSelectedMenu;}
-
- void setName(const OUString& rName);
- const OUString& getName() const { return maName;}
-
- void executeMenuItem(size_t nPos);
- void getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const;
- ScMenuFloatingWindow* getParentMenuWindow() const { return mpParentMenu;}
-
-protected:
- virtual void handlePopupEnd();
-
- Size getMenuSize() const;
- void drawMenuItem(vcl::RenderContext& rRenderContext, size_t nPos);
- void drawSeparator(vcl::RenderContext& rRenderContext, size_t nPos);
- void drawAllMenuItems(vcl::RenderContext& rRenderContext);
- const vcl::Font& getLabelFont() const
- {
- return maLabelFont;
- }
-
- void queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu);
- void queueCloseSubMenu();
- void launchSubMenu(bool bSetMenuPos);
- void endSubMenu(ScMenuFloatingWindow* pSubMenu);
-
- void fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const;
-
- ScDocument* getDoc() { return mpDoc;}
-
-protected:
- css::uno::Reference<css::accessibility::XAccessible> mxAccessible;
-
-private:
- struct SubMenuItemData;
- void handleMenuTimeout(const SubMenuItemData* pTimer);
-
- void resizeToFitMenuItems();
- void highlightMenuItem(vcl::RenderContext& rRenderContext, size_t nPos, bool bSelected);
-
- size_t getEnclosingMenuItem(const Point& rPos) const;
- size_t getSubMenuPos(const ScMenuFloatingWindow* pSubMenu);
- /**
- * Fire a menu highlight event since the accessibility framework needs
- * this to track focus on menu items.
- */
- void fireMenuHighlightedEvent();
-
- /**
- * Make sure that the specified submenu is permanently up, the submenu
- * close timer is not active, and the correct menu item associated with
- * the submenu is highlighted.
- */
- void setSubMenuFocused(const ScMenuFloatingWindow* pSubMenu);
-
- /**
- * When a menu item of an invisible submenu is selected, we need to make
- * sure that all its parent menu(s) are visible, with the right menu item
- * highlighted in each of the parents. Calling this method ensures it.
- */
- void ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu);
-
- /**
- * Dismiss any visible child submenus when a menu item of a parent menu is
- * selected.
- */
- void ensureSubMenuNotVisible();
-
- /**
- * 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:
-
- struct MenuItemData
- {
- OUString maText;
- bool mbEnabled:1;
- bool mbSeparator:1;
-
- std::shared_ptr<Action> mpAction;
- VclPtr<ScMenuFloatingWindow> mpSubMenuWin;
-
- MenuItemData();
- };
-
- std::vector<MenuItemData> maMenuItems;
-
- struct SubMenuItemData
- {
- Timer maTimer;
- VclPtr<ScMenuFloatingWindow> mpSubMenu;
- size_t mnMenuPos;
-
- DECL_LINK( TimeoutHdl, Timer*, void );
-
- SubMenuItemData(ScMenuFloatingWindow* pParent);
- void reset();
-
- private:
- VclPtr<ScMenuFloatingWindow> mpParent;
- };
- SubMenuItemData maOpenTimer;
- SubMenuItemData maCloseTimer;
-
- vcl::Font maLabelFont;
-
- // Name of this menu window, taken from the menu item of the parent window
- // that launches it (if this is a sub menu). If this is a top-level menu
- // window, then this name can be anything.
- OUString maName;
-
- size_t mnSelectedMenu;
- size_t mnClickedMenu;
-
- ScDocument* mpDoc;
-
- VclPtr<ScMenuFloatingWindow> mpParentMenu;
-};
-
-class ScCheckListMenuWindow;
-
-template <class T> struct VclPtr_hash;
-template <> struct VclPtr_hash< VclPtr<vcl::Window> >
-{
- size_t operator()( const VclPtr<vcl::Window>& r ) const
- {
- return reinterpret_cast<size_t>(r.get());
- }
-};
-
-class ScTabStops
-{
-private:
- typedef std::unordered_map< VclPtr<vcl::Window>, size_t, VclPtr_hash<VclPtr<vcl::Window>> > ControlToPosMap;
- VclPtr<ScCheckListMenuWindow> mpMenuWindow;
- ControlToPosMap maControlToPos;
- std::vector<VclPtr<vcl::Window>> maControls;
- size_t mnCurTabStop;
-public:
- ScTabStops( ScCheckListMenuWindow* mpMenuWin );
- ~ScTabStops();
- void AddTabStop( vcl::Window* pWin );
- void SetTabStop( vcl::Window* pWin );
- void CycleFocus( bool bReverse = false );
- void clear();
-};
+class ScCheckListMenuControl;
struct ScCheckListMember;
-class ScCheckListBox : public SvTreeListBox
-{
- std::unique_ptr<SvLBoxButtonData> mpCheckButton;
- ScTabStops* mpTabStops;
- bool mbSeenMouseButtonDown;
- void CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const;
- void CheckAllChildren( SvTreeListEntry* pEntry, bool bCheck );
-
- public:
-
- ScCheckListBox( vcl::Window* pParent );
- virtual ~ScCheckListBox() override { disposeOnce(); }
- virtual void dispose() override { mpCheckButton.reset(); SvTreeListBox::dispose(); }
- void Init();
- void CheckEntry( const OUString& sName, SvTreeListEntry* pParent, bool bCheck );
- void CheckEntry( SvTreeListEntry* pEntry, bool bCheck );
- SvTreeListEntry* ShowCheckEntry( const OUString& sName, ScCheckListMember& rMember, bool bShow = true, bool bCheck = true );
- void GetRecursiveChecked( SvTreeListEntry* pEntry, std::unordered_set<OUString>& vOut, OUString& rLabel );
- std::unordered_set<OUString> GetAllChecked();
- bool IsChecked( const OUString& sName, SvTreeListEntry* pParent );
- SvTreeListEntry* FindEntry( SvTreeListEntry* pParent, const OUString& sNode );
- sal_uInt16 GetCheckedEntryCount() const;
- virtual void KeyInput( const KeyEvent& rKEvt ) override;
- virtual void MouseButtonDown(const MouseEvent& rMEvt) override;
- virtual void MouseButtonUp(const MouseEvent& rMEvt) override;
- void SetTabStopsContainer( ScTabStops* pTabStops ) { mpTabStops = pTabStops; }
-};
-
-class ScSearchEdit : public Edit
-{
-private:
- ScTabStops* mpTabStops;
-public:
- ScSearchEdit(Window* pParent)
- : Edit(pParent)
- , mpTabStops(nullptr)
- {
- set_id("search_edit");
- }
-
- virtual void MouseButtonDown( const MouseEvent& rMEvt ) override;
- void SetTabStopsContainer( ScTabStops* pTabStops ) { mpTabStops = pTabStops; }
-};
-
struct ScCheckListMember
{
enum DatePartType
@@ -283,16 +45,27 @@ struct ScCheckListMember
// To store Year and Month if the member if DAY type
std::vector<OUString> maDateParts;
ScCheckListMember();
- SvTreeListEntry* mpParent;
+ std::unique_ptr<weld::TreeIter> mxParent;
};
-/**
- * This class implements a popup window for field button, for quick access
- * of hide-item list, and possibly more stuff related to field options.
- */
-class ScCheckListMenuWindow : public ScMenuFloatingWindow
+class ScCheckListMenuWindow;
+
+class ScCheckListMenuControl final
{
public:
+ static constexpr size_t MENU_NOT_SELECTED = 999;
+
+ /**
+ * Action to perform when an event takes place. Create a sub-class of
+ * this to implement the desired action.
+ */
+ class Action
+ {
+ public:
+ virtual ~Action() {}
+ virtual void execute() = 0;
+ };
+
struct ResultEntry
{
OUString aName;
@@ -313,6 +86,18 @@ public:
};
typedef std::set<ResultEntry> ResultType;
+ struct MenuItemData
+ {
+ OUString maText;
+ bool mbEnabled:1;
+ bool mbSeparator:1;
+
+ std::shared_ptr<Action> mxAction;
+ VclPtr<ScCheckListMenuWindow> mxSubMenuWin;
+
+ MenuItemData();
+ };
+
/**
* Extended data that the client code may need to store. Create a
* sub-class of this and store data there.
@@ -333,17 +118,19 @@ public:
Config();
};
- explicit ScCheckListMenuWindow(vcl::Window* pParent, ScDocument* pDoc, int nWidth = -1);
- virtual ~ScCheckListMenuWindow() override;
- virtual void dispose() override;
+ explicit ScCheckListMenuControl(ScCheckListMenuWindow* pParent, vcl::Window* pContainer, ScDocument* pDoc,
+ bool bCanHaveSubMenu, int nWidth);
+ ~ScCheckListMenuControl();
- virtual void MouseMove(const MouseEvent& rMEvt) override;
- virtual bool EventNotify(NotifyEvent& rNEvt) override;
- virtual void Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect) override;
- virtual css::uno::Reference< css::accessibility::XAccessible > CreateAccessible() override;
+ void addMenuItem(const OUString& rText, Action* pAction);
+ void addSeparator();
+ ScCheckListMenuWindow* addSubMenuItem(const OUString& rText, bool bEnabled);
+ void resizeToFitMenuItems();
+
+ void selectMenuItem(size_t nPos, bool bSubMenuTimer);
+ void queueLaunchSubMenu(size_t nPos, ScCheckListMenuWindow* pMenu);
void setMemberSize(size_t n);
- void setHasDates(bool bHasDates);
void addDateMember(const OUString& rName, double nVal, bool bVisible);
void addMember(const OUString& rName, bool bVisible);
size_t initMembers();
@@ -354,6 +141,14 @@ public:
void launch(const tools::Rectangle& rRect);
void close(bool bOK);
+ void StartPopupMode(const tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags);
+ void EndPopupMode();
+
+ size_t getSubMenuPos(const ScCheckListMenuControl* pSubMenu);
+ void setSubMenuFocused(const ScCheckListMenuControl* pSubMenu);
+ void queueCloseSubMenu();
+ void clearSelectedMenuItem();
+
/**
* Set auxiliary data that the client code might need. Note that this
* popup window class manages its life time; no explicit deletion of the
@@ -366,26 +161,16 @@ public:
*/
ExtendedData* getExtendedData();
+ void GrabFocus();
+
void setOKAction(Action* p);
void setPopupEndAction(Action* p);
-protected:
- virtual void handlePopupEnd() override;
+ void setHasDates(bool bHasDates);
private:
- class CancelButton : public ::CancelButton
- {
- public:
- CancelButton(ScCheckListMenuWindow* pParent);
- virtual ~CancelButton() override;
- virtual void dispose() override;
-
- virtual void Click() override;
-
- private:
- VclPtr<ScCheckListMenuWindow> mpParent;
- };
+ std::vector<MenuItemData> maMenuItems;
enum SectionType {
WHOLE, // entire window
@@ -408,38 +193,153 @@ private:
void packWindow();
void setAllMemberState(bool bSet);
void selectCurrentMemberOnly(bool bSet);
- void updateMemberParents( const SvTreeListEntry* pLeaf, size_t nIdx );
+ void updateMemberParents(const weld::TreeIter* pLeaf, size_t nIdx);
+
+ std::unique_ptr<weld::TreeIter> ShowCheckEntry(const OUString& sName, ScCheckListMember& rMember, bool bShow = true, bool bCheck = true);
+ void CheckEntry(const OUString& sName, const weld::TreeIter* pParent, bool bCheck);
+ void CheckEntry(const weld::TreeIter* pEntry, bool bCheck);
+ void GetRecursiveChecked(const weld::TreeIter* pEntry, std::unordered_set<OUString>& vOut, OUString& rLabel);
+ std::unordered_set<OUString> GetAllChecked();
+ bool IsChecked(const OUString& sName, const weld::TreeIter* pParent);
+ int GetCheckedEntryCount() const;
+ void CheckAllChildren(const weld::TreeIter* pEntry, bool bCheck);
+
+ void setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu);
+
+ std::unique_ptr<weld::TreeIter> FindEntry(const weld::TreeIter* pParent, const OUString& sNode);
+
+ void executeMenuItem(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();
+
+ /**
+ * Dismiss any visible child submenus when a menu item of a parent menu is
+ * selected.
+ */
+ void ensureSubMenuNotVisible();
+
+ void endSubMenu(ScCheckListMenuControl& rSubMenu);
+
+ struct SubMenuItemData;
+
+ void handleMenuTimeout(const SubMenuItemData* pTimer);
+
+ void launchSubMenu(bool bSetMenuPos);
- DECL_LINK( ButtonHdl, Button*, void );
- DECL_LINK( TriStateHdl, Button*, void );
- DECL_LINK( CheckHdl, SvTreeListBox*, void );
- DECL_LINK( EdModifyHdl, Edit&, void );
+ void CreateDropDown();
+
+ DECL_LINK(ButtonHdl, weld::Button&, void);
+ DECL_LINK(TriStateHdl, weld::ToggleButton&, void);
+
+ void Check(const weld::TreeIter* pIter);
+
+ DECL_LINK(CheckHdl, const weld::TreeView::iter_col&, void);
+
+ DECL_LINK(PopupModeEndHdl, FloatingWindow*, 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(PostPopdownHdl, void*, void);
private:
- VclPtr<ScSearchEdit> maEdSearch;
- VclPtr<ScCheckListBox> maChecks;
+ VclPtr<ScCheckListMenuWindow> mxFrame;
+ std::unique_ptr<weld::Builder> mxBuilder;
+ std::unique_ptr<weld::Container> mxContainer;
+ std::unique_ptr<weld::TreeView> mxMenu;
+ std::unique_ptr<weld::TreeIter> mxScratchIter;
+ std::unique_ptr<weld::Entry> mxEdSearch;
+ std::unique_ptr<weld::Widget> mxBox;
+ std::unique_ptr<weld::TreeView> mxChecks;
+
+ std::unique_ptr<weld::CheckButton> mxChkToggleAll;
+ std::unique_ptr<weld::Button> mxBtnSelectSingle;
+ std::unique_ptr<weld::Button> mxBtnUnselectSingle;
- VclPtr<CheckBox> maChkToggleAll;
- VclPtr<ImageButton> maBtnSelectSingle;
- VclPtr<ImageButton> maBtnUnselectSingle;
+ std::unique_ptr<weld::Box> mxButtonBox;
+ std::unique_ptr<weld::Button> mxBtnOk;
+ std::unique_ptr<weld::Button> mxBtnCancel;
- VclPtr<OKButton> maBtnOk;
- VclPtr<CancelButton> maBtnCancel;
+ ScopedVclPtr<VirtualDevice> mxDropDown;
std::vector<ScCheckListMember> maMembers;
// For Dates
std::map<OUString, size_t> maYearMonthMap;
- std::unique_ptr<ExtendedData> mpExtendedData;
- std::unique_ptr<Action> mpOKAction;
- std::unique_ptr<Action> mpPopupEndAction;
+ std::unique_ptr<ExtendedData> mxExtendedData;
+ std::unique_ptr<Action> mxOKAction;
+ std::unique_ptr<Action> mxPopupEndAction;
Config maConfig;
+ int mnWidthHint; /// min width hint
Size maWndSize; /// whole window size.
Size maMenuSize; /// size of all menu items combined.
TriState mePrevToggleAllState;
- ScTabStops maTabStops;
+
+ size_t mnSelectedMenu;
+
+ ScDocument* mpDoc;
+
+ ImplSVEvent* mnAsyncPostPopdownId;
+
bool mbHasDates;
+ bool mbCanHaveSubMenu;
+
+ struct SubMenuItemData
+ {
+ Timer maTimer;
+ VclPtr<ScCheckListMenuWindow> mpSubMenu;
+ size_t mnMenuPos;
+
+ DECL_LINK( TimeoutHdl, Timer*, void );
+
+ SubMenuItemData(ScCheckListMenuControl* pParent);
+ void reset();
+
+ private:
+ ScCheckListMenuControl* mpParent;
+ };
+
+ SubMenuItemData maOpenTimer;
+ SubMenuItemData maCloseTimer;
+};
+
+/**
+ * This class implements a popup window for field button, for quick access
+ * of hide-item list, and possibly more stuff related to field options.
+ */
+class ScCheckListMenuWindow : public DockingWindow
+{
+public:
+ explicit ScCheckListMenuWindow(vcl::Window* pParent, ScDocument* pDoc, bool bCanHaveSubMenu, int nWidth = -1,
+ sal_uInt16 nMenuStackLevel = 0, ScCheckListMenuWindow* pParentMenu = nullptr);
+ virtual void dispose() override;
+ virtual ~ScCheckListMenuWindow() override;
+
+ virtual void GetFocus() override;
+ virtual bool EventNotify(NotifyEvent& rNEvt) override;
+
+ ScCheckListMenuWindow* GetParentMenu() { return mxParentMenu; }
+ ScCheckListMenuControl& get_widget() { return *mxControl; }
+
+ sal_uInt16 GetMenuStackLevel() const { return mnMenuStackLevel; }
+
+private:
+ VclPtr<ScCheckListMenuWindow> mxParentMenu;
+ VclPtr<vcl::Window> mxBox;
+ std::unique_ptr<ScCheckListMenuControl> mxControl;
+ sal_uInt16 mnMenuStackLevel;
};
#endif
diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx
index e04fc42cbc74..b3439381f702 100644
--- a/sc/source/ui/inc/gridwin.hxx
+++ b/sc/source/ui/inc/gridwin.hxx
@@ -157,7 +157,7 @@ class SAL_DLLPUBLIC_RTTI ScGridWindow : public vcl::Window, public DropTargetHel
VclPtr<ScCheckListMenuWindow> mpDPFieldPopup;
std::unique_ptr<ScDPFieldButton> mpFilterButton;
- ScCheckListMenuWindow::ResultType aSaveAutoFilterResult;
+ ScCheckListMenuControl::ResultType aSaveAutoFilterResult;
sal_uInt16 nCursorHideCount;
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 85f2cd517085..9fbc6798d320 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -522,7 +522,7 @@ void ScGridWindow::ClickExtern()
if (mpDPFieldPopup)
{
- mpDPFieldPopup->close(false);
+ mpDPFieldPopup->get_widget().close(false);
mpDPFieldPopup.disposeAndClear();
}
}
@@ -544,13 +544,13 @@ IMPL_LINK( ScGridWindow, PopupSpellingHdl, SpellCallbackInfo&, rInfo, void )
namespace {
-struct AutoFilterData : public ScCheckListMenuWindow::ExtendedData
+struct AutoFilterData : public ScCheckListMenuControl::ExtendedData
{
ScAddress maPos;
ScDBData* mpData;
};
-class AutoFilterAction : public ScMenuFloatingWindow::Action
+class AutoFilterAction : public ScCheckListMenuControl::Action
{
VclPtr<ScGridWindow> mpWindow;
ScGridWindow::AutoFilterMode meMode;
@@ -563,7 +563,7 @@ public:
}
};
-class AutoFilterPopupEndAction : public ScMenuFloatingWindow::Action
+class AutoFilterPopupEndAction : public ScCheckListMenuControl::Action
{
VclPtr<ScGridWindow> mpWindow;
ScAddress maPos;
@@ -583,7 +583,7 @@ class AddItemToEntry
public:
AddItemToEntry(ScQueryEntry::QueryItemsType& rItems, svl::SharedStringPool& rPool) :
mrItems(rItems), mrPool(rPool) {}
- void operator() (const ScCheckListMenuWindow::ResultEntry& rEntry)
+ void operator() (const ScCheckListMenuControl::ResultEntry& rEntry)
{
if (rEntry.bValid)
{
@@ -632,17 +632,13 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
mpAutoFilterPopup.disposeAndClear();
int nColWidth = ScViewData::ToPixel(pDoc->GetColWidth(nCol, nTab), pViewData->GetPPTX());
- mpAutoFilterPopup.reset(VclPtr<ScCheckListMenuWindow>::Create(this, pDoc, nColWidth));
-
- // Avoid flicker when hovering over the menu items.
- if (!IsNativeControlSupported(ControlType::Pushbutton, ControlPart::Focus))
- // If NWF renders the focus rects itself, that breaks double-buffering.
- mpAutoFilterPopup->RequestDoubleBuffering(true);
+ mpAutoFilterPopup.reset(VclPtr<ScCheckListMenuWindow>::Create(this, pDoc, false, nColWidth));
+ ScCheckListMenuControl& rControl = mpAutoFilterPopup->get_widget();
if (bLOKActive)
mpAutoFilterPopup->SetLOKNotifier(SfxViewShell::Current());
- mpAutoFilterPopup->setOKAction(new AutoFilterAction(this, AutoFilterMode::Normal));
- mpAutoFilterPopup->setPopupEndAction(
+ rControl.setOKAction(new AutoFilterAction(this, AutoFilterMode::Normal));
+ rControl.setPopupEndAction(
new AutoFilterPopupEndAction(this, ScAddress(nCol, nRow, nTab)));
std::unique_ptr<AutoFilterData> pData(new AutoFilterData);
pData->maPos = ScAddress(nCol, nRow, nTab);
@@ -670,7 +666,7 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
return;
pData->mpData = pDBData;
- mpAutoFilterPopup->setExtendedData(std::move(pData));
+ rControl.setExtendedData(std::move(pData));
ScQueryParam aParam;
pDBData->GetQueryParam(aParam);
@@ -689,8 +685,8 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
ScFilterEntries aFilterEntries;
pDoc->GetFilterEntries(nCol, nRow, nTab, aFilterEntries);
- mpAutoFilterPopup->setHasDates(aFilterEntries.mbHasDates);
- mpAutoFilterPopup->setMemberSize(aFilterEntries.size());
+ rControl.setHasDates(aFilterEntries.mbHasDates);
+ rControl.setMemberSize(aFilterEntries.size());
for (const auto& rEntry : aFilterEntries)
{
const OUString& aVal = rEntry.GetString();
@@ -698,38 +694,40 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
if (!aSelected.empty())
bSelected = aSelected.count(aVal) > 0;
if ( rEntry.IsDate() )
- mpAutoFilterPopup->addDateMember( aVal, rEntry.GetValue(), bSelected );
+ rControl.addDateMember( aVal, rEntry.GetValue(), bSelected );
else
- mpAutoFilterPopup->addMember(aVal, bSelected);
+ rControl.addMember(aVal, bSelected);
}
- mpAutoFilterPopup->initMembers();
+ rControl.initMembers();
// Populate the menu.
- mpAutoFilterPopup->addMenuItem(
+ rControl.addMenuItem(
ScResId(STR_MENU_SORT_ASC),
new AutoFilterAction(this, AutoFilterMode::SortAscending));
- mpAutoFilterPopup->addMenuItem(
+ rControl.addMenuItem(
ScResId(STR_MENU_SORT_DESC),
new AutoFilterAction(this, AutoFilterMode::SortDescending));
- mpAutoFilterPopup->addSeparator();
- mpAutoFilterPopup->addMenuItem(
+ rControl.addSeparator();
+ rControl.addMenuItem(
ScResId(SCSTR_TOP10FILTER), new AutoFilterAction(this, AutoFilterMode::Top10));
- mpAutoFilterPopup->addMenuItem(
+ rControl.addMenuItem(
ScResId(SCSTR_FILTER_EMPTY), new AutoFilterAction(this, AutoFilterMode::Empty));
- mpAutoFilterPopup->addMenuItem(
+ rControl.addMenuItem(
ScResId(SCSTR_FILTER_NOTEMPTY), new AutoFilterAction(this, AutoFilterMode::NonEmpty));
- mpAutoFilterPopup->addSeparator();
- mpAutoFilterPopup->addMenuItem(
+ rControl.addSeparator();
+ rControl.addMenuItem(
ScResId(SCSTR_STDFILTER), new AutoFilterAction(this, AutoFilterMode::Custom));
- ScCheckListMenuWindow::Config aConfig;
+ ScCheckListMenuControl::Config aConfig;
aConfig.mbAllowEmptySet = false;
aConfig.mbRTL = pViewData->GetDocument()->IsLayoutRTL(pViewData->GetTabNo());
- mpAutoFilterPopup->setConfig(aConfig);
- mpAutoFilterPopup->launch(aCellRect);
+ rControl.setConfig(aConfig);
+ if (IsMouseCaptured())
+ ReleaseMouse();
+ rControl.launch(aCellRect);
// remember filter rules before modification
- mpAutoFilterPopup->getResult(aSaveAutoFilterResult);
+ rControl.getResult(aSaveAutoFilterResult);
collectUIInformation(OUString::number(nRow), OUString::number(nCol));
}
@@ -747,8 +745,10 @@ void ScGridWindow::RefreshAutoFilterButton(const ScAddress& rPos)
void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
{
+ ScCheckListMenuControl& rControl = mpAutoFilterPopup->get_widget();
+
const AutoFilterData* pData =
- static_cast<const AutoFilterData*>(mpAutoFilterPopup->getExtendedData());
+ static_cast<const AutoFilterData*>(rControl.getExtendedData());
if (!pData)
return;
@@ -812,8 +812,8 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
if (eMode == AutoFilterMode::Normal)
{
// Do not recreate autofilter rules if there are no changes from the user
- ScCheckListMenuWindow::ResultType aResult;
- mpAutoFilterPopup->getResult(aResult);
+ ScCheckListMenuControl::ResultType aResult;
+ rControl.getResult(aResult);
if (aResult == aSaveAutoFilterResult)
{
@@ -832,7 +832,7 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
// Remove old entries in auto-filter rules
aParam.RemoveAllEntriesByField(rPos.Col());
- if( !(eMode == AutoFilterMode::Normal && mpAutoFilterPopup->isAllSelected() ) )
+ if( !(eMode == AutoFilterMode::Normal && rControl.isAllSelected() ) )
{
// Try to use the existing entry for the column (if one exists).
ScQueryEntry* pEntry = aParam.FindEntryByField(rPos.Col(), true);
@@ -854,8 +854,8 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
{
pEntry->eOp = SC_EQUAL;
- ScCheckListMenuWindow::ResultType aResult;
- mpAutoFilterPopup->getResult(aResult);
+ ScCheckListMenuControl::ResultType aResult;
+ rControl.getResult(aResult);
ScQueryEntry::QueryItemsType& rItems = pEntry->GetQueryItems();
rItems.clear();
diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx
index 134a6f4734ed..71a68605d1d2 100644
--- a/sc/source/ui/view/gridwin2.cxx
+++ b/sc/source/ui/view/gridwin2.cxx
@@ -370,14 +370,14 @@ bool ScGridWindow::DPTestFieldPopupArrow(
namespace {
-struct DPFieldPopupData : public ScCheckListMenuWindow::ExtendedData
+struct DPFieldPopupData : public ScCheckListMenuControl::ExtendedData
{
ScDPLabelData maLabels;
ScDPObject* mpDPObj;
long mnDim;
};
-class DPFieldPopupOKAction : public ScMenuFloatingWindow::Action
+class DPFieldPopupOKAction : public ScCheckListMenuControl::Action
{
public:
explicit DPFieldPopupOKAction(ScGridWindow* p) :
@@ -391,7 +391,7 @@ private:
VclPtr<ScGridWindow> mpGridWindow;
};
-class PopupSortAction : public ScMenuFloatingWindow::Action
+class PopupSortAction : public ScCheckListMenuControl::Action
{
public:
enum SortType { ASCENDING, DESCENDING, CUSTOM };
@@ -458,6 +458,8 @@ void ScGridWindow::DPLaunchFieldPopupMenu(const Point& rScrPos, const Size& rScr
// This should never happen.
return;
+ bool bDimOrientNotPage = pDim->GetOrientation() != DataPilotFieldOrientation_PAGE;
+
// We need to get the list of field members.
pDPObj->FillLabelData(pDPData->mnDim, pDPData->maLabels);
pDPData->mpDPObj = pDPObj;
@@ -465,34 +467,29 @@ void ScGridWindow::DPLaunchFieldPopupMenu(const Point& rScrPos, const Size& rScr
const ScDPLabelData& rLabelData = pDPData->maLabels;
mpDPFieldPopup.disposeAndClear();
- mpDPFieldPopup.reset(VclPtr<ScCheckListMenuWindow>::Create(this, pViewData->GetDocument()));
-
- // Avoid flicker when hovering over the menu items.
- if (!IsNativeControlSupported(ControlType::Pushbutton, ControlPart::Focus))
- // If NWF renders the focus rects itself, that breaks double-buffering.
- mpDPFieldPopup->RequestDoubleBuffering(true);
+ mpDPFieldPopup.reset(VclPtr<ScCheckListMenuWindow>::Create(this, pViewData->GetDocument(), bDimOrientNotPage));
- mpDPFieldPopup->setName("DataPilot field member popup");
- mpDPFieldPopup->setExtendedData(std::move(pDPData));
- mpDPFieldPopup->setOKAction(new DPFieldPopupOKAction(this));
+ ScCheckListMenuControl& rControl = mpDPFieldPopup->get_widget();
+ rControl.setExtendedData(std::move(pDPData));
+ rControl.setOKAction(new DPFieldPopupOKAction(this));
{
// Populate field members.
size_t n = rLabelData.maMembers.size();
- mpDPFieldPopup->setMemberSize(n);
+ rControl.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.
- mpDPFieldPopup->addMember(ScResId(STR_EMPTYDATA), rMem.mbVisible);
+ rControl.addMember(ScResId(STR_EMPTYDATA), rMem.mbVisible);
else
- mpDPFieldPopup->addMember(rMem.getDisplayName(), rMem.mbVisible);
+ rControl.addMember(rMem.getDisplayName(), rMem.mbVisible);
}
- mpDPFieldPopup->initMembers();
+ rControl.initMembers();
}
- if (pDim->GetOrientation() != DataPilotFieldOrientation_PAGE)
+ if (bDimOrientNotPage)
{
vector<OUString> aUserSortNames;
ScUserList* pUserList = ScGlobal::GetUserList();
@@ -509,35 +506,36 @@ void ScGridWindow::DPLaunchFieldPopupMenu(const Point& rScrPos, const Size& rScr
// Populate the menus.
ScTabViewShell* pViewShell = pViewData->GetViewShell();
- mpDPFieldPopup->addMenuItem(
+ rControl.addMenuItem(
ScResId(STR_MENU_SORT_ASC),
new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::ASCENDING, 0, pViewShell));
- mpDPFieldPopup->addMenuItem(
+ rControl.addMenuItem(
ScResId(STR_MENU_SORT_DESC),
new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::DESCENDING, 0, pViewShell));
- ScMenuFloatingWindow* pSubMenu = mpDPFieldPopup->addSubMenuItem(
- ScResId(STR_MENU_SORT_CUSTOM), !aUserSortNames.empty());
+ ScCheckListMenuWindow* pSubMenu = rControl.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)
{
- pSubMenu->addMenuItem(
- aUserSortNames[i],
- new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::CUSTOM, sal_uInt16(i), pViewShell));
+ rSubMenu.addMenuItem(aUserSortNames[i],
+ new PopupSortAction(pDPObj, nDimIndex, PopupSortAction::CUSTOM, sal_uInt16(i), pViewShell));
}
+ rSubMenu.resizeToFitMenuItems();
}
}
tools::Rectangle aCellRect(rScrPos, rScrSize);
- mpDPFieldPopup->SetPopupModeEndHdl( LINK(this, ScGridWindow, PopupModeEndHdl) );
- ScCheckListMenuWindow::Config aConfig;
+ ScCheckListMenuControl::Config aConfig;
aConfig.mbAllowEmptySet = false;
aConfig.mbRTL = pViewData->GetDocument()->IsLayoutRTL(pViewData->GetTabNo());
- mpDPFieldPopup->setConfig(aConfig);
- mpDPFieldPopup->launch(aCellRect);
+ rControl.setConfig(aConfig);
+ if (IsMouseCaptured())
+ ReleaseMouse();
+ rControl.launch(aCellRect);
}
void ScGridWindow::UpdateDPFromFieldPopupMenu()
@@ -547,7 +545,9 @@ void ScGridWindow::UpdateDPFromFieldPopupMenu()
if (!mpDPFieldPopup)
return;
- DPFieldPopupData* pDPData = static_cast<DPFieldPopupData*>(mpDPFieldPopup->getExtendedData());
+ ScCheckListMenuControl& rControl = mpDPFieldPopup->get_widget();
+
+ DPFieldPopupData* pDPData = static_cast<DPFieldPopupData*>(rControl.getExtendedData());
if (!pDPData)
return;
@@ -567,8 +567,8 @@ void ScGridWindow::UpdateDPFromFieldPopupMenu()
aMemNameMap.emplace(rMember.maLayoutName, rMember.maName);
// The raw result may contain a mixture of layout names and original names.
- ScCheckListMenuWindow::ResultType aRawResult;
- mpDPFieldPopup->getResult(aRawResult);
+ ScCheckListMenuControl::ResultType aRawResult;
+ rControl.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
new file mode 100644
index 000000000000..c37771a2116c
--- /dev/null
+++ b/sc/uiconfig/scalc/ui/filterdropdown.ui
@@ -0,0 +1,304 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.2 -->
+<interface domain="sw">
+ <requires lib="gtk+" version="3.18"/>
+ <object class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">sc/res/popup_select_current.png</property>
+ </object>
+ <object class="GtkImage" id="image2">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="icon_name">sc/res/popup_unselect_current.png</property>
+ </object>
+ <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="GtkTreeStore" id="liststore2">
+ <columns>
+ <!-- column-name check1 -->
+ <column type="gboolean"/>
+ <!-- column-name text -->
+ <column type="gchararray"/>
+ <!-- column-name id -->
+ <column type="gchararray"/>
+ <!-- column-name checkvis1 -->
+ <column type="gboolean"/>
+ <!-- column-name checktri1 -->
+ <column type="gboolean"/>
+ </columns>
+ </object>
+ <object class="GtkBox" id="FilterDropDown">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="hexpand">True</property>
+ <property name="vexpand">True</property>
+ <property name="orientation">vertical</property>
+ <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>
+ <property name="orientation">vertical</property>
+ <property name="spacing">6</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" id="treeview-selection1"/>
+ </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="treeviewcolumn44">
+ <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>
+ <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="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">
+ <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>
+ <child>
+ <object class="GtkSeparator">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">True</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">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="xalign">0</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>
+ <property name="fill">True</property>
+ <property name="position">1</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="hscrollbar_policy">never</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkTreeView" id="check_list_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">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>
+ <property name="enable_tree_lines">True</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">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">gtk-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_stock">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">gtk-cancel</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="use_stock">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>
+ </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/listmenu.ui b/sc/uiconfig/scalc/ui/listmenu.ui
new file mode 100644
index 000000000000..c826f21f3eae
--- /dev/null
+++ b/sc/uiconfig/scalc/ui/listmenu.ui
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.2 -->
+<interface domain="sc">
+ <requires lib="gtk+" version="3.18"/>
+ <object class="GtkMenu" id="listmenu">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ </object>
+</interface>
diff --git a/solenv/clang-format/blacklist b/solenv/clang-format/blacklist
index 566479f935ad..1a1e268591ae 100644
--- a/solenv/clang-format/blacklist
+++ b/solenv/clang-format/blacklist
@@ -9152,9 +9152,6 @@ sax/test/sax/testsax.cxx
sax/test/sax/testwriter.cxx
sax/test/saxdemo.cxx
sax/test/testcomponent.cxx
-sc/inc/AccessibleFilterMenu.hxx
-sc/inc/AccessibleFilterMenuItem.hxx
-sc/inc/AccessibleFilterTopWindow.hxx
sc/inc/AccessibleGlobal.hxx
sc/inc/ChartTools.hxx
sc/inc/NumberFormatControl.hxx
@@ -10113,9 +10110,6 @@ sc/source/ui/Accessibility/AccessibleDocument.cxx
sc/source/ui/Accessibility/AccessibleDocumentBase.cxx
sc/source/ui/Accessibility/AccessibleDocumentPagePreview.cxx
sc/source/ui/Accessibility/AccessibleEditObject.cxx
-sc/source/ui/Accessibility/AccessibleFilterMenu.cxx
-sc/source/ui/Accessibility/AccessibleFilterMenuItem.cxx
-sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx
sc/source/ui/Accessibility/AccessibleGlobal.cxx
sc/source/ui/Accessibility/AccessiblePageHeader.cxx
sc/source/ui/Accessibility/AccessiblePageHeaderArea.cxx
diff --git a/svtools/source/control/toolbarmenu.cxx b/svtools/source/control/toolbarmenu.cxx
index da45acfbddf6..5c76ae6cad89 100644
--- a/svtools/source/control/toolbarmenu.cxx
+++ b/svtools/source/control/toolbarmenu.cxx
@@ -237,6 +237,8 @@ InterimToolbarPopup::InterimToolbarPopup(const css::uno::Reference<css::frame::X
void InterimToolbarPopup::GetFocus()
{
ToolbarPopup::GetFocus();
+ if (!m_xPopup)
+ return;
m_xPopup->GrabFocus();
}
diff --git a/vcl/source/window/dockmgr.cxx b/vcl/source/window/dockmgr.cxx
index 4cd3482cd7b7..90f9caf76812 100644
--- a/vcl/source/window/dockmgr.cxx
+++ b/vcl/source/window/dockmgr.cxx
@@ -366,6 +366,13 @@ void DockingManager::EndPopupMode( const vcl::Window *pWin )
pWrapper->GetFloatingWindow()->EndPopupMode();
}
+void DockingManager::SetPopupModeEndHdl( const vcl::Window *pWindow, const Link<FloatingWindow*,void>& rLink )
+{
+ ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
+ if( pWrapper )
+ pWrapper->SetPopupModeEndHdl(rLink);
+}
+
void DockingManager::AddWindow( const vcl::Window *pWindow )
{
ImplDockingWindowWrapper* pWrapper = GetDockingWindowWrapper( pWindow );
@@ -472,6 +479,7 @@ ImplDockingWindowWrapper::ImplDockingWindowWrapper( const vcl::Window *pWindow )
, mbStartDockingEnabled(false)
, mbLocked(false)
{
+ assert(mpDockingWindow);
DockingWindow *pDockWin = dynamic_cast< DockingWindow* > ( mpDockingWindow.get() );
if( pDockWin )
mnFloatBits = pDockWin->GetFloatStyle();
@@ -850,6 +858,7 @@ IMPL_LINK_NOARG(ImplDockingWindowWrapper, PopupModeEnd, FloatingWindow*, void)
GetWindow()->SetParent( pRealParent );
GetWindow()->mpWindowImpl->mpRealParent = pRealParent;
+ maPopupModeEndHdl.Call(mpFloatWin);
mpFloatWin.disposeAndClear();
// call handler - which will destroy the window and thus the wrapper as well !