summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Meeks <michael.meeks@collabora.com>2016-01-04 21:28:59 +0000
committerMichael Stahl <mstahl@redhat.com>2016-01-07 14:42:46 +0000
commit9a22f9f5fe528c7c0f45813a025b377f79c8372e (patch)
treebd498d62c2b9ea0764a543abc28df7f7e3e86c38
parentd48370043b3759c79340c162048c5f2b4da394b9 (diff)
tdf#94715 - ensure we remove ourselves from the same event source.
Seemingly event removal was not occuring; also clean up historic duplication of UNO and C++ references using rtl::Reference. Reviewed-on: https://gerrit.libreoffice.org/21088 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Michael Meeks <michael.meeks@collabora.com> Conflicts: include/toolkit/awt/vclxaccessiblecomponent.hxx toolkit/source/awt/vclxaccessiblecomponent.cxx Change-Id: I56dfb76501929886f70495804670f8c4f70e796b Reviewed-on: https://gerrit.libreoffice.org/21110 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Michael Stahl <mstahl@redhat.com>
-rw-r--r--include/toolkit/awt/vclxaccessiblecomponent.hxx15
-rw-r--r--toolkit/source/awt/vclxaccessiblecomponent.cxx70
2 files changed, 43 insertions, 42 deletions
diff --git a/include/toolkit/awt/vclxaccessiblecomponent.hxx b/include/toolkit/awt/vclxaccessiblecomponent.hxx
index 0fdc2a8f083f..f01183fa3d9b 100644
--- a/include/toolkit/awt/vclxaccessiblecomponent.hxx
+++ b/include/toolkit/awt/vclxaccessiblecomponent.hxx
@@ -63,15 +63,16 @@ class TOOLKIT_DLLPUBLIC VCLXAccessibleComponent
,public VCLXAccessibleComponent_BASE
{
private:
- ::com::sun::star::uno::Reference< ::com::sun::star::awt::XWindow> mxWindow;
- VCLXWindow* mpVCLXindow;
+ rtl::Reference<VCLXWindow> m_xVCLXWindow;
+ VclPtr<vcl::Window> m_xEventSource;
VCLExternalSolarLock* m_pSolarLock;
-protected:
- DECL_LINK( WindowEventListener, VclSimpleEvent* );
- DECL_LINK( WindowChildEventListener, VclSimpleEvent* );
+ DECL_LINK( WindowEventListener, VclSimpleEvent* );
+ DECL_LINK( WindowChildEventListener, VclSimpleEvent* );
+ void DisconnectEvents();
+protected:
virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent );
virtual void ProcessWindowChildEvent( const VclWindowEvent& rVclWindowEvent );
virtual void FillAccessibleRelationSet( utl::AccessibleRelationSetHelper& rRelationSet );
@@ -80,10 +81,10 @@ protected:
virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > GetChildAccessible( const VclWindowEvent& rVclWindowEvent );
public:
- VCLXAccessibleComponent( VCLXWindow* pVCLXindow );
+ VCLXAccessibleComponent( VCLXWindow* pVCLXWindow );
virtual ~VCLXAccessibleComponent();
- VCLXWindow* GetVCLXWindow() const { return mpVCLXindow; }
+ VCLXWindow* GetVCLXWindow() const;
VclPtr<vcl::Window> GetWindow() const;
template< class derived_type > VclPtr< derived_type > GetAs() const {
return VclPtr< derived_type >( static_cast< derived_type * >( GetWindow().get() ) ); }
diff --git a/toolkit/source/awt/vclxaccessiblecomponent.cxx b/toolkit/source/awt/vclxaccessiblecomponent.cxx
index 9031492fbf2a..2d50fd528643 100644
--- a/toolkit/source/awt/vclxaccessiblecomponent.cxx
+++ b/toolkit/source/awt/vclxaccessiblecomponent.cxx
@@ -42,35 +42,45 @@
using namespace ::com::sun::star;
using namespace ::comphelper;
-VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow* pVCLXindow )
+VCLXAccessibleComponent::VCLXAccessibleComponent( VCLXWindow* pVCLXWindow )
: AccessibleExtendedComponentHelper_BASE( new VCLExternalSolarLock() )
, OAccessibleImplementationAccess( )
{
- mpVCLXindow = pVCLXindow;
- mxWindow = pVCLXindow;
+ m_xVCLXWindow = pVCLXWindow;
m_pSolarLock = static_cast< VCLExternalSolarLock* >( getExternalLock( ) );
- DBG_ASSERT( pVCLXindow->GetWindow(), "VCLXAccessibleComponent - no window!" );
- if ( pVCLXindow->GetWindow() )
+ DBG_ASSERT( pVCLXWindow->GetWindow(), "VCLXAccessibleComponent - no window!" );
+ m_xEventSource = pVCLXWindow->GetWindow();
+ if ( m_xEventSource )
{
- pVCLXindow->GetWindow()->AddEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
- pVCLXindow->GetWindow()->AddChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
+ m_xEventSource->AddEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
+ m_xEventSource->AddChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
}
// announce the XAccessible of our creator to the base class
- lateInit( pVCLXindow );
+ lateInit( pVCLXWindow );
}
-VCLXAccessibleComponent::~VCLXAccessibleComponent()
+VCLXWindow* VCLXAccessibleComponent::GetVCLXWindow() const
{
- ensureDisposed();
+ return m_xVCLXWindow.get();
+}
- if ( mpVCLXindow && mpVCLXindow->GetWindow() )
+void VCLXAccessibleComponent::DisconnectEvents()
+{
+ if ( m_xEventSource )
{
- mpVCLXindow->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
- mpVCLXindow->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
+ m_xEventSource->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
+ m_xEventSource->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
+ m_xEventSource.clear();
}
+}
+
+VCLXAccessibleComponent::~VCLXAccessibleComponent()
+{
+ ensureDisposed();
+ DisconnectEvents();
delete m_pSolarLock;
m_pSolarLock = NULL;
@@ -104,13 +114,11 @@ uno::Sequence< OUString > VCLXAccessibleComponent::getSupportedServiceNames() th
IMPL_LINK( VCLXAccessibleComponent, WindowEventListener, VclSimpleEvent*, pEvent )
{
- DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
-
- /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper
- * might have been destroyed by the previous VCLEventListener (if no AT tool
- * is running), e.g. sub-toolbars in impress.
- */
- if ( pEvent && pEvent->ISA( VclWindowEvent ) && mxWindow.is() /* #122218# */ && (pEvent->GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) )
+ /* Ignore VCLEVENT_WINDOW_ENDPOPUPMODE, because the UNO accessibility wrapper
+ * might have been destroyed by the previous VCLEventListener (if no AT tool
+ * is running), e.g. sub-toolbars in impress.
+ */
+ if ( pEvent && pEvent->ISA( VclWindowEvent ) && m_xVCLXWindow.is() /* #122218# */ && (pEvent->GetId() != VCLEVENT_WINDOW_ENDPOPUPMODE) )
{
DBG_ASSERT( static_cast<VclWindowEvent*>(pEvent)->GetWindow(), "Window???" );
if( !static_cast<VclWindowEvent*>(pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() || ( pEvent->GetId() == VCLEVENT_OBJECT_DYING ) )
@@ -123,8 +131,7 @@ IMPL_LINK( VCLXAccessibleComponent, WindowEventListener, VclSimpleEvent*, pEvent
IMPL_LINK( VCLXAccessibleComponent, WindowChildEventListener, VclSimpleEvent*, pEvent )
{
- DBG_ASSERT( pEvent && pEvent->ISA( VclWindowEvent ), "Unknown WindowEvent!" );
- if ( pEvent && pEvent->ISA( VclWindowEvent ) && mxWindow.is() /* #i68079# */ )
+ if ( pEvent && pEvent->ISA( VclWindowEvent ) && m_xVCLXWindow.is() /* #i68079# */ )
{
DBG_ASSERT( static_cast<VclWindowEvent*>(pEvent)->GetWindow(), "Window???" );
if( !static_cast<VclWindowEvent*>(pEvent)->GetWindow()->IsAccessibilityEventsSuppressed() )
@@ -192,10 +199,8 @@ void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent& rVclWind
{
case VCLEVENT_OBJECT_DYING:
{
- pAccWindow->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
- pAccWindow->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
- mxWindow.clear();
- mpVCLXindow = NULL;
+ DisconnectEvents();
+ m_xVCLXWindow.clear();
}
break;
case VCLEVENT_WINDOW_CHILDDESTROYED:
@@ -344,16 +349,11 @@ void VCLXAccessibleComponent::ProcessWindowEvent( const VclWindowEvent& rVclWind
void VCLXAccessibleComponent::disposing()
{
- if ( mpVCLXindow && mpVCLXindow->GetWindow() )
- {
- mpVCLXindow->GetWindow()->RemoveEventListener( LINK( this, VCLXAccessibleComponent, WindowEventListener ) );
- mpVCLXindow->GetWindow()->RemoveChildEventListener( LINK( this, VCLXAccessibleComponent, WindowChildEventListener ) );
- }
+ DisconnectEvents();
AccessibleExtendedComponentHelper_BASE::disposing();
- mxWindow.clear();
- mpVCLXindow = NULL;
+ m_xVCLXWindow.clear();
}
VclPtr<vcl::Window> VCLXAccessibleComponent::GetWindow() const
@@ -770,8 +770,8 @@ void VCLXAccessibleComponent::grabFocus( ) throw (uno::RuntimeException, std::e
OExternalLockGuard aGuard( this );
uno::Reference< accessibility::XAccessibleStateSet > xStates = getAccessibleStateSet();
- if ( mxWindow.is() && xStates.is() && xStates->contains( accessibility::AccessibleStateType::FOCUSABLE ) )
- mxWindow->setFocus();
+ if ( m_xVCLXWindow.is() && xStates.is() && xStates->contains( accessibility::AccessibleStateType::FOCUSABLE ) )
+ m_xVCLXWindow->setFocus();
}
sal_Int32 SAL_CALL VCLXAccessibleComponent::getForeground( ) throw (uno::RuntimeException, std::exception)