LibreOffice Module comphelper (master) 1
accessiblecomponenthelper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
22#include <osl/diagnose.h>
23#include <com/sun/star/accessibility/IllegalAccessibleComponentStateException.hpp>
26
27
28namespace comphelper
29{
30
31
32 using namespace ::com::sun::star;
33 using namespace ::com::sun::star::uno;
34 using namespace ::com::sun::star::lang;
35 using namespace ::com::sun::star::accessibility;
36
39 ,m_nClientId( 0 )
40 {
41 }
42
43
45 {
46 // this ensures that the lock, which may be already destroyed as part of the derivee,
47 // is not used anymore
48
50 }
51
52
54 {
55 // rhbz#1001768: de facto this class is locked by SolarMutex;
56 // do not lock m_Mutex because it may cause deadlock
57 osl::Guard<SolarMutex> aGuard(SolarMutex::get());
58
59 if ( m_nClientId )
60 {
63 }
64 }
65
66
67 void SAL_CALL OCommonAccessibleComponent::addAccessibleEventListener( const Reference< XAccessibleEventListener >& _rxListener )
68 {
69 osl::Guard<SolarMutex> aGuard(SolarMutex::get());
70 // don't use the OContextEntryGuard - it will throw an exception if we're not alive
71 // anymore, while the most recent specification for XComponent states that we should
72 // silently ignore the call in such a situation
73 if ( !isAlive() )
74 {
75 if ( _rxListener.is() )
76 _rxListener->disposing( EventObject( *this ) );
77 return;
78 }
79
80 if ( _rxListener.is() )
81 {
82 if ( !m_nClientId )
84
86 }
87 }
88
89
90 void SAL_CALL OCommonAccessibleComponent::removeAccessibleEventListener( const Reference< XAccessibleEventListener >& _rxListener )
91 {
92 osl::Guard<SolarMutex> aGuard(SolarMutex::get());
93 // don't use the OContextEntryGuard - it will throw an exception if we're not alive
94 // anymore, while the most recent specification for XComponent states that we should
95 // silently ignore the call in such a situation
96 if ( !isAlive() )
97 return;
98
99 if ( !(_rxListener.is() && m_nClientId) )
100 return;
101
102 sal_Int32 nListenerCount = AccessibleEventNotifier::removeEventListener( m_nClientId, _rxListener );
103 if ( !nListenerCount )
104 {
105 // no listeners anymore
106 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
107 // and at least to us not firing any events anymore, in case somebody calls
108 // NotifyAccessibleEvent, again
110 m_nClientId = 0;
111 }
112 }
113
114
116 const Any& _rOldValue, const Any& _rNewValue, sal_Int32 nIndexHint )
117 {
118 if ( !m_nClientId )
119 // if we don't have a client id for the notifier, then we don't have listeners, then
120 // we don't need to notify anything
121 return;
122
123 // build an event object
124 AccessibleEventObject aEvent(*this, _nEventId, _rNewValue, _rOldValue, nIndexHint);
125
126 // let the notifier handle this event
128 }
129
130
132 {
133 return !rBHelper.bDisposed && !rBHelper.bInDispose;
134 }
135
136
138 {
139 if( !isAlive() )
140 throw DisposedException();
141 }
142
143
145 {
146 if ( !rBHelper.bDisposed )
147 {
148 OSL_ENSURE( 0 == m_refCount, "OCommonAccessibleComponent::ensureDisposed: this method _has_ to be called from without your dtor only!" );
149 acquire();
150 dispose();
151 }
152 }
153
154
155 void OCommonAccessibleComponent::lateInit( const Reference< XAccessible >& _rxAccessible )
156 {
157 m_aCreator = _rxAccessible;
158 }
159
160
161 Reference< XAccessible > OCommonAccessibleComponent::getAccessibleCreator( ) const
162 {
163 return m_aCreator;
164 }
165
166
168 {
169 return OUString();
170 }
171
172
174 {
175 OExternalLockGuard aGuard( this );
176
177 // -1 for child not found/no parent (according to specification)
178 sal_Int64 nRet = -1;
179
180 try
181 {
182
183 Reference< XAccessibleContext > xParentContext( implGetParentContext() );
184
185 // iterate over parent's children and search for this object
186 if ( xParentContext.is() )
187 {
188 // our own XAccessible for comparing with the children of our parent
189 Reference< XAccessible > xCreator( m_aCreator);
190
191 OSL_ENSURE( xCreator.is(), "OCommonAccessibleComponent::getAccessibleIndexInParent: invalid creator!" );
192 // two ideas why this could be NULL:
193 // * nobody called our late ctor (init), so we never had a creator at all -> bad
194 // * the creator is already dead. In this case, we should have been disposed, and
195 // never survived the above OContextEntryGuard.
196 // in all other situations the creator should be non-NULL
197
198 if ( xCreator.is() )
199 {
200 sal_Int64 nChildCount = xParentContext->getAccessibleChildCount();
201 for ( sal_Int64 nChild = 0; ( nChild < nChildCount ) && ( -1 == nRet ); ++nChild )
202 {
203 Reference< XAccessible > xChild( xParentContext->getAccessibleChild( nChild ) );
204 if ( xChild.get() == xCreator.get() )
205 nRet = nChild;
206 }
207 }
208 }
209 }
210 catch( const Exception& )
211 {
212 OSL_FAIL( "OCommonAccessibleComponent::getAccessibleIndexInParent: caught an exception!" );
213 }
214
215 return nRet;
216 }
217
218
220 {
221 // simply ask the parent
222 Reference< XAccessible > xParent = getAccessibleParent();
223 Reference< XAccessibleContext > xParentContext;
224 if ( xParent.is() )
225 xParentContext = xParent->getAccessibleContext();
226
227 if ( !xParentContext.is() )
228 throw IllegalAccessibleComponentStateException( OUString(), *this );
229
230 return xParentContext->getLocale();
231 }
232
233
234 Reference< XAccessibleContext > OCommonAccessibleComponent::implGetParentContext()
235 {
236 Reference< XAccessible > xParent = getAccessibleParent();
237 Reference< XAccessibleContext > xParentContext;
238 if ( xParent.is() )
239 xParentContext = xParent->getAccessibleContext();
240 return xParentContext;
241 }
242
243
244 bool OCommonAccessibleComponent::containsPoint( const awt::Point& _rPoint )
245 {
246 OExternalLockGuard aGuard( this );
247 awt::Rectangle aBounds( implGetBounds() );
248 return ( _rPoint.X >= 0 )
249 && ( _rPoint.Y >= 0 )
250 && ( _rPoint.X < aBounds.Width )
251 && ( _rPoint.Y < aBounds.Height );
252 }
253
254
256 {
257 OExternalLockGuard aGuard( this );
258 awt::Rectangle aBounds( implGetBounds() );
259 return awt::Point( aBounds.X, aBounds.Y );
260 }
261
262
264 {
265 OExternalLockGuard aGuard( this );
266
267 awt::Point aScreenLoc( 0, 0 );
268
269 Reference< XAccessibleComponent > xParentComponent( implGetParentContext(), UNO_QUERY );
270 OSL_ENSURE( xParentComponent.is(), "OCommonAccessibleComponent::getLocationOnScreen: no parent component!" );
271 if ( xParentComponent.is() )
272 {
273 awt::Point aParentScreenLoc( xParentComponent->getLocationOnScreen() );
274 awt::Point aOwnRelativeLoc( getLocation() );
275 aScreenLoc.X = aParentScreenLoc.X + aOwnRelativeLoc.X;
276 aScreenLoc.Y = aParentScreenLoc.Y + aOwnRelativeLoc.Y;
277 }
278
279 return aScreenLoc;
280 }
281
282
284 {
285 OExternalLockGuard aGuard( this );
286 awt::Rectangle aBounds( implGetBounds() );
287 return awt::Size( aBounds.Width, aBounds.Height );
288 }
289
290
292 {
293 OExternalLockGuard aGuard( this );
294 return implGetBounds();
295 }
296
298 {
299 }
300
301
302 sal_Bool SAL_CALL OAccessibleComponentHelper::containsPoint( const awt::Point& _rPoint )
303 {
305 }
306
307
309 {
311 }
312
313
315 {
317 }
318
319
321 {
323 }
324
325
326 awt::Rectangle SAL_CALL OAccessibleComponentHelper::getBounds( )
327 {
329 }
330
332 {
333 }
334
335
337 {
339 }
340
341
343 {
345 }
346
347
349 {
351 }
352
353
355 {
357 }
358
359
361 {
363 }
364
365
366} // namespace comphelper
367
368
369/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
static sal_Int32 addEventListener(const TClientId _nClient, const css::uno::Reference< css::accessibility::XAccessibleEventListener > &_rxListener)
registers a listener for the given client
static void addEvent(const TClientId _nClient, const css::accessibility::AccessibleEventObject &_rEvent)
adds an event, which is to be broadcasted, to the queue
static sal_Int32 removeEventListener(const TClientId _nClient, const css::uno::Reference< css::accessibility::XAccessibleEventListener > &_rxListener)
revokes a listener for the given client
static TClientId registerClient()
registers a client of this class, means a broadcaster of AccessibleEvents
static void revokeClient(const TClientId _nClient)
revokes a broadcaster of AccessibleEvents
static void revokeClientNotifyDisposing(const TClientId _nClient, const css::uno::Reference< css::uno::XInterface > &_rxEventSource)
revokes a client, with additionally notifying a disposing event to all listeners registered for this ...
virtual sal_Bool SAL_CALL containsPoint(const css::awt::Point &aPoint) override
virtual css::awt::Point SAL_CALL getLocationOnScreen() override
virtual css::awt::Size SAL_CALL getSize() override
virtual css::awt::Point SAL_CALL getLocation() override
virtual css::awt::Rectangle SAL_CALL getBounds() override
virtual css::awt::Point SAL_CALL getLocation() override
virtual css::awt::Rectangle SAL_CALL getBounds() override
virtual sal_Bool SAL_CALL containsPoint(const css::awt::Point &aPoint) override
virtual css::awt::Size SAL_CALL getSize() override
virtual css::awt::Point SAL_CALL getLocationOnScreen() override
virtual OUString SAL_CALL getAccessibleId() override
void lateInit(const css::uno::Reference< css::accessibility::XAccessible > &_rxAccessible)
late construction
virtual css::awt::Rectangle implGetBounds()=0
implements the calculation of the bounding rectangle - still waiting to be overwritten
virtual void SAL_CALL removeAccessibleEventListener(const css::uno::Reference< css::accessibility::XAccessibleEventListener > &xListener) override
virtual sal_Int64 SAL_CALL getAccessibleIndexInParent() override
default implementation for retrieving the index of this object within the parent
css::uno::WeakReference< css::accessibility::XAccessible > m_aCreator
virtual void SAL_CALL disposing() override
css::uno::Reference< css::accessibility::XAccessibleContext > implGetParentContext()
shortcut for retrieving the context of the parent (returned by getAccessibleParent)
void NotifyAccessibleEvent(const sal_Int16 _nEventId, const css::uno::Any &_rOldValue, const css::uno::Any &_rNewValue, sal_Int32 nIndexHint=-1)
notifies all AccessibleEventListeners of a certain event
bool containsPoint(const css::awt::Point &aPoint)
non-virtual versions of the methods which can be implemented using <method>implGetBounds</method> not...
virtual css::lang::Locale SAL_CALL getLocale() override
default implementation for retrieving the locale
AccessibleEventNotifier::TClientId m_nClientId
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent() override=0
void ensureAlive() const
checks for being alive. If the object is already disposed (i.e. not alive), an exception is thrown.
bool isAlive() const
checks whether the object is alive (returns <TRUE> then) or disposed
virtual void SAL_CALL addAccessibleEventListener(const css::uno::Reference< css::accessibility::XAccessibleEventListener > &xListener) override
void ensureDisposed()
ensures that the object is disposed.
css::uno::Reference< css::accessibility::XAccessible > getAccessibleCreator() const
retrieves the creator previously set with <method>lateInit</method>
static SolarMutex * get()
Help components to get the SolarMutex easily.
Definition: solarmutex.cxx:34
ULONG m_refCount
@ Exception
::cppu::WeakComponentImplHelper< css::accessibility::XAccessibleContext2, css::accessibility::XAccessibleEventBroadcaster > OCommonAccessibleComponent_Base
void dispose()
unsigned char sal_Bool