1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <extended/AccessibleGridControlBase.hxx>
21 #include <toolkit/helper/convert.hxx>
22 #include <vcl/accessibletable.hxx>
23 #include <vcl/svapp.hxx>
24 #include <vcl/window.hxx>
25 #include <cppuhelper/supportsservice.hxx>
26 #include <sal/types.h>
28 #include <com/sun/star/accessibility/AccessibleRole.hpp>
29 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
30 #include <com/sun/star/accessibility/IllegalAccessibleComponentStateException.hpp>
31 #include <unotools/accessiblerelationsethelper.hxx>
32 #include <sal/log.hxx>
34 using ::com::sun::star::uno::Sequence
;
35 using ::com::sun::star::uno::Any
;
37 using namespace ::com::sun::star
;
38 using namespace ::com::sun::star::accessibility
;
39 using namespace ::comphelper
;
40 using namespace ::vcl
;
41 using namespace ::vcl::table
;
44 namespace accessibility
{
46 using namespace com::sun::star::accessibility::AccessibleStateType
;
49 AccessibleGridControlBase::AccessibleGridControlBase(
50 const css::uno::Reference
< css::accessibility::XAccessible
>& rxParent
,
51 ::vcl::table::IAccessibleTable
& rTable
,
52 ::vcl::table::AccessibleTableControlObjType eObjType
) :
53 AccessibleGridControlImplHelper( m_aMutex
),
54 m_xParent( rxParent
),
56 m_eObjType( eObjType
),
57 m_aName( rTable
.GetAccessibleObjectName( eObjType
, 0, 0 ) ),
58 m_aDescription( rTable
.GetAccessibleObjectDescription( eObjType
) ),
63 AccessibleGridControlBase::~AccessibleGridControlBase()
67 // increment ref count to prevent double call of Dtor
68 osl_atomic_increment( &m_refCount
);
73 void SAL_CALL
AccessibleGridControlBase::disposing()
79 AccessibleEventNotifier::TClientId
nId( getClientId( ) );
81 AccessibleEventNotifier::revokeClientNotifyDisposing( nId
, *this );
88 // css::accessibility::XAccessibleContext
90 css::uno::Reference
< css::accessibility::XAccessible
> SAL_CALL
AccessibleGridControlBase::getAccessibleParent()
98 sal_Int32 SAL_CALL
AccessibleGridControlBase::getAccessibleIndexInParent()
104 // -1 for child not found/no parent (according to specification)
107 css::uno::Reference
< uno::XInterface
> xMeMyselfAndI( static_cast< css::accessibility::XAccessibleContext
* >( this ), uno::UNO_QUERY
);
109 // iterate over parent's children and search for this object
112 css::uno::Reference
< css::accessibility::XAccessibleContext
>
113 xParentContext( m_xParent
->getAccessibleContext() );
114 if( xParentContext
.is() )
116 css::uno::Reference
< uno::XInterface
> xChild
;
118 sal_Int32 nChildCount
= xParentContext
->getAccessibleChildCount();
119 for( sal_Int32 nChild
= 0; nChild
< nChildCount
; ++nChild
)
121 xChild
.set(xParentContext
->getAccessibleChild( nChild
), css::uno::UNO_QUERY
);
122 if ( xMeMyselfAndI
.get() == xChild
.get() )
133 OUString SAL_CALL
AccessibleGridControlBase::getAccessibleDescription()
138 return m_aDescription
;
141 OUString SAL_CALL
AccessibleGridControlBase::getAccessibleName()
149 css::uno::Reference
< css::accessibility::XAccessibleRelationSet
> SAL_CALL
150 AccessibleGridControlBase::getAccessibleRelationSet()
155 // GridControl does not have relations.
156 return new utl::AccessibleRelationSetHelper
;
159 css::uno::Reference
< css::accessibility::XAccessibleStateSet
> SAL_CALL
160 AccessibleGridControlBase::getAccessibleStateSet()
162 SolarMutexGuard aSolarGuard
;
164 // don't check whether alive -> StateSet may contain DEFUNC
165 return implCreateStateSetHelper();
168 lang::Locale SAL_CALL
AccessibleGridControlBase::getLocale()
175 css::uno::Reference
< css::accessibility::XAccessibleContext
>
176 xParentContext( m_xParent
->getAccessibleContext() );
177 if( xParentContext
.is() )
178 return xParentContext
->getLocale();
180 throw IllegalAccessibleComponentStateException();
183 // css::accessibility::XAccessibleComponent
185 sal_Bool SAL_CALL
AccessibleGridControlBase::containsPoint( const awt::Point
& rPoint
)
187 return tools::Rectangle( Point(), getBoundingBox().GetSize() ).Contains( VCLPoint( rPoint
) );
190 awt::Rectangle SAL_CALL
AccessibleGridControlBase::getBounds()
192 return AWTRectangle( getBoundingBox() );
195 awt::Point SAL_CALL
AccessibleGridControlBase::getLocation()
197 return AWTPoint( getBoundingBox().TopLeft() );
200 awt::Point SAL_CALL
AccessibleGridControlBase::getLocationOnScreen()
202 return AWTPoint( getBoundingBoxOnScreen().TopLeft() );
205 awt::Size SAL_CALL
AccessibleGridControlBase::getSize()
207 return AWTSize( getBoundingBox().GetSize() );
210 // css::accessibility::XAccessibleEventBroadcaster
212 void SAL_CALL
AccessibleGridControlBase::addAccessibleEventListener(
213 const css::uno::Reference
< css::accessibility::XAccessibleEventListener
>& _rxListener
)
215 if ( _rxListener
.is() )
219 if ( !getClientId( ) )
220 setClientId( AccessibleEventNotifier::registerClient( ) );
222 AccessibleEventNotifier::addEventListener( getClientId( ), _rxListener
);
226 void SAL_CALL
AccessibleGridControlBase::removeAccessibleEventListener(
227 const css::uno::Reference
< css::accessibility::XAccessibleEventListener
>& _rxListener
)
229 if( !(_rxListener
.is() && getClientId( )) )
234 sal_Int32 nListenerCount
= AccessibleEventNotifier::removeEventListener( getClientId( ), _rxListener
);
235 if ( !nListenerCount
)
237 // no listeners anymore
238 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
239 // and at least to us not firing any events anymore, in case somebody calls
240 // NotifyAccessibleEvent, again
241 AccessibleEventNotifier::TClientId
nId( getClientId( ) );
243 AccessibleEventNotifier::revokeClient( nId
);
249 Sequence
< sal_Int8
> SAL_CALL
AccessibleGridControlBase::getImplementationId()
251 return css::uno::Sequence
<sal_Int8
>();
256 sal_Bool SAL_CALL
AccessibleGridControlBase::supportsService(
257 const OUString
& rServiceName
)
259 return cppu::supportsService(this, rServiceName
);
262 Sequence
< OUString
> SAL_CALL
AccessibleGridControlBase::getSupportedServiceNames()
264 return { "com.sun.star.accessibility.AccessibleContext" };
266 // internal virtual methods
268 bool AccessibleGridControlBase::implIsShowing()
270 bool bShowing
= false;
273 css::uno::Reference
< css::accessibility::XAccessibleComponent
>
274 xParentComp( m_xParent
->getAccessibleContext(), uno::UNO_QUERY
);
275 if( xParentComp
.is() )
276 bShowing
= implGetBoundingBox().Overlaps(
277 VCLRectangle( xParentComp
->getBounds() ) );
282 rtl::Reference
<::utl::AccessibleStateSetHelper
> AccessibleGridControlBase::implCreateStateSetHelper()
284 rtl::Reference
<::utl::AccessibleStateSetHelper
>
285 pStateSetHelper
= new ::utl::AccessibleStateSetHelper
;
289 // SHOWING done with m_xParent
290 if( implIsShowing() )
291 pStateSetHelper
->AddState( AccessibleStateType::SHOWING
);
292 // GridControl fills StateSet with states depending on object type
293 m_aTable
.FillAccessibleStateSet( *pStateSetHelper
, getType() );
296 pStateSetHelper
->AddState( AccessibleStateType::DEFUNC
);
297 return pStateSetHelper
;
300 // internal helper methods
302 bool AccessibleGridControlBase::isAlive() const
304 ::osl::MutexGuard
g(m_aMutex
); // guards rBHelper members
305 return !rBHelper
.bDisposed
&& !rBHelper
.bInDispose
;
308 void AccessibleGridControlBase::ensureIsAlive() const
311 throw lang::DisposedException();
314 tools::Rectangle
AccessibleGridControlBase::getBoundingBox()
316 SolarMutexGuard aSolarGuard
;
318 tools::Rectangle aRect
= implGetBoundingBox();
319 if ( aRect
.Left() == 0 && aRect
.Top() == 0 && aRect
.Right() == 0 && aRect
.Bottom() == 0 )
321 SAL_WARN( "accessibility", "rectangle doesn't exist" );
326 tools::Rectangle
AccessibleGridControlBase::getBoundingBoxOnScreen()
328 SolarMutexGuard aSolarGuard
;
330 tools::Rectangle aRect
= implGetBoundingBoxOnScreen();
331 if ( aRect
.Left() == 0 && aRect
.Top() == 0 && aRect
.Right() == 0 && aRect
.Bottom() == 0 )
333 SAL_WARN( "accessibility", "rectangle doesn't exist" );
338 void AccessibleGridControlBase::commitEvent(
339 sal_Int16 _nEventId
, const Any
& _rNewValue
, const Any
& _rOldValue
)
343 if ( !getClientId( ) )
344 // if we don't have a client id for the notifier, then we don't have listeners, then
345 // we don't need to notify anything
348 // build an event object
349 AccessibleEventObject aEvent
;
350 aEvent
.Source
= *this;
351 aEvent
.EventId
= _nEventId
;
352 aEvent
.OldValue
= _rOldValue
;
353 aEvent
.NewValue
= _rNewValue
;
355 // let the notifier handle this event
357 AccessibleEventNotifier::addEvent( getClientId( ), aEvent
);
360 sal_Int16 SAL_CALL
AccessibleGridControlBase::getAccessibleRole()
363 sal_Int16 nRole
= AccessibleRole::UNKNOWN
;
364 switch ( m_eObjType
)
366 case TCTYPE_ROWHEADERCELL
:
367 nRole
= AccessibleRole::ROW_HEADER
;
369 case TCTYPE_COLUMNHEADERCELL
:
370 nRole
= AccessibleRole::COLUMN_HEADER
;
372 case TCTYPE_COLUMNHEADERBAR
:
373 case TCTYPE_ROWHEADERBAR
:
375 nRole
= AccessibleRole::TABLE
;
377 case TCTYPE_TABLECELL
:
378 nRole
= AccessibleRole::TABLE_CELL
;
380 case TCTYPE_GRIDCONTROL
:
381 nRole
= AccessibleRole::PANEL
;
387 css::uno::Reference
<css::accessibility::XAccessible
> SAL_CALL
AccessibleGridControlBase::getAccessibleAtPoint( const css::awt::Point
& )
392 sal_Int32 SAL_CALL
AccessibleGridControlBase::getForeground( )
394 SolarMutexGuard aSolarGuard
;
399 vcl::Window
* pInst
= m_aTable
.GetWindowInstance();
402 if ( pInst
->IsControlForeground() )
403 nColor
= pInst
->GetControlForeground();
407 if ( pInst
->IsControlFont() )
408 aFont
= pInst
->GetControlFont();
410 aFont
= pInst
->GetFont();
411 nColor
= aFont
.GetColor();
414 return sal_Int32(nColor
);
417 sal_Int32 SAL_CALL
AccessibleGridControlBase::getBackground( )
419 SolarMutexGuard aSolarGuard
;
423 vcl::Window
* pInst
= m_aTable
.GetWindowInstance();
426 if ( pInst
->IsControlBackground() )
427 nColor
= pInst
->GetControlBackground();
429 nColor
= pInst
->GetBackground().GetColor();
431 return sal_Int32(nColor
);
435 GridControlAccessibleElement::GridControlAccessibleElement( const css::uno::Reference
< css::accessibility::XAccessible
>& rxParent
,
436 ::vcl::table::IAccessibleTable
& rTable
,
437 ::vcl::table::AccessibleTableControlObjType eObjType
)
438 :AccessibleGridControlBase( rxParent
, rTable
, eObjType
)
443 IMPLEMENT_FORWARD_XINTERFACE2( GridControlAccessibleElement
, AccessibleGridControlBase
, GridControlAccessibleElement_Base
)
446 IMPLEMENT_FORWARD_XTYPEPROVIDER2( GridControlAccessibleElement
, AccessibleGridControlBase
, GridControlAccessibleElement_Base
)
448 // css::accessibility::XAccessible
450 css::uno::Reference
< css::accessibility::XAccessibleContext
> SAL_CALL
GridControlAccessibleElement::getAccessibleContext()
458 GridControlAccessibleElement::~GridControlAccessibleElement( )
463 } // namespace accessibility
466 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */