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