1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: AccessibleBrowseBoxBase.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_accessibility.hxx"
33 #include "accessibility/extended/AccessibleBrowseBoxBase.hxx"
34 #include <svtools/accessibletableprovider.hxx>
37 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
38 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
39 #include <unotools/accessiblerelationsethelper.hxx>
41 // ============================================================================
43 using ::rtl::OUString
;
45 using ::com::sun::star::uno::Reference
;
46 using ::com::sun::star::uno::Sequence
;
47 using ::com::sun::star::uno::Any
;
49 using namespace ::com::sun::star
;
50 using namespace ::com::sun::star::accessibility
;
51 using namespace ::comphelper
;
52 using namespace ::svt
;
55 // ============================================================================
57 namespace accessibility
{
59 using namespace com::sun::star::accessibility::AccessibleStateType
;
60 // ============================================================================
62 // Ctor/Dtor/disposing --------------------------------------------------------
64 DBG_NAME( AccessibleBrowseBoxBase
)
66 AccessibleBrowseBoxBase::AccessibleBrowseBoxBase(
67 const Reference
< XAccessible
>& rxParent
,
68 IAccessibleTableProvider
& rBrowseBox
,
69 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XWindow
>& _xFocusWindow
,
70 AccessibleBrowseBoxObjType eObjType
) :
71 AccessibleBrowseBoxImplHelper( m_aMutex
),
73 mpBrowseBox( &rBrowseBox
),
74 m_xFocusWindow(_xFocusWindow
),
75 maName( rBrowseBox
.GetAccessibleObjectName( eObjType
) ),
76 maDescription( rBrowseBox
.GetAccessibleObjectDescription( eObjType
) ),
77 meObjType( eObjType
),
80 DBG_CTOR( AccessibleBrowseBoxBase
, NULL
);
81 if ( m_xFocusWindow
.is() )
82 m_xFocusWindow
->addFocusListener( this );
85 AccessibleBrowseBoxBase::AccessibleBrowseBoxBase(
86 const Reference
< XAccessible
>& rxParent
,
87 IAccessibleTableProvider
& rBrowseBox
,
88 const ::com::sun::star::uno::Reference
< ::com::sun::star::awt::XWindow
>& _xFocusWindow
,
89 AccessibleBrowseBoxObjType eObjType
,
90 const ::rtl::OUString
& rName
,
91 const ::rtl::OUString
& rDescription
) :
92 AccessibleBrowseBoxImplHelper( m_aMutex
),
94 mpBrowseBox( &rBrowseBox
),
95 m_xFocusWindow(_xFocusWindow
),
97 maDescription( rDescription
),
98 meObjType( eObjType
),
101 DBG_CTOR( AccessibleBrowseBoxBase
, NULL
);
102 if ( m_xFocusWindow
.is() )
103 m_xFocusWindow
->addFocusListener( this );
106 AccessibleBrowseBoxBase::~AccessibleBrowseBoxBase()
108 DBG_DTOR( AccessibleBrowseBoxBase
, NULL
);
112 // increment ref count to prevent double call of Dtor
113 osl_incrementInterlockedCount( &m_refCount
);
118 void SAL_CALL
AccessibleBrowseBoxBase::disposing()
120 ::osl::MutexGuard
aGuard( getOslMutex() );
121 if ( m_xFocusWindow
.is() )
123 BBSolarGuard aSolarGuard
;
124 m_xFocusWindow
->removeFocusListener( this );
127 if ( getClientId( ) )
129 AccessibleEventNotifier::TClientId
nId( getClientId( ) );
131 AccessibleEventNotifier::revokeClientNotifyDisposing( nId
, *this );
138 // XAccessibleContext ---------------------------------------------------------
140 Reference
< XAccessible
> SAL_CALL
AccessibleBrowseBoxBase::getAccessibleParent()
141 throw ( uno::RuntimeException
)
143 ::osl::MutexGuard
aGuard( getOslMutex() );
148 sal_Int32 SAL_CALL
AccessibleBrowseBoxBase::getAccessibleIndexInParent()
149 throw ( uno::RuntimeException
)
151 ::osl::MutexGuard
aGuard( getOslMutex() );
154 // -1 for child not found/no parent (according to specification)
157 Reference
< uno::XInterface
> xMeMyselfAndI( static_cast< XAccessibleContext
* >( this ), uno::UNO_QUERY
);
159 // iterate over parent's children and search for this object
162 Reference
< XAccessibleContext
>
163 xParentContext( mxParent
->getAccessibleContext() );
164 if( xParentContext
.is() )
166 Reference
< uno::XInterface
> xChild
;
168 sal_Int32 nChildCount
= xParentContext
->getAccessibleChildCount();
169 for( sal_Int32 nChild
= 0; nChild
< nChildCount
; ++nChild
)
171 xChild
= xChild
.query( xParentContext
->getAccessibleChild( nChild
) );
173 if ( xMeMyselfAndI
.get() == xChild
.get() )
184 OUString SAL_CALL
AccessibleBrowseBoxBase::getAccessibleDescription()
185 throw ( uno::RuntimeException
)
187 ::osl::MutexGuard
aGuard( getOslMutex() );
189 return maDescription
;
192 OUString SAL_CALL
AccessibleBrowseBoxBase::getAccessibleName()
193 throw ( uno::RuntimeException
)
195 ::osl::MutexGuard
aGuard( getOslMutex() );
200 Reference
< XAccessibleRelationSet
> SAL_CALL
201 AccessibleBrowseBoxBase::getAccessibleRelationSet()
202 throw ( uno::RuntimeException
)
205 // BrowseBox does not have relations.
206 return new utl::AccessibleRelationSetHelper
;
209 Reference
< XAccessibleStateSet
> SAL_CALL
210 AccessibleBrowseBoxBase::getAccessibleStateSet()
211 throw ( uno::RuntimeException
)
213 BBSolarGuard aSolarGuard
;
214 ::osl::MutexGuard
aGuard( getOslMutex() );
215 // don't check whether alive -> StateSet may contain DEFUNC
216 return implCreateStateSetHelper();
219 lang::Locale SAL_CALL
AccessibleBrowseBoxBase::getLocale()
220 throw ( IllegalAccessibleComponentStateException
, uno::RuntimeException
)
222 ::osl::MutexGuard
aGuard( getOslMutex() );
226 Reference
< XAccessibleContext
>
227 xParentContext( mxParent
->getAccessibleContext() );
228 if( xParentContext
.is() )
229 return xParentContext
->getLocale();
231 throw IllegalAccessibleComponentStateException();
234 // XAccessibleComponent -------------------------------------------------------
236 sal_Bool SAL_CALL
AccessibleBrowseBoxBase::containsPoint( const awt::Point
& rPoint
)
237 throw ( uno::RuntimeException
)
239 return Rectangle( Point(), getBoundingBox().GetSize() ).IsInside( VCLPoint( rPoint
) );
242 awt::Rectangle SAL_CALL
AccessibleBrowseBoxBase::getBounds()
243 throw ( uno::RuntimeException
)
245 return AWTRectangle( getBoundingBox() );
248 awt::Point SAL_CALL
AccessibleBrowseBoxBase::getLocation()
249 throw ( uno::RuntimeException
)
251 return AWTPoint( getBoundingBox().TopLeft() );
254 awt::Point SAL_CALL
AccessibleBrowseBoxBase::getLocationOnScreen()
255 throw ( uno::RuntimeException
)
257 return AWTPoint( getBoundingBoxOnScreen().TopLeft() );
260 awt::Size SAL_CALL
AccessibleBrowseBoxBase::getSize()
261 throw ( uno::RuntimeException
)
263 return AWTSize( getBoundingBox().GetSize() );
266 sal_Bool SAL_CALL
AccessibleBrowseBoxBase::isShowing()
267 throw ( uno::RuntimeException
)
269 BBSolarGuard aSolarGuard
;
270 ::osl::MutexGuard
aGuard( getOslMutex() );
272 return implIsShowing();
275 sal_Bool SAL_CALL
AccessibleBrowseBoxBase::isVisible()
276 throw ( uno::RuntimeException
)
278 Reference
< XAccessibleStateSet
> xStateSet
= getAccessibleStateSet();
279 return xStateSet
.is() ?
280 xStateSet
->contains( AccessibleStateType::VISIBLE
) : sal_False
;
283 sal_Bool SAL_CALL
AccessibleBrowseBoxBase::isFocusTraversable()
284 throw ( uno::RuntimeException
)
286 Reference
< XAccessibleStateSet
> xStateSet
= getAccessibleStateSet();
287 return xStateSet
.is() ?
288 xStateSet
->contains( AccessibleStateType::FOCUSABLE
) : sal_False
;
291 void SAL_CALL
AccessibleBrowseBoxBase::focusGained( const ::com::sun::star::awt::FocusEvent
& ) throw (::com::sun::star::uno::RuntimeException
)
293 com::sun::star::uno::Any aFocused
;
294 com::sun::star::uno::Any aEmpty
;
295 aFocused
<<= FOCUSED
;
297 commitEvent(AccessibleEventId::STATE_CHANGED
,aFocused
,aEmpty
);
299 // -----------------------------------------------------------------------------
301 void SAL_CALL
AccessibleBrowseBoxBase::focusLost( const ::com::sun::star::awt::FocusEvent
& ) throw (::com::sun::star::uno::RuntimeException
)
303 com::sun::star::uno::Any aFocused
;
304 com::sun::star::uno::Any aEmpty
;
305 aFocused
<<= FOCUSED
;
307 commitEvent(AccessibleEventId::STATE_CHANGED
,aEmpty
,aFocused
);
309 // XAccessibleEventBroadcaster ------------------------------------------------
311 void SAL_CALL
AccessibleBrowseBoxBase::addEventListener(
312 const Reference
< XAccessibleEventListener
>& _rxListener
)
313 throw ( uno::RuntimeException
)
315 if ( _rxListener
.is() )
317 ::osl::MutexGuard
aGuard( getOslMutex() );
318 if ( !getClientId( ) )
319 setClientId( AccessibleEventNotifier::registerClient( ) );
321 AccessibleEventNotifier::addEventListener( getClientId( ), _rxListener
);
325 void SAL_CALL
AccessibleBrowseBoxBase::removeEventListener(
326 const Reference
< XAccessibleEventListener
>& _rxListener
)
327 throw ( uno::RuntimeException
)
329 if( _rxListener
.is() && getClientId( ) )
331 ::osl::MutexGuard
aGuard( getOslMutex() );
332 sal_Int32 nListenerCount
= AccessibleEventNotifier::removeEventListener( getClientId( ), _rxListener
);
333 if ( !nListenerCount
)
335 // no listeners anymore
336 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
337 // and at least to us not firing any events anymore, in case somebody calls
338 // NotifyAccessibleEvent, again
340 AccessibleEventNotifier::TClientId
nId( getClientId( ) );
342 AccessibleEventNotifier::revokeClient( nId
);
347 // XTypeProvider --------------------------------------------------------------
349 Sequence
< sal_Int8
> SAL_CALL
AccessibleBrowseBoxBase::getImplementationId()
350 throw ( uno::RuntimeException
)
352 ::osl::MutexGuard
aGuard( getOslGlobalMutex() );
353 static Sequence
< sal_Int8
> aId
;
354 implCreateUuid( aId
);
358 // XServiceInfo ---------------------------------------------------------------
360 sal_Bool SAL_CALL
AccessibleBrowseBoxBase::supportsService(
361 const OUString
& rServiceName
)
362 throw ( uno::RuntimeException
)
364 ::osl::MutexGuard
aGuard( getOslMutex() );
366 Sequence
< OUString
> aSupportedServices( getSupportedServiceNames() );
367 const OUString
* pArrBegin
= aSupportedServices
.getConstArray();
368 const OUString
* pArrEnd
= pArrBegin
+ aSupportedServices
.getLength();
369 const OUString
* pString
= pArrBegin
;
371 for( ; ( pString
!= pArrEnd
) && ( rServiceName
!= *pString
); ++pString
)
374 return pString
!= pArrEnd
;
377 Sequence
< OUString
> SAL_CALL
AccessibleBrowseBoxBase::getSupportedServiceNames()
378 throw ( uno::RuntimeException
)
380 const OUString
aServiceName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) );
381 return Sequence
< OUString
>( &aServiceName
, 1 );
384 // other public methods -------------------------------------------------------
386 void AccessibleBrowseBoxBase::setAccessibleName( const OUString
& rName
)
388 ::osl::ClearableMutexGuard
aGuard( getOslMutex() );
396 AccessibleEventId::NAME_CHANGED
,
397 uno::makeAny( maName
),
401 void AccessibleBrowseBoxBase::setAccessibleDescription( const OUString
& rDescription
)
403 ::osl::ClearableMutexGuard
aGuard( getOslMutex() );
405 aOld
<<= maDescription
;
406 maDescription
= rDescription
;
411 AccessibleEventId::DESCRIPTION_CHANGED
,
412 uno::makeAny( maDescription
),
416 // internal virtual methods ---------------------------------------------------
418 sal_Bool
AccessibleBrowseBoxBase::implIsShowing()
420 sal_Bool bShowing
= sal_False
;
423 Reference
< XAccessibleComponent
>
424 xParentComp( mxParent
->getAccessibleContext(), uno::UNO_QUERY
);
425 if( xParentComp
.is() )
426 bShowing
= implGetBoundingBox().IsOver(
427 VCLRectangle( xParentComp
->getBounds() ) );
432 ::utl::AccessibleStateSetHelper
* AccessibleBrowseBoxBase::implCreateStateSetHelper()
434 ::utl::AccessibleStateSetHelper
*
435 pStateSetHelper
= new ::utl::AccessibleStateSetHelper
;
439 // SHOWING done with mxParent
440 if( implIsShowing() )
441 pStateSetHelper
->AddState( AccessibleStateType::SHOWING
);
442 // BrowseBox fills StateSet with states depending on object type
443 mpBrowseBox
->FillAccessibleStateSet( *pStateSetHelper
, getType() );
446 pStateSetHelper
->AddState( AccessibleStateType::DEFUNC
);
448 return pStateSetHelper
;
451 // internal helper methods ----------------------------------------------------
453 sal_Bool
AccessibleBrowseBoxBase::isAlive() const
455 return !rBHelper
.bDisposed
&& !rBHelper
.bInDispose
&& mpBrowseBox
;
458 void AccessibleBrowseBoxBase::ensureIsAlive() const
459 throw ( lang::DisposedException
)
462 throw lang::DisposedException();
465 Rectangle
AccessibleBrowseBoxBase::getBoundingBox()
466 throw ( lang::DisposedException
)
468 BBSolarGuard aSolarGuard
;
469 ::osl::MutexGuard
aGuard( getOslMutex() );
471 Rectangle aRect
= implGetBoundingBox();
472 if ( 0 == aRect
.Left() && 0 == aRect
.Top() && 0 == aRect
.Right() && 0 == aRect
.Bottom() )
474 DBG_ERRORFILE( "shit" );
479 Rectangle
AccessibleBrowseBoxBase::getBoundingBoxOnScreen()
480 throw ( lang::DisposedException
)
482 BBSolarGuard aSolarGuard
;
483 ::osl::MutexGuard
aGuard( getOslMutex() );
485 Rectangle aRect
= implGetBoundingBoxOnScreen();
486 if ( 0 == aRect
.Left() && 0 == aRect
.Top() && 0 == aRect
.Right() && 0 == aRect
.Bottom() )
488 DBG_ERRORFILE( "shit" );
493 void AccessibleBrowseBoxBase::commitEvent(
494 sal_Int16 _nEventId
, const Any
& _rNewValue
, const Any
& _rOldValue
)
496 ::osl::ClearableMutexGuard
aGuard( getOslMutex() );
497 if ( !getClientId( ) )
498 // if we don't have a client id for the notifier, then we don't have listeners, then
499 // we don't need to notify anything
502 // build an event object
503 AccessibleEventObject aEvent
;
504 aEvent
.Source
= *this;
505 aEvent
.EventId
= _nEventId
;
506 aEvent
.OldValue
= _rOldValue
;
507 aEvent
.NewValue
= _rNewValue
;
509 // let the notifier handle this event
511 AccessibleEventNotifier::addEvent( getClientId( ), aEvent
);
513 // -----------------------------------------------------------------------------
515 void AccessibleBrowseBoxBase::implCreateUuid( Sequence
< sal_Int8
>& rId
)
517 if( !rId
.hasElements() )
520 rtl_createUuid( reinterpret_cast< sal_uInt8
* >( rId
.getArray() ), 0, sal_True
);
523 // -----------------------------------------------------------------------------
524 sal_Int16 SAL_CALL
AccessibleBrowseBoxBase::getAccessibleRole()
525 throw ( uno::RuntimeException
)
528 sal_Int16 nRole
= AccessibleRole::UNKNOWN
;
531 case BBTYPE_ROWHEADERCELL
:
532 nRole
= AccessibleRole::ROW_HEADER
;
534 case BBTYPE_COLUMNHEADERCELL
:
535 nRole
= AccessibleRole::COLUMN_HEADER
;
537 case BBTYPE_COLUMNHEADERBAR
:
538 case BBTYPE_ROWHEADERBAR
:
540 nRole
= AccessibleRole::TABLE
;
542 case BBTYPE_TABLECELL
:
543 nRole
= AccessibleRole::TABLE_CELL
;
545 case BBTYPE_BROWSEBOX
:
546 nRole
= AccessibleRole::PANEL
;
548 case BBTYPE_CHECKBOXCELL
:
549 nRole
= AccessibleRole::CHECK_BOX
;
554 // -----------------------------------------------------------------------------
555 Any SAL_CALL
AccessibleBrowseBoxBase::getAccessibleKeyBinding()
556 throw ( uno::RuntimeException
)
560 // -----------------------------------------------------------------------------
561 Reference
<XAccessible
> SAL_CALL
AccessibleBrowseBoxBase::getAccessibleAtPoint( const ::com::sun::star::awt::Point
& )
562 throw ( uno::RuntimeException
)
566 // -----------------------------------------------------------------------------
567 void SAL_CALL
AccessibleBrowseBoxBase::disposing( const ::com::sun::star::lang::EventObject
& ) throw (::com::sun::star::uno::RuntimeException
)
569 m_xFocusWindow
= NULL
;
571 // -----------------------------------------------------------------------------
572 sal_Int32 SAL_CALL
AccessibleBrowseBoxBase::getForeground( ) throw (::com::sun::star::uno::RuntimeException
)
574 BBSolarGuard aSolarGuard
;
575 ::osl::MutexGuard
aGuard( getOslMutex() );
578 sal_Int32 nColor
= 0;
579 Window
* pInst
= mpBrowseBox
->GetWindowInstance();
582 if ( pInst
->IsControlForeground() )
583 nColor
= pInst
->GetControlForeground().GetColor();
587 if ( pInst
->IsControlFont() )
588 aFont
= pInst
->GetControlFont();
590 aFont
= pInst
->GetFont();
591 nColor
= aFont
.GetColor().GetColor();
597 // -----------------------------------------------------------------------------
598 sal_Int32 SAL_CALL
AccessibleBrowseBoxBase::getBackground( ) throw (::com::sun::star::uno::RuntimeException
)
600 BBSolarGuard aSolarGuard
;
601 ::osl::MutexGuard
aGuard( getOslMutex() );
603 sal_Int32 nColor
= 0;
604 Window
* pInst
= mpBrowseBox
->GetWindowInstance();
607 if ( pInst
->IsControlBackground() )
608 nColor
= pInst
->GetControlBackground().GetColor();
610 nColor
= pInst
->GetBackground().GetColor().GetColor();
616 // ============================================================================
617 DBG_NAME( BrowseBoxAccessibleElement
)
619 // XInterface -----------------------------------------------------------------
620 IMPLEMENT_FORWARD_XINTERFACE2( BrowseBoxAccessibleElement
, AccessibleBrowseBoxBase
, BrowseBoxAccessibleElement_Base
)
622 // XTypeProvider --------------------------------------------------------------
623 IMPLEMENT_FORWARD_XTYPEPROVIDER2( BrowseBoxAccessibleElement
, AccessibleBrowseBoxBase
, BrowseBoxAccessibleElement_Base
)
625 // XAccessible ----------------------------------------------------------------
627 Reference
< XAccessibleContext
> SAL_CALL
BrowseBoxAccessibleElement::getAccessibleContext() throw ( uno::RuntimeException
)
633 // ----------------------------------------------------------------------------
634 BrowseBoxAccessibleElement::BrowseBoxAccessibleElement( const Reference
< XAccessible
>& rxParent
, IAccessibleTableProvider
& rBrowseBox
,
635 const Reference
< awt::XWindow
>& _xFocusWindow
, AccessibleBrowseBoxObjType eObjType
)
636 :AccessibleBrowseBoxBase( rxParent
, rBrowseBox
, _xFocusWindow
, eObjType
)
638 DBG_CTOR( BrowseBoxAccessibleElement
, NULL
);
641 // ----------------------------------------------------------------------------
642 BrowseBoxAccessibleElement::BrowseBoxAccessibleElement( const Reference
< XAccessible
>& rxParent
, IAccessibleTableProvider
& rBrowseBox
,
643 const Reference
< awt::XWindow
>& _xFocusWindow
, AccessibleBrowseBoxObjType eObjType
,
644 const ::rtl::OUString
& rName
, const ::rtl::OUString
& rDescription
)
645 :AccessibleBrowseBoxBase( rxParent
, rBrowseBox
, _xFocusWindow
, eObjType
, rName
, rDescription
)
647 DBG_CTOR( BrowseBoxAccessibleElement
, NULL
);
650 // ----------------------------------------------------------------------------
651 BrowseBoxAccessibleElement::~BrowseBoxAccessibleElement( )
653 DBG_DTOR( BrowseBoxAccessibleElement
, NULL
);
656 // ============================================================================
658 } // namespace accessibility
660 // ============================================================================