merge the formfield patch from ooo-build
[ooovba.git] / chart2 / source / controller / accessibility / AccessibleBase.cxx
blobdebb973617d3964e5cc1086d8a6fa2ee0877c032
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: AccessibleBase.cxx,v $
10 * $Revision: 1.5 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_chart2.hxx"
34 #include "AccessibleBase.hxx"
35 #include "ObjectHierarchy.hxx"
36 #include "ObjectIdentifier.hxx"
37 #include "chartview/ExplicitValueProvider.hxx"
38 #include "macros.hxx"
40 #include <com/sun/star/awt/XDevice.hpp>
41 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
42 #include <com/sun/star/accessibility/AccessibleEventObject.hpp>
43 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
44 #include <com/sun/star/accessibility/AccessibleRole.hpp>
46 #include <com/sun/star/drawing/LineStyle.hpp>
47 #include <com/sun/star/drawing/FillStyle.hpp>
48 #include <rtl/ustrbuf.hxx>
49 // for SolarMutex
50 #include <vcl/svapp.hxx>
51 #include <rtl/uuid.h>
52 #include <cppuhelper/queryinterface.hxx>
53 #include <svtools/itemset.hxx>
54 #include <svx/unofdesc.hxx>
55 #include <svx/outliner.hxx>
56 #include <svx/svdoutl.hxx>
57 #include <svx/svdetc.hxx>
58 #include <svx/unoshape.hxx>
59 #include <svx/unoprov.hxx>
60 #include <vcl/unohelp.hxx>
61 #include <toolkit/helper/vclunohelper.hxx>
62 #include <vcl/window.hxx>
64 #include <algorithm>
66 #include "ChartElementFactory.hxx"
68 using namespace ::com::sun::star;
69 using namespace ::com::sun::star::accessibility;
71 using ::com::sun::star::uno::UNO_QUERY;
72 using ::rtl::OUString;
73 using ::rtl::OUStringBuffer;
74 using ::com::sun::star::uno::Reference;
75 using ::osl::MutexGuard;
76 using ::osl::ClearableMutexGuard;
77 using ::osl::ResettableMutexGuard;
78 using ::com::sun::star::uno::RuntimeException;
79 using ::com::sun::star::uno::Any;
81 namespace chart
84 /** @param bMayHaveChildren is false per default
86 AccessibleBase::AccessibleBase(
87 const AccessibleElementInfo & rAccInfo,
88 bool bMayHaveChildren,
89 bool bAlwaysTransparent /* default: false */ ) :
90 impl::AccessibleBase_Base( m_aMutex ),
91 m_bIsDisposed( false ),
92 m_bMayHaveChildren( bMayHaveChildren ),
93 m_bChildrenInitialized( false ),
94 m_nEventNotifierId(0),
95 m_pStateSetHelper( new ::utl::AccessibleStateSetHelper() ),
96 m_aStateSet( m_pStateSetHelper ),
97 m_aAccInfo( rAccInfo ),
98 m_bAlwaysTransparent( bAlwaysTransparent ),
99 m_bStateSetInitialized( false )
101 // initialize some states
102 OSL_ASSERT( m_pStateSetHelper );
103 m_pStateSetHelper->AddState( AccessibleStateType::ENABLED );
104 m_pStateSetHelper->AddState( AccessibleStateType::SHOWING );
105 m_pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
106 m_pStateSetHelper->AddState( AccessibleStateType::SELECTABLE );
107 m_pStateSetHelper->AddState( AccessibleStateType::FOCUSABLE );
110 AccessibleBase::~AccessibleBase()
112 OSL_ASSERT( m_bIsDisposed );
115 // ________ public ________
117 bool AccessibleBase::CheckDisposeState( bool bThrowException /* default: true */ ) const
118 throw (lang::DisposedException)
120 if( bThrowException &&
121 m_bIsDisposed )
123 throw lang::DisposedException(
124 C2U("component has state DEFUNC" ),
125 static_cast< uno::XWeak * >( const_cast< AccessibleBase * >( this )));
127 return m_bIsDisposed;
130 bool AccessibleBase::NotifyEvent( EventType eEventType, const AccessibleUniqueId & rId )
132 if( GetId() == rId )
134 // event is addressed to this object
136 ::com::sun::star::uno::Any aEmpty;
137 ::com::sun::star::uno::Any aSelected;
138 aSelected <<= AccessibleStateType::SELECTED;
139 switch( eEventType )
141 case OBJECT_CHANGE:
143 BroadcastAccEvent( AccessibleEventId::VISIBLE_DATA_CHANGED, aEmpty, aEmpty );
144 #if OSL_DEBUG_LEVEL > 1
145 OSL_TRACE(
146 ::rtl::OUStringToOString(
147 OUString( RTL_CONSTASCII_USTRINGPARAM(
148 "Visible data event sent by: " )) +
149 getAccessibleName(),
150 RTL_TEXTENCODING_ASCII_US ).getStr() );
151 #endif
153 break;
155 case GOT_SELECTION:
157 AddState( AccessibleStateType::SELECTED );
158 BroadcastAccEvent( AccessibleEventId::STATE_CHANGED, aSelected, aEmpty );
160 AddState( AccessibleStateType::FOCUSED );
161 aSelected <<= AccessibleStateType::FOCUSED;
162 BroadcastAccEvent( AccessibleEventId::STATE_CHANGED, aSelected, aEmpty, true );
163 #if OSL_DEBUG_LEVEL > 1
164 OSL_TRACE(
165 ::rtl::OUStringToOString(
166 OUString( RTL_CONSTASCII_USTRINGPARAM(
167 "Selection acquired by: " )) +
168 getAccessibleName(),
169 RTL_TEXTENCODING_ASCII_US ).getStr() );
170 #endif
172 break;
174 case LOST_SELECTION:
176 RemoveState( AccessibleStateType::SELECTED );
177 BroadcastAccEvent( AccessibleEventId::STATE_CHANGED, aEmpty, aSelected );
179 AddState( AccessibleStateType::FOCUSED );
180 aSelected <<= AccessibleStateType::FOCUSED;
181 BroadcastAccEvent( AccessibleEventId::STATE_CHANGED, aEmpty, aSelected, true );
182 #if OSL_DEBUG_LEVEL > 1
183 OSL_TRACE(
184 ::rtl::OUStringToOString(
185 OUString( RTL_CONSTASCII_USTRINGPARAM(
186 "Selection lost by: " )) +
187 getAccessibleName(),
188 RTL_TEXTENCODING_ASCII_US ).getStr() );
189 #endif
191 break;
193 case PROPERTY_CHANGE:
195 //not implemented --> rebuild all
197 break;
199 return true;
201 else if( m_bMayHaveChildren )
203 bool bStop = false;
204 // /--
205 ClearableMutexGuard aGuard( GetMutex() );
206 // make local copy for notification
207 ChildListVectorType aLocalChildList( m_aChildList );
208 aGuard.clear();
209 // \--
211 ChildListVectorType::iterator aEndIter = aLocalChildList.end();
212 for( ChildListVectorType::iterator aIter = aLocalChildList.begin() ;
213 ( aIter != aEndIter ) && ( ! bStop ) ;
214 ++aIter )
216 // Note: at this place we must be sure to have an AccessibleBase
217 // object in the UNO reference to XAccessible !
218 bStop = (*static_cast< AccessibleBase * >
219 ( (*aIter).get() )).NotifyEvent( eEventType, rId );
221 return bStop;
224 return false;
227 void AccessibleBase::AddState( sal_Int16 aState )
228 throw (RuntimeException)
230 CheckDisposeState();
231 OSL_ASSERT( m_pStateSetHelper );
232 m_pStateSetHelper->AddState( aState );
235 void AccessibleBase::RemoveState( sal_Int16 aState )
236 throw (RuntimeException)
238 CheckDisposeState();
239 OSL_ASSERT( m_pStateSetHelper );
240 m_pStateSetHelper->RemoveState( aState );
243 // ________ protected ________
245 bool AccessibleBase::UpdateChildren()
247 bool bMustUpdateChildren = false;
249 // /--
250 MutexGuard aGuard( GetMutex() );
251 if( ! m_bMayHaveChildren ||
252 m_bIsDisposed )
253 return false;
255 bMustUpdateChildren = ( m_bMayHaveChildren &&
256 ! m_bChildrenInitialized );
257 // \--
260 // update unguarded
261 if( bMustUpdateChildren )
262 m_bChildrenInitialized = ImplUpdateChildren();
264 return m_bChildrenInitialized;
267 bool AccessibleBase::ImplUpdateChildren()
269 bool bResult = false;
271 if( m_aAccInfo.m_spObjectHierarchy )
273 ObjectHierarchy::tChildContainer aModelChildren(
274 m_aAccInfo.m_spObjectHierarchy->getChildren( GetId() ));
275 ::std::vector< ChildCIDMap::key_type > aAccChildren;
276 aAccChildren.reserve( aModelChildren.size());
277 ::std::transform( m_aChildCIDMap.begin(), m_aChildCIDMap.end(),
278 ::std::back_inserter( aAccChildren ),
279 ::std::select1st< ChildCIDMap::value_type >());
281 ::std::sort( aModelChildren.begin(), aModelChildren.end());
283 ::std::vector< OUString > aChildrenToRemove, aChildrenToAdd;
284 ::std::set_difference( aModelChildren.begin(), aModelChildren.end(),
285 aAccChildren.begin(), aAccChildren.end(),
286 ::std::back_inserter( aChildrenToAdd ));
287 ::std::set_difference( aAccChildren.begin(), aAccChildren.end(),
288 aModelChildren.begin(), aModelChildren.end(),
289 ::std::back_inserter( aChildrenToRemove ));
291 ::std::vector< OUString >::const_iterator aIt( aChildrenToRemove.begin());
292 for( ; aIt != aChildrenToRemove.end(); ++aIt )
294 RemoveChildById( *aIt );
297 AccessibleElementInfo aAccInfo( GetInfo());
298 aAccInfo.m_pParent = this;
300 for( aIt = aChildrenToAdd.begin(); aIt != aChildrenToAdd.end(); ++aIt )
302 aAccInfo.m_aCID = *aIt;
303 AddChild( ChartElementFactory::CreateChartElement( aAccInfo ));
305 bResult = true;
308 return bResult;
311 void AccessibleBase::AddChild( AccessibleBase * pChild )
313 OSL_ENSURE( pChild != NULL, "Invalid Child" );
314 if( pChild )
316 // /--
317 ClearableMutexGuard aGuard( GetMutex() );
319 Reference< XAccessible > xChild( pChild );
320 m_aChildList.push_back( xChild );
322 m_aChildCIDMap[ pChild->GetId() ] = xChild;
324 // inform listeners of new child
325 if( m_bChildrenInitialized )
327 Any aEmpty, aNew;
328 aNew <<= xChild;
330 aGuard.clear();
331 // \-- (1st)
332 BroadcastAccEvent( AccessibleEventId::CHILD, aNew, aEmpty );
334 // \-- (2nd)
338 /** in this method we imply that the Reference< XAccessible > elements in the
339 vector are AccessibleBase objects !
341 void AccessibleBase::RemoveChildById( const ::rtl::OUString & rId )
343 // /--
344 ClearableMutexGuard aGuard( GetMutex() );
346 ChildCIDMap::iterator aIt( m_aChildCIDMap.find( rId ));
347 if( aIt != m_aChildCIDMap.end())
349 Reference< XAccessible > xChild( aIt->second );
351 // remove from map
352 m_aChildCIDMap.erase( aIt );
354 // search child in vector
355 ChildListVectorType::iterator aVecIter =
356 ::std::find( m_aChildList.begin(), m_aChildList.end(), xChild );
358 OSL_ENSURE( aVecIter != m_aChildList.end(),
359 "Inconsistent ChildMap" );
361 // remove child from vector
362 m_aChildList.erase( aVecIter );
363 bool bInitialized = m_bChildrenInitialized;
365 // call listeners unguarded
366 aGuard.clear();
367 // \-- (1st)
369 // inform listeners of removed child
370 if( bInitialized )
372 Any aEmpty, aOld;
373 aOld <<= xChild;
375 BroadcastAccEvent( AccessibleEventId::CHILD, aEmpty, aOld );
378 // dispose the child
379 Reference< lang::XComponent > xComp( xChild, UNO_QUERY );
380 if( xComp.is())
381 xComp->dispose();
385 awt::Point AccessibleBase::GetUpperLeftOnScreen() const
387 awt::Point aResult;
388 if( m_aAccInfo.m_pParent )
390 // /--
391 ClearableMutexGuard aGuard( GetMutex() );
392 AccessibleBase * pParent = m_aAccInfo.m_pParent;
393 aGuard.clear();
394 // \--
396 if( pParent )
398 aResult = pParent->GetUpperLeftOnScreen();
400 else
401 OSL_ENSURE( false, "Default position used is probably incorrect." );
404 return aResult;
407 void AccessibleBase::BroadcastAccEvent(
408 sal_Int16 nId,
409 const Any & rNew,
410 const Any & rOld,
411 bool bSendGlobally ) const
413 // /--
414 ClearableMutexGuard aGuard( GetMutex() );
416 if ( !m_nEventNotifierId && !bSendGlobally )
417 return;
418 // if we don't have a client id for the notifier, then we don't have listeners, then
419 // we don't need to notify anything
420 //except SendGlobally for focus handling?
422 // the const cast is needed, because UNO parameters are never const
423 const AccessibleEventObject aEvent(
424 const_cast< uno::XWeak * >( static_cast< const uno::XWeak * >( this )),
425 nId, rNew, rOld );
427 if ( m_nEventNotifierId ) // let the notifier handle this event
428 ::comphelper::AccessibleEventNotifier::addEvent( m_nEventNotifierId, aEvent );
430 aGuard.clear();
431 // \--
433 // send event to global message queue
434 if( bSendGlobally )
436 ::vcl::unohelper::NotifyAccessibleStateEventGlobally( aEvent );
440 void AccessibleBase::KillAllChildren()
442 // /--
443 ClearableMutexGuard aGuard( GetMutex() );
445 // make local copy for notification
446 ChildListVectorType aLocalChildList( m_aChildList );
448 // remove all children
449 m_aChildList.clear();
450 m_aChildCIDMap.clear();
452 aGuard.clear();
453 // \--
455 // call dispose for all children
456 // and notify listeners
457 Reference< lang::XComponent > xComp;
458 Any aEmpty, aOld;
459 ChildListVectorType::const_iterator aEndIter = aLocalChildList.end();
460 for( ChildListVectorType::const_iterator aIter = aLocalChildList.begin();
461 aIter != aEndIter; ++aIter )
463 aOld <<= (*aIter);
464 BroadcastAccEvent( AccessibleEventId::CHILD, aEmpty, aOld );
466 xComp.set( *aIter, UNO_QUERY );
467 if( xComp.is())
468 xComp->dispose();
470 m_bChildrenInitialized = false;
473 AccessibleElementInfo AccessibleBase::GetInfo() const
475 return m_aAccInfo;
478 void AccessibleBase::SetInfo( const AccessibleElementInfo & rNewInfo )
480 m_aAccInfo = rNewInfo;
481 if( m_bMayHaveChildren )
483 KillAllChildren();
485 BroadcastAccEvent( AccessibleEventId::INVALIDATE_ALL_CHILDREN, uno::Any(), uno::Any(),
486 true /* global notification */ );
489 AccessibleUniqueId AccessibleBase::GetId() const
491 return m_aAccInfo.m_aCID;
494 // ____________________________________
495 // ____________________________________
497 // Interfaces
498 // ____________________________________
499 // ____________________________________
501 // ________ (XComponent::dispose) ________
502 void SAL_CALL AccessibleBase::disposing()
504 // /--
505 ClearableMutexGuard aGuard( GetMutex() );
506 OSL_ENSURE( ! m_bIsDisposed, "dispose() called twice" );
508 // notify disposing to all AccessibleEvent listeners asynchron
509 if ( m_nEventNotifierId )
511 ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( m_nEventNotifierId, *this );
512 m_nEventNotifierId = 0;
515 // reset pointers
516 m_aAccInfo.m_pParent = NULL;
518 // invalidate implementation for helper, but keep UNO reference to still
519 // allow a tool to query the DEFUNC state.
520 // Note: The object will be deleted when the last reference is released
521 m_pStateSetHelper = NULL;
523 // attach new empty state set helper to member reference
524 ::utl::AccessibleStateSetHelper * pHelper = new ::utl::AccessibleStateSetHelper();
525 pHelper->AddState( AccessibleStateType::DEFUNC );
526 // release old helper and attach new one
527 m_aStateSet.set( pHelper );
529 m_bIsDisposed = true;
531 // call listeners unguarded
532 aGuard.clear();
533 // \--
535 if( m_bMayHaveChildren )
537 KillAllChildren();
539 else
540 OSL_ENSURE( m_aChildList.empty(), "Child list should be empty" );
543 // ________ XAccessible ________
544 Reference< XAccessibleContext > SAL_CALL AccessibleBase::getAccessibleContext()
545 throw (RuntimeException)
547 return this;
550 // ________ AccessibleBase::XAccessibleContext ________
551 sal_Int32 SAL_CALL AccessibleBase::getAccessibleChildCount()
552 throw (RuntimeException)
554 // /--
555 ClearableMutexGuard aGuard( GetMutex() );
556 if( ! m_bMayHaveChildren ||
557 m_bIsDisposed )
558 return 0;
560 bool bMustUpdateChildren = ( m_bMayHaveChildren &&
561 ! m_bChildrenInitialized );
563 aGuard.clear();
564 // \--
566 // update unguarded
567 if( bMustUpdateChildren )
568 UpdateChildren();
570 return ImplGetAccessibleChildCount();
573 sal_Int32 AccessibleBase::ImplGetAccessibleChildCount() const
574 throw (RuntimeException)
576 return m_aChildList.size();
579 Reference< XAccessible > SAL_CALL AccessibleBase::getAccessibleChild( sal_Int32 i )
580 throw (lang::IndexOutOfBoundsException, RuntimeException)
582 CheckDisposeState();
583 Reference< XAccessible > xResult;
585 // /--
586 ResettableMutexGuard aGuard( GetMutex() );
587 bool bMustUpdateChildren = ( m_bMayHaveChildren &&
588 ! m_bChildrenInitialized );
590 aGuard.clear();
591 // \--
593 if( bMustUpdateChildren )
594 UpdateChildren();
596 xResult.set( ImplGetAccessibleChildById( i ));
598 return xResult;
599 // \--
602 Reference< XAccessible > AccessibleBase::ImplGetAccessibleChildById( sal_Int32 i ) const
603 throw (lang::IndexOutOfBoundsException, RuntimeException)
605 Reference< XAccessible > xResult;
606 // /--
607 MutexGuard aGuard( GetMutex());
608 if( ! m_bMayHaveChildren ||
609 i < 0 ||
610 static_cast< ChildListVectorType::size_type >( i ) >= m_aChildList.size() )
612 OUStringBuffer aBuf;
613 aBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "Index " ));
614 aBuf.append( i );
615 aBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " is invalid for range [ 0, " ));
616 aBuf.append( static_cast< sal_Int32 >( m_aChildList.size() - 1 ) );
617 aBuf.appendAscii( RTL_CONSTASCII_STRINGPARAM( " ]" ) );
618 lang::IndexOutOfBoundsException aEx( aBuf.makeStringAndClear(),
619 const_cast< ::cppu::OWeakObject * >(
620 static_cast< const ::cppu::OWeakObject * >( this )));
621 throw aEx;
623 else
624 xResult.set( m_aChildList[ i ] );
626 return xResult;
629 Reference< XAccessible > SAL_CALL AccessibleBase::getAccessibleParent()
630 throw (RuntimeException)
632 CheckDisposeState();
633 Reference< XAccessible > aResult;
634 if( m_aAccInfo.m_pParent )
635 aResult.set( m_aAccInfo.m_pParent );
637 return aResult;
640 sal_Int32 SAL_CALL AccessibleBase::getAccessibleIndexInParent()
641 throw (RuntimeException)
643 CheckDisposeState();
645 if( m_aAccInfo.m_spObjectHierarchy )
646 return m_aAccInfo.m_spObjectHierarchy->getIndexInParent( GetId() );
647 return -1;
650 sal_Int16 SAL_CALL AccessibleBase::getAccessibleRole()
651 throw (RuntimeException)
653 return AccessibleRole::LIST_ITEM; // #i73747# role SHAPE seems more appropriate, but is not read
656 Reference< XAccessibleRelationSet > SAL_CALL AccessibleBase::getAccessibleRelationSet()
657 throw (RuntimeException)
659 Reference< XAccessibleRelationSet > aResult;
660 return aResult;
663 Reference< XAccessibleStateSet > SAL_CALL AccessibleBase::getAccessibleStateSet()
664 throw (RuntimeException)
666 if( ! m_bStateSetInitialized )
668 OUString aSelCID;
669 Reference< view::XSelectionSupplier > xSelSupp( GetInfo().m_xSelectionSupplier );
670 if( xSelSupp.is() &&
671 ( xSelSupp->getSelection() >>= aSelCID ) &&
672 GetId().equals( aSelCID ) )
674 AddState( AccessibleStateType::SELECTED );
675 AddState( AccessibleStateType::FOCUSED );
677 m_bStateSetInitialized = true;
680 return m_aStateSet;
684 lang::Locale SAL_CALL AccessibleBase::getLocale()
685 throw (IllegalAccessibleComponentStateException, RuntimeException)
687 CheckDisposeState();
689 return Application::GetSettings().GetLocale();
692 // ________ AccessibleBase::XAccessibleComponent ________
693 sal_Bool SAL_CALL AccessibleBase::containsPoint( const awt::Point& aPoint )
694 throw (RuntimeException)
696 awt::Rectangle aRect( getBounds() );
698 // contains() works with relative coordinates
699 aRect.X = 0;
700 aRect.Y = 0;
702 return ( aPoint.X >= aRect.X &&
703 aPoint.Y >= aRect.Y &&
704 aPoint.X < (aRect.X + aRect.Width) &&
705 aPoint.Y < (aRect.Y + aRect.Height) );
708 Reference< XAccessible > SAL_CALL AccessibleBase::getAccessibleAtPoint( const awt::Point& aPoint )
709 throw (RuntimeException)
711 CheckDisposeState();
712 Reference< XAccessible > aResult;
713 awt::Rectangle aRect( getBounds());
715 // children are positioned relative to this object, so translate bound rect
716 aRect.X = 0;
717 aRect.Y = 0;
719 // children must be inside the own bound rect
720 if( ( aRect.X <= aPoint.X && aPoint.X <= (aRect.X + aRect.Width) ) &&
721 ( aRect.Y <= aPoint.Y && aPoint.Y <= (aRect.Y + aRect.Height)))
723 // /--
724 ClearableMutexGuard aGuard( GetMutex() );
725 ChildListVectorType aLocalChildList( m_aChildList );
726 aGuard.clear();
727 // \--
729 Reference< XAccessibleComponent > aComp;
730 for( ChildListVectorType::const_iterator aIter = aLocalChildList.begin();
731 aIter != aLocalChildList.end(); ++aIter )
733 aComp.set( *aIter, UNO_QUERY );
734 if( aComp.is())
736 aRect = aComp->getBounds();
737 if( ( aRect.X <= aPoint.X && aPoint.X <= (aRect.X + aRect.Width) ) &&
738 ( aRect.Y <= aPoint.Y && aPoint.Y <= (aRect.Y + aRect.Height)))
740 aResult = (*aIter);
741 break;
747 return aResult;
750 awt::Rectangle SAL_CALL AccessibleBase::getBounds()
751 throw (RuntimeException)
753 ExplicitValueProvider *pExplicitValueProvider(
754 ExplicitValueProvider::getExplicitValueProvider( m_aAccInfo.m_xView ));
755 if( pExplicitValueProvider )
757 Window* pWindow( VCLUnoHelper::GetWindow( m_aAccInfo.m_xWindow ));
758 awt::Rectangle aLogicRect( pExplicitValueProvider->getRectangleOfObject( m_aAccInfo.m_aCID ));
759 if( pWindow )
761 Rectangle aRect( aLogicRect.X, aLogicRect.Y,
762 aLogicRect.X + aLogicRect.Width,
763 aLogicRect.Y + aLogicRect.Height );
764 // /-- solar
765 ::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
766 aRect = pWindow->LogicToPixel( aRect );
768 // aLogicRect ist relative to the page, but we need a value relative
769 // to the parent object
770 awt::Point aParentLocOnScreen;
771 uno::Reference< XAccessibleComponent > xParent( getAccessibleParent(), uno::UNO_QUERY );
772 if( xParent.is() )
773 aParentLocOnScreen = xParent->getLocationOnScreen();
775 // aOffset = aParentLocOnScreen - GetUpperLeftOnScreen()
776 awt::Point aULOnScreen = GetUpperLeftOnScreen();
777 awt::Point aOffset( aParentLocOnScreen.X - aULOnScreen.X,
778 aParentLocOnScreen.Y - aULOnScreen.Y );
780 return awt::Rectangle( aRect.getX() - aOffset.X, aRect.getY() - aOffset.Y,
781 aRect.getWidth(), aRect.getHeight());
782 // \-- solar
786 return awt::Rectangle();
789 awt::Point SAL_CALL AccessibleBase::getLocation()
790 throw (RuntimeException)
792 CheckDisposeState();
793 awt::Rectangle aBBox( getBounds() );
794 return awt::Point( aBBox.X, aBBox.Y );
797 awt::Point SAL_CALL AccessibleBase::getLocationOnScreen()
798 throw (RuntimeException)
800 CheckDisposeState();
802 if( m_aAccInfo.m_pParent != NULL )
804 AccessibleBase * pParent = m_aAccInfo.m_pParent;
805 awt::Point aLocThisRel( getLocation());
806 awt::Point aUpperLeft;
808 if( pParent != NULL )
809 aUpperLeft = pParent->getLocationOnScreen();
811 return awt::Point( aUpperLeft.X + aLocThisRel.X,
812 aUpperLeft.Y + aLocThisRel.Y );
814 else
815 return getLocation();
818 awt::Size SAL_CALL AccessibleBase::getSize()
819 throw (RuntimeException)
821 CheckDisposeState();
822 awt::Rectangle aBBox( getBounds() );
823 return awt::Size( aBBox.Width, aBBox.Height );
826 void SAL_CALL AccessibleBase::grabFocus()
827 throw (RuntimeException)
829 CheckDisposeState();
831 OUString aSelCID;
832 Reference< view::XSelectionSupplier > xSelSupp( GetInfo().m_xSelectionSupplier );
833 if( xSelSupp.is())
834 xSelSupp->select( uno::makeAny( GetId()));
837 sal_Int32 SAL_CALL AccessibleBase::getForeground()
838 throw (RuntimeException)
840 return getColor( ACC_BASE_FOREGROUND );
843 sal_Int32 SAL_CALL AccessibleBase::getBackground()
844 throw (RuntimeException)
846 return getColor( ACC_BASE_BACKGROUND );
849 sal_Int32 AccessibleBase::getColor( eColorType eColType )
851 sal_Int32 nResult = static_cast< sal_Int32 >( Color( COL_TRANSPARENT ).GetColor());
852 if( m_bAlwaysTransparent )
853 return nResult;
855 ObjectType eType( ObjectIdentifier::getObjectType( m_aAccInfo.m_aCID ));
856 Reference< beans::XPropertySet > xObjProp;
857 OUString aObjectCID = m_aAccInfo.m_aCID;
858 if( eType == OBJECTTYPE_LEGEND_ENTRY )
860 // for colors get the data series/point properties
861 OUString aParentParticle( ObjectIdentifier::getFullParentParticle( aObjectCID ));
862 aObjectCID = ObjectIdentifier::createClassifiedIdentifierForParticle( aParentParticle );
865 xObjProp.set(
866 ObjectIdentifier::getObjectPropertySet(
867 aObjectCID, Reference< chart2::XChartDocument >( m_aAccInfo.m_xChartDocument )), uno::UNO_QUERY );
868 if( xObjProp.is())
872 OUString aPropName;
873 OUString aStylePropName;
875 switch( eType )
877 case OBJECTTYPE_LEGEND_ENTRY:
878 case OBJECTTYPE_DATA_SERIES:
879 case OBJECTTYPE_DATA_POINT:
880 if( eColType == ACC_BASE_FOREGROUND )
882 aPropName = C2U("BorderColor");
883 aStylePropName = C2U("BorderTransparency");
885 else
887 aPropName = C2U("Color");
888 aStylePropName = C2U("Transparency");
890 break;
891 default:
892 if( eColType == ACC_BASE_FOREGROUND )
894 aPropName = C2U("LineColor");
895 aStylePropName = C2U("LineTransparence");
897 else
899 aPropName = C2U("FillColor");
900 aStylePropName = C2U("FillTransparence");
902 break;
905 bool bTransparent = m_bAlwaysTransparent;
906 Reference< beans::XPropertySetInfo > xInfo( xObjProp->getPropertySetInfo(), uno::UNO_QUERY );
907 if( xInfo.is() &&
908 xInfo->hasPropertyByName( aStylePropName ))
910 if( eColType == ACC_BASE_FOREGROUND )
912 drawing::LineStyle aLStyle;
913 if( xObjProp->getPropertyValue( aStylePropName ) >>= aLStyle )
914 bTransparent = (aLStyle == drawing::LineStyle_NONE);
916 else
918 drawing::FillStyle aFStyle;
919 if( xObjProp->getPropertyValue( aStylePropName ) >>= aFStyle )
920 bTransparent = (aFStyle == drawing::FillStyle_NONE);
924 if( !bTransparent &&
925 xInfo.is() &&
926 xInfo->hasPropertyByName( aPropName ))
928 xObjProp->getPropertyValue( aPropName ) >>= nResult;
931 catch( const uno::Exception & ex )
933 ASSERT_EXCEPTION( ex );
937 return nResult;
940 // ________ AccessibleBase::XServiceInfo ________
941 OUString SAL_CALL AccessibleBase::getImplementationName()
942 throw (RuntimeException)
944 return OUString( RTL_CONSTASCII_USTRINGPARAM( "AccessibleBase" ));
947 sal_Bool SAL_CALL AccessibleBase::supportsService( const OUString& ServiceName )
948 throw (RuntimeException)
950 return SvxServiceInfoHelper::supportsService( ServiceName, getSupportedServiceNames() );
953 uno::Sequence< OUString > SAL_CALL AccessibleBase::getSupportedServiceNames()
954 throw (RuntimeException)
956 uno::Sequence< ::rtl::OUString > aSeq( 2 );
957 ::rtl::OUString* pStr = aSeq.getArray();
958 pStr[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.Accessible" ));
959 pStr[ 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ));
961 return aSeq;
964 // ________ AccessibleBase::XEventListener ________
965 void SAL_CALL AccessibleBase::disposing( const lang::EventObject& /*Source*/ )
966 throw (RuntimeException)
970 // ________ XAccessibleEventBroadcasters ________
971 void SAL_CALL AccessibleBase::addEventListener( const Reference< XAccessibleEventListener >& xListener )
972 throw (RuntimeException)
974 MutexGuard aGuard( GetMutex() );
976 if ( xListener.is() )
978 if ( !m_nEventNotifierId )
979 m_nEventNotifierId = ::comphelper::AccessibleEventNotifier::registerClient();
981 ::comphelper::AccessibleEventNotifier::addEventListener( m_nEventNotifierId, xListener );
985 void SAL_CALL AccessibleBase::removeEventListener( const Reference< XAccessibleEventListener >& xListener )
986 throw (RuntimeException)
988 MutexGuard aGuard( GetMutex() );
990 if ( xListener.is() )
992 sal_Int32 nListenerCount = ::comphelper::AccessibleEventNotifier::removeEventListener( m_nEventNotifierId, xListener );
993 if ( !nListenerCount )
995 // no listeners anymore
996 ::comphelper::AccessibleEventNotifier::revokeClient( m_nEventNotifierId );
997 m_nEventNotifierId = 0;
1002 } // namespace chart