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>
This commit is contained in:
parent
8d8f62852a
commit
1e0b16f869
2 changed files with 48 additions and 2 deletions
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue