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