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