bump product version to 5.0.4.1
[LibreOffice.git] / sd / source / ui / accessibility / AccessibleDrawDocumentView.cxx
blob2e85582e3de5074314d1e737d23a002f11b24403
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
38 #include <svx/AccessibleShape.hxx>
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>
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"
56 #include "accessibility.hrc"
57 #include "sdresid.hxx"
58 #include <osl/mutex.hxx>
60 using namespace ::com::sun::star;
61 using namespace ::com::sun::star::uno;
62 using namespace ::com::sun::star::accessibility;
64 namespace accessibility {
66 struct XShapePosCompareHelper
68 bool operator() ( const uno::Reference<drawing::XShape>& xshape1,
69 const uno::Reference<drawing::XShape>& xshape2 ) const
71 // modify the compare method to return the Z-Order, not layout order
72 SdrObject* pObj1 = GetSdrObjectFromXShape(xshape1);
73 SdrObject* pObj2 = GetSdrObjectFromXShape(xshape2);
74 if(pObj1 && pObj2)
75 return pObj1->GetOrdNum() < pObj2->GetOrdNum();
76 else
77 return false;
80 //===== internal ============================================================
82 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 mpChildrenManager (NULL)
91 OSL_TRACE ("AccessibleDrawDocumentView");
92 UpdateAccessibleName();
95 AccessibleDrawDocumentView::~AccessibleDrawDocumentView()
97 OSL_TRACE ("~AccessibleDrawDocumentView");
98 DBG_ASSERT (rBHelper.bDisposed || rBHelper.bInDispose,
99 "~AccessibleDrawDocumentView: object has not been disposed");
102 void AccessibleDrawDocumentView::Init()
104 AccessibleDocumentViewBase::Init ();
106 // Determine the list of shapes on the current page.
107 uno::Reference<drawing::XShapes> xShapeList;
108 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
109 if (xView.is())
110 xShapeList = uno::Reference<drawing::XShapes> (
111 xView->getCurrentPage(), uno::UNO_QUERY);
113 // Create the children manager.
114 mpChildrenManager = new ChildrenManager(this, xShapeList, maShapeTreeInfo, *this);
116 rtl::Reference<AccessiblePageShape> xPage(CreateDrawPageShape());
117 if (xPage.is())
119 xPage->Init();
120 mpChildrenManager->AddAccessibleShape (xPage.get());
121 mpChildrenManager->Update ();
124 mpChildrenManager->UpdateSelection ();
127 void AccessibleDrawDocumentView::ViewForwarderChanged (ChangeType aChangeType,
128 const IAccessibleViewForwarder* pViewForwarder)
130 AccessibleDocumentViewBase::ViewForwarderChanged (aChangeType, pViewForwarder);
131 if (mpChildrenManager != NULL)
132 mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder);
135 /** The page shape is created on every call at the moment (provided that
136 every thing goes well).
138 rtl::Reference<AccessiblePageShape> AccessibleDrawDocumentView::CreateDrawPageShape()
140 rtl::Reference<AccessiblePageShape> xShape;
142 // Create a shape that represents the actual draw page.
143 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
144 if (xView.is())
146 uno::Reference<beans::XPropertySet> xSet (
147 uno::Reference<beans::XPropertySet> (xView->getCurrentPage(), uno::UNO_QUERY));
148 if (xSet.is())
150 // Create a rectangle shape that will represent the draw page.
151 uno::Reference<lang::XMultiServiceFactory> xFactory (mxModel, uno::UNO_QUERY);
152 uno::Reference<drawing::XShape> xRectangle;
153 if (xFactory.is())
154 xRectangle = uno::Reference<drawing::XShape>(xFactory->createInstance ("com.sun.star.drawing.RectangleShape"),
155 uno::UNO_QUERY);
157 // Set the shape's size and position.
158 if (xRectangle.is())
160 uno::Any aValue;
161 awt::Point aPosition;
162 awt::Size aSize;
164 // Set size and position of the shape to those of the draw
165 // page.
166 aValue = xSet->getPropertyValue ("BorderLeft");
167 aValue >>= aPosition.X;
168 aValue = xSet->getPropertyValue ("BorderTop");
169 aValue >>= aPosition.Y;
170 xRectangle->setPosition (aPosition);
172 aValue = xSet->getPropertyValue ("Width");
173 aValue >>= aSize.Width;
174 aValue = xSet->getPropertyValue ("Height");
175 aValue >>= aSize.Height;
176 xRectangle->setSize (aSize);
178 // Create the accessible object for the shape and
179 // initialize it.
180 xShape = new AccessiblePageShape (
181 xView->getCurrentPage(), this, maShapeTreeInfo);
185 return xShape;
188 //===== XAccessibleContext ==================================================
190 sal_Int32 SAL_CALL
191 AccessibleDrawDocumentView::getAccessibleChildCount()
192 throw (uno::RuntimeException, std::exception)
194 ThrowIfDisposed ();
196 long mpChildCount = AccessibleDocumentViewBase::getAccessibleChildCount();
198 // Forward request to children manager.
199 if (mpChildrenManager != NULL)
200 mpChildCount += mpChildrenManager->GetChildCount ();
202 return mpChildCount;
205 uno::Reference<XAccessible> SAL_CALL
206 AccessibleDrawDocumentView::getAccessibleChild (sal_Int32 nIndex)
207 throw (uno::RuntimeException, lang::IndexOutOfBoundsException, std::exception)
209 ThrowIfDisposed ();
211 ::osl::ClearableMutexGuard aGuard (maMutex);
213 // Take care of children of the base class.
214 sal_Int32 nCount = AccessibleDocumentViewBase::getAccessibleChildCount();
215 if (nCount > 0)
217 if (nIndex < nCount)
218 return AccessibleDocumentViewBase::getAccessibleChild(nIndex);
219 else
220 nIndex -= nCount;
223 // Create a copy of the pointer to the children manager and release the
224 // mutex before calling any of its methods.
225 ChildrenManager* pChildrenManager = mpChildrenManager;
226 aGuard.clear();
228 // Forward request to children manager.
229 if (pChildrenManager != NULL)
231 return pChildrenManager->GetChild (nIndex);
233 else
234 throw lang::IndexOutOfBoundsException (
235 "no accessible child with index " + OUString::number(nIndex),
236 static_cast<uno::XWeak*>(this));
239 OUString SAL_CALL
240 AccessibleDrawDocumentView::getAccessibleName()
241 throw (::com::sun::star::uno::RuntimeException, std::exception)
243 SolarMutexGuard g;
245 OUString sName = SdResId(SID_SD_A11Y_D_PRESENTATION);
246 ::sd::View* pSdView = static_cast< ::sd::View* >( maShapeTreeInfo.GetSdrView() );
247 if ( pSdView )
249 SdDrawDocument& rDoc = pSdView->GetDoc();
250 OUString sFileName = rDoc.getDocAccTitle();
251 if ( !sFileName.getLength() )
253 ::sd::DrawDocShell* pDocSh = pSdView->GetDocSh();
254 if ( pDocSh )
256 sFileName = pDocSh->GetTitle( SFX_TITLE_APINAME );
260 OUString sReadOnly;
261 if(rDoc.getDocReadOnly())
263 sReadOnly = SdResId(SID_SD_A11Y_D_PRESENTATION_READONLY);
266 if ( sFileName.getLength() )
268 sName = sFileName + sReadOnly + " - " + sName;
272 return sName;
275 //===== XEventListener ======================================================
277 void SAL_CALL
278 AccessibleDrawDocumentView::disposing (const lang::EventObject& rEventObject)
279 throw (::com::sun::star::uno::RuntimeException, std::exception)
281 ThrowIfDisposed ();
283 AccessibleDocumentViewBase::disposing (rEventObject);
284 if (rEventObject.Source == mxModel)
286 ::osl::Guard< ::osl::Mutex> aGuard (::osl::Mutex::getGlobalMutex());
287 // maShapeTreeInfo has been modified in base class.
288 if (mpChildrenManager != NULL)
289 mpChildrenManager->SetInfo (maShapeTreeInfo);
293 //===== XPropertyChangeListener =============================================
295 void SAL_CALL
296 AccessibleDrawDocumentView::propertyChange (const beans::PropertyChangeEvent& rEventObject)
297 throw (::com::sun::star::uno::RuntimeException, std::exception)
299 ThrowIfDisposed ();
301 AccessibleDocumentViewBase::propertyChange (rEventObject);
303 OSL_TRACE ("AccessibleDrawDocumentView::propertyChange");
304 // add page switch event for slide show mode
305 if (rEventObject.PropertyName == "CurrentPage" ||
306 rEventObject.PropertyName == "PageChange")
308 OSL_TRACE (" current page changed");
310 // Update the accessible name to reflect the current slide.
311 UpdateAccessibleName();
313 // The current page changed. Update the children manager accordingly.
314 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
315 if (xView.is() && mpChildrenManager!=NULL)
317 // Inform the children manager to forget all children and give
318 // him the new ones.
319 mpChildrenManager->ClearAccessibleShapeList ();
320 mpChildrenManager->SetShapeList (uno::Reference<drawing::XShapes> (
321 xView->getCurrentPage(), uno::UNO_QUERY));
323 rtl::Reference<AccessiblePageShape> xPage(CreateDrawPageShape ());
324 if (xPage.is())
326 xPage->Init();
327 mpChildrenManager->AddAccessibleShape (xPage.get());
328 mpChildrenManager->Update (false);
331 else
332 OSL_TRACE ("View invalid");
333 CommitChange(AccessibleEventId::PAGE_CHANGED,rEventObject.NewValue,rEventObject.OldValue);
335 else if ( rEventObject.PropertyName == "VisibleArea" )
337 OSL_TRACE (" visible area changed");
338 if (mpChildrenManager != NULL)
339 mpChildrenManager->ViewForwarderChanged (
340 IAccessibleViewForwarderListener::VISIBLE_AREA,
341 &maViewForwarder);
343 else if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("ActiveLayer")))
345 CommitChange(AccessibleEventId::PAGE_CHANGED,rEventObject.NewValue,rEventObject.OldValue);
347 else if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("UpdateAcc")))
349 OSL_TRACE (" acc on current page should be updated");
351 // The current page changed. Update the children manager accordingly.
352 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
353 if (xView.is() && mpChildrenManager!=NULL)
355 // Inform the children manager to forget all children and give
356 // him the new ones.
357 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 rtl::Reference< sd::SlideShow > xSlideshow( sd::SlideShow::GetSlideShow( mpSdViewSh->GetViewShellBase() ) );
362 if( xSlideshow.is() && xSlideshow->isRunning() && xSlideshow->isFullScreen() )
364 ::com::sun::star::uno::Reference< drawing::XDrawPage > xSlide;
365 // MT IA2: Not used...
366 // sal_Int32 currentPageIndex = xSlideshow->getCurrentPageIndex();
367 ::com::sun::star::uno::Reference< ::com::sun::star::presentation::XSlideShowController > mpSlideController = xSlideshow->getController();
368 if( mpSlideController.is() )
370 xSlide = mpSlideController->getCurrentSlide();
371 if (xSlide.is())
373 mpChildrenManager->SetShapeList (uno::Reference<drawing::XShapes> (
374 xSlide, uno::UNO_QUERY));
378 rtl::Reference<AccessiblePageShape> xPage(CreateDrawPageShape ());
379 if (xPage.is())
381 xPage->Init();
382 mpChildrenManager->AddAccessibleShape (xPage.get());
383 mpChildrenManager->Update (false);
387 else
389 OSL_TRACE (" unhandled");
391 OSL_TRACE (" done");
394 // XServiceInfo
396 OUString SAL_CALL
397 AccessibleDrawDocumentView::getImplementationName()
398 throw (::com::sun::star::uno::RuntimeException, std::exception)
400 return OUString("AccessibleDrawDocumentView");
403 ::com::sun::star::uno::Sequence< OUString> SAL_CALL
404 AccessibleDrawDocumentView::getSupportedServiceNames()
405 throw (::com::sun::star::uno::RuntimeException, std::exception)
407 ThrowIfDisposed();
408 // Get list of supported service names from base class...
409 uno::Sequence<OUString> aServiceNames =
410 AccessibleDocumentViewBase::getSupportedServiceNames();
411 sal_Int32 nCount (aServiceNames.getLength());
413 // ...and add additional names.
414 aServiceNames.realloc (nCount + 1);
415 aServiceNames[nCount] = "com.sun.star.drawing.AccessibleDrawDocumentView";
417 return aServiceNames;
420 //===== XInterface ==========================================================
422 uno::Any SAL_CALL
423 AccessibleDrawDocumentView::queryInterface (const uno::Type & rType)
424 throw (uno::RuntimeException, std::exception)
426 uno::Any aReturn = AccessibleDocumentViewBase::queryInterface (rType);
427 if ( ! aReturn.hasValue())
428 aReturn = ::cppu::queryInterface (rType,
429 static_cast<XAccessibleGroupPosition*>(this)
431 return aReturn;
434 void SAL_CALL
435 AccessibleDrawDocumentView::acquire()
436 throw ()
438 AccessibleDocumentViewBase::acquire ();
440 void SAL_CALL
441 AccessibleDrawDocumentView::release()
442 throw ()
444 AccessibleDocumentViewBase::release ();
446 //===== XAccessibleGroupPosition =========================================
447 uno::Sequence< sal_Int32 > SAL_CALL
448 AccessibleDrawDocumentView::getGroupPosition( const uno::Any& rAny )
449 throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
451 SolarMutexGuard g;
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 uno::Sequence< sal_Int32 > aRet( 3 );
458 //get the xShape of the current selected drawing object
459 uno::Reference<XAccessibleContext> xAccContent;
460 rAny >>= xAccContent;
461 if ( !xAccContent.is() )
463 return aRet;
465 AccessibleShape* pAcc = AccessibleShape::getImplementation( xAccContent );
466 if ( !pAcc )
468 return aRet;
470 uno::Reference< drawing::XShape > xCurShape = pAcc->GetXShape();
471 if ( !xCurShape.is() )
473 return aRet;
475 //find all the child in the page, insert them into a vector and sort
476 if ( mpChildrenManager == NULL )
478 return aRet;
480 std::vector< uno::Reference<drawing::XShape> > vXShapes;
481 sal_Int32 nCount = mpChildrenManager->GetChildCount();
482 //get pointer of SdView & SdrPageView for further use.
483 SdrPageView* pPV = NULL;
484 ::sd::View* pSdView = NULL;
485 if ( mpSdViewSh )
487 pSdView = mpSdViewSh->GetView();
488 pPV = pSdView->GetSdrPageView();
490 for ( sal_Int32 i = 0; i < nCount; i++ )
492 uno::Reference< drawing::XShape > xShape = mpChildrenManager->GetChildShape(i);
493 if ( xShape.is() )
495 //if the object is visible in the page, we add it into the group list.
496 SdrObject* pObj = GetSdrObjectFromXShape(xShape);
497 if ( pObj && pPV && pSdView && pSdView->IsObjMarkable( pObj, pPV ) )
499 vXShapes.push_back( xShape );
503 std::sort( vXShapes.begin(), vXShapes.end(), XShapePosCompareHelper() );
504 //get the index of the selected object in the group
505 std::vector< uno::Reference<drawing::XShape> >::iterator aIter;
506 //we start counting position from 1
507 sal_Int32 nPos = 1;
508 for ( aIter = vXShapes.begin(); aIter != vXShapes.end(); ++aIter, nPos++ )
510 if ( (*aIter).get() == xCurShape.get() )
512 sal_Int32* pArray = aRet.getArray();
513 pArray[0] = 1; //it should be 1 based, not 0 based.
514 pArray[1] = vXShapes.size();
515 pArray[2] = nPos;
516 break;
519 return aRet;
522 OUString AccessibleDrawDocumentView::getObjectLink( const uno::Any& rAny )
523 throw (uno::RuntimeException, std::exception)
525 SolarMutexGuard g;
527 OUString aRet;
528 //get the xShape of the current selected drawing object
529 uno::Reference<XAccessibleContext> xAccContent;
530 rAny >>= xAccContent;
531 if ( !xAccContent.is() )
533 return aRet;
535 AccessibleShape* pAcc = AccessibleShape::getImplementation( xAccContent );
536 if ( !pAcc )
538 return aRet;
540 uno::Reference< drawing::XShape > xCurShape = pAcc->GetXShape();
541 if ( !xCurShape.is() )
543 return aRet;
545 SdrObject* pObj = GetSdrObjectFromXShape(xCurShape);
546 if (pObj)
548 SdAnimationInfo* pInfo = SdDrawDocument::GetShapeUserData(*pObj);
549 if( pInfo && (pInfo->meClickAction == presentation::ClickAction_DOCUMENT) )
550 aRet = pInfo->GetBookmark();
552 return aRet;
555 /// Create a name for this view.
556 OUString AccessibleDrawDocumentView::CreateAccessibleName()
557 throw (::com::sun::star::uno::RuntimeException)
559 OUString sName;
561 uno::Reference<lang::XServiceInfo> xInfo (mxController, uno::UNO_QUERY);
562 if (xInfo.is())
564 uno::Sequence< OUString > aServices( xInfo->getSupportedServiceNames() );
565 OUString sFirstService = aServices[0];
566 if ( sFirstService == "com.sun.star.drawing.DrawingDocumentDrawView" )
568 if( aServices.getLength() >= 2 && aServices[1] == "com.sun.star.presentation.PresentationView")
570 SolarMutexGuard aGuard;
572 sName = SD_RESSTR(SID_SD_A11Y_I_DRAWVIEW_N);
574 else
576 SolarMutexGuard aGuard;
578 sName = SD_RESSTR(SID_SD_A11Y_D_DRAWVIEW_N);
581 else if ( sFirstService == "com.sun.star.presentation.NotesView" )
583 SolarMutexGuard aGuard;
585 sName = SD_RESSTR(SID_SD_A11Y_I_NOTESVIEW_N);
587 else if ( sFirstService == "com.sun.star.presentation.HandoutView" )
589 SolarMutexGuard aGuard;
591 sName = SD_RESSTR(SID_SD_A11Y_I_HANDOUTVIEW_N);
593 else
595 sName = sFirstService;
598 else
600 sName = "AccessibleDrawDocumentView";
602 return sName;
605 /** Create a description for this view. Use the model's description or URL
606 if a description is not available.
608 OUString
609 AccessibleDrawDocumentView::CreateAccessibleDescription()
610 throw (::com::sun::star::uno::RuntimeException)
612 OUString sDescription;
614 uno::Reference<lang::XServiceInfo> xInfo (mxController, uno::UNO_QUERY);
615 if (xInfo.is())
617 uno::Sequence< OUString > aServices( xInfo->getSupportedServiceNames() );
618 OUString sFirstService = aServices[0];
619 if ( sFirstService == "com.sun.star.drawing.DrawingDocumentDrawView" )
621 if( aServices.getLength() >= 2 && aServices[1] == "com.sun.star.presentation.PresentationView")
623 SolarMutexGuard aGuard;
625 sDescription = SD_RESSTR(SID_SD_A11Y_I_DRAWVIEW_D);
627 else
629 SolarMutexGuard aGuard;
631 sDescription = SD_RESSTR(SID_SD_A11Y_D_DRAWVIEW_D);
634 else if ( sFirstService == "com.sun.star.presentation.NotesView" )
636 SolarMutexGuard aGuard;
638 sDescription = SD_RESSTR(SID_SD_A11Y_I_NOTESVIEW_D);
640 else if ( sFirstService == "com.sun.star.presentation.HandoutView" )
642 SolarMutexGuard aGuard;
644 sDescription = SD_RESSTR(SID_SD_A11Y_I_HANDOUTVIEW_D);
646 else
648 sDescription = sFirstService;
651 else
653 sDescription = "Accessible Draw Document";
655 return sDescription;
658 /** Return selection state of specified child
660 bool
661 AccessibleDrawDocumentView::implIsSelected( sal_Int32 nAccessibleChildIndex )
662 throw (uno::RuntimeException)
664 const SolarMutexGuard aSolarGuard;
665 uno::Reference< view::XSelectionSupplier > xSel( mxController, uno::UNO_QUERY );
666 bool bRet = false;
668 OSL_ENSURE( 0 <= nAccessibleChildIndex, "AccessibleDrawDocumentView::implIsSelected: invalid index!" );
670 if( xSel.is() && ( 0 <= nAccessibleChildIndex ) )
672 uno::Any aAny( xSel->getSelection() );
673 uno::Reference< drawing::XShapes > xShapes;
675 aAny >>= xShapes;
677 if( xShapes.is() )
679 AccessibleShape* pAcc = AccessibleShape::getImplementation( getAccessibleChild( nAccessibleChildIndex ) );
681 if( pAcc )
683 uno::Reference< drawing::XShape > xShape( pAcc->GetXShape() );
685 if( xShape.is() )
687 for( sal_Int32 i = 0, nCount = xShapes->getCount(); ( i < nCount ) && !bRet; ++i )
688 if( xShapes->getByIndex( i ) == xShape )
689 bRet = true;
695 return bRet;
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.
702 void
703 AccessibleDrawDocumentView::implSelect( sal_Int32 nAccessibleChildIndex, bool bSelect )
704 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
706 const SolarMutexGuard aSolarGuard;
707 uno::Reference< view::XSelectionSupplier > xSel( mxController, uno::UNO_QUERY );
709 if( xSel.is() )
711 uno::Any aAny;
713 if( ACCESSIBLE_SELECTION_CHILD_ALL == nAccessibleChildIndex )
715 // Select or deselect all children.
717 if( !bSelect )
718 xSel->select( aAny );
719 else
721 uno::Reference< drawing::XShapes > xShapes = drawing::ShapeCollection::create(
722 comphelper::getProcessComponentContext());
724 for(sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
726 AccessibleShape* pAcc = AccessibleShape::getImplementation( getAccessibleChild( i ) );
728 if( pAcc && pAcc->GetXShape().is() )
729 xShapes->add( pAcc->GetXShape() );
732 if( xShapes->getCount() )
734 aAny <<= xShapes;
735 xSel->select( aAny );
739 else if( nAccessibleChildIndex >= 0 )
741 // Select or deselect only the child with index
742 // nAccessibleChildIndex.
744 AccessibleShape* pAcc = AccessibleShape::getImplementation(
745 getAccessibleChild( nAccessibleChildIndex ));
747 // Add or remove the shape that is made accessible from the
748 // selection of the controller.
749 if( pAcc )
751 uno::Reference< drawing::XShape > xShape( pAcc->GetXShape() );
753 if( xShape.is() )
755 uno::Reference< drawing::XShapes > xShapes;
756 bool bFound = false;
758 aAny = xSel->getSelection();
759 aAny >>= xShapes;
761 // Search shape to be selected in current selection.
762 if (xShapes.is())
764 sal_Int32 nCount = xShapes->getCount();
765 for (sal_Int32 i=0; ( i < nCount ) && !bFound; ++i )
766 if( xShapes->getByIndex( i ) == xShape )
767 bFound = true;
769 else
770 // Create an empty selection to add the shape to.
771 xShapes = drawing::ShapeCollection::create(
772 comphelper::getProcessComponentContext());
774 // Update the selection.
775 if( !bFound && bSelect )
776 xShapes->add( xShape );
777 else if( bFound && !bSelect )
778 xShapes->remove( xShape );
780 aAny <<= xShapes;
781 xSel->select( aAny );
788 void AccessibleDrawDocumentView::Activated()
790 if (mpChildrenManager != NULL)
792 bool bChange = false;
793 // When none of the children has the focus then claim it for the
794 // view.
795 if ( ! mpChildrenManager->HasFocus())
797 SetState (AccessibleStateType::FOCUSED);
798 bChange = true;
800 else
801 ResetState (AccessibleStateType::FOCUSED);
802 mpChildrenManager->UpdateSelection();
803 // if the child gets focus in UpdateSelection(), needs to reset the focus on document.
804 if (mpChildrenManager->HasFocus() && bChange)
805 ResetState (AccessibleStateType::FOCUSED);
809 void AccessibleDrawDocumentView::Deactivated()
811 if (mpChildrenManager != NULL)
812 mpChildrenManager->RemoveFocus();
813 ResetState (AccessibleStateType::FOCUSED);
816 void AccessibleDrawDocumentView::impl_dispose()
818 if (mpChildrenManager != NULL)
820 delete mpChildrenManager;
821 mpChildrenManager = NULL;
824 AccessibleDocumentViewBase::impl_dispose();
827 /** This method is called from the component helper base class while
828 disposing.
830 void SAL_CALL AccessibleDrawDocumentView::disposing()
833 // Release resources.
834 if (mpChildrenManager != NULL)
836 delete mpChildrenManager;
837 mpChildrenManager = NULL;
840 // Forward call to base classes.
841 AccessibleDocumentViewBase::disposing ();
844 ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >
845 SAL_CALL AccessibleDrawDocumentView::getAccFlowTo(const ::com::sun::star::uno::Any& rAny, sal_Int32 nType)
846 throw ( ::com::sun::star::uno::RuntimeException, std::exception )
848 SolarMutexGuard g;
850 const sal_Int32 SPELLCHECKFLOWTO = 1;
851 const sal_Int32 FINDREPLACEFLOWTO = 2;
852 if ( nType == SPELLCHECKFLOWTO )
854 uno::Reference< ::com::sun::star::drawing::XShape > xShape;
855 rAny >>= xShape;
856 if ( mpChildrenManager && xShape.is() )
858 uno::Reference < XAccessible > xAcc = mpChildrenManager->GetChild(xShape);
859 uno::Reference < XAccessibleSelection > xAccSelection( xAcc, uno::UNO_QUERY );
860 if ( xAccSelection.is() )
862 if ( xAccSelection->getSelectedAccessibleChildCount() )
864 uno::Reference < XAccessible > xSel = xAccSelection->getSelectedAccessibleChild( 0 );
865 if ( xSel.is() )
867 uno::Reference < XAccessibleContext > xSelContext( xSel->getAccessibleContext() );
868 if ( xSelContext.is() )
870 //if in sw we find the selected paragraph here
871 if ( xSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
873 uno::Sequence<uno::Any> aRet( 1 );
874 aRet[0] = uno::makeAny( xSel );
875 return aRet;
881 uno::Reference<XAccessible> xPara = GetSelAccContextInTable();
882 if ( xPara.is() )
884 uno::Sequence<uno::Any> aRet( 1 );
885 aRet[0] = uno::makeAny( xPara );
886 return aRet;
889 else
891 goto Rt;
894 else if ( nType == FINDREPLACEFLOWTO )
896 sal_Int32 nChildCount = getSelectedAccessibleChildCount();
897 if ( nChildCount )
899 uno::Reference < XAccessible > xSel = getSelectedAccessibleChild( 0 );
900 if ( xSel.is() )
902 uno::Reference < XAccessibleSelection > xAccChildSelection( xSel, uno::UNO_QUERY );
903 if ( xAccChildSelection.is() )
905 if ( xAccChildSelection->getSelectedAccessibleChildCount() )
907 uno::Reference < XAccessible > xChildSel = xAccChildSelection->getSelectedAccessibleChild( 0 );
908 if ( xChildSel.is() )
910 uno::Reference < XAccessibleContext > xChildSelContext( xChildSel->getAccessibleContext() );
911 if ( xChildSelContext.is() &&
912 xChildSelContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
914 uno::Sequence<uno::Any> aRet( 1 );
915 aRet[0] = uno::makeAny( xChildSel );
916 return aRet;
923 else
925 uno::Reference<XAccessible> xPara = GetSelAccContextInTable();
926 if ( xPara.is() )
928 uno::Sequence<uno::Any> aRet( 1 );
929 aRet[0] = uno::makeAny( xPara );
930 return aRet;
936 ::com::sun::star::uno::Sequence< uno::Any> aRet;
937 return aRet;
939 uno::Reference<XAccessible> AccessibleDrawDocumentView::GetSelAccContextInTable()
941 uno::Reference<XAccessible> xRet;
942 sal_Int32 nCount = mpChildrenManager ? mpChildrenManager->GetChildCount() : 0;
943 if ( nCount )
945 for ( sal_Int32 i = 0; i < nCount; i++ )
949 uno::Reference<XAccessible> xObj = mpChildrenManager->GetChild(i);
950 if ( xObj.is() )
952 uno::Reference<XAccessibleContext> xObjContext( xObj, uno::UNO_QUERY );
953 if ( xObjContext.is() && xObjContext->getAccessibleRole() == AccessibleRole::TABLE )
955 uno::Reference<XAccessibleSelection> xObjSelection( xObj, uno::UNO_QUERY );
956 if ( xObjSelection.is() && xObjSelection->getSelectedAccessibleChildCount() )
958 uno::Reference<XAccessible> xCell = xObjSelection->getSelectedAccessibleChild(0);
959 if ( xCell.is() )
961 uno::Reference<XAccessibleSelection> xCellSel( xCell, uno::UNO_QUERY );
962 if ( xCellSel.is() && xCellSel->getSelectedAccessibleChildCount() )
964 uno::Reference<XAccessible> xPara = xCellSel->getSelectedAccessibleChild( 0 );
965 if ( xPara.is() )
967 uno::Reference<XAccessibleContext> xParaContext( xPara, uno::UNO_QUERY );
968 if ( xParaContext.is() &&
969 xParaContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
971 xRet = xPara;
972 return xRet;
981 catch (const lang::IndexOutOfBoundsException&)
983 uno::Reference<XAccessible> xEmpty;
984 return xEmpty;
986 catch (const uno::RuntimeException&)
988 uno::Reference<XAccessible> xEmpty;
989 return xEmpty;
994 return xRet;
997 void AccessibleDrawDocumentView::UpdateAccessibleName()
999 OUString sNewName (CreateAccessibleName());
1000 sNewName += ": ";
1002 // Add the number of the current slide.
1003 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
1004 if (xView.is())
1006 uno::Reference<beans::XPropertySet> xProperties (xView->getCurrentPage(), UNO_QUERY);
1007 if (xProperties.is())
1010 sal_Int16 nPageNumber (0);
1011 if (xProperties->getPropertyValue("Number") >>= nPageNumber)
1013 sNewName += OUString::number(nPageNumber);
1016 catch (const beans::UnknownPropertyException&)
1021 // Add the number of pages/slides.
1022 Reference<drawing::XDrawPagesSupplier> xPagesSupplier (mxModel, UNO_QUERY);
1023 if (xPagesSupplier.is())
1025 Reference<container::XIndexAccess> xPages (xPagesSupplier->getDrawPages(), UNO_QUERY);
1026 if (xPages.is())
1028 sNewName += " / ";
1029 sNewName += OUString::number(xPages->getCount());
1033 SetAccessibleName (sNewName, AutomaticallyCreated);
1036 } // end of namespace accessibility
1038 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */