Avoid potential negative array index access to cached text.
[LibreOffice.git] / toolkit / source / awt / vclxmenu.cxx
blob6515258861b4d18644122d3da1da95970e929218
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 #include <toolkit/awt/vclxmenu.hxx>
21 #include <toolkit/helper/convert.hxx>
22 #include <toolkit/helper/vclunohelper.hxx>
24 #include <com/sun/star/uno/XComponentContext.hpp>
25 #include <cppuhelper/supportsservice.hxx>
26 #include <cppuhelper/queryinterface.hxx>
27 #include <cppuhelper/typeprovider.hxx>
28 #include <tools/debug.hxx>
29 #include <vcl/dialoghelper.hxx>
30 #include <vcl/graph.hxx>
31 #include <vcl/menu.hxx>
32 #include <vcl/keycod.hxx>
33 #include <vcl/image.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/window.hxx>
37 #include <com/sun/star/awt/KeyModifier.hpp>
39 VCLXMenu::VCLXMenu()
40 : maMenuListeners( *this )
41 , mnDefaultItem(0)
43 mpMenu = nullptr;
46 VCLXMenu::VCLXMenu( Menu* pMenu )
47 : maMenuListeners( *this )
48 , mnDefaultItem(0)
50 mpMenu = pMenu;
53 VCLXMenu::~VCLXMenu()
55 maPopupMenuRefs.clear();
56 if ( mpMenu )
58 SolarMutexGuard g;
59 mpMenu->RemoveEventListener( LINK( this, VCLXMenu, MenuEventListener ) );
60 mpMenu.disposeAndClear();
64 bool VCLXMenu::IsPopupMenu() const
66 return (mpMenu && ! mpMenu->IsMenuBar());
69 void VCLXMenu::ImplCreateMenu( bool bPopup )
71 DBG_ASSERT( !mpMenu, "CreateMenu: Menu exists!" );
73 if ( bPopup )
74 mpMenu = VclPtr<PopupMenu>::Create();
75 else
76 mpMenu = VclPtr<MenuBar>::Create();
78 mpMenu->AddEventListener( LINK( this, VCLXMenu, MenuEventListener ) );
81 void VCLXMenu::ImplAddListener()
83 assert(mpMenu);
84 mpMenu->AddEventListener( LINK( this, VCLXMenu, MenuEventListener ) );
87 IMPL_LINK( VCLXMenu, MenuEventListener, VclMenuEvent&, rMenuEvent, void )
89 DBG_ASSERT( rMenuEvent.GetMenu() && mpMenu, "Menu???" );
91 if ( rMenuEvent.GetMenu() != mpMenu ) // Also called for the root menu
92 return;
94 switch ( rMenuEvent.GetId() )
96 case VclEventId::MenuSelect:
98 if ( maMenuListeners.getLength() )
100 css::awt::MenuEvent aEvent;
101 aEvent.Source = getXWeak();
102 aEvent.MenuId = mpMenu->GetCurItemId();
103 maMenuListeners.itemSelected( aEvent );
106 break;
107 case VclEventId::ObjectDying:
109 mpMenu = nullptr;
111 break;
112 case VclEventId::MenuHighlight:
114 if ( maMenuListeners.getLength() )
116 css::awt::MenuEvent aEvent;
117 aEvent.Source = getXWeak();
118 aEvent.MenuId = mpMenu->GetCurItemId();
119 maMenuListeners.itemHighlighted( aEvent );
122 break;
123 case VclEventId::MenuActivate:
125 if ( maMenuListeners.getLength() )
127 css::awt::MenuEvent aEvent;
128 aEvent.Source = getXWeak();
129 aEvent.MenuId = mpMenu->GetCurItemId();
130 maMenuListeners.itemActivated( aEvent );
133 break;
134 case VclEventId::MenuDeactivate:
136 if ( maMenuListeners.getLength() )
138 css::awt::MenuEvent aEvent;
139 aEvent.Source = getXWeak();
140 aEvent.MenuId = mpMenu->GetCurItemId();
141 maMenuListeners.itemDeactivated( aEvent );
144 break;
146 // ignore accessibility events
147 case VclEventId::MenuEnable:
148 case VclEventId::MenuInsertItem:
149 case VclEventId::MenuRemoveItem:
150 case VclEventId::MenuSubmenuActivate:
151 case VclEventId::MenuSubmenuDeactivate:
152 case VclEventId::MenuSubmenuChanged:
153 case VclEventId::MenuDehighlight:
154 case VclEventId::MenuDisable:
155 case VclEventId::MenuItemRoleChanged:
156 case VclEventId::MenuItemTextChanged:
157 case VclEventId::MenuItemChecked:
158 case VclEventId::MenuItemUnchecked:
159 case VclEventId::MenuShow:
160 case VclEventId::MenuHide:
161 break;
163 default: OSL_FAIL( "MenuEventListener - Unknown event!" );
168 OUString SAL_CALL VCLXMenu::getImplementationName( )
170 std::unique_lock aGuard( maMutex );
171 const bool bIsPopupMenu = IsPopupMenu();
172 aGuard.unlock();
174 OUString implName( "stardiv.Toolkit." );
175 if ( bIsPopupMenu )
176 implName += "VCLXPopupMenu";
177 else
178 implName += "VCLXMenuBar";
180 return implName;
183 css::uno::Sequence< OUString > SAL_CALL VCLXMenu::getSupportedServiceNames( )
185 std::unique_lock aGuard( maMutex );
186 const bool bIsPopupMenu = IsPopupMenu();
187 aGuard.unlock();
189 if ( bIsPopupMenu )
190 return css::uno::Sequence<OUString>{
191 "com.sun.star.awt.PopupMenu",
192 "stardiv.vcl.PopupMenu"};
193 else
194 return css::uno::Sequence<OUString>{
195 "com.sun.star.awt.MenuBar",
196 "stardiv.vcl.MenuBar"};
199 sal_Bool SAL_CALL VCLXMenu::supportsService(const OUString& rServiceName )
201 return cppu::supportsService(this, rServiceName);
204 css::uno::Any VCLXMenu::queryInterface(
205 const css::uno::Type & rType )
207 std::unique_lock aGuard( maMutex );
208 const bool bIsPopupMenu = IsPopupMenu();
209 aGuard.unlock();
211 css::uno::Any aRet;
213 if ( bIsPopupMenu )
214 aRet = ::cppu::queryInterface( rType,
215 static_cast< css::awt::XMenu* >(static_cast<css::awt::XMenuBar*>(this)),
216 static_cast< css::awt::XPopupMenu* >(this),
217 static_cast< css::lang::XTypeProvider* >(this),
218 static_cast< css::lang::XServiceInfo* >(this) );
219 else
220 aRet = ::cppu::queryInterface( rType,
221 static_cast< css::awt::XMenu* >(static_cast<css::awt::XMenuBar*>(this)),
222 static_cast< css::awt::XMenuBar* >(this),
223 static_cast< css::lang::XTypeProvider* >(this),
224 static_cast< css::lang::XServiceInfo* >(this) );
226 return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType ));
230 css::uno::Sequence< css::uno::Type > VCLXMenu::getTypes()
232 std::unique_lock aGuard( maMutex );
233 const bool bIsPopupMenu = IsPopupMenu();
234 aGuard.unlock();
236 if ( bIsPopupMenu )
238 static cppu::OTypeCollection collectionPopupMenu(
239 cppu::UnoType<css::lang::XTypeProvider>::get(), cppu::UnoType<css::awt::XMenu>::get(),
240 cppu::UnoType<css::awt::XPopupMenu>::get(),
241 cppu::UnoType<css::lang::XServiceInfo>::get());
242 return collectionPopupMenu.getTypes();
244 else
246 static cppu::OTypeCollection collectionMenuBar(
247 cppu::UnoType<css::lang::XTypeProvider>::get(), cppu::UnoType<css::awt::XMenu>::get(),
248 cppu::UnoType<css::awt::XMenuBar>::get(),
249 cppu::UnoType<css::lang::XServiceInfo>::get());
250 return collectionMenuBar.getTypes();
255 css::uno::Sequence< sal_Int8 > VCLXMenu::getImplementationId()
257 return css::uno::Sequence<sal_Int8>();
260 void VCLXMenu::addMenuListener(
261 const css::uno::Reference< css::awt::XMenuListener >& rxListener )
263 std::unique_lock aGuard( maMutex );
265 maMenuListeners.addInterface( rxListener );
268 void VCLXMenu::removeMenuListener(
269 const css::uno::Reference< css::awt::XMenuListener >& rxListener )
271 std::unique_lock aGuard( maMutex );
273 maMenuListeners.removeInterface( rxListener );
276 void VCLXMenu::insertItem(
277 sal_Int16 nItemId,
278 const OUString& aText,
279 sal_Int16 nItemStyle,
280 sal_Int16 nPos )
282 SolarMutexGuard aSolarGuard;
283 std::unique_lock aGuard( maMutex );
285 if ( mpMenu )
286 mpMenu->InsertItem(nItemId, aText, static_cast<MenuItemBits>(nItemStyle), {}, nPos);
289 void VCLXMenu::removeItem(
290 sal_Int16 nPos,
291 sal_Int16 nCount )
293 SolarMutexGuard aSolarGuard;
294 std::unique_lock aGuard( maMutex );
296 if (!mpMenu)
297 return;
299 sal_Int32 nItemCount = static_cast<sal_Int32>(mpMenu->GetItemCount());
300 if ((nCount > 0) && (nPos >= 0) && (nPos < nItemCount))
302 sal_Int16 nP = sal::static_int_cast< sal_Int16 >(
303 std::min( static_cast<int>(nPos+nCount), static_cast<int>(nItemCount) ));
304 while( nP-nPos > 0 )
305 mpMenu->RemoveItem( --nP );
309 sal_Int16 VCLXMenu::getItemCount( )
311 SolarMutexGuard aSolarGuard;
312 std::unique_lock aGuard( maMutex );
314 return mpMenu ? mpMenu->GetItemCount() : 0;
317 sal_Int16 VCLXMenu::getItemId(
318 sal_Int16 nPos )
320 SolarMutexGuard aSolarGuard;
321 std::unique_lock aGuard( maMutex );
323 return mpMenu ? mpMenu->GetItemId( nPos ) : 0;
326 sal_Int16 VCLXMenu::getItemPos(
327 sal_Int16 nId )
329 SolarMutexGuard aSolarGuard;
330 std::unique_lock aGuard( maMutex );
332 return mpMenu ? mpMenu->GetItemPos( nId ) : 0;
335 void VCLXMenu::enableItem(
336 sal_Int16 nItemId,
337 sal_Bool bEnable )
339 SolarMutexGuard aSolarGuard;
340 std::unique_lock aGuard( maMutex );
342 if ( mpMenu )
343 mpMenu->EnableItem( nItemId, bEnable );
346 sal_Bool VCLXMenu::isItemEnabled(
347 sal_Int16 nItemId )
349 SolarMutexGuard aSolarGuard;
350 std::unique_lock aGuard( maMutex );
352 return mpMenu && mpMenu->IsItemEnabled( nItemId );
355 void VCLXMenu::setItemText(
356 sal_Int16 nItemId,
357 const OUString& aText )
359 SolarMutexGuard aSolarGuard;
360 std::unique_lock aGuard( maMutex );
362 if ( mpMenu )
363 mpMenu->SetItemText( nItemId, aText );
366 OUString VCLXMenu::getItemText(
367 sal_Int16 nItemId )
369 SolarMutexGuard aSolarGuard;
370 std::unique_lock aGuard( maMutex );
372 OUString aItemText;
373 if ( mpMenu )
374 aItemText = mpMenu->GetItemText( nItemId );
375 return aItemText;
378 void VCLXMenu::setPopupMenu(
379 sal_Int16 nItemId,
380 const css::uno::Reference< css::awt::XPopupMenu >& rxPopupMenu )
382 SolarMutexGuard aSolarGuard;
383 std::unique_lock aGuard( maMutex );
385 VCLXMenu* pVCLMenu = dynamic_cast<VCLXMenu*>( rxPopupMenu.get() );
386 DBG_ASSERT( pVCLMenu && pVCLMenu->GetMenu() && pVCLMenu->IsPopupMenu(), "setPopupMenu: Invalid Menu!" );
388 if ( mpMenu && pVCLMenu && pVCLMenu->GetMenu() && pVCLMenu->IsPopupMenu() )
390 maPopupMenuRefs.push_back( rxPopupMenu );
392 mpMenu->SetPopupMenu( nItemId, static_cast<PopupMenu*>( pVCLMenu->GetMenu() ) );
396 css::uno::Reference< css::awt::XPopupMenu > VCLXMenu::getPopupMenu(
397 sal_Int16 nItemId )
399 SolarMutexGuard aSolarGuard;
400 std::unique_lock aGuard( maMutex );
402 css::uno::Reference< css::awt::XPopupMenu > aRef;
403 Menu* pMenu = mpMenu ? mpMenu->GetPopupMenu( nItemId ) : nullptr;
404 if ( pMenu )
406 for ( size_t n = maPopupMenuRefs.size(); n; )
408 css::uno::Reference< css::awt::XPopupMenu >& rRef = maPopupMenuRefs[ --n ];
409 Menu* pM = static_cast<VCLXMenu*>(rRef.get())->GetMenu();
410 if ( pM == pMenu )
412 aRef = rRef;
413 break;
417 If the popup menu is not inserted via setPopupMenu then
418 maPopupMenuRefs won't have an entry for it, so create an XPopupMenu
419 for it now.
421 This means that this vcl PopupMenu "pMenu" either existed as a child
422 of the vcl Menu "mpMenu" before the VCLXMenu was created for that or
423 it was added directly via vcl.
425 if( !aRef.is() )
427 aRef = new VCLXPopupMenu( static_cast<PopupMenu*>(pMenu) );
429 In any case, the VCLXMenu has ownership of "mpMenu" and will
430 destroy it in the VCLXMenu dtor.
432 Similarly because VCLXPopupMenu takes ownership of the vcl
433 PopupMenu "pMenu", the underlying vcl popup will be destroyed
434 when VCLXPopupMenu is, so we should add it now to
435 maPopupMenuRefs to ensure its lifecycle is at least bound to
436 the VCLXMenu that owns the parent "mpMenu" similarly to
437 PopupMenus added via the more conventional setPopupMenu.
439 maPopupMenuRefs.push_back( aRef );
442 return aRef;
445 // css::awt::XPopupMenu
446 void VCLXMenu::insertSeparator(
447 sal_Int16 nPos )
449 SolarMutexGuard aSolarGuard;
450 std::unique_lock aGuard( maMutex );
452 if ( mpMenu )
453 mpMenu->InsertSeparator({}, nPos);
456 void VCLXMenu::setDefaultItem(
457 sal_Int16 nItemId )
459 std::unique_lock aGuard( maMutex );
461 mnDefaultItem = nItemId;
464 sal_Int16 VCLXMenu::getDefaultItem( )
466 std::unique_lock aGuard( maMutex );
468 return mnDefaultItem;
471 void VCLXMenu::checkItem(
472 sal_Int16 nItemId,
473 sal_Bool bCheck )
475 SolarMutexGuard aSolarGuard;
476 std::unique_lock aGuard( maMutex );
478 if ( mpMenu )
479 mpMenu->CheckItem( nItemId, bCheck );
482 sal_Bool VCLXMenu::isItemChecked(
483 sal_Int16 nItemId )
485 SolarMutexGuard aSolarGuard;
486 std::unique_lock aGuard( maMutex );
488 return mpMenu && mpMenu->IsItemChecked( nItemId );
491 sal_Int16 VCLXMenu::execute(
492 const css::uno::Reference< css::awt::XWindowPeer >& rxWindowPeer,
493 const css::awt::Rectangle& rPos,
494 sal_Int16 nFlags )
496 SolarMutexGuard aSolarGuard;
497 auto pMenu = mpMenu;
499 std::unique_lock aGuard( maMutex );
500 if ( !mpMenu || !IsPopupMenu() )
501 return 0;
503 PopupMenu* pPopupMenu = static_cast<PopupMenu*>(pMenu.get());
504 MenuFlags nMenuFlags = pPopupMenu->GetMenuFlags();
505 // #102790# context menus shall never show disabled entries
506 nMenuFlags |= MenuFlags::HideDisabledEntries;
507 pPopupMenu->SetMenuFlags(nMenuFlags);
508 // cannot call this with mutex locked because it will call back into us
509 return pPopupMenu->Execute(
510 VCLUnoHelper::GetWindow( rxWindowPeer ),
511 VCLRectangle( rPos ),
512 static_cast<PopupMenuFlags>(nFlags) | PopupMenuFlags::NoMouseUpClose );
516 void SAL_CALL VCLXMenu::setCommand(
517 sal_Int16 nItemId,
518 const OUString& aCommand )
520 SolarMutexGuard aSolarGuard;
521 std::unique_lock aGuard( maMutex );
523 if ( mpMenu )
524 mpMenu->SetItemCommand( nItemId, aCommand );
527 OUString SAL_CALL VCLXMenu::getCommand(
528 sal_Int16 nItemId )
530 SolarMutexGuard aSolarGuard;
531 std::unique_lock aGuard( maMutex );
533 OUString aItemCommand;
534 if ( mpMenu )
535 aItemCommand = mpMenu->GetItemCommand( nItemId );
536 return aItemCommand;
539 void SAL_CALL VCLXMenu::setHelpCommand(
540 sal_Int16 nItemId,
541 const OUString& aHelp )
543 SolarMutexGuard aSolarGuard;
544 std::unique_lock aGuard( maMutex );
546 if ( mpMenu )
547 mpMenu->SetHelpCommand( nItemId, aHelp );
550 OUString SAL_CALL VCLXMenu::getHelpCommand(
551 sal_Int16 nItemId )
553 SolarMutexGuard aSolarGuard;
554 std::unique_lock aGuard( maMutex );
556 OUString aHelpCommand;
557 if ( mpMenu )
558 aHelpCommand = mpMenu->GetHelpCommand( nItemId );
559 return aHelpCommand;
563 namespace
565 Image lcl_XGraphic2VCLImage(
566 const css::uno::Reference< css::graphic::XGraphic >& xGraphic,
567 bool bResize )
569 Image aImage;
570 if ( !xGraphic.is() )
571 return aImage;
573 aImage = Image( xGraphic );
574 const ::Size aCurSize = aImage.GetSizePixel();
575 const sal_Int32 nCurWidth = aCurSize.Width();
576 const sal_Int32 nCurHeight = aCurSize.Height();
577 constexpr sal_Int32 nIdeal( 16 );
579 if ( nCurWidth > 0 && nCurHeight > 0 )
581 if ( bResize && ( nCurWidth > nIdeal || nCurHeight > nIdeal ) )
583 sal_Int32 nIdealWidth = std::min(nCurWidth, nIdeal);
584 sal_Int32 nIdealHeight = std::min(nCurHeight, nIdeal);
586 ::Size aNewSize( nIdealWidth, nIdealHeight );
588 bool bModified( false );
589 BitmapEx aBitmapEx = aImage.GetBitmapEx();
590 bModified = aBitmapEx.Scale( aNewSize, BmpScaleFlag::BestQuality );
592 if ( bModified )
593 aImage = Image( aBitmapEx );
596 return aImage;
599 /** Copied from include/svtools/acceleratorexecute.hxx */
600 css::awt::KeyEvent lcl_VCLKey2AWTKey(
601 const vcl::KeyCode& aVCLKey)
603 css::awt::KeyEvent aAWTKey;
604 aAWTKey.Modifiers = 0;
605 aAWTKey.KeyCode = static_cast<sal_Int16>(aVCLKey.GetCode());
607 if (aVCLKey.IsShift())
608 aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT;
609 if (aVCLKey.IsMod1())
610 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1;
611 if (aVCLKey.IsMod2())
612 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2;
613 if (aVCLKey.IsMod3())
614 aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3;
616 return aAWTKey;
619 vcl::KeyCode lcl_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey)
621 bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT );
622 bool bMod1 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 );
623 bool bMod2 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 );
624 bool bMod3 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 );
625 sal_uInt16 nKey = static_cast<sal_uInt16>(aAWTKey.KeyCode);
627 return vcl::KeyCode(nKey, bShift, bMod1, bMod2, bMod3);
633 sal_Bool SAL_CALL VCLXMenu::isPopupMenu( )
635 SolarMutexGuard aSolarGuard;
636 std::unique_lock aGuard( maMutex );
637 return IsPopupMenu();
640 void SAL_CALL VCLXMenu::clear( )
642 SolarMutexGuard aSolarGuard;
643 std::unique_lock aGuard( maMutex );
644 if ( mpMenu )
645 mpMenu->Clear();
649 css::awt::MenuItemType SAL_CALL VCLXMenu::getItemType(
650 ::sal_Int16 nItemPos )
652 SolarMutexGuard aSolarGuard;
653 std::unique_lock aGuard( maMutex );
655 css::awt::MenuItemType aMenuItemType =
656 css::awt::MenuItemType_DONTKNOW;
657 if ( mpMenu )
659 aMenuItemType = static_cast<css::awt::MenuItemType>(mpMenu->GetItemType( nItemPos ));
662 return aMenuItemType;
665 void SAL_CALL VCLXMenu::hideDisabledEntries(
666 sal_Bool bHide )
668 SolarMutexGuard aSolarGuard;
669 std::unique_lock aGuard( maMutex );
670 if ( mpMenu )
672 if ( bHide )
673 mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MenuFlags::HideDisabledEntries );
674 else
675 mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MenuFlags::HideDisabledEntries );
680 sal_Bool SAL_CALL VCLXMenu::isInExecute( )
682 SolarMutexGuard aSolarGuard;
683 std::unique_lock aGuard( maMutex );
685 if ( mpMenu && IsPopupMenu() )
686 return vcl::IsInPopupMenuExecute();
687 else
688 return false;
692 void SAL_CALL VCLXMenu::endExecute()
694 SolarMutexGuard aSolarGuard;
695 std::unique_lock aGuard( maMutex );
697 if ( mpMenu && IsPopupMenu() )
698 static_cast<PopupMenu*>( mpMenu.get() )->EndExecute();
702 void SAL_CALL VCLXMenu::enableAutoMnemonics(
703 sal_Bool bEnable )
705 SolarMutexGuard aSolarGuard;
706 std::unique_lock aGuard( maMutex );
707 if ( mpMenu )
709 if ( !bEnable )
710 mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MenuFlags::NoAutoMnemonics );
711 else
712 mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MenuFlags::NoAutoMnemonics );
717 void SAL_CALL VCLXMenu::setAcceleratorKeyEvent(
718 ::sal_Int16 nItemId,
719 const css::awt::KeyEvent& aKeyEvent )
721 SolarMutexGuard aSolarGuard;
722 std::unique_lock aGuard( maMutex );
724 if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
726 vcl::KeyCode aVCLKeyCode = lcl_AWTKey2VCLKey( aKeyEvent );
727 mpMenu->SetAccelKey( nItemId, aVCLKeyCode );
732 css::awt::KeyEvent SAL_CALL VCLXMenu::getAcceleratorKeyEvent(
733 ::sal_Int16 nItemId )
735 SolarMutexGuard aSolarGuard;
736 std::unique_lock aGuard( maMutex );
738 css::awt::KeyEvent aKeyEvent;
739 if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
741 vcl::KeyCode nKeyCode = mpMenu->GetAccelKey( nItemId );
742 aKeyEvent = lcl_VCLKey2AWTKey( nKeyCode );
745 return aKeyEvent;
749 void SAL_CALL VCLXMenu::setHelpText(
750 ::sal_Int16 nItemId,
751 const OUString& sHelpText )
753 SolarMutexGuard aSolarGuard;
754 std::unique_lock aGuard( maMutex );
756 if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
758 mpMenu->SetHelpText( nItemId, sHelpText );
763 OUString SAL_CALL VCLXMenu::getHelpText(
764 ::sal_Int16 nItemId )
766 SolarMutexGuard aSolarGuard;
767 std::unique_lock aGuard( maMutex );
769 OUString sHelpText;
770 if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
772 sHelpText = mpMenu->GetHelpText( nItemId );
775 return sHelpText;
779 void SAL_CALL VCLXMenu::setTipHelpText(
780 ::sal_Int16 nItemId,
781 const OUString& sTipHelpText )
783 SolarMutexGuard aSolarGuard;
784 std::unique_lock aGuard( maMutex );
786 if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
788 mpMenu->SetTipHelpText( nItemId, sTipHelpText );
793 OUString SAL_CALL VCLXMenu::getTipHelpText(
794 ::sal_Int16 nItemId )
796 SolarMutexGuard aSolarGuard;
797 std::unique_lock aGuard( maMutex );
799 OUString sTipHelpText;
800 if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
802 sTipHelpText = mpMenu->GetTipHelpText( nItemId );
804 return sTipHelpText;
808 void SAL_CALL VCLXMenu::setItemImage(
809 ::sal_Int16 nItemId,
810 const css::uno::Reference< css::graphic::XGraphic >& xGraphic,
811 sal_Bool bScale )
813 SolarMutexGuard aSolarGuard;
814 std::unique_lock aGuard( maMutex );
816 if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
818 Image aImage = lcl_XGraphic2VCLImage( xGraphic, bScale );
819 mpMenu->SetItemImage( nItemId, aImage );
824 css::uno::Reference< css::graphic::XGraphic > SAL_CALL
825 VCLXMenu::getItemImage(
826 ::sal_Int16 nItemId )
828 SolarMutexGuard aSolarGuard;
829 std::unique_lock aGuard( maMutex );
831 css::uno::Reference< css::graphic::XGraphic > rxGraphic;
833 if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) )
835 Image aImage = mpMenu->GetItemImage( nItemId );
836 if ( !!aImage )
837 rxGraphic = Graphic(aImage.GetBitmapEx()).GetXGraphic();
839 return rxGraphic;
842 void VCLXMenu::setUserValue(sal_uInt16 nItemId, void* nUserValue, MenuUserDataReleaseFunction aFunc)
844 SolarMutexGuard aSolarGuard;
845 std::unique_lock aGuard(maMutex);
847 mpMenu->SetUserValue(nItemId, nUserValue, aFunc);
850 void* VCLXMenu::getUserValue(sal_uInt16 nItemId)
852 SolarMutexGuard aSolarGuard;
853 std::unique_lock aGuard(maMutex);
855 return mpMenu->GetUserValue(nItemId);
858 VCLXMenuBar::VCLXMenuBar()
860 ImplCreateMenu( false );
863 VCLXMenuBar::VCLXMenuBar( MenuBar* pMenuBar ) : VCLXMenu( static_cast<Menu *>(pMenuBar) )
867 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
868 stardiv_Toolkit_VCLXMenuBar_get_implementation(
869 css::uno::XComponentContext *,
870 css::uno::Sequence<css::uno::Any> const &)
872 return cppu::acquire(new VCLXMenuBar());
875 VCLXPopupMenu::VCLXPopupMenu()
877 ImplCreateMenu( true );
880 VCLXPopupMenu::VCLXPopupMenu( PopupMenu* pPopMenu ) : VCLXMenu( static_cast<Menu *>(pPopMenu) )
882 ImplAddListener();
885 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
886 stardiv_Toolkit_VCLXPopupMenu_get_implementation(
887 css::uno::XComponentContext *,
888 css::uno::Sequence<css::uno::Any> const &)
890 return cppu::acquire(new VCLXPopupMenu());
893 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */