xref: /AOO41X/main/svx/source/accessibility/GraphCtlAccessibleContext.cxx (revision 0aabba3ab117bd1ebf1560f23f52dfa1a54fd4c7)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 #include <com/sun/star/accessibility/AccessibleRole.hpp>
27 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
28 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
29 #include <com/sun/star/lang/DisposedException.hpp>
30 #include <com/sun/star/beans/PropertyChangeEvent.hpp>
31 #include <com/sun/star/awt/XWindow.hpp>
32 #include <unotools/accessiblestatesethelper.hxx>
33 #include <cppuhelper/typeprovider.hxx>
34 #include <toolkit/helper/vclunohelper.hxx>
35 #include <vcl/svapp.hxx>
36 #include <osl/mutex.hxx>
37 #include <rtl/uuid.h>
38 #include <tools/debug.hxx>
39 #include <tools/gen.hxx>
40 #include <svl/smplhint.hxx>
41 #include <toolkit/helper/convert.hxx>
42 #include <svtools/colorcfg.hxx>
43 #include <comphelper/accessibleeventnotifier.hxx>
44 #include <svx/sdrpaintwindow.hxx>
45 
46 //===== local includes ========================================================
47 #include <svx/ShapeTypeHandler.hxx>
48 #include <svx/AccessibleShapeInfo.hxx>
49 #include "GraphCtlAccessibleContext.hxx"
50 #include <svx/graphctl.hxx>
51 #ifndef _SVX_DIALOGS_HRC
52 #include <svx/dialogs.hrc>
53 #endif
54 #ifndef _SVX_ACCESSIBILITY_HRC
55 #include "accessibility.hrc"
56 #endif
57 #include <svx/svdpage.hxx>
58 #include <svx/unomod.hxx>
59 #include <svx/dialmgr.hxx>
60 #include <svx/svdetc.hxx>
61 #include <svx/sdrhittesthelper.hxx>
62 
63 //=====  namespaces ===========================================================
64 
65 using namespace ::vos;
66 using namespace ::cppu;
67 using namespace ::osl;
68 using ::rtl::OUString;
69 using namespace ::accessibility;
70 using namespace	::com::sun::star;
71 using namespace	::com::sun::star::uno;
72 using namespace	::com::sun::star::drawing;
73 using namespace	::com::sun::star::lang;
74 using namespace	::com::sun::star::accessibility;
75 
76 //=====  internal  ============================================================
77 
78 /** initialize this component and set default values */
79 SvxGraphCtrlAccessibleContext::SvxGraphCtrlAccessibleContext(
80 	const Reference< XAccessible >&	rxParent,
81 	GraphCtrl&								rRepr,
82 	const OUString*							pName,
83 	const OUString*							pDesc ) :
84 
85 	SvxGraphCtrlAccessibleContext_Base( m_aMutex ),
86 	mxParent( rxParent ),
87 	mpControl( &rRepr ),
88     mpModel (NULL),
89     mpPage (NULL),
90     mpView (NULL),
91     mnClientId( 0 ),
92     mbDisposed( sal_False )
93 {
94     if (mpControl != NULL)
95     {
96         mpModel = mpControl->GetSdrModel();
97         if (mpModel != NULL)
98             mpPage = (SdrPage*)mpModel->GetPage( 0 );
99         mpView = mpControl->GetSdrView();
100 
101         if( mpModel == NULL || mpPage == NULL || mpView == NULL )
102         {
103             mbDisposed = true;
104             // Set all the pointers to NULL just in case they are used as
105             // a disposed flag.
106             mpModel = NULL;
107             mpPage = NULL;
108             mpView = NULL;
109         }
110     }
111 
112 	if( pName )
113 	{
114 		msName = *pName;
115 	}
116 	else
117 	{
118 		::vos::OGuard	aSolarGuard( Application::GetSolarMutex() );
119 		msName = SVX_RESSTR( RID_SVXSTR_GRAPHCTRL_ACC_NAME );
120 	}
121 
122 	if( pDesc )
123 	{
124 		msDescription = *pDesc;
125 	}
126 	else
127 	{
128 		::vos::OGuard	aSolarGuard( Application::GetSolarMutex() );
129 		msDescription = SVX_RESSTR( RID_SVXSTR_GRAPHCTRL_ACC_DESCRIPTION );
130 	}
131 
132 	maTreeInfo.SetSdrView( mpView );
133 	maTreeInfo.SetWindow( mpControl );
134 	maTreeInfo.SetViewForwarder( const_cast<SvxGraphCtrlAccessibleContext*>(this) );
135 }
136 
137 //-----------------------------------------------------------------------------
138 
139 /** on destruction, this component is disposed and all dispose listeners
140 	are called, except if this component was already disposed */
141 SvxGraphCtrlAccessibleContext::~SvxGraphCtrlAccessibleContext()
142 {
143 	disposing();
144 }
145 
146 //-----------------------------------------------------------------------------
147 
148 /** returns the XAccessible interface for a given SdrObject.
149 	Multiple calls for the same SdrObject return the same XAccessible.
150 */
151 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessible( const SdrObject* pObj )
152 {
153 	Reference<XAccessible> xAccessibleShape;
154 
155 	if( pObj )
156 	{
157 		// see if we already created an XAccessible for the given SdrObject
158 		ShapesMapType::iterator iter = mxShapes.find( pObj );
159 
160 		if( iter != mxShapes.end() )
161 		{
162 			// if we already have one, return it
163 			xAccessibleShape = (*iter).second;
164 		}
165 		else
166 		{
167 			// create a new one and remember in our internal map
168 			Reference< XShape > xShape( Reference< XShape >::query( (const_cast<SdrObject*>(pObj))->getUnoShape() ) );
169 
170             AccessibleShapeInfo aShapeInfo (xShape,mxParent);
171 			// Create accessible object that corresponds to the descriptor's shape.
172 			AccessibleShape* pAcc = ShapeTypeHandler::Instance().CreateAccessibleObject(
173                 aShapeInfo, maTreeInfo);
174 			xAccessibleShape = pAcc;
175             if (pAcc != NULL)
176             {
177                 pAcc->acquire();
178                 // Now that we acquired the new accessible shape we can
179                 // safely call its Init() method.
180                 pAcc->Init ();
181             }
182 			mxShapes[pObj] = pAcc;
183 
184 			// Create event and inform listeners of the object creation.
185 			CommitChange( AccessibleEventId::CHILD, makeAny( xAccessibleShape ), makeAny( Reference<XAccessible>() ) );
186 		}
187 	}
188 
189     return xAccessibleShape;
190 }
191 
192 //=====  XAccessible  =========================================================
193 
194 Reference< XAccessibleContext > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleContext( void ) throw( RuntimeException )
195 {
196 	return this;
197 }
198 
199 //=====  XAccessibleComponent  ================================================
200 
201 sal_Bool SAL_CALL SvxGraphCtrlAccessibleContext::containsPoint( const awt::Point& rPoint ) throw( RuntimeException )
202 {
203 	// no guard -> done in getSize()
204     awt::Size aSize (getSize());
205     return (rPoint.X >= 0)
206         && (rPoint.X < aSize.Width)
207         && (rPoint.Y >= 0)
208         && (rPoint.Y < aSize.Height);
209 }
210 
211 //-----------------------------------------------------------------------------
212 
213 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleAtPoint( const awt::Point& rPoint ) throw( RuntimeException )
214 {
215 	::osl::MutexGuard	aGuard( m_aMutex );
216 
217 	Reference< XAccessible > xAccessible;
218 
219 	if( mpControl )
220 	{
221 		Point aPnt( rPoint.X, rPoint.Y );
222 		mpControl->PixelToLogic( aPnt );
223 
224         SdrObject* pObj = 0;
225 
226         if(mpView && mpView->GetSdrPageView())
227         {
228             pObj = SdrObjListPrimitiveHit(*mpPage, aPnt, 1, *mpView->GetSdrPageView(), 0, false);
229         }
230 
231 		if( pObj )
232 			xAccessible = getAccessible( pObj );
233 	}
234 	else
235 	{
236 		throw DisposedException();
237 	}
238 
239 	return xAccessible;
240 }
241 
242 //-----------------------------------------------------------------------------
243 
244 awt::Rectangle SAL_CALL SvxGraphCtrlAccessibleContext::getBounds() throw( RuntimeException )
245 {
246 	// no guard -> done in GetBoundingBox()
247 	Rectangle			aCoreBounds( GetBoundingBox() );
248 	awt::Rectangle		aBounds;
249 	aBounds.X = aCoreBounds.getX();
250 	aBounds.Y = aCoreBounds.getY();
251 	aBounds.Width = aCoreBounds.getWidth();
252 	aBounds.Height = aCoreBounds.getHeight();
253 	return aBounds;
254 }
255 
256 //-----------------------------------------------------------------------------
257 
258 awt::Point SAL_CALL SvxGraphCtrlAccessibleContext::getLocation() throw( RuntimeException )
259 {
260 	// no guard -> done in GetBoundingBox()
261 	Rectangle	aRect( GetBoundingBox() );
262 	return awt::Point( aRect.getX(), aRect.getY() );
263 }
264 
265 //-----------------------------------------------------------------------------
266 
267 awt::Point SAL_CALL SvxGraphCtrlAccessibleContext::getLocationOnScreen() throw( RuntimeException )
268 {
269 	// no guard -> done in GetBoundingBoxOnScreen()
270 	Rectangle	aRect( GetBoundingBoxOnScreen() );
271 	return awt::Point( aRect.getX(), aRect.getY() );
272 }
273 
274 //-----------------------------------------------------------------------------
275 
276 awt::Size SAL_CALL SvxGraphCtrlAccessibleContext::getSize() throw( RuntimeException )
277 {
278 	// no guard -> done in GetBoundingBox()
279 	Rectangle	aRect( GetBoundingBox() );
280 	return awt::Size( aRect.getWidth(), aRect.getHeight() );
281 }
282 
283 
284 //=====  XAccessibleContext  ==================================================
285 
286 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleChildCount( void ) throw( RuntimeException )
287 {
288 	OGuard aGuard( Application::GetSolarMutex() );
289 
290 	if( NULL == mpPage )
291 		throw DisposedException();
292 
293 	return mpPage->GetObjCount();
294 }
295 
296 //-----------------------------------------------------------------------------
297 
298 /** returns the SdrObject at index nIndex from the model of this graph */
299 SdrObject* SvxGraphCtrlAccessibleContext::getSdrObject( sal_Int32 nIndex )
300 	throw( RuntimeException, lang::IndexOutOfBoundsException )
301 {
302 	OGuard aGuard( Application::GetSolarMutex() );
303 
304 	if( NULL == mpPage )
305 		throw DisposedException();
306 
307 	if( (nIndex < 0) || ( static_cast<sal_uInt32>(nIndex) >= mpPage->GetObjCount() ) )
308 		throw lang::IndexOutOfBoundsException();
309 
310 	return mpPage->GetObj( nIndex );
311 }
312 
313 //-----------------------------------------------------------------------------
314 
315 /** sends an AccessibleEventObject to all added XAccessibleEventListeners */
316 void SvxGraphCtrlAccessibleContext::CommitChange (
317     sal_Int16 nEventId,
318     const uno::Any& rNewValue,
319     const uno::Any& rOldValue)
320 {
321     AccessibleEventObject aEvent (
322         static_cast<uno::XWeak*>(this),
323         nEventId,
324         rNewValue,
325         rOldValue);
326 
327     FireEvent (aEvent);
328 }
329 
330 /** sends an AccessibleEventObject to all added XAccessibleEventListeners */
331 void SvxGraphCtrlAccessibleContext::FireEvent (const AccessibleEventObject& aEvent)
332 {
333 	if (mnClientId)
334 		comphelper::AccessibleEventNotifier::addEvent( mnClientId, aEvent );
335 }
336 
337 //-----------------------------------------------------------------------------
338 
339 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleChild( sal_Int32 nIndex )
340 	throw( RuntimeException, lang::IndexOutOfBoundsException )
341 {
342 	OGuard aGuard( Application::GetSolarMutex() );
343 
344 	return getAccessible( getSdrObject( nIndex ) );
345 }
346 
347 //-----------------------------------------------------------------------------
348 
349 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleParent( void ) throw( RuntimeException )
350 {
351 	return mxParent;
352 }
353 
354 //-----------------------------------------------------------------------------
355 
356 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleIndexInParent( void ) throw( RuntimeException )
357 {
358 	OGuard aGuard( Application::GetSolarMutex() );
359 	//	Use a simple but slow solution for now.  Optimize later.
360 
361     //	Iterate over all the parent's children and search for this object.
362     if( mxParent.is() )
363     {
364     	Reference< XAccessibleContext >	xParentContext( mxParent->getAccessibleContext() );
365         if( xParentContext.is() )
366         {
367         	sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
368             for( sal_Int32 i = 0 ; i < nChildCount ; ++i )
369             {
370             	Reference< XAccessible > xChild( xParentContext->getAccessibleChild( i ) );
371                 if( xChild.is() )
372                 {
373                 	Reference< XAccessibleContext >	xChildContext = xChild->getAccessibleContext();
374 	            	if( xChildContext == ( XAccessibleContext* ) this )
375                     	return i;
376                 }
377             }
378         }
379    }
380 
381    //	Return -1 to indicate that this object's parent does not know about the
382    //	object.
383    return -1;
384 }
385 
386 //-----------------------------------------------------------------------------
387 
388 sal_Int16 SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleRole( void ) throw( RuntimeException )
389 {
390 	return AccessibleRole::PANEL;
391 }
392 
393 //-----------------------------------------------------------------------------
394 
395 OUString SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleDescription( void ) throw( RuntimeException )
396 {
397 	OGuard aGuard( Application::GetSolarMutex() );
398 	return msDescription;
399 }
400 
401 //-----------------------------------------------------------------------------
402 
403 OUString SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleName( void ) throw( RuntimeException )
404 {
405 	OGuard aGuard( Application::GetSolarMutex() );
406 	return msName;
407 }
408 
409 //-----------------------------------------------------------------------------
410 
411 /**	Return empty reference to indicate that the relation set is not
412 	supported.
413 */
414 Reference< XAccessibleRelationSet > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleRelationSet( void ) throw( RuntimeException )
415 {
416 	return Reference< XAccessibleRelationSet >();
417 }
418 
419 //-----------------------------------------------------------------------------
420 
421 Reference< XAccessibleStateSet > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleStateSet( void ) throw( RuntimeException )
422 {
423 	OGuard aGuard( Application::GetSolarMutex() );
424 
425 	utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
426 
427 	if ( rBHelper.bDisposed || mbDisposed )
428 	{
429 		pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
430 	}
431 	else
432 	{
433 		// pStateSetHelper->AddState( AccessibleStateType::ENABLED );
434         // pStateSetHelper->AddState( AccessibleStateType::SENSITIVE );
435 		pStateSetHelper->AddState( AccessibleStateType::FOCUSABLE );
436 		if( mpControl->HasFocus() )
437 			pStateSetHelper->AddState( AccessibleStateType::FOCUSED );
438 		pStateSetHelper->AddState( AccessibleStateType::OPAQUE );
439 		pStateSetHelper->AddState( AccessibleStateType::SHOWING );
440 		pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
441 	}
442 
443 	return pStateSetHelper;
444 }
445 
446 //-----------------------------------------------------------------------------
447 
448 lang::Locale SAL_CALL SvxGraphCtrlAccessibleContext::getLocale( void ) throw( IllegalAccessibleComponentStateException, RuntimeException )
449 {
450 	OGuard aGuard( Application::GetSolarMutex() );
451 
452 	if( mxParent.is() )
453     {
454     	Reference< XAccessibleContext >	xParentContext( mxParent->getAccessibleContext() );
455         if( xParentContext.is() )
456 	    	return xParentContext->getLocale();
457     }
458 
459     //	No parent.  Therefore throw exception to indicate this cluelessness.
460     throw IllegalAccessibleComponentStateException();
461 }
462 
463 //=====  XAccessibleEventListener  ============================================
464 
465 void SAL_CALL SvxGraphCtrlAccessibleContext::addEventListener( const Reference< XAccessibleEventListener >& xListener )
466     throw( RuntimeException )
467 {
468 	if (xListener.is())
469     {
470         OGuard aGuard( Application::GetSolarMutex() );
471 		if (!mnClientId)
472             mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
473 		comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
474     }
475 }
476 
477 //-----------------------------------------------------------------------------
478 
479 void SAL_CALL SvxGraphCtrlAccessibleContext::removeEventListener( const Reference< XAccessibleEventListener >& xListener )
480     throw( RuntimeException )
481 {
482 	if (xListener.is())
483 	{
484     	OGuard aGuard( Application::GetSolarMutex() );
485 
486         sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
487 		if ( !nListenerCount )
488 		{
489 			// no listeners anymore
490 			// -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
491 			// and at least to us not firing any events anymore, in case somebody calls
492 			// NotifyAccessibleEvent, again
493 			comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
494 			mnClientId = 0;
495 		}
496 	}
497 }
498 
499 //-----------------------------------------------------------------------------
500 
501 void SAL_CALL SvxGraphCtrlAccessibleContext::addFocusListener( const Reference< awt::XFocusListener >& xListener )
502 	throw( RuntimeException )
503 {
504 	OGuard aGuard( Application::GetSolarMutex() );
505 
506 	if( xListener.is() )
507     {
508 		Reference< ::com::sun::star::awt::XWindow >	xWindow( VCLUnoHelper::GetInterface( mpControl ) );
509 		if( xWindow.is() )
510 			xWindow->addFocusListener( xListener );
511     }
512 }
513 
514 //-----------------------------------------------------------------------------
515 
516 void SAL_CALL SvxGraphCtrlAccessibleContext::removeFocusListener( const Reference< awt::XFocusListener >& xListener )
517 	throw (RuntimeException)
518 {
519 	OGuard aGuard( Application::GetSolarMutex() );
520 
521 	if( xListener.is() )
522     {
523 		Reference< ::com::sun::star::awt::XWindow >	xWindow = VCLUnoHelper::GetInterface( mpControl );
524 		if( xWindow.is() )
525 			xWindow->removeFocusListener( xListener );
526     }
527 }
528 
529 //-----------------------------------------------------------------------------
530 
531 void SAL_CALL SvxGraphCtrlAccessibleContext::grabFocus() throw( RuntimeException )
532 {
533 	OGuard aGuard( Application::GetSolarMutex() );
534 
535 	if( NULL == mpControl )
536 		throw DisposedException();
537 
538 	mpControl->GrabFocus();
539 }
540 
541 //-----------------------------------------------------------------------------
542 
543 Any SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleKeyBinding() throw( RuntimeException )
544 {
545 	// here is no implementation, because here are no KeyBindings for every object
546 	return Any();
547 }
548 
549 
550 
551 
552 
553 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getForeground (void)
554     throw (::com::sun::star::uno::RuntimeException)
555 {
556 	svtools::ColorConfig aColorConfig;
557     sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor;
558     return static_cast<sal_Int32>(nColor);
559 }
560 
561 
562 
563 
564 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getBackground (void)
565     throw (::com::sun::star::uno::RuntimeException)
566 {
567     sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor();
568     return static_cast<sal_Int32>(nColor);
569 }
570 
571 
572 //=====  XServiceInfo  ========================================================
573 
574 OUString SAL_CALL SvxGraphCtrlAccessibleContext::getImplementationName( void ) throw( RuntimeException )
575 {
576 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ui.SvxGraphCtrlAccessibleContext" ) );
577 }
578 
579 //-----------------------------------------------------------------------------
580 
581 sal_Bool SAL_CALL SvxGraphCtrlAccessibleContext::supportsService( const OUString& sServiceName ) throw( RuntimeException )
582 {
583 	OGuard aGuard( Application::GetSolarMutex() );
584     //  Iterate over all supported service names and return true if on of them
585     //  matches the given name.
586     Sequence< OUString >	aSupportedServices( getSupportedServiceNames() );
587 	int						nLenght = aSupportedServices.getLength();
588 
589     for( int i = 0 ; i < nLenght ; ++i )
590 	{
591         if( sServiceName == aSupportedServices[ i ] )
592             return sal_True;
593 	}
594 
595     return sal_False;
596 }
597 
598 //-----------------------------------------------------------------------------
599 
600 Sequence< OUString > SAL_CALL SvxGraphCtrlAccessibleContext::getSupportedServiceNames( void ) throw( RuntimeException )
601 {
602 	Sequence< OUString > aSNs( 3 );
603 
604 	aSNs[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.Accessible" ) );
605 	aSNs[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) );
606 	aSNs[2] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.AccessibleGraphControl" ) );
607 
608 	return aSNs;
609 }
610 
611 //=====  XTypeProvider  =======================================================
612 
613 Sequence<sal_Int8> SAL_CALL SvxGraphCtrlAccessibleContext::getImplementationId( void ) throw( RuntimeException )
614 {
615 	OGuard aGuard( Application::GetSolarMutex() );
616 	return getUniqueId();
617 }
618 
619 //=====  XServiceName  ========================================================
620 
621 OUString SvxGraphCtrlAccessibleContext::getServiceName( void ) throw( RuntimeException )
622 {
623 	return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) );
624 }
625 
626 //=====  XAccessibleSelection =============================================
627 
628 void SAL_CALL SvxGraphCtrlAccessibleContext::selectAccessibleChild( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException )
629 {
630 	OGuard aGuard( Application::GetSolarMutex() );
631 
632 	if( NULL == mpView )
633 		throw DisposedException();
634 
635 	SdrObject* pObj = getSdrObject( nIndex );
636 
637 	if( pObj )
638 		mpView->MarkObj( pObj, mpView->GetSdrPageView());
639 }
640 
641 //-----------------------------------------------------------------------------
642 
643 sal_Bool SAL_CALL SvxGraphCtrlAccessibleContext::isAccessibleChildSelected( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException )
644 {
645 	OGuard aGuard( Application::GetSolarMutex() );
646 
647 	if( NULL == mpView )
648 		throw DisposedException();
649 
650 	return mpView->IsObjMarked( getSdrObject( nIndex ) );
651 }
652 
653 //-----------------------------------------------------------------------------
654 
655 void SAL_CALL SvxGraphCtrlAccessibleContext::clearAccessibleSelection() throw( RuntimeException )
656 {
657 	OGuard aGuard( Application::GetSolarMutex() );
658 
659 	if( NULL == mpView )
660 		throw DisposedException();
661 
662 	mpView->UnmarkAllObj();
663 }
664 
665 //-----------------------------------------------------------------------------
666 
667 void SAL_CALL SvxGraphCtrlAccessibleContext::selectAllAccessibleChildren() throw( RuntimeException )
668 {
669 	OGuard aGuard( Application::GetSolarMutex() );
670 
671 	if( NULL == mpView )
672 		throw DisposedException();
673 
674 	mpView->MarkAllObj();
675 }
676 
677 //-----------------------------------------------------------------------------
678 
679 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getSelectedAccessibleChildCount() throw( RuntimeException )
680 {
681 	OGuard aGuard( Application::GetSolarMutex() );
682 
683 	if( NULL == mpView )
684 		throw DisposedException();
685 
686 	const SdrMarkList& rList = mpView->GetMarkedObjectList();
687 	return rList.GetMarkCount();
688 }
689 
690 //-----------------------------------------------------------------------------
691 
692 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getSelectedAccessibleChild( sal_Int32 nIndex )
693 	throw( lang::IndexOutOfBoundsException, RuntimeException )
694 {
695 	OGuard aGuard( Application::GetSolarMutex() );
696 
697 	checkChildIndexOnSelection( nIndex );
698 
699 	Reference< XAccessible > xAccessible;
700 
701 	const SdrMarkList& rList = mpView->GetMarkedObjectList();
702 	SdrObject* pObj = rList.GetMark(nIndex)->GetMarkedSdrObj();
703 	if( pObj )
704 		xAccessible = getAccessible( pObj );
705 
706 	return xAccessible;
707 }
708 
709 //-----------------------------------------------------------------------------
710 
711 void SAL_CALL SvxGraphCtrlAccessibleContext::deselectAccessibleChild( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException )
712 {
713 	OGuard aGuard( Application::GetSolarMutex() );
714 
715 	checkChildIndexOnSelection( nIndex );
716 
717 	if( mpView )
718 	{
719 		const SdrMarkList& rList = mpView->GetMarkedObjectList();
720 
721         SdrObject* pObj = getSdrObject( nIndex );
722 		if( pObj )
723 		{
724 			SdrMarkList aRefList( rList );
725 
726 			SdrPageView* pPV = mpView->GetSdrPageView();
727 			mpView->UnmarkAllObj( pPV );
728 
729 			sal_uInt32 nCount = aRefList.GetMarkCount();
730 			sal_uInt32 nMark;
731 			for( nMark = 0; nMark < nCount; nMark++ )
732 			{
733 				if( aRefList.GetMark(nMark)->GetMarkedSdrObj() != pObj )
734 					mpView->MarkObj( aRefList.GetMark(nMark)->GetMarkedSdrObj(), pPV );
735 			}
736 		}
737 	}
738 }
739 
740 //=====  internals ========================================================
741 
742 void SvxGraphCtrlAccessibleContext::checkChildIndex( long nIndex ) throw( lang::IndexOutOfBoundsException )
743 {
744 	if( nIndex < 0 || nIndex >= getAccessibleChildCount() )
745 		throw lang::IndexOutOfBoundsException();
746 }
747 
748 //-----------------------------------------------------------------------------
749 
750 void SvxGraphCtrlAccessibleContext::checkChildIndexOnSelection( long nIndex ) throw( lang::IndexOutOfBoundsException )
751 {
752 	if( nIndex < 0 || nIndex >= getSelectedAccessibleChildCount() )
753 		throw lang::IndexOutOfBoundsException();
754 }
755 
756 //-----------------------------------------------------------------------------
757 
758 void SvxGraphCtrlAccessibleContext::setName( const OUString& rName )
759 {
760 	OGuard aGuard( Application::GetSolarMutex() );
761 
762 	msName = rName;
763 }
764 
765 //-----------------------------------------------------------------------------
766 
767 void SvxGraphCtrlAccessibleContext::setDescription( const OUString& rDescr )
768 {
769 	OGuard aGuard( Application::GetSolarMutex() );
770 
771 	msDescription = rDescr;
772 }
773 
774 
775 
776 
777 /** Replace the model, page, and view pointers by the ones provided
778     (explicitly and implicitly).
779 */
780 void SvxGraphCtrlAccessibleContext::setModelAndView (
781     SdrModel* pModel,
782     SdrView* pView)
783 {
784 	OGuard aGuard (Application::GetSolarMutex());
785 
786     mpModel = pModel;
787     if (mpModel != NULL)
788         mpPage = (SdrPage*)mpModel->GetPage( 0 );
789     mpView = pView;
790 
791     if (mpModel == NULL || mpPage == NULL || mpView == NULL)
792     {
793         mbDisposed = true;
794 
795         // Set all the pointers to NULL just in case they are used as
796         // a disposed flag.
797         mpModel = NULL;
798         mpPage = NULL;
799         mpView = NULL;
800     }
801 
802 	maTreeInfo.SetSdrView (mpView);
803 }
804 
805 
806 
807 //-----------------------------------------------------------------------------
808 
809 void SAL_CALL SvxGraphCtrlAccessibleContext::disposing()
810 {
811 	OGuard aGuard( Application::GetSolarMutex() );
812 
813 	if( mbDisposed )
814 		return;
815 
816 	mbDisposed = sal_True;
817 
818 	mpControl = NULL;		// object dies with representation
819 	mpView = NULL;
820 	mpPage = NULL;
821 
822 	{
823 		ShapesMapType::iterator I;
824 
825 		for (I=mxShapes.begin(); I!=mxShapes.end(); I++)
826 		{
827 			XAccessible* pAcc = (*I).second;
828 			Reference< XComponent > xComp( pAcc, UNO_QUERY );
829 			if( xComp.is() )
830 				xComp->dispose();
831 
832 			(*I).second->release();
833 		}
834 
835 		mxShapes.clear();
836 	}
837 
838     // Send a disposing to all listeners.
839 	if ( mnClientId )
840 	{
841         comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
842 		mnClientId =  0;
843 	}
844 }
845 
846 //-----------------------------------------------------------------------------
847 
848 Rectangle SvxGraphCtrlAccessibleContext::GetBoundingBoxOnScreen( void ) throw( RuntimeException )
849 {
850 	OGuard aGuard( Application::GetSolarMutex() );
851 
852 	if( NULL == mpControl )
853 		throw DisposedException();
854 
855 	return Rectangle(
856         mpControl->GetAccessibleParentWindow()->OutputToAbsoluteScreenPixel(
857             mpControl->GetPosPixel() ),
858         mpControl->GetSizePixel() );
859 }
860 
861 //-----------------------------------------------------------------------------
862 
863 /** Calculate the relative coordinates of the bounding box as difference
864     between the absolute coordinates of the bounding boxes of this control
865     and its parent in the accessibility tree.
866 */
867 Rectangle SvxGraphCtrlAccessibleContext::GetBoundingBox( void ) throw( RuntimeException )
868 {
869 	OGuard aGuard( Application::GetSolarMutex() );
870 
871 	Rectangle aBounds ( 0, 0, 0, 0 );
872 
873 	Window* pWindow = mpControl;
874 	if (pWindow != NULL)
875 	{
876 		aBounds = pWindow->GetWindowExtentsRelative (NULL);
877 		Window* pParent = pWindow->GetAccessibleParentWindow();
878 		if (pParent != NULL)
879 		{
880 			Rectangle aParentRect = pParent->GetWindowExtentsRelative (NULL);
881 			aBounds -= aParentRect.TopLeft();
882 		}
883 	}
884     else
885 		throw DisposedException();
886 
887 	return aBounds;
888 }
889 
890 //-----------------------------------------------------------------------------
891 
892 Sequence< sal_Int8 > SvxGraphCtrlAccessibleContext::getUniqueId( void )
893 {
894 	// no guard because it's private -> has to guarded when using it!
895 	static OImplementationId*	pId = 0;
896 	if( !pId )
897 	{
898 		OGuard aGuard( Application::GetSolarMutex() );
899 		if( !pId)
900 		{
901 			static OImplementationId	aId;
902 			pId = &aId;
903 		}
904 	}
905 	return pId->getImplementationId();
906 }
907 
908 //-----------------------------------------------------------------------------
909 
910 void SvxGraphCtrlAccessibleContext::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
911 {
912 	const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
913 
914 	if( pSdrHint )
915 	{
916 		switch( pSdrHint->GetKind() )
917 		{
918 			case HINT_OBJCHG:
919 				{
920 					ShapesMapType::iterator iter = mxShapes.find( pSdrHint->GetObject() );
921 
922 					if( iter != mxShapes.end() )
923 					{
924 						// if we already have one, return it
925 						AccessibleShape* pShape = (*iter).second;
926 
927 						if( NULL != pShape )
928 							pShape->CommitChange( AccessibleEventId::VISIBLE_DATA_CHANGED, uno::Any(), uno::Any() );
929 					}
930 				}
931 				break;
932 
933 			case HINT_OBJINSERTED:
934 				CommitChange( AccessibleEventId::CHILD, makeAny( getAccessible( pSdrHint->GetObject() ) ) , uno::Any());
935 				break;
936 			case HINT_OBJREMOVED:
937 				CommitChange( AccessibleEventId::CHILD, uno::Any(), makeAny( getAccessible( pSdrHint->GetObject() ) )  );
938 				break;
939 			case HINT_MODELCLEARED:
940 				dispose();
941 				break;
942             default:
943                 break;
944 		}
945 	}
946 	else
947 	{
948 		const SfxSimpleHint* pSfxHint = PTR_CAST(SfxSimpleHint, &rHint );
949 
950 		// ist unser SdDrawDocument gerade gestorben?
951 		if(pSfxHint && pSfxHint->GetId() == SFX_HINT_DYING)
952 		{
953 			dispose();
954 		}
955 	}
956 }
957 
958 //=====  IAccessibleViewforwarder  ========================================
959 
960 sal_Bool SvxGraphCtrlAccessibleContext::IsValid (void) const
961 {
962     return sal_True;
963 }
964 
965 //-----------------------------------------------------------------------------
966 
967 Rectangle SvxGraphCtrlAccessibleContext::GetVisibleArea (void) const
968 {
969 	Rectangle aVisArea;
970 
971 	if( mpView && mpView->PaintWindowCount())
972 	{
973 		SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow(0L);
974 		aVisArea = pPaintWindow->GetVisibleArea();
975 	}
976 
977 	return aVisArea;
978 }
979 
980 //-----------------------------------------------------------------------------
981 
982 Point SvxGraphCtrlAccessibleContext::LogicToPixel (const Point& rPoint) const
983 {
984 	if( mpControl )
985 	{
986 		Rectangle aBBox(mpControl->GetWindowExtentsRelative(NULL));
987 	    return mpControl->LogicToPixel (rPoint) + aBBox.TopLeft();
988 	}
989 	else
990 	{
991 		return rPoint;
992 	}
993 }
994 
995 //-----------------------------------------------------------------------------
996 
997 Size SvxGraphCtrlAccessibleContext::LogicToPixel (const Size& rSize) const
998 {
999 	if( mpControl )
1000 		return mpControl->LogicToPixel (rSize);
1001 	else
1002 		return rSize;
1003 }
1004 
1005 //-----------------------------------------------------------------------------
1006 
1007 Point SvxGraphCtrlAccessibleContext::PixelToLogic (const Point& rPoint) const
1008 {
1009 	if( mpControl )
1010 		return mpControl->PixelToLogic (rPoint);
1011 	else
1012 		return rPoint;
1013 }
1014 
1015 //-----------------------------------------------------------------------------
1016 
1017 Size SvxGraphCtrlAccessibleContext::PixelToLogic (const Size& rSize) const
1018 {
1019 	if( mpControl )
1020 		return mpControl->PixelToLogic (rSize);
1021 	else
1022 		return rSize;
1023 }
1024