vcl/inc/qt5/QtMenu.hxx | 8 ++++++++ vcl/qt5/QtMenu.cxx | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+)
New commits: commit 2ef9880f97de6629ddef12eb788123ab4be1ec83 Author: Michael Weghorn <m.wegh...@posteo.de> AuthorDate: Sun Jul 30 01:59:31 2023 +0200 Commit: Michael Weghorn <m.wegh...@posteo.de> CommitDate: Tue Aug 1 08:21:22 2023 +0200 tdf#156376 qt: Open help for focused native menu entry on F1 In order to allow have pressing F1 (`QKeySequence::HelpContents`) open the corresponding help entry for the currently selected menu entry, connect to the signal that gets emitted when a menu entry is selected (`QAction::hovered`) and remember its help ID. Register the F1 shortcut for the menu and connect its `activated`/`activatedAmbiguously` signal with a slot that opens the help for the current/ last selected menu entry. Change-Id: I24eec4806e5a202052a49c239e4836b92c9f0228 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155055 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.wegh...@posteo.de> diff --git a/vcl/inc/qt5/QtMenu.hxx b/vcl/inc/qt5/QtMenu.hxx index 3e43272b6212..bd704507f69c 100644 --- a/vcl/inc/qt5/QtMenu.hxx +++ b/vcl/inc/qt5/QtMenu.hxx @@ -53,6 +53,9 @@ private: QMenu* mpQMenu; QButtonGroup* m_pButtonGroup; + // help ID of currently/last selected item + static OUString m_sCurrentHelpId; + void DoFullMenuUpdate(Menu* pMenuBar); static void NativeItemText(OUString& rItemText); @@ -64,6 +67,9 @@ private: bool validateQMenuBar() const; QPushButton* ImplAddMenuBarButton(const QIcon& rIcon, const QString& rToolTip, int nId); void ImplRemoveMenuBarButton(int nId); + void connectHelpShortcut(QMenu* pMenu); + // set slots that handle signals relevent for help menu + void connectHelpSignalSlots(QMenu* pMenu, QtMenuItem* pSalMenuItem); public: QtMenu(bool bMenuBar); @@ -102,6 +108,8 @@ public: QtMenuItem* GetItemAtPos(unsigned nPos) { return maItems[nPos]; } private slots: + static void slotShowHelp(); + static void slotMenuHovered(QtMenuItem* pItem); static void slotMenuTriggered(QtMenuItem* pQItem); static void slotMenuAboutToShow(QtMenuItem* pQItem); static void slotMenuAboutToHide(QtMenuItem* pQItem); diff --git a/vcl/qt5/QtMenu.cxx b/vcl/qt5/QtMenu.cxx index b976fa3f5739..b1e62bc09475 100644 --- a/vcl/qt5/QtMenu.cxx +++ b/vcl/qt5/QtMenu.cxx @@ -24,6 +24,11 @@ #include <QtWidgets/QHBoxLayout> #include <QtWidgets/QMenuBar> #include <QtWidgets/QPushButton> +#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0) +#include <QtGui/QShortcut> +#else +#include <QtWidgets/QShortcut> +#endif #include <QtWidgets/QStyle> #include <o3tl/safeint.hxx> @@ -48,6 +53,8 @@ static inline void lcl_force_menubar_layout_update(QMenuBar& rMenuBar) rMenuBar.adjustSize(); } +OUString QtMenu::m_sCurrentHelpId = u""; + QtMenu::QtMenu(bool bMenuBar) : mpVCLMenu(nullptr) , mpParentSalMenu(nullptr) @@ -77,6 +84,7 @@ void QtMenu::InsertMenuItem(QtMenuItem* pSalMenuItem, unsigned nPos) if (validateQMenuBar()) { QMenu* pQMenu = new QMenu(toQString(aText), nullptr); + connectHelpSignalSlots(pQMenu, pSalMenuItem); pSalMenuItem->mpMenu.reset(pQMenu); if ((nPos != MENU_APPEND) @@ -108,12 +116,14 @@ void QtMenu::InsertMenuItem(QtMenuItem* pSalMenuItem, unsigned nPos) // no QMenu set, instantiate own one mpOwnedQMenu.reset(new QMenu); mpQMenu = mpOwnedQMenu.get(); + connectHelpSignalSlots(mpQMenu, pSalMenuItem); } if (pSalMenuItem->mpSubMenu) { // submenu QMenu* pQMenu = new QMenu(toQString(aText), nullptr); + connectHelpSignalSlots(pQMenu, pSalMenuItem); pSalMenuItem->mpMenu.reset(pQMenu); if ((nPos != MENU_APPEND) @@ -183,6 +193,8 @@ void QtMenu::InsertMenuItem(QtMenuItem* pSalMenuItem, unsigned nPos) connect(pAction, &QAction::triggered, this, [pSalMenuItem] { slotMenuTriggered(pSalMenuItem); }); + connect(pAction, &QAction::hovered, this, + [pSalMenuItem] { slotMenuHovered(pSalMenuItem); }); } } } @@ -618,6 +630,22 @@ const QtFrame* QtMenu::GetFrame() const return pMenu ? pMenu->mpFrame : nullptr; } +void QtMenu::slotMenuHovered(QtMenuItem* pItem) +{ + const OUString sHelpId = pItem->mpParentMenu->GetMenu()->GetHelpId(pItem->mnId); + m_sCurrentHelpId = sHelpId; +} + +void QtMenu::slotShowHelp() +{ + SolarMutexGuard aGuard; + Help* pHelp = Application::GetHelp(); + if (pHelp && !m_sCurrentHelpId.isEmpty()) + { + pHelp->Start(m_sCurrentHelpId); + } +} + void QtMenu::slotMenuTriggered(QtMenuItem* pQItem) { if (!pQItem) @@ -772,6 +800,26 @@ void QtMenu::ImplRemoveMenuBarButton(int nId) lcl_force_menubar_layout_update(*mpQMenuBar); } +void QtMenu::connectHelpShortcut(QMenu* pMenu) +{ + assert(pMenu); + QKeySequence sequence(QKeySequence::HelpContents); + QShortcut* pQShortcut = new QShortcut(sequence, pMenu); + connect(pQShortcut, &QShortcut::activated, this, QtMenu::slotShowHelp); + connect(pQShortcut, &QShortcut::activatedAmbiguously, this, QtMenu::slotShowHelp); +} + +void QtMenu::connectHelpSignalSlots(QMenu* pMenu, QtMenuItem* pSalMenuItem) +{ + // connect hovered signal of the menu's own action + QAction* pAction = pMenu->menuAction(); + assert(pAction); + connect(pAction, &QAction::hovered, this, [pSalMenuItem] { slotMenuHovered(pSalMenuItem); }); + + // connect slot to handle Help key (F1) + connectHelpShortcut(pMenu); +} + void QtMenu::RemoveMenuBarButton(sal_uInt16 nId) { ImplRemoveMenuBarButton(nId); } tools::Rectangle QtMenu::GetMenuBarButtonRectPixel(sal_uInt16 nId, SalFrame* pFrame)