tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / chart2 / source / controller / accessibility / AccessibleBase.cxx
blobd73724587c22543ebb3107fcc3cb64cf1d29fecd
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>
27 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
28 #include <com/sun/star/accessibility/AccessibleEventObject.hpp>
29 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
30 #include <com/sun/star/accessibility/AccessibleRole.hpp>
31 #include <com/sun/star/drawing/LineStyle.hpp>
32 #include <com/sun/star/drawing/FillStyle.hpp>
33 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
34 #include <sal/log.hxx>
35 #include <utility>
36 #include <vcl/svapp.hxx>
37 #include <cppuhelper/supportsservice.hxx>
38 #include <i18nlangtag/languagetag.hxx>
39 #include <toolkit/helper/vclunohelper.hxx>
40 #include <vcl/window.hxx>
41 #include <vcl/settings.hxx>
42 #include <o3tl/functional.hxx>
43 #include <o3tl/safeint.hxx>
44 #include <comphelper/diagnose_ex.hxx>
46 #include <algorithm>
47 #include <iterator>
49 #include "ChartElementFactory.hxx"
51 using namespace ::com::sun::star;
52 using namespace ::com::sun::star::accessibility;
54 using ::com::sun::star::uno::UNO_QUERY;
55 using ::com::sun::star::uno::Reference;
56 using ::osl::MutexGuard;
57 using ::osl::ClearableMutexGuard;
58 using ::com::sun::star::uno::Any;
60 namespace chart
63 /** @param bMayHaveChildren is false per default
65 AccessibleBase::AccessibleBase(
66 AccessibleElementInfo aAccInfo,
67 bool bMayHaveChildren,
68 bool bAlwaysTransparent /* default: false */ ) :
69 impl::AccessibleBase_Base( m_aMutex ),
70 m_bIsDisposed( false ),
71 m_bMayHaveChildren( bMayHaveChildren ),
72 m_bChildrenInitialized( false ),
73 m_nEventNotifierId(0),
74 m_nStateSet( 0 ),
75 m_aAccInfo(std::move( aAccInfo )),
76 m_bAlwaysTransparent( bAlwaysTransparent ),
77 m_bStateSetInitialized( false )
79 // initialize some states
80 m_nStateSet |= AccessibleStateType::ENABLED;
81 m_nStateSet |= AccessibleStateType::SHOWING;
82 m_nStateSet |= AccessibleStateType::VISIBLE;
83 m_nStateSet |= AccessibleStateType::SELECTABLE;
84 m_nStateSet |= AccessibleStateType::FOCUSABLE;
87 AccessibleBase::~AccessibleBase()
89 OSL_ASSERT( m_bIsDisposed );
92 bool AccessibleBase::CheckDisposeState( bool bThrowException /* default: true */ ) const
94 if( bThrowException &&
95 m_bIsDisposed )
97 throw lang::DisposedException(u"component has state DEFUNC"_ustr,
98 static_cast< uno::XWeak * >( const_cast< AccessibleBase * >( this )));
100 return m_bIsDisposed;
103 bool AccessibleBase::NotifyEvent( EventType eEventType, const AccessibleUniqueId & rId )
105 if( GetId() == rId )
107 // event is addressed to this object
109 css::uno::Any aEmpty;
110 css::uno::Any aSelected;
111 aSelected <<= AccessibleStateType::SELECTED;
112 switch( eEventType )
114 case EventType::GOT_SELECTION:
116 AddState( AccessibleStateType::SELECTED );
117 BroadcastAccEvent( AccessibleEventId::STATE_CHANGED, aSelected, aEmpty );
119 AddState( AccessibleStateType::FOCUSED );
120 aSelected <<= AccessibleStateType::FOCUSED;
121 BroadcastAccEvent( AccessibleEventId::STATE_CHANGED, aSelected, aEmpty );
123 SAL_INFO("chart2.accessibility", "Selection acquired by: " << getAccessibleName());
125 break;
127 case EventType::LOST_SELECTION:
129 RemoveState( AccessibleStateType::SELECTED );
130 BroadcastAccEvent( AccessibleEventId::STATE_CHANGED, aEmpty, aSelected );
132 AddState( AccessibleStateType::FOCUSED );
133 aSelected <<= AccessibleStateType::FOCUSED;
134 BroadcastAccEvent( AccessibleEventId::STATE_CHANGED, aEmpty, aSelected );
135 SAL_INFO("chart2.accessibility", "Selection lost by: " << getAccessibleName());
137 break;
139 return true;
141 else if( m_bMayHaveChildren )
143 bool bStop = false;
145 ClearableMutexGuard aGuard( m_aMutex );
146 // make local copy for notification
147 std::vector<Reference<XAccessible>> aLocalChildList(m_aChildList);
148 aGuard.clear();
150 for (auto const& localChild : aLocalChildList)
152 // Note: at this place we must be sure to have an AccessibleBase
153 // object in the UNO reference to XAccessible !
154 bStop = (*static_cast< AccessibleBase * >
155 ( localChild.get() )).NotifyEvent( eEventType, rId );
156 if (bStop)
157 break;
159 return bStop;
162 return false;
165 void AccessibleBase::AddState( sal_Int64 aState )
167 CheckDisposeState();
168 m_nStateSet |= aState;
171 void AccessibleBase::RemoveState( sal_Int64 aState )
173 CheckDisposeState();
174 m_nStateSet &= ~aState;
177 bool AccessibleBase::UpdateChildren()
179 bool bMustUpdateChildren = false;
181 MutexGuard aGuard( m_aMutex );
182 if( ! m_bMayHaveChildren ||
183 m_bIsDisposed )
184 return false;
186 bMustUpdateChildren = ( m_bMayHaveChildren &&
187 ! m_bChildrenInitialized );
190 // update unguarded
191 if( bMustUpdateChildren )
192 m_bChildrenInitialized = ImplUpdateChildren();
194 return m_bChildrenInitialized;
197 bool AccessibleBase::ImplUpdateChildren()
199 bool bResult = false;
201 if( m_aAccInfo.m_spObjectHierarchy )
203 ObjectHierarchy::tChildContainer aModelChildren(
204 m_aAccInfo.m_spObjectHierarchy->getChildren( GetId() ));
205 std::vector< ChildOIDMap::key_type > aAccChildren;
206 aAccChildren.reserve( aModelChildren.size());
207 std::transform( m_aChildOIDMap.begin(), m_aChildOIDMap.end(),
208 std::back_inserter( aAccChildren ),
209 ::o3tl::select1st< ChildOIDMap::value_type >() );
211 std::sort( aModelChildren.begin(), aModelChildren.end());
213 std::vector< ObjectIdentifier > aChildrenToRemove, aChildrenToAdd;
214 std::set_difference( aModelChildren.begin(), aModelChildren.end(),
215 aAccChildren.begin(), aAccChildren.end(),
216 std::back_inserter( aChildrenToAdd ));
217 std::set_difference( aAccChildren.begin(), aAccChildren.end(),
218 aModelChildren.begin(), aModelChildren.end(),
219 std::back_inserter( aChildrenToRemove ));
221 for (auto const& childToRemove : aChildrenToRemove)
223 RemoveChildByOId(childToRemove);
226 AccessibleElementInfo aAccInfo( GetInfo());
227 aAccInfo.m_pParent = this;
229 for (auto const& childToAdd : aChildrenToAdd)
231 aAccInfo.m_aOID = childToAdd;
232 if ( childToAdd.isAutoGeneratedObject() )
234 AddChild( ChartElementFactory::CreateChartElement( aAccInfo ).get() );
236 else if ( childToAdd.isAdditionalShape() )
238 AddChild( new AccessibleChartShape( aAccInfo ) );
241 bResult = true;
244 return bResult;
247 void AccessibleBase::AddChild( AccessibleBase * pChild )
249 OSL_ENSURE( pChild != nullptr, "Invalid Child" );
250 if( !pChild )
251 return;
253 ClearableMutexGuard aGuard( m_aMutex );
255 Reference< XAccessible > xChild( pChild );
256 m_aChildList.push_back( xChild );
258 m_aChildOIDMap[ pChild->GetId() ] = xChild;
260 // inform listeners of new child
261 if( m_bChildrenInitialized )
263 Any aEmpty, aNew;
264 aNew <<= xChild;
266 aGuard.clear();
267 BroadcastAccEvent( AccessibleEventId::CHILD, aNew, aEmpty );
271 /** in this method we imply that the Reference< XAccessible > elements in the
272 vector are AccessibleBase objects !
274 void AccessibleBase::RemoveChildByOId( const ObjectIdentifier& rOId )
276 ClearableMutexGuard aGuard( m_aMutex );
278 ChildOIDMap::iterator aIt( m_aChildOIDMap.find( rOId ));
279 if( aIt == m_aChildOIDMap.end())
280 return;
282 Reference< XAccessible > xChild( aIt->second );
284 // remove from map
285 m_aChildOIDMap.erase( aIt );
287 // search child in vector
288 auto aVecIter = std::find(m_aChildList.begin(), m_aChildList.end(), xChild);
290 OSL_ENSURE( aVecIter != m_aChildList.end(),
291 "Inconsistent ChildMap" );
293 // remove child from vector
294 m_aChildList.erase( aVecIter );
295 bool bInitialized = m_bChildrenInitialized;
297 // call listeners unguarded
298 aGuard.clear();
300 // inform listeners of removed child
301 if( bInitialized )
303 Any aEmpty, aOld;
304 aOld <<= xChild;
306 BroadcastAccEvent( AccessibleEventId::CHILD, aEmpty, aOld );
309 // dispose the child
310 Reference< lang::XComponent > xComp( xChild, UNO_QUERY );
311 if( xComp.is())
312 xComp->dispose();
315 awt::Point AccessibleBase::GetUpperLeftOnScreen() const
317 awt::Point aResult;
318 if( m_aAccInfo.m_pParent )
320 ClearableMutexGuard aGuard( m_aMutex );
321 AccessibleBase * pParent = m_aAccInfo.m_pParent;
322 aGuard.clear();
324 if( pParent )
326 aResult = pParent->GetUpperLeftOnScreen();
328 else
329 OSL_FAIL( "Default position used is probably incorrect." );
332 return aResult;
335 void AccessibleBase::BroadcastAccEvent(
336 sal_Int16 nId,
337 const Any & rNew,
338 const Any & rOld ) const
340 ClearableMutexGuard aGuard( m_aMutex );
342 if ( !m_nEventNotifierId )
343 return;
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
347 // the const cast is needed, because UNO parameters are never const
348 const AccessibleEventObject aEvent(
349 const_cast< uno::XWeak * >( static_cast< const uno::XWeak * >( this )),
350 nId, rNew, rOld, -1 );
352 // let the notifier handle this event
353 ::comphelper::AccessibleEventNotifier::addEvent( m_nEventNotifierId, aEvent );
355 aGuard.clear();
358 void AccessibleBase::KillAllChildren()
360 ClearableMutexGuard aGuard( m_aMutex );
362 // make local copy for notification, and remove all children
363 std::vector<Reference<XAccessible>> aLocalChildList;
364 aLocalChildList.swap( m_aChildList );
365 m_aChildOIDMap.clear();
367 aGuard.clear();
369 // call dispose for all children
370 // and notify listeners
371 Reference< lang::XComponent > xComp;
372 Any aEmpty, aOld;
373 for (auto const& localChild : aLocalChildList)
375 aOld <<= localChild;
376 BroadcastAccEvent( AccessibleEventId::CHILD, aEmpty, aOld );
378 xComp.set(localChild, UNO_QUERY);
379 if( xComp.is())
380 xComp->dispose();
382 m_bChildrenInitialized = false;
385 void AccessibleBase::SetInfo( const AccessibleElementInfo & rNewInfo )
387 m_aAccInfo = rNewInfo;
388 if( m_bMayHaveChildren )
390 KillAllChildren();
392 BroadcastAccEvent( AccessibleEventId::INVALIDATE_ALL_CHILDREN, uno::Any(), uno::Any());
395 // ________ (XComponent::dispose) ________
396 void SAL_CALL AccessibleBase::disposing()
399 MutexGuard aGuard(m_aMutex);
400 OSL_ENSURE(!m_bIsDisposed, "dispose() called twice");
402 // notify disposing to all AccessibleEvent listeners asynchronous
403 if (m_nEventNotifierId)
405 ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing(m_nEventNotifierId,
406 *this);
407 m_nEventNotifierId = 0;
410 // reset pointers
411 m_aAccInfo.m_pParent = nullptr;
413 m_nStateSet = AccessibleStateType::DEFUNC;
415 m_bIsDisposed = true;
418 // call listeners unguarded
420 if( m_bMayHaveChildren )
422 KillAllChildren();
424 else
425 OSL_ENSURE( m_aChildList.empty(), "Child list should be empty" );
428 // ________ XAccessible ________
429 Reference< XAccessibleContext > SAL_CALL AccessibleBase::getAccessibleContext()
431 return this;
434 // ________ AccessibleBase::XAccessibleContext ________
435 sal_Int64 SAL_CALL AccessibleBase::getAccessibleChildCount()
437 ClearableMutexGuard aGuard( m_aMutex );
438 if( ! m_bMayHaveChildren ||
439 m_bIsDisposed )
440 return 0;
442 bool bMustUpdateChildren = ( m_bMayHaveChildren &&
443 ! m_bChildrenInitialized );
445 aGuard.clear();
447 // update unguarded
448 if( bMustUpdateChildren )
449 UpdateChildren();
451 return ImplGetAccessibleChildCount();
454 sal_Int64 AccessibleBase::ImplGetAccessibleChildCount() const
456 return m_aChildList.size();
459 Reference< XAccessible > SAL_CALL AccessibleBase::getAccessibleChild( sal_Int64 i )
461 CheckDisposeState();
462 Reference< XAccessible > xResult;
464 ClearableMutexGuard aGuard( m_aMutex );
465 bool bMustUpdateChildren = ( m_bMayHaveChildren &&
466 ! m_bChildrenInitialized );
468 aGuard.clear();
470 if( bMustUpdateChildren )
471 UpdateChildren();
473 xResult.set( ImplGetAccessibleChildById( i ));
475 return xResult;
478 Reference< XAccessible > AccessibleBase::ImplGetAccessibleChildById( sal_Int64 i ) const
480 Reference< XAccessible > xResult;
482 MutexGuard aGuard( m_aMutex);
483 if( ! m_bMayHaveChildren ||
484 i < 0 ||
485 o3tl::make_unsigned( i ) >= m_aChildList.size() )
487 OUString aBuf = "Index " + OUString::number( i ) + " is invalid for range [ 0, " +
488 OUString::number( m_aChildList.size() - 1 ) +
489 " ]";
490 lang::IndexOutOfBoundsException aEx( aBuf,
491 const_cast< ::cppu::OWeakObject * >(
492 static_cast< const ::cppu::OWeakObject * >( this )));
493 throw aEx;
495 else
496 xResult.set( m_aChildList[ i ] );
498 return xResult;
501 Reference< XAccessible > SAL_CALL AccessibleBase::getAccessibleParent()
503 CheckDisposeState();
504 Reference< XAccessible > aResult;
505 if( m_aAccInfo.m_pParent )
506 aResult.set( m_aAccInfo.m_pParent );
508 return aResult;
511 sal_Int64 SAL_CALL AccessibleBase::getAccessibleIndexInParent()
513 CheckDisposeState();
515 if( m_aAccInfo.m_spObjectHierarchy )
516 return m_aAccInfo.m_spObjectHierarchy->getIndexInParent( GetId() );
517 return -1;
520 sal_Int16 SAL_CALL AccessibleBase::getAccessibleRole()
522 return AccessibleRole::SHAPE;
525 Reference< XAccessibleRelationSet > SAL_CALL AccessibleBase::getAccessibleRelationSet()
527 Reference< XAccessibleRelationSet > aResult;
528 return aResult;
531 sal_Int64 SAL_CALL AccessibleBase::getAccessibleStateSet()
533 if( ! m_bStateSetInitialized )
535 rtl::Reference< ::chart::ChartController > xSelSupp( GetInfo().m_xChartController );
536 if ( xSelSupp.is() )
538 ObjectIdentifier aOID( xSelSupp->getSelection() );
539 if ( aOID.isValid() && GetId() == aOID )
541 AddState( AccessibleStateType::SELECTED );
542 AddState( AccessibleStateType::FOCUSED );
545 m_bStateSetInitialized = true;
548 return m_nStateSet;
551 lang::Locale SAL_CALL AccessibleBase::getLocale()
553 CheckDisposeState();
555 return Application::GetSettings().GetLanguageTag().getLocale();
558 // ________ AccessibleBase::XAccessibleComponent ________
559 sal_Bool SAL_CALL AccessibleBase::containsPoint( const awt::Point& aPoint )
561 awt::Rectangle aRect( getBounds() );
563 // contains() works with relative coordinates
564 aRect.X = 0;
565 aRect.Y = 0;
567 return ( aPoint.X >= aRect.X &&
568 aPoint.Y >= aRect.Y &&
569 aPoint.X < (aRect.X + aRect.Width) &&
570 aPoint.Y < (aRect.Y + aRect.Height) );
573 Reference< XAccessible > SAL_CALL AccessibleBase::getAccessibleAtPoint( const awt::Point& aPoint )
575 CheckDisposeState();
576 Reference< XAccessible > aResult;
577 awt::Rectangle aRect( getBounds());
579 // children are positioned relative to this object, so translate bound rect
580 aRect.X = 0;
581 aRect.Y = 0;
583 // children must be inside the own bound rect
584 if( ( aRect.X <= aPoint.X && aPoint.X <= (aRect.X + aRect.Width) ) &&
585 ( aRect.Y <= aPoint.Y && aPoint.Y <= (aRect.Y + aRect.Height)))
587 ClearableMutexGuard aGuard( m_aMutex );
588 std::vector<Reference<XAccessible>> aLocalChildList( m_aChildList );
589 aGuard.clear();
591 Reference< XAccessibleComponent > aComp;
592 for (auto const& localChild : aLocalChildList)
594 aComp.set(localChild, UNO_QUERY);
595 if( aComp.is())
597 aRect = aComp->getBounds();
598 if( ( aRect.X <= aPoint.X && aPoint.X <= (aRect.X + aRect.Width) ) &&
599 ( aRect.Y <= aPoint.Y && aPoint.Y <= (aRect.Y + aRect.Height)))
601 aResult = localChild;
602 break;
608 return aResult;
611 awt::Rectangle SAL_CALL AccessibleBase::getBounds()
613 rtl::Reference<ChartView> pChartView = m_aAccInfo.m_xView.get();
614 if( pChartView )
616 VclPtr<vcl::Window> pWindow( VCLUnoHelper::GetWindow( m_aAccInfo.m_xWindow ));
617 awt::Rectangle aLogicRect( pChartView->getRectangleOfObject( m_aAccInfo.m_aOID.getObjectCID() ));
618 if( pWindow )
620 tools::Rectangle aRect( aLogicRect.X, aLogicRect.Y,
621 aLogicRect.X + aLogicRect.Width,
622 aLogicRect.Y + aLogicRect.Height );
623 SolarMutexGuard aSolarGuard;
624 aRect = pWindow->LogicToPixel( aRect );
626 // aLogicRect is relative to the page, but we need a value relative
627 // to the parent object
628 awt::Point aParentLocOnScreen;
629 uno::Reference< XAccessibleComponent > xParent( getAccessibleParent(), uno::UNO_QUERY );
630 if( xParent.is() )
631 aParentLocOnScreen = xParent->getLocationOnScreen();
633 awt::Point aULOnScreen = GetUpperLeftOnScreen();
634 awt::Point aOffset( aParentLocOnScreen.X - aULOnScreen.X,
635 aParentLocOnScreen.Y - aULOnScreen.Y );
637 return awt::Rectangle( aRect.Left() - aOffset.X, aRect.Top() - aOffset.Y,
638 aRect.getOpenWidth(), aRect.getOpenHeight());
642 return awt::Rectangle();
645 awt::Point SAL_CALL AccessibleBase::getLocation()
647 CheckDisposeState();
648 awt::Rectangle aBBox( getBounds() );
649 return awt::Point( aBBox.X, aBBox.Y );
652 awt::Point SAL_CALL AccessibleBase::getLocationOnScreen()
654 CheckDisposeState();
656 if (AccessibleBase* pParent = m_aAccInfo.m_pParent)
658 awt::Point aLocThisRel( getLocation());
659 awt::Point aUpperLeft(pParent->getLocationOnScreen());
661 return awt::Point( aUpperLeft.X + aLocThisRel.X,
662 aUpperLeft.Y + aLocThisRel.Y );
664 else
665 return getLocation();
668 awt::Size SAL_CALL AccessibleBase::getSize()
670 CheckDisposeState();
671 awt::Rectangle aBBox( getBounds() );
672 return awt::Size( aBBox.Width, aBBox.Height );
675 void SAL_CALL AccessibleBase::grabFocus()
677 CheckDisposeState();
679 rtl::Reference< ::chart::ChartController > xSelSupp( GetInfo().m_xChartController );
680 if ( xSelSupp.is() )
682 xSelSupp->select( GetId().getAny() );
686 sal_Int32 SAL_CALL AccessibleBase::getForeground()
688 return sal_Int32(getColor( ACC_BASE_FOREGROUND ));
691 sal_Int32 SAL_CALL AccessibleBase::getBackground()
693 return sal_Int32(getColor( ACC_BASE_BACKGROUND ));
696 Color AccessibleBase::getColor( eColorType eColType )
698 Color nResult = COL_TRANSPARENT;
699 if( m_bAlwaysTransparent )
700 return nResult;
702 ObjectIdentifier aOID( m_aAccInfo.m_aOID );
703 ObjectType eType( aOID.getObjectType() );
704 Reference< beans::XPropertySet > xObjProp;
705 OUString aObjectCID = aOID.getObjectCID();
706 if( eType == OBJECTTYPE_LEGEND_ENTRY )
708 // for colors get the data series/point properties
709 std::u16string_view aParentParticle( ObjectIdentifier::getFullParentParticle( aObjectCID ));
710 aObjectCID = ObjectIdentifier::createClassifiedIdentifierForParticle( aParentParticle );
713 xObjProp =
714 ObjectIdentifier::getObjectPropertySet(
715 aObjectCID, m_aAccInfo.m_xChartDocument );
716 if( xObjProp.is())
720 OUString aPropName;
721 OUString aStylePropName;
723 switch( eType )
725 case OBJECTTYPE_LEGEND_ENTRY:
726 case OBJECTTYPE_DATA_SERIES:
727 case OBJECTTYPE_DATA_POINT:
728 if( eColType == ACC_BASE_FOREGROUND )
730 aPropName = "BorderColor";
731 aStylePropName = "BorderTransparency";
733 else
735 aPropName = "Color";
736 aStylePropName = "Transparency";
738 break;
739 default:
740 if( eColType == ACC_BASE_FOREGROUND )
742 aPropName = "LineColor";
743 aStylePropName = "LineTransparence";
745 else
747 aPropName = "FillColor";
748 aStylePropName = "FillTransparence";
750 break;
753 bool bTransparent = m_bAlwaysTransparent;
754 Reference< beans::XPropertySetInfo > xInfo = xObjProp->getPropertySetInfo();
755 if( xInfo.is() &&
756 xInfo->hasPropertyByName( aStylePropName ))
758 if( eColType == ACC_BASE_FOREGROUND )
760 drawing::LineStyle aLStyle = drawing::LineStyle_SOLID;
761 if( xObjProp->getPropertyValue( aStylePropName ) >>= aLStyle )
762 bTransparent = (aLStyle == drawing::LineStyle_NONE);
764 else
766 drawing::FillStyle aFStyle = drawing::FillStyle_SOLID;
767 if( xObjProp->getPropertyValue( aStylePropName ) >>= aFStyle )
768 bTransparent = (aFStyle == drawing::FillStyle_NONE);
772 if( !bTransparent &&
773 xInfo.is() &&
774 xInfo->hasPropertyByName( aPropName ))
776 xObjProp->getPropertyValue( aPropName ) >>= nResult;
779 catch( const uno::Exception & )
781 DBG_UNHANDLED_EXCEPTION("chart2");
785 return nResult;
788 // ________ AccessibleBase::XServiceInfo ________
789 OUString SAL_CALL AccessibleBase::getImplementationName()
791 return u"AccessibleBase"_ustr;
794 sal_Bool SAL_CALL AccessibleBase::supportsService( const OUString& ServiceName )
796 return cppu::supportsService( this, ServiceName );
799 uno::Sequence< OUString > SAL_CALL AccessibleBase::getSupportedServiceNames()
801 return {
802 u"com.sun.star.accessibility.Accessible"_ustr,
803 u"com.sun.star.accessibility.AccessibleContext"_ustr
807 // ________ AccessibleBase::XEventListener ________
808 void SAL_CALL AccessibleBase::disposing( const lang::EventObject& /*Source*/ )
812 // ________ XAccessibleEventBroadcasters ________
813 void SAL_CALL AccessibleBase::addAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener )
815 MutexGuard aGuard( m_aMutex );
817 if ( xListener.is() )
819 if ( !m_nEventNotifierId )
820 m_nEventNotifierId = ::comphelper::AccessibleEventNotifier::registerClient();
822 ::comphelper::AccessibleEventNotifier::addEventListener( m_nEventNotifierId, xListener );
826 void SAL_CALL AccessibleBase::removeAccessibleEventListener( const Reference< XAccessibleEventListener >& xListener )
828 MutexGuard aGuard( m_aMutex );
830 if ( xListener.is() && m_nEventNotifierId)
832 sal_Int32 nListenerCount = ::comphelper::AccessibleEventNotifier::removeEventListener( m_nEventNotifierId, xListener );
833 if ( !nListenerCount )
835 // no listeners anymore
836 ::comphelper::AccessibleEventNotifier::revokeClient( m_nEventNotifierId );
837 m_nEventNotifierId = 0;
842 } // namespace chart
844 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */