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/supportsservice.hxx>
28 : #include <cppuhelper/typeprovider.hxx>
29 : #include <toolkit/helper/vclunohelper.hxx>
30 : #include <vcl/svapp.hxx>
31 : #include <vcl/settings.hxx>
32 : #include <osl/mutex.hxx>
33 : #include <tools/gen.hxx>
34 : #include <svl/smplhint.hxx>
35 : #include <toolkit/helper/convert.hxx>
36 : #include <svtools/colorcfg.hxx>
37 : #include <comphelper/accessibleeventnotifier.hxx>
38 : #include <svx/sdrpaintwindow.hxx>
39 :
40 : //===== local includes ========================================================
41 : #include <svx/ShapeTypeHandler.hxx>
42 : #include <svx/AccessibleShapeInfo.hxx>
43 : #include "GraphCtlAccessibleContext.hxx"
44 : #include <svx/graphctl.hxx>
45 : #include <svx/dialogs.hrc>
46 : #include "accessibility.hrc"
47 : #include <svx/svdpage.hxx>
48 : #include <svx/unomod.hxx>
49 : #include <svx/dialmgr.hxx>
50 : #include <svx/svdetc.hxx>
51 : #include <svx/sdrhittesthelper.hxx>
52 :
53 : //===== namespaces ===========================================================
54 :
55 : using namespace ::cppu;
56 : using namespace ::osl;
57 : using namespace ::accessibility;
58 : using namespace ::com::sun::star;
59 : using namespace ::com::sun::star::uno;
60 : using namespace ::com::sun::star::drawing;
61 : using namespace ::com::sun::star::lang;
62 : using namespace ::com::sun::star::accessibility;
63 :
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, std::exception )
184 : {
185 0 : return this;
186 : }
187 :
188 : //===== XAccessibleComponent ================================================
189 :
190 0 : sal_Bool SAL_CALL SvxGraphCtrlAccessibleContext::containsPoint( const awt::Point& rPoint ) throw( RuntimeException, std::exception )
191 : {
192 : // no guard -> done in getSize()
193 0 : awt::Size aSize (getSize());
194 0 : return (rPoint.X >= 0)
195 0 : && (rPoint.X < aSize.Width)
196 0 : && (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, std::exception )
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, std::exception )
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, std::exception )
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, std::exception )
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, std::exception )
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, std::exception )
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, std::exception )
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, std::exception )
339 : {
340 0 : return mxParent;
341 : }
342 :
343 :
344 :
345 0 : sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleIndexInParent( void ) throw( RuntimeException, std::exception )
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, std::exception )
378 : {
379 0 : return AccessibleRole::PANEL;
380 : }
381 :
382 :
383 :
384 0 : OUString SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleDescription( void ) throw( RuntimeException, std::exception )
385 : {
386 0 : ::SolarMutexGuard aGuard;
387 0 : return msDescription;
388 : }
389 :
390 :
391 :
392 0 : OUString SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleName( void ) throw( RuntimeException, std::exception )
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, std::exception )
404 : {
405 0 : return Reference< XAccessibleRelationSet >();
406 : }
407 :
408 :
409 :
410 0 : Reference< XAccessibleStateSet > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleStateSet( void ) throw( RuntimeException, std::exception )
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, std::exception )
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, std::exception )
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, std::exception )
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, std::exception )
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, std::exception)
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, std::exception)
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 0 : OUString SAL_CALL SvxGraphCtrlAccessibleContext::getImplementationName( void ) throw( RuntimeException, std::exception )
561 : {
562 0 : return OUString( "com.sun.star.comp.ui.SvxGraphCtrlAccessibleContext" );
563 : }
564 :
565 0 : sal_Bool SAL_CALL SvxGraphCtrlAccessibleContext::supportsService( const OUString& sServiceName ) throw( RuntimeException, std::exception )
566 : {
567 0 : return cppu::supportsService(this, sServiceName);
568 : }
569 :
570 0 : Sequence< OUString > SAL_CALL SvxGraphCtrlAccessibleContext::getSupportedServiceNames( void ) throw( RuntimeException, std::exception )
571 : {
572 0 : Sequence< OUString > aSNs( 3 );
573 :
574 0 : aSNs[0] = "com.sun.star.accessibility.Accessible";
575 0 : aSNs[1] = "com.sun.star.accessibility.AccessibleContext";
576 0 : aSNs[2] = "com.sun.star.drawing.AccessibleGraphControl";
577 :
578 0 : return aSNs;
579 : }
580 :
581 : //===== XTypeProvider =======================================================
582 0 : Sequence<sal_Int8> SAL_CALL SvxGraphCtrlAccessibleContext::getImplementationId( void ) throw( RuntimeException, std::exception )
583 : {
584 0 : return css::uno::Sequence<sal_Int8>();
585 : }
586 :
587 : //===== XServiceName ========================================================
588 :
589 0 : OUString SvxGraphCtrlAccessibleContext::getServiceName( void ) throw( RuntimeException, std::exception )
590 : {
591 0 : return OUString( "com.sun.star.accessibility.AccessibleContext" );
592 : }
593 :
594 : //===== XAccessibleSelection =============================================
595 :
596 0 : void SAL_CALL SvxGraphCtrlAccessibleContext::selectAccessibleChild( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException, std::exception )
597 : {
598 0 : ::SolarMutexGuard aGuard;
599 :
600 0 : if( NULL == mpView )
601 0 : throw DisposedException();
602 :
603 0 : SdrObject* pObj = getSdrObject( nIndex );
604 :
605 0 : if( pObj )
606 0 : mpView->MarkObj( pObj, mpView->GetSdrPageView());
607 0 : }
608 :
609 :
610 :
611 0 : sal_Bool SAL_CALL SvxGraphCtrlAccessibleContext::isAccessibleChildSelected( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException, std::exception )
612 : {
613 0 : ::SolarMutexGuard aGuard;
614 :
615 0 : if( NULL == mpView )
616 0 : throw DisposedException();
617 :
618 0 : return mpView->IsObjMarked( getSdrObject( nIndex ) );
619 : }
620 :
621 :
622 :
623 0 : void SAL_CALL SvxGraphCtrlAccessibleContext::clearAccessibleSelection() throw( RuntimeException, std::exception )
624 : {
625 0 : ::SolarMutexGuard aGuard;
626 :
627 0 : if( NULL == mpView )
628 0 : throw DisposedException();
629 :
630 0 : mpView->UnmarkAllObj();
631 0 : }
632 :
633 :
634 :
635 0 : void SAL_CALL SvxGraphCtrlAccessibleContext::selectAllAccessibleChildren() throw( RuntimeException, std::exception )
636 : {
637 0 : ::SolarMutexGuard aGuard;
638 :
639 0 : if( NULL == mpView )
640 0 : throw DisposedException();
641 :
642 0 : mpView->MarkAllObj();
643 0 : }
644 :
645 :
646 :
647 0 : sal_Int32 SAL_CALL SvxGraphCtrlAccessibleContext::getSelectedAccessibleChildCount() throw( RuntimeException, std::exception )
648 : {
649 0 : ::SolarMutexGuard aGuard;
650 :
651 0 : if( NULL == mpView )
652 0 : throw DisposedException();
653 :
654 0 : const SdrMarkList& rList = mpView->GetMarkedObjectList();
655 0 : return rList.GetMarkCount();
656 : }
657 :
658 :
659 :
660 0 : Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getSelectedAccessibleChild( sal_Int32 nIndex )
661 : throw( lang::IndexOutOfBoundsException, RuntimeException, std::exception )
662 : {
663 0 : ::SolarMutexGuard aGuard;
664 :
665 0 : checkChildIndexOnSelection( nIndex );
666 :
667 0 : Reference< XAccessible > xAccessible;
668 :
669 0 : const SdrMarkList& rList = mpView->GetMarkedObjectList();
670 0 : SdrObject* pObj = rList.GetMark(nIndex)->GetMarkedSdrObj();
671 0 : if( pObj )
672 0 : xAccessible = getAccessible( pObj );
673 :
674 0 : return xAccessible;
675 : }
676 :
677 :
678 :
679 0 : void SAL_CALL SvxGraphCtrlAccessibleContext::deselectAccessibleChild( sal_Int32 nIndex ) throw( lang::IndexOutOfBoundsException, RuntimeException, std::exception )
680 : {
681 0 : ::SolarMutexGuard aGuard;
682 :
683 0 : checkChildIndexOnSelection( nIndex );
684 :
685 0 : if( mpView )
686 : {
687 0 : const SdrMarkList& rList = mpView->GetMarkedObjectList();
688 :
689 0 : SdrObject* pObj = getSdrObject( nIndex );
690 0 : if( pObj )
691 : {
692 0 : SdrMarkList aRefList( rList );
693 :
694 0 : SdrPageView* pPV = mpView->GetSdrPageView();
695 0 : mpView->UnmarkAllObj( pPV );
696 :
697 0 : sal_uInt32 nCount = aRefList.GetMarkCount();
698 : sal_uInt32 nMark;
699 0 : for( nMark = 0; nMark < nCount; nMark++ )
700 : {
701 0 : if( aRefList.GetMark(nMark)->GetMarkedSdrObj() != pObj )
702 0 : mpView->MarkObj( aRefList.GetMark(nMark)->GetMarkedSdrObj(), pPV );
703 0 : }
704 : }
705 0 : }
706 0 : }
707 :
708 : //===== internals ========================================================
709 :
710 0 : void SvxGraphCtrlAccessibleContext::checkChildIndexOnSelection( long nIndex ) throw( lang::IndexOutOfBoundsException )
711 : {
712 0 : if( nIndex < 0 || nIndex >= getSelectedAccessibleChildCount() )
713 0 : throw lang::IndexOutOfBoundsException();
714 0 : }
715 :
716 :
717 :
718 : /** Replace the model, page, and view pointers by the ones provided
719 : (explicitly and implicitly).
720 : */
721 0 : void SvxGraphCtrlAccessibleContext::setModelAndView (
722 : SdrModel* pModel,
723 : SdrView* pView)
724 : {
725 0 : ::SolarMutexGuard aGuard;
726 :
727 0 : mpModel = pModel;
728 0 : if (mpModel != NULL)
729 0 : mpPage = (SdrPage*)mpModel->GetPage( 0 );
730 0 : mpView = pView;
731 :
732 0 : if (mpModel == NULL || mpPage == NULL || mpView == NULL)
733 : {
734 0 : mbDisposed = true;
735 :
736 : // Set all the pointers to NULL just in case they are used as
737 : // a disposed flag.
738 0 : mpModel = NULL;
739 0 : mpPage = NULL;
740 0 : mpView = NULL;
741 : }
742 :
743 0 : maTreeInfo.SetSdrView (mpView);
744 0 : }
745 :
746 :
747 :
748 :
749 :
750 0 : void SAL_CALL SvxGraphCtrlAccessibleContext::disposing()
751 : {
752 0 : ::SolarMutexGuard aGuard;
753 :
754 0 : if( mbDisposed )
755 0 : return;
756 :
757 0 : mbDisposed = sal_True;
758 :
759 0 : mpControl = NULL; // object dies with representation
760 0 : mpView = NULL;
761 0 : mpPage = NULL;
762 :
763 : {
764 0 : ShapesMapType::iterator I;
765 :
766 0 : for (I=mxShapes.begin(); I!=mxShapes.end(); ++I)
767 : {
768 0 : XAccessible* pAcc = (*I).second;
769 0 : Reference< XComponent > xComp( pAcc, UNO_QUERY );
770 0 : if( xComp.is() )
771 0 : xComp->dispose();
772 :
773 0 : (*I).second->release();
774 0 : }
775 :
776 0 : mxShapes.clear();
777 : }
778 :
779 : // Send a disposing to all listeners.
780 0 : if ( mnClientId )
781 : {
782 0 : comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( mnClientId, *this );
783 0 : mnClientId = 0;
784 0 : }
785 : }
786 :
787 :
788 :
789 0 : Rectangle SvxGraphCtrlAccessibleContext::GetBoundingBoxOnScreen( void ) throw( RuntimeException )
790 : {
791 0 : ::SolarMutexGuard aGuard;
792 :
793 0 : if( NULL == mpControl )
794 0 : throw DisposedException();
795 :
796 : return Rectangle(
797 : mpControl->GetAccessibleParentWindow()->OutputToAbsoluteScreenPixel(
798 0 : mpControl->GetPosPixel() ),
799 0 : mpControl->GetSizePixel() );
800 : }
801 :
802 :
803 :
804 : /** Calculate the relative coordinates of the bounding box as difference
805 : between the absolute coordinates of the bounding boxes of this control
806 : and its parent in the accessibility tree.
807 : */
808 0 : Rectangle SvxGraphCtrlAccessibleContext::GetBoundingBox( void ) throw( RuntimeException )
809 : {
810 0 : ::SolarMutexGuard aGuard;
811 :
812 0 : Rectangle aBounds ( 0, 0, 0, 0 );
813 :
814 0 : Window* pWindow = mpControl;
815 0 : if (pWindow != NULL)
816 : {
817 0 : aBounds = pWindow->GetWindowExtentsRelative (NULL);
818 0 : Window* pParent = pWindow->GetAccessibleParentWindow();
819 0 : if (pParent != NULL)
820 : {
821 0 : Rectangle aParentRect = pParent->GetWindowExtentsRelative (NULL);
822 0 : aBounds -= aParentRect.TopLeft();
823 : }
824 : }
825 : else
826 0 : throw DisposedException();
827 :
828 0 : return aBounds;
829 : }
830 :
831 0 : void SvxGraphCtrlAccessibleContext::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
832 : {
833 0 : const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
834 :
835 0 : if( pSdrHint )
836 : {
837 0 : switch( pSdrHint->GetKind() )
838 : {
839 : case HINT_OBJCHG:
840 : {
841 0 : ShapesMapType::iterator iter = mxShapes.find( pSdrHint->GetObject() );
842 :
843 0 : if( iter != mxShapes.end() )
844 : {
845 : // if we already have one, return it
846 0 : AccessibleShape* pShape = (*iter).second;
847 :
848 0 : if( NULL != pShape )
849 0 : pShape->CommitChange( AccessibleEventId::VISIBLE_DATA_CHANGED, uno::Any(), uno::Any() );
850 : }
851 : }
852 0 : break;
853 :
854 : case HINT_OBJINSERTED:
855 0 : CommitChange( AccessibleEventId::CHILD, makeAny( getAccessible( pSdrHint->GetObject() ) ) , uno::Any());
856 0 : break;
857 : case HINT_OBJREMOVED:
858 0 : CommitChange( AccessibleEventId::CHILD, uno::Any(), makeAny( getAccessible( pSdrHint->GetObject() ) ) );
859 0 : break;
860 : case HINT_MODELCLEARED:
861 0 : dispose();
862 0 : break;
863 : default:
864 0 : break;
865 : }
866 : }
867 : else
868 : {
869 0 : const SfxSimpleHint* pSfxHint = PTR_CAST(SfxSimpleHint, &rHint );
870 :
871 : // Has our SdDrawDocument just died?
872 0 : if(pSfxHint && pSfxHint->GetId() == SFX_HINT_DYING)
873 : {
874 0 : dispose();
875 : }
876 : }
877 0 : }
878 :
879 : //===== IAccessibleViewforwarder ========================================
880 :
881 0 : bool SvxGraphCtrlAccessibleContext::IsValid (void) const
882 : {
883 0 : return true;
884 : }
885 :
886 :
887 :
888 0 : Rectangle SvxGraphCtrlAccessibleContext::GetVisibleArea (void) const
889 : {
890 0 : Rectangle aVisArea;
891 :
892 0 : if( mpView && mpView->PaintWindowCount())
893 : {
894 0 : SdrPaintWindow* pPaintWindow = mpView->GetPaintWindow(0L);
895 0 : aVisArea = pPaintWindow->GetVisibleArea();
896 : }
897 :
898 0 : return aVisArea;
899 : }
900 :
901 :
902 :
903 0 : Point SvxGraphCtrlAccessibleContext::LogicToPixel (const Point& rPoint) const
904 : {
905 0 : if( mpControl )
906 : {
907 0 : Rectangle aBBox(mpControl->GetWindowExtentsRelative(NULL));
908 0 : return mpControl->LogicToPixel (rPoint) + aBBox.TopLeft();
909 : }
910 : else
911 : {
912 0 : return rPoint;
913 : }
914 : }
915 :
916 :
917 :
918 0 : Size SvxGraphCtrlAccessibleContext::LogicToPixel (const Size& rSize) const
919 : {
920 0 : if( mpControl )
921 0 : return mpControl->LogicToPixel (rSize);
922 : else
923 0 : return rSize;
924 : }
925 :
926 :
927 :
928 0 : Point SvxGraphCtrlAccessibleContext::PixelToLogic (const Point& rPoint) const
929 : {
930 0 : if( mpControl )
931 0 : return mpControl->PixelToLogic (rPoint);
932 : else
933 0 : return rPoint;
934 : }
935 :
936 :
937 :
938 0 : Size SvxGraphCtrlAccessibleContext::PixelToLogic (const Size& rSize) const
939 : {
940 0 : if( mpControl )
941 0 : return mpControl->PixelToLogic (rSize);
942 : else
943 0 : return rSize;
944 : }
945 :
946 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|