summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Weghorn <m.weghorn@posteo.de>2020-02-12 08:07:42 +0100
committerMichael Weghorn <m.weghorn@posteo.de>2020-02-12 09:18:21 +0100
commit1e0b16f8695498e4eea7c2208aabf7e7664ce749 (patch)
tree5cfe351dfc9a6817e7a73e5071398ffa89c023ee
parent8d8f62852a64bd2fcae47a9499406d9167aebf83 (diff)
tdf#128921 tdf#130341 tdf#122053 qt5: Native PopupMenus
This implements native PopupMenus for the qt5 VCL plugin, which not only gives them the native look and feel, but also makes context menus faster (tdf#128921), accessible (e.g. to the Orca screen reader, tdf#122053), and makes them work for a case in Base's relationship dialog where entries in the non-native context menu were not selectable/clickable (tdf#130341). For now, this always shows the popup menu at cursor position, which can be changed by taking the Rectangle passed to 'Qt5Menu::ShowNativePopupMenu' into account if there should be any need. Change-Id: Ie52cbc682acacb92716ff51e8bf7f1ab07d34cf0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88512 Tested-by: Jenkins Reviewed-by: Michael Weghorn <m.weghorn@posteo.de>
-rw-r--r--vcl/inc/qt5/Qt5Menu.hxx16
-rw-r--r--vcl/qt5/Qt5Menu.cxx34
2 files changed, 48 insertions, 2 deletions
diff --git a/vcl/inc/qt5/Qt5Menu.hxx b/vcl/inc/qt5/Qt5Menu.hxx
index efcfb8eeb81c..2e5434f4db74 100644
--- a/vcl/inc/qt5/Qt5Menu.hxx
+++ b/vcl/inc/qt5/Qt5Menu.hxx
@@ -24,6 +24,17 @@ class QMenuBar;
class Qt5MenuItem;
class Qt5Frame;
+/*
+ * Qt5Menu can represent
+ * (1) the top-level menu of a menubar, in which case 'mbMenuBar' is true and
+ * 'mpQMenuBar' refers to the corresponding QMenuBar
+ * (2) another kind of menu (like a PopupMenu), in which case the corresponding QMenu
+ * object is instantiated and owned by this Qt5Menu (held in 'mpOwnedQMenu').
+ * (3) a "submenu" in an existing menu (like (1)), in which case the corresponding
+ * QMenu object is owned by the corresponding Qt5MenuItem.
+ *
+ * For (2) and (3), member 'mpQMenu' points to the corresponding QMenu object.
+ */
class Qt5Menu : public QObject, public SalMenu
{
Q_OBJECT
@@ -34,6 +45,9 @@ private:
Qt5Frame* mpFrame;
bool mbMenuBar;
QMenuBar* mpQMenuBar;
+ // self-created QMenu that this Qt5Menu represents, if applicable (s. comment for class)
+ std::unique_ptr<QMenu> mpOwnedQMenu;
+ // pointer to QMenu owned by the corresponding Qt5MenuItem or self (-> mpOwnedQMenu)
QMenu* mpQMenu;
QPushButton* mpCloseButton;
QMetaObject::Connection maCloseButtonConnection;
@@ -58,6 +72,8 @@ public:
virtual void SetFrame(const SalFrame* pFrame) override;
const Qt5Frame* GetFrame() const;
virtual void ShowMenuBar(bool bVisible) override;
+ virtual bool ShowNativePopupMenu(FloatingWindow* pWin, const tools::Rectangle& rRect,
+ FloatWinPopupFlags nFlags) override;
Qt5Menu* GetTopLevel();
virtual void SetItemBits(unsigned nPos, MenuItemBits nBits) override;
virtual void CheckItem(unsigned nPos, bool bCheck) override;
diff --git a/vcl/qt5/Qt5Menu.cxx b/vcl/qt5/Qt5Menu.cxx
index b2e752faedaa..98615247035a 100644
--- a/vcl/qt5/Qt5Menu.cxx
+++ b/vcl/qt5/Qt5Menu.cxx
@@ -24,6 +24,9 @@
#include <strings.hrc>
#include <bitmaps.hlst>
+#include <vcl/floatwin.hxx>
+#include <window.h>
+
Qt5Menu::Qt5Menu(bool bMenuBar)
: mpVCLMenu(nullptr)
, mpParentSalMenu(nullptr)
@@ -77,8 +80,15 @@ void Qt5Menu::InsertMenuItem(Qt5MenuItem* pSalMenuItem, unsigned nPos)
[pSalMenuItem] { slotMenuAboutToHide(pSalMenuItem); });
}
}
- else if (mpQMenu)
+ else
{
+ if (!mpQMenu)
+ {
+ // no QMenu set, instantiate own one
+ mpOwnedQMenu.reset(new QMenu);
+ mpQMenu = mpOwnedQMenu.get();
+ }
+
if (pSalMenuItem->mpSubMenu)
{
// submenu
@@ -148,7 +158,9 @@ void Qt5Menu::InsertMenuItem(Qt5MenuItem* pSalMenuItem, unsigned nPos)
UpdateActionGroupItem(pSalMenuItem);
- pAction->setShortcut(toQString(nAccelKey.GetName(GetFrame()->GetWindow())));
+ const Qt5Frame* pFrame = GetFrame();
+ if (pFrame)
+ pAction->setShortcut(toQString(nAccelKey.GetName(pFrame->GetWindow())));
connect(pAction, &QAction::triggered, this,
[pSalMenuItem] { slotMenuTriggered(pSalMenuItem); });
@@ -442,6 +454,11 @@ void Qt5Menu::DoFullMenuUpdate(Menu* pMenuBar)
Qt5MenuItem* pSalMenuItem = GetItemAtPos(nItem);
InsertMenuItem(pSalMenuItem, nItem);
SetItemImage(nItem, pSalMenuItem, pSalMenuItem->maImage);
+ const bool bShowDisabled
+ = bool(pMenuBar->GetMenuFlags() & MenuFlags::AlwaysShowDisabledEntries)
+ || !bool(pMenuBar->GetMenuFlags() & MenuFlags::HideDisabledEntries);
+ const bool bVisible = bShowDisabled || mpVCLMenu->IsItemEnabled(pSalMenuItem->mnId);
+ pSalMenuItem->getAction()->setVisible(bVisible);
if (pSalMenuItem->mpSubMenu != nullptr)
{
@@ -651,6 +668,19 @@ void Qt5Menu::ShowCloseButton(bool bShow)
pButton->hide();
}
+bool Qt5Menu::ShowNativePopupMenu(FloatingWindow*, const tools::Rectangle&,
+ FloatWinPopupFlags nFlags)
+{
+ assert(mpQMenu);
+ DoFullMenuUpdate(mpVCLMenu);
+ mpQMenu->setTearOffEnabled(bool(nFlags & FloatWinPopupFlags::AllowTearOff));
+
+ const QPoint aPos = QCursor::pos();
+ mpQMenu->exec(aPos);
+
+ return true;
+}
+
Qt5MenuItem::Qt5MenuItem(const SalItemParams* pItemData)
: mpParentMenu(nullptr)
, mpSubMenu(nullptr)