bump product version to 7.6.3.2-android
[LibreOffice.git] / include / vcl / menu.hxx
blobc6bd47efba0121c3a0f87ef5bbf5a1573a36fe99
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_VCL_MENU_HXX
21 #define INCLUDED_VCL_MENU_HXX
23 #include <memory>
24 #include <string_view>
26 #include <vcl/vclenum.hxx>
27 #include <tools/link.hxx>
28 #include <tools/long.hxx>
29 #include <vcl/dllapi.h>
30 #include <vcl/keycod.hxx>
31 #include <vcl/vclptr.hxx>
32 #include <vcl/vclreferencebase.hxx>
33 #include <com/sun/star/uno/Reference.hxx>
34 #include <o3tl/typed_flags_set.hxx>
35 #include <list>
37 class OutputDevice;
38 struct ImplSVEvent;
39 struct MenuItemData;
40 class Point;
41 class Size;
42 namespace tools { class Rectangle; }
43 class Menu;
44 class MenuItemList;
45 class Image;
46 class PopupMenu;
47 class KeyEvent;
48 class MenuFloatingWindow;
49 class SalMenu;
50 class MenuBarWindow;
51 class VclMenuEvent;
52 struct SystemMenuData;
53 enum class FloatWinPopupFlags;
54 enum class VclEventId;
56 namespace com::sun::star::awt { class XPopupMenu; }
57 namespace com::sun::star::accessibility { class XAccessible; }
59 namespace vcl
61 class Window;
62 struct MenuLayoutData;
63 typedef OutputDevice RenderContext; // same as in include/vcl/outdev.hxx
64 class ILibreOfficeKitNotifier;
67 constexpr sal_uInt16 MENU_APPEND = 0xFFFF;
68 constexpr sal_uInt16 MENU_ITEM_NOTFOUND = 0xFFFF;
70 // Must match the definitions in css::awt::PopupMenuDirection.idl
71 enum class PopupMenuFlags
73 NONE = 0x0000,
74 ExecuteDown = 0x0001,
75 ExecuteUp = 0x0002,
76 ExecuteRight = 0x0008,
77 NoMouseUpClose = 0x0010,
80 namespace o3tl
82 template<> struct typed_flags<PopupMenuFlags> : is_typed_flags<PopupMenuFlags, 0x001b> {};
85 enum class MenuFlags
87 NONE = 0x0000,
88 NoAutoMnemonics = 0x0001,
89 HideDisabledEntries = 0x0002,
90 // overrides default hiding of disabled entries in popup menus
91 AlwaysShowDisabledEntries = 0x0004,
94 namespace o3tl
96 template<> struct typed_flags<MenuFlags> : is_typed_flags<MenuFlags, 0x0007> {};
99 /// Invalid menu item id
100 constexpr auto ITEMPOS_INVALID = 0xFFFF;
102 struct ImplMenuDelData
104 ImplMenuDelData* mpNext;
105 VclPtr<const Menu> mpMenu;
107 explicit ImplMenuDelData( const Menu* );
108 ~ImplMenuDelData();
110 bool isDeleted() const { return mpMenu == nullptr; }
113 typedef void (*MenuUserDataReleaseFunction)(void*);
115 class VCL_DLLPUBLIC Menu : public VclReferenceBase
117 friend class MenuBar;
118 friend class MenuBarWindow;
119 friend class MenuButton;
120 friend class MenuFloatingWindow;
121 friend class PopupMenu;
122 friend class SystemWindow;
123 friend struct ImplMenuDelData;
124 private:
125 ImplMenuDelData* mpFirstDel;
126 std::unique_ptr<MenuItemList> pItemList; // list with MenuItems
127 VclPtr<Menu> pStartedFrom;
128 VclPtr<vcl::Window> pWindow;
130 Link<Menu*, bool> aActivateHdl; // Active-Handler
131 Link<Menu*, bool> aDeactivateHdl; // Deactivate-Handler
132 Link<Menu*, bool> aSelectHdl; // Select-Handler
134 std::list<Link<VclMenuEvent&,void> > maEventListeners;
136 OUString maID;
138 OUString aTitleText; // PopupMenu text
139 sal_uInt16 nTitleHeight;
141 ImplSVEvent* nEventId;
142 sal_uInt16 mnHighlightedItemPos; // for native menus: keeps track of the highlighted item
143 MenuFlags nMenuFlags;
144 sal_uInt16 nSelectedId;
145 OUString sSelectedIdent;
147 // for output:
148 sal_uInt16 nImgOrChkPos;
149 sal_uInt16 nTextPos;
151 bool bCanceled : 1; ///< Terminated during a callback
152 bool bInCallback : 1; ///< In Activate/Deactivate
153 bool bKilled : 1; ///< Killed
155 css::uno::Reference<css::accessibility::XAccessible > mxAccessible;
156 mutable std::unique_ptr<vcl::MenuLayoutData> mpLayoutData;
157 std::unique_ptr<SalMenu> mpSalMenu;
159 protected:
160 SAL_DLLPRIVATE Menu* ImplGetStartMenu();
161 SAL_DLLPRIVATE Menu* ImplFindSelectMenu();
162 SAL_DLLPRIVATE Menu* ImplFindMenu( sal_uInt16 nId );
163 SAL_DLLPRIVATE Size ImplCalcSize( vcl::Window* pWin );
164 SAL_DLLPRIVATE bool ImplIsVisible( sal_uInt16 nPos ) const;
165 SAL_DLLPRIVATE bool ImplCurrentlyHiddenOnGUI(sal_uInt16 nPos) const;
166 SAL_DLLPRIVATE bool ImplIsSelectable( sal_uInt16 nPos ) const;
167 SAL_DLLPRIVATE sal_uInt16 ImplGetVisibleItemCount() const;
168 SAL_DLLPRIVATE sal_uInt16 ImplGetFirstVisible() const;
169 SAL_DLLPRIVATE sal_uInt16 ImplGetPrevVisible( sal_uInt16 nPos ) const;
170 SAL_DLLPRIVATE sal_uInt16 ImplGetNextVisible( sal_uInt16 nPos ) const;
171 SAL_DLLPRIVATE void ImplPaint(vcl::RenderContext& rRenderContext, Size const & rSize,
172 sal_uInt16 nBorder, tools::Long nOffY = 0, MenuItemData const * pThisDataOnly = nullptr,
173 bool bHighlighted = false, bool bLayout = false, bool bRollover = false ) const;
174 SAL_DLLPRIVATE void ImplPaintMenuTitle(vcl::RenderContext&, const tools::Rectangle& rRect) const;
175 SAL_DLLPRIVATE void ImplSelect();
176 SAL_DLLPRIVATE void ImplCallHighlight( sal_uInt16 nHighlightItem );
177 SAL_DLLPRIVATE void ImplCallEventListeners( VclEventId nEvent, sal_uInt16 nPos );
178 DECL_DLLPRIVATE_LINK(ImplCallSelect, void*, void );
180 SAL_DLLPRIVATE void ImplFillLayoutData() const;
181 SAL_DLLPRIVATE SalMenu* ImplGetSalMenu() { return mpSalMenu.get(); }
182 SAL_DLLPRIVATE OUString ImplGetHelpText( sal_uInt16 nItemId ) const;
184 // returns native check and option menu symbol height in rCheckHeight and rRadioHeight
185 // return value is maximum width and height of checkboxes and radiobuttons
186 SAL_DLLPRIVATE Size ImplGetNativeCheckAndRadioSize(vcl::RenderContext const & rRenderContext, tools::Long& rCheckHeight, tools::Long& rRadioHeight) const;
188 // returns native submenu arrow size and spacing from right border
189 // return value is whether it's supported natively
190 SAL_DLLPRIVATE static bool ImplGetNativeSubmenuArrowSize(vcl::RenderContext const & rRenderContext, Size& rArrowSize, tools::Long& rArrowSpacing);
192 SAL_DLLPRIVATE void ImplAddDel( ImplMenuDelData &rDel );
193 SAL_DLLPRIVATE void ImplRemoveDel( ImplMenuDelData &rDel );
195 SAL_DLLPRIVATE MenuItemData* NbcInsertItem(sal_uInt16 nId, MenuItemBits nBits,
196 const OUString& rStr, Menu* pMenu,
197 size_t nPos, const OUString &rIdent);
199 /// Close the 'pStartedFrom' menu window.
200 virtual void ClosePopup(Menu* pMenu) = 0;
202 /// Forward the KeyInput call to the MenuBar.
203 virtual void MenuBarKeyInput(const KeyEvent& rEvent);
205 public:
206 SAL_DLLPRIVATE void ImplKillLayoutData() const;
208 SAL_DLLPRIVATE vcl::Window* ImplGetWindow() const { return pWindow; }
209 #if defined(MACOSX)
210 void ImplSelectWithStart( Menu* pStartMenu = nullptr );
211 #endif
213 protected:
215 /** The Menu constructor is protected.
217 The callers are supposed to instantiate either PopupMenu or MenuBar, but
218 not a Menu directly.
220 Menu();
222 public:
223 virtual ~Menu() override;
224 virtual void dispose() override;
226 void Activate();
227 void Deactivate();
228 void Select();
230 void InsertItem(sal_uInt16 nItemId, const OUString& rStr,
231 MenuItemBits nItemBits = MenuItemBits::NONE,
232 const OUString &rIdent = {},
233 sal_uInt16 nPos = MENU_APPEND);
234 void InsertItem(sal_uInt16 nItemId, const Image& rImage,
235 MenuItemBits nItemBits = MenuItemBits::NONE,
236 const OUString &rIdent = {},
237 sal_uInt16 nPos = MENU_APPEND);
238 void InsertItem(sal_uInt16 nItemId,
239 const OUString& rString, const Image& rImage,
240 MenuItemBits nItemBits = MenuItemBits::NONE,
241 const OUString &rIdent = {},
242 sal_uInt16 nPos = MENU_APPEND);
243 void InsertSeparator(const OUString &rIdent = {}, sal_uInt16 nPos = MENU_APPEND);
244 void RemoveItem( sal_uInt16 nPos );
245 void Clear();
247 void CreateAutoMnemonics();
249 void SetMenuFlags( MenuFlags nFlags ) { nMenuFlags = nFlags; }
250 MenuFlags GetMenuFlags() const { return nMenuFlags; }
252 sal_uInt16 GetItemCount() const;
253 sal_uInt16 GetItemId(sal_uInt16 nPos) const;
254 sal_uInt16 GetItemId(std::u16string_view rIdent) const;
255 sal_uInt16 GetItemPos( sal_uInt16 nItemId ) const;
256 OUString GetItemIdent(sal_uInt16 nItemId) const;
257 MenuItemType GetItemType( sal_uInt16 nPos ) const;
258 sal_uInt16 GetCurItemId() const { return nSelectedId;}
259 OUString const & GetCurItemIdent() const { return sSelectedIdent; }
260 void SetItemBits( sal_uInt16 nItemId, MenuItemBits nBits );
261 MenuItemBits GetItemBits( sal_uInt16 nItemId ) const;
263 void SetUserValue(sal_uInt16 nItemId, void* nUserValue, MenuUserDataReleaseFunction aFunc=nullptr);
264 void* GetUserValue(sal_uInt16 nItemId) const;
266 void SetPopupMenu( sal_uInt16 nItemId, PopupMenu* pMenu );
267 PopupMenu* GetPopupMenu( sal_uInt16 nItemId ) const;
269 void SetAccelKey( sal_uInt16 nItemId, const vcl::KeyCode& rKeyCode );
270 vcl::KeyCode GetAccelKey( sal_uInt16 nItemId ) const;
272 void CheckItem( sal_uInt16 nItemId, bool bCheck = true );
273 void CheckItem( std::u16string_view rIdent, bool bCheck = true );
274 bool IsItemChecked( sal_uInt16 nItemId ) const;
276 virtual void SelectItem(sal_uInt16 nItemId) = 0;
278 void EnableItem( sal_uInt16 nItemId, bool bEnable = true );
279 void EnableItem(std::u16string_view rIdent, bool bEnable = true)
281 EnableItem(GetItemId(rIdent), bEnable);
283 bool IsItemEnabled( sal_uInt16 nItemId ) const;
285 void ShowItem( sal_uInt16 nItemId, bool bVisible = true );
286 void HideItem( sal_uInt16 nItemId ) { ShowItem( nItemId, false ); }
288 bool IsItemPosVisible( sal_uInt16 nItemPos ) const;
289 bool IsMenuVisible() const;
290 virtual bool IsMenuBar() const = 0;
292 void RemoveDisabledEntries( bool bRemoveEmptyPopups = false );
294 void UpdateNativeMenu();
296 void SetItemText( sal_uInt16 nItemId, const OUString& rStr );
297 OUString GetItemText( sal_uInt16 nItemId ) const;
299 void SetItemImage( sal_uInt16 nItemId, const Image& rImage );
300 Image GetItemImage( sal_uInt16 nItemId ) const;
302 void SetItemCommand( sal_uInt16 nItemId, const OUString& rCommand );
303 OUString GetItemCommand( sal_uInt16 nItemId ) const;
305 void SetHelpText( sal_uInt16 nItemId, const OUString& rString );
306 OUString GetHelpText( sal_uInt16 nItemId ) const;
308 void SetTipHelpText( sal_uInt16 nItemId, const OUString& rString );
309 OUString GetTipHelpText( sal_uInt16 nItemId ) const;
311 void SetHelpCommand( sal_uInt16 nItemId, const OUString& rString );
312 OUString GetHelpCommand( sal_uInt16 nItemId ) const;
314 void SetHelpId( sal_uInt16 nItemId, const OUString& rHelpId );
315 OUString GetHelpId( sal_uInt16 nItemId ) const;
317 void SetActivateHdl( const Link<Menu *, bool>& rLink )
319 aActivateHdl = rLink;
322 void SetDeactivateHdl( const Link<Menu *, bool>& rLink )
324 aDeactivateHdl = rLink;
327 void SetSelectHdl( const Link<Menu*,bool>& rLink )
329 aSelectHdl = rLink;
332 sal_uInt16 GetTitleHeight() const
334 return nTitleHeight;
337 void AddEventListener( const Link<VclMenuEvent&,void>& rEventListener );
338 void RemoveEventListener( const Link<VclMenuEvent&,void>& rEventListener );
340 Menu& operator =( const Menu& rMenu );
342 // for menu functions
343 MenuItemList* GetItemList() const
345 return pItemList.get();
348 // returns the system's menu handle if native menus are supported
349 // pData must point to a SystemMenuData structure
350 void GetSystemMenuData( SystemMenuData* pData ) const;
352 // accessibility helpers
354 // returns the bounding box for the character at index nIndex
355 // where nIndex is relative to the starting index of the item
356 // with id nItemId (in coordinates of the displaying window)
357 tools::Rectangle GetCharacterBounds( sal_uInt16 nItemId, tools::Long nIndex ) const;
358 // -1 is returned if no character is at that point
359 // if an index is found the corresponding item id is filled in (else 0)
360 tools::Long GetIndexForPoint( const Point& rPoint, sal_uInt16& rItemID ) const;
361 // returns the bounding rectangle for an item at pos nItemPos
362 tools::Rectangle GetBoundingRectangle( sal_uInt16 nItemPos ) const;
364 css::uno::Reference<css::accessibility::XAccessible> GetAccessible();
365 void SetAccessible(const css::uno::Reference<css::accessibility::XAccessible >& rxAccessible);
367 // gets the activation key of the specified item
368 KeyEvent GetActivationKey( sal_uInt16 nItemId ) const;
370 vcl::Window* GetWindow() const { return pWindow; }
372 void SetAccessibleName( sal_uInt16 nItemId, const OUString& rStr );
373 OUString GetAccessibleName( sal_uInt16 nItemId ) const;
375 void SetAccessibleDescription( sal_uInt16 nItemId, const OUString& rStr );
376 OUString GetAccessibleDescription( sal_uInt16 nItemId ) const;
378 // returns whether the item a position nItemPos is highlighted or not.
379 bool IsHighlighted( sal_uInt16 nItemPos ) const;
381 void HighlightItem( sal_uInt16 nItemPos );
382 void DeHighlight() { HighlightItem( 0xFFFF ); } // MENUITEMPOS_INVALID
384 bool HandleMenuCommandEvent(Menu *pMenu, sal_uInt16 nEventId) const;
385 bool HandleMenuActivateEvent(Menu *pMenu) const;
386 bool HandleMenuDeActivateEvent(Menu *pMenu) const;
389 * Sets an ID.
391 void set_id(const OUString& rID) { maID = rID; }
394 * Get the ID of the window.
396 const OUString& get_id() const { return maID; }
399 struct MenuBarButtonCallbackArg
401 sal_uInt16 nId; // Id of the button
402 bool bHighlight; // highlight on/off
405 class VCL_DLLPUBLIC MenuBar final : public Menu
407 Link<void*,void> maCloseHdl;
408 bool mbCloseBtnVisible : 1;
409 bool mbFloatBtnVisible : 1;
410 bool mbHideBtnVisible : 1;
411 bool mbDisplayable : 1;
413 friend class Application;
414 friend class Menu;
415 friend class MenuBarWindow;
416 friend class MenuFloatingWindow;
417 friend class SystemWindow;
419 SAL_DLLPRIVATE static VclPtr<vcl::Window> ImplCreate(vcl::Window* pParent, vcl::Window* pWindow, MenuBar* pMenu);
420 SAL_DLLPRIVATE static void ImplDestroy(MenuBar* pMenu, bool bDelete);
421 SAL_DLLPRIVATE bool ImplHandleKeyEvent(const KeyEvent& rKEvent);
423 /// Return the MenuBarWindow.
424 MenuBarWindow* getMenuBarWindow();
426 public:
427 MenuBar();
428 MenuBar( const MenuBar& rMenu );
429 virtual ~MenuBar() override;
430 virtual void dispose() override;
432 MenuBar& operator =( const MenuBar& rMenu );
434 virtual bool IsMenuBar() const override { return true; }
436 /// Close the 'pStartedFrom' menu window.
437 virtual void ClosePopup(Menu* pMenu) override;
439 /// Forward the KeyInput call to the MenuBar.
440 virtual void MenuBarKeyInput(const KeyEvent& rEvent) override;
442 void ShowCloseButton( bool bShow );
443 bool HasCloseButton() const { return mbCloseBtnVisible; }
444 bool HasFloatButton() const { return mbFloatBtnVisible; }
445 bool HasHideButton() const { return mbHideBtnVisible; }
446 void ShowButtons( bool bClose, bool bFloat, bool bHide );
448 virtual void SelectItem(sal_uInt16 nId) override;
449 bool HandleMenuHighlightEvent(Menu *pMenu, sal_uInt16 nEventId) const;
450 bool HandleMenuButtonEvent(sal_uInt16 nEventId);
452 void SetCloseButtonClickHdl( const Link<void*,void>& rLink ) { maCloseHdl = rLink; }
453 const Link<void*,void>& GetCloseButtonClickHdl() const { return maCloseHdl; }
455 // - by default a menubar is displayable
456 // - if a menubar is not displayable, its MenuBarWindow will never be shown
457 // and it will be hidden if it was visible before
458 // - note: if a menubar is displayable, this does not necessarily mean that it is currently visible
459 void SetDisplayable( bool bDisplayable );
460 bool IsDisplayable() const { return mbDisplayable; }
462 // add an arbitrary button to the menubar (will appear next to closer)
463 // passed link will be call with a MenuBarButtonCallbackArg on press
464 // passed string will be set as tooltip
465 sal_uInt16 AddMenuBarButton( const Image&, const Link<MenuBarButtonCallbackArg&,bool>&, const OUString& );
466 // set the highlight link for additional button with ID nId
467 // highlight link will be called with a MenuBarButtonHighlightArg
468 // the bHighlight member of that struct shall contain the new state
469 void SetMenuBarButtonHighlightHdl( sal_uInt16 nId, const Link<MenuBarButtonCallbackArg&,bool>& );
470 // returns the rectangle occupied by the additional button named nId
471 // coordinates are relative to the systemwindow the menubar is attached to
472 // if the menubar is unattached an empty rectangle is returned
473 tools::Rectangle GetMenuBarButtonRectPixel( sal_uInt16 nId );
474 void RemoveMenuBarButton( sal_uInt16 nId );
475 void LayoutChanged();
476 // get the height of the menubar, return the native menubar height if that is active or the vcl
477 // one if not
478 int GetMenuBarHeight() const;
481 inline MenuBar& MenuBar::operator=( const MenuBar& rMenu )
483 Menu::operator=(rMenu);
484 return *this;
487 class VCL_DLLPUBLIC PopupMenu final : public Menu
489 friend class Menu;
490 friend class MenuFloatingWindow;
491 friend class MenuBarWindow;
492 friend struct MenuItemData;
494 private:
495 SAL_DLLPRIVATE MenuFloatingWindow * ImplGetFloatingWindow() const;
496 SAL_DLLPRIVATE bool PrepareRun(const VclPtr<vcl::Window>& pParentWin, tools::Rectangle& rRect, FloatWinPopupFlags& nPopupModeFlags, Menu* pSFrom, bool& bRealExecute, VclPtr<MenuFloatingWindow>&);
497 SAL_DLLPRIVATE bool Run(const VclPtr<MenuFloatingWindow>&, bool bRealExecute, bool bPreSelectFirst, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, const tools::Rectangle& rRect);
498 SAL_DLLPRIVATE void FinishRun(const VclPtr<MenuFloatingWindow>&, const VclPtr<vcl::Window>& pParentWin, bool bRealExecute, bool bIsNativeMenu);
499 SAL_DLLPRIVATE sal_uInt16 ImplExecute(const VclPtr<vcl::Window>& pParentWin, const tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool bPreSelectFirst);
500 SAL_DLLPRIVATE void ImplFlushPendingSelect();
501 SAL_DLLPRIVATE tools::Long ImplCalcHeight( sal_uInt16 nEntries ) const;
502 SAL_DLLPRIVATE sal_uInt16 ImplCalcVisEntries( tools::Long nMaxHeight, sal_uInt16 nStartEntry, sal_uInt16* pLastVisible = nullptr ) const;
504 public:
505 PopupMenu();
506 PopupMenu( const PopupMenu& rMenu );
507 virtual ~PopupMenu() override;
509 virtual bool IsMenuBar() const override { return false; }
511 /// Close the 'pStartedFrom' menu window.
512 virtual void ClosePopup(Menu* pMenu) override;
514 void SetText( const OUString& rTitle )
516 aTitleText = rTitle;
519 sal_uInt16 Execute( vcl::Window* pWindow, const Point& rPopupPos );
520 sal_uInt16 Execute( vcl::Window* pWindow, const tools::Rectangle& rRect, PopupMenuFlags nFlags = PopupMenuFlags::NONE );
522 // for the TestTool
523 void EndExecute();
524 virtual void SelectItem(sal_uInt16 nId) override;
525 void SetSelectedEntry( sal_uInt16 nId ); // for use by native submenu only
527 css::uno::Reference<css::awt::XPopupMenu> CreateMenuInterface();
529 static PopupMenu* GetActivePopupMenu();
531 PopupMenu& operator=( const PopupMenu& rMenu );
534 inline PopupMenu& PopupMenu::operator=( const PopupMenu& rMenu )
536 Menu::operator=( rMenu );
537 return *this;
540 #endif // INCLUDED_VCL_MENU_HXX
542 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */