1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_accessibility.hxx"
26 #include "accessibility/extended/AccessibleGridControlBase.hxx"
27 #include <svtools/accessibletable.hxx>
28 #include <rtl/uuid.h>
29 //
30 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
31 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
32 #include <unotools/accessiblerelationsethelper.hxx>
33
34 // ============================================================================
35
36 using ::rtl::OUString;
37
38 using ::com::sun::star::uno::Reference;
39 using ::com::sun::star::uno::Sequence;
40 using ::com::sun::star::uno::Any;
41
42 using namespace ::com::sun::star;
43 using namespace ::com::sun::star::accessibility;
44 using namespace ::comphelper;
45 using namespace ::svt;
46 using namespace ::svt::table;
47
48
49 // ============================================================================
50
51 namespace accessibility {
52
53 using namespace com::sun::star::accessibility::AccessibleStateType;
54 // ============================================================================
55
DBG_NAME(AccessibleGridControlBase)56 DBG_NAME( AccessibleGridControlBase )
57
58 AccessibleGridControlBase::AccessibleGridControlBase(
59 const Reference< XAccessible >& rxParent,
60 svt::table::IAccessibleTable& rTable,
61 AccessibleTableControlObjType eObjType ) :
62 AccessibleGridControlImplHelper( m_aMutex ),
63 m_xParent( rxParent ),
64 m_aTable( rTable),
65 m_eObjType( eObjType ),
66 m_aName( rTable.GetAccessibleObjectName( eObjType, 0, 0 ) ),
67 m_aDescription( rTable.GetAccessibleObjectDescription( eObjType ) ),
68 m_aClientId(0)
69 {
70 }
71
~AccessibleGridControlBase()72 AccessibleGridControlBase::~AccessibleGridControlBase()
73 {
74 if( isAlive() )
75 {
76 // increment ref count to prevent double call of Dtor
77 osl_incrementInterlockedCount( &m_refCount );
78 dispose();
79 }
80 }
81
disposing()82 void SAL_CALL AccessibleGridControlBase::disposing()
83 {
84 ::osl::MutexGuard aGuard( getOslMutex() );
85
86 if ( getClientId( ) )
87 {
88 AccessibleEventNotifier::TClientId nId( getClientId( ) );
89 setClientId( 0 );
90 AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this );
91 }
92
93 m_xParent = NULL;
94 //m_aTable = NULL;
95 }
96
97 // XAccessibleContext ---------------------------------------------------------
98
getAccessibleParent()99 Reference< XAccessible > SAL_CALL AccessibleGridControlBase::getAccessibleParent()
100 throw ( uno::RuntimeException )
101 {
102 ::osl::MutexGuard aGuard( getOslMutex() );
103 ensureIsAlive();
104 return m_xParent;
105 }
106
getAccessibleIndexInParent()107 sal_Int32 SAL_CALL AccessibleGridControlBase::getAccessibleIndexInParent()
108 throw ( uno::RuntimeException )
109 {
110 ::osl::MutexGuard aGuard( getOslMutex() );
111 ensureIsAlive();
112
113 // -1 for child not found/no parent (according to specification)
114 sal_Int32 nRet = -1;
115
116 Reference< uno::XInterface > xMeMyselfAndI( static_cast< XAccessibleContext* >( this ), uno::UNO_QUERY );
117
118 // iterate over parent's children and search for this object
119 if( m_xParent.is() )
120 {
121 Reference< XAccessibleContext >
122 xParentContext( m_xParent->getAccessibleContext() );
123 if( xParentContext.is() )
124 {
125 Reference< uno::XInterface > xChild;
126
127 sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
128 for( sal_Int32 nChild = 0; nChild < nChildCount; ++nChild )
129 {
130 xChild = xChild.query( xParentContext->getAccessibleChild( nChild ) );
131 if ( xMeMyselfAndI.get() == xChild.get() )
132 {
133 nRet = nChild;
134 break;
135 }
136 }
137 }
138 }
139 return nRet;
140 }
141
getAccessibleDescription()142 OUString SAL_CALL AccessibleGridControlBase::getAccessibleDescription()
143 throw ( uno::RuntimeException )
144 {
145 ::osl::MutexGuard aGuard( getOslMutex() );
146 ensureIsAlive();
147 return m_aDescription;
148 }
149
getAccessibleName()150 OUString SAL_CALL AccessibleGridControlBase::getAccessibleName()
151 throw ( uno::RuntimeException )
152 {
153 ::osl::MutexGuard aGuard( getOslMutex() );
154 ensureIsAlive();
155 return m_aName;
156 }
157
158 Reference< XAccessibleRelationSet > SAL_CALL
getAccessibleRelationSet()159 AccessibleGridControlBase::getAccessibleRelationSet()
160 throw ( uno::RuntimeException )
161 {
162 ensureIsAlive();
163 // GridControl does not have relations.
164 return new utl::AccessibleRelationSetHelper;
165 }
166
167 Reference< XAccessibleStateSet > SAL_CALL
getAccessibleStateSet()168 AccessibleGridControlBase::getAccessibleStateSet()
169 throw ( uno::RuntimeException )
170 {
171 TCSolarGuard aSolarGuard;
172 ::osl::MutexGuard aGuard( getOslMutex() );
173 // don't check whether alive -> StateSet may contain DEFUNC
174 return implCreateStateSetHelper();
175 }
176
getLocale()177 lang::Locale SAL_CALL AccessibleGridControlBase::getLocale()
178 throw ( IllegalAccessibleComponentStateException, uno::RuntimeException )
179 {
180 ::osl::MutexGuard aGuard( getOslMutex() );
181 ensureIsAlive();
182 if( m_xParent.is() )
183 {
184 Reference< XAccessibleContext >
185 xParentContext( m_xParent->getAccessibleContext() );
186 if( xParentContext.is() )
187 return xParentContext->getLocale();
188 }
189 throw IllegalAccessibleComponentStateException();
190 }
191
192 // XAccessibleComponent -------------------------------------------------------
193
containsPoint(const awt::Point & rPoint)194 sal_Bool SAL_CALL AccessibleGridControlBase::containsPoint( const awt::Point& rPoint )
195 throw ( uno::RuntimeException )
196 {
197 return Rectangle( Point(), getBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint ) );
198 }
199
getBounds()200 awt::Rectangle SAL_CALL AccessibleGridControlBase::getBounds()
201 throw ( uno::RuntimeException )
202 {
203 return AWTRectangle( getBoundingBox() );
204 }
205
getLocation()206 awt::Point SAL_CALL AccessibleGridControlBase::getLocation()
207 throw ( uno::RuntimeException )
208 {
209 return AWTPoint( getBoundingBox().TopLeft() );
210 }
211
getLocationOnScreen()212 awt::Point SAL_CALL AccessibleGridControlBase::getLocationOnScreen()
213 throw ( uno::RuntimeException )
214 {
215 return AWTPoint( getBoundingBoxOnScreen().TopLeft() );
216 }
217
getSize()218 awt::Size SAL_CALL AccessibleGridControlBase::getSize()
219 throw ( uno::RuntimeException )
220 {
221 return AWTSize( getBoundingBox().GetSize() );
222 }
223
isShowing()224 sal_Bool SAL_CALL AccessibleGridControlBase::isShowing()
225 throw ( uno::RuntimeException )
226 {
227 TCSolarGuard aSolarGuard;
228 ::osl::MutexGuard aGuard( getOslMutex() );
229 ensureIsAlive();
230 return implIsShowing();
231 }
232
isVisible()233 sal_Bool SAL_CALL AccessibleGridControlBase::isVisible()
234 throw ( uno::RuntimeException )
235 {
236 Reference< XAccessibleStateSet > xStateSet = getAccessibleStateSet();
237 return xStateSet.is() ?
238 xStateSet->contains( AccessibleStateType::VISIBLE ) : sal_False;
239 }
240
isFocusTraversable()241 sal_Bool SAL_CALL AccessibleGridControlBase::isFocusTraversable()
242 throw ( uno::RuntimeException )
243 {
244 Reference< XAccessibleStateSet > xStateSet = getAccessibleStateSet();
245 return xStateSet.is() ?
246 xStateSet->contains( AccessibleStateType::FOCUSABLE ) : sal_False;
247 }
248 // XAccessibleEventBroadcaster ------------------------------------------------
249
addEventListener(const Reference<XAccessibleEventListener> & _rxListener)250 void SAL_CALL AccessibleGridControlBase::addEventListener(
251 const Reference< XAccessibleEventListener>& _rxListener )
252 throw ( uno::RuntimeException )
253 {
254 if ( _rxListener.is() )
255 {
256 ::osl::MutexGuard aGuard( getOslMutex() );
257 if ( !getClientId( ) )
258 setClientId( AccessibleEventNotifier::registerClient( ) );
259
260 AccessibleEventNotifier::addEventListener( getClientId( ), _rxListener );
261 }
262 }
263
removeEventListener(const Reference<XAccessibleEventListener> & _rxListener)264 void SAL_CALL AccessibleGridControlBase::removeEventListener(
265 const Reference< XAccessibleEventListener>& _rxListener )
266 throw ( uno::RuntimeException )
267 {
268 if( _rxListener.is() && getClientId( ) )
269 {
270 ::osl::MutexGuard aGuard( getOslMutex() );
271 sal_Int32 nListenerCount = AccessibleEventNotifier::removeEventListener( getClientId( ), _rxListener );
272 if ( !nListenerCount )
273 {
274 // no listeners anymore
275 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
276 // and at least to us not firing any events anymore, in case somebody calls
277 // NotifyAccessibleEvent, again
278 AccessibleEventNotifier::TClientId nId( getClientId( ) );
279 setClientId( 0 );
280 AccessibleEventNotifier::revokeClient( nId );
281 }
282 }
283 }
284
285 // XTypeProvider --------------------------------------------------------------
286
getImplementationId()287 Sequence< sal_Int8 > SAL_CALL AccessibleGridControlBase::getImplementationId()
288 throw ( uno::RuntimeException )
289 {
290 ::osl::MutexGuard aGuard( getOslGlobalMutex() );
291 static Sequence< sal_Int8 > aId;
292 implCreateUuid( aId );
293 return aId;
294 }
295
296 // XServiceInfo ---------------------------------------------------------------
297
supportsService(const OUString & rServiceName)298 sal_Bool SAL_CALL AccessibleGridControlBase::supportsService(
299 const OUString& rServiceName )
300 throw ( uno::RuntimeException )
301 {
302 ::osl::MutexGuard aGuard( getOslMutex() );
303
304 Sequence< OUString > aSupportedServices( getSupportedServiceNames() );
305 const OUString* pArrBegin = aSupportedServices.getConstArray();
306 const OUString* pArrEnd = pArrBegin + aSupportedServices.getLength();
307 const OUString* pString = pArrBegin;
308
309 for( ; ( pString != pArrEnd ) && ( rServiceName != *pString ); ++pString )
310 ;
311 return pString != pArrEnd;
312 }
313
getSupportedServiceNames()314 Sequence< OUString > SAL_CALL AccessibleGridControlBase::getSupportedServiceNames()
315 throw ( uno::RuntimeException )
316 {
317 const OUString aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) );
318 return Sequence< OUString >( &aServiceName, 1 );
319 }
320 // internal virtual methods ---------------------------------------------------
321
implIsShowing()322 sal_Bool AccessibleGridControlBase::implIsShowing()
323 {
324 sal_Bool bShowing = sal_False;
325 if( m_xParent.is() )
326 {
327 Reference< XAccessibleComponent >
328 xParentComp( m_xParent->getAccessibleContext(), uno::UNO_QUERY );
329 if( xParentComp.is() )
330 bShowing = implGetBoundingBox().IsOver(
331 VCLRectangle( xParentComp->getBounds() ) );
332 }
333 return bShowing;
334 }
335
implCreateStateSetHelper()336 ::utl::AccessibleStateSetHelper* AccessibleGridControlBase::implCreateStateSetHelper()
337 {
338 ::utl::AccessibleStateSetHelper*
339 pStateSetHelper = new ::utl::AccessibleStateSetHelper;
340
341 if( isAlive() )
342 {
343 // SHOWING done with m_xParent
344 if( implIsShowing() )
345 pStateSetHelper->AddState( AccessibleStateType::SHOWING );
346 // GridControl fills StateSet with states depending on object type
347 m_aTable.FillAccessibleStateSet( *pStateSetHelper, getType() );
348 }
349 else
350 pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
351 return pStateSetHelper;
352 }
353
354 // internal helper methods ----------------------------------------------------
355
isAlive() const356 sal_Bool AccessibleGridControlBase::isAlive() const
357 {
358 return !rBHelper.bDisposed && !rBHelper.bInDispose && &m_aTable;
359 }
360
ensureIsAlive() const361 void AccessibleGridControlBase::ensureIsAlive() const
362 throw ( lang::DisposedException )
363 {
364 if( !isAlive() )
365 throw lang::DisposedException();
366 }
367
getBoundingBox()368 Rectangle AccessibleGridControlBase::getBoundingBox()
369 throw ( lang::DisposedException )
370 {
371 TCSolarGuard aSolarGuard;
372 ::osl::MutexGuard aGuard( getOslMutex() );
373 ensureIsAlive();
374 Rectangle aRect = implGetBoundingBox();
375 if ( 0 == aRect.Left() && 0 == aRect.Top() && 0 == aRect.Right() && 0 == aRect.Bottom() )
376 {
377 DBG_ERRORFILE( "rectangle doesn't exist" );
378 }
379 return aRect;
380 }
381
getBoundingBoxOnScreen()382 Rectangle AccessibleGridControlBase::getBoundingBoxOnScreen()
383 throw ( lang::DisposedException )
384 {
385 TCSolarGuard aSolarGuard;
386 ::osl::MutexGuard aGuard( getOslMutex() );
387 ensureIsAlive();
388 Rectangle aRect = implGetBoundingBoxOnScreen();
389 if ( 0 == aRect.Left() && 0 == aRect.Top() && 0 == aRect.Right() && 0 == aRect.Bottom() )
390 {
391 DBG_ERRORFILE( "rectangle doesn't exist" );
392 }
393 return aRect;
394 }
395
commitEvent(sal_Int16 _nEventId,const Any & _rNewValue,const Any & _rOldValue)396 void AccessibleGridControlBase::commitEvent(
397 sal_Int16 _nEventId, const Any& _rNewValue, const Any& _rOldValue )
398 {
399 ::osl::ClearableMutexGuard aGuard( getOslMutex() );
400 if ( !getClientId( ) )
401 // if we don't have a client id for the notifier, then we don't have listeners, then
402 // we don't need to notify anything
403 return;
404
405 // build an event object
406 AccessibleEventObject aEvent;
407 aEvent.Source = *this;
408 aEvent.EventId = _nEventId;
409 aEvent.OldValue = _rOldValue;
410 aEvent.NewValue = _rNewValue;
411
412 // let the notifier handle this event
413
414 AccessibleEventNotifier::addEvent( getClientId( ), aEvent );
415 }
416 // -----------------------------------------------------------------------------
417
implCreateUuid(Sequence<sal_Int8> & rId)418 void AccessibleGridControlBase::implCreateUuid( Sequence< sal_Int8 >& rId )
419 {
420 if( !rId.hasElements() )
421 {
422 rId.realloc( 16 );
423 rtl_createUuid( reinterpret_cast< sal_uInt8* >( rId.getArray() ), 0, sal_True );
424 }
425 }
426 // -----------------------------------------------------------------------------
getAccessibleRole()427 sal_Int16 SAL_CALL AccessibleGridControlBase::getAccessibleRole()
428 throw ( uno::RuntimeException )
429 {
430 ensureIsAlive();
431 sal_Int16 nRole = AccessibleRole::UNKNOWN;
432 switch ( m_eObjType )
433 {
434 case TCTYPE_ROWHEADERCELL:
435 nRole = AccessibleRole::ROW_HEADER;
436 break;
437 case TCTYPE_COLUMNHEADERCELL:
438 nRole = AccessibleRole::COLUMN_HEADER;
439 break;
440 case TCTYPE_COLUMNHEADERBAR:
441 case TCTYPE_ROWHEADERBAR:
442 case TCTYPE_TABLE:
443 nRole = AccessibleRole::TABLE;
444 break;
445 case TCTYPE_TABLECELL:
446 nRole = AccessibleRole::TABLE_CELL;
447 break;
448 case TCTYPE_GRIDCONTROL:
449 nRole = AccessibleRole::PANEL;
450 break;
451 }
452 return nRole;
453 }
454 // -----------------------------------------------------------------------------
getAccessibleKeyBinding()455 Any SAL_CALL AccessibleGridControlBase::getAccessibleKeyBinding()
456 throw ( uno::RuntimeException )
457 {
458 return Any();
459 }
460 // -----------------------------------------------------------------------------
getAccessibleAtPoint(const::com::sun::star::awt::Point &)461 Reference<XAccessible > SAL_CALL AccessibleGridControlBase::getAccessibleAtPoint( const ::com::sun::star::awt::Point& )
462 throw ( uno::RuntimeException )
463 {
464 return NULL;
465 }
466 //// -----------------------------------------------------------------------------
getForeground()467 sal_Int32 SAL_CALL AccessibleGridControlBase::getForeground( ) throw (::com::sun::star::uno::RuntimeException)
468 {
469 TCSolarGuard aSolarGuard;
470 ::osl::MutexGuard aGuard( getOslMutex() );
471 ensureIsAlive();
472
473 sal_Int32 nColor = 0;
474 Window* pInst = m_aTable.GetWindowInstance();
475 if ( pInst )
476 {
477 if ( pInst->IsControlForeground() )
478 nColor = pInst->GetControlForeground().GetColor();
479 else
480 {
481 Font aFont;
482 if ( pInst->IsControlFont() )
483 aFont = pInst->GetControlFont();
484 else
485 aFont = pInst->GetFont();
486 nColor = aFont.GetColor().GetColor();
487 }
488 }
489 return nColor;
490 }
491 // -----------------------------------------------------------------------------
getBackground()492 sal_Int32 SAL_CALL AccessibleGridControlBase::getBackground( ) throw (::com::sun::star::uno::RuntimeException)
493 {
494 TCSolarGuard aSolarGuard;
495 ::osl::MutexGuard aGuard( getOslMutex() );
496 ensureIsAlive();
497 sal_Int32 nColor = 0;
498 Window* pInst = m_aTable.GetWindowInstance();
499 if ( pInst )
500 {
501 if ( pInst->IsControlBackground() )
502 nColor = pInst->GetControlBackground().GetColor();
503 else
504 nColor = pInst->GetBackground().GetColor().GetColor();
505 }
506 return nColor;
507 }
508
509 //// ============================================================================
GridControlAccessibleElement(const Reference<XAccessible> & rxParent,IAccessibleTable & rTable,AccessibleTableControlObjType eObjType)510 GridControlAccessibleElement::GridControlAccessibleElement( const Reference< XAccessible >& rxParent,
511 IAccessibleTable& rTable,
512 AccessibleTableControlObjType eObjType )
513 :AccessibleGridControlBase( rxParent, rTable, eObjType )
514 {
515 }
516
517 // XInterface -----------------------------------------------------------------
IMPLEMENT_FORWARD_XINTERFACE2(GridControlAccessibleElement,AccessibleGridControlBase,GridControlAccessibleElement_Base)518 IMPLEMENT_FORWARD_XINTERFACE2( GridControlAccessibleElement, AccessibleGridControlBase, GridControlAccessibleElement_Base)
519
520 // XTypeProvider --------------------------------------------------------------
521 IMPLEMENT_FORWARD_XTYPEPROVIDER2( GridControlAccessibleElement, AccessibleGridControlBase, GridControlAccessibleElement_Base )
522
523 // XAccessible ----------------------------------------------------------------
524
525 Reference< XAccessibleContext > SAL_CALL GridControlAccessibleElement::getAccessibleContext() throw ( uno::RuntimeException )
526 {
527 ensureIsAlive();
528 return this;
529 }
530 // ----------------------------------------------------------------------------
~GridControlAccessibleElement()531 GridControlAccessibleElement::~GridControlAccessibleElement( )
532 {
533 }
534
535 // ============================================================================
536
537 } // namespace accessibility
538
539 // ============================================================================
540
541