summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2011-01-21 10:51:30 +0000
committerCaolán McNamara <caolanm@redhat.com>2011-01-21 10:51:30 +0000
commitdbe02986e8005fd5e66f5b95fe6ba08253e6410d (patch)
tree4ec8c6e449e356ed54d0a4864d4c02853156218b
parent87ce4f4744188cd3a76315896bcf2ab03c4378f4 (diff)
break ownership cycle
-rw-r--r--framework/inc/helper/mischelper.hxx71
-rw-r--r--framework/inc/uifactory/factoryconfiguration.hxx1
-rw-r--r--framework/inc/uifactory/uielementfactorymanager.hxx1
-rw-r--r--framework/source/uiconfiguration/uicategorydescription.cxx10
-rw-r--r--framework/source/uiconfiguration/windowstateconfiguration.cxx10
-rw-r--r--framework/source/uielement/uicommanddescription.cxx21
-rw-r--r--framework/source/uifactory/factoryconfiguration.cxx9
-rw-r--r--framework/source/uifactory/uielementfactorymanager.cxx10
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);
+ }
}
}