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