Avoid potential negative array index access to cached text.
[LibreOffice.git] / chart2 / source / controller / accessibility / AccessibleBase.cxx
blob905c7f89696eea4f957014122f0bc7f9b3d1000e
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 <AccessibleBase.hxx>
21 #include "AccessibleChartShape.hxx"
22 #include <ObjectHierarchy.hxx>
23 #include <ObjectIdentifier.hxx>
24 #include <ChartView.hxx>
25 #include <ChartController.hxx>
26 #include <chartview/ExplicitValueProvider.hxx>
28 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
29 #include <com/sun/star/accessibility/AccessibleEventObject.hpp>
30 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
31 #include <com/sun/star/accessibility/AccessibleRole.hpp>
32 #include <com/sun/star/drawing/LineStyle.hpp>
33 #include <com/sun/star/drawing/FillStyle.hpp>
34 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
35 #include <com/sun/star/view/XSelectionSupplier.hpp>
36 #include <sal/log.hxx>
37 #include <utility>
38 #include <vcl/svapp.hxx>
39 #include <comphelper/servicehelper.hxx>
40 #include <cppuhelper/supportsservice.hxx>
41 #include <i18nlangtag/languagetag.hxx>
42 #include <toolkit/helper/vclunohelper.hxx>
43 #include <vcl/window.hxx>
44 #include <vcl/settings.hxx>
45 #include <o3tl/functional.hxx>
46 #include <o3tl/safeint.hxx>
47 #include <comphelper/diagnose_ex.hxx>
49 #include <algorithm>
50 #include <iterator>
52 #include "ChartElementFactory.hxx"
54 using namespace ::com::sun::star;
55 using namespace ::com::sun::star::accessibility;
57 using ::com::sun::star::uno::UNO_QUERY;
58 using ::com::sun::star::uno::Reference;
59 using ::osl::MutexGuard;
60 using ::osl::ClearableMutexGuard;
61 using ::com::sun::star::uno::Any;
63 namespace chart
66 /** @param bMayHaveChildren is false per default
68 AccessibleBase::AccessibleBase(
69 AccessibleElementInfo aAccInfo,
70 bool bMayHaveChildren,
71 bool bAlwaysTransparent /* default: false */ ) :
72 impl::AccessibleBase_Base( m_aMutex ),
73 m_bIsDisposed( false ),
74 m_bMayHaveChildren( bMayHaveChildren ),
75 m_bChildrenInitialized( false ),
76 m_nEventNotifierId(0),
77 m_nStateSet( 0 ),
78 m_aAccInfo(std::move( aAccInfo )),
79 m_bAlwaysTransparent( bAlwaysTransparent ),
80 m_bStateSetInitialized( false )
82 // initialize some states
83 m_nStateSet |= AccessibleStateType::ENABLED;
84 m_nStateSet |= AccessibleStateType::SHOWING;
85 m_nStateSet |= AccessibleStateType::VISIBLE;
86 m_nStateSet |= AccessibleStateType::SELECTABLE;
87 m_nStateSet |= AccessibleStateType::FOCUSABLE;
90 AccessibleBase::~AccessibleBase()
92 OSL_ASSERT( m_bIsDisposed );
95 bool AccessibleBase::CheckDisposeState( bool bThrowException /* default: true */ ) const
97 if( bThrowException &&
98 m_bIsDisposed )
100 throw lang::DisposedException("component has state DEFUNC",
101 static_cast< uno::XWeak * >( const_cast< AccessibleBase * >( this )));
103 return m_bIsDisposed;
106 bool AccessibleBase::NotifyEvent( EventType eEventType, const AccessibleUniqueId & rId )
108 if( GetId() == rId )
110 // event is addressed to this object
112 css::uno::Any aEmpty;
113 css::uno::Any aSelected;
114 aSelected <<= AccessibleStateType::SELECTED;
115 switch( eEventType )
117 case EventType::GOT_SELECTION:
119 AddState( AccessibleStateType::SELECTED );
120 BroadcastAccEvent( AccessibleEventId::STATE_CHANGED, aSelected, aEmpty );
122 AddState( AccessibleStateType::FOCUSED );
123 aSelected <<= AccessibleStateType::FOCUSED;
124 BroadcastAccEvent( AccessibleEventId::STATE_CHANGED, aSelected, aEmpty );
126 SAL_INFO("chart2.accessibility", "Selection acquired by: " << getAccessibleName());
128 break;
130 case EventType::LOST_SELECTION:
132 RemoveState( AccessibleStateType::SELECTED );
133 BroadcastAccEvent( AccessibleEventId::STATE_CHANGED, aEmpty, aSelected );
135 AddState( AccessibleStateType::FOCUSED );
136 aSelected <<= AccessibleStateType::FOCUSED;
137 BroadcastAccEvent( AccessibleEventId::STATE_CHANGED, aEmpty, aSelected );
138 SAL_INFO("chart2.accessibility", "Selection lost by: " << getAccessibleName());
140 break;
142 return true;
144 else if( m_bMayHaveChildren )
146 bool bStop = false;
148 ClearableMutexGuard aGuard( m_aMutex );
149 // make local copy for notification
150 ChildListVectorType aLocalChildList( m_aChildList );
151 aGuard.clear();
153 for (auto const& localChild : aLocalChildList)
155 // Note: at this place we must be sure to have an AccessibleBase
156 // object in the UNO reference to XAccessible !
157 bStop = (*static_cast< AccessibleBase * >
158 ( localChild.get() )).NotifyEvent( eEventType, rId );
159 if (bStop)
160 break;
162 return bStop;
165 return false;
168 void AccessibleBase::AddState( sal_Int64 aState )
170 CheckDisposeState();
171 m_nStateSet |= aState;
174 void AccessibleBase::RemoveState( sal_Int64 aState )
176 CheckDisposeState();
177 m_nStateSet &= ~aState;
180 bool AccessibleBase::UpdateChildren()
182 bool bMustUpdateChildren = false;
184 MutexGuard aGuard( m_aMutex );
185 if( ! m_bMayHaveChildren ||
186 m_bIsDisposed )
187 return false;
189 bMustUpdateChildren = ( m_bMayHaveChildren &&
190 ! m_bChildrenInitialized );
193 // update unguarded
194 if( bMustUpdateChildren )
195 m_bChildrenInitialized = ImplUpdateChildren();
197 return m_bChildrenInitialized;
200 bool AccessibleBase::ImplUpdateChildren()
202 bool bResult = false;
204 if( m_aAccInfo.m_spObjectHierarchy )
206 ObjectHierarchy::tChildContainer aModelChildren(
207 m_aAccInfo.m_spObjectHierarchy->getChildren( GetId() ));
208 std::vector< ChildOIDMap::key_type > aAccChildren;
209 aAccChildren.reserve( aModelChildren.size());
210 std::transform( m_aChildOIDMap.begin(), m_aChildOIDMap.end(),
211 std::back_inserter( aAccChildren ),
212 ::o3tl::select1st< ChildOIDMap::value_type >() );
214 std::sort( aModelChildren.begin(), aModelChildren.end());
216 std::vector< ObjectIdentifier > aChildrenToRemove, aChildrenToAdd;
217 std::set_difference( aModelChildren.begin(), aModelChildren.end(),
218 aAccChildren.begin(), aAccChildren.end(),
219 std::back_inserter( aChildrenToAdd ));
220 std::set_difference( aAccChildren.begin(), aAccChildren.end(),
221 aModelChildren.begin(), aModelChildren.end(),
222 std::back_inserter( aChildrenToRemove ));
224 for (auto const& childToRemove : aChildrenToRemove)
226 RemoveChildByOId(childToRemove);
229 AccessibleElementInfo aAccInfo( GetInfo());
230 aAccInfo.m_pParent = this;
232 for (auto const& childToAdd : aChildrenToAdd)
234 aAccInfo.m_aOID = childToAdd;
235 if ( childToAdd.isAutoGeneratedObject() )
237 AddChild( ChartElementFactory::CreateChartElement( aAccInfo ).get() );
239 else if ( childToAdd.isAdditionalShape() )
241 AddChild( new AccessibleChartShape( aAccInfo ) );
244 bResult = true;
247 return bResult;
250 void AccessibleBase::AddChild( AccessibleBase * pChild )
252 OSL_ENSURE( pChild != nullptr, "Invalid Child" );
253 if( !pChild )
254 return;
256 ClearableMutexGuard aGuard( m_aMutex );
258 Reference< XAccessible > xChild( pChild );
259 m_aChildList.push_back( xChild );
261 m_aChildOIDMap[ pChild->GetId() ] = xChild;
263 // inform listeners of new child
264 if( m_bChildrenInitialized )
266 Any aEmpty, aNew;
267 aNew <<= xChild;
269 aGuard.clear();
270 BroadcastAccEvent( AccessibleEventId::CHILD, aNew, aEmpty );
274 /** in this method we imply that the Reference< XAccessible > elements in the
275 vector are AccessibleBase objects !
277 void AccessibleBase::RemoveChildByOId( const ObjectIdentifier& rOId )
279 ClearableMutexGuard aGuard( m_aMutex );
281 ChildOIDMap::iterator aIt( m_aChildOIDMap.find( rOId ));
282 if( aIt == m_aChildOIDMap.end())
283 return;
285 Reference< XAccessible > xChild( aIt->second );
287 // remove from map
288 m_aChildOIDMap.erase( aIt );
290 // search child in vector
291 ChildListVectorType::iterator aVecIter =
292 std::find( m_aChildList.begin(), m_aChildList.end(), xChild );
294 OSL_ENSURE( aVecIter != m_aChildList.end(),
295 "Inconsistent ChildMap" );
297 // remove child from vector
298 m_aChildList.erase( aVecIter );
299 bool bInitialized = m_bChildrenInitialized;
301 // call listeners unguarded
302 aGuard.clear();
304 // inform listeners of removed child
305 if( bInitialized )
307 Any aEmpty, aOld;
308 aOld <<= xChild;
310 BroadcastAccEvent( AccessibleEventId::CHILD, aEmpty, aOld );
313 // dispose the child
314 Reference< lang::XComponent > xComp( xChild, UNO_QUERY );
315 if( xComp.is())
316 xComp->dispose();
319 awt::Point AccessibleBase::GetUpperLeftOnScreen() const
321 awt::Point aResult;
322 if( m_aAccInfo.m_pParent )
324 ClearableMutexGuard aGuard( m_aMutex );
325 AccessibleBase * pParent = m_aAccInfo.m_pParent;
326 aGuard.clear();
328 if( pParent )
330 aResult = pParent->GetUpperLeftOnScreen();
332 else
333 OSL_FAIL( "Default position used is probably incorrect." );
336 return aResult;
339 void AccessibleBase::BroadcastAccEvent(
340 sal_Int16 nId,
341 const Any & rNew,
342 const Any & rOld ) const
344 ClearableMutexGuard aGuard( m_aMutex );
346 if ( !m_nEventNotifierId )
347 return;
348 // if we don't have a client id for the notifier, then we don't have listeners, then
349 // we don't need to notify anything
351 // the const cast is needed, because UNO parameters are never const
352 const AccessibleEventObject aEvent(
353 const_cast< uno::XWeak * >( static_cast< const uno::XWeak * >( this )),
354 nId, rNew, rOld, -1 );
356 // let the notifier handle this event
357 ::comphelper::AccessibleEventNotifier::addEvent( m_nEventNotifierId, aEvent );
359 aGuard.clear();
362 void AccessibleBase::KillAllChildren()
364 ClearableMutexGuard aGuard( m_aMutex );
366 // make local copy for notification, and remove all children
367 ChildListVectorType aLocalChildList;
368 aLocalChildList.swap( m_aChildList );
369 m_aChildOIDMap.clear();
371 aGuard.clear();
373 // call dispose for all children
374 // and notify listeners
375 Reference< lang::XComponent > xComp;
376 Any aEmpty, aOld;
377 for (auto const& localChild : aLocalChildList)
379 aOld <<= localChild;
380 BroadcastAccEvent( AccessibleEventId::CHILD, aEmpty, aOld );
382 xComp.set(localChild, UNO_QUERY);
383 if( xComp.is())
384 xComp->dispose();
386 m_bChildrenInitialized = false;
389 void AccessibleBase::SetInfo( const AccessibleElementInfo & rNewInfo )
391 m_aAccInfo = rNewInfo;
392 if( m_bMayHaveChildren )
394 KillAllChildren();
396 BroadcastAccEvent( AccessibleEventId::INVALIDATE_ALL_CHILDREN, uno::Any(), uno::Any());
399 // ________ (XComponent::dispose) ________
400 void SAL_CALL AccessibleBase::disposing()
403 MutexGuard aGuard(m_aMutex);
404 OSL_ENSURE(!m_bIsDisposed, "dispose() called twice");
406 // notify disposing to all AccessibleEvent listeners asynchronous
407 if (m_nEventNotifierId)
409 ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing(m_nEventNotifierId,
410 *this);
411 m_nEventNotifierId = 0;
414 // reset pointers
415 m_aAccInfo.m_pParent = nullptr;
417 m_nStateSet = AccessibleStateType::DEFUNC;
419 m_bIsDisposed = true;
422 // call listeners unguarded
424 if( m_bMayHaveChildren )
426 KillAllChildren();
428 else
429 OSL_ENSURE( m_aChildList.empty(), "Child list should be empty" );
432 // ________ XAccessible ________
433 Reference< XAccessibleContext > SAL_CALL AccessibleBase::getAccessibleContext()
435 return this;
438 // ________ AccessibleBase::XAccessibleContext ________
439 sal_Int64 SAL_CALL AccessibleBase::getAccessibleChildCount()
441 ClearableMutexGuard aGuard( m_aMutex );
442 if( ! m_bMayHaveChildren ||
443 m_bIsDisposed )
444 return 0;
446 bool bMustUpdateChildren = ( m_bMayHaveChildren &&
447 ! m_bChildrenInitialized );
449 aGuard.clear();
451 // update unguarded
452 if( bMustUpdateChildren )
453 UpdateChildren();
455 return ImplGetAccessibleChildCount();
458 sal_Int64 AccessibleBase::ImplGetAccessibleChildCount() const
460 return m_aChildList.size();
463 Reference< XAccessible > SAL_CALL AccessibleBase::getAccessibleChild( sal_Int64 i )
465 CheckDisposeState();
466 Reference< XAccessible > xResult;
468 ClearableMutexGuard aGuard( m_aMutex );
469 bool bMustUpdateChildren = ( m_bMayHaveChildren &&
470 ! m_bChildrenInitialized );
472 aGuard.clear();
474 if( bMustUpdateChildren )
475 UpdateChildren();
477 xResult.set( ImplGetAccessibleChildById( i ));
479 return xResult;
482 Reference< XAccessible > AccessibleBase::ImplGetAccessibleChildById( sal_Int64 i ) const
484 Reference< XAccessible > xResult;
486 MutexGuard aGuard( m_aMutex);
487 if( ! m_bMayHaveChildren ||
488 i < 0 ||
489 o3tl::make_unsigned( i ) >= m_aChildList.size() )
491 OUString aBuf = "Index " + OUString::number( i ) + " is invalid for range [ 0, " +
492 OUString::number( m_aChildList.size() - 1 ) +
493 " ]";
494 lang::IndexOutOfBoundsException aEx( aBuf,
495 const_cast< ::cppu::OWeakObject * >(
496 static_cast< const ::cppu::OWeakObject * >( this )));
497 throw aEx;
499 else
500 xResult.set( m_aChildList[ i ] );
502 return xResult;
505 Reference< XAccessible > SAL_CALL AccessibleBase::getAccessibleParent()
507 CheckDisposeState();
508 Reference< XAccessible > aResult;
509 if( m_aAccInfo.m_pParent )
510 aResult.set( m_aAccInfo.m_pParent );
512 return aResult;
515 sal_Int64 SAL_CALL AccessibleBase::getAccessibleIndexInParent()
517 CheckDisposeState();
519 if( m_aAccInfo.m_spObjectHierarchy )
520 return m_aAccInfo.m_spObjectHierarchy->getIndexInParent( GetId() );
521 return -1;
524 sal_Int16 SAL_CALL AccessibleBase::getAccessibleRole()
526 return AccessibleRole::SHAPE;
529 Reference< XAccessibleRelationSet > SAL_CALL AccessibleBase::getAccessibleRelationSet()
531 Reference< XAccessibleRelationSet > aResult;
532 return aResult;
535 sal_Int64 SAL_CALL AccessibleBase::getAccessibleStateSet()
537 if( ! m_bStateSetInitialized )
539 rtl::Reference< ::chart::ChartController > xSelSupp( GetInfo().m_xChartController );
540 if ( xSelSupp.is() )
542 ObjectIdentifier aOID( xSelSupp->getSelection() );
543 if ( aOID.isValid() && GetId() == aOID )
545 AddState( AccessibleStateType::SELECTED );
546 AddState( AccessibleStateType::FOCUSED );
549 m_bStateSetInitialized = true;
552 return m_nStateSet;
555 lang::Locale SAL_CALL AccessibleBase::getLocale()
557 CheckDisposeState();
559 return Application::GetSettings().GetLanguageTag().getLocale();
562 // ________ AccessibleBase::XAccessibleComponent ________
563 sal_Bool SAL_CALL AccessibleBase::containsPoint( const awt::Point& aPoint )
565 awt::Rectangle aRect( getBounds() );
567 // contains() works with relative coordinates
568 aRect.X = 0;
569 aRect.Y = 0;
571 return ( aPoint.X >= aRect.X &&
572 aPoint.Y >= aRect.Y &&
573 aPoint.X < (aRect.X + aRect.Width) &&
574 aPoint.Y < (aRect.Y + aRect.Height) );
577 Reference< XAccessible > SAL_CALL AccessibleBase::getAccessibleAtPoint( const awt::Point& aPoint )
579 CheckDisposeState();
580 Reference< XAccessible > aResult;
581 awt::Rectangle aRect( getBounds());
583 // children are positioned relative to this object, so translate bound rect
584 aRect.X = 0;
585 aRect.Y = 0;
587 // children must be inside the own bound rect
588 if( ( aRect.X <= aPoint.X && aPoint.X <= (aRect.X + aRect.Width) ) &&
589 ( aRect.Y <= aPoint.Y && aPoint.Y <= (aRect.Y + aRect.Height)))
591 ClearableMutexGuard aGuard( m_aMutex );
592 ChildListVectorType aLocalChildList( m_aChildList );
593 aGuard.clear();
595 Reference< XAccessibleComponent > aComp;
596 for (auto const& localChild : aLocalChildList)
598 aComp.set(localChild, UNO_QUERY);
599 if( aComp.is())
601 aRect = aComp->getBounds();
602 if( ( aRect.X <= aPoint.X && aPoint.X <= (aRect.X + aRect.Width) ) &&
603 ( aRect.Y <= aPoint.Y && aPoint.Y <= (aRect.Y + aRect.Height)))
605 aResult = localChild;
606 break;
612 return aResult;
615 awt::Rectangle SAL_CALL AccessibleBase::getBounds()
617 rtl::Reference<ChartView> pChartView = m_aAccInfo.m_xView.get();
618 if( pChartView )
620 VclPtr<vcl::Window> pWindow( VCLUnoHelper::GetWindow( m_aAccInfo.m_xWindow ));
621 awt::Rectangle aLogicRect( pChartView->getRectangleOfObject( m_aAccInfo.m_aOID.getObjectCID() ));
622 if( pWindow )
624 tools::Rectangle aRect( aLogicRect.X, aLogicRect.Y,
625 aLogicRect.X + aLogicRect.Width,
626 aLogicRect.Y + aLogicRect.Height );
627 SolarMutexGuard aSolarGuard;
628 aRect = pWindow->LogicToPixel( aRect );
630 // aLogicRect is relative to the page, but we need a value relative
631 // to the parent object
632 awt::Point aParentLocOnScreen;
633 uno::Reference< XAccessibleComponent > xParent( getAccessibleParent(), uno::UNO_QUERY );
634 if( xParent.is() )
635 aParentLocOnScreen = xParent->getLocationOnScreen();
637 awt::Point aULOnScreen = GetUpperLeftOnScreen();
638 awt::Point aOffset( aParentLocOnScreen.X - aULOnScreen.X,
639 aParentLocOnScreen.Y - aULOnScreen.Y );
641 return awt::Rectangle( aRect.Left() - aOffset.X, aRect.Top() - aOffset.Y,
642 aRect.getOpenWidth(), aRect.getOpenHeight());
646 return awt::Rectangle();
649 awt::Point SAL_CALL AccessibleBase::getLocation()
651 CheckDisposeState();
652 awt::Rectangle aBBox( getBounds() );
653 return awt::Point( aBBox.X, aBBox.Y );
656 awt::Point SAL_CALL AccessibleBase::getLocationOnScreen()
658 CheckDisposeState();
660 if (AccessibleBase* pParent = m_aAccInfo.m_pParent)
662 awt::Point aLocThisRel( getLocation());
663 awt::Point aUpperLeft(pParent->getLocationOnScreen());
665 return awt::Point( aUpperLeft.X + aLocThisRel.X,
666 aUpperLeft.Y + aLocThisRel.Y );
668 else
669 return getLocation();
672 awt::Size SAL_CALL AccessibleBase::getSize()
674 CheckDisposeState();
675 awt::Rectangle aBBox( getBounds() );
676 return awt::Size( aBBox.Width, aBBox.Height );
679 void SAL_CALL AccessibleBase::grabFocus()
681 CheckDisposeState();
683 rtl::Reference< ::chart::ChartController > xSelSupp( GetInfo().m_xChartController );
684 if ( xSelSupp.is() )
686 xSelSupp->select( GetId().getAny() );
690 sal_Int32 SAL_CALL AccessibleBase::getForeground()
692 return sal_Int32(getColor( ACC_BASE_FOREGROUND ));
695 sal_Int32 SAL_CALL AccessibleBase::getBackground()
697 return sal_Int32(getColor( ACC_BASE_BACKGROUND ));
700 Color AccessibleBase::getColor( eColorType eColType )
702 Color nResult = COL_TRANSPARENT;
703 if( m_bAlwaysTransparent )
704 return nResult;
706 ObjectIdentifier aOID( m_aAccInfo.m_aOID );
707 ObjectType eType( aOID.getObjectType() );
708 Reference< beans::XPropertySet > xObjProp;
709 OUString aObjectCID = aOID.getObjectCID();
710 if( eType == OBJECTTYPE_LEGEND_ENTRY )
712 // for colors get the data series/point properties
713 std::u16string_view aParentParticle( ObjectIdentifier::getFullParentParticle( aObjectCID ));
714 aObjectCID = ObjectIdentifier::createClassifiedIdentifierForParticle( aParentParticle );
717 xObjProp =
718 ObjectIdentifier::getObjectPropertySet(
719 aObjectCID, m_aAccInfo.m_xChartDocument );
720 if( xObjProp.is())
724 OUString aPropName;
725 OUString aStylePropName;
727 switch( eType )
729 case OBJECTTYPE_LEGEND_ENTRY:
730 case OBJECTTYPE_DATA_SERIES:
731 case OBJECTTYPE_DATA_POINT:
732 if( eColType == ACC_BASE_FOREGROUND )
734 aPropName = "BorderColor";
735 aStylePropName = "BorderTransparency";
737 else
739 aPropName = "Color";
740 aStylePropName = "Transparency";
742 break;
743 default:
744 if( eColType == ACC_BASE_FOREGROUND )
746 aPropName = "LineColor";
747 aStylePropName = "LineTransparence";
749 else
751 aPropName = "FillColor";
752 aStylePropName = "FillTransparence";
754 break;
757 bool bTransparent = m_bAlwaysTransparent;
758 Reference< beans::XPropertySetInfo > xInfo = xObjProp->getPropertySetInfo();
759 if( xInfo.is() &&
760 xInfo->hasPropertyByName( aStylePropName ))
762 if( eColType == ACC_BASE_FOREGROUND )
764 drawing::LineStyle aLStyle;
765 if( xObjProp->getPropertyValue( aStylePropName ) >>= aLStyle )
766 bTransparent = (aLStyle == drawing::LineStyle_NONE);
768 else
770 drawing::FillStyle aFStyle;
771 if( xObjProp->getPropertyValue( aStylePropName ) >>= aFStyle )
772 bTransparent = (aFStyle == drawing::FillStyle_NONE);
776 if( !bTransparent &&
777 xInfo.is() &&
778 xInfo->hasPropertyByName( aPropName ))
780 xObjProp->getPropertyValue( aPropName ) >>= nResult;
783 catch( const uno::Exception & )
785 DBG_UNHANDLED_EXCEPTION("chart2");
789 return nResult;
792 // ________ AccessibleBase::XServiceInfo ________
793 OUString SAL_CALL AccessibleBase::getImplementationName()
795 return "AccessibleBase";
798 sal_Bool SAL_CALL AccessibleBase::supportsService( const OUString& ServiceName )
800 return cppu::supportsService( this, ServiceName );
803 uno::Sequence< OUString > SAL_CALL AccessibleBase::getSupportedServiceNames()
805 return {
806 "com.sun.star.accessibility.Accessible",
807 "com.sun.star.accessibility.AccessibleContext"
811 // ________ AccessibleBase::XEventListener ________
812 void SAL_CALL AccessibleBase::disposing( const lang::EventObject& /*Source*/ )
816 // ________ XAccessibleEventBroadcasters ________
817 void SAL_CALL AccessibleBase::addAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener )
819 MutexGuard aGuard( m_aMutex );
821 if ( xListener.is() )
823 if ( !m_nEventNotifierId )
824 m_nEventNotifierId = ::comphelper::AccessibleEventNotifier::registerClient();
826 ::comphelper::AccessibleEventNotifier::addEventListener( m_nEventNotifierId, xListener );
830 void SAL_CALL AccessibleBase::removeAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener )
832 MutexGuard aGuard( m_aMutex );
834 if ( xListener.is() && m_nEventNotifierId)
836 sal_Int32 nListenerCount = ::comphelper::AccessibleEventNotifier::removeEventListener( m_nEventNotifierId, xListener );
837 if ( !nListenerCount )
839 // no listeners anymore
840 ::comphelper::AccessibleEventNotifier::revokeClient( m_nEventNotifierId );
841 m_nEventNotifierId = 0;
846 } // namespace chart
848 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */