diff options
author | Caolán McNamara <caolanm@redhat.com> | 2011-01-21 10:51:30 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2011-01-21 10:51:30 +0000 |
commit | dbe02986e8005fd5e66f5b95fe6ba08253e6410d (patch) | |
tree | 4ec8c6e449e356ed54d0a4864d4c02853156218b /framework | |
parent | 87ce4f4744188cd3a76315896bcf2ab03c4378f4 (diff) |
break ownership cycle
Diffstat (limited to 'framework')
8 files changed, 119 insertions, 14 deletions
diff --git a/framework/inc/helper/mischelper.hxx b/framework/inc/helper/mischelper.hxx index ceedf78b38..e1428932f3 100644 --- a/framework/inc/helper/mischelper.hxx +++ b/framework/inc/helper/mischelper.hxx @@ -31,8 +31,11 @@ #include <com/sun/star/linguistic2/XLanguageGuessing.hpp> #include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XContainerListener.hpp> #include <com/sun/star/frame/XFrame.hpp> +#include <cppuhelper/implbase1.hxx> + #include <i18npool/lang.h> #include <svl/languageoptions.hxx> #include <rtl/ustring.hxx> @@ -119,6 +122,74 @@ void FillLangItems( std::set< ::rtl::OUString > &rLangItems, const ::rtl::OUString & rKeyboardLang, const ::rtl::OUString & rGuessedTextLang ); +//It's common for an object to want to create and own a Broadcaster and set +//itself as a Listener on its own Broadcaster member. +// +//However, calling addListener on a Broadcaster means that the Broadcaster adds +//a reference to the Listener leading to an ownership cycle where the Listener +//owns the Broadcaster which "owns" the Listener. +// +//The WeakContainerListener allows breaking this cycle and retrofitting +//afflicted implentations fairly easily. +// +//OriginalListener owns the Broadcaster which "owns" the WeakContainerListener +//which forwards the events to the OriginalListener without taking ownership of +//it. +class WeakContainerListener : public ::cppu::WeakImplHelper1<com::sun::star::container::XContainerListener> +{ + private: + com::sun::star::uno::WeakReference<com::sun::star::container::XContainerListener> mxOwner; + + public: + WeakContainerListener(com::sun::star::uno::Reference<com::sun::star::container::XContainerListener> xOwner) + : mxOwner(xOwner) + { + } + + virtual ~WeakContainerListener() + { + } + + // container.XContainerListener + virtual void SAL_CALL elementInserted(const com::sun::star::container::ContainerEvent& rEvent) + throw(com::sun::star::uno::RuntimeException) + { + com::sun::star::uno::Reference<com::sun::star::container::XContainerListener> xOwner(mxOwner.get(), + com::sun::star::uno::UNO_QUERY); + if (xOwner.is()) + xOwner->elementInserted(rEvent); + } + + virtual void SAL_CALL elementRemoved(const com::sun::star::container::ContainerEvent& rEvent) + throw(com::sun::star::uno::RuntimeException) + { + com::sun::star::uno::Reference<com::sun::star::container::XContainerListener> xOwner(mxOwner.get(), + com::sun::star::uno::UNO_QUERY); + if (xOwner.is()) + xOwner->elementRemoved(rEvent); + } + + virtual void SAL_CALL elementReplaced(const com::sun::star::container::ContainerEvent& rEvent) + throw(com::sun::star::uno::RuntimeException) + { + com::sun::star::uno::Reference<com::sun::star::container::XContainerListener> xOwner(mxOwner.get(), + com::sun::star::uno::UNO_QUERY); + if (xOwner.is()) + xOwner->elementReplaced(rEvent); + } + + // lang.XEventListener + virtual void SAL_CALL disposing(const com::sun::star::lang::EventObject& rEvent) + throw(com::sun::star::uno::RuntimeException) + { + com::sun::star::uno::Reference<com::sun::star::container::XContainerListener> xOwner(mxOwner.get(), + com::sun::star::uno::UNO_QUERY); + if (xOwner.is()) + xOwner->disposing(rEvent); + + } +}; + } // namespace framework #endif // __MISC_HELPER_HXX_ diff --git a/framework/inc/uifactory/factoryconfiguration.hxx b/framework/inc/uifactory/factoryconfiguration.hxx index 0ced586bf9..4030155e11 100644 --- a/framework/inc/uifactory/factoryconfiguration.hxx +++ b/framework/inc/uifactory/factoryconfiguration.hxx @@ -117,6 +117,7 @@ private: ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager; ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xConfigProvider; ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xConfigAccess; + ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener > m_xConfigAccessListener; sal_Bool m_bConfigAccessInitialized; bool m_bAskValue; }; diff --git a/framework/inc/uifactory/uielementfactorymanager.hxx b/framework/inc/uifactory/uielementfactorymanager.hxx index 80b2711aca..55eeda62e1 100644 --- a/framework/inc/uifactory/uielementfactorymanager.hxx +++ b/framework/inc/uifactory/uielementfactorymanager.hxx @@ -113,6 +113,7 @@ namespace framework ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xServiceManager; ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > m_xConfigProvider; ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess > m_xConfigAccess; + ::com::sun::star::uno::Reference< ::com::sun::star::container::XContainerListener > m_xConfigListener; sal_Bool m_bConfigAccessInitialized; bool m_bConfigDirty; }; diff --git a/framework/source/uiconfiguration/uicategorydescription.cxx b/framework/source/uiconfiguration/uicategorydescription.cxx index fddea766fe..1bc66fc77d 100644 --- a/framework/source/uiconfiguration/uicategorydescription.cxx +++ b/framework/source/uiconfiguration/uicategorydescription.cxx @@ -39,6 +39,8 @@ #include "properties.h" +#include "helper/mischelper.hxx" + //_________________________________________________________________________________________________________________ // interface includes //_________________________________________________________________________________________________________________ @@ -148,6 +150,7 @@ class ConfigurationAccess_UICategory : // Order is neccessary for right initiali Reference< XMultiServiceFactory > m_xServiceManager; Reference< XMultiServiceFactory > m_xConfigProvider; Reference< XNameAccess > m_xConfigAccess; + Reference< XContainerListener > m_xConfigListener; sal_Bool m_bConfigAccessInitialized; sal_Bool m_bCacheFilled; IdToInfoCache m_aIdCache; @@ -180,7 +183,7 @@ ConfigurationAccess_UICategory::~ConfigurationAccess_UICategory() ResetableGuard aLock( m_aLock ); Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY ); if ( xContainer.is() ) - xContainer->removeContainerListener( this ); + xContainer->removeContainerListener(m_xConfigListener); } // XNameAccess @@ -387,7 +390,10 @@ sal_Bool ConfigurationAccess_UICategory::initializeConfigAccess() // Add as container listener Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY ); if ( xContainer.is() ) - xContainer->addContainerListener( this ); + { + m_xConfigListener = new WeakContainerListener(this); + xContainer->addContainerListener(m_xConfigListener); + } } return sal_True; diff --git a/framework/source/uiconfiguration/windowstateconfiguration.cxx b/framework/source/uiconfiguration/windowstateconfiguration.cxx index e4f2de761c..600e9cfefd 100644 --- a/framework/source/uiconfiguration/windowstateconfiguration.cxx +++ b/framework/source/uiconfiguration/windowstateconfiguration.cxx @@ -36,6 +36,8 @@ #include <threadhelp/resetableguard.hxx> #include "services.h" +#include "helper/mischelper.hxx" + //_________________________________________________________________________________________________________________ // interface includes //_________________________________________________________________________________________________________________ @@ -264,6 +266,7 @@ class ConfigurationAccess_WindowState : // interfaces Reference< XMultiServiceFactory > m_xServiceManager; Reference< XMultiServiceFactory > m_xConfigProvider; Reference< XNameAccess > m_xConfigAccess; + Reference< XContainerListener > m_xConfigListener; ResourceURLToInfoCache m_aResourceURLToInfoCache; sal_Bool m_bConfigAccessInitialized : 1, m_bModified : 1; @@ -321,7 +324,7 @@ ConfigurationAccess_WindowState::~ConfigurationAccess_WindowState() ResetableGuard aLock( m_aLock ); Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY ); if ( xContainer.is() ) - xContainer->removeContainerListener( this ); + xContainer->removeContainerListener(m_xConfigListener); } // XNameAccess @@ -1324,7 +1327,10 @@ sal_Bool ConfigurationAccess_WindowState::impl_initializeConfigAccess() // Add as container listener Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY ); if ( xContainer.is() ) - xContainer->addContainerListener( this ); + { + m_xConfigListener = new WeakContainerListener(this); + xContainer->addContainerListener(m_xConfigListener); + } } return sal_True; diff --git a/framework/source/uielement/uicommanddescription.cxx b/framework/source/uielement/uicommanddescription.cxx index c9c7956ee2..8a9ec117b1 100644 --- a/framework/source/uielement/uicommanddescription.cxx +++ b/framework/source/uielement/uicommanddescription.cxx @@ -38,6 +38,8 @@ #include "properties.h" +#include "helper/mischelper.hxx" + //_________________________________________________________________________________________________________________ // interface includes //_________________________________________________________________________________________________________________ @@ -193,9 +195,10 @@ class ConfigurationAccess_UICommand : // Order is neccessary for right initializ Reference< XNameAccess > m_xGenericUICommands; Reference< XMultiServiceFactory > m_xServiceManager; Reference< XMultiServiceFactory > m_xConfigProvider; - //Reference< XMultiServiceFactory > m_xConfigProviderPopups; Reference< XNameAccess > m_xConfigAccess; + Reference< XContainerListener > m_xConfigListener; Reference< XNameAccess > m_xConfigAccessPopups; + Reference< XContainerListener > m_xConfigAccessListener; Sequence< rtl::OUString > m_aCommandImageList; Sequence< rtl::OUString > m_aCommandRotateImageList; Sequence< rtl::OUString > m_aCommandMirrorImageList; @@ -246,10 +249,10 @@ ConfigurationAccess_UICommand::~ConfigurationAccess_UICommand() ResetableGuard aLock( m_aLock ); Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY ); if ( xContainer.is() ) - xContainer->removeContainerListener( this ); + xContainer->removeContainerListener(m_xConfigListener); xContainer = Reference< XContainer >( m_xConfigAccessPopups, UNO_QUERY ); if ( xContainer.is() ) - xContainer->removeContainerListener( this ); + xContainer->removeContainerListener(m_xConfigAccessListener); } // XNameAccess @@ -394,7 +397,7 @@ void ConfigurationAccess_UICommand::impl_fill(const Reference< XNameAccess >& _x { } } - } // if ( m_xConfigAccessPopups.is() ) + } } sal_Bool ConfigurationAccess_UICommand::fillCache() { @@ -558,7 +561,10 @@ sal_Bool ConfigurationAccess_UICommand::initializeConfigAccess() // Add as container listener Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY ); if ( xContainer.is() ) - xContainer->addContainerListener( this ); + { + m_xConfigListener = new WeakContainerListener(this); + xContainer->addContainerListener(m_xConfigListener); + } } aPropValue.Value <<= m_aConfigPopupAccess; @@ -569,7 +575,10 @@ sal_Bool ConfigurationAccess_UICommand::initializeConfigAccess() // Add as container listener Reference< XContainer > xContainer( m_xConfigAccessPopups, UNO_QUERY ); if ( xContainer.is() ) - xContainer->addContainerListener( this ); + { + m_xConfigAccessListener = new WeakContainerListener(this); + xContainer->addContainerListener(m_xConfigAccessListener); + } } return sal_True; diff --git a/framework/source/uifactory/factoryconfiguration.cxx b/framework/source/uifactory/factoryconfiguration.cxx index 3c253ee38d..2f96a265c0 100644 --- a/framework/source/uifactory/factoryconfiguration.cxx +++ b/framework/source/uifactory/factoryconfiguration.cxx @@ -36,6 +36,8 @@ #include <threadhelp/resetableguard.hxx> #include "services.h" +#include "helper/mischelper.hxx" + //_________________________________________________________________________________________________________________ // interface includes //_________________________________________________________________________________________________________________ @@ -103,7 +105,7 @@ ConfigurationAccess_ControllerFactory::~ConfigurationAccess_ControllerFactory() Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY ); if ( xContainer.is() ) - xContainer->removeContainerListener( this ); + xContainer->removeContainerListener(m_xConfigAccessListener); } rtl::OUString ConfigurationAccess_ControllerFactory::getServiceFromCommandModule( const rtl::OUString& rCommandURL, const rtl::OUString& rModule ) const @@ -269,7 +271,10 @@ void ConfigurationAccess_ControllerFactory::readConfigurationData() aLock.unlock(); if ( xContainer.is() ) - xContainer->addContainerListener( this ); + { + m_xConfigAccessListener = new WeakContainerListener(this); + xContainer->addContainerListener(m_xConfigAccessListener); + } } } diff --git a/framework/source/uifactory/uielementfactorymanager.cxx b/framework/source/uifactory/uielementfactorymanager.cxx index 9ca88c3f67..ed3889d5dd 100644 --- a/framework/source/uifactory/uielementfactorymanager.cxx +++ b/framework/source/uifactory/uielementfactorymanager.cxx @@ -37,6 +37,8 @@ #include <threadhelp/resetableguard.hxx> #include "services.h" +#include "helper/mischelper.hxx" + //_________________________________________________________________________________________________________________ // interface includes //_________________________________________________________________________________________________________________ @@ -55,6 +57,7 @@ #include <tools/urlobj.hxx> #include <vcl/svapp.hxx> #include <rtl/logfile.hxx> + //_________________________________________________________________________________________________________________ // Defines //_________________________________________________________________________________________________________________ @@ -115,7 +118,7 @@ ConfigurationAccess_FactoryManager::~ConfigurationAccess_FactoryManager() Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY ); if ( xContainer.is() ) - xContainer->removeContainerListener( this ); + xContainer->removeContainerListener(m_xConfigListener); } rtl::OUString ConfigurationAccess_FactoryManager::getFactorySpecifierFromTypeNameModule( const rtl::OUString& rType, const rtl::OUString& rName, const rtl::OUString& rModule ) const @@ -353,7 +356,10 @@ void ConfigurationAccess_FactoryManager::readConfigurationData() aLock.unlock(); // UNSAFE if ( xContainer.is() ) - xContainer->addContainerListener( this ); + { + m_xConfigListener = new WeakContainerListener(this); + xContainer->addContainerListener(m_xConfigListener); + } } } |