1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
23 #include <tools/solar.h>
24 #include <vcl/dllapi.h>
25 #include <tools/rc.hxx>
26 #include <tools/resid.hxx>
27 #include <rsc/rsc-vcl-shared-types.hxx>
28 #include <vcl/bitmapex.hxx>
29 #include <tools/color.hxx>
30 #include <vcl/vclevent.hxx>
31 #include <com/sun/star/uno/Reference.hxx>
44 class MenuFloatingWindow
;
47 struct SystemMenuData
;
52 namespace accessibility
{
56 namespace vcl
{ struct MenuLayoutData
; }
62 #define MENU_APPEND ((sal_uInt16)0xFFFF)
63 #define MENU_ITEM_NOTFOUND ((sal_uInt16)0xFFFF)
65 #define POPUPMENU_EXECUTE_DOWN ((sal_uInt16)0x0001)
66 #define POPUPMENU_EXECUTE_UP ((sal_uInt16)0x0002)
67 #define POPUPMENU_EXECUTE_LEFT ((sal_uInt16)0x0004)
68 #define POPUPMENU_EXECUTE_RIGHT ((sal_uInt16)0x0008)
70 #define POPUPMENU_NOMOUSEUPCLOSE ((sal_uInt16)0x0010)
72 #define MENU_FLAG_NOAUTOMNEMONICS 0x0001
73 #define MENU_FLAG_HIDEDISABLEDENTRIES 0x0002
75 // overrides default hiding of disabled entries in popup menus
76 #define MENU_FLAG_ALWAYSSHOWDISABLEDENTRIES 0x0004
78 struct ImplMenuDelData
80 ImplMenuDelData
* mpNext
;
83 explicit ImplMenuDelData( const Menu
* );
86 bool isDeleted() const { return mpMenu
== 0; }
100 class VCL_DLLPUBLIC Menu
: public Resource
102 friend class MenuBar
;
103 friend class MenuBarWindow
;
104 friend class MenuButton
;
105 friend class MenuFloatingWindow
;
106 friend class PopupMenu
;
107 friend class SystemWindow
;
108 friend struct ImplMenuDelData
;
110 ImplMenuDelData
* mpFirstDel
;
111 MenuItemList
* pItemList
; // Liste mit den MenuItems
116 Link aActivateHdl
; // Active-Handler
117 Link aDeactivateHdl
; // Deactivate-Handler
118 Link aHighlightHdl
; // Highlight-Handler
119 Link aSelectHdl
; // Highlight-Handler
121 VclEventListeners maEventListeners
;
122 VclEventListeners maChildEventListeners
;
124 OUString aTitleText
; // PopupMenu text
127 sal_uInt16 mnHighlightedItemPos
; // for native menus: keeps track of the highlighted item
128 sal_uInt16 nMenuFlags
;
129 sal_uInt16 nDefaultItem
; // Id of default item
130 sal_uInt16 nSelectedId
;
133 sal_uInt16 nImgOrChkPos
;
136 sal_Bool bIsMenuBar
: 1, // Is this a menubar?
137 bCanceled
: 1, // Terminated during a callback
138 bInCallback
: 1, // In Activate/Deactivate
139 bKilled
: 1; // Killed...
141 ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
> mxAccessible
;
142 mutable vcl::MenuLayoutData
* mpLayoutData
;
146 SAL_DLLPRIVATE
void ImplInit();
147 SAL_DLLPRIVATE
void ImplLoadRes( const ResId
& rResId
);
148 SAL_DLLPRIVATE Menu
* ImplGetStartMenu();
149 SAL_DLLPRIVATE Menu
* ImplFindSelectMenu();
150 SAL_DLLPRIVATE Menu
* ImplFindMenu( sal_uInt16 nId
);
151 SAL_DLLPRIVATE Size
ImplCalcSize( Window
* pWin
);
152 SAL_DLLPRIVATE sal_Bool
ImplIsVisible( sal_uInt16 nPos
) const;
153 SAL_DLLPRIVATE sal_Bool
ImplIsSelectable( sal_uInt16 nPos
) const;
154 SAL_DLLPRIVATE sal_uInt16
ImplGetVisibleItemCount() const;
155 SAL_DLLPRIVATE sal_uInt16
ImplGetFirstVisible() const;
156 SAL_DLLPRIVATE sal_uInt16
ImplGetPrevVisible( sal_uInt16 nPos
) const;
157 SAL_DLLPRIVATE sal_uInt16
ImplGetNextVisible( sal_uInt16 nPos
) const;
158 SAL_DLLPRIVATE
void ImplPaint( Window
* pWin
, sal_uInt16 nBorder
, long nOffY
= 0, MenuItemData
* pThisDataOnly
= 0, sal_Bool bHighlighted
= sal_False
, bool bLayout
= false, bool bRollover
= false ) const;
159 SAL_DLLPRIVATE
void ImplSelect();
160 SAL_DLLPRIVATE
void ImplCallHighlight( sal_uInt16 nHighlightItem
);
161 SAL_DLLPRIVATE
void ImplCallEventListeners( sal_uLong nEvent
, sal_uInt16 nPos
);
162 DECL_DLLPRIVATE_LINK( ImplCallSelect
, void* );
164 SAL_DLLPRIVATE
void ImplFillLayoutData() const;
165 SAL_DLLPRIVATE SalMenu
* ImplGetSalMenu() { return mpSalMenu
; }
166 SAL_DLLPRIVATE
void ImplSetSalMenu( SalMenu
*pMenu
);
167 SAL_DLLPRIVATE
const XubString
& ImplGetHelpText( sal_uInt16 nItemId
) const;
169 // returns native check and option menu symbol height in rCheckHeight and rRadioHeight
170 // return value is maximum width and height of checkboxes and radiobuttons
171 SAL_DLLPRIVATE Size
ImplGetNativeCheckAndRadioSize( Window
*, long& rCheckHeight
, long& rRadioHeight
) const;
173 // returns native submenu arrow size and spacing from right border
174 // return value is whether it's supported natively
175 SAL_DLLPRIVATE sal_Bool
ImplGetNativeSubmenuArrowSize( Window
* pWin
, Size
& rArrowSize
, long& rArrowSpacing
) const;
177 SAL_DLLPRIVATE
void ImplAddDel( ImplMenuDelData
&rDel
);
178 SAL_DLLPRIVATE
void ImplRemoveDel( ImplMenuDelData
&rDel
);
180 SAL_DLLPRIVATE
void ImplKillLayoutData() const;
181 SAL_DLLPRIVATE Menu
* ImplGetStartedFrom() const { return pStartedFrom
; }
184 explicit Menu( sal_Bool bMenuBar
);
185 SAL_DLLPRIVATE Window
* ImplGetWindow() const { return pWindow
; }
186 void ImplSelectWithStart( Menu
* pStartMenu
= NULL
);
191 virtual void Activate();
192 virtual void Deactivate();
193 virtual void Highlight();
194 virtual void Select();
195 virtual void RequestHelp( const HelpEvent
& rHEvt
);
197 void InsertItem( sal_uInt16 nItemId
, const XubString
& rStr
,
198 MenuItemBits nItemBits
= 0,
199 const OString
&rIdent
= OString(),
200 sal_uInt16 nPos
= MENU_APPEND
);
201 void InsertItem( sal_uInt16 nItemId
, const Image
& rImage
,
202 MenuItemBits nItemBits
= 0,
203 const OString
&rIdent
= OString(),
204 sal_uInt16 nPos
= MENU_APPEND
);
205 void InsertItem( sal_uInt16 nItemId
,
206 const XubString
& rString
, const Image
& rImage
,
207 MenuItemBits nItemBits
= 0,
208 const OString
&rIdent
= OString(),
209 sal_uInt16 nPos
= MENU_APPEND
);
210 void InsertItem( const ResId
& rResId
, sal_uInt16 nPos
= MENU_APPEND
);
211 void InsertSeparator( const OString
&rIdent
= OString(),
212 sal_uInt16 nPos
= MENU_APPEND
);
213 void RemoveItem( sal_uInt16 nPos
);
214 void CopyItem( const Menu
& rMenu
, sal_uInt16 nPos
,
215 sal_uInt16 nNewPos
= MENU_APPEND
);
218 void CreateAutoMnemonics();
220 void SetMenuFlags( sal_uInt16 nFlags
) { nMenuFlags
= nFlags
; }
221 sal_uInt16
GetMenuFlags() const { return nMenuFlags
; }
223 sal_uInt16
GetItemCount() const;
224 sal_uInt16
GetItemId(sal_uInt16 nPos
) const;
225 sal_uInt16
GetItemId(const OString
&rIdent
) const;
226 sal_uInt16
GetItemPos( sal_uInt16 nItemId
) const;
227 OString
GetItemIdent(sal_uInt16 nItemId
) const;
228 MenuItemType
GetItemType( sal_uInt16 nPos
) const;
229 sal_uInt16
GetCurItemId() const;
230 OString
GetCurItemIdent() const;
232 void SetDefaultItem( sal_uInt16 nItemId
) { nDefaultItem
= nItemId
; }
233 sal_uInt16
GetDefaultItem() const { return nDefaultItem
; }
235 void SetItemBits( sal_uInt16 nItemId
, MenuItemBits nBits
);
236 MenuItemBits
GetItemBits( sal_uInt16 nItemId
) const;
238 void SetUserValue( sal_uInt16 nItemId
, sal_uLong nValue
);
239 sal_uLong
GetUserValue( sal_uInt16 nItemId
) const;
241 void SetPopupMenu( sal_uInt16 nItemId
, PopupMenu
* pMenu
);
242 PopupMenu
* GetPopupMenu( sal_uInt16 nItemId
) const;
244 void SetAccelKey( sal_uInt16 nItemId
, const KeyCode
& rKeyCode
);
245 KeyCode
GetAccelKey( sal_uInt16 nItemId
) const;
247 void CheckItem( sal_uInt16 nItemId
, sal_Bool bCheck
= sal_True
);
248 sal_Bool
IsItemChecked( sal_uInt16 nItemId
) const;
250 void SelectItem( sal_uInt16 nItemId
);
251 void DeSelect() { SelectItem( 0xFFFF ); } // MENUITEMPOS_INVALID
253 void EnableItem( sal_uInt16 nItemId
, sal_Bool bEnable
= sal_True
);
254 void EnableItem(const OString
&rIdent
, bool bEnable
= true)
256 EnableItem(GetItemId(rIdent
), bEnable
);
258 sal_Bool
IsItemEnabled( sal_uInt16 nItemId
) const;
260 void ShowItem( sal_uInt16 nItemId
, sal_Bool bVisible
= sal_True
);
261 void HideItem( sal_uInt16 nItemId
) { ShowItem( nItemId
, sal_False
); }
263 sal_Bool
IsItemPosVisible( sal_uInt16 nItemPos
) const;
264 sal_Bool
IsMenuVisible() const;
265 sal_Bool
IsMenuBar() const { return bIsMenuBar
; }
267 void RemoveDisabledEntries( sal_Bool bCheckPopups
= sal_True
, sal_Bool bRemoveEmptyPopups
= sal_False
);
268 sal_Bool
HasValidEntries( sal_Bool bCheckPopups
= sal_True
);
270 void SetItemText( sal_uInt16 nItemId
, const XubString
& rStr
);
271 XubString
GetItemText( sal_uInt16 nItemId
) const;
273 void SetItemImage( sal_uInt16 nItemId
, const Image
& rImage
);
274 Image
GetItemImage( sal_uInt16 nItemId
) const;
275 void SetItemImageAngle( sal_uInt16 nItemId
, long nAngle10
);
276 long GetItemImageAngle( sal_uInt16 nItemId
) const;
277 void SetItemImageMirrorMode( sal_uInt16 nItemId
, sal_Bool bMirror
);
278 sal_Bool
GetItemImageMirrorMode( sal_uInt16
) const;
280 void SetItemCommand( sal_uInt16 nItemId
, const XubString
& rCommand
);
281 const XubString
& GetItemCommand( sal_uInt16 nItemId
) const;
283 void SetHelpText( sal_uInt16 nItemId
, const XubString
& rString
);
284 const XubString
& GetHelpText( sal_uInt16 nItemId
) const;
286 void SetTipHelpText( sal_uInt16 nItemId
, const XubString
& rString
);
287 const XubString
& GetTipHelpText( sal_uInt16 nItemId
) const;
289 void SetHelpCommand( sal_uInt16 nItemId
, const XubString
& rString
);
290 const XubString
& GetHelpCommand( sal_uInt16 nItemId
) const;
292 void SetHelpId( sal_uInt16 nItemId
, const OString
& rHelpId
);
293 OString
GetHelpId( sal_uInt16 nItemId
) const;
295 void SetActivateHdl( const Link
& rLink
) { aActivateHdl
= rLink
; }
296 const Link
& GetActivateHdl() const { return aActivateHdl
; }
298 void SetDeactivateHdl( const Link
& rLink
) { aDeactivateHdl
= rLink
; }
299 const Link
& GetDeactivateHdl() const { return aDeactivateHdl
; }
301 void SetHighlightHdl( const Link
& rLink
) { aHighlightHdl
= rLink
; }
302 const Link
& GetHighlightHdl() const { return aHighlightHdl
; }
304 void SetSelectHdl( const Link
& rLink
) { aSelectHdl
= rLink
; }
305 const Link
& GetSelectHdl() const { return aSelectHdl
; }
307 void SetLogo( const MenuLogo
& rLogo
);
309 sal_Bool
HasLogo() const { return pLogo
? sal_True
: sal_False
; }
310 MenuLogo
GetLogo() const;
312 void AddEventListener( const Link
& rEventListener
);
313 void RemoveEventListener( const Link
& rEventListener
);
314 void AddChildEventListener( const Link
& rEventListener
);
315 void RemoveChildEventListener( const Link
& rEventListener
);
317 Menu
& operator =( const Menu
& rMenu
);
319 // Fuer Menu-'Funktionen'
320 MenuItemList
* GetItemList() const { return pItemList
; }
322 // returns the system's menu handle if native menus are supported
323 // pData must point to a SystemMenuData structure
324 sal_Bool
GetSystemMenuData( SystemMenuData
* pData
) const;
326 // accessibility helpers
328 // returns the bounding box for the character at index nIndex
329 // where nIndex is relative to the starting index of the item
330 // with id nItemId (in coordinates of the displaying window)
331 Rectangle
GetCharacterBounds( sal_uInt16 nItemId
, long nIndex
) const;
332 // -1 is returned if no character is at that point
333 // if an index is found the corresponding item id is filled in (else 0)
334 long GetIndexForPoint( const Point
& rPoint
, sal_uInt16
& rItemID
) const;
335 // returns the bounding rectangle for an item at pos nItemPos
336 Rectangle
GetBoundingRectangle( sal_uInt16 nItemPos
) const;
338 ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
> GetAccessible();
339 void SetAccessible( const ::com::sun::star::uno::Reference
< ::com::sun::star::accessibility::XAccessible
>& rxAccessible
);
341 // gets the activation key of the specified item
342 KeyEvent
GetActivationKey( sal_uInt16 nItemId
) const;
344 Window
* GetWindow() const { return pWindow
; }
346 void SetAccessibleName( sal_uInt16 nItemId
, const XubString
& rStr
);
347 XubString
GetAccessibleName( sal_uInt16 nItemId
) const;
349 // returns whether the item a position nItemPos is highlighted or not.
350 bool IsHighlighted( sal_uInt16 nItemPos
) const;
352 void HighlightItem( sal_uInt16 nItemPos
);
353 void DeHighlight() { HighlightItem( 0xFFFF ); } // MENUITEMPOS_INVALID
360 class VCL_DLLPUBLIC MenuBar
: public Menu
365 sal_Bool mbCloserVisible
;
366 sal_Bool mbFloatBtnVisible
;
367 sal_Bool mbHideBtnVisible
;
368 sal_Bool mbDisplayable
;
370 friend class Application
;
372 friend class MenuBarWindow
;
373 friend class MenuFloatingWindow
;
374 friend class SystemWindow
;
376 SAL_DLLPRIVATE
static Window
* ImplCreate( Window
* pParent
, Window
* pWindow
, MenuBar
* pMenu
);
377 SAL_DLLPRIVATE
static void ImplDestroy( MenuBar
* pMenu
, sal_Bool bDelete
);
378 SAL_DLLPRIVATE sal_Bool
ImplHandleKeyEvent( const KeyEvent
& rKEvent
, sal_Bool bFromMenu
= sal_True
);
382 MenuBar( const MenuBar
& rMenu
);
385 MenuBar
& operator =( const MenuBar
& rMenu
);
387 void ShowCloser( sal_Bool bShow
= sal_True
);
388 sal_Bool
HasCloser() const { return mbCloserVisible
; }
389 sal_Bool
HasFloatButton() const { return mbFloatBtnVisible
; }
390 sal_Bool
HasHideButton() const { return mbHideBtnVisible
; }
391 void ShowButtons( sal_Bool bClose
, sal_Bool bFloat
, sal_Bool bHide
);
393 void SelectEntry( sal_uInt16 nId
);
394 sal_Bool
HandleMenuActivateEvent( Menu
*pMenu
) const;
395 sal_Bool
HandleMenuDeActivateEvent( Menu
*pMenu
) const;
396 sal_Bool
HandleMenuHighlightEvent( Menu
*pMenu
, sal_uInt16 nEventId
) const;
397 sal_Bool
HandleMenuCommandEvent( Menu
*pMenu
, sal_uInt16 nEventId
) const;
398 sal_Bool
HandleMenuButtonEvent( Menu
*pMenu
, sal_uInt16 nEventId
) const;
400 void SetCloserHdl( const Link
& rLink
) { maCloserHdl
= rLink
; }
401 const Link
& GetCloserHdl() const { return maCloserHdl
; }
402 void SetFloatButtonClickHdl( const Link
& rLink
) { maFloatHdl
= rLink
; }
403 const Link
& GetFloatButtonClickHdl() const { return maFloatHdl
; }
404 void SetHideButtonClickHdl( const Link
& rLink
) { maHideHdl
= rLink
; }
405 const Link
& GetHideButtonClickHdl() const { return maHideHdl
; }
407 // - by default a menubar is displayable
408 // - if a menubar is not displayable, its MenuBarWindow will never be shown
409 // and it will be hidden if it was visible before
410 // - note: if a menubar is diplayable, this does not necessarily mean that it is currently visible
411 void SetDisplayable( sal_Bool bDisplayable
);
412 sal_Bool
IsDisplayable() const { return mbDisplayable
; }
414 struct MenuBarButtonCallbackArg
416 sal_uInt16 nId
; // Id of the button
417 bool bHighlight
; // highlight on/off
418 MenuBar
* pMenuBar
; // menubar the button belongs to
420 // add an arbitrary button to the menubar (will appear next to closer)
421 // passed link will be call with a MenuBarButtonCallbackArg on press
422 // passed string will be set as tooltip
423 sal_uInt16
AddMenuBarButton( const Image
&, const Link
&, const String
&, sal_uInt16 nPos
= 0 );
424 // set the highlight link for additional button with ID nId
425 // highlight link will be called with a MenuBarButtonHighlightArg
426 // the bHighlight member of that struct shall contain the new state
427 void SetMenuBarButtonHighlightHdl( sal_uInt16 nId
, const Link
& );
428 // returns the rectangle occupied by the additional button named nId
429 // coordinates are relative to the systemwindiow the menubar is attached to
430 // if the menubar is unattached an empty rectangle is returned
431 Rectangle
GetMenuBarButtonRectPixel( sal_uInt16 nId
);
432 void RemoveMenuBarButton( sal_uInt16 nId
);
435 inline MenuBar
& MenuBar::operator =( const MenuBar
& rMenu
)
437 Menu::operator =( rMenu
);
446 class VCL_DLLPUBLIC PopupMenu
: public Menu
449 friend class MenuFloatingWindow
;
450 friend class MenuBarWindow
;
451 friend struct MenuItemData
;
454 Menu
** pRefAutoSubMenu
; // keeps track if a pointer to this Menu is stored in the MenuItemData
456 SAL_DLLPRIVATE MenuFloatingWindow
* ImplGetFloatingWindow() const { return (MenuFloatingWindow
*)Menu::ImplGetWindow(); }
459 SAL_DLLPRIVATE sal_uInt16
ImplExecute( Window
* pWindow
, const Rectangle
& rRect
, sal_uLong nPopupFlags
, Menu
* pStaredFrom
, sal_Bool bPreSelectFirst
);
460 SAL_DLLPRIVATE
long ImplCalcHeight( sal_uInt16 nEntries
) const;
461 SAL_DLLPRIVATE sal_uInt16
ImplCalcVisEntries( long nMaxHeight
, sal_uInt16 nStartEntry
= 0, sal_uInt16
* pLastVisible
= NULL
) const;
465 PopupMenu( const PopupMenu
& rMenu
);
466 explicit PopupMenu( const ResId
& );
467 virtual ~PopupMenu();
469 void SetText( const OUString
& rTitle
) { aTitleText
= rTitle
; }
470 const OUString
& GetText() const { return aTitleText
; }
472 sal_uInt16
Execute( Window
* pWindow
, const Point
& rPopupPos
);
473 sal_uInt16
Execute( Window
* pWindow
, const Rectangle
& rRect
, sal_uInt16 nFlags
= 0 );
476 void EndExecute( sal_uInt16 nSelect
= 0 );
477 void SelectEntry( sal_uInt16 nId
);
478 void SetSelectedEntry( sal_uInt16 nId
); // for use by native submenu only
480 static sal_Bool
IsInExecute();
481 static PopupMenu
* GetActivePopupMenu();
483 PopupMenu
& operator =( const PopupMenu
& rMenu
);
486 inline PopupMenu
& PopupMenu::operator =( const PopupMenu
& rMenu
)
488 Menu::operator =( rMenu
);
492 #endif // _SV_MENU_HXX
494 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */