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