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