/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include VCLXMenu::VCLXMenu() : maMenuListeners( *this ) , mnDefaultItem(0) { mpMenu = nullptr; } VCLXMenu::VCLXMenu( Menu* pMenu ) : maMenuListeners( *this ) , mnDefaultItem(0) { mpMenu = pMenu; } VCLXMenu::~VCLXMenu() { maPopupMenuRefs.clear(); if ( mpMenu ) { SolarMutexGuard g; mpMenu->RemoveEventListener( LINK( this, VCLXMenu, MenuEventListener ) ); mpMenu.disposeAndClear(); } } bool VCLXMenu::IsPopupMenu() const { return (mpMenu && ! mpMenu->IsMenuBar()); } void VCLXMenu::ImplCreateMenu( bool bPopup ) { DBG_ASSERT( !mpMenu, "CreateMenu: Menu exists!" ); if ( bPopup ) mpMenu = VclPtr::Create(); else mpMenu = VclPtr::Create(); mpMenu->AddEventListener( LINK( this, VCLXMenu, MenuEventListener ) ); } void VCLXMenu::ImplAddListener() { assert(mpMenu); mpMenu->AddEventListener( LINK( this, VCLXMenu, MenuEventListener ) ); } IMPL_LINK( VCLXMenu, MenuEventListener, VclMenuEvent&, rMenuEvent, void ) { DBG_ASSERT( rMenuEvent.GetMenu() && mpMenu, "Menu???" ); if ( rMenuEvent.GetMenu() != mpMenu ) // Also called for the root menu return; switch ( rMenuEvent.GetId() ) { case VclEventId::MenuSelect: { if ( maMenuListeners.getLength() ) { css::awt::MenuEvent aEvent; aEvent.Source = getXWeak(); aEvent.MenuId = mpMenu->GetCurItemId(); maMenuListeners.itemSelected( aEvent ); } } break; case VclEventId::ObjectDying: { mpMenu = nullptr; } break; case VclEventId::MenuHighlight: { if ( maMenuListeners.getLength() ) { css::awt::MenuEvent aEvent; aEvent.Source = getXWeak(); aEvent.MenuId = mpMenu->GetCurItemId(); maMenuListeners.itemHighlighted( aEvent ); } } break; case VclEventId::MenuActivate: { if ( maMenuListeners.getLength() ) { css::awt::MenuEvent aEvent; aEvent.Source = getXWeak(); aEvent.MenuId = mpMenu->GetCurItemId(); maMenuListeners.itemActivated( aEvent ); } } break; case VclEventId::MenuDeactivate: { if ( maMenuListeners.getLength() ) { css::awt::MenuEvent aEvent; aEvent.Source = getXWeak(); aEvent.MenuId = mpMenu->GetCurItemId(); maMenuListeners.itemDeactivated( aEvent ); } } break; // ignore accessibility events case VclEventId::MenuEnable: case VclEventId::MenuInsertItem: case VclEventId::MenuRemoveItem: case VclEventId::MenuSubmenuActivate: case VclEventId::MenuSubmenuDeactivate: case VclEventId::MenuSubmenuChanged: case VclEventId::MenuDehighlight: case VclEventId::MenuDisable: case VclEventId::MenuItemRoleChanged: case VclEventId::MenuItemTextChanged: case VclEventId::MenuItemChecked: case VclEventId::MenuItemUnchecked: case VclEventId::MenuShow: case VclEventId::MenuHide: break; default: OSL_FAIL( "MenuEventListener - Unknown event!" ); } } OUString SAL_CALL VCLXMenu::getImplementationName( ) { std::unique_lock aGuard( maMutex ); const bool bIsPopupMenu = IsPopupMenu(); aGuard.unlock(); OUString implName( "stardiv.Toolkit." ); if ( bIsPopupMenu ) implName += "VCLXPopupMenu"; else implName += "VCLXMenuBar"; return implName; } css::uno::Sequence< OUString > SAL_CALL VCLXMenu::getSupportedServiceNames( ) { std::unique_lock aGuard( maMutex ); const bool bIsPopupMenu = IsPopupMenu(); aGuard.unlock(); if ( bIsPopupMenu ) return css::uno::Sequence{ "com.sun.star.awt.PopupMenu", "stardiv.vcl.PopupMenu"}; else return css::uno::Sequence{ "com.sun.star.awt.MenuBar", "stardiv.vcl.MenuBar"}; } sal_Bool SAL_CALL VCLXMenu::supportsService(const OUString& rServiceName ) { return cppu::supportsService(this, rServiceName); } css::uno::Any VCLXMenu::queryInterface( const css::uno::Type & rType ) { std::unique_lock aGuard( maMutex ); const bool bIsPopupMenu = IsPopupMenu(); aGuard.unlock(); css::uno::Any aRet; if ( bIsPopupMenu ) aRet = ::cppu::queryInterface( rType, static_cast< css::awt::XMenu* >(static_cast(this)), static_cast< css::awt::XPopupMenu* >(this), static_cast< css::lang::XTypeProvider* >(this), static_cast< css::lang::XServiceInfo* >(this) ); else aRet = ::cppu::queryInterface( rType, static_cast< css::awt::XMenu* >(static_cast(this)), static_cast< css::awt::XMenuBar* >(this), static_cast< css::lang::XTypeProvider* >(this), static_cast< css::lang::XServiceInfo* >(this) ); return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType )); } css::uno::Sequence< css::uno::Type > VCLXMenu::getTypes() { std::unique_lock aGuard( maMutex ); const bool bIsPopupMenu = IsPopupMenu(); aGuard.unlock(); if ( bIsPopupMenu ) { static cppu::OTypeCollection collectionPopupMenu( cppu::UnoType::get(), cppu::UnoType::get(), cppu::UnoType::get(), cppu::UnoType::get()); return collectionPopupMenu.getTypes(); } else { static cppu::OTypeCollection collectionMenuBar( cppu::UnoType::get(), cppu::UnoType::get(), cppu::UnoType::get(), cppu::UnoType::get()); return collectionMenuBar.getTypes(); } } css::uno::Sequence< sal_Int8 > VCLXMenu::getImplementationId() { return css::uno::Sequence(); } void VCLXMenu::addMenuListener( const css::uno::Reference< css::awt::XMenuListener >& rxListener ) { std::unique_lock aGuard( maMutex ); maMenuListeners.addInterface( rxListener ); } void VCLXMenu::removeMenuListener( const css::uno::Reference< css::awt::XMenuListener >& rxListener ) { std::unique_lock aGuard( maMutex ); maMenuListeners.removeInterface( rxListener ); } void VCLXMenu::insertItem( sal_Int16 nItemId, const OUString& aText, sal_Int16 nItemStyle, sal_Int16 nPos ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu ) mpMenu->InsertItem(nItemId, aText, static_cast(nItemStyle), {}, nPos); } void VCLXMenu::removeItem( sal_Int16 nPos, sal_Int16 nCount ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if (!mpMenu) return; sal_Int32 nItemCount = static_cast(mpMenu->GetItemCount()); if ((nCount > 0) && (nPos >= 0) && (nPos < nItemCount)) { sal_Int16 nP = sal::static_int_cast< sal_Int16 >( std::min( static_cast(nPos+nCount), static_cast(nItemCount) )); while( nP-nPos > 0 ) mpMenu->RemoveItem( --nP ); } } sal_Int16 VCLXMenu::getItemCount( ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); return mpMenu ? mpMenu->GetItemCount() : 0; } sal_Int16 VCLXMenu::getItemId( sal_Int16 nPos ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); return mpMenu ? mpMenu->GetItemId( nPos ) : 0; } sal_Int16 VCLXMenu::getItemPos( sal_Int16 nId ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); return mpMenu ? mpMenu->GetItemPos( nId ) : 0; } void VCLXMenu::enableItem( sal_Int16 nItemId, sal_Bool bEnable ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu ) mpMenu->EnableItem( nItemId, bEnable ); } sal_Bool VCLXMenu::isItemEnabled( sal_Int16 nItemId ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); return mpMenu && mpMenu->IsItemEnabled( nItemId ); } void VCLXMenu::setItemText( sal_Int16 nItemId, const OUString& aText ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu ) mpMenu->SetItemText( nItemId, aText ); } OUString VCLXMenu::getItemText( sal_Int16 nItemId ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); OUString aItemText; if ( mpMenu ) aItemText = mpMenu->GetItemText( nItemId ); return aItemText; } void VCLXMenu::setPopupMenu( sal_Int16 nItemId, const css::uno::Reference< css::awt::XPopupMenu >& rxPopupMenu ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); VCLXMenu* pVCLMenu = dynamic_cast( rxPopupMenu.get() ); DBG_ASSERT( pVCLMenu && pVCLMenu->GetMenu() && pVCLMenu->IsPopupMenu(), "setPopupMenu: Invalid Menu!" ); if ( mpMenu && pVCLMenu && pVCLMenu->GetMenu() && pVCLMenu->IsPopupMenu() ) { maPopupMenuRefs.push_back( rxPopupMenu ); mpMenu->SetPopupMenu( nItemId, static_cast( pVCLMenu->GetMenu() ) ); } } css::uno::Reference< css::awt::XPopupMenu > VCLXMenu::getPopupMenu( sal_Int16 nItemId ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); css::uno::Reference< css::awt::XPopupMenu > aRef; Menu* pMenu = mpMenu ? mpMenu->GetPopupMenu( nItemId ) : nullptr; if ( pMenu ) { for ( size_t n = maPopupMenuRefs.size(); n; ) { css::uno::Reference< css::awt::XPopupMenu >& rRef = maPopupMenuRefs[ --n ]; Menu* pM = static_cast(rRef.get())->GetMenu(); if ( pM == pMenu ) { aRef = rRef; break; } } // it seems the popup menu is not insert into maPopupMenuRefs // if the popup men is not created by stardiv.Toolkit.VCLXPopupMenu if( !aRef.is() ) { aRef = new VCLXPopupMenu( static_cast(pMenu) ); } } return aRef; } // css::awt::XPopupMenu void VCLXMenu::insertSeparator( sal_Int16 nPos ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu ) mpMenu->InsertSeparator({}, nPos); } void VCLXMenu::setDefaultItem( sal_Int16 nItemId ) { std::unique_lock aGuard( maMutex ); mnDefaultItem = nItemId; } sal_Int16 VCLXMenu::getDefaultItem( ) { std::unique_lock aGuard( maMutex ); return mnDefaultItem; } void VCLXMenu::checkItem( sal_Int16 nItemId, sal_Bool bCheck ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu ) mpMenu->CheckItem( nItemId, bCheck ); } sal_Bool VCLXMenu::isItemChecked( sal_Int16 nItemId ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); return mpMenu && mpMenu->IsItemChecked( nItemId ); } sal_Int16 VCLXMenu::execute( const css::uno::Reference< css::awt::XWindowPeer >& rxWindowPeer, const css::awt::Rectangle& rPos, sal_Int16 nFlags ) { SolarMutexGuard aSolarGuard; auto pMenu = mpMenu; { std::unique_lock aGuard( maMutex ); if ( !mpMenu || !IsPopupMenu() ) return 0; } // cannot call this with mutex locked because it will call back into us return static_cast(pMenu.get())->Execute( VCLUnoHelper::GetWindow( rxWindowPeer ), VCLRectangle( rPos ), static_cast(nFlags) | PopupMenuFlags::NoMouseUpClose ); } void SAL_CALL VCLXMenu::setCommand( sal_Int16 nItemId, const OUString& aCommand ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu ) mpMenu->SetItemCommand( nItemId, aCommand ); } OUString SAL_CALL VCLXMenu::getCommand( sal_Int16 nItemId ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); OUString aItemCommand; if ( mpMenu ) aItemCommand = mpMenu->GetItemCommand( nItemId ); return aItemCommand; } void SAL_CALL VCLXMenu::setHelpCommand( sal_Int16 nItemId, const OUString& aHelp ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu ) mpMenu->SetHelpCommand( nItemId, aHelp ); } OUString SAL_CALL VCLXMenu::getHelpCommand( sal_Int16 nItemId ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); OUString aHelpCommand; if ( mpMenu ) aHelpCommand = mpMenu->GetHelpCommand( nItemId ); return aHelpCommand; } namespace { Image lcl_XGraphic2VCLImage( const css::uno::Reference< css::graphic::XGraphic >& xGraphic, bool bResize ) { Image aImage; if ( !xGraphic.is() ) return aImage; aImage = Image( xGraphic ); const ::Size aCurSize = aImage.GetSizePixel(); const sal_Int32 nCurWidth = aCurSize.Width(); const sal_Int32 nCurHeight = aCurSize.Height(); constexpr sal_Int32 nIdeal( 16 ); if ( nCurWidth > 0 && nCurHeight > 0 ) { if ( bResize && ( nCurWidth > nIdeal || nCurHeight > nIdeal ) ) { sal_Int32 nIdealWidth = std::min(nCurWidth, nIdeal); sal_Int32 nIdealHeight = std::min(nCurHeight, nIdeal); ::Size aNewSize( nIdealWidth, nIdealHeight ); bool bModified( false ); BitmapEx aBitmapEx = aImage.GetBitmapEx(); bModified = aBitmapEx.Scale( aNewSize, BmpScaleFlag::BestQuality ); if ( bModified ) aImage = Image( aBitmapEx ); } } return aImage; } /** Copied from include/svtools/acceleratorexecute.hxx */ css::awt::KeyEvent lcl_VCLKey2AWTKey( const vcl::KeyCode& aVCLKey) { css::awt::KeyEvent aAWTKey; aAWTKey.Modifiers = 0; aAWTKey.KeyCode = static_cast(aVCLKey.GetCode()); if (aVCLKey.IsShift()) aAWTKey.Modifiers |= css::awt::KeyModifier::SHIFT; if (aVCLKey.IsMod1()) aAWTKey.Modifiers |= css::awt::KeyModifier::MOD1; if (aVCLKey.IsMod2()) aAWTKey.Modifiers |= css::awt::KeyModifier::MOD2; if (aVCLKey.IsMod3()) aAWTKey.Modifiers |= css::awt::KeyModifier::MOD3; return aAWTKey; } vcl::KeyCode lcl_AWTKey2VCLKey(const css::awt::KeyEvent& aAWTKey) { bool bShift = ((aAWTKey.Modifiers & css::awt::KeyModifier::SHIFT) == css::awt::KeyModifier::SHIFT ); bool bMod1 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD1 ) == css::awt::KeyModifier::MOD1 ); bool bMod2 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD2 ) == css::awt::KeyModifier::MOD2 ); bool bMod3 = ((aAWTKey.Modifiers & css::awt::KeyModifier::MOD3 ) == css::awt::KeyModifier::MOD3 ); sal_uInt16 nKey = static_cast(aAWTKey.KeyCode); return vcl::KeyCode(nKey, bShift, bMod1, bMod2, bMod3); } } sal_Bool SAL_CALL VCLXMenu::isPopupMenu( ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); return IsPopupMenu(); } void SAL_CALL VCLXMenu::clear( ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu ) mpMenu->Clear(); } css::awt::MenuItemType SAL_CALL VCLXMenu::getItemType( ::sal_Int16 nItemPos ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); css::awt::MenuItemType aMenuItemType = css::awt::MenuItemType_DONTKNOW; if ( mpMenu ) { aMenuItemType = static_cast(mpMenu->GetItemType( nItemPos )); } return aMenuItemType; } void SAL_CALL VCLXMenu::hideDisabledEntries( sal_Bool bHide ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu ) { if ( bHide ) mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MenuFlags::HideDisabledEntries ); else mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MenuFlags::HideDisabledEntries ); } } sal_Bool SAL_CALL VCLXMenu::isInExecute( ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu && IsPopupMenu() ) return vcl::IsInPopupMenuExecute(); else return false; } void SAL_CALL VCLXMenu::endExecute() { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu && IsPopupMenu() ) static_cast( mpMenu.get() )->EndExecute(); } void SAL_CALL VCLXMenu::enableAutoMnemonics( sal_Bool bEnable ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu ) { if ( !bEnable ) mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() | MenuFlags::NoAutoMnemonics ); else mpMenu->SetMenuFlags( mpMenu->GetMenuFlags() & ~MenuFlags::NoAutoMnemonics ); } } void SAL_CALL VCLXMenu::setAcceleratorKeyEvent( ::sal_Int16 nItemId, const css::awt::KeyEvent& aKeyEvent ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) { vcl::KeyCode aVCLKeyCode = lcl_AWTKey2VCLKey( aKeyEvent ); mpMenu->SetAccelKey( nItemId, aVCLKeyCode ); } } css::awt::KeyEvent SAL_CALL VCLXMenu::getAcceleratorKeyEvent( ::sal_Int16 nItemId ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); css::awt::KeyEvent aKeyEvent; if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) { vcl::KeyCode nKeyCode = mpMenu->GetAccelKey( nItemId ); aKeyEvent = lcl_VCLKey2AWTKey( nKeyCode ); } return aKeyEvent; } void SAL_CALL VCLXMenu::setHelpText( ::sal_Int16 nItemId, const OUString& sHelpText ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) { mpMenu->SetHelpText( nItemId, sHelpText ); } } OUString SAL_CALL VCLXMenu::getHelpText( ::sal_Int16 nItemId ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); OUString sHelpText; if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) { sHelpText = mpMenu->GetHelpText( nItemId ); } return sHelpText; } void SAL_CALL VCLXMenu::setTipHelpText( ::sal_Int16 nItemId, const OUString& sTipHelpText ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) { mpMenu->SetTipHelpText( nItemId, sTipHelpText ); } } OUString SAL_CALL VCLXMenu::getTipHelpText( ::sal_Int16 nItemId ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); OUString sTipHelpText; if ( mpMenu && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) { sTipHelpText = mpMenu->GetTipHelpText( nItemId ); } return sTipHelpText; } void SAL_CALL VCLXMenu::setItemImage( ::sal_Int16 nItemId, const css::uno::Reference< css::graphic::XGraphic >& xGraphic, sal_Bool bScale ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) { Image aImage = lcl_XGraphic2VCLImage( xGraphic, bScale ); mpMenu->SetItemImage( nItemId, aImage ); } } css::uno::Reference< css::graphic::XGraphic > SAL_CALL VCLXMenu::getItemImage( ::sal_Int16 nItemId ) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard( maMutex ); css::uno::Reference< css::graphic::XGraphic > rxGraphic; if ( mpMenu && IsPopupMenu() && MENU_ITEM_NOTFOUND != mpMenu->GetItemPos( nItemId ) ) { Image aImage = mpMenu->GetItemImage( nItemId ); if ( !!aImage ) rxGraphic = Graphic(aImage.GetBitmapEx()).GetXGraphic(); } return rxGraphic; } void VCLXMenu::setUserValue(sal_uInt16 nItemId, void* nUserValue, MenuUserDataReleaseFunction aFunc) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard(maMutex); mpMenu->SetUserValue(nItemId, nUserValue, aFunc); } void* VCLXMenu::getUserValue(sal_uInt16 nItemId) { SolarMutexGuard aSolarGuard; std::unique_lock aGuard(maMutex); return mpMenu->GetUserValue(nItemId); } VCLXMenuBar::VCLXMenuBar() { ImplCreateMenu( false ); } VCLXMenuBar::VCLXMenuBar( MenuBar* pMenuBar ) : VCLXMenu( static_cast(pMenuBar) ) { } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * stardiv_Toolkit_VCLXMenuBar_get_implementation( css::uno::XComponentContext *, css::uno::Sequence const &) { return cppu::acquire(new VCLXMenuBar()); } VCLXPopupMenu::VCLXPopupMenu() { ImplCreateMenu( true ); } VCLXPopupMenu::VCLXPopupMenu( PopupMenu* pPopMenu ) : VCLXMenu( static_cast(pPopMenu) ) { ImplAddListener(); } extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * stardiv_Toolkit_VCLXPopupMenu_get_implementation( css::uno::XComponentContext *, css::uno::Sequence const &) { return cppu::acquire(new VCLXPopupMenu()); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */