xref: /AOO41X/main/comphelper/inc/comphelper/accessiblecontexthelper.hxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #ifndef COMPHELPER_ACCESSIBLE_CONTEXT_HELPER_HXX
29*cdf0e10cSrcweir #define COMPHELPER_ACCESSIBLE_CONTEXT_HELPER_HXX
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <cppuhelper/compbase2.hxx>
32*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleContext.hpp>
33*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/lang/DisposedException.hpp>
35*cdf0e10cSrcweir #include <comphelper/broadcasthelper.hxx>
36*cdf0e10cSrcweir #include "comphelper/comphelperdllapi.h"
37*cdf0e10cSrcweir 
38*cdf0e10cSrcweir //.........................................................................
39*cdf0e10cSrcweir namespace comphelper
40*cdf0e10cSrcweir {
41*cdf0e10cSrcweir //.........................................................................
42*cdf0e10cSrcweir 
43*cdf0e10cSrcweir     class AccessibleEventBuffer;
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir 	//=====================================================================
46*cdf0e10cSrcweir 	//= IMutex
47*cdf0e10cSrcweir 	//=====================================================================
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir 	// This whole thingie here (own mutex classes and such) is a HACK. I hate the SolarMutex.
50*cdf0e10cSrcweir 	// See below for more explanations ....
51*cdf0e10cSrcweir 
52*cdf0e10cSrcweir 	/** abstract interface for implementing a mutex
53*cdf0e10cSrcweir 	*/
54*cdf0e10cSrcweir 	class IMutex
55*cdf0e10cSrcweir 	{
56*cdf0e10cSrcweir 	public:
57*cdf0e10cSrcweir 		virtual void acquire() = 0;
58*cdf0e10cSrcweir 		virtual void release() = 0;
59*cdf0e10cSrcweir 	};
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir 	//=====================================================================
62*cdf0e10cSrcweir 	//= OMutexGuard
63*cdf0e10cSrcweir 	//=====================================================================
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir 	class OMutexGuard
66*cdf0e10cSrcweir 	{
67*cdf0e10cSrcweir 		IMutex*	m_pMutex;
68*cdf0e10cSrcweir 	public:
69*cdf0e10cSrcweir 		inline OMutexGuard( IMutex* _pMutex )
70*cdf0e10cSrcweir 			:m_pMutex( _pMutex )
71*cdf0e10cSrcweir 		{
72*cdf0e10cSrcweir 			if ( m_pMutex )
73*cdf0e10cSrcweir 				m_pMutex->acquire();
74*cdf0e10cSrcweir 		}
75*cdf0e10cSrcweir 
76*cdf0e10cSrcweir 		inline ~OMutexGuard( )
77*cdf0e10cSrcweir 		{
78*cdf0e10cSrcweir 			if ( m_pMutex )
79*cdf0e10cSrcweir 				m_pMutex->release();
80*cdf0e10cSrcweir 		}
81*cdf0e10cSrcweir 	};
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir 	//=====================================================================
84*cdf0e10cSrcweir 	//= OAccessibleContextHelper
85*cdf0e10cSrcweir 	//=====================================================================
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir 	class OContextHelper_Impl;
88*cdf0e10cSrcweir 	typedef	::cppu::WeakAggComponentImplHelper2	<	::com::sun::star::accessibility::XAccessibleContext,
89*cdf0e10cSrcweir 													::com::sun::star::accessibility::XAccessibleEventBroadcaster
90*cdf0e10cSrcweir 												>	OAccessibleContextHelper_Base;
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir 	/** helper class for implementing an AccessibleContext
93*cdf0e10cSrcweir 	*/
94*cdf0e10cSrcweir 	class COMPHELPER_DLLPUBLIC OAccessibleContextHelper
95*cdf0e10cSrcweir 				:public ::comphelper::OBaseMutex
96*cdf0e10cSrcweir 				,public OAccessibleContextHelper_Base
97*cdf0e10cSrcweir 	{
98*cdf0e10cSrcweir 	private:
99*cdf0e10cSrcweir 		OContextHelper_Impl*	m_pImpl;
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir 	protected:
102*cdf0e10cSrcweir 		OAccessibleContextHelper( );
103*cdf0e10cSrcweir 		~OAccessibleContextHelper( );
104*cdf0e10cSrcweir 
105*cdf0e10cSrcweir 		/** ctor
106*cdf0e10cSrcweir 
107*cdf0e10cSrcweir 			<p>If you need additional object safety for your class, and want to ensure that your own
108*cdf0e10cSrcweir 			mutex is locked before the mutex this class provides is, than use this ctor.</p>
109*cdf0e10cSrcweir 
110*cdf0e10cSrcweir 			<p>Beware that this is a hack. Unfortunately, OpenOffice.org has two different mutex hierarchies,
111*cdf0e10cSrcweir 			which are not compatible. In addition, wide parts of the code (especially VCL) is not thread-safe,
112*cdf0e10cSrcweir 			but instead relies on a <em>single global mutex</em>. As a consequence, components using
113*cdf0e10cSrcweir 			directly or indirectly such code need to care for this global mutex. Yes, this is as ugly as
114*cdf0e10cSrcweir 			anything.</p>
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir 			<p>Note that the external lock is used as additional lock, not as the only one. The own mutex of the
117*cdf0e10cSrcweir 			instance is used for internal actions, and every action which potentially involves external code
118*cdf0e10cSrcweir 			(for instance every call to a virtual method overridden by derivees) is <em>additionally</em> and
119*cdf0e10cSrcweir 			<em>first</em> guarded by with the external lock.</p>
120*cdf0e10cSrcweir 
121*cdf0e10cSrcweir 			<p>Beware of the lifetime of the lock - you must ensure that the lock exists at least as long as
122*cdf0e10cSrcweir 			the context does. A good approach to implement the lock may be to derive you own context
123*cdf0e10cSrcweir 			not only from OAccessibleContextHelper, but also from IMutex.</p>
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir 			<p>One more note. This lock is definately not used once the dtor is reached. Means whatever
126*cdf0e10cSrcweir 			the dtor implementation does, it does <em>not</em> guard the external lock. See this as a contract.
127*cdf0e10cSrcweir 			<br/>You should ensure the same thing for own derivees which do not supply the lock themself,
128*cdf0e10cSrcweir 			but get them from yet another derivee.</p>
129*cdf0e10cSrcweir 			@see forgetExternalLock
130*cdf0e10cSrcweir 		*/
131*cdf0e10cSrcweir 		OAccessibleContextHelper( IMutex* _pExternalLock );
132*cdf0e10cSrcweir 
133*cdf0e10cSrcweir 		/** late construction
134*cdf0e10cSrcweir 		@param _rxAccessible
135*cdf0e10cSrcweir 			the Accessible object which created this context.
136*cdf0e10cSrcweir 			<p>If your derived implementation implements the XAccessible (and does not follow the proposed
137*cdf0e10cSrcweir 			separation of XAccessible from XAccessibleContext), you may pass <code>this</code> here.</p>
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir 			<p>The object is hold weak, so it's life time is not affected.</p>
140*cdf0e10cSrcweir 
141*cdf0e10cSrcweir 			<p>The object is needed for performance reasons: for <method>getAccessibleIndexInParent</method>,
142*cdf0e10cSrcweir 			all children (which are XAccessible's theirself) of our parent have to be asked. If we know our
143*cdf0e10cSrcweir 			XAccessible, we can compare it with all the children, instead of asking all children for their
144*cdf0e10cSrcweir 			context and comparing this context with ourself.</p>
145*cdf0e10cSrcweir 		*/
146*cdf0e10cSrcweir 		void	lateInit( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >& _rxAccessible );
147*cdf0e10cSrcweir 
148*cdf0e10cSrcweir 		/** retrieves the creator previously set with <method>lateInit</method>
149*cdf0e10cSrcweir 		*/
150*cdf0e10cSrcweir 		::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >
151*cdf0e10cSrcweir 				getAccessibleCreator( ) const;
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir 		/** forgets the reference to the external lock, if present.
154*cdf0e10cSrcweir 
155*cdf0e10cSrcweir 			<p>This means any further locking will not be guard the external lock anymore, never.</p>
156*cdf0e10cSrcweir 
157*cdf0e10cSrcweir 			<p>To be used in derived classes which do not supply the external lock themself, but instead get
158*cdf0e10cSrcweir 			them passed from own derivees (or clients).</p>
159*cdf0e10cSrcweir 		*/
160*cdf0e10cSrcweir 		void	forgetExternalLock();
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir 	public:
163*cdf0e10cSrcweir 		// XAccessibleEventBroadcaster
164*cdf0e10cSrcweir         using WeakAggComponentImplHelperBase::addEventListener;
165*cdf0e10cSrcweir 		virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
166*cdf0e10cSrcweir         using WeakAggComponentImplHelperBase::removeEventListener;
167*cdf0e10cSrcweir 		virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException);
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir 		// XAccessibleContext - still waiting to be overwritten
170*cdf0e10cSrcweir 		virtual sal_Int32 SAL_CALL getAccessibleChildCount(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
171*cdf0e10cSrcweir 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) = 0;
172*cdf0e10cSrcweir 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
173*cdf0e10cSrcweir 		virtual sal_Int16 SAL_CALL getAccessibleRole(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
174*cdf0e10cSrcweir 		virtual ::rtl::OUString SAL_CALL getAccessibleDescription(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
175*cdf0e10cSrcweir 		virtual ::rtl::OUString SAL_CALL getAccessibleName(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
176*cdf0e10cSrcweir 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
177*cdf0e10cSrcweir 		virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet(  ) throw (::com::sun::star::uno::RuntimeException) = 0;
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir 		// XAccessibleContext - default implementations
180*cdf0e10cSrcweir 		/** default implementation for retrieving the index of this object within the parent
181*cdf0e10cSrcweir 			<p>This basic implementation here returns the index <code>i</code> of the child for which
182*cdf0e10cSrcweir 				<code>&lt;parent&gt;.getAccessibleChild( i )</code> equals our creator.</p>
183*cdf0e10cSrcweir 		*/
184*cdf0e10cSrcweir 		virtual sal_Int32 SAL_CALL getAccessibleIndexInParent(  ) throw (::com::sun::star::uno::RuntimeException);
185*cdf0e10cSrcweir 		/** default implementation for retrieving the locale
186*cdf0e10cSrcweir 			<p>This basic implementation returns the locale of the parent context,
187*cdf0e10cSrcweir 			as retrieved via getAccessibleParent()->getAccessibleContext.</p>
188*cdf0e10cSrcweir 		*/
189*cdf0e10cSrcweir 		virtual ::com::sun::star::lang::Locale SAL_CALL getLocale(  ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException);
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir 	public:
192*cdf0e10cSrcweir 		// helper struct for granting selective access rights
193*cdf0e10cSrcweir 		struct OAccessControl
194*cdf0e10cSrcweir 		{
195*cdf0e10cSrcweir 			friend class OContextEntryGuard;
196*cdf0e10cSrcweir 			friend class OContextHelper_Impl;
197*cdf0e10cSrcweir 			friend class OExternalLockGuard;
198*cdf0e10cSrcweir 		private:
199*cdf0e10cSrcweir 			OAccessControl() { }
200*cdf0e10cSrcweir 		};
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir 		// ensures that the object is alive
203*cdf0e10cSrcweir 		inline	void			ensureAlive( const OAccessControl& ) const SAL_THROW( ( ::com::sun::star::lang::DisposedException ) );
204*cdf0e10cSrcweir 		inline	IMutex*			getExternalLock( const OAccessControl& );
205*cdf0e10cSrcweir 		inline	::osl::Mutex&	GetMutex( const OAccessControl& );
206*cdf0e10cSrcweir 
207*cdf0e10cSrcweir 	protected:
208*cdf0e10cSrcweir 		// OComponentHelper
209*cdf0e10cSrcweir 		virtual void SAL_CALL disposing();
210*cdf0e10cSrcweir 
211*cdf0e10cSrcweir 	protected:
212*cdf0e10cSrcweir 		// helper
213*cdf0e10cSrcweir 		/** notifies all AccessibleEventListeners of a certain event
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir 		@precond	not too be called with our mutex locked
216*cdf0e10cSrcweir 		@param	_nEventId
217*cdf0e10cSrcweir 			the id of the even. See AccessibleEventType
218*cdf0e10cSrcweir 		@param	_rOldValue
219*cdf0e10cSrcweir 			the old value to be notified
220*cdf0e10cSrcweir 		@param	_rNewValue
221*cdf0e10cSrcweir 			the new value to be notified
222*cdf0e10cSrcweir 		*/
223*cdf0e10cSrcweir 		virtual void SAL_CALL	NotifyAccessibleEvent(
224*cdf0e10cSrcweir 					const sal_Int16 _nEventId,
225*cdf0e10cSrcweir 					const ::com::sun::star::uno::Any& _rOldValue,
226*cdf0e10cSrcweir 					const ::com::sun::star::uno::Any& _rNewValue
227*cdf0e10cSrcweir 				);
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir 		/** records a certain event so that all AccessibleEventListeners can
230*cdf0e10cSrcweir             be notified later on.
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir             Can even be called with our mutex locked.
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir 		@param	_nEventId
235*cdf0e10cSrcweir 			the id of the even. See AccessibleEventType
236*cdf0e10cSrcweir 		@param	_rOldValue
237*cdf0e10cSrcweir 			the old value to be notified
238*cdf0e10cSrcweir 		@param	_rNewValue
239*cdf0e10cSrcweir 			the new value to be notified
240*cdf0e10cSrcweir         @param  _rBuffer
241*cdf0e10cSrcweir             the buffer that records the event
242*cdf0e10cSrcweir 		*/
243*cdf0e10cSrcweir 		virtual void SAL_CALL	BufferAccessibleEvent(
244*cdf0e10cSrcweir 					const sal_Int16 _nEventId,
245*cdf0e10cSrcweir 					const ::com::sun::star::uno::Any& _rOldValue,
246*cdf0e10cSrcweir 					const ::com::sun::star::uno::Any& _rNewValue,
247*cdf0e10cSrcweir                     AccessibleEventBuffer & _rBuffer
248*cdf0e10cSrcweir 				);
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir 		// life time control
251*cdf0e10cSrcweir 		/// checks whether the object is alive (returns <TRUE/> then) or disposed
252*cdf0e10cSrcweir 		sal_Bool	isAlive() const;
253*cdf0e10cSrcweir 		/// checks for beeing alive. If the object is already disposed (i.e. not alive), an exception is thrown.
254*cdf0e10cSrcweir 		void		ensureAlive() const SAL_THROW( ( ::com::sun::star::lang::DisposedException ) );
255*cdf0e10cSrcweir 
256*cdf0e10cSrcweir 		/** ensures that the object is disposed.
257*cdf0e10cSrcweir 		@precond
258*cdf0e10cSrcweir 			to be called from within the destructor of your derived class only!
259*cdf0e10cSrcweir 		*/
260*cdf0e10cSrcweir 		void		ensureDisposed( );
261*cdf0e10cSrcweir 
262*cdf0e10cSrcweir 		/** shortcut for retrieving the context of the parent (returned by getAccessibleParent)
263*cdf0e10cSrcweir 		*/
264*cdf0e10cSrcweir 		::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >
265*cdf0e10cSrcweir 					implGetParentContext() SAL_THROW( ( ::com::sun::star::uno::RuntimeException ) );
266*cdf0e10cSrcweir 
267*cdf0e10cSrcweir 		// access to the base class' broadcast helper/mutex
268*cdf0e10cSrcweir 		::cppu::OBroadcastHelper&		GetBroadcastHelper()		{ return rBHelper; }
269*cdf0e10cSrcweir 		const ::cppu::OBroadcastHelper&	GetBroadcastHelper() const	{ return rBHelper; }
270*cdf0e10cSrcweir 		::osl::Mutex&					GetMutex()					{ return m_aMutex; }
271*cdf0e10cSrcweir 		IMutex*							getExternalLock( );
272*cdf0e10cSrcweir 	};
273*cdf0e10cSrcweir 
274*cdf0e10cSrcweir 	//---------------------------------------------------------------------
275*cdf0e10cSrcweir 	inline	void OAccessibleContextHelper::ensureAlive( const OAccessControl& ) const SAL_THROW( ( ::com::sun::star::lang::DisposedException ) )
276*cdf0e10cSrcweir 	{
277*cdf0e10cSrcweir 		ensureAlive();
278*cdf0e10cSrcweir 	}
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir 	//---------------------------------------------------------------------
281*cdf0e10cSrcweir 	inline	IMutex* OAccessibleContextHelper::getExternalLock( const OAccessControl& )
282*cdf0e10cSrcweir 	{
283*cdf0e10cSrcweir 		return getExternalLock();
284*cdf0e10cSrcweir 	}
285*cdf0e10cSrcweir 
286*cdf0e10cSrcweir 	//---------------------------------------------------------------------
287*cdf0e10cSrcweir 	inline	::osl::Mutex& OAccessibleContextHelper::GetMutex( const OAccessControl& )
288*cdf0e10cSrcweir 	{
289*cdf0e10cSrcweir 		return GetMutex();
290*cdf0e10cSrcweir 	}
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir 	//=====================================================================
293*cdf0e10cSrcweir 	//= OContextEntryGuard
294*cdf0e10cSrcweir 	//=====================================================================
295*cdf0e10cSrcweir 	typedef ::osl::ClearableMutexGuard	OContextEntryGuard_Base;
296*cdf0e10cSrcweir 	/** helper class for guarding the entry into OAccessibleContextHelper methods.
297*cdf0e10cSrcweir 
298*cdf0e10cSrcweir 		<p>The class has two responsibilities:
299*cdf0e10cSrcweir 		<ul><li>it locks the mutex of an OAccessibleContextHelper instance, as long as the guard lives</li>
300*cdf0e10cSrcweir 			<li>it checks if an given OAccessibleContextHelper instance is alive, else an exception is thrown
301*cdf0e10cSrcweir 				our of the constructor of the guard</li>
302*cdf0e10cSrcweir 		</ul>
303*cdf0e10cSrcweir 		<br/>
304*cdf0e10cSrcweir 		This makes it your first choice (hopefully :) for guarding any interface method implementations of
305*cdf0e10cSrcweir 		you derived class.
306*cdf0e10cSrcweir 		</p>
307*cdf0e10cSrcweir 	*/
308*cdf0e10cSrcweir 	class OContextEntryGuard : public OContextEntryGuard_Base
309*cdf0e10cSrcweir 	{
310*cdf0e10cSrcweir 	public:
311*cdf0e10cSrcweir 		/** constructs the guard
312*cdf0e10cSrcweir 
313*cdf0e10cSrcweir 			<p>The given context (it's mutex, respectively) is locked, and an exception is thrown if the context
314*cdf0e10cSrcweir 			is not alive anymore. In the latter case, of course, the mutex is freed, again.</p>
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir 		@param _pContext
317*cdf0e10cSrcweir 			the context which shall be guarded
318*cdf0e10cSrcweir 		@precond <arg>_pContext</arg> != NULL
319*cdf0e10cSrcweir 		*/
320*cdf0e10cSrcweir 		inline OContextEntryGuard( OAccessibleContextHelper* _pContext );
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir 		/** destructs the guard.
323*cdf0e10cSrcweir 			<p>The context (it's mutex, respectively) is unlocked.</p>
324*cdf0e10cSrcweir 		*/
325*cdf0e10cSrcweir 		inline ~OContextEntryGuard();
326*cdf0e10cSrcweir 	};
327*cdf0e10cSrcweir 
328*cdf0e10cSrcweir 	//.....................................................................
329*cdf0e10cSrcweir 	inline OContextEntryGuard::OContextEntryGuard( OAccessibleContextHelper* _pContext  )
330*cdf0e10cSrcweir 		:OContextEntryGuard_Base( _pContext->GetMutex( OAccessibleContextHelper::OAccessControl() ) )
331*cdf0e10cSrcweir 	{
332*cdf0e10cSrcweir 		_pContext->ensureAlive( OAccessibleContextHelper::OAccessControl() );
333*cdf0e10cSrcweir 	}
334*cdf0e10cSrcweir 
335*cdf0e10cSrcweir 	//.....................................................................
336*cdf0e10cSrcweir 	inline OContextEntryGuard::~OContextEntryGuard()
337*cdf0e10cSrcweir 	{
338*cdf0e10cSrcweir 	}
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir 	//=====================================================================
341*cdf0e10cSrcweir 	//= OExternalLockGuard
342*cdf0e10cSrcweir 	//=====================================================================
343*cdf0e10cSrcweir 	class OExternalLockGuard
344*cdf0e10cSrcweir 			:public OMutexGuard
345*cdf0e10cSrcweir 			,public OContextEntryGuard
346*cdf0e10cSrcweir 	{
347*cdf0e10cSrcweir 	public:
348*cdf0e10cSrcweir 		inline OExternalLockGuard( OAccessibleContextHelper* _pContext );
349*cdf0e10cSrcweir 		inline ~OExternalLockGuard( );
350*cdf0e10cSrcweir 	};
351*cdf0e10cSrcweir 
352*cdf0e10cSrcweir 	//.....................................................................
353*cdf0e10cSrcweir 	inline OExternalLockGuard::OExternalLockGuard( OAccessibleContextHelper* _pContext )
354*cdf0e10cSrcweir 		:OMutexGuard( _pContext->getExternalLock( OAccessibleContextHelper::OAccessControl() ) )
355*cdf0e10cSrcweir 		,OContextEntryGuard( _pContext )
356*cdf0e10cSrcweir 	{
357*cdf0e10cSrcweir 		// #102438#
358*cdf0e10cSrcweir 		// Only lock the external mutex,
359*cdf0e10cSrcweir 		// release the ::osl::Mutex of the OAccessibleContextHelper instance.
360*cdf0e10cSrcweir 		// If you call into another UNO object with locked ::osl::Mutex,
361*cdf0e10cSrcweir 		// this may lead to dead locks.
362*cdf0e10cSrcweir 		clear();
363*cdf0e10cSrcweir 	}
364*cdf0e10cSrcweir 
365*cdf0e10cSrcweir 	//.....................................................................
366*cdf0e10cSrcweir 	inline OExternalLockGuard::~OExternalLockGuard( )
367*cdf0e10cSrcweir 	{
368*cdf0e10cSrcweir 	}
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir //.........................................................................
371*cdf0e10cSrcweir }	// namespace comphelper
372*cdf0e10cSrcweir //.........................................................................
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir #endif // COMPHELPER_ACCESSIBLE_CONTEXT_HELPER_HXX
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir 
377