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_sd.hxx"
26 #include "AccessibleDrawDocumentView.hxx"
27 #include <com/sun/star/drawing/XDrawPage.hpp>
28 #include <com/sun/star/drawing/XDrawView.hpp>
29 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
30 #include <com/sun/star/drawing/XShapes.hpp>
31 #include <com/sun/star/container/XChild.hpp>
32 #include <com/sun/star/frame/XController.hpp>
33 #include <com/sun/star/frame/XFrame.hpp>
34 #include <com/sun/star/document/XEventBroadcaster.hpp>
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
37 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <rtl/ustring.h>
40 #include<sfx2/viewfrm.hxx>
41
42 #include <svx/AccessibleShape.hxx>
43
44 #include <svx/svdobj.hxx>
45 #include <svx/svdmodel.hxx>
46 #include <svx/unoapi.hxx>
47 #include <svx/unoshcol.hxx>
48 #include <toolkit/helper/vclunohelper.hxx>
49 #include "Window.hxx"
50 #include <vcl/svapp.hxx>
51
52
53 #include "ViewShell.hxx"
54 #include "View.hxx"
55 #include "DrawDocShell.hxx"
56 #include <drawdoc.hxx>
57 #include <algorithm>
58 #include "sdpage.hxx"
59 #include "slideshow.hxx"
60 #include "anminfo.hxx"
61 #include <memory>
62
63 #include "accessibility.hrc"
64 #include "sdresid.hxx"
65 #include <vos/mutex.hxx>
66
67 using ::rtl::OUString;
68 using namespace ::com::sun::star;
69 using namespace ::com::sun::star::uno;
70 using namespace ::com::sun::star::accessibility;
71
72 class SfxViewFrame;
73
74 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
75
76 namespace accessibility {
77
78
79 struct XShapePosCompareHelper
80 {
operator ()accessibility::XShapePosCompareHelper81 bool operator() ( const uno::Reference<drawing::XShape>& xshape1,
82 const uno::Reference<drawing::XShape>& xshape2 ) const
83 {
84 // modify the compare method to return the Z-Order, not layout order
85 SdrObject* pObj1 = GetSdrObjectFromXShape(xshape1);
86 SdrObject* pObj2 = GetSdrObjectFromXShape(xshape2);
87 if(pObj1 && pObj2)
88 return pObj1->GetOrdNum() < pObj2->GetOrdNum();
89 else
90 return 0;
91 }
92 };
93 //===== internal ============================================================
94
AccessibleDrawDocumentView(::sd::Window * pSdWindow,::sd::ViewShell * pViewShell,const uno::Reference<frame::XController> & rxController,const uno::Reference<XAccessible> & rxParent)95 AccessibleDrawDocumentView::AccessibleDrawDocumentView (
96 ::sd::Window* pSdWindow,
97 ::sd::ViewShell* pViewShell,
98 const uno::Reference<frame::XController>& rxController,
99 const uno::Reference<XAccessible>& rxParent)
100 : AccessibleDocumentViewBase (pSdWindow, pViewShell, rxController, rxParent),
101 mpSdViewSh( pViewShell ),
102 mpChildrenManager (NULL)
103 {
104 OSL_TRACE ("AccessibleDrawDocumentView");
105 UpdateAccessibleName();
106 }
107
108
109
110
~AccessibleDrawDocumentView(void)111 AccessibleDrawDocumentView::~AccessibleDrawDocumentView (void)
112 {
113 OSL_TRACE ("~AccessibleDrawDocumentView");
114 DBG_ASSERT (rBHelper.bDisposed || rBHelper.bInDispose,
115 "~AccessibleDrawDocumentView: object has not been disposed");
116 }
117
118
119
120
Init(void)121 void AccessibleDrawDocumentView::Init (void)
122 {
123 AccessibleDocumentViewBase::Init ();
124
125 // Determine the list of shapes on the current page.
126 uno::Reference<drawing::XShapes> xShapeList;
127 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
128 if (xView.is())
129 xShapeList = uno::Reference<drawing::XShapes> (
130 xView->getCurrentPage(), uno::UNO_QUERY);
131
132 // Create the children manager.
133 mpChildrenManager = new ChildrenManager(this, xShapeList, maShapeTreeInfo, *this);
134 if (mpChildrenManager != NULL)
135 {
136 // Create the page shape and initialize it. The shape is acquired
137 // before initialization and released after transferring ownership
138 // to the children manager to prevent premature disposing of the
139 // shape.
140 AccessiblePageShape* pPage = CreateDrawPageShape();
141 if (pPage != NULL)
142 {
143 pPage->acquire();
144 pPage->Init();
145 mpChildrenManager->AddAccessibleShape (
146 std::auto_ptr<AccessibleShape>(pPage));
147 pPage->release();
148 mpChildrenManager->Update ();
149 }
150 mpChildrenManager->UpdateSelection ();
151 }
152 }
153
154
155
156
ViewForwarderChanged(ChangeType aChangeType,const IAccessibleViewForwarder * pViewForwarder)157 void AccessibleDrawDocumentView::ViewForwarderChanged (ChangeType aChangeType,
158 const IAccessibleViewForwarder* pViewForwarder)
159 {
160 AccessibleDocumentViewBase::ViewForwarderChanged (aChangeType, pViewForwarder);
161 if (mpChildrenManager != NULL)
162 mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder);
163 }
164
165
166
167
168 /** The page shape is created on every call at the moment (provided that
169 every thing goes well).
170 */
CreateDrawPageShape(void)171 AccessiblePageShape* AccessibleDrawDocumentView::CreateDrawPageShape (void)
172 {
173 AccessiblePageShape* pShape = NULL;
174
175 // Create a shape that represents the actual draw page.
176 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
177 if (xView.is())
178 {
179 uno::Reference<beans::XPropertySet> xSet (
180 uno::Reference<beans::XPropertySet> (xView->getCurrentPage(), uno::UNO_QUERY));
181 if (xSet.is())
182 {
183 // Create a rectangle shape that will represent the draw page.
184 uno::Reference<lang::XMultiServiceFactory> xFactory (mxModel, uno::UNO_QUERY);
185 uno::Reference<drawing::XShape> xRectangle;
186 if (xFactory.is())
187 xRectangle = uno::Reference<drawing::XShape>(xFactory->createInstance (
188 OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.RectangleShape"))),
189 uno::UNO_QUERY);
190
191 // Set the shape's size and position.
192 if (xRectangle.is())
193 {
194 uno::Any aValue;
195 awt::Point aPosition;
196 awt::Size aSize;
197
198 // Set size and position of the shape to those of the draw
199 // page.
200 aValue = xSet->getPropertyValue (
201 OUString (RTL_CONSTASCII_USTRINGPARAM("BorderLeft")));
202 aValue >>= aPosition.X;
203 aValue = xSet->getPropertyValue (
204 OUString (RTL_CONSTASCII_USTRINGPARAM("BorderTop")));
205 aValue >>= aPosition.Y;
206 xRectangle->setPosition (aPosition);
207
208 aValue = xSet->getPropertyValue (
209 OUString (RTL_CONSTASCII_USTRINGPARAM("Width")));
210 aValue >>= aSize.Width;
211 aValue = xSet->getPropertyValue (
212 OUString (RTL_CONSTASCII_USTRINGPARAM("Height")));
213 aValue >>= aSize.Height;
214 xRectangle->setSize (aSize);
215
216 // Create the accessible object for the shape and
217 // initialize it.
218 pShape = new AccessiblePageShape (
219 xView->getCurrentPage(), this, maShapeTreeInfo);
220 }
221 }
222 }
223 return pShape;
224 }
225
226
227
228
229 //===== XAccessibleContext ==================================================
230
231 sal_Int32 SAL_CALL
getAccessibleChildCount(void)232 AccessibleDrawDocumentView::getAccessibleChildCount (void)
233 throw (uno::RuntimeException)
234 {
235 ThrowIfDisposed ();
236
237 long mpChildCount = AccessibleDocumentViewBase::getAccessibleChildCount();
238
239 // Forward request to children manager.
240 if (mpChildrenManager != NULL)
241 mpChildCount += mpChildrenManager->GetChildCount ();
242
243 return mpChildCount;
244 }
245
246
247
248
249 uno::Reference<XAccessible> SAL_CALL
getAccessibleChild(sal_Int32 nIndex)250 AccessibleDrawDocumentView::getAccessibleChild (sal_Int32 nIndex)
251 throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
252 {
253 ThrowIfDisposed ();
254
255 ::osl::ClearableMutexGuard aGuard (maMutex);
256
257 // Take care of children of the base class.
258 sal_Int32 nCount = AccessibleDocumentViewBase::getAccessibleChildCount();
259 if (nCount > 0)
260 {
261 if (nIndex < nCount)
262 return AccessibleDocumentViewBase::getAccessibleChild(nIndex);
263 else
264 nIndex -= nCount;
265 }
266
267 // Create a copy of the pointer to the children manager and release the
268 // mutex before calling any of its methods.
269 ChildrenManager* pChildrenManager = mpChildrenManager;
270 aGuard.clear();
271
272 // Forward request to children manager.
273 if (pChildrenManager != NULL)
274 {
275 return pChildrenManager->GetChild (nIndex);
276 }
277 else
278 throw lang::IndexOutOfBoundsException (
279 ::rtl::OUString::createFromAscii ("no accessible child with index ")
280 + rtl::OUString::valueOf(nIndex),
281 static_cast<uno::XWeak*>(this));
282 }
283
284 OUString SAL_CALL
getAccessibleName(void)285 AccessibleDrawDocumentView::getAccessibleName(void)
286 throw (::com::sun::star::uno::RuntimeException)
287 {
288 OUString sName = String( SdResId(SID_SD_A11Y_D_PRESENTATION) );
289 ::sd::View* pSdView = static_cast< ::sd::View* >( maShapeTreeInfo.GetSdrView() );
290 if ( pSdView )
291 {
292 SdDrawDocument* pDoc = pSdView->GetDoc();
293 if ( pDoc )
294 {
295 rtl::OUString sFileName = pDoc->getDocAccTitle();
296 if ( !sFileName.getLength() )
297 {
298 ::sd::DrawDocShell* pDocSh = pSdView->GetDocSh();
299 if ( pDocSh )
300 {
301 sFileName = pDocSh->GetTitle( SFX_TITLE_APINAME );
302 }
303 }
304
305 OUString sReadOnly;
306 if(pDoc->getDocReadOnly())
307 {
308 sReadOnly = String(SdResId(SID_SD_A11Y_D_PRESENTATION_READONLY));
309 }
310
311 if ( sFileName.getLength() )
312 {
313 sName = sFileName + sReadOnly + OUString(RTL_CONSTASCII_USTRINGPARAM(" - ")) + sName;
314 }
315 }
316 }
317
318 return sName;
319 }
320 //===== XEventListener ======================================================
321
322 void SAL_CALL
disposing(const lang::EventObject & rEventObject)323 AccessibleDrawDocumentView::disposing (const lang::EventObject& rEventObject)
324 throw (::com::sun::star::uno::RuntimeException)
325 {
326 ThrowIfDisposed ();
327
328 AccessibleDocumentViewBase::disposing (rEventObject);
329 if (rEventObject.Source == mxModel)
330 {
331 ::osl::Guard< ::osl::Mutex> aGuard (::osl::Mutex::getGlobalMutex());
332 // maShapeTreeInfo has been modified in base class.
333 if (mpChildrenManager != NULL)
334 mpChildrenManager->SetInfo (maShapeTreeInfo);
335 }
336 }
337
338
339
340
341 //===== XPropertyChangeListener =============================================
342
343 void SAL_CALL
propertyChange(const beans::PropertyChangeEvent & rEventObject)344 AccessibleDrawDocumentView::propertyChange (const beans::PropertyChangeEvent& rEventObject)
345 throw (::com::sun::star::uno::RuntimeException)
346 {
347 ThrowIfDisposed ();
348
349 AccessibleDocumentViewBase::propertyChange (rEventObject);
350
351 OSL_TRACE ("AccessibleDrawDocumentView::propertyChange");
352 // add page switch event for slide show mode
353 if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("CurrentPage")) ||
354 rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("PageChange")) )
355 {
356 OSL_TRACE (" current page changed");
357
358 // Update the accessible name to reflect the current slide.
359 UpdateAccessibleName();
360
361 // The current page changed. Update the children manager accordingly.
362 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
363 if (xView.is() && mpChildrenManager!=NULL)
364 {
365 // Inform the children manager to forget all children and give
366 // him the new ones.
367 mpChildrenManager->ClearAccessibleShapeList ();
368 mpChildrenManager->SetShapeList (uno::Reference<drawing::XShapes> (
369 xView->getCurrentPage(), uno::UNO_QUERY));
370
371 // Create the page shape and initialize it. The shape is
372 // acquired before initialization and released after
373 // transferring ownership to the children manager to prevent
374 // premature disposing of the shape.
375 AccessiblePageShape* pPage = CreateDrawPageShape ();
376 if (pPage != NULL)
377 {
378 pPage->acquire();
379 pPage->Init();
380 mpChildrenManager->AddAccessibleShape (
381 std::auto_ptr<AccessibleShape>(pPage));
382 mpChildrenManager->Update (false);
383 pPage->release();
384 }
385 }
386 else
387 OSL_TRACE ("View invalid");
388 CommitChange(AccessibleEventId::PAGE_CHANGED,rEventObject.NewValue,rEventObject.OldValue);
389 }
390 else if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("VisibleArea")))
391 {
392 OSL_TRACE (" visible area changed");
393 if (mpChildrenManager != NULL)
394 mpChildrenManager->ViewForwarderChanged (
395 IAccessibleViewForwarderListener::VISIBLE_AREA,
396 &maViewForwarder);
397 }
398 else if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("ActiveLayer")))
399 {
400 CommitChange(AccessibleEventId::PAGE_CHANGED,rEventObject.NewValue,rEventObject.OldValue);
401 }
402 else if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("UpdateAcc")))
403 {
404 OSL_TRACE (" acc on current page should be updated");
405
406 // The current page changed. Update the children manager accordingly.
407 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
408 if (xView.is() && mpChildrenManager!=NULL)
409 {
410 // Inform the children manager to forget all children and give
411 // him the new ones.
412 mpChildrenManager->ClearAccessibleShapeList ();
413 // update the slide show page's accessible info
414 //mpChildrenManager->SetShapeList (uno::Reference<drawing::XShapes> (
415 // xView->getCurrentPage(), uno::UNO_QUERY));
416 rtl::Reference< sd::SlideShow > xSlideshow( sd::SlideShow::GetSlideShow( mpSdViewSh->GetViewShellBase() ) );
417 if( xSlideshow.is() && xSlideshow->isRunning() && xSlideshow->isFullScreen() )
418 {
419 ::com::sun::star::uno::Reference< drawing::XDrawPage > xSlide;
420 // MT IA2: Not used...
421 // sal_Int32 currentPageIndex = xSlideshow->getCurrentPageIndex();
422 ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XSlideShowController > mpSlideController = xSlideshow->getController();
423 if( mpSlideController.is() )
424 {
425 xSlide = mpSlideController->getCurrentSlide();
426 if (xSlide.is())
427 {
428 mpChildrenManager->SetShapeList (uno::Reference<drawing::XShapes> (
429 xSlide, uno::UNO_QUERY));
430 }
431 }
432 }
433 // Create the page shape and initialize it. The shape is
434 // acquired before initialization and released after
435 // transferring ownership to the children manager to prevent
436 // premature disposing of the shape.
437 AccessiblePageShape* pPage = CreateDrawPageShape ();
438 if (pPage != NULL)
439 {
440 pPage->acquire();
441 pPage->Init();
442 mpChildrenManager->AddAccessibleShape (
443 std::auto_ptr<AccessibleShape>(pPage));
444 mpChildrenManager->Update (false);
445 pPage->release();
446 }
447 }
448 }
449 else
450 {
451 OSL_TRACE (" unhandled");
452 }
453 OSL_TRACE (" done");
454 }
455
456
457
458 //===== XServiceInfo ========================================================
459
460 ::rtl::OUString SAL_CALL
getImplementationName(void)461 AccessibleDrawDocumentView::getImplementationName (void)
462 throw (::com::sun::star::uno::RuntimeException)
463 {
464 return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
465 "AccessibleDrawDocumentView"));
466 }
467
468
469
470
471 ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
getSupportedServiceNames(void)472 AccessibleDrawDocumentView::getSupportedServiceNames (void)
473 throw (::com::sun::star::uno::RuntimeException)
474 {
475 ThrowIfDisposed();
476 // Get list of supported service names from base class...
477 uno::Sequence<OUString> aServiceNames =
478 AccessibleDocumentViewBase::getSupportedServiceNames();
479 sal_Int32 nCount (aServiceNames.getLength());
480
481 // ...and add additional names.
482 aServiceNames.realloc (nCount + 1);
483 static const OUString sAdditionalServiceName (RTL_CONSTASCII_USTRINGPARAM(
484 "com.sun.star.drawing.AccessibleDrawDocumentView"));
485 aServiceNames[nCount] = sAdditionalServiceName;
486
487 return aServiceNames;
488 }
489
490 //===== XInterface ==========================================================
491
492 uno::Any SAL_CALL
queryInterface(const uno::Type & rType)493 AccessibleDrawDocumentView::queryInterface (const uno::Type & rType)
494 throw (uno::RuntimeException)
495 {
496 uno::Any aReturn = AccessibleDocumentViewBase::queryInterface (rType);
497 if ( ! aReturn.hasValue())
498 aReturn = ::cppu::queryInterface (rType,
499 static_cast<XAccessibleGroupPosition*>(this)
500 );
501 return aReturn;
502 }
503
504 void SAL_CALL
acquire(void)505 AccessibleDrawDocumentView::acquire (void)
506 throw ()
507 {
508 AccessibleDocumentViewBase::acquire ();
509 }
510 void SAL_CALL
release(void)511 AccessibleDrawDocumentView::release (void)
512 throw ()
513 {
514 AccessibleDocumentViewBase::release ();
515 }
516 //===== XAccessibleGroupPosition =========================================
517 uno::Sequence< sal_Int32 > SAL_CALL
getGroupPosition(const uno::Any & rAny)518 AccessibleDrawDocumentView::getGroupPosition( const uno::Any& rAny )
519 throw (uno::RuntimeException)
520 {
521 // we will return the:
522 // [0] group level(always be 0 now)
523 // [1] similar items counts in the group
524 // [2] the position of the object in the group
525 uno::Sequence< sal_Int32 > aRet( 3 );
526 //get the xShape of the current selected drawing object
527 uno::Reference<XAccessibleContext> xAccContent;
528 rAny >>= xAccContent;
529 if ( !xAccContent.is() )
530 {
531 return aRet;
532 }
533 AccessibleShape* pAcc = AccessibleShape::getImplementation( xAccContent );
534 if ( !pAcc )
535 {
536 return aRet;
537 }
538 uno::Reference< drawing::XShape > xCurShape = pAcc->GetXShape();
539 if ( !xCurShape.is() )
540 {
541 return aRet;
542 }
543 //find all the child in the page, insert them into a vector and sort
544 if ( mpChildrenManager == NULL )
545 {
546 return aRet;
547 }
548 std::vector< uno::Reference<drawing::XShape> > vXShapes;
549 sal_Int32 nCount = mpChildrenManager->GetChildCount();
550 //get pointer of SdView & SdrPageView for further use.
551 SdrPageView* pPV = NULL;
552 ::sd::View* pSdView = NULL;
553 if ( mpSdViewSh )
554 {
555 pSdView = mpSdViewSh->GetView();
556 pPV = pSdView->GetSdrPageView();
557 }
558 for ( sal_Int32 i = 0; i < nCount; i++ )
559 {
560 uno::Reference< drawing::XShape > xShape = mpChildrenManager->GetChildShape(i);
561 if ( xShape.is() )
562 {
563 //if the object is visible in the page, we add it into the group list.
564 SdrObject* pObj = GetSdrObjectFromXShape(xShape);
565 if ( pObj && pPV && pSdView && pSdView->IsObjMarkable( pObj, pPV ) )
566 {
567 vXShapes.push_back( xShape );
568 }
569 }
570 }
571 std::sort( vXShapes.begin(), vXShapes.end(), XShapePosCompareHelper() );
572 //get the index of the selected object in the group
573 std::vector< uno::Reference<drawing::XShape> >::iterator aIter;
574 //we start counting position from 1
575 sal_Int32 nPos = 1;
576 for ( aIter = vXShapes.begin(); aIter != vXShapes.end(); aIter++, nPos++ )
577 {
578 if ( (*aIter).get() == xCurShape.get() )
579 {
580 sal_Int32* pArray = aRet.getArray();
581 pArray[0] = 1; //it should be 1 based, not 0 based.
582 pArray[1] = vXShapes.size();
583 pArray[2] = nPos;
584 break;
585 }
586 }
587 return aRet;
588 }
getObjectLink(const uno::Any & rAny)589 ::rtl::OUString AccessibleDrawDocumentView::getObjectLink( const uno::Any& rAny )
590 throw (uno::RuntimeException)
591 {
592 ::rtl::OUString aRet;
593 //get the xShape of the current selected drawing object
594 uno::Reference<XAccessibleContext> xAccContent;
595 rAny >>= xAccContent;
596 if ( !xAccContent.is() )
597 {
598 return aRet;
599 }
600 AccessibleShape* pAcc = AccessibleShape::getImplementation( xAccContent );
601 if ( !pAcc )
602 {
603 return aRet;
604 }
605 uno::Reference< drawing::XShape > xCurShape = pAcc->GetXShape();
606 if ( !xCurShape.is() )
607 {
608 return aRet;
609 }
610 SdrObject* pObj = GetSdrObjectFromXShape(xCurShape);
611 if (pObj)
612 {
613 SdAnimationInfo* pInfo = SdDrawDocument::GetShapeUserData(*pObj);
614 if( pInfo && (pInfo->meClickAction == presentation::ClickAction_DOCUMENT) )
615 aRet = (::rtl::OUString)pInfo->GetBookmark();
616 }
617 return aRet;
618 }
619 /// Create a name for this view.
620 ::rtl::OUString
CreateAccessibleName(void)621 AccessibleDrawDocumentView::CreateAccessibleName (void)
622 throw (::com::sun::star::uno::RuntimeException)
623 {
624 rtl::OUString sName;
625
626 uno::Reference<lang::XServiceInfo> xInfo (mxController, uno::UNO_QUERY);
627 if (xInfo.is())
628 {
629 uno::Sequence< ::rtl::OUString > aServices( xInfo->getSupportedServiceNames() );
630 OUString sFirstService = aServices[0];
631 if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocumentDrawView")))
632 {
633 if( aServices.getLength() >= 2 &&
634 aServices[1] == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationView")))
635 {
636 ::vos::OGuard aGuard( Application::GetSolarMutex() );
637
638 sName = String( SdResId(SID_SD_A11Y_I_DRAWVIEW_N) );
639 }
640 else
641 {
642 ::vos::OGuard aGuard( Application::GetSolarMutex() );
643
644 sName = String( SdResId(SID_SD_A11Y_D_DRAWVIEW_N) );
645 }
646 }
647 else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.NotesView")))
648 {
649 ::vos::OGuard aGuard( Application::GetSolarMutex() );
650
651 sName = String( SdResId(SID_SD_A11Y_I_NOTESVIEW_N) );
652 }
653 else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.HandoutView")))
654 {
655 ::vos::OGuard aGuard( Application::GetSolarMutex() );
656
657 sName = String( SdResId(SID_SD_A11Y_I_HANDOUTVIEW_N) );
658 }
659 else
660 {
661 sName = sFirstService;
662 }
663 }
664 else
665 {
666 sName = OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleDrawDocumentView"));
667 }
668 return sName;
669 }
670
671
672
673
674 /** Create a description for this view. Use the model's description or URL
675 if a description is not available.
676 */
677 ::rtl::OUString
CreateAccessibleDescription(void)678 AccessibleDrawDocumentView::CreateAccessibleDescription (void)
679 throw (::com::sun::star::uno::RuntimeException)
680 {
681 rtl::OUString sDescription;
682
683 uno::Reference<lang::XServiceInfo> xInfo (mxController, uno::UNO_QUERY);
684 if (xInfo.is())
685 {
686 uno::Sequence< ::rtl::OUString > aServices( xInfo->getSupportedServiceNames() );
687 OUString sFirstService = aServices[0];
688 if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocumentDrawView")))
689 {
690 if( aServices.getLength() >= 2 &&
691 aServices[1] == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationView")))
692 {
693 ::vos::OGuard aGuard( Application::GetSolarMutex() );
694
695 sDescription = String( SdResId(SID_SD_A11Y_I_DRAWVIEW_D) );
696 }
697 else
698 {
699 ::vos::OGuard aGuard( Application::GetSolarMutex() );
700
701 sDescription = String( SdResId(SID_SD_A11Y_D_DRAWVIEW_D) );
702 }
703 }
704 else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.NotesView")))
705 {
706 ::vos::OGuard aGuard( Application::GetSolarMutex() );
707
708 sDescription = String( SdResId(SID_SD_A11Y_I_NOTESVIEW_D) );
709 }
710 else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.HandoutView")))
711 {
712 ::vos::OGuard aGuard( Application::GetSolarMutex() );
713
714 sDescription = String( SdResId(SID_SD_A11Y_I_HANDOUTVIEW_D) );
715 }
716 else
717 {
718 sDescription = sFirstService;
719 }
720 }
721 else
722 {
723 sDescription = OUString(RTL_CONSTASCII_USTRINGPARAM("Accessible Draw Document"));
724 }
725 return sDescription;
726 }
727
728
729
730
731 /** Return selection state of specified child
732 */
733 sal_Bool
implIsSelected(sal_Int32 nAccessibleChildIndex)734 AccessibleDrawDocumentView::implIsSelected( sal_Int32 nAccessibleChildIndex )
735 throw (uno::RuntimeException)
736 {
737 const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
738 uno::Reference< view::XSelectionSupplier > xSel( mxController, uno::UNO_QUERY );
739 sal_Bool bRet = sal_False;
740
741 OSL_ENSURE( 0 <= nAccessibleChildIndex, "AccessibleDrawDocumentView::implIsSelected: invalid index!" );
742
743 if( xSel.is() && ( 0 <= nAccessibleChildIndex ) )
744 {
745 uno::Any aAny( xSel->getSelection() );
746 uno::Reference< drawing::XShapes > xShapes;
747
748 aAny >>= xShapes;
749
750 if( xShapes.is() )
751 {
752 AccessibleShape* pAcc = AccessibleShape::getImplementation( getAccessibleChild( nAccessibleChildIndex ) );
753
754 if( pAcc )
755 {
756 uno::Reference< drawing::XShape > xShape( pAcc->GetXShape() );
757
758 if( xShape.is() )
759 {
760 for( sal_Int32 i = 0, nCount = xShapes->getCount(); ( i < nCount ) && !bRet; ++i )
761 if( xShapes->getByIndex( i ) == xShape )
762 bRet = sal_True;
763 }
764 }
765 }
766 }
767
768 return( bRet );
769 }
770
771
772
773
774 /** Select or delselect the specified shapes. The corresponding accessible
775 shapes are notified over the selection change listeners registered with
776 the XSelectionSupplier of the controller.
777 */
778 void
implSelect(sal_Int32 nAccessibleChildIndex,sal_Bool bSelect)779 AccessibleDrawDocumentView::implSelect( sal_Int32 nAccessibleChildIndex, sal_Bool bSelect )
780 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
781 {
782 const vos::OGuard aSolarGuard( Application::GetSolarMutex() );
783 uno::Reference< view::XSelectionSupplier > xSel( mxController, uno::UNO_QUERY );
784 AccessibleShape* pAccessibleChild;
785
786 if( xSel.is() )
787 {
788 uno::Any aAny;
789
790 if( ACCESSIBLE_SELECTION_CHILD_ALL == nAccessibleChildIndex )
791 {
792 // Select or deselect all children.
793
794 if( !bSelect )
795 xSel->select( aAny );
796 else
797 {
798 uno::Reference< drawing::XShapes > xShapes( new SvxShapeCollection() );
799
800 for(sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
801 {
802 AccessibleShape* pAcc = AccessibleShape::getImplementation( getAccessibleChild( i ) );
803
804 if( pAcc && pAcc->GetXShape().is() )
805 {
806 xShapes->add( pAcc->GetXShape() );
807 pAccessibleChild = pAcc;
808 }
809 }
810
811 if( xShapes->getCount() )
812 {
813 aAny <<= xShapes;
814 xSel->select( aAny );
815 }
816 }
817 }
818 else if( nAccessibleChildIndex >= 0 )
819 {
820 // Select or deselect only the child with index
821 // nAccessibleChildIndex.
822
823 AccessibleShape* pAcc = AccessibleShape::getImplementation(
824 getAccessibleChild( nAccessibleChildIndex ));
825 pAccessibleChild = pAcc;
826
827 // Add or remove the shape that is made accessible from the
828 // selection of the controller.
829 if( pAcc )
830 {
831 uno::Reference< drawing::XShape > xShape( pAcc->GetXShape() );
832
833 if( xShape.is() )
834 {
835 uno::Reference< drawing::XShapes > xShapes;
836 sal_Bool bFound = sal_False;
837
838 aAny = xSel->getSelection();
839 aAny >>= xShapes;
840
841 // Search shape to be selected in current selection.
842 if (xShapes.is())
843 {
844 sal_Int32 nCount = xShapes->getCount();
845 for (sal_Int32 i=0; ( i < nCount ) && !bFound; ++i )
846 if( xShapes->getByIndex( i ) == xShape )
847 bFound = sal_True;
848 }
849 else
850 // Create an empty selection to add the shape to.
851 xShapes = new SvxShapeCollection();
852
853 // Update the selection.
854 if( !bFound && bSelect )
855 xShapes->add( xShape );
856 else if( bFound && !bSelect )
857 xShapes->remove( xShape );
858
859 aAny <<= xShapes;
860 xSel->select( aAny );
861 }
862 }
863 }
864 }
865 }
866
867
868
869
Activated(void)870 void AccessibleDrawDocumentView::Activated (void)
871 {
872 if (mpChildrenManager != NULL)
873 {
874 sal_Bool bChange = sal_False;
875 // When none of the children has the focus then claim it for the
876 // view.
877 if ( ! mpChildrenManager->HasFocus())
878 {
879 SetState (AccessibleStateType::FOCUSED);
880 bChange = sal_True;
881 }
882 else
883 ResetState (AccessibleStateType::FOCUSED);
884 mpChildrenManager->UpdateSelection();
885 // if the child gets focus in UpdateSelection(), needs to reset the focus on document.
886 if (mpChildrenManager->HasFocus() && bChange)
887 ResetState (AccessibleStateType::FOCUSED);
888 }
889 }
890
891
892
893
Deactivated(void)894 void AccessibleDrawDocumentView::Deactivated (void)
895 {
896 if (mpChildrenManager != NULL)
897 mpChildrenManager->RemoveFocus();
898 ResetState (AccessibleStateType::FOCUSED);
899 }
900
901
902
903
impl_dispose(void)904 void AccessibleDrawDocumentView::impl_dispose (void)
905 {
906 if (mpChildrenManager != NULL)
907 {
908 delete mpChildrenManager;
909 mpChildrenManager = NULL;
910 }
911
912 AccessibleDocumentViewBase::impl_dispose();
913 }
914
915
916
917 /** This method is called from the component helper base class while
918 disposing.
919 */
disposing(void)920 void SAL_CALL AccessibleDrawDocumentView::disposing (void)
921 {
922
923 // Release resources.
924 if (mpChildrenManager != NULL)
925 {
926 delete mpChildrenManager;
927 mpChildrenManager = NULL;
928 }
929
930 // Forward call to base classes.
931 AccessibleDocumentViewBase::disposing ();
932 }
933
934 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
get_AccFlowTo(const::com::sun::star::uno::Any & rAny,sal_Int32 nType)935 SAL_CALL AccessibleDrawDocumentView::get_AccFlowTo(const ::com::sun::star::uno::Any& rAny, sal_Int32 nType)
936 throw ( ::com::sun::star::uno::RuntimeException )
937 {
938 const sal_Int32 SPELLCHECKFLOWTO = 1;
939 const sal_Int32 FINDREPLACEFLOWTO = 2;
940 if ( nType == SPELLCHECKFLOWTO )
941 {
942 uno::Reference< ::com::sun::star::drawing::XShape > xShape;
943 rAny >>= xShape;
944 if ( mpChildrenManager && xShape.is() )
945 {
946 uno::Reference < XAccessible > xAcc = mpChildrenManager->GetChild(xShape);
947 uno::Reference < XAccessibleSelection > xAccSelection( xAcc, uno::UNO_QUERY );
948 if ( xAccSelection.is() )
949 {
950 if ( xAccSelection->getSelectedAccessibleChildCount() )
951 {
952 uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 );
953 if ( xSel.is() )
954 {
955 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() );
956 if ( xSelContext.is() )
957 {
958 //if in sw we find the selected paragraph here
959 if ( xSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
960 {
961 uno::Sequence<uno::Any> aRet( 1 );
962 aRet[0] = uno::makeAny( xSel );
963 return aRet;
964 }
965 }
966 }
967 }
968 }
969 uno::Reference<XAccessible> xPara = GetSelAccContextInTable();
970 if ( xPara.is() )
971 {
972 uno::Sequence<uno::Any> aRet( 1 );
973 aRet[0] = uno::makeAny( xPara );
974 return aRet;
975 }
976 }
977 else
978 {
979 goto Rt;
980 }
981 }
982 else if ( nType == FINDREPLACEFLOWTO )
983 {
984 sal_Int32 nChildCount = getSelectedAccessibleChildCount();
985 if ( nChildCount )
986 {
987 uno::Reference < XAccessible > xSel = getSelectedAccessibleChild( 0 );
988 if ( xSel.is() )
989 {
990 uno::Reference < XAccessibleSelection > xAccChildSelection( xSel, uno::UNO_QUERY );
991 if ( xAccChildSelection.is() )
992 {
993 if ( xAccChildSelection->getSelectedAccessibleChildCount() )
994 {
995 uno::Reference < XAccessible > xChildSel = xAccChildSelection->getSelectedAccessibleChild( 0 );
996 if ( xChildSel.is() )
997 {
998 uno::Reference < XAccessibleContext > xChildSelContext( xChildSel->getAccessibleContext() );
999 if ( xChildSelContext.is() &&
1000 xChildSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
1001 {
1002 uno::Sequence<uno::Any> aRet( 1 );
1003 aRet[0] = uno::makeAny( xChildSel );
1004 return aRet;
1005 }
1006 }
1007 }
1008 }
1009 }
1010 }
1011 else
1012 {
1013 uno::Reference<XAccessible> xPara = GetSelAccContextInTable();
1014 if ( xPara.is() )
1015 {
1016 uno::Sequence<uno::Any> aRet( 1 );
1017 aRet[0] = uno::makeAny( xPara );
1018 return aRet;
1019 }
1020 }
1021 }
1022
1023 Rt:
1024 ::com::sun::star::uno::Sequence< uno::Any> aRet;
1025 return aRet;
1026 }
GetSelAccContextInTable()1027 uno::Reference<XAccessible> AccessibleDrawDocumentView::GetSelAccContextInTable()
1028 {
1029 uno::Reference<XAccessible> xRet;
1030 sal_Int32 nCount = mpChildrenManager ? mpChildrenManager->GetChildCount() : 0;
1031 if ( nCount )
1032 {
1033 for ( sal_Int32 i = 0; i < nCount; i++ )
1034 {
1035 try
1036 {
1037 uno::Reference<XAccessible> xObj = mpChildrenManager->GetChild(i);
1038 if ( xObj.is() )
1039 {
1040 uno::Reference<XAccessibleContext> xObjContext( xObj, uno::UNO_QUERY );
1041 if ( xObjContext.is() && xObjContext->getAccessibleRole() == AccessibleRole::TABLE )
1042 {
1043 uno::Reference<XAccessibleSelection> xObjSelection( xObj, uno::UNO_QUERY );
1044 if ( xObjSelection.is() && xObjSelection->getSelectedAccessibleChildCount() )
1045 {
1046 uno::Reference<XAccessible> xCell = xObjSelection->getSelectedAccessibleChild(0);
1047 if ( xCell.is() )
1048 {
1049 uno::Reference<XAccessibleSelection> xCellSel( xCell, uno::UNO_QUERY );
1050 if ( xCellSel.is() && xCellSel->getSelectedAccessibleChildCount() )
1051 {
1052 uno::Reference<XAccessible> xPara = xCellSel->getSelectedAccessibleChild( 0 );
1053 if ( xPara.is() )
1054 {
1055 uno::Reference<XAccessibleContext> xParaContext( xPara, uno::UNO_QUERY );
1056 if ( xParaContext.is() &&
1057 xParaContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
1058 {
1059 xRet = xPara;
1060 return xRet;
1061 }
1062 }
1063 }
1064 }
1065 }
1066 }
1067 }
1068 }
1069 catch ( lang::IndexOutOfBoundsException )
1070 {
1071 uno::Reference<XAccessible> xEmpty;
1072 return xEmpty;
1073 }
1074 catch ( uno::RuntimeException )
1075 {
1076 uno::Reference<XAccessible> xEmpty;
1077 return xEmpty;
1078 }
1079 }
1080 }
1081
1082 return xRet;
1083 }
1084
UpdateAccessibleName(void)1085 void AccessibleDrawDocumentView::UpdateAccessibleName (void)
1086 {
1087 OUString sNewName (CreateAccessibleName());
1088 sNewName += A2S(": ");
1089
1090 // Add the number of the current slide.
1091 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
1092 if (xView.is())
1093 {
1094 uno::Reference<beans::XPropertySet> xProperties (xView->getCurrentPage(), UNO_QUERY);
1095 if (xProperties.is())
1096 try
1097 {
1098 sal_Int16 nPageNumber (0);
1099 if (xProperties->getPropertyValue(A2S("Number")) >>= nPageNumber)
1100 {
1101 sNewName += OUString::valueOf(sal_Int32(nPageNumber));
1102 }
1103 }
1104 catch (beans::UnknownPropertyException&)
1105 {
1106 }
1107 }
1108
1109 // Add the number of pages/slides.
1110 Reference<drawing::XDrawPagesSupplier> xPagesSupplier (mxModel, UNO_QUERY);
1111 if (xPagesSupplier.is())
1112 {
1113 Reference<container::XIndexAccess> xPages (xPagesSupplier->getDrawPages(), UNO_QUERY);
1114 if (xPages.is())
1115 {
1116 sNewName += A2S(" / ");
1117 sNewName += OUString::valueOf(xPages->getCount());
1118 }
1119 }
1120
1121 SetAccessibleName (sNewName, AutomaticallyCreated);
1122 }
1123
1124
1125
1126
1127 } // end of namespace accessibility
1128