1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sd.hxx"
30 #include "AccessibleDrawDocumentView.hxx"
31 #include <com/sun/star/drawing/XDrawPage.hpp>
32 #include <com/sun/star/drawing/XDrawView.hpp>
33 #include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
34 #include <com/sun/star/drawing/XShapes.hpp>
35 #include <com/sun/star/container/XChild.hpp>
36 #include <com/sun/star/frame/XController.hpp>
37 #include <com/sun/star/frame/XFrame.hpp>
38 #include <com/sun/star/document/XEventBroadcaster.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
41 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
42 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
43 #include <rtl/ustring.h>
44 #include<sfx2/viewfrm.hxx>
45 
46 #include <svx/AccessibleShape.hxx>
47 
48 #include <svx/svdobj.hxx>
49 #include <svx/svdmodel.hxx>
50 #include <svx/unoapi.hxx>
51 #include <svx/unoshcol.hxx>
52 #include <toolkit/helper/vclunohelper.hxx>
53 #include "Window.hxx"
54 #include <vcl/svapp.hxx>
55 
56 
57 #include "ViewShell.hxx"
58 #include "View.hxx"
59 #include <memory>
60 
61 #include "accessibility.hrc"
62 #include "sdresid.hxx"
63 #include <vos/mutex.hxx>
64 
65 using ::rtl::OUString;
66 using namespace ::com::sun::star;
67 using namespace ::com::sun::star::uno;
68 using namespace	::com::sun::star::accessibility;
69 
70 class SfxViewFrame;
71 
72 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
73 
74 namespace accessibility {
75 
76 
77 //=====  internal  ============================================================
78 
79 AccessibleDrawDocumentView::AccessibleDrawDocumentView (
80     ::sd::Window* pSdWindow,
81     ::sd::ViewShell* pViewShell,
82     const uno::Reference<frame::XController>& rxController,
83     const uno::Reference<XAccessible>& rxParent)
84     : AccessibleDocumentViewBase (pSdWindow, pViewShell, rxController, rxParent),
85       mpChildrenManager (NULL)
86 {
87     OSL_TRACE ("AccessibleDrawDocumentView");
88     UpdateAccessibleName();
89 }
90 
91 
92 
93 
94 AccessibleDrawDocumentView::~AccessibleDrawDocumentView (void)
95 {
96     OSL_TRACE ("~AccessibleDrawDocumentView");
97     DBG_ASSERT (rBHelper.bDisposed || rBHelper.bInDispose,
98         "~AccessibleDrawDocumentView: object has not been disposed");
99 }
100 
101 
102 
103 
104 void AccessibleDrawDocumentView::Init (void)
105 {
106     AccessibleDocumentViewBase::Init ();
107 
108     // Determine the list of shapes on the current page.
109     uno::Reference<drawing::XShapes> xShapeList;
110     uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
111     if (xView.is())
112         xShapeList = uno::Reference<drawing::XShapes> (
113             xView->getCurrentPage(), uno::UNO_QUERY);
114 
115     // Create the children manager.
116     mpChildrenManager = new ChildrenManager(this, xShapeList, maShapeTreeInfo, *this);
117     if (mpChildrenManager != NULL)
118     {
119         // Create the page shape and initialize it.  The shape is acquired
120         // before initialization and released after transferring ownership
121         // to the children manager to prevent premature disposing of the
122         // shape.
123         AccessiblePageShape* pPage = CreateDrawPageShape();
124         if (pPage != NULL)
125         {
126             pPage->acquire();
127             pPage->Init();
128             mpChildrenManager->AddAccessibleShape (
129                 std::auto_ptr<AccessibleShape>(pPage));
130             pPage->release();
131             mpChildrenManager->Update ();
132         }
133         mpChildrenManager->UpdateSelection ();
134     }
135 }
136 
137 
138 
139 
140 void AccessibleDrawDocumentView::ViewForwarderChanged (ChangeType aChangeType,
141     const IAccessibleViewForwarder* pViewForwarder)
142 {
143     AccessibleDocumentViewBase::ViewForwarderChanged (aChangeType, pViewForwarder);
144     if (mpChildrenManager != NULL)
145         mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder);
146 }
147 
148 
149 
150 
151 /**  The page shape is created on every call at the moment (provided that
152      every thing goes well).
153 */
154 AccessiblePageShape* AccessibleDrawDocumentView::CreateDrawPageShape (void)
155 {
156     AccessiblePageShape* pShape = NULL;
157 
158     // Create a shape that represents the actual draw page.
159     uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
160     if (xView.is())
161     {
162         uno::Reference<beans::XPropertySet> xSet (
163             uno::Reference<beans::XPropertySet> (xView->getCurrentPage(), uno::UNO_QUERY));
164         if (xSet.is())
165         {
166             // Create a rectangle shape that will represent the draw page.
167             uno::Reference<lang::XMultiServiceFactory> xFactory (mxModel, uno::UNO_QUERY);
168             uno::Reference<drawing::XShape> xRectangle;
169             if (xFactory.is())
170                 xRectangle = uno::Reference<drawing::XShape>(xFactory->createInstance (
171                     OUString (RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.RectangleShape"))),
172                     uno::UNO_QUERY);
173 
174             // Set the shape's size and position.
175             if (xRectangle.is())
176             {
177                 uno::Any aValue;
178                 awt::Point aPosition;
179                 awt::Size aSize;
180 
181                 // Set size and position of the shape to those of the draw
182                 // page.
183                 aValue = xSet->getPropertyValue (
184                     OUString (RTL_CONSTASCII_USTRINGPARAM("BorderLeft")));
185                 aValue >>= aPosition.X;
186                 aValue = xSet->getPropertyValue (
187                     OUString (RTL_CONSTASCII_USTRINGPARAM("BorderTop")));
188                 aValue >>= aPosition.Y;
189                 xRectangle->setPosition (aPosition);
190 
191                 aValue = xSet->getPropertyValue (
192                     OUString (RTL_CONSTASCII_USTRINGPARAM("Width")));
193                 aValue >>= aSize.Width;
194                 aValue = xSet->getPropertyValue (
195                     OUString (RTL_CONSTASCII_USTRINGPARAM("Height")));
196                 aValue >>= aSize.Height;
197                 xRectangle->setSize (aSize);
198 
199                 // Create the accessible object for the shape and
200                 // initialize it.
201                 pShape = new AccessiblePageShape (
202                     xView->getCurrentPage(), this, maShapeTreeInfo);
203             }
204         }
205     }
206     return pShape;
207 }
208 
209 
210 
211 
212 //=====  XAccessibleContext  ==================================================
213 
214 sal_Int32 SAL_CALL
215     AccessibleDrawDocumentView::getAccessibleChildCount (void)
216     throw (uno::RuntimeException)
217 {
218     ThrowIfDisposed ();
219 
220     long mpChildCount = AccessibleDocumentViewBase::getAccessibleChildCount();
221 
222     // Forward request to children manager.
223     if (mpChildrenManager != NULL)
224         mpChildCount += mpChildrenManager->GetChildCount ();
225 
226     return mpChildCount;
227 }
228 
229 
230 
231 
232 uno::Reference<XAccessible> SAL_CALL
233     AccessibleDrawDocumentView::getAccessibleChild (sal_Int32 nIndex)
234     throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
235 {
236     ThrowIfDisposed ();
237 
238     ::osl::ClearableMutexGuard aGuard (maMutex);
239 
240     // Take care of children of the base class.
241     sal_Int32 nCount = AccessibleDocumentViewBase::getAccessibleChildCount();
242     if (nCount > 0)
243     {
244         if (nIndex < nCount)
245             return AccessibleDocumentViewBase::getAccessibleChild(nIndex);
246         else
247             nIndex -= nCount;
248     }
249 
250     // Create a copy of the pointer to the children manager and release the
251     // mutex before calling any of its methods.
252     ChildrenManager* pChildrenManager = mpChildrenManager;
253     aGuard.clear();
254 
255     // Forward request to children manager.
256     if (pChildrenManager != NULL)
257     {
258         return pChildrenManager->GetChild (nIndex);
259     }
260     else
261         throw lang::IndexOutOfBoundsException (
262             ::rtl::OUString::createFromAscii ("no accessible child with index ")
263             + rtl::OUString::valueOf(nIndex),
264             static_cast<uno::XWeak*>(this));
265 }
266 
267 
268 
269 
270 //=====  XEventListener  ======================================================
271 
272 void SAL_CALL
273     AccessibleDrawDocumentView::disposing (const lang::EventObject& rEventObject)
274     throw (::com::sun::star::uno::RuntimeException)
275 {
276     ThrowIfDisposed ();
277 
278     AccessibleDocumentViewBase::disposing (rEventObject);
279     if (rEventObject.Source == mxModel)
280     {
281         ::osl::Guard< ::osl::Mutex> aGuard (::osl::Mutex::getGlobalMutex());
282         // maShapeTreeInfo has been modified in base class.
283         if (mpChildrenManager != NULL)
284             mpChildrenManager->SetInfo (maShapeTreeInfo);
285     }
286 }
287 
288 
289 
290 
291 //=====  XPropertyChangeListener  =============================================
292 
293 void SAL_CALL
294     AccessibleDrawDocumentView::propertyChange (const beans::PropertyChangeEvent& rEventObject)
295     throw (::com::sun::star::uno::RuntimeException)
296 {
297     ThrowIfDisposed ();
298 
299     AccessibleDocumentViewBase::propertyChange (rEventObject);
300 
301     OSL_TRACE ("AccessibleDrawDocumentView::propertyChange");
302     if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("CurrentPage")))
303     {
304         OSL_TRACE ("    current page changed");
305 
306         // Update the accessible name to reflect the current slide.
307         UpdateAccessibleName();
308 
309         // The current page changed.  Update the children manager accordingly.
310         uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
311         if (xView.is() && mpChildrenManager!=NULL)
312         {
313             // Inform the children manager to forget all children and give
314             // him the new ones.
315             mpChildrenManager->ClearAccessibleShapeList ();
316             mpChildrenManager->SetShapeList (uno::Reference<drawing::XShapes> (
317                 xView->getCurrentPage(), uno::UNO_QUERY));
318 
319             // Create the page shape and initialize it.  The shape is
320             // acquired before initialization and released after
321             // transferring ownership to the children manager to prevent
322             // premature disposing of the shape.
323             AccessiblePageShape* pPage = CreateDrawPageShape ();
324             if (pPage != NULL)
325             {
326                 pPage->acquire();
327                 pPage->Init();
328                 mpChildrenManager->AddAccessibleShape (
329                     std::auto_ptr<AccessibleShape>(pPage));
330                 mpChildrenManager->Update (false);
331                 pPage->release();
332             }
333         }
334         else
335             OSL_TRACE ("View invalid");
336     }
337     else if (rEventObject.PropertyName == OUString (RTL_CONSTASCII_USTRINGPARAM("VisibleArea")))
338     {
339         OSL_TRACE ("    visible area changed");
340         if (mpChildrenManager != NULL)
341             mpChildrenManager->ViewForwarderChanged (
342                 IAccessibleViewForwarderListener::VISIBLE_AREA,
343                 &maViewForwarder);
344     }
345     else
346     {
347         OSL_TRACE ("  unhandled");
348     }
349     OSL_TRACE ("  done");
350 }
351 
352 
353 
354 //=====  XServiceInfo  ========================================================
355 
356 ::rtl::OUString SAL_CALL
357     AccessibleDrawDocumentView::getImplementationName (void)
358     throw (::com::sun::star::uno::RuntimeException)
359 {
360 	return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
361         "AccessibleDrawDocumentView"));
362 }
363 
364 
365 
366 
367 ::com::sun::star::uno::Sequence< ::rtl::OUString> SAL_CALL
368     AccessibleDrawDocumentView::getSupportedServiceNames (void)
369     throw (::com::sun::star::uno::RuntimeException)
370 {
371     ThrowIfDisposed();
372     // Get list of supported service names from base class...
373     uno::Sequence<OUString> aServiceNames =
374         AccessibleDocumentViewBase::getSupportedServiceNames();
375     sal_Int32 nCount (aServiceNames.getLength());
376 
377     // ...and add additional names.
378     aServiceNames.realloc (nCount + 1);
379     static const OUString sAdditionalServiceName (RTL_CONSTASCII_USTRINGPARAM(
380         "com.sun.star.drawing.AccessibleDrawDocumentView"));
381     aServiceNames[nCount] = sAdditionalServiceName;
382 
383     return aServiceNames;
384 }
385 
386 
387 
388 
389 ///	Create a name for this view.
390 ::rtl::OUString
391     AccessibleDrawDocumentView::CreateAccessibleName (void)
392     throw (::com::sun::star::uno::RuntimeException)
393 {
394 	rtl::OUString sName;
395 
396     uno::Reference<lang::XServiceInfo> xInfo (mxController, uno::UNO_QUERY);
397     if (xInfo.is())
398     {
399         uno::Sequence< ::rtl::OUString > aServices( xInfo->getSupportedServiceNames() );
400         OUString sFirstService = aServices[0];
401         if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocumentDrawView")))
402         {
403             if( aServices.getLength() >= 2 &&
404                 aServices[1] == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationView")))
405             {
406                 ::vos::OGuard aGuard( Application::GetSolarMutex() );
407 
408                 sName = String( SdResId(SID_SD_A11Y_I_DRAWVIEW_N) );
409             }
410             else
411             {
412                 ::vos::OGuard aGuard( Application::GetSolarMutex() );
413 
414                 sName = String( SdResId(SID_SD_A11Y_D_DRAWVIEW_N) );
415             }
416         }
417         else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.NotesView")))
418         {
419             ::vos::OGuard aGuard( Application::GetSolarMutex() );
420 
421             sName = String( SdResId(SID_SD_A11Y_I_NOTESVIEW_N) );
422         }
423         else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.HandoutView")))
424         {
425             ::vos::OGuard aGuard( Application::GetSolarMutex() );
426 
427             sName = String( SdResId(SID_SD_A11Y_I_HANDOUTVIEW_N) );
428         }
429         else
430         {
431             sName = sFirstService;
432         }
433     }
434     else
435     {
436         sName = OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleDrawDocumentView"));
437     }
438 	return sName;
439 }
440 
441 
442 
443 
444 /** Create a description for this view.  Use the model's description or URL
445     if a description is not available.
446 */
447 ::rtl::OUString
448     AccessibleDrawDocumentView::CreateAccessibleDescription (void)
449     throw (::com::sun::star::uno::RuntimeException)
450 {
451 	rtl::OUString sDescription;
452 
453     uno::Reference<lang::XServiceInfo> xInfo (mxController, uno::UNO_QUERY);
454     if (xInfo.is())
455     {
456         uno::Sequence< ::rtl::OUString > aServices( xInfo->getSupportedServiceNames() );
457         OUString sFirstService = aServices[0];
458         if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.drawing.DrawingDocumentDrawView")))
459         {
460             if( aServices.getLength() >= 2 &&
461                 aServices[1] == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.PresentationView")))
462             {
463                 ::vos::OGuard aGuard( Application::GetSolarMutex() );
464 
465                 sDescription = String( SdResId(SID_SD_A11Y_I_DRAWVIEW_D) );
466             }
467             else
468             {
469                 ::vos::OGuard aGuard( Application::GetSolarMutex() );
470 
471                 sDescription = String( SdResId(SID_SD_A11Y_D_DRAWVIEW_D) );
472             }
473         }
474         else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.NotesView")))
475         {
476             ::vos::OGuard aGuard( Application::GetSolarMutex() );
477 
478             sDescription = String( SdResId(SID_SD_A11Y_I_NOTESVIEW_D) );
479         }
480         else if (sFirstService == OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.presentation.HandoutView")))
481         {
482             ::vos::OGuard aGuard( Application::GetSolarMutex() );
483 
484             sDescription = String( SdResId(SID_SD_A11Y_I_HANDOUTVIEW_D) );
485         }
486         else
487         {
488             sDescription = sFirstService;
489         }
490     }
491     else
492     {
493         sDescription = OUString(RTL_CONSTASCII_USTRINGPARAM("Accessible Draw Document"));
494     }
495 	return sDescription;
496 }
497 
498 
499 
500 
501 /** Return selection state of specified child
502 */
503 sal_Bool
504     AccessibleDrawDocumentView::implIsSelected( sal_Int32 nAccessibleChildIndex )
505     throw (uno::RuntimeException)
506 {
507     const vos::OGuard                           aSolarGuard( Application::GetSolarMutex() );
508     uno::Reference< view::XSelectionSupplier >  xSel( mxController, uno::UNO_QUERY );
509     sal_Bool                                    bRet = sal_False;
510 
511 	OSL_ENSURE( 0 <= nAccessibleChildIndex, "AccessibleDrawDocumentView::implIsSelected: invalid index!" );
512 
513     if( xSel.is() && ( 0 <= nAccessibleChildIndex ) )
514     {
515         uno::Any                            aAny( xSel->getSelection() );
516         uno::Reference< drawing::XShapes >  xShapes;
517 
518         aAny >>= xShapes;
519 
520         if( xShapes.is() )
521         {
522             AccessibleShape* pAcc = AccessibleShape::getImplementation( getAccessibleChild( nAccessibleChildIndex ) );
523 
524             if( pAcc )
525             {
526                 uno::Reference< drawing::XShape > xShape( pAcc->GetXShape() );
527 
528                 if( xShape.is() )
529                 {
530                     for( sal_Int32 i = 0, nCount = xShapes->getCount(); ( i < nCount ) && !bRet; ++i )
531                         if( xShapes->getByIndex( i ) == xShape )
532                             bRet = sal_True;
533                 }
534             }
535         }
536     }
537 
538     return( bRet );
539 }
540 
541 
542 
543 
544 /** Select or delselect the specified shapes.  The corresponding accessible
545     shapes are notified over the selection change listeners registered with
546     the XSelectionSupplier of the controller.
547 */
548 void
549     AccessibleDrawDocumentView::implSelect( sal_Int32 nAccessibleChildIndex, sal_Bool bSelect )
550     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
551 {
552     const vos::OGuard                           aSolarGuard( Application::GetSolarMutex() );
553     uno::Reference< view::XSelectionSupplier >  xSel( mxController, uno::UNO_QUERY );
554     AccessibleShape* pAccessibleChild;
555 
556     if( xSel.is() )
557     {
558         uno::Any aAny;
559 
560         if( ACCESSIBLE_SELECTION_CHILD_ALL == nAccessibleChildIndex )
561         {
562             // Select or deselect all children.
563 
564             if( !bSelect )
565                 xSel->select( aAny );
566             else
567             {
568                 uno::Reference< drawing::XShapes > xShapes( new SvxShapeCollection() );
569 
570                 for(sal_Int32 i = 0, nCount = getAccessibleChildCount(); i < nCount; ++i )
571                 {
572                     AccessibleShape* pAcc = AccessibleShape::getImplementation( getAccessibleChild( i ) );
573 
574                     if( pAcc && pAcc->GetXShape().is() )
575                     {
576                         xShapes->add( pAcc->GetXShape() );
577                         pAccessibleChild = pAcc;
578                     }
579                 }
580 
581                 if( xShapes->getCount() )
582                 {
583                     aAny <<= xShapes;
584                     xSel->select( aAny );
585                 }
586             }
587         }
588         else if( nAccessibleChildIndex >= 0 )
589         {
590             // Select or deselect only the child with index
591             // nAccessibleChildIndex.
592 
593             AccessibleShape* pAcc = AccessibleShape::getImplementation(
594                 getAccessibleChild( nAccessibleChildIndex ));
595             pAccessibleChild = pAcc;
596 
597             // Add or remove the shape that is made accessible from the
598             // selection of the controller.
599             if( pAcc )
600             {
601                 uno::Reference< drawing::XShape > xShape( pAcc->GetXShape() );
602 
603                 if( xShape.is() )
604                 {
605                     uno::Reference< drawing::XShapes >  xShapes;
606                     sal_Bool                            bFound = sal_False;
607 
608                     aAny = xSel->getSelection();
609                     aAny >>= xShapes;
610 
611                     // Search shape to be selected in current selection.
612                     if (xShapes.is())
613                     {
614                         sal_Int32 nCount = xShapes->getCount();
615                         for (sal_Int32 i=0; ( i < nCount ) && !bFound; ++i )
616                             if( xShapes->getByIndex( i ) == xShape )
617                                 bFound = sal_True;
618                     }
619                     else
620                         // Create an empty selection to add the shape to.
621                         xShapes = new SvxShapeCollection();
622 
623                     // Update the selection.
624                     if( !bFound && bSelect )
625                         xShapes->add( xShape );
626                     else if( bFound && !bSelect )
627                         xShapes->remove( xShape );
628 
629                     aAny <<= xShapes;
630                     xSel->select( aAny );
631                 }
632             }
633         }
634     }
635 }
636 
637 
638 
639 
640 void AccessibleDrawDocumentView::Activated (void)
641 {
642     if (mpChildrenManager != NULL)
643     {
644         mpChildrenManager->UpdateSelection();
645         // When none of the children has the focus then claim it for the
646         // view.
647         if ( ! mpChildrenManager->HasFocus())
648             SetState (AccessibleStateType::FOCUSED);
649         else
650             ResetState (AccessibleStateType::FOCUSED);
651     }
652 }
653 
654 
655 
656 
657 void AccessibleDrawDocumentView::Deactivated (void)
658 {
659     if (mpChildrenManager != NULL)
660         mpChildrenManager->RemoveFocus();
661     ResetState (AccessibleStateType::FOCUSED);
662 }
663 
664 
665 
666 
667 void AccessibleDrawDocumentView::impl_dispose (void)
668 {
669     if (mpChildrenManager != NULL)
670     {
671         delete mpChildrenManager;
672         mpChildrenManager = NULL;
673     }
674 
675     AccessibleDocumentViewBase::impl_dispose();
676 }
677 
678 
679 
680 /** This method is called from the component helper base class while
681     disposing.
682 */
683 void SAL_CALL AccessibleDrawDocumentView::disposing (void)
684 {
685 
686     // Release resources.
687     if (mpChildrenManager != NULL)
688     {
689         delete mpChildrenManager;
690         mpChildrenManager = NULL;
691     }
692 
693     // Forward call to base classes.
694     AccessibleDocumentViewBase::disposing ();
695 }
696 
697 
698 
699 
700 void AccessibleDrawDocumentView::UpdateAccessibleName (void)
701 {
702 	OUString sNewName (CreateAccessibleName());
703     sNewName += A2S(": ");
704 
705     // Add the number of the current slide.
706     uno::Reference<drawing::XDrawView> xView (mxController, uno::UNO_QUERY);
707     if (xView.is())
708     {
709         uno::Reference<beans::XPropertySet> xProperties (xView->getCurrentPage(), UNO_QUERY);
710         if (xProperties.is())
711             try
712             {
713                 sal_Int16 nPageNumber (0);
714                 if (xProperties->getPropertyValue(A2S("Number")) >>= nPageNumber)
715                 {
716                     sNewName += OUString::valueOf(sal_Int32(nPageNumber));
717                 }
718             }
719             catch (beans::UnknownPropertyException&)
720             {
721             }
722     }
723 
724     // Add the number of pages/slides.
725     Reference<drawing::XDrawPagesSupplier> xPagesSupplier (mxModel, UNO_QUERY);
726     if (xPagesSupplier.is())
727     {
728         Reference<container::XIndexAccess> xPages (xPagesSupplier->getDrawPages(), UNO_QUERY);
729         if (xPages.is())
730         {
731             sNewName += A2S(" / ");
732             sNewName += OUString::valueOf(xPages->getCount());
733         }
734     }
735 
736     SetAccessibleName (sNewName, AutomaticallyCreated);
737 }
738 
739 
740 
741 
742 } // end of namespace accessibility
743