fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / sd / source / ui / accessibility / AccessibleDrawDocumentView.cxx
blob7d0f2f6a46b55e5f0401cb775f32c84623d6952e
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/XDrawPage.hpp>
22 #include <com/sun/star/drawing/XDrawView.hpp>
23 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
24 #include <com/sun/star/drawing/XShapes.hpp>
25 #include <com/sun/star/container/XChild.hpp>
26 #include <com/sun/star/frame/XController.hpp>
27 #include <com/sun/star/frame/XFrame.hpp>
28 #include <com/sun/star/document/XEventBroadcaster.hpp>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
31 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
32 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 #include <rtl/ustring.h>
34 #include<sfx2/viewfrm.hxx>
36 #include <svx/AccessibleShape.hxx>
38 #include <svx/svdobj.hxx>
39 #include <svx/svdmodel.hxx>
40 #include <svx/unoapi.hxx>
41 #include <svx/unoshcol.hxx>
42 #include <toolkit/helper/vclunohelper.hxx>
43 #include "Window.hxx"
44 #include <vcl/svapp.hxx>
47 #include "ViewShell.hxx"
48 #include "View.hxx"
49 #include <memory>
51 #include "accessibility.hrc"
52 #include "sdresid.hxx"
53 #include <osl/mutex.hxx>
55 using namespace ::com::sun::star;
56 using namespace ::com::sun::star::uno;
57 using namespace ::com::sun::star::accessibility;
59 namespace accessibility {
62 //===== internal ============================================================
64 AccessibleDrawDocumentView::AccessibleDrawDocumentView (
65 ::sd::Window* pSdWindow,
66 ::sd::ViewShell* pViewShell,
67 const uno::Reference<frame::XController>& rxController,
68 const uno::Reference<XAccessible>& rxParent)
69 : AccessibleDocumentViewBase (pSdWindow, pViewShell, rxController, rxParent),
70 mpChildrenManager (NULL)
72 OSL_TRACE ("AccessibleDrawDocumentView");
73 UpdateAccessibleName();
79 AccessibleDrawDocumentView::~AccessibleDrawDocumentView (void)
81 OSL_TRACE ("~AccessibleDrawDocumentView");
82 DBG_ASSERT (rBHelper.bDisposed || rBHelper.bInDispose,
83 "~AccessibleDrawDocumentView: object has not been disposed");
89 void AccessibleDrawDocumentView::Init (void)
91 AccessibleDocumentViewBase::Init ();
93 // Determine the list of shapes on the current page.
94 uno::Reference<drawing::XShapes> xShapeList;
95 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
96 if (xView.is())
97 xShapeList = uno::Reference<drawing::XShapes> (
98 xView->getCurrentPage(), uno::UNO_QUERY);
100 // Create the children manager.
101 mpChildrenManager = new ChildrenManager(this, xShapeList, maShapeTreeInfo, *this);
102 if (mpChildrenManager != NULL)
104 // Create the page shape and initialize it. The shape is acquired
105 // before initialization and released after transferring ownership
106 // to the children manager to prevent premature disposing of the
107 // shape.
108 AccessiblePageShape* pPage = CreateDrawPageShape();
109 if (pPage != NULL)
111 pPage->acquire();
112 pPage->Init();
113 mpChildrenManager->AddAccessibleShape (
114 std::auto_ptr<AccessibleShape>(pPage));
115 pPage->release();
116 mpChildrenManager->Update ();
118 mpChildrenManager->UpdateSelection ();
125 void AccessibleDrawDocumentView::ViewForwarderChanged (ChangeType aChangeType,
126 const IAccessibleViewForwarder* pViewForwarder)
128 AccessibleDocumentViewBase::ViewForwarderChanged (aChangeType, pViewForwarder);
129 if (mpChildrenManager != NULL)
130 mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder);
136 /** The page shape is created on every call at the moment (provided that
137 every thing goes well).
139 AccessiblePageShape* AccessibleDrawDocumentView::CreateDrawPageShape (void)
141 AccessiblePageShape* pShape = NULL;
143 // Create a shape that represents the actual draw page.
144 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
145 if (xView.is())
147 uno::Reference<beans::XPropertySet> xSet (
148 uno::Reference<beans::XPropertySet> (xView->getCurrentPage(), uno::UNO_QUERY));
149 if (xSet.is())
151 // Create a rectangle shape that will represent the draw page.
152 uno::Reference<lang::XMultiServiceFactory> xFactory (mxModel, uno::UNO_QUERY);
153 uno::Reference<drawing::XShape> xRectangle;
154 if (xFactory.is())
155 xRectangle = uno::Reference<drawing::XShape>(xFactory->createInstance ("com.sun.star.drawing.RectangleShape"),
156 uno::UNO_QUERY);
158 // Set the shape's size and position.
159 if (xRectangle.is())
161 uno::Any aValue;
162 awt::Point aPosition;
163 awt::Size aSize;
165 // Set size and position of the shape to those of the draw
166 // page.
167 aValue = xSet->getPropertyValue ("BorderLeft");
168 aValue >>= aPosition.X;
169 aValue = xSet->getPropertyValue ("BorderTop");
170 aValue >>= aPosition.Y;
171 xRectangle->setPosition (aPosition);
173 aValue = xSet->getPropertyValue ("Width");
174 aValue >>= aSize.Width;
175 aValue = xSet->getPropertyValue ("Height");
176 aValue >>= aSize.Height;
177 xRectangle->setSize (aSize);
179 // Create the accessible object for the shape and
180 // initialize it.
181 pShape = new AccessiblePageShape (
182 xView->getCurrentPage(), this, maShapeTreeInfo);
186 return pShape;
192 //===== XAccessibleContext ==================================================
194 sal_Int32 SAL_CALL
195 AccessibleDrawDocumentView::getAccessibleChildCount (void)
196 throw (uno::RuntimeException)
198 ThrowIfDisposed ();
200 long mpChildCount = AccessibleDocumentViewBase::getAccessibleChildCount();
202 // Forward request to children manager.
203 if (mpChildrenManager != NULL)
204 mpChildCount += mpChildrenManager->GetChildCount ();
206 return mpChildCount;
212 uno::Reference<XAccessible> SAL_CALL
213 AccessibleDrawDocumentView::getAccessibleChild (sal_Int32 nIndex)
214 throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
216 ThrowIfDisposed ();
218 ::osl::ClearableMutexGuard aGuard (maMutex);
220 // Take care of children of the base class.
221 sal_Int32 nCount = AccessibleDocumentViewBase::getAccessibleChildCount();
222 if (nCount > 0)
224 if (nIndex < nCount)
225 return AccessibleDocumentViewBase::getAccessibleChild(nIndex);
226 else
227 nIndex -= nCount;
230 // Create a copy of the pointer to the children manager and release the
231 // mutex before calling any of its methods.
232 ChildrenManager* pChildrenManager = mpChildrenManager;
233 aGuard.clear();
235 // Forward request to children manager.
236 if (pChildrenManager != NULL)
238 return pChildrenManager->GetChild (nIndex);
240 else
241 throw lang::IndexOutOfBoundsException (
242 "no accessible child with index " + OUString::valueOf(nIndex),
243 static_cast<uno::XWeak*>(this));
249 //===== XEventListener ======================================================
251 void SAL_CALL
252 AccessibleDrawDocumentView::disposing (const lang::EventObject& rEventObject)
253 throw (::com::sun::star::uno::RuntimeException)
255 ThrowIfDisposed ();
257 AccessibleDocumentViewBase::disposing (rEventObject);
258 if (rEventObject.Source == mxModel)
260 ::osl::Guard< ::osl::Mutex> aGuard (::osl::Mutex::getGlobalMutex());
261 // maShapeTreeInfo has been modified in base class.
262 if (mpChildrenManager != NULL)
263 mpChildrenManager->SetInfo (maShapeTreeInfo);
270 //===== XPropertyChangeListener =============================================
272 void SAL_CALL
273 AccessibleDrawDocumentView::propertyChange (const beans::PropertyChangeEvent& rEventObject)
274 throw (::com::sun::star::uno::RuntimeException)
276 ThrowIfDisposed ();
278 AccessibleDocumentViewBase::propertyChange (rEventObject);
280 OSL_TRACE ("AccessibleDrawDocumentView::propertyChange");
281 if ( rEventObject.PropertyName == "CurrentPage" )
283 OSL_TRACE (" current page changed");
285 // Update the accessible name to reflect the current slide.
286 UpdateAccessibleName();
288 // The current page changed. Update the children manager accordingly.
289 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
290 if (xView.is() && mpChildrenManager!=NULL)
292 // Inform the children manager to forget all children and give
293 // him the new ones.
294 mpChildrenManager->ClearAccessibleShapeList ();
295 mpChildrenManager->SetShapeList (uno::Reference<drawing::XShapes> (
296 xView->getCurrentPage(), uno::UNO_QUERY));
298 // Create the page shape and initialize it. The shape is
299 // acquired before initialization and released after
300 // transferring ownership to the children manager to prevent
301 // premature disposing of the shape.
302 AccessiblePageShape* pPage = CreateDrawPageShape ();
303 if (pPage != NULL)
305 pPage->acquire();
306 pPage->Init();
307 mpChildrenManager->AddAccessibleShape (
308 std::auto_ptr<AccessibleShape>(pPage));
309 mpChildrenManager->Update (false);
310 pPage->release();
313 else
314 OSL_TRACE ("View invalid");
316 else if ( rEventObject.PropertyName == "VisibleArea" )
318 OSL_TRACE (" visible area changed");
319 if (mpChildrenManager != NULL)
320 mpChildrenManager->ViewForwarderChanged (
321 IAccessibleViewForwarderListener::VISIBLE_AREA,
322 &maViewForwarder);
324 else
326 OSL_TRACE (" unhandled");
328 OSL_TRACE (" done");
333 //===== XServiceInfo ========================================================
335 OUString SAL_CALL
336 AccessibleDrawDocumentView::getImplementationName (void)
337 throw (::com::sun::star::uno::RuntimeException)
339 return OUString("AccessibleDrawDocumentView");
345 ::com::sun::star::uno::Sequence< OUString> SAL_CALL
346 AccessibleDrawDocumentView::getSupportedServiceNames (void)
347 throw (::com::sun::star::uno::RuntimeException)
349 ThrowIfDisposed();
350 // Get list of supported service names from base class...
351 uno::Sequence<OUString> aServiceNames =
352 AccessibleDocumentViewBase::getSupportedServiceNames();
353 sal_Int32 nCount (aServiceNames.getLength());
355 // ...and add additional names.
356 aServiceNames.realloc (nCount + 1);
357 static const OUString sAdditionalServiceName ("com.sun.star.drawing.AccessibleDrawDocumentView");
358 aServiceNames[nCount] = sAdditionalServiceName;
360 return aServiceNames;
366 /// Create a name for this view.
367 OUString
368 AccessibleDrawDocumentView::CreateAccessibleName (void)
369 throw (::com::sun::star::uno::RuntimeException)
371 OUString sName;
373 uno::Reference<lang::XServiceInfo> xInfo (mxController, uno::UNO_QUERY);
374 if (xInfo.is())
376 uno::Sequence< OUString > aServices( xInfo->getSupportedServiceNames() );
377 OUString sFirstService = aServices[0];
378 if ( sFirstService == "com.sun.star.drawing.DrawingDocumentDrawView" )
380 if( aServices.getLength() >= 2 && aServices[1] == "com.sun.star.presentation.PresentationView")
382 SolarMutexGuard aGuard;
384 sName = SD_RESSTR(SID_SD_A11Y_I_DRAWVIEW_N);
386 else
388 SolarMutexGuard aGuard;
390 sName = SD_RESSTR(SID_SD_A11Y_D_DRAWVIEW_N);
393 else if ( sFirstService == "com.sun.star.presentation.NotesView" )
395 SolarMutexGuard aGuard;
397 sName = SD_RESSTR(SID_SD_A11Y_I_NOTESVIEW_N);
399 else if ( sFirstService == "com.sun.star.presentation.HandoutView" )
401 SolarMutexGuard aGuard;
403 sName = SD_RESSTR(SID_SD_A11Y_I_HANDOUTVIEW_N);
405 else
407 sName = sFirstService;
410 else
412 sName = "AccessibleDrawDocumentView";
414 return sName;
420 /** Create a description for this view. Use the model's description or URL
421 if a description is not available.
423 OUString
424 AccessibleDrawDocumentView::CreateAccessibleDescription (void)
425 throw (::com::sun::star::uno::RuntimeException)
427 OUString sDescription;
429 uno::Reference<lang::XServiceInfo> xInfo (mxController, uno::UNO_QUERY);
430 if (xInfo.is())
432 uno::Sequence< OUString > aServices( xInfo->getSupportedServiceNames() );
433 OUString sFirstService = aServices[0];
434 if ( sFirstService == "com.sun.star.drawing.DrawingDocumentDrawView" )
436 if( aServices.getLength() >= 2 && aServices[1] == "com.sun.star.presentation.PresentationView")
438 SolarMutexGuard aGuard;
440 sDescription = SD_RESSTR(SID_SD_A11Y_I_DRAWVIEW_D);
442 else
444 SolarMutexGuard aGuard;
446 sDescription = SD_RESSTR(SID_SD_A11Y_D_DRAWVIEW_D);
449 else if ( sFirstService == "com.sun.star.presentation.NotesView" )
451 SolarMutexGuard aGuard;
453 sDescription = SD_RESSTR(SID_SD_A11Y_I_NOTESVIEW_D);
455 else if ( sFirstService == "com.sun.star.presentation.HandoutView" )
457 SolarMutexGuard aGuard;
459 sDescription = SD_RESSTR(SID_SD_A11Y_I_HANDOUTVIEW_D);
461 else
463 sDescription = sFirstService;
466 else
468 sDescription = "Accessible Draw Document";
470 return sDescription;
476 /** Return selection state of specified child
478 sal_Bool
479 AccessibleDrawDocumentView::implIsSelected( sal_Int32 nAccessibleChildIndex )
480 throw (uno::RuntimeException)
482 const SolarMutexGuard aSolarGuard;
483 uno::Reference< view::XSelectionSupplier > xSel( mxController, uno::UNO_QUERY );
484 sal_Bool bRet = sal_False;
486 OSL_ENSURE( 0 <= nAccessibleChildIndex, "AccessibleDrawDocumentView::implIsSelected: invalid index!" );
488 if( xSel.is() && ( 0 <= nAccessibleChildIndex ) )
490 uno::Any aAny( xSel->getSelection() );
491 uno::Reference< drawing::XShapes > xShapes;
493 aAny >>= xShapes;
495 if( xShapes.is() )
497 AccessibleShape* pAcc = AccessibleShape::getImplementation( getAccessibleChild( nAccessibleChildIndex ) );
499 if( pAcc )
501 uno::Reference< drawing::XShape > xShape( pAcc->GetXShape() );
503 if( xShape.is() )
505 for( sal_Int32 i = 0, nCount = xShapes->getCount(); ( i < nCount ) && !bRet; ++i )
506 if( xShapes->getByIndex( i ) == xShape )
507 bRet = sal_True;
513 return( bRet );
519 /** Select or delselect the specified shapes. The corresponding accessible
520 shapes are notified over the selection change listeners registered with
521 the XSelectionSupplier of the controller.
523 void
524 AccessibleDrawDocumentView::implSelect( sal_Int32 nAccessibleChildIndex, sal_Bool bSelect )
525 throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
527 const SolarMutexGuard aSolarGuard;
528 uno::Reference< view::XSelectionSupplier > xSel( mxController, uno::UNO_QUERY );
530 if( xSel.is() )
532 uno::Any aAny;
534 if( ACCESSIBLE_SELECTION_CHILD_ALL == nAccessibleChildIndex )
536 // Select or deselect all children.
538 if( !bSelect )
539 xSel->select( aAny );
540 else
542 uno::Reference< drawing::XShapes > xShapes( new SvxShapeCollection() );
544 for(sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
546 AccessibleShape* pAcc = AccessibleShape::getImplementation( getAccessibleChild( i ) );
548 if( pAcc && pAcc->GetXShape().is() )
549 xShapes->add( pAcc->GetXShape() );
552 if( xShapes->getCount() )
554 aAny <<= xShapes;
555 xSel->select( aAny );
559 else if( nAccessibleChildIndex >= 0 )
561 // Select or deselect only the child with index
562 // nAccessibleChildIndex.
564 AccessibleShape* pAcc = AccessibleShape::getImplementation(
565 getAccessibleChild( nAccessibleChildIndex ));
567 // Add or remove the shape that is made accessible from the
568 // selection of the controller.
569 if( pAcc )
571 uno::Reference< drawing::XShape > xShape( pAcc->GetXShape() );
573 if( xShape.is() )
575 uno::Reference< drawing::XShapes > xShapes;
576 sal_Bool bFound = sal_False;
578 aAny = xSel->getSelection();
579 aAny >>= xShapes;
581 // Search shape to be selected in current selection.
582 if (xShapes.is())
584 sal_Int32 nCount = xShapes->getCount();
585 for (sal_Int32 i=0; ( i < nCount ) && !bFound; ++i )
586 if( xShapes->getByIndex( i ) == xShape )
587 bFound = sal_True;
589 else
590 // Create an empty selection to add the shape to.
591 xShapes = new SvxShapeCollection();
593 // Update the selection.
594 if( !bFound && bSelect )
595 xShapes->add( xShape );
596 else if( bFound && !bSelect )
597 xShapes->remove( xShape );
599 aAny <<= xShapes;
600 xSel->select( aAny );
610 void AccessibleDrawDocumentView::Activated (void)
612 if (mpChildrenManager != NULL)
614 mpChildrenManager->UpdateSelection();
615 // When none of the children has the focus then claim it for the
616 // view.
617 if ( ! mpChildrenManager->HasFocus())
618 SetState (AccessibleStateType::FOCUSED);
619 else
620 ResetState (AccessibleStateType::FOCUSED);
627 void AccessibleDrawDocumentView::Deactivated (void)
629 if (mpChildrenManager != NULL)
630 mpChildrenManager->RemoveFocus();
631 ResetState (AccessibleStateType::FOCUSED);
637 void AccessibleDrawDocumentView::impl_dispose (void)
639 if (mpChildrenManager != NULL)
641 delete mpChildrenManager;
642 mpChildrenManager = NULL;
645 AccessibleDocumentViewBase::impl_dispose();
650 /** This method is called from the component helper base class while
651 disposing.
653 void SAL_CALL AccessibleDrawDocumentView::disposing (void)
656 // Release resources.
657 if (mpChildrenManager != NULL)
659 delete mpChildrenManager;
660 mpChildrenManager = NULL;
663 // Forward call to base classes.
664 AccessibleDocumentViewBase::disposing ();
670 void AccessibleDrawDocumentView::UpdateAccessibleName (void)
672 OUString sNewName (CreateAccessibleName());
673 sNewName += ": ";
675 // Add the number of the current slide.
676 uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
677 if (xView.is())
679 uno::Reference<beans::XPropertySet> xProperties (xView->getCurrentPage(), UNO_QUERY);
680 if (xProperties.is())
683 sal_Int16 nPageNumber (0);
684 if (xProperties->getPropertyValue("Number") >>= nPageNumber)
686 sNewName += OUString::valueOf(sal_Int32(nPageNumber));
689 catch (beans::UnknownPropertyException&)
694 // Add the number of pages/slides.
695 Reference<drawing::XDrawPagesSupplier> xPagesSupplier (mxModel, UNO_QUERY);
696 if (xPagesSupplier.is())
698 Reference<container::XIndexAccess> xPages (xPagesSupplier->getDrawPages(), UNO_QUERY);
699 if (xPages.is())
701 sNewName += " / ";
702 sNewName += OUString::valueOf(xPages->getCount());
706 SetAccessibleName (sNewName, AutomaticallyCreated);
709 } // end of namespace accessibility
711 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */