Kaydet (Commit) 49041802 authored tarafından Caolán McNamara's avatar Caolán McNamara

fix leak from framework::AddonMenuManager::BuildMenu

provide a callback when a menu item gets deleted

Change-Id: I5b5f1a181fb10f53f6b1fe7b5637d385e1517530
üst 0c3505f0
...@@ -81,9 +81,6 @@ namespace framework ...@@ -81,9 +81,6 @@ namespace framework
private: private:
virtual void impl_setPopupMenu() SAL_OVERRIDE; virtual void impl_setPopupMenu() SAL_OVERRIDE;
typedef MenuConfiguration::Attributes AddInfo;
typedef std::unordered_map< int, std::unique_ptr<AddInfo> > AddInfoForId;
void fillPopupMenu( com::sun::star::uno::Reference< com::sun::star::awt::XPopupMenu >& rPopupMenu ); void fillPopupMenu( com::sun::star::uno::Reference< com::sun::star::awt::XPopupMenu >& rPopupMenu );
void retrieveShortcutsFromConfiguration( const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XAcceleratorConfiguration >& rAccelCfg, void retrieveShortcutsFromConfiguration( const ::com::sun::star::uno::Reference< ::com::sun::star::ui::XAcceleratorConfiguration >& rAccelCfg,
...@@ -99,7 +96,6 @@ namespace framework ...@@ -99,7 +96,6 @@ namespace framework
m_bNewMenu : 1, m_bNewMenu : 1,
m_bModuleIdentified : 1, m_bModuleIdentified : 1,
m_bAcceleratorCfg : 1; m_bAcceleratorCfg : 1;
AddInfoForId m_aAddInfoForItem;
OUString m_aTargetFrame; OUString m_aTargetFrame;
OUString m_aModuleIdentifier; OUString m_aModuleIdentifier;
OUString m_aEmptyDocURL; OUString m_aEmptyDocURL;
......
...@@ -58,10 +58,7 @@ AddonMenu::~AddonMenu() ...@@ -58,10 +58,7 @@ AddonMenu::~AddonMenu()
{ {
if ( GetItemType( i ) != MenuItemType::SEPARATOR ) if ( GetItemType( i ) != MenuItemType::SEPARATOR )
{ {
// delete user attributes created with new!
sal_uInt16 nId = GetItemId( i ); sal_uInt16 nId = GetItemId( i );
MenuConfiguration::Attributes* pUserAttributes = reinterpret_cast<MenuConfiguration::Attributes*>(GetUserValue( nId ));
delete pUserAttributes;
delete GetPopupMenu( nId ); delete GetPopupMenu( nId );
} }
} }
...@@ -333,7 +330,8 @@ void AddonMenuManager::BuildMenu( PopupMenu* pCurrent ...@@ -333,7 +330,8 @@ void AddonMenuManager::BuildMenu( PopupMenu* pCurrent
// Store values from configuration to the New and Wizard menu entries to enable // Store values from configuration to the New and Wizard menu entries to enable
// sfx2 based code to support high contrast mode correctly! // sfx2 based code to support high contrast mode correctly!
pCurrentMenu->SetUserValue( nId, sal_uIntPtr( new MenuConfiguration::Attributes( aTarget, aImageId )) ); sal_uIntPtr nAttributePtr = MenuConfiguration::Attributes::CreateAttribute(aTarget, aImageId);
pCurrentMenu->SetUserValue(nId, nAttributePtr, MenuConfiguration::Attributes::ReleaseAttribute);
pCurrentMenu->SetItemCommand( nId, aURL ); pCurrentMenu->SetItemCommand( nId, aURL );
if ( pSubMenu ) if ( pSubMenu )
......
...@@ -164,8 +164,8 @@ void BmkMenu::Initialize() ...@@ -164,8 +164,8 @@ void BmkMenu::Initialize()
else else
InsertItem( nId, aTitle ); InsertItem( nId, aTitle );
MenuConfiguration::Attributes* pUserAttributes = new MenuConfiguration::Attributes( aTargetFrame, aImageId ); sal_uIntPtr nAttributePtr = MenuConfiguration::Attributes::CreateAttribute(aTargetFrame, aImageId);
SetUserValue( nId, reinterpret_cast<sal_uIntPtr>(pUserAttributes) ); SetUserValue(nId, nAttributePtr, MenuConfiguration::Attributes::ReleaseAttribute);
SetItemCommand( nId, aURL ); SetItemCommand( nId, aURL );
} }
......
...@@ -139,6 +139,28 @@ void MenuConfiguration::StoreMenuBarConfigurationToXML( ...@@ -139,6 +139,28 @@ void MenuConfiguration::StoreMenuBarConfigurationToXML(
} }
} }
sal_uIntPtr MenuConfiguration::Attributes::CreateAttribute(const OUString& rFrame, const OUString& rImageIdStr)
{
Attributes* pAttributes = new Attributes(rFrame, rImageIdStr);
pAttributes->acquire();
return reinterpret_cast<sal_uIntPtr>(pAttributes);
}
sal_uIntPtr MenuConfiguration::Attributes::CreateAttribute(const css::uno::WeakReference<css::frame::XDispatchProvider>& rDispatchProvider)
{
Attributes* pAttributes = new Attributes(rDispatchProvider);
pAttributes->acquire();
return reinterpret_cast<sal_uIntPtr>(pAttributes);
}
void MenuConfiguration::Attributes::ReleaseAttribute(sal_uIntPtr nAttributePtr)
{
if (!nAttributePtr)
return;
Attributes* pAttributes = reinterpret_cast<Attributes*>(nAttributePtr);
pAttributes->release();
}
} }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -1687,9 +1687,8 @@ void MenuBarManager::FillMenu( ...@@ -1687,9 +1687,8 @@ void MenuBarManager::FillMenu(
if ( xDispatchProvider.is() ) if ( xDispatchProvider.is() )
{ {
// Use attributes struct to transport special dispatch provider // Use attributes struct to transport special dispatch provider
MenuConfiguration::Attributes* pAttributes = new MenuConfiguration::Attributes; sal_uIntPtr nAttributePtr = MenuConfiguration::Attributes::CreateAttribute(xDispatchProvider);
pAttributes->xDispatchProvider = xDispatchProvider; pMenu->SetUserValue(nId, nAttributePtr, MenuConfiguration::Attributes::ReleaseAttribute);
pMenu->SetUserValue( nId, reinterpret_cast<sal_uIntPtr>( pAttributes ));
} }
// Use help command to transport module identifier // Use help command to transport module identifier
......
...@@ -83,9 +83,10 @@ void NewMenuController::setMenuImages( PopupMenu* pPopupMenu, bool bSetImages ) ...@@ -83,9 +83,10 @@ void NewMenuController::setMenuImages( PopupMenu* pPopupMenu, bool bSetImages )
bool bImageSet( false ); bool bImageSet( false );
OUString aImageId; OUString aImageId;
AddInfoForId::const_iterator pInfo = m_aAddInfoForItem.find( nItemId ); sal_uIntPtr nAttributePtr = pPopupMenu->GetUserValue(sal::static_int_cast<sal_uInt16>(i));
if ( pInfo != m_aAddInfoForItem.end() ) MenuConfiguration::Attributes* pAttributes = reinterpret_cast<MenuConfiguration::Attributes *>(nAttributePtr);
aImageId = pInfo->second->aImageId; // Retrieve image id for menu item if (pAttributes)
aImageId = pAttributes->aImageId;
if ( !aImageId.isEmpty() ) if ( !aImageId.isEmpty() )
{ {
...@@ -345,13 +346,12 @@ void NewMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopup ...@@ -345,13 +346,12 @@ void NewMenuController::fillPopupMenu( Reference< css::awt::XPopupMenu >& rPopup
if (( nItemId != 0 ) && if (( nItemId != 0 ) &&
( pSubMenu->GetItemType( nItemId ) != MenuItemType::SEPARATOR )) ( pSubMenu->GetItemType( nItemId ) != MenuItemType::SEPARATOR ))
{ {
MenuConfiguration::Attributes* pBmkAttributes = reinterpret_cast<MenuConfiguration::Attributes *>(pSubMenu->GetUserValue( nItemId )); sal_uIntPtr nAttributePtr = pSubMenu->GetUserValue(nItemId);
if ( pBmkAttributes != 0 ) if (nAttributePtr)
{ {
auto result = m_aAddInfoForItem.insert( MenuConfiguration::Attributes* pAttributes = reinterpret_cast<MenuConfiguration::Attributes *>(nAttributePtr);
std::make_pair(nItemId, std::unique_ptr<AddInfo>(new AddInfo(*pBmkAttributes)))); pAttributes->acquire();
MenuConfiguration::Attributes *pNewInfo = result.first->second.get(); pVCLPopupMenu->SetUserValue(nItemId, nAttributePtr, MenuConfiguration::Attributes::ReleaseAttribute);
pVCLPopupMenu->SetUserValue(nItemId, reinterpret_cast<sal_uIntPtr>(pNewInfo));
} }
} }
} }
...@@ -405,10 +405,16 @@ void SAL_CALL NewMenuController::itemSelected( const css::awt::MenuEvent& rEvent ...@@ -405,10 +405,16 @@ void SAL_CALL NewMenuController::itemSelected( const css::awt::MenuEvent& rEvent
VCLXPopupMenu* pPopupMenu = static_cast<VCLXPopupMenu *>(VCLXPopupMenu::GetImplementation( xPopupMenu )); VCLXPopupMenu* pPopupMenu = static_cast<VCLXPopupMenu *>(VCLXPopupMenu::GetImplementation( xPopupMenu ));
if ( pPopupMenu ) if ( pPopupMenu )
{ {
OUString aTargetFrame( m_aTargetFrame );
{ {
SolarMutexGuard aSolarMutexGuard; SolarMutexGuard aSolarMutexGuard;
PopupMenu* pVCLPopupMenu = static_cast<PopupMenu *>(pPopupMenu->GetMenu()); PopupMenu* pVCLPopupMenu = static_cast<PopupMenu *>(pPopupMenu->GetMenu());
aTargetURL.Complete = pVCLPopupMenu->GetItemCommand( rEvent.MenuId ); aTargetURL.Complete = pVCLPopupMenu->GetItemCommand(rEvent.MenuId);
sal_uIntPtr nAttributePtr = pVCLPopupMenu->GetUserValue(rEvent.MenuId);
MenuConfiguration::Attributes* pAttributes = reinterpret_cast<MenuConfiguration::Attributes *>(nAttributePtr);
if (pAttributes)
aTargetFrame = pAttributes->aTargetFrame;
} }
xURLTransformer->parseStrict( aTargetURL ); xURLTransformer->parseStrict( aTargetURL );
...@@ -416,11 +422,6 @@ void SAL_CALL NewMenuController::itemSelected( const css::awt::MenuEvent& rEvent ...@@ -416,11 +422,6 @@ void SAL_CALL NewMenuController::itemSelected( const css::awt::MenuEvent& rEvent
aArgsList[0].Name = "Referer"; aArgsList[0].Name = "Referer";
aArgsList[0].Value = makeAny( OUString( "private:user" )); aArgsList[0].Value = makeAny( OUString( "private:user" ));
OUString aTargetFrame( m_aTargetFrame );
AddInfoForId::const_iterator pItem = m_aAddInfoForItem.find( rEvent.MenuId );
if ( pItem != m_aAddInfoForItem.end() )
aTargetFrame = pItem->second->aTargetFrame;
xDispatch = xDispatchProvider->queryDispatch( aTargetURL, aTargetFrame, 0 ); xDispatch = xDispatchProvider->queryDispatch( aTargetURL, aTargetFrame, 0 );
} }
} }
......
...@@ -61,22 +61,46 @@ class FWE_DLLPUBLIC MenuConfiguration ...@@ -61,22 +61,46 @@ class FWE_DLLPUBLIC MenuConfiguration
public: public:
struct Attributes struct Attributes
{ {
Attributes() private:
: nStyle(0) oslInterlockedCount refCount;
Attributes(const OUString& rFrame, const OUString& rImageIdStr)
: refCount(0)
, aTargetFrame(rFrame)
, aImageId(rImageIdStr)
, nStyle(0)
{ {
} }
Attributes( const OUString& aFrame, const OUString& aImageIdStr ) Attributes(const css::uno::WeakReference<css::frame::XDispatchProvider>& rDispatchProvider)
: aTargetFrame(aFrame) : refCount(0)
, aImageId(aImageIdStr) , xDispatchProvider(rDispatchProvider)
, nStyle(0) , nStyle(0)
{ {
} }
Attributes(const Attributes&); //not-implemented
public:
OUString aTargetFrame; OUString aTargetFrame;
OUString aImageId; OUString aImageId;
::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XDispatchProvider > xDispatchProvider; css::uno::WeakReference<css::frame::XDispatchProvider> xDispatchProvider;
sal_Int16 nStyle; sal_Int16 nStyle;
static sal_uIntPtr CreateAttribute(const OUString& rFrame, const OUString& rImageIdStr);
static sal_uIntPtr CreateAttribute(const css::uno::WeakReference<css::frame::XDispatchProvider>& rDispatchProvider);
static void ReleaseAttribute(sal_uIntPtr nAttributePtr);
void acquire()
{
osl_atomic_increment(&refCount);
}
void release()
{
if (!osl_atomic_decrement(&refCount))
delete this;
}
}; };
MenuConfiguration( MenuConfiguration(
......
...@@ -108,6 +108,8 @@ struct MenuLogo ...@@ -108,6 +108,8 @@ struct MenuLogo
Color aEndColor; Color aEndColor;
}; };
typedef void (*MenuUserDataReleaseFunction)(sal_uLong);
class VCL_DLLPUBLIC Menu : public Resource class VCL_DLLPUBLIC Menu : public Resource
{ {
friend class MenuBar; friend class MenuBar;
...@@ -263,8 +265,8 @@ public: ...@@ -263,8 +265,8 @@ public:
void SetItemBits( sal_uInt16 nItemId, MenuItemBits nBits ); void SetItemBits( sal_uInt16 nItemId, MenuItemBits nBits );
MenuItemBits GetItemBits( sal_uInt16 nItemId ) const; MenuItemBits GetItemBits( sal_uInt16 nItemId ) const;
void SetUserValue( sal_uInt16 nItemId, sal_uLong nValue ); void SetUserValue(sal_uInt16 nItemId, sal_uLong nValue, MenuUserDataReleaseFunction aFunc=0);
sal_uLong GetUserValue( sal_uInt16 nItemId ) const; sal_uLong GetUserValue(sal_uInt16 nItemId) const;
void SetPopupMenu( sal_uInt16 nItemId, PopupMenu* pMenu ); void SetPopupMenu( sal_uInt16 nItemId, PopupMenu* pMenu );
PopupMenu* GetPopupMenu( sal_uInt16 nItemId ) const; PopupMenu* GetPopupMenu( sal_uInt16 nItemId ) const;
......
...@@ -758,11 +758,16 @@ MenuItemBits Menu::GetItemBits( sal_uInt16 nItemId ) const ...@@ -758,11 +758,16 @@ MenuItemBits Menu::GetItemBits( sal_uInt16 nItemId ) const
return nBits; return nBits;
} }
void Menu::SetUserValue( sal_uInt16 nItemId, sal_uLong nValue ) void Menu::SetUserValue(sal_uInt16 nItemId, sal_uLong nValue, MenuUserDataReleaseFunction aFunc)
{ {
MenuItemData* pData = pItemList->GetData( nItemId ); MenuItemData* pData = pItemList->GetData(nItemId);
if ( pData ) if (pData)
{
if (pData->aUserValueReleaseFunc)
pData->aUserValueReleaseFunc(pData->nUserValue);
pData->aUserValueReleaseFunc = aFunc;
pData->nUserValue = nValue; pData->nUserValue = nValue;
}
} }
sal_uLong Menu::GetUserValue( sal_uInt16 nItemId ) const sal_uLong Menu::GetUserValue( sal_uInt16 nItemId ) const
......
...@@ -32,6 +32,8 @@ using namespace vcl; ...@@ -32,6 +32,8 @@ using namespace vcl;
MenuItemData::~MenuItemData() MenuItemData::~MenuItemData()
{ {
if (aUserValueReleaseFunc)
aUserValueReleaseFunc(nUserValue);
if( pAutoSubMenu ) if( pAutoSubMenu )
{ {
static_cast<PopupMenu*>(pAutoSubMenu)->pRefAutoSubMenu = NULL; static_cast<PopupMenu*>(pAutoSubMenu)->pRefAutoSubMenu = NULL;
......
...@@ -42,7 +42,8 @@ struct MenuItemData ...@@ -42,7 +42,8 @@ struct MenuItemData
OUString aHelpCommandStr; // Help command string (to reference external help) OUString aHelpCommandStr; // Help command string (to reference external help)
OString sIdent; OString sIdent;
OString aHelpId; // Help-Id OString aHelpId; // Help-Id
sal_uLong nUserValue; // User value sal_uLong nUserValue; // User value
MenuUserDataReleaseFunction aUserValueReleaseFunc; // called when MenuItemData is destroyed
Image aImage; // Image Image aImage; // Image
vcl::KeyCode aAccelKey; // Accelerator-Key vcl::KeyCode aAccelKey; // Accelerator-Key
bool bChecked; // Checked bool bChecked; // Checked
...@@ -64,6 +65,7 @@ struct MenuItemData ...@@ -64,6 +65,7 @@ struct MenuItemData
, pSubMenu(NULL) , pSubMenu(NULL)
, pAutoSubMenu(NULL) , pAutoSubMenu(NULL)
, nUserValue(0) , nUserValue(0)
, aUserValueReleaseFunc(0)
, bChecked(false) , bChecked(false)
, bEnabled(false) , bEnabled(false)
, bVisible(false) , bVisible(false)
...@@ -81,6 +83,7 @@ struct MenuItemData ...@@ -81,6 +83,7 @@ struct MenuItemData
, pAutoSubMenu(NULL) , pAutoSubMenu(NULL)
, aText(rStr) , aText(rStr)
, nUserValue(0) , nUserValue(0)
, aUserValueReleaseFunc(0)
, aImage(rImage) , aImage(rImage)
, bChecked(false) , bChecked(false)
, bEnabled(false) , bEnabled(false)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment