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