LanguageTool: don't crash if REST protocol isn't set
[LibreOffice.git] / accessibility / source / extended / AccessibleBrowseBoxBase.cxx
blobee64200065d1af6be3dd5671acc308094b036697
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 <vcl/accessibletableprovider.hxx>
23 #include <cppuhelper/supportsservice.hxx>
25 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
26 #include <com/sun/star/accessibility/AccessibleRole.hpp>
27 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
28 #include <com/sun/star/accessibility/IllegalAccessibleComponentStateException.hpp>
29 #include <unotools/accessiblerelationsethelper.hxx>
30 #include <vcl/window.hxx>
31 #include <vcl/svapp.hxx>
32 #include <sal/log.hxx>
35 using ::com::sun::star::uno::Reference;
36 using ::com::sun::star::uno::Sequence;
37 using ::com::sun::star::uno::Any;
39 using namespace ::com::sun::star;
40 using namespace ::com::sun::star::accessibility;
41 using namespace ::comphelper;
44 namespace accessibility {
46 using namespace com::sun::star::accessibility::AccessibleStateType;
49 // Ctor/Dtor/disposing
51 AccessibleBrowseBoxBase::AccessibleBrowseBoxBase(
52 const css::uno::Reference< css::accessibility::XAccessible >& rxParent,
53 ::vcl::IAccessibleTableProvider& rBrowseBox,
54 const css::uno::Reference< css::awt::XWindow >& _xFocusWindow,
55 AccessibleBrowseBoxObjType eObjType ) :
56 AccessibleBrowseBoxImplHelper( m_aMutex ),
57 mxParent( rxParent ),
58 mpBrowseBox( &rBrowseBox ),
59 m_xFocusWindow(_xFocusWindow),
60 maName( rBrowseBox.GetAccessibleObjectName( eObjType ) ),
61 maDescription( rBrowseBox.GetAccessibleObjectDescription( eObjType ) ),
62 meObjType( eObjType ),
63 m_aClientId(0)
65 if ( m_xFocusWindow.is() )
66 m_xFocusWindow->addFocusListener( this );
69 AccessibleBrowseBoxBase::AccessibleBrowseBoxBase(
70 const css::uno::Reference< css::accessibility::XAccessible >& rxParent,
71 ::vcl::IAccessibleTableProvider& rBrowseBox,
72 const css::uno::Reference< css::awt::XWindow >& _xFocusWindow,
73 AccessibleBrowseBoxObjType eObjType,
74 const OUString& rName,
75 const OUString& rDescription ) :
76 AccessibleBrowseBoxImplHelper( m_aMutex ),
77 mxParent( rxParent ),
78 mpBrowseBox( &rBrowseBox ),
79 m_xFocusWindow(_xFocusWindow),
80 maName( rName ),
81 maDescription( rDescription ),
82 meObjType( eObjType ),
83 m_aClientId(0)
85 if ( m_xFocusWindow.is() )
86 m_xFocusWindow->addFocusListener( this );
89 AccessibleBrowseBoxBase::~AccessibleBrowseBoxBase()
91 if( isAlive() )
93 // increment ref count to prevent double call of Dtor
94 osl_atomic_increment( &m_refCount );
95 dispose();
99 void SAL_CALL AccessibleBrowseBoxBase::disposing()
101 ::osl::MutexGuard aGuard( getMutex() );
102 if ( m_xFocusWindow.is() )
104 SolarMutexGuard aSolarGuard;
105 m_xFocusWindow->removeFocusListener( this );
108 if ( getClientId( ) )
110 AccessibleEventNotifier::TClientId nId( getClientId( ) );
111 setClientId( 0 );
112 AccessibleEventNotifier::revokeClientNotifyDisposing( nId, *this );
115 mxParent = nullptr;
116 mpBrowseBox = nullptr;
119 // css::accessibility::XAccessibleContext
121 Reference< css::accessibility::XAccessible > SAL_CALL AccessibleBrowseBoxBase::getAccessibleParent()
123 ::osl::MutexGuard aGuard( getMutex() );
124 ensureIsAlive();
125 return mxParent;
128 sal_Int32 SAL_CALL AccessibleBrowseBoxBase::getAccessibleIndexInParent()
130 ::osl::MutexGuard aGuard( getMutex() );
131 ensureIsAlive();
133 // -1 for child not found/no parent (according to specification)
134 sal_Int32 nRet = -1;
136 css::uno::Reference< uno::XInterface > xMeMyselfAndI( static_cast< css::accessibility::XAccessibleContext* >( this ), uno::UNO_QUERY );
138 // iterate over parent's children and search for this object
139 if( mxParent.is() )
141 css::uno::Reference< css::accessibility::XAccessibleContext >
142 xParentContext( mxParent->getAccessibleContext() );
143 if( xParentContext.is() )
145 css::uno::Reference< uno::XInterface > xChild;
147 sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
148 for( sal_Int32 nChild = 0; nChild < nChildCount; ++nChild )
150 xChild.set(xParentContext->getAccessibleChild( nChild ), css::uno::UNO_QUERY);
152 if ( xMeMyselfAndI.get() == xChild.get() )
154 nRet = nChild;
155 break;
160 return nRet;
163 OUString SAL_CALL AccessibleBrowseBoxBase::getAccessibleDescription()
165 ::osl::MutexGuard aGuard( getMutex() );
166 ensureIsAlive();
167 return maDescription;
170 OUString SAL_CALL AccessibleBrowseBoxBase::getAccessibleName()
172 ::osl::MutexGuard aGuard( getMutex() );
173 ensureIsAlive();
174 return maName;
177 Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL
178 AccessibleBrowseBoxBase::getAccessibleRelationSet()
180 ::osl::MutexGuard aGuard( getMutex() );
181 ensureIsAlive();
182 // BrowseBox does not have relations.
183 return new utl::AccessibleRelationSetHelper;
186 Reference< css::accessibility::XAccessibleStateSet > SAL_CALL
187 AccessibleBrowseBoxBase::getAccessibleStateSet()
189 SolarMethodGuard aGuard( getMutex() );
190 // don't check whether alive -> StateSet may contain DEFUNC
191 return implCreateStateSetHelper();
194 lang::Locale SAL_CALL AccessibleBrowseBoxBase::getLocale()
196 ::osl::MutexGuard aGuard( getMutex() );
197 ensureIsAlive();
198 if( mxParent.is() )
200 css::uno::Reference< css::accessibility::XAccessibleContext >
201 xParentContext( mxParent->getAccessibleContext() );
202 if( xParentContext.is() )
203 return xParentContext->getLocale();
205 throw IllegalAccessibleComponentStateException();
208 // css::accessibility::XAccessibleComponent
210 sal_Bool SAL_CALL AccessibleBrowseBoxBase::containsPoint( const css::awt::Point& rPoint )
212 return tools::Rectangle( Point(), getBoundingBox().GetSize() ).Contains( VCLPoint( rPoint ) );
215 awt::Rectangle SAL_CALL AccessibleBrowseBoxBase::getBounds()
217 return AWTRectangle( getBoundingBox() );
220 awt::Point SAL_CALL AccessibleBrowseBoxBase::getLocation()
222 return AWTPoint( getBoundingBox().TopLeft() );
225 awt::Point SAL_CALL AccessibleBrowseBoxBase::getLocationOnScreen()
227 return AWTPoint( getBoundingBoxOnScreen().TopLeft() );
230 awt::Size SAL_CALL AccessibleBrowseBoxBase::getSize()
232 return AWTSize( getBoundingBox().GetSize() );
235 void SAL_CALL AccessibleBrowseBoxBase::focusGained( const css::awt::FocusEvent& )
237 com::sun::star::uno::Any aFocused;
238 com::sun::star::uno::Any aEmpty;
239 aFocused <<= FOCUSED;
241 commitEvent(AccessibleEventId::STATE_CHANGED,aFocused,aEmpty);
245 void SAL_CALL AccessibleBrowseBoxBase::focusLost( const css::awt::FocusEvent& )
247 com::sun::star::uno::Any aFocused;
248 com::sun::star::uno::Any aEmpty;
249 aFocused <<= FOCUSED;
251 commitEvent(AccessibleEventId::STATE_CHANGED,aEmpty,aFocused);
253 // css::accessibility::XAccessibleEventBroadcaster
255 void SAL_CALL AccessibleBrowseBoxBase::addAccessibleEventListener(
256 const css::uno::Reference< css::accessibility::XAccessibleEventListener>& _rxListener )
258 if ( _rxListener.is() )
260 ::osl::MutexGuard aGuard( getMutex() );
261 if ( !getClientId( ) )
262 setClientId( AccessibleEventNotifier::registerClient( ) );
264 AccessibleEventNotifier::addEventListener( getClientId( ), _rxListener );
268 void SAL_CALL AccessibleBrowseBoxBase::removeAccessibleEventListener(
269 const css::uno::Reference< css::accessibility::XAccessibleEventListener>& _rxListener )
271 if( !(_rxListener.is() && getClientId( )) )
272 return;
274 ::osl::MutexGuard aGuard( getMutex() );
275 sal_Int32 nListenerCount = AccessibleEventNotifier::removeEventListener( getClientId( ), _rxListener );
276 if ( !nListenerCount )
278 // no listeners anymore
279 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
280 // and at least to us not firing any events anymore, in case somebody calls
281 // NotifyAccessibleEvent, again
283 AccessibleEventNotifier::TClientId nId( getClientId( ) );
284 setClientId( 0 );
285 AccessibleEventNotifier::revokeClient( nId );
289 // XTypeProvider
291 Sequence< sal_Int8 > SAL_CALL AccessibleBrowseBoxBase::getImplementationId()
293 return css::uno::Sequence<sal_Int8>();
296 // XServiceInfo
298 sal_Bool SAL_CALL AccessibleBrowseBoxBase::supportsService(
299 const OUString& rServiceName )
301 return cppu::supportsService(this, rServiceName);
304 Sequence< OUString > SAL_CALL AccessibleBrowseBoxBase::getSupportedServiceNames()
306 return { "com.sun.star.accessibility.AccessibleContext" };
309 // other public methods
311 void AccessibleBrowseBoxBase::setAccessibleName( const OUString& rName )
313 ::osl::ClearableMutexGuard aGuard( getMutex() );
314 Any aOld;
315 aOld <<= maName;
316 maName = rName;
318 aGuard.clear();
320 commitEvent(
321 AccessibleEventId::NAME_CHANGED,
322 uno::Any( maName ),
323 aOld );
326 void AccessibleBrowseBoxBase::setAccessibleDescription( const OUString& rDescription )
328 ::osl::ClearableMutexGuard aGuard( getMutex() );
329 Any aOld;
330 aOld <<= maDescription;
331 maDescription = rDescription;
333 aGuard.clear();
335 commitEvent(
336 AccessibleEventId::DESCRIPTION_CHANGED,
337 uno::Any( maDescription ),
338 aOld );
341 // internal virtual methods
343 bool AccessibleBrowseBoxBase::implIsShowing()
345 bool bShowing = false;
346 if( mxParent.is() )
348 css::uno::Reference< css::accessibility::XAccessibleComponent >
349 xParentComp( mxParent->getAccessibleContext(), uno::UNO_QUERY );
350 if( xParentComp.is() )
351 bShowing = implGetBoundingBox().Overlaps(
352 VCLRectangle( xParentComp->getBounds() ) );
354 return bShowing;
357 rtl::Reference<::utl::AccessibleStateSetHelper> AccessibleBrowseBoxBase::implCreateStateSetHelper()
359 rtl::Reference<::utl::AccessibleStateSetHelper>
360 pStateSetHelper = new ::utl::AccessibleStateSetHelper;
362 if( isAlive() )
364 // SHOWING done with mxParent
365 if( implIsShowing() )
366 pStateSetHelper->AddState( AccessibleStateType::SHOWING );
367 // BrowseBox fills StateSet with states depending on object type
368 mpBrowseBox->FillAccessibleStateSet( *pStateSetHelper, getType() );
370 else
371 pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
373 return pStateSetHelper;
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: */