lok: calc - send other views our selection in their co-ordinates.
[LibreOffice.git] / include / vcl / menu.hxx
blob76a39c813eef24aec4f6e7177ffd12516ce2fb30
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 <vcl/vclenum.hxx>
25 #include <tools/link.hxx>
26 #include <vcl/dllapi.h>
27 #include <vcl/keycod.hxx>
28 #include <vcl/vclreferencebase.hxx>
29 #include <vcl/vclevent.hxx>
30 #include <com/sun/star/uno/Reference.hxx>
31 #include <o3tl/typed_flags_set.hxx>
32 #include <list>
34 class OutputDevice;
35 struct ImplSVEvent;
36 struct MenuItemData;
37 class Point;
38 class Size;
39 namespace tools { class Rectangle; }
40 class Menu;
41 class MenuItemList;
42 class Image;
43 class PopupMenu;
44 class KeyEvent;
45 class CommandEvent;
46 class MenuFloatingWindow;
47 class SalMenu;
48 class MenuBarWindow;
49 struct SystemMenuData;
50 enum class FloatWinPopupFlags;
52 namespace com { namespace sun { namespace star { namespace accessibility {
53 class XAccessible;
54 }}}}
56 namespace com { namespace sun { namespace star { namespace frame { class XFrame; } } } }
58 namespace vcl
60 class Window;
61 struct MenuLayoutData;
62 typedef OutputDevice RenderContext; // same as in include/vcl/outdev.hxx
63 class ILibreOfficeKitNotifier;
66 #define MENU_APPEND (sal_uInt16(0xFFFF))
67 #define MENU_ITEM_NOTFOUND (sal_uInt16(0xFFFF))
69 // Must match the definitions in css::awt::PopupMenuDirection.idl
70 enum class PopupMenuFlags
72 NONE = 0x0000,
73 ExecuteDown = 0x0001,
74 ExecuteUp = 0x0002,
75 ExecuteLeft = 0x0004,
76 ExecuteRight = 0x0008,
77 NoMouseUpClose = 0x0010,
78 //If there isn't enough space to put the menu where it wants
79 //to go, then they will be autoplaced. Toggle this bit
80 //on to force menus to be placed either above or below
81 //the starting rectangle and shrunk to fit and then scroll rather than place
82 //the menu beside that rectangle
83 NoHorzPlacement = 0x0020,
86 namespace o3tl
88 template<> struct typed_flags<PopupMenuFlags> : is_typed_flags<PopupMenuFlags, 0x003f> {};
91 enum class MenuFlags
93 NONE = 0x0000,
94 NoAutoMnemonics = 0x0001,
95 HideDisabledEntries = 0x0002,
96 // overrides default hiding of disabled entries in popup menus
97 AlwaysShowDisabledEntries = 0x0004,
100 namespace o3tl
102 template<> struct typed_flags<MenuFlags> : is_typed_flags<MenuFlags, 0x0007> {};
105 /// Invalid menu item id
106 #define ITEMPOS_INVALID 0xFFFF
108 struct ImplMenuDelData
110 ImplMenuDelData* mpNext;
111 VclPtr<const Menu> mpMenu;
113 explicit ImplMenuDelData( const Menu* );
114 ~ImplMenuDelData();
116 bool isDeleted() const { return mpMenu == nullptr; }
119 typedef void (*MenuUserDataReleaseFunction)(void*);
121 class VCL_DLLPUBLIC Menu : public VclReferenceBase
123 friend class MenuBar;
124 friend class MenuBarWindow;
125 friend class MenuButton;
126 friend class MenuFloatingWindow;
127 friend class PopupMenu;
128 friend class SystemWindow;
129 friend struct ImplMenuDelData;
130 private:
131 ImplMenuDelData* mpFirstDel;
132 std::unique_ptr<MenuItemList> pItemList; // list with MenuItems
133 VclPtr<Menu> pStartedFrom;
134 VclPtr<vcl::Window> pWindow;
136 Link<Menu*, bool> aActivateHdl; // Active-Handler
137 Link<Menu*, bool> aDeactivateHdl; // Deactivate-Handler
138 Link<Menu*, bool> aSelectHdl; // Select-Handler
140 std::list<Link<VclMenuEvent&,void> > maEventListeners;
142 OUString aTitleText; // PopupMenu text
143 sal_uInt16 nTitleHeight;
145 ImplSVEvent* nEventId;
146 sal_uInt16 mnHighlightedItemPos; // for native menus: keeps track of the highlighted item
147 MenuFlags nMenuFlags;
148 sal_uInt16 nSelectedId;
149 OString sSelectedIdent;
151 // for output:
152 sal_uInt16 nImgOrChkPos;
153 sal_uInt16 nTextPos;
155 bool bCanceled : 1; ///< Terminated during a callback
156 bool bInCallback : 1; ///< In Activate/Deactivate
157 bool bKilled : 1; ///< Killed
159 css::uno::Reference<css::accessibility::XAccessible > mxAccessible;
160 mutable std::unique_ptr<vcl::MenuLayoutData> mpLayoutData;
161 std::unique_ptr<SalMenu> mpSalMenu;
163 protected:
164 SAL_DLLPRIVATE Menu* ImplGetStartMenu();
165 SAL_DLLPRIVATE Menu* ImplFindSelectMenu();
166 SAL_DLLPRIVATE Menu* ImplFindMenu( sal_uInt16 nId );
167 SAL_DLLPRIVATE Size ImplCalcSize( vcl::Window* pWin );
168 SAL_DLLPRIVATE bool ImplIsVisible( sal_uInt16 nPos ) const;
169 SAL_DLLPRIVATE bool ImplCurrentlyHiddenOnGUI(sal_uInt16 nPos) const;
170 SAL_DLLPRIVATE bool ImplIsSelectable( sal_uInt16 nPos ) const;
171 SAL_DLLPRIVATE sal_uInt16 ImplGetVisibleItemCount() const;
172 SAL_DLLPRIVATE sal_uInt16 ImplGetFirstVisible() const;
173 SAL_DLLPRIVATE sal_uInt16 ImplGetPrevVisible( sal_uInt16 nPos ) const;
174 SAL_DLLPRIVATE sal_uInt16 ImplGetNextVisible( sal_uInt16 nPos ) const;
175 SAL_DLLPRIVATE void ImplPaint(vcl::RenderContext& rRenderContext, Size const & rSize,
176 sal_uInt16 nBorder, long nOffY = 0, MenuItemData const * pThisDataOnly = nullptr,
177 bool bHighlighted = false, bool bLayout = false, bool bRollover = false ) const;
178 SAL_DLLPRIVATE void ImplPaintMenuTitle(vcl::RenderContext&, const tools::Rectangle& rRect) const;
179 SAL_DLLPRIVATE void ImplSelect();
180 SAL_DLLPRIVATE void ImplCallHighlight( sal_uInt16 nHighlightItem );
181 SAL_DLLPRIVATE void ImplCallEventListeners( VclEventId nEvent, sal_uInt16 nPos );
182 DECL_DLLPRIVATE_LINK(ImplCallSelect, void*, void );
184 SAL_DLLPRIVATE void ImplFillLayoutData() const;
185 SAL_DLLPRIVATE SalMenu* ImplGetSalMenu() { return mpSalMenu.get(); }
186 SAL_DLLPRIVATE void ImplClearSalMenu();
187 SAL_DLLPRIVATE OUString ImplGetHelpText( sal_uInt16 nItemId ) const;
189 // returns native check and option menu symbol height in rCheckHeight and rRadioHeight
190 // return value is maximum width and height of checkboxes and radiobuttons
191 SAL_DLLPRIVATE Size ImplGetNativeCheckAndRadioSize(vcl::RenderContext const & rRenderContext, long& rCheckHeight, long& rRadioHeight) const;
193 // returns native submenu arrow size and spacing from right border
194 // return value is whether it's supported natively
195 SAL_DLLPRIVATE static bool ImplGetNativeSubmenuArrowSize(vcl::RenderContext const & rRenderContext, Size& rArrowSize, long& rArrowSpacing);
197 SAL_DLLPRIVATE void ImplAddDel( ImplMenuDelData &rDel );
198 SAL_DLLPRIVATE void ImplRemoveDel( ImplMenuDelData &rDel );
200 SAL_DLLPRIVATE MenuItemData* NbcInsertItem(sal_uInt16 nId, MenuItemBits nBits,
201 const OUString& rStr, Menu* pMenu,
202 size_t nPos, const OString &rIdent);
204 /// Close the 'pStartedFrom' menu window.
205 virtual void ClosePopup(Menu* pMenu) = 0;
207 /// Forward the KeyInput call to the MenuBar.
208 virtual void MenuBarKeyInput(const KeyEvent& rEvent);
210 public:
211 SAL_DLLPRIVATE void ImplKillLayoutData() const;
213 SAL_DLLPRIVATE vcl::Window* ImplGetWindow() const { return pWindow; }
214 #if defined(MACOSX)
215 void ImplSelectWithStart( Menu* pStartMenu = nullptr );
216 #endif
218 protected:
220 /** The Menu constructor is protected.
222 The callers are supposed to instantiate either PopupMenu or MenuBar, but
223 not a Menu directly.
225 Menu();
227 public:
228 virtual ~Menu() override;
229 virtual void dispose() override;
231 void Activate();
232 void Deactivate();
233 virtual void Select();
235 void InsertItem(sal_uInt16 nItemId, const OUString& rStr,
236 MenuItemBits nItemBits = MenuItemBits::NONE,
237 const OString &rIdent = OString(),
238 sal_uInt16 nPos = MENU_APPEND);
239 void InsertItem(sal_uInt16 nItemId, const Image& rImage,
240 MenuItemBits nItemBits = MenuItemBits::NONE,
241 const OString &rIdent = OString(),
242 sal_uInt16 nPos = MENU_APPEND);
243 void InsertItem(sal_uInt16 nItemId,
244 const OUString& rString, const Image& rImage,
245 MenuItemBits nItemBits = MenuItemBits::NONE,
246 const OString &rIdent = OString(),
247 sal_uInt16 nPos = MENU_APPEND);
248 void InsertItem(const OUString& rCommand,
249 const css::uno::Reference<css::frame::XFrame>& rFrame);
250 void InsertSeparator(const OString &rIdent = OString(), sal_uInt16 nPos = MENU_APPEND);
251 void RemoveItem( sal_uInt16 nPos );
252 void Clear();
254 void CreateAutoMnemonics();
256 void SetMenuFlags( MenuFlags nFlags ) { nMenuFlags = nFlags; }
257 MenuFlags GetMenuFlags() const { return nMenuFlags; }
259 sal_uInt16 GetItemCount() const;
260 sal_uInt16 GetItemId(sal_uInt16 nPos) const;
261 sal_uInt16 GetItemId(const OString &rIdent) const;
262 sal_uInt16 GetItemPos( sal_uInt16 nItemId ) const;
263 OString GetItemIdent(sal_uInt16 nItemId) const;
264 MenuItemType GetItemType( sal_uInt16 nPos ) const;
265 sal_uInt16 GetCurItemId() const { return nSelectedId;}
266 OString const & GetCurItemIdent() const { return sSelectedIdent; }
267 void SetItemBits( sal_uInt16 nItemId, MenuItemBits nBits );
268 MenuItemBits GetItemBits( sal_uInt16 nItemId ) const;
270 void SetUserValue(sal_uInt16 nItemId, void* nUserValue, MenuUserDataReleaseFunction aFunc=nullptr);
271 void* GetUserValue(sal_uInt16 nItemId) const;
273 void SetPopupMenu( sal_uInt16 nItemId, PopupMenu* pMenu );
274 PopupMenu* GetPopupMenu( sal_uInt16 nItemId ) const;
276 void SetAccelKey( sal_uInt16 nItemId, const vcl::KeyCode& rKeyCode );
277 vcl::KeyCode GetAccelKey( sal_uInt16 nItemId ) const;
279 void CheckItem( sal_uInt16 nItemId, bool bCheck = true );
280 void CheckItem( const OString &rIdent, bool bCheck = true );
281 bool IsItemChecked( sal_uInt16 nItemId ) const;
283 virtual void SelectItem(sal_uInt16 nItemId) = 0;
285 void EnableItem( sal_uInt16 nItemId, bool bEnable = true );
286 void EnableItem(const OString &rIdent, bool bEnable = true)
288 EnableItem(GetItemId(rIdent), bEnable);
290 bool IsItemEnabled( sal_uInt16 nItemId ) const;
292 void ShowItem( sal_uInt16 nItemId, bool bVisible = true );
293 void HideItem( sal_uInt16 nItemId ) { ShowItem( nItemId, false ); }
295 bool IsItemPosVisible( sal_uInt16 nItemPos ) const;
296 bool IsMenuVisible() const;
297 virtual bool IsMenuBar() const = 0;
299 void RemoveDisabledEntries( bool bCheckPopups = true, bool bRemoveEmptyPopups = false );
301 void UpdateNativeMenu();
303 void SetItemText( sal_uInt16 nItemId, const OUString& rStr );
304 OUString GetItemText( sal_uInt16 nItemId ) const;
306 void SetItemImage( sal_uInt16 nItemId, const Image& rImage );
307 Image GetItemImage( sal_uInt16 nItemId ) const;
309 void SetItemCommand( sal_uInt16 nItemId, const OUString& rCommand );
310 OUString GetItemCommand( sal_uInt16 nItemId ) const;
312 void SetHelpText( sal_uInt16 nItemId, const OUString& rString );
313 OUString GetHelpText( sal_uInt16 nItemId ) const;
315 void SetTipHelpText( sal_uInt16 nItemId, const OUString& rString );
316 OUString GetTipHelpText( sal_uInt16 nItemId ) const;
318 void SetHelpCommand( sal_uInt16 nItemId, const OUString& rString );
319 OUString GetHelpCommand( sal_uInt16 nItemId ) const;
321 void SetHelpId( sal_uInt16 nItemId, const OString& rHelpId );
322 OString GetHelpId( sal_uInt16 nItemId ) const;
324 void SetActivateHdl( const Link<Menu *, bool>& rLink )
326 aActivateHdl = rLink;
329 void SetDeactivateHdl( const Link<Menu *, bool>& rLink )
331 aDeactivateHdl = rLink;
334 void SetSelectHdl( const Link<Menu*,bool>& rLink )
336 aSelectHdl = rLink;
339 sal_uInt16 GetTitleHeight() const
341 return nTitleHeight;
344 void AddEventListener( const Link<VclMenuEvent&,void>& rEventListener );
345 void RemoveEventListener( const Link<VclMenuEvent&,void>& rEventListener );
347 Menu& operator =( const Menu& rMenu );
349 // for menu functions
350 MenuItemList* GetItemList() const
352 return pItemList.get();
355 // returns the system's menu handle if native menus are supported
356 // pData must point to a SystemMenuData structure
357 void GetSystemMenuData( SystemMenuData* pData ) const;
359 // accessibility helpers
361 // returns the bounding box for the character at index nIndex
362 // where nIndex is relative to the starting index of the item
363 // with id nItemId (in coordinates of the displaying window)
364 tools::Rectangle GetCharacterBounds( sal_uInt16 nItemId, long nIndex ) const;
365 // -1 is returned if no character is at that point
366 // if an index is found the corresponding item id is filled in (else 0)
367 long GetIndexForPoint( const Point& rPoint, sal_uInt16& rItemID ) const;
368 // returns the bounding rectangle for an item at pos nItemPos
369 tools::Rectangle GetBoundingRectangle( sal_uInt16 nItemPos ) const;
371 css::uno::Reference<css::accessibility::XAccessible> GetAccessible();
372 void SetAccessible(const css::uno::Reference<css::accessibility::XAccessible >& rxAccessible);
374 // gets the activation key of the specified item
375 KeyEvent GetActivationKey( sal_uInt16 nItemId ) const;
377 vcl::Window* GetWindow() const { return pWindow; }
379 OUString GetAccessibleName( sal_uInt16 nItemId ) const;
381 // returns whether the item a position nItemPos is highlighted or not.
382 bool IsHighlighted( sal_uInt16 nItemPos ) const;
384 void HighlightItem( sal_uInt16 nItemPos );
385 void DeHighlight() { HighlightItem( 0xFFFF ); } // MENUITEMPOS_INVALID
387 bool HandleMenuCommandEvent(Menu *pMenu, sal_uInt16 nEventId) const;
388 bool HandleMenuActivateEvent(Menu *pMenu) const;
389 bool HandleMenuDeActivateEvent(Menu *pMenu) const;
392 class VCL_DLLPUBLIC MenuBar : public Menu
394 Link<void*,void> maCloseHdl;
395 bool mbCloseBtnVisible : 1;
396 bool mbFloatBtnVisible : 1;
397 bool mbHideBtnVisible : 1;
398 bool mbDisplayable : 1;
400 friend class Application;
401 friend class Menu;
402 friend class MenuBarWindow;
403 friend class MenuFloatingWindow;
404 friend class SystemWindow;
406 SAL_DLLPRIVATE static VclPtr<vcl::Window> ImplCreate(vcl::Window* pParent, vcl::Window* pWindow, MenuBar* pMenu);
407 SAL_DLLPRIVATE static void ImplDestroy(MenuBar* pMenu, bool bDelete);
408 SAL_DLLPRIVATE bool ImplHandleKeyEvent(const KeyEvent& rKEvent);
409 SAL_DLLPRIVATE bool ImplHandleCmdEvent(const CommandEvent& rCEvent);
411 protected:
413 /// Return the MenuBarWindow.
414 MenuBarWindow* getMenuBarWindow();
416 public:
417 MenuBar();
418 MenuBar( const MenuBar& rMenu );
419 virtual ~MenuBar() override;
420 virtual void dispose() override;
422 MenuBar& operator =( const MenuBar& rMenu );
424 virtual bool IsMenuBar() const override { return true; }
426 /// Close the 'pStartedFrom' menu window.
427 virtual void ClosePopup(Menu* pMenu) override;
429 /// Forward the KeyInput call to the MenuBar.
430 virtual void MenuBarKeyInput(const KeyEvent& rEvent) override;
432 void ShowCloseButton( bool bShow );
433 bool HasCloseButton() const { return mbCloseBtnVisible; }
434 bool HasFloatButton() const { return mbFloatBtnVisible; }
435 bool HasHideButton() const { return mbHideBtnVisible; }
436 void ShowButtons( bool bClose, bool bFloat, bool bHide );
438 virtual void SelectItem(sal_uInt16 nId) override;
439 bool HandleMenuHighlightEvent(Menu *pMenu, sal_uInt16 nEventId) const;
440 bool HandleMenuButtonEvent(sal_uInt16 nEventId);
442 void SetCloseButtonClickHdl( const Link<void*,void>& rLink ) { maCloseHdl = rLink; }
443 const Link<void*,void>& GetCloseButtonClickHdl() const { return maCloseHdl; }
445 // - by default a menubar is displayable
446 // - if a menubar is not displayable, its MenuBarWindow will never be shown
447 // and it will be hidden if it was visible before
448 // - note: if a menubar is displayable, this does not necessarily mean that it is currently visible
449 void SetDisplayable( bool bDisplayable );
450 bool IsDisplayable() const { return mbDisplayable; }
452 struct MenuBarButtonCallbackArg
454 sal_uInt16 nId; // Id of the button
455 bool bHighlight; // highlight on/off
457 // add an arbitrary button to the menubar (will appear next to closer)
458 // passed link will be call with a MenuBarButtonCallbackArg on press
459 // passed string will be set as tooltip
460 sal_uInt16 AddMenuBarButton( const Image&, const Link<MenuBar::MenuBarButtonCallbackArg&,bool>&, const OUString& );
461 // set the highlight link for additional button with ID nId
462 // highlight link will be called with a MenuBarButtonHighlightArg
463 // the bHighlight member of that struct shall contain the new state
464 void SetMenuBarButtonHighlightHdl( sal_uInt16 nId, const Link<MenuBar::MenuBarButtonCallbackArg&,bool>& );
465 // returns the rectangle occupied by the additional button named nId
466 // coordinates are relative to the systemwindow the menubar is attached to
467 // if the menubar is unattached an empty rectangle is returned
468 tools::Rectangle GetMenuBarButtonRectPixel( sal_uInt16 nId );
469 void RemoveMenuBarButton( sal_uInt16 nId );
470 void LayoutChanged();
471 // get the height of the menubar, return the native menubar height if that is active or the vcl
472 // one if not
473 int GetMenuBarHeight() const;
476 inline MenuBar& MenuBar::operator=( const MenuBar& rMenu )
478 Menu::operator=(rMenu);
479 return *this;
482 class VCL_DLLPUBLIC PopupMenu : public Menu
484 friend class Menu;
485 friend class MenuFloatingWindow;
486 friend class MenuBarWindow;
487 friend struct MenuItemData;
489 private:
490 const vcl::ILibreOfficeKitNotifier* mpLOKNotifier; ///< To emit the LOK callbacks eg. for dialog tunneling.
492 SAL_DLLPRIVATE MenuFloatingWindow * ImplGetFloatingWindow() const;
494 protected:
495 SAL_DLLPRIVATE sal_uInt16 ImplExecute( const VclPtr<vcl::Window>& pW, const tools::Rectangle& rRect, FloatWinPopupFlags nPopupModeFlags, Menu* pSFrom, bool bPreSelectFirst );
496 SAL_DLLPRIVATE void ImplFlushPendingSelect();
497 SAL_DLLPRIVATE long ImplCalcHeight( sal_uInt16 nEntries ) const;
498 SAL_DLLPRIVATE sal_uInt16 ImplCalcVisEntries( long nMaxHeight, sal_uInt16 nStartEntry, sal_uInt16* pLastVisible = nullptr ) const;
500 public:
501 PopupMenu();
502 PopupMenu( const PopupMenu& rMenu );
503 virtual ~PopupMenu() override;
505 virtual bool IsMenuBar() const override { return false; }
507 /// Close the 'pStartedFrom' menu window.
508 virtual void ClosePopup(Menu* pMenu) override;
510 void SetText( const OUString& rTitle )
512 aTitleText = rTitle;
515 sal_uInt16 Execute( vcl::Window* pWindow, const Point& rPopupPos );
516 sal_uInt16 Execute( vcl::Window* pWindow, const tools::Rectangle& rRect, PopupMenuFlags nFlags = PopupMenuFlags::NONE );
518 // for the TestTool
519 void EndExecute();
520 virtual void SelectItem(sal_uInt16 nId) override;
521 void SetSelectedEntry( sal_uInt16 nId ); // for use by native submenu only
523 static bool IsInExecute();
524 static PopupMenu* GetActivePopupMenu();
526 /// Interface to register for dialog / window tunneling.
527 void SetLOKNotifier(const vcl::ILibreOfficeKitNotifier* pNotifier)
529 mpLOKNotifier = pNotifier;
532 PopupMenu& operator=( const PopupMenu& rMenu );
535 inline PopupMenu& PopupMenu::operator=( const PopupMenu& rMenu )
537 Menu::operator=( rMenu );
538 return *this;
541 #endif // INCLUDED_VCL_MENU_HXX
543 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */