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 ) throw( RuntimeException )
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 ) 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
getAccessibleAtPoint(const awt::Point & rPoint)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
getBounds()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
getLocation()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
getLocationOnScreen()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
getSize()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
getAccessibleChildCount(void)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 */
getSdrObject(sal_Int32 nIndex)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 */
CommitChange(sal_Int16 nEventId,const uno::Any & rNewValue,const uno::Any & rOldValue)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 */
FireEvent(const AccessibleEventObject & aEvent)331 void SvxGraphCtrlAccessibleContext::FireEvent (const AccessibleEventObject& aEvent)
332 {
333 if (mnClientId)
334 comphelper::AccessibleEventNotifier::addEvent( mnClientId, aEvent );
335 }
336
337 //-----------------------------------------------------------------------------
338
getAccessibleChild(sal_Int32 nIndex)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
getAccessibleParent(void)349 Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleParent( void ) throw( RuntimeException )
350 {
351 return mxParent;
352 }
353
354 //-----------------------------------------------------------------------------
355
getAccessibleIndexInParent(void)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
getAccessibleRole(void)388 sal_Int16 SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleRole( void ) throw( RuntimeException )
389 {
390 return AccessibleRole::PANEL;
391 }
392
393 //-----------------------------------------------------------------------------
394
getAccessibleDescription(void)395 OUString SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleDescription( void ) throw( RuntimeException )
396 {
397 OGuard aGuard( Application::GetSolarMutex() );
398 return msDescription;
399 }
400
401 //-----------------------------------------------------------------------------
402
getAccessibleName(void)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 */
getAccessibleRelationSet(void)414 Reference< XAccessibleRelationSet > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleRelationSet( void ) throw( RuntimeException )
415 {
416 return Reference< XAccessibleRelationSet >();
417 }
418
419 //-----------------------------------------------------------------------------
420
getAccessibleStateSet(void)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
getLocale(void)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
addEventListener(const Reference<XAccessibleEventListener> & xListener)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
removeEventListener(const Reference<XAccessibleEventListener> & xListener)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
addFocusListener(const Reference<awt::XFocusListener> & xListener)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
removeFocusListener(const Reference<awt::XFocusListener> & xListener)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
grabFocus()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
getAccessibleKeyBinding()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
getForeground(void)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
getBackground(void)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
getImplementationName(void)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
supportsService(const OUString & sServiceName)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
getSupportedServiceNames(void)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
getImplementationId(void)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
getServiceName(void)621 OUString SvxGraphCtrlAccessibleContext::getServiceName( void ) throw( RuntimeException )
622 {
623 return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.accessibility.AccessibleContext" ) );
624 }
625
626 //===== XAccessibleSelection =============================================
627
selectAccessibleChild(sal_Int32 nIndex)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
isAccessibleChildSelected(sal_Int32 nIndex)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
clearAccessibleSelection()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
selectAllAccessibleChildren()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
getSelectedAccessibleChildCount()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
getSelectedAccessibleChild(sal_Int32 nIndex)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
deselectAccessibleChild(sal_Int32 nIndex)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
checkChildIndex(long nIndex)742 void SvxGraphCtrlAccessibleContext::checkChildIndex( long nIndex ) throw( lang::IndexOutOfBoundsException )
743 {
744 if( nIndex < 0 || nIndex >= getAccessibleChildCount() )
745 throw lang::IndexOutOfBoundsException();
746 }
747
748 //-----------------------------------------------------------------------------
749
checkChildIndexOnSelection(long nIndex)750 void SvxGraphCtrlAccessibleContext::checkChildIndexOnSelection( long nIndex ) throw( lang::IndexOutOfBoundsException )
751 {
752 if( nIndex < 0 || nIndex >= getSelectedAccessibleChildCount() )
753 throw lang::IndexOutOfBoundsException();
754 }
755
756 //-----------------------------------------------------------------------------
757
setName(const OUString & rName)758 void SvxGraphCtrlAccessibleContext::setName( const OUString& rName )
759 {
760 OGuard aGuard( Application::GetSolarMutex() );
761
762 msName = rName;
763 }
764
765 //-----------------------------------------------------------------------------
766
setDescription(const OUString & rDescr)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 */
setModelAndView(SdrModel * pModel,SdrView * pView)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
disposing()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
GetBoundingBoxOnScreen(void)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 */
GetBoundingBox(void)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
getUniqueId(void)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
Notify(SfxBroadcaster &,const SfxHint & rHint)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
IsValid(void) const960 sal_Bool SvxGraphCtrlAccessibleContext::IsValid (void) const
961 {
962 return sal_True;
963 }
964
965 //-----------------------------------------------------------------------------
966
GetVisibleArea(void) const967 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
LogicToPixel(const Point & rPoint) const982 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
LogicToPixel(const Size & rSize) const997 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
PixelToLogic(const Point & rPoint) const1007 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
PixelToLogic(const Size & rSize) const1017 Size SvxGraphCtrlAccessibleContext::PixelToLogic (const Size& rSize) const
1018 {
1019 if( mpControl )
1020 return mpControl->PixelToLogic (rSize);
1021 else
1022 return rSize;
1023 }
1024