summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorCaolán McNamara <caolan.mcnamara@collabora.com>2024-05-13 10:43:20 +0100
committerCaolán McNamara <caolan.mcnamara@collabora.com>2024-05-14 17:34:23 +0200
commita525895a5f820350dc307969b1e8fd5d218a1ddd (patch)
treeb40429c390d9267bfc603fe8661294ac04908188 /sc
parentbcc1b9f22d4b2772c735176e78dfa1e7c8c39b3a (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.cxx63
-rw-r--r--sc/source/ui/inc/checklistmenu.hxx22
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;