diff options
author | Caolán McNamara <caolan.mcnamara@collabora.com> | 2024-05-13 10:43:20 +0100 |
---|---|---|
committer | Caolán McNamara <caolan.mcnamara@collabora.com> | 2024-05-14 17:34:23 +0200 |
commit | a525895a5f820350dc307969b1e8fd5d218a1ddd (patch) | |
tree | b40429c390d9267bfc603fe8661294ac04908188 /sc | |
parent | bcc1b9f22d4b2772c735176e78dfa1e7c8c39b3a (diff) |
Resolves: tdf#146326 restore focus on autofilter submenu popdown
to where it was before the submenu popup, unless the keyboard was used
in the submenu, in which case restore focus to the menu instead.
Change-Id: Iaa24b4eadf206b877a093529678667927488de8c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167580
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/ui/cctrl/checklistmenu.cxx | 63 | ||||
-rw-r--r-- | sc/source/ui/inc/checklistmenu.hxx | 22 |
2 files changed, 83 insertions, 2 deletions
diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx index 60078c335437..1d720cb3b0dd 100644 --- a/sc/source/ui/cctrl/checklistmenu.cxx +++ b/sc/source/ui/cctrl/checklistmenu.cxx @@ -77,6 +77,10 @@ IMPL_LINK_NOARG(ScCheckListMenuControl, RowActivatedHdl, weld::TreeView&, bool) IMPL_LINK(ScCheckListMenuControl, MenuKeyInputHdl, const KeyEvent&, rKEvt, bool) { + // Assume that once the keyboard is used that focus should restore to this menu + // on dismissing a submenu + SetRestoreFocus(ScCheckListMenuControl::RestoreFocus::Menu); + const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode(); switch (rKeyCode.GetCode()) @@ -328,17 +332,65 @@ void ScCheckListMenuControl::launchSubMenu() if (!mxMenu->get_selected(mxScratchIter.get())) return; + meRestoreFocus = DetermineRestoreFocus(); + tools::Rectangle aRect = GetSubMenuParentRect(); pSubMenu->StartPopupMode(mxMenu.get(), aRect); mxMenu->select(*mxScratchIter); + pSubMenu->GrabFocus(); } +ScCheckListMenuControl::RestoreFocus ScCheckListMenuControl::DetermineRestoreFocus() const +{ + if (mxEdSearch->has_focus()) + return RestoreFocus::EdSearch; + if (mpChecks->has_focus()) + return RestoreFocus::Checks; + if (mxChkToggleAll->has_focus()) + return RestoreFocus::ChkToggleAll; + if (mxChkLockChecked->has_focus()) + return RestoreFocus::ChkLockChecked; + if (mxBtnSelectSingle->has_focus()) + return RestoreFocus::BtnSelectSingle; + if (mxBtnUnselectSingle->has_focus()) + return RestoreFocus::BtnUnselectSingle; + return RestoreFocus::Menu; +} + +void ScCheckListMenuControl::RestorePreviousFocus() +{ + switch (meRestoreFocus) + { + case RestoreFocus::EdSearch: + mxEdSearch->grab_focus(); + break; + case RestoreFocus::Checks: + mpChecks->grab_focus(); + break; + case RestoreFocus::ChkToggleAll: + mxChkToggleAll->grab_focus(); + break; + case RestoreFocus::ChkLockChecked: + mxChkLockChecked->grab_focus(); + break; + case RestoreFocus::BtnSelectSingle: + mxBtnSelectSingle->grab_focus(); + break; + case RestoreFocus::BtnUnselectSingle: + mxBtnUnselectSingle->grab_focus(); + break; + default: + mxMenu->grab_focus(); + break; + } +} + IMPL_LINK_NOARG(ScCheckListMenuControl, PostPopdownHdl, void*, void) { mnAsyncPostPopdownId = nullptr; - mxMenu->grab_focus(); + RestorePreviousFocus(); } IMPL_LINK(ScCheckListMenuControl, MouseEnterHdl, const MouseEvent&, rMEvt, bool) @@ -522,6 +574,7 @@ ScCheckListMenuControl::ScCheckListMenuControl(weld::Widget* pParent, ScViewData , mrViewData(rViewData) , mnAsyncPostPopdownId(nullptr) , mnAsyncSetDropdownPosId(nullptr) + , meRestoreFocus(RestoreFocus::Menu) , mbHasDates(bHasDates) , mbIsPoppedUp(false) , maOpenTimer(this) @@ -1815,8 +1868,14 @@ IMPL_LINK(ScListSubMenuControl, MenuKeyInputHdl, const KeyEvent&, rKEvt, bool) { bool bConsumed = false; const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode(); + const sal_uInt16 eKeyCode = rKeyCode.GetCode(); - switch (rKeyCode.GetCode()) + // Assume that once the keyboard is used that focus should restore to the + // parent menu + if (eKeyCode != KEY_ESCAPE) + mrParentControl.SetRestoreFocus(ScCheckListMenuControl::RestoreFocus::Menu); + + switch (eKeyCode) { case KEY_ESCAPE: case KEY_LEFT: diff --git a/sc/source/ui/inc/checklistmenu.hxx b/sc/source/ui/inc/checklistmenu.hxx index 8e24baef433b..558ef9f47e37 100644 --- a/sc/source/ui/inc/checklistmenu.hxx +++ b/sc/source/ui/inc/checklistmenu.hxx @@ -96,6 +96,18 @@ public: }; typedef std::set<ResultEntry> ResultType; + + enum RestoreFocus + { + Menu, + EdSearch, + Checks, + ChkToggleAll, + ChkLockChecked, + BtnSelectSingle, + BtnUnselectSingle + }; + struct MenuItemData { bool mbEnabled:1; @@ -190,6 +202,11 @@ public: void addFields(const std::vector<OUString>& aFields); tools::Long getField(); + + void SetRestoreFocus(RestoreFocus eFocus) + { + meRestoreFocus = eFocus; + } private: std::vector<MenuItemData> maMenuItems; @@ -266,6 +283,9 @@ private: void DropPendingEvents(); + RestoreFocus DetermineRestoreFocus() const; + void RestorePreviousFocus(); + private: std::unique_ptr<weld::Builder> mxBuilder; std::unique_ptr<weld::Popover> mxPopover; @@ -316,6 +336,8 @@ private: ImplSVEvent* mnAsyncPostPopdownId; ImplSVEvent* mnAsyncSetDropdownPosId; + RestoreFocus meRestoreFocus; + bool mbHasDates; bool mbIsPoppedUp; |