bump product version to 7.6.3.2-android
[LibreOffice.git] / accessibility / source / extended / AccessibleBrowseBoxBase.cxx
bloba3b0b0891c5316b8fe18d489f55af18463e66152
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/AccessibleBrowseBoxBase.hxx>
21 #include <toolkit/helper/convert.hxx>
22 #include <utility>
23 #include <vcl/accessibletableprovider.hxx>
24 #include <cppuhelper/supportsservice.hxx>
26 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
27 #include <com/sun/star/accessibility/AccessibleRole.hpp>
28 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
29 #include <com/sun/star/accessibility/IllegalAccessibleComponentStateException.hpp>
30 #include <unotools/accessiblerelationsethelper.hxx>
31 #include <vcl/window.hxx>
32 #include <vcl/svapp.hxx>
33 #include <sal/log.hxx>
36 using ::com::sun::star::uno::Reference;
37 using ::com::sun::star::uno::Sequence;
38 using ::com::sun::star::uno::Any;
40 using namespace ::com::sun::star;
41 using namespace ::com::sun::star::accessibility;
42 using namespace ::comphelper;
45 namespace accessibility {
47 using namespace com::sun::star::accessibility::AccessibleStateType;
50 // Ctor/Dtor/disposing
52 AccessibleBrowseBoxBase::AccessibleBrowseBoxBase(
53 css::uno::Reference< css::accessibility::XAccessible > xParent,
54 ::vcl::IAccessibleTableProvider& rBrowseBox,
55 css::uno::Reference< css::awt::XWindow > _xFocusWindow,
56 AccessibleBrowseBoxObjType eObjType ) :
57 AccessibleBrowseBoxImplHelper( m_aMutex ),
58 mxParent(std::move( xParent )),
59 mpBrowseBox( &rBrowseBox ),
60 m_xFocusWindow(std::move(_xFocusWindow)),
61 maName( rBrowseBox.GetAccessibleObjectName( eObjType ) ),
62 maDescription( rBrowseBox.GetAccessibleObjectDescription( eObjType ) ),
63 meObjType( eObjType ),
64 m_aClientId(0)
66 if ( m_xFocusWindow.is() )
67 m_xFocusWindow->addFocusListener( this );
70 AccessibleBrowseBoxBase::AccessibleBrowseBoxBase(
71 css::uno::Reference< css::accessibility::XAccessible > rxParent,
72 ::vcl::IAccessibleTableProvider& rBrowseBox,
73 css::uno::Reference< css::awt::XWindow > _xFocusWindow,
74 AccessibleBrowseBoxObjType eObjType,
75 OUString rName,
76 OUString rDescription ) :
77 AccessibleBrowseBoxImplHelper( m_aMutex ),
78 mxParent(std::move( rxParent )),
79 mpBrowseBox( &rBrowseBox ),
80 m_xFocusWindow(std::move(_xFocusWindow)),
81 maName(std::move( rName )),
82 maDescription(std::move( rDescription )),
83 meObjType( eObjType ),
84 m_aClientId(0)
86 if ( m_xFocusWindow.is() )
87 m_xFocusWindow->addFocusListener( this );
90 AccessibleBrowseBoxBase::~AccessibleBrowseBoxBase()
92 if( isAlive() )
94 // increment ref count to prevent double call of Dtor
95 osl_atomic_increment( &m_refCount );
96 dispose();
100 void SAL_CALL AccessibleBrowseBoxBase::disposing()
102 ::osl::MutexGuard aGuard( getMutex() );
103 if ( m_xFocusWindow.is() )
105 SolarMutexGuard aSolarGuard;
106 m_xFocusWindow->removeFocusListener( this );
109 if ( getClientId( ) )
111 AccessibleEventNotifier::TClientId nId( getClientId( ) );
112 setClientId( 0 );
113 AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this );
116 mxParent = nullptr;
117 mpBrowseBox = nullptr;
120 // css::accessibility::XAccessibleContext
122 Reference< css::accessibility::XAccessible > SAL_CALL AccessibleBrowseBoxBase::getAccessibleParent()
124 ::osl::MutexGuard aGuard( getMutex() );
125 ensureIsAlive();
126 return mxParent;
129 sal_Int64 SAL_CALL AccessibleBrowseBoxBase::getAccessibleIndexInParent()
131 ::osl::MutexGuard aGuard( getMutex() );
132 ensureIsAlive();
134 // -1 for child not found/no parent (according to specification)
135 sal_Int64 nRet = -1;
137 css::uno::Reference< uno::XInterface > xMeMyselfAndI( static_cast< css::accessibility::XAccessibleContext* >( this ), uno::UNO_QUERY );
139 // iterate over parent's children and search for this object
140 if( mxParent.is() )
142 css::uno::Reference< css::accessibility::XAccessibleContext >
143 xParentContext( mxParent->getAccessibleContext() );
144 if( xParentContext.is() )
146 css::uno::Reference< uno::XInterface > xChild;
148 sal_Int64 nChildCount = xParentContext->getAccessibleChildCount();
149 for( sal_Int64 nChild = 0; nChild < nChildCount; ++nChild )
151 xChild.set(xParentContext->getAccessibleChild( nChild ), css::uno::UNO_QUERY);
153 if ( xMeMyselfAndI.get() == xChild.get() )
155 nRet = nChild;
156 break;
161 return nRet;
164 OUString SAL_CALL AccessibleBrowseBoxBase::getAccessibleDescription()
166 ::osl::MutexGuard aGuard( getMutex() );
167 ensureIsAlive();
168 return maDescription;
171 OUString SAL_CALL AccessibleBrowseBoxBase::getAccessibleName()
173 ::osl::MutexGuard aGuard( getMutex() );
174 ensureIsAlive();
175 return maName;
178 Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL
179 AccessibleBrowseBoxBase::getAccessibleRelationSet()
181 ::osl::MutexGuard aGuard( getMutex() );
182 ensureIsAlive();
183 // BrowseBox does not have relations.
184 return new utl::AccessibleRelationSetHelper;
187 sal_Int64 SAL_CALL
188 AccessibleBrowseBoxBase::getAccessibleStateSet()
190 SolarMethodGuard aGuard( getMutex() );
191 // don't check whether alive -> StateSet may contain DEFUNC
192 return implCreateStateSet();
195 lang::Locale SAL_CALL AccessibleBrowseBoxBase::getLocale()
197 ::osl::MutexGuard aGuard( getMutex() );
198 ensureIsAlive();
199 if( mxParent.is() )
201 css::uno::Reference< css::accessibility::XAccessibleContext >
202 xParentContext( mxParent->getAccessibleContext() );
203 if( xParentContext.is() )
204 return xParentContext->getLocale();
206 throw IllegalAccessibleComponentStateException();
209 // css::accessibility::XAccessibleComponent
211 sal_Bool SAL_CALL AccessibleBrowseBoxBase::containsPoint( const css::awt::Point& rPoint )
213 return tools::Rectangle( Point(), getBoundingBox().GetSize() ).Contains( VCLPoint( rPoint ) );
216 awt::Rectangle SAL_CALL AccessibleBrowseBoxBase::getBounds()
218 return AWTRectangle( getBoundingBox() );
221 awt::Point SAL_CALL AccessibleBrowseBoxBase::getLocation()
223 return AWTPoint( getBoundingBox().TopLeft() );
226 awt::Point SAL_CALL AccessibleBrowseBoxBase::getLocationOnScreen()
228 return AWTPoint( getBoundingBoxOnScreen().TopLeft() );
231 awt::Size SAL_CALL AccessibleBrowseBoxBase::getSize()
233 return AWTSize( getBoundingBox().GetSize() );
236 void SAL_CALL AccessibleBrowseBoxBase::focusGained( const css::awt::FocusEvent& )
238 com::sun::star::uno::Any aFocused;
239 com::sun::star::uno::Any aEmpty;
240 aFocused <<= FOCUSED;
242 commitEvent(AccessibleEventId::STATE_CHANGED,aFocused,aEmpty);
246 void SAL_CALL AccessibleBrowseBoxBase::focusLost( const css::awt::FocusEvent& )
248 com::sun::star::uno::Any aFocused;
249 com::sun::star::uno::Any aEmpty;
250 aFocused <<= FOCUSED;
252 commitEvent(AccessibleEventId::STATE_CHANGED,aEmpty,aFocused);
254 // css::accessibility::XAccessibleEventBroadcaster
256 void SAL_CALL AccessibleBrowseBoxBase::addAccessibleEventListener(
257 const css::uno::Reference< css::accessibility::XAccessibleEventListener>& _rxListener )
259 if ( _rxListener.is() )
261 ::osl::MutexGuard aGuard( getMutex() );
262 if ( !getClientId( ) )
263 setClientId( AccessibleEventNotifier::registerClient( ) );
265 AccessibleEventNotifier::addEventListener( getClientId( ), _rxListener );
269 void SAL_CALL AccessibleBrowseBoxBase::removeAccessibleEventListener(
270 const css::uno::Reference< css::accessibility::XAccessibleEventListener>& _rxListener )
272 if( !(_rxListener.is() && getClientId( )) )
273 return;
275 ::osl::MutexGuard aGuard( getMutex() );
276 sal_Int32 nListenerCount = AccessibleEventNotifier::removeEventListener( getClientId( ), _rxListener );
277 if ( !nListenerCount )
279 // no listeners anymore
280 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
281 // and at least to us not firing any events anymore, in case somebody calls
282 // NotifyAccessibleEvent, again
284 AccessibleEventNotifier::TClientId nId( getClientId( ) );
285 setClientId( 0 );
286 AccessibleEventNotifier::revokeClient( nId );
290 // XTypeProvider
292 Sequence< sal_Int8 > SAL_CALL AccessibleBrowseBoxBase::getImplementationId()
294 return css::uno::Sequence<sal_Int8>();
297 // XServiceInfo
299 sal_Bool SAL_CALL AccessibleBrowseBoxBase::supportsService(
300 const OUString& rServiceName )
302 return cppu::supportsService(this, rServiceName);
305 Sequence< OUString > SAL_CALL AccessibleBrowseBoxBase::getSupportedServiceNames()
307 return { "com.sun.star.accessibility.AccessibleContext" };
310 // other public methods
312 void AccessibleBrowseBoxBase::setAccessibleName( const OUString& rName )
314 ::osl::ClearableMutexGuard aGuard( getMutex() );
315 Any aOld;
316 aOld <<= maName;
317 maName = rName;
319 aGuard.clear();
321 commitEvent(
322 AccessibleEventId::NAME_CHANGED,
323 uno::Any( maName ),
324 aOld );
327 void AccessibleBrowseBoxBase::setAccessibleDescription( const OUString& rDescription )
329 ::osl::ClearableMutexGuard aGuard( getMutex() );
330 Any aOld;
331 aOld <<= maDescription;
332 maDescription = rDescription;
334 aGuard.clear();
336 commitEvent(
337 AccessibleEventId::DESCRIPTION_CHANGED,
338 uno::Any( maDescription ),
339 aOld );
342 // internal virtual methods
344 bool AccessibleBrowseBoxBase::implIsShowing()
346 bool bShowing = false;
347 if( mxParent.is() )
349 css::uno::Reference< css::accessibility::XAccessibleComponent >
350 xParentComp( mxParent->getAccessibleContext(), uno::UNO_QUERY );
351 if( xParentComp.is() )
352 bShowing = implGetBoundingBox().Overlaps(
353 VCLRectangle( xParentComp->getBounds() ) );
355 return bShowing;
358 sal_Int64 AccessibleBrowseBoxBase::implCreateStateSet()
360 sal_Int64 nStateSet = 0;
362 if( isAlive() )
364 // SHOWING done with mxParent
365 if( implIsShowing() )
366 nStateSet |= AccessibleStateType::SHOWING;
367 // BrowseBox fills StateSet with states depending on object type
368 mpBrowseBox->FillAccessibleStateSet( nStateSet, getType() );
370 else
371 nStateSet |= AccessibleStateType::DEFUNC;
373 return nStateSet;
376 // internal helper methods
378 bool AccessibleBrowseBoxBase::isAlive() const
380 return !rBHelper.bDisposed && !rBHelper.bInDispose && mpBrowseBox;
383 void AccessibleBrowseBoxBase::ensureIsAlive() const
385 if( !isAlive() )
386 throw lang::DisposedException();
389 tools::Rectangle AccessibleBrowseBoxBase::getBoundingBox()
391 SolarMethodGuard aGuard(getMutex());
392 ensureIsAlive();
394 tools::Rectangle aRect = implGetBoundingBox();
395 if ( aRect.Left() == 0 && aRect.Top() == 0 && aRect.Right() == 0 && aRect.Bottom() == 0 )
397 SAL_WARN( "accessibility", "rectangle doesn't exist" );
399 return aRect;
402 tools::Rectangle AccessibleBrowseBoxBase::getBoundingBoxOnScreen()
404 SolarMethodGuard aGuard(getMutex());
405 ensureIsAlive();
407 tools::Rectangle aRect = implGetBoundingBoxOnScreen();
408 if ( aRect.Left() == 0 && aRect.Top() == 0 && aRect.Right() == 0 && aRect.Bottom() == 0 )
410 SAL_WARN( "accessibility", "rectangle doesn't exist" );
412 return aRect;
415 void AccessibleBrowseBoxBase::commitEvent(
416 sal_Int16 _nEventId, const Any& _rNewValue, const Any& _rOldValue )
418 osl::MutexGuard aGuard( getMutex() );
419 if ( !getClientId( ) )
420 // if we don't have a client id for the notifier, then we don't have listeners, then
421 // we don't need to notify anything
422 return;
424 // build an event object
425 AccessibleEventObject aEvent;
426 aEvent.Source = *this;
427 aEvent.EventId = _nEventId;
428 aEvent.OldValue = _rOldValue;
429 aEvent.NewValue = _rNewValue;
431 // let the notifier handle this event
433 AccessibleEventNotifier::addEvent( getClientId( ), aEvent );
436 sal_Int16 SAL_CALL AccessibleBrowseBoxBase::getAccessibleRole()
438 osl::MutexGuard aGuard( getMutex() );
439 ensureIsAlive();
440 sal_Int16 nRole = AccessibleRole::UNKNOWN;
441 switch ( meObjType )
443 case AccessibleBrowseBoxObjType::RowHeaderCell:
444 nRole = AccessibleRole::ROW_HEADER;
445 break;
446 case AccessibleBrowseBoxObjType::ColumnHeaderCell:
447 nRole = AccessibleRole::COLUMN_HEADER;
448 break;
449 case AccessibleBrowseBoxObjType::ColumnHeaderBar:
450 case AccessibleBrowseBoxObjType::RowHeaderBar:
451 case AccessibleBrowseBoxObjType::Table:
452 nRole = AccessibleRole::TABLE;
453 break;
454 case AccessibleBrowseBoxObjType::TableCell:
455 nRole = AccessibleRole::TABLE_CELL;
456 break;
457 case AccessibleBrowseBoxObjType::BrowseBox:
458 nRole = AccessibleRole::PANEL;
459 break;
460 case AccessibleBrowseBoxObjType::CheckBoxCell:
461 nRole = AccessibleRole::CHECK_BOX;
462 break;
464 return nRole;
467 Reference<XAccessible > SAL_CALL AccessibleBrowseBoxBase::getAccessibleAtPoint( const css::awt::Point& )
469 return nullptr;
472 void SAL_CALL AccessibleBrowseBoxBase::disposing( const css::lang::EventObject& )
474 m_xFocusWindow = nullptr;
477 sal_Int32 SAL_CALL AccessibleBrowseBoxBase::getForeground( )
479 SolarMethodGuard aGuard(getMutex());
480 ensureIsAlive();
482 Color nColor;
483 vcl::Window* pInst = mpBrowseBox->GetWindowInstance();
484 if ( pInst )
486 if ( pInst->IsControlForeground() )
487 nColor = pInst->GetControlForeground();
488 else
490 vcl::Font aFont;
491 if ( pInst->IsControlFont() )
492 aFont = pInst->GetControlFont();
493 else
494 aFont = pInst->GetFont();
495 nColor = aFont.GetColor();
499 return sal_Int32(nColor);
502 sal_Int32 SAL_CALL AccessibleBrowseBoxBase::getBackground( )
504 SolarMethodGuard aGuard(getMutex());
505 ensureIsAlive();
507 Color nColor;
508 vcl::Window* pInst = mpBrowseBox->GetWindowInstance();
509 if ( pInst )
511 if ( pInst->IsControlBackground() )
512 nColor = pInst->GetControlBackground();
513 else
514 nColor = pInst->GetBackground().GetColor();
517 return sal_Int32(nColor);
521 // XInterface
522 IMPLEMENT_FORWARD_XINTERFACE2( BrowseBoxAccessibleElement, AccessibleBrowseBoxBase, BrowseBoxAccessibleElement_Base )
524 // XTypeProvider
525 IMPLEMENT_FORWARD_XTYPEPROVIDER2( BrowseBoxAccessibleElement, AccessibleBrowseBoxBase, BrowseBoxAccessibleElement_Base )
527 // css::accessibility::XAccessible
529 Reference< css::accessibility::XAccessibleContext > SAL_CALL BrowseBoxAccessibleElement::getAccessibleContext()
531 osl::MutexGuard aGuard( getMutex() );
532 ensureIsAlive();
533 return this;
537 BrowseBoxAccessibleElement::BrowseBoxAccessibleElement( const css::uno::Reference< css::accessibility::XAccessible >& rxParent, ::vcl::IAccessibleTableProvider& rBrowseBox,
538 const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, AccessibleBrowseBoxObjType eObjType )
539 :AccessibleBrowseBoxBase( rxParent, rBrowseBox, _xFocusWindow, eObjType )
544 BrowseBoxAccessibleElement::BrowseBoxAccessibleElement( const css::uno::Reference< css::accessibility::XAccessible >& rxParent, ::vcl::IAccessibleTableProvider& rBrowseBox,
545 const css::uno::Reference< css::awt::XWindow >& _xFocusWindow, AccessibleBrowseBoxObjType eObjType,
546 const OUString& rName, const OUString& rDescription )
547 :AccessibleBrowseBoxBase( rxParent, rBrowseBox, _xFocusWindow, eObjType, rName, rDescription )
552 BrowseBoxAccessibleElement::~BrowseBoxAccessibleElement( )
557 } // namespace accessibility
560 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */