xref: /trunk/main/svx/source/accessibility/GraphCtlAccessibleContext.cxx (revision 91144cd0085a7583d2099b982122deb2184ab956)
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 */
SvxGraphCtrlAccessibleContext(const Reference<XAccessible> & rxParent,GraphCtrl & rRepr,const OUString * pName,const OUString * pDesc)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 */
~SvxGraphCtrlAccessibleContext()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 */
getAccessible(const SdrObject * pObj)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 
getAccessibleContext(void)194 Reference< XAccessibleContext > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleContext( void )
195 {
196     return this;
197 }
198 
199 //=====  XAccessibleComponent  ================================================
200 
containsPoint(const awt::Point & rPoint)201 sal_Bool SAL_CALL SvxGraphCtrlAccessibleContext::containsPoint( const awt::Point& rPoint )
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 
getAccessibleAtPoint(const awt::Point & rPoint)213 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleAtPoint( const awt::Point& rPoint )
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 
getBounds()244 awt::Rectangle SAL_CALL SvxGraphCtrlAccessibleContext::getBounds()
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 
getLocation()258 awt::Point SAL_CALL SvxGraphCtrlAccessibleContext::getLocation()
259 {
260     // no guard -> done in GetBoundingBox()
261     Rectangle   aRect( GetBoundingBox() );
262     return awt::Point( aRect.getX(), aRect.getY() );
263 }
264 
265 //-----------------------------------------------------------------------------
266 
getLocationOnScreen()267 awt::Point SAL_CALL SvxGraphCtrlAccessibleContext::getLocationOnScreen()
268 {
269     // no guard -> done in GetBoundingBoxOnScreen()
270     Rectangle   aRect( GetBoundingBoxOnScreen() );
271     return awt::Point( aRect.getX(), aRect.getY() );
272 }
273 
274 //-----------------------------------------------------------------------------
275 
getSize()276 awt::Size SAL_CALL SvxGraphCtrlAccessibleContext::getSize()
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 
getAccessibleChildCount(void)286 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleChildCount( void )
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 */
getSdrObject(sal_Int32 nIndex)299 SdrObject* SvxGraphCtrlAccessibleContext::getSdrObject( sal_Int32 nIndex )
300 {
301     OGuard aGuard( Application::GetSolarMutex() );
302 
303     if( NULL == mpPage )
304         throw DisposedException();
305 
306     if( (nIndex < 0) || ( static_cast<sal_uInt32>(nIndex) >= mpPage->GetObjCount() ) )
307         throw lang::IndexOutOfBoundsException();
308 
309     return mpPage->GetObj( nIndex );
310 }
311 
312 //-----------------------------------------------------------------------------
313 
314 /** sends an AccessibleEventObject to all added XAccessibleEventListeners */
CommitChange(sal_Int16 nEventId,const uno::Any & rNewValue,const uno::Any & rOldValue)315 void SvxGraphCtrlAccessibleContext::CommitChange (
316     sal_Int16 nEventId,
317     const uno::Any& rNewValue,
318     const uno::Any& rOldValue)
319 {
320     AccessibleEventObject aEvent (
321         static_cast<uno::XWeak*>(this),
322         nEventId,
323         rNewValue,
324         rOldValue);
325 
326     FireEvent (aEvent);
327 }
328 
329 /** sends an AccessibleEventObject to all added XAccessibleEventListeners */
FireEvent(const AccessibleEventObject & aEvent)330 void SvxGraphCtrlAccessibleContext::FireEvent (const AccessibleEventObject& aEvent)
331 {
332     if (mnClientId)
333         comphelper::AccessibleEventNotifier::addEvent( mnClientId, aEvent );
334 }
335 
336 //-----------------------------------------------------------------------------
337 
getAccessibleChild(sal_Int32 nIndex)338 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleChild( sal_Int32 nIndex )
339 {
340     OGuard aGuard( Application::GetSolarMutex() );
341 
342     return getAccessible( getSdrObject( nIndex ) );
343 }
344 
345 //-----------------------------------------------------------------------------
346 
getAccessibleParent(void)347 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleParent( void )
348 {
349     return mxParent;
350 }
351 
352 //-----------------------------------------------------------------------------
353 
getAccessibleIndexInParent(void)354 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleIndexInParent( void )
355 {
356     OGuard aGuard( Application::GetSolarMutex() );
357     //  Use a simple but slow solution for now.  Optimize later.
358 
359     //  Iterate over all the parent's children and search for this object.
360     if( mxParent.is() )
361     {
362         Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() );
363         if( xParentContext.is() )
364         {
365             sal_Int32 nChildCount = xParentContext->getAccessibleChildCount();
366             for( sal_Int32 i = 0 ; i < nChildCount ; ++i )
367             {
368                 Reference< XAccessible > xChild( xParentContext->getAccessibleChild( i ) );
369                 if( xChild.is() )
370                 {
371                     Reference< XAccessibleContext > xChildContext = xChild->getAccessibleContext();
372                     if( xChildContext == ( XAccessibleContext* ) this )
373                         return i;
374                 }
375             }
376         }
377    }
378 
379    //   Return -1 to indicate that this object's parent does not know about the
380    //   object.
381    return -1;
382 }
383 
384 //-----------------------------------------------------------------------------
385 
getAccessibleRole(void)386 sal_Int16 SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleRole( void )
387 {
388     return AccessibleRole::PANEL;
389 }
390 
391 //-----------------------------------------------------------------------------
392 
getAccessibleDescription(void)393 OUString SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleDescription( void )
394 {
395     OGuard aGuard( Application::GetSolarMutex() );
396     return msDescription;
397 }
398 
399 //-----------------------------------------------------------------------------
400 
getAccessibleName(void)401 OUString SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleName( void )
402 {
403     OGuard aGuard( Application::GetSolarMutex() );
404     return msName;
405 }
406 
407 //-----------------------------------------------------------------------------
408 
409 /** Return empty reference to indicate that the relation set is not
410     supported.
411 */
getAccessibleRelationSet(void)412 Reference< XAccessibleRelationSet > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleRelationSet( void )
413 {
414     return Reference< XAccessibleRelationSet >();
415 }
416 
417 //-----------------------------------------------------------------------------
418 
getAccessibleStateSet(void)419 Reference< XAccessibleStateSet > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleStateSet( void )
420 {
421     OGuard aGuard( Application::GetSolarMutex() );
422 
423     utl::AccessibleStateSetHelper* pStateSetHelper = new utl::AccessibleStateSetHelper;
424 
425     if ( rBHelper.bDisposed || mbDisposed )
426     {
427         pStateSetHelper->AddState( AccessibleStateType::DEFUNC );
428     }
429     else
430     {
431         // pStateSetHelper->AddState( AccessibleStateType::ENABLED );
432         // pStateSetHelper->AddState( AccessibleStateType::SENSITIVE );
433         pStateSetHelper->AddState( AccessibleStateType::FOCUSABLE );
434         if( mpControl->HasFocus() )
435             pStateSetHelper->AddState( AccessibleStateType::FOCUSED );
436         pStateSetHelper->AddState( AccessibleStateType::OPAQUE );
437         pStateSetHelper->AddState( AccessibleStateType::SHOWING );
438         pStateSetHelper->AddState( AccessibleStateType::VISIBLE );
439     }
440 
441     return pStateSetHelper;
442 }
443 
444 //-----------------------------------------------------------------------------
445 
getLocale(void)446 lang::Locale SAL_CALL SvxGraphCtrlAccessibleContext::getLocale( void )
447 {
448     OGuard aGuard( Application::GetSolarMutex() );
449 
450     if( mxParent.is() )
451     {
452         Reference< XAccessibleContext > xParentContext( mxParent->getAccessibleContext() );
453         if( xParentContext.is() )
454             return xParentContext->getLocale();
455     }
456 
457     //  No parent.  Therefore throw exception to indicate this cluelessness.
458     throw IllegalAccessibleComponentStateException();
459 }
460 
461 //=====  XAccessibleEventListener  ============================================
462 
addEventListener(const Reference<XAccessibleEventListener> & xListener)463 void SAL_CALL SvxGraphCtrlAccessibleContext::addEventListener( const Reference< XAccessibleEventListener >& xListener )
464 {
465     if (xListener.is())
466     {
467         OGuard aGuard( Application::GetSolarMutex() );
468         if (!mnClientId)
469             mnClientId = comphelper::AccessibleEventNotifier::registerClient( );
470         comphelper::AccessibleEventNotifier::addEventListener( mnClientId, xListener );
471     }
472 }
473 
474 //-----------------------------------------------------------------------------
475 
removeEventListener(const Reference<XAccessibleEventListener> & xListener)476 void SAL_CALL SvxGraphCtrlAccessibleContext::removeEventListener( const Reference< XAccessibleEventListener >& xListener )
477 {
478     if (xListener.is())
479     {
480         OGuard aGuard( Application::GetSolarMutex() );
481 
482         sal_Int32 nListenerCount = comphelper::AccessibleEventNotifier::removeEventListener( mnClientId, xListener );
483         if ( !nListenerCount )
484         {
485             // no listeners anymore
486             // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
487             // and at least to us not firing any events anymore, in case somebody calls
488             // NotifyAccessibleEvent, again
489             comphelper::AccessibleEventNotifier::revokeClient( mnClientId );
490             mnClientId = 0;
491         }
492     }
493 }
494 
495 //-----------------------------------------------------------------------------
496 
addFocusListener(const Reference<awt::XFocusListener> & xListener)497 void SAL_CALL SvxGraphCtrlAccessibleContext::addFocusListener( const Reference< awt::XFocusListener >& xListener )
498 {
499     OGuard aGuard( Application::GetSolarMutex() );
500 
501     if( xListener.is() )
502     {
503         Reference< ::com::sun::star::awt::XWindow > xWindow( VCLUnoHelper::GetInterface( mpControl ) );
504         if( xWindow.is() )
505             xWindow->addFocusListener( xListener );
506     }
507 }
508 
509 //-----------------------------------------------------------------------------
510 
removeFocusListener(const Reference<awt::XFocusListener> & xListener)511 void SAL_CALL SvxGraphCtrlAccessibleContext::removeFocusListener( const Reference< awt::XFocusListener >& xListener )
512 {
513     OGuard aGuard( Application::GetSolarMutex() );
514 
515     if( xListener.is() )
516     {
517         Reference< ::com::sun::star::awt::XWindow > xWindow = VCLUnoHelper::GetInterface( mpControl );
518         if( xWindow.is() )
519             xWindow->removeFocusListener( xListener );
520     }
521 }
522 
523 //-----------------------------------------------------------------------------
524 
grabFocus()525 void SAL_CALL SvxGraphCtrlAccessibleContext::grabFocus()
526 {
527     OGuard aGuard( Application::GetSolarMutex() );
528 
529     if( NULL == mpControl )
530         throw DisposedException();
531 
532     mpControl->GrabFocus();
533 }
534 
535 //-----------------------------------------------------------------------------
536 
getAccessibleKeyBinding()537 Any SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleKeyBinding()
538 {
539     // here is no implementation, because here are no KeyBindings for every object
540     return Any();
541 }
542 
543 
544 
545 
546 
getForeground(void)547 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getForeground (void)
548 {
549     svtools::ColorConfig aColorConfig;
550     sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor;
551     return static_cast<sal_Int32>(nColor);
552 }
553 
554 
555 
556 
getBackground(void)557 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getBackground (void)
558 {
559     sal_uInt32 nColor = Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor();
560     return static_cast<sal_Int32>(nColor);
561 }
562 
563 
564 //=====  XServiceInfo  ========================================================
565 
getImplementationName(void)566 OUString SAL_CALL SvxGraphCtrlAccessibleContext::getImplementationName( void )
567 {
568     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.ui.SvxGraphCtrlAccessibleContext" ) );
569 }
570 
571 //-----------------------------------------------------------------------------
572 
supportsService(const OUString & sServiceName)573 sal_Bool SAL_CALL SvxGraphCtrlAccessibleContext::supportsService( const OUString& sServiceName )
574 {
575     OGuard aGuard( Application::GetSolarMutex() );
576     //  Iterate over all supported service names and return true if on of them
577     //  matches the given name.
578     Sequence< OUString >    aSupportedServices( getSupportedServiceNames() );
579     int                     nLenght = aSupportedServices.getLength();
580 
581     for( int i = 0 ; i < nLenght ; ++i )
582     {
583         if( sServiceName == aSupportedServices[ i ] )
584             return sal_True;
585     }
586 
587     return sal_False;
588 }
589 
590 //-----------------------------------------------------------------------------
591 
getSupportedServiceNames(void)592 Sequence< OUString > SAL_CALL SvxGraphCtrlAccessibleContext::getSupportedServiceNames( void )
593 {
594     Sequence< OUString > aSNs( 3 );
595 
596     aSNs[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.Accessible" ) );
597     aSNs[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) );
598     aSNs[2] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.AccessibleGraphControl" ) );
599 
600     return aSNs;
601 }
602 
603 //=====  XTypeProvider  =======================================================
604 
getImplementationId(void)605 Sequence<sal_Int8> SAL_CALL SvxGraphCtrlAccessibleContext::getImplementationId( void )
606 {
607     OGuard aGuard( Application::GetSolarMutex() );
608     return getUniqueId();
609 }
610 
611 //=====  XServiceName  ========================================================
612 
getServiceName(void)613 OUString SvxGraphCtrlAccessibleContext::getServiceName( void )
614 {
615     return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) );
616 }
617 
618 //=====  XAccessibleSelection =============================================
619 
selectAccessibleChild(sal_Int32 nIndex)620 void SAL_CALL SvxGraphCtrlAccessibleContext::selectAccessibleChild( sal_Int32 nIndex )
621 {
622     OGuard aGuard( Application::GetSolarMutex() );
623 
624     if( NULL == mpView )
625         throw DisposedException();
626 
627     SdrObject* pObj = getSdrObject( nIndex );
628 
629     if( pObj )
630         mpView->MarkObj( pObj, mpView->GetSdrPageView());
631 }
632 
633 //-----------------------------------------------------------------------------
634 
isAccessibleChildSelected(sal_Int32 nIndex)635 sal_Bool SAL_CALL SvxGraphCtrlAccessibleContext::isAccessibleChildSelected( sal_Int32 nIndex )
636 {
637     OGuard aGuard( Application::GetSolarMutex() );
638 
639     if( NULL == mpView )
640         throw DisposedException();
641 
642     return mpView->IsObjMarked( getSdrObject( nIndex ) );
643 }
644 
645 //-----------------------------------------------------------------------------
646 
clearAccessibleSelection()647 void SAL_CALL SvxGraphCtrlAccessibleContext::clearAccessibleSelection()
648 {
649     OGuard aGuard( Application::GetSolarMutex() );
650 
651     if( NULL == mpView )
652         throw DisposedException();
653 
654     mpView->UnmarkAllObj();
655 }
656 
657 //-----------------------------------------------------------------------------
658 
selectAllAccessibleChildren()659 void SAL_CALL SvxGraphCtrlAccessibleContext::selectAllAccessibleChildren()
660 {
661     OGuard aGuard( Application::GetSolarMutex() );
662 
663     if( NULL == mpView )
664         throw DisposedException();
665 
666     mpView->MarkAllObj();
667 }
668 
669 //-----------------------------------------------------------------------------
670 
getSelectedAccessibleChildCount()671 sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getSelectedAccessibleChildCount()
672 {
673     OGuard aGuard( Application::GetSolarMutex() );
674 
675     if( NULL == mpView )
676         throw DisposedException();
677 
678     const SdrMarkList& rList = mpView->GetMarkedObjectList();
679     return rList.GetMarkCount();
680 }
681 
682 //-----------------------------------------------------------------------------
683 
getSelectedAccessibleChild(sal_Int32 nIndex)684 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getSelectedAccessibleChild( sal_Int32 nIndex )
685 {
686     OGuard aGuard( Application::GetSolarMutex() );
687 
688     checkChildIndexOnSelection( nIndex );
689 
690     Reference< XAccessible > xAccessible;
691 
692     const SdrMarkList& rList = mpView->GetMarkedObjectList();
693     SdrObject* pObj = rList.GetMark(nIndex)->GetMarkedSdrObj();
694     if( pObj )
695         xAccessible = getAccessible( pObj );
696 
697     return xAccessible;
698 }
699 
700 //-----------------------------------------------------------------------------
701 
deselectAccessibleChild(sal_Int32 nIndex)702 void SAL_CALL SvxGraphCtrlAccessibleContext::deselectAccessibleChild( sal_Int32 nIndex )
703 {
704     OGuard aGuard( Application::GetSolarMutex() );
705 
706     checkChildIndexOnSelection( nIndex );
707 
708     if( mpView )
709     {
710         const SdrMarkList& rList = mpView->GetMarkedObjectList();
711 
712         SdrObject* pObj = getSdrObject( nIndex );
713         if( pObj )
714         {
715             SdrMarkList aRefList( rList );
716 
717             SdrPageView* pPV = mpView->GetSdrPageView();
718             mpView->UnmarkAllObj( pPV );
719 
720             sal_uInt32 nCount = aRefList.GetMarkCount();
721             sal_uInt32 nMark;
722             for( nMark = 0; nMark < nCount; nMark++ )
723             {
724                 if( aRefList.GetMark(nMark)->GetMarkedSdrObj() != pObj )
725                     mpView->MarkObj( aRefList.GetMark(nMark)->GetMarkedSdrObj(), pPV );
726             }
727         }
728     }
729 }
730 
731 //=====  internals ========================================================
732 
checkChildIndex(long nIndex)733 void SvxGraphCtrlAccessibleContext::checkChildIndex( long nIndex )
734 {
735     if( nIndex < 0 || nIndex >= getAccessibleChildCount() )
736         throw lang::IndexOutOfBoundsException();
737 }
738 
739 //-----------------------------------------------------------------------------
740 
checkChildIndexOnSelection(long nIndex)741 void SvxGraphCtrlAccessibleContext::checkChildIndexOnSelection( long nIndex )
742 {
743     if( nIndex < 0 || nIndex >= getSelectedAccessibleChildCount() )
744         throw lang::IndexOutOfBoundsException();
745 }
746 
747 //-----------------------------------------------------------------------------
748 
setName(const OUString & rName)749 void SvxGraphCtrlAccessibleContext::setName( const OUString& rName )
750 {
751     OGuard aGuard( Application::GetSolarMutex() );
752 
753     msName = rName;
754 }
755 
756 //-----------------------------------------------------------------------------
757 
setDescription(const OUString & rDescr)758 void SvxGraphCtrlAccessibleContext::setDescription( const OUString& rDescr )
759 {
760     OGuard aGuard( Application::GetSolarMutex() );
761 
762     msDescription = rDescr;
763 }
764 
765 
766 
767 
768 /** Replace the model, page, and view pointers by the ones provided
769     (explicitly and implicitly).
770 */
setModelAndView(SdrModel * pModel,SdrView * pView)771 void SvxGraphCtrlAccessibleContext::setModelAndView (
772     SdrModel* pModel,
773     SdrView* pView)
774 {
775     OGuard aGuard (Application::GetSolarMutex());
776 
777     mpModel = pModel;
778     if (mpModel != NULL)
779         mpPage = (SdrPage*)mpModel->GetPage( 0 );
780     mpView = pView;
781 
782     if (mpModel == NULL || mpPage == NULL || mpView == NULL)
783     {
784         mbDisposed = true;
785 
786         // Set all the pointers to NULL just in case they are used as
787         // a disposed flag.
788         mpModel = NULL;
789         mpPage = NULL;
790         mpView = NULL;
791     }
792 
793     maTreeInfo.SetSdrView (mpView);
794 }
795 
796 
797 
798 //-----------------------------------------------------------------------------
799 
disposing()800 void SAL_CALL SvxGraphCtrlAccessibleContext::disposing()
801 {
802     OGuard aGuard( Application::GetSolarMutex() );
803 
804     if( mbDisposed )
805         return;
806 
807     mbDisposed = sal_True;
808 
809     mpControl = NULL;       // object dies with representation
810     mpView = NULL;
811     mpPage = NULL;
812 
813     {
814         ShapesMapType::iterator I;
815 
816         for (I=mxShapes.begin(); I!=mxShapes.end(); I++)
817         {
818             XAccessible* pAcc = (*I).second;
819             Reference< XComponent > xComp( pAcc, UNO_QUERY );
820             if( xComp.is() )
821                 xComp->dispose();
822 
823             (*I).second->release();
824         }
825 
826         mxShapes.clear();
827     }
828 
829     // Send a disposing to all listeners.
830     if ( mnClientId )
831     {
832         comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
833         mnClientId =  0;
834     }
835 }
836 
837 //-----------------------------------------------------------------------------
838 
GetBoundingBoxOnScreen(void)839 Rectangle SvxGraphCtrlAccessibleContext::GetBoundingBoxOnScreen( void )
840 {
841     OGuard aGuard( Application::GetSolarMutex() );
842 
843     if( NULL == mpControl )
844         throw DisposedException();
845 
846     return Rectangle(
847         mpControl->GetAccessibleParentWindow()->OutputToAbsoluteScreenPixel(
848             mpControl->GetPosPixel() ),
849         mpControl->GetSizePixel() );
850 }
851 
852 //-----------------------------------------------------------------------------
853 
854 /** Calculate the relative coordinates of the bounding box as difference
855     between the absolute coordinates of the bounding boxes of this control
856     and its parent in the accessibility tree.
857 */
GetBoundingBox(void)858 Rectangle SvxGraphCtrlAccessibleContext::GetBoundingBox( void )
859 {
860     OGuard aGuard( Application::GetSolarMutex() );
861 
862     Rectangle aBounds ( 0, 0, 0, 0 );
863 
864     Window* pWindow = mpControl;
865     if (pWindow != NULL)
866     {
867         aBounds = pWindow->GetWindowExtentsRelative (NULL);
868         Window* pParent = pWindow->GetAccessibleParentWindow();
869         if (pParent != NULL)
870         {
871             Rectangle aParentRect = pParent->GetWindowExtentsRelative (NULL);
872             aBounds -= aParentRect.TopLeft();
873         }
874     }
875     else
876         throw DisposedException();
877 
878     return aBounds;
879 }
880 
881 //-----------------------------------------------------------------------------
882 
getUniqueId(void)883 Sequence< sal_Int8 > SvxGraphCtrlAccessibleContext::getUniqueId( void )
884 {
885     // no guard because it's private -> has to guarded when using it!
886     static OImplementationId*   pId = 0;
887     if( !pId )
888     {
889         OGuard aGuard( Application::GetSolarMutex() );
890         if( !pId)
891         {
892             static OImplementationId    aId;
893             pId = &aId;
894         }
895     }
896     return pId->getImplementationId();
897 }
898 
899 //-----------------------------------------------------------------------------
900 
Notify(SfxBroadcaster &,const SfxHint & rHint)901 void SvxGraphCtrlAccessibleContext::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
902 {
903     const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
904 
905     if( pSdrHint )
906     {
907         switch( pSdrHint->GetKind() )
908         {
909             case HINT_OBJCHG:
910                 {
911                     ShapesMapType::iterator iter = mxShapes.find( pSdrHint->GetObject() );
912 
913                     if( iter != mxShapes.end() )
914                     {
915                         // if we already have one, return it
916                         AccessibleShape* pShape = (*iter).second;
917 
918                         if( NULL != pShape )
919                             pShape->CommitChange( AccessibleEventId::VISIBLE_DATA_CHANGED, uno::Any(), uno::Any() );
920                     }
921                 }
922                 break;
923 
924             case HINT_OBJINSERTED:
925                 CommitChange( AccessibleEventId::CHILD, makeAny( getAccessible( pSdrHint->GetObject() ) ) , uno::Any());
926                 break;
927             case HINT_OBJREMOVED:
928                 CommitChange( AccessibleEventId::CHILD, uno::Any(), makeAny( getAccessible( pSdrHint->GetObject() ) )  );
929                 break;
930             case HINT_MODELCLEARED:
931                 dispose();
932                 break;
933             default:
934                 break;
935         }
936     }
937     else
938     {
939         const SfxSimpleHint* pSfxHint = PTR_CAST(SfxSimpleHint, &rHint );
940 
941         // ist unser SdDrawDocument gerade gestorben?
942         if(pSfxHint && pSfxHint->GetId() == SFX_HINT_DYING)
943         {
944             dispose();
945         }
946     }
947 }
948 
949 //=====  IAccessibleViewforwarder  ========================================
950 
IsValid(void) const951 sal_Bool SvxGraphCtrlAccessibleContext::IsValid (void) const
952 {
953     return sal_True;
954 }
955 
956 //-----------------------------------------------------------------------------
957 
GetVisibleArea(void) const958 Rectangle SvxGraphCtrlAccessibleContext::GetVisibleArea (void) const
959 {
960     Rectangle aVisArea;
961 
962     if( mpView && mpView->PaintWindowCount())
963     {
964         SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow(0L);
965         aVisArea = pPaintWindow->GetVisibleArea();
966     }
967 
968     return aVisArea;
969 }
970 
971 //-----------------------------------------------------------------------------
972 
LogicToPixel(const Point & rPoint) const973 Point SvxGraphCtrlAccessibleContext::LogicToPixel (const Point& rPoint) const
974 {
975     if( mpControl )
976     {
977         Rectangle aBBox(mpControl->GetWindowExtentsRelative(NULL));
978         return mpControl->LogicToPixel (rPoint) + aBBox.TopLeft();
979     }
980     else
981     {
982         return rPoint;
983     }
984 }
985 
986 //-----------------------------------------------------------------------------
987 
LogicToPixel(const Size & rSize) const988 Size SvxGraphCtrlAccessibleContext::LogicToPixel (const Size& rSize) const
989 {
990     if( mpControl )
991         return mpControl->LogicToPixel (rSize);
992     else
993         return rSize;
994 }
995 
996 //-----------------------------------------------------------------------------
997 
PixelToLogic(const Point & rPoint) const998 Point SvxGraphCtrlAccessibleContext::PixelToLogic (const Point& rPoint) const
999 {
1000     if( mpControl )
1001         return mpControl->PixelToLogic (rPoint);
1002     else
1003         return rPoint;
1004 }
1005 
1006 //-----------------------------------------------------------------------------
1007 
PixelToLogic(const Size & rSize) const1008 Size SvxGraphCtrlAccessibleContext::PixelToLogic (const Size& rSize) const
1009 {
1010     if( mpControl )
1011         return mpControl->PixelToLogic (rSize);
1012     else
1013         return rSize;
1014 }
1015