xref: /AOO41X/main/svx/source/accessibility/AccessibleShape.cxx (revision 3dceaf700ec27bdf08a615f6b12e29fa57df2c56)
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_svx.hxx"
26 #include <svx/AccessibleShape.hxx>
27 #include "svx/DescriptionGenerator.hxx"
28 #include <svx/AccessibleShapeInfo.hxx>
29 #include <com/sun/star/view/XSelectionSupplier.hpp>
30 #include <rtl/uuid.h>
31 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLE_ROLE_HPP_
32 #include <com/sun/star/accessibility/AccessibleRole.hpp>
33 #endif
34 //IAccessibility2 Implementation 2009-----
35 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLETEXTTYPE_HPP_
36 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
37 #endif
38 //-----IAccessibility2 Implementation 2009
39 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLE_STATE_TYPE_HPP_
40 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
41 #endif
42 #include <com/sun/star/beans/XPropertySet.hpp>
43 #include <com/sun/star/container/XChild.hpp>
44 #include <com/sun/star/drawing/XShapes.hpp>
45 #include <com/sun/star/drawing/XShapeDescriptor.hpp>
46 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
47 #include <com/sun/star/drawing/FillStyle.hpp>
48 #include <com/sun/star/text/XText.hpp>
49 #include <editeng/outlobj.hxx>
50 #include <rtl/ref.hxx>
51 #include <editeng/unoedsrc.hxx>
52 #include <svx/unoshtxt.hxx>
53 #include <svx/svdobj.hxx>
54 #include <svx/svdmodel.hxx>
55 #include "svx/unoapi.hxx"
56 #include <com/sun/star/uno/Exception.hpp>
57 #include <svx/ShapeTypeHandler.hxx>
58 #include <svx/SvxShapeTypes.hxx>
59 
60 #ifndef _SVX_ACCESSIBILITY_HRC
61 #include "accessibility.hrc"
62 #endif
63 #include "svx/svdstr.hrc"
64 #include <svx/dialmgr.hxx>
65 #include <vcl/svapp.hxx>
66 #include <unotools/accessiblestatesethelper.hxx>
67 #include <svx/svdview.hxx>
68 #include "AccessibleEmptyEditSource.hxx"
69 //IAccessibility2 Implementation 2009-----
70 #include <svx/svdpage.hxx>
71 #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HPP_
72 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
73 #endif
74 #ifndef _UTL_ACCESSIBLERELATIONSETHELPER_HXX_
75 #include <unotools/accessiblerelationsethelper.hxx>
76 #endif
77 //-----IAccessibility2 Implementation 2009
78 using namespace ::com::sun::star;
79 using namespace ::com::sun::star::accessibility;
80 //IAccessibility2 Implementation 2009-----
81 using ::com::sun::star::lang::IndexOutOfBoundsException;
82 using ::com::sun::star::uno::RuntimeException;
83 //-----IAccessibility2 Implementation 2009
84 using ::com::sun::star::uno::Reference;
85 using ::rtl::OUString;
86 //IAccessibility2 Implementation 2009-----
87 #include <algorithm>
88 
89 // #include <Accessiblehyperlink.hxx>
90 //-----IAccessibility2 Implementation 2009
91 namespace accessibility {
92 
93 namespace {
94 
95 OUString GetOptionalProperty (
96     const Reference<beans::XPropertySet>& rxSet,
97     const OUString& rsPropertyName)
98 {
99     OUString sValue;
100 
101     if (rxSet.is())
102     {
103         const Reference<beans::XPropertySetInfo> xInfo (rxSet->getPropertySetInfo());
104         if ( ! xInfo.is() || xInfo->hasPropertyByName(rsPropertyName))
105         {
106             try
107             {
108                 rxSet->getPropertyValue(rsPropertyName) >>= sValue;
109             }
110             catch (beans::UnknownPropertyException&)
111             {
112                 // This exception should only be thrown when the property
113                 // does not exits (of course) and the XPropertySetInfo is
114                 // not available.
115             }
116         }
117     }
118     return sValue;
119 }
120 
121 } // end of anonymous namespace
122 
123 
124 
125 
126 //=====  internal  ============================================================
127 
128 AccessibleShape::AccessibleShape (
129     const AccessibleShapeInfo& rShapeInfo,
130     const AccessibleShapeTreeInfo& rShapeTreeInfo)
131     //IAccessibility2 Implementation 2009-----
132     : AccessibleContextBase (rShapeInfo.mxParent,AccessibleRole::SHAPE),
133     //-----IAccessibility2 Implementation 2009
134       mpChildrenManager(NULL),
135       mxShape (rShapeInfo.mxShape),
136       maShapeTreeInfo (rShapeTreeInfo),
137       mnIndex (rShapeInfo.mnIndex),
138       m_nIndexInParent(-1),
139       mpText (NULL),
140       mpParent (rShapeInfo.mpChildrenManager)
141 {
142     m_pShape = GetSdrObjectFromXShape(mxShape);
143     UpdateNameAndDescription();
144 }
145 //IAccessibility2 Implementation 2009-----
146 AccessibleShape::AccessibleShape (
147         const ::com::sun::star::uno::Reference<
148             ::com::sun::star::drawing::XShape>& rxShape,
149         const ::com::sun::star::uno::Reference<
150             ::com::sun::star::accessibility::XAccessible>& rxParent,
151         const AccessibleShapeTreeInfo& rShapeTreeInfo,
152         sal_Int32 nIndex)
153     : AccessibleContextBase (rxParent,AccessibleRole::SHAPE),
154       mpChildrenManager(NULL),
155       mxShape (rxShape),
156       maShapeTreeInfo (rShapeTreeInfo),
157       mnIndex (nIndex),
158       m_nIndexInParent(-1),
159       mpText (NULL),
160       mpParent (NULL)
161 {
162     m_pShape = GetSdrObjectFromXShape(mxShape);
163 }
164 //-----IAccessibility2 Implementation 2009
165 AccessibleShape::~AccessibleShape (void)
166 {
167     if (mpChildrenManager != NULL)
168         delete mpChildrenManager;
169     if (mpText != NULL)
170         delete mpText;
171     OSL_TRACE ("~AccessibleShape");
172 
173     // Unregistering from the various broadcasters should be unnecessary
174     // since this destructor would not have been called if one of the
175     // broadcasters would still hold a strong reference to this object.
176 }
177 
178 
179 
180 
181 void AccessibleShape::Init (void)
182 {
183     // Update the OPAQUE and SELECTED shape.
184     UpdateStates ();
185 
186     // Create a children manager when this shape has children of its own.
187     Reference<drawing::XShapes> xShapes (mxShape, uno::UNO_QUERY);
188     if (xShapes.is() && xShapes->getCount() > 0)
189         mpChildrenManager = new ChildrenManager (
190             this, xShapes, maShapeTreeInfo, *this);
191     if (mpChildrenManager != NULL)
192         mpChildrenManager->Update();
193 
194     // Register at model as document::XEventListener.
195     if (maShapeTreeInfo.GetModelBroadcaster().is())
196         maShapeTreeInfo.GetModelBroadcaster()->addEventListener (
197             static_cast<document::XEventListener*>(this));
198 
199     // Beware! Here we leave the paths of the UNO API and descend into the
200     // depths of the core.  Necessary for makeing the edit engine
201     // accessible.
202     Reference<text::XText> xText (mxShape, uno::UNO_QUERY);
203     if (xText.is())
204     {
205         SdrView* pView = maShapeTreeInfo.GetSdrView ();
206         const Window* pWindow = maShapeTreeInfo.GetWindow ();
207         if (pView != NULL && pWindow != NULL && mxShape.is())
208         {
209             // #107948# Determine whether shape text is empty
210             SdrObject* pSdrObject = GetSdrObjectFromXShape(mxShape);
211             if( pSdrObject )
212             {
213                 SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, pSdrObject );
214                 OutlinerParaObject* pOutlinerParaObject = NULL;
215 
216                 if( pTextObj )
217                     pOutlinerParaObject = pTextObj->GetEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active
218 
219                 bool bOwnParaObj = pOutlinerParaObject != NULL;
220 
221                 if( !pOutlinerParaObject && pSdrObject )
222                     pOutlinerParaObject = pSdrObject->GetOutlinerParaObject();
223 
224                 // create AccessibleTextHelper to handle this shape's text
225                 if( !pOutlinerParaObject )
226                 {
227                     // empty text -> use proxy edit source to delay creation of EditEngine
228                     ::std::auto_ptr<SvxEditSource> pEditSource( new AccessibleEmptyEditSource ( *pSdrObject, *pView, *pWindow) );
229                     mpText = new AccessibleTextHelper( pEditSource );
230                 }
231                 else
232                 {
233                     // non-empty text -> use full-fledged edit source right away
234                     ::std::auto_ptr<SvxEditSource> pEditSource( new SvxTextEditSource ( *pSdrObject, 0, *pView, *pWindow) );
235                     mpText = new AccessibleTextHelper( pEditSource );
236                 }
237 
238                 if( bOwnParaObj )
239                     delete pOutlinerParaObject;
240 
241                 mpText->SetEventSource(this);
242             }
243         }
244     }
245 }
246 
247 
248 
249 
250 void AccessibleShape::UpdateStates (void)
251 {
252     ::utl::AccessibleStateSetHelper* pStateSet =
253         static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
254     if (pStateSet == NULL)
255         return;
256 
257     // Set the opaque state for certain shape types when their fill style is
258     // solid.
259     bool bShapeIsOpaque = false;
260     switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
261     {
262         case DRAWING_PAGE:
263         case DRAWING_RECTANGLE:
264         case DRAWING_TEXT:
265         {
266             uno::Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY);
267             if (xSet.is())
268             {
269                 try
270                 {
271                     drawing::FillStyle aFillStyle;
272                     bShapeIsOpaque =  ( xSet->getPropertyValue (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillStyle"))) >>= aFillStyle)
273                                         && aFillStyle == drawing::FillStyle_SOLID;
274                 }
275                 catch (::com::sun::star::beans::UnknownPropertyException&)
276                 {
277                     // Ignore.
278                 }
279             }
280         }
281     }
282     if (bShapeIsOpaque)
283         pStateSet->AddState (AccessibleStateType::OPAQUE);
284     else
285         pStateSet->RemoveState (AccessibleStateType::OPAQUE);
286 
287     // Set the selected state.
288     bool bShapeIsSelected = false;
289     // XXX fix_me this has to be done with an extra interface later on
290     if ( m_pShape && maShapeTreeInfo.GetSdrView() )
291     {
292         bShapeIsSelected = maShapeTreeInfo.GetSdrView()->IsObjMarked(m_pShape) == sal_True;
293     }
294 
295     if (bShapeIsSelected)
296         pStateSet->AddState (AccessibleStateType::SELECTED);
297     else
298         pStateSet->RemoveState (AccessibleStateType::SELECTED);
299 }
300 //IAccessibility2 Implementation 2009-----
301     ::rtl::OUString AccessibleShape::GetStyle()
302     {
303         return ShapeTypeHandler::CreateAccessibleBaseName( mxShape );
304     }
305 
306 //-----IAccessibility2 Implementation 2009
307 bool AccessibleShape::operator== (const AccessibleShape& rShape)
308 {
309     return this==&rShape;
310 }
311 
312 
313 
314 
315 sal_Bool AccessibleShape::SetState (sal_Int16 aState)
316 {
317     sal_Bool bStateHasChanged = sal_False;
318 
319     if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
320     {
321         // Offer FOCUSED state to edit engine and detect whether the state
322         // changes.
323         sal_Bool bIsFocused = mpText->HaveFocus ();
324         mpText->SetFocus (sal_True);
325         bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
326     }
327     else
328         bStateHasChanged = AccessibleContextBase::SetState (aState);
329 
330     return bStateHasChanged;
331 }
332 
333 
334 
335 
336 sal_Bool AccessibleShape::ResetState (sal_Int16 aState)
337 {
338     sal_Bool bStateHasChanged = sal_False;
339 
340     if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
341     {
342         // Try to remove FOCUSED state from the edit engine and detect
343         // whether the state changes.
344         sal_Bool bIsFocused = mpText->HaveFocus ();
345         mpText->SetFocus (sal_False);
346         bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
347     }
348     else
349         bStateHasChanged = AccessibleContextBase::ResetState (aState);
350 
351     return bStateHasChanged;
352 }
353 
354 
355 
356 
357 sal_Bool AccessibleShape::GetState (sal_Int16 aState)
358 {
359     if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
360     {
361         // Just delegate the call to the edit engine.  The state is not
362         // merged into the state set.
363         return mpText->HaveFocus();
364     }
365     else
366         return AccessibleContextBase::GetState (aState);
367 }
368 //IAccessibility2 Implementation 2009-----
369 // Solution: OverWrite the parent's getAccessibleName method
370 ::rtl::OUString SAL_CALL AccessibleShape::getAccessibleName (void)
371     throw (::com::sun::star::uno::RuntimeException)
372 {
373         ThrowIfDisposed ();
374     if( m_pShape && m_pShape->GetTitle().Len() > 0)
375         return CreateAccessibleName() + ::rtl::OUString(' ') + m_pShape->GetTitle();
376     else
377         return CreateAccessibleName();
378 }
379 
380 ::rtl::OUString SAL_CALL AccessibleShape::getAccessibleDescription (void)
381     throw (::com::sun::star::uno::RuntimeException)
382 {
383         ThrowIfDisposed ();
384     if( m_pShape && m_pShape->GetDescription().Len() > 0)
385         return  m_pShape->GetDescription() ;
386     else
387         return OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
388 }
389 //-----IAccessibility2 Implementation 2009
390 //=====  XAccessibleContext  ==================================================
391 
392 /** The children of this shape come from two sources: The children from
393     group or scene shapes and the paragraphs of text.
394 */
395 sal_Int32 SAL_CALL
396     AccessibleShape::getAccessibleChildCount ()
397     throw (::com::sun::star::uno::RuntimeException)
398 {
399     ThrowIfDisposed ();
400     sal_Int32 nChildCount = 0;
401 
402     // Add the number of shapes that are children of this shape.
403     if (mpChildrenManager != NULL)
404         nChildCount += mpChildrenManager->GetChildCount ();
405     // Add the number text paragraphs.
406     if (mpText != NULL)
407         nChildCount += mpText->GetChildCount ();
408 
409     return nChildCount;
410 }
411 
412 
413 
414 
415 /** Forward the request to the shape.  Return the requested shape or throw
416     an exception for a wrong index.
417 */
418 uno::Reference<XAccessible> SAL_CALL
419     AccessibleShape::getAccessibleChild (sal_Int32 nIndex)
420     throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
421 {
422     ThrowIfDisposed ();
423 
424     uno::Reference<XAccessible> xChild;
425 
426     // Depending on the index decide whether to delegate this call to the
427     // children manager or the edit engine.
428     if ((mpChildrenManager != NULL)
429         && (nIndex < mpChildrenManager->GetChildCount()))
430     {
431         xChild = mpChildrenManager->GetChild (nIndex);
432     }
433     else if (mpText != NULL)
434     {
435         sal_Int32 nI = nIndex;
436         if (mpChildrenManager != NULL)
437             nI -= mpChildrenManager->GetChildCount();
438         xChild = mpText->GetChild (nI);
439     }
440     else
441         throw lang::IndexOutOfBoundsException (
442             ::rtl::OUString::createFromAscii ("shape has no child with index ")
443             + rtl::OUString::valueOf(nIndex),
444             static_cast<uno::XWeak*>(this));
445 
446     return xChild;
447 }
448 
449 //IAccessibility2 Implementation 2009-----
450 uno::Reference<XAccessibleRelationSet> SAL_CALL
451     AccessibleShape::getAccessibleRelationSet (void)
452         throw (::com::sun::star::uno::RuntimeException)
453 {
454     ::osl::MutexGuard aGuard (maMutex);
455     ::utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper;
456     uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
457     aSequence[0] = mpParent->GetAccessibleCaption(mxShape);
458 
459     //this mxshape is the captioned shape, only for sw
460     if(aSequence[0].get())
461     {
462         pRelationSet->AddRelation(
463             AccessibleRelation( AccessibleRelationType::DESCRIBED_BY, aSequence ) );
464     }
465 
466     if (pRelationSet != NULL)
467     {
468         return uno::Reference<XAccessibleRelationSet> (
469             new ::utl::AccessibleRelationSetHelper (*pRelationSet));
470     }
471     else
472     {
473         return uno::Reference<XAccessibleRelationSet>(NULL);
474     }
475 
476     return uno::Reference<XAccessibleRelationSet>();
477 }
478 //-----IAccessibility2 Implementation 2009
479 
480 /** Return a copy of the state set.
481     Possible states are:
482         ENABLED
483         SHOWING
484         VISIBLE
485 */
486 uno::Reference<XAccessibleStateSet> SAL_CALL
487     AccessibleShape::getAccessibleStateSet (void)
488     throw (::com::sun::star::uno::RuntimeException)
489 {
490     ::osl::MutexGuard aGuard (maMutex);
491     Reference<XAccessibleStateSet> xStateSet;
492 
493     if (rBHelper.bDisposed || mpText == NULL)
494         // Return a minimal state set that only contains the DEFUNC state.
495     //IAccessibility2 Implementation 2009-----
496     //xStateSet = AccessibleContextBase::getAccessibleStateSet ();
497     {
498         xStateSet = AccessibleContextBase::getAccessibleStateSet ();
499         ::utl::AccessibleStateSetHelper* pStateSet =
500               static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
501             ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent();
502             if( xTempAcc.is() )
503             {
504                 ::com::sun::star::uno::Reference<XAccessibleContext>
505                                         xTempAccContext = xTempAcc->getAccessibleContext();
506                 if( xTempAccContext.is() )
507                 {
508                     ::com::sun::star::uno::Reference<XAccessibleStateSet> rState =
509                         xTempAccContext->getAccessibleStateSet();
510                     if( rState.is() )           {
511                         com::sun::star::uno::Sequence<short> pStates = rState->getStates();
512                         int count = pStates.getLength();
513                         for( int iIndex = 0;iIndex < count;iIndex++ )
514                         {
515                             if( pStates[iIndex] == AccessibleStateType::EDITABLE )
516                             {
517                                 pStateSet->AddState (AccessibleStateType::EDITABLE);
518                                 pStateSet->AddState (AccessibleStateType::RESIZABLE);
519                                 pStateSet->AddState (AccessibleStateType::MOVEABLE);
520                                 break;
521                             }
522                         }
523                     }
524                 }
525             }
526             xStateSet = Reference<XAccessibleStateSet>(
527                 new ::utl::AccessibleStateSetHelper (*pStateSet));
528             //-----IAccessibility2 Implementation 2009
529     }else
530     {
531         ::utl::AccessibleStateSetHelper* pStateSet =
532               static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
533 
534         if (pStateSet != NULL)
535         {
536             // Merge current FOCUSED state from edit engine.
537             if (mpText != NULL)
538             {
539                 if (mpText->HaveFocus())
540                     pStateSet->AddState (AccessibleStateType::FOCUSED);
541                 else
542                     pStateSet->RemoveState (AccessibleStateType::FOCUSED);
543             }
544             //IAccessibility2 Implementation 2009-----
545             //Solution:Just when the document is not read-only,set states EDITABLE,RESIZABLE,MOVEABLE
546             ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent();
547             if( xTempAcc.is() )
548             {
549                 ::com::sun::star::uno::Reference<XAccessibleContext>
550                                         xTempAccContext = xTempAcc->getAccessibleContext();
551                 if( xTempAccContext.is() )
552                 {
553                     ::com::sun::star::uno::Reference<XAccessibleStateSet> rState =
554                         xTempAccContext->getAccessibleStateSet();
555                     if( rState.is() )           {
556                         com::sun::star::uno::Sequence<short> pStates = rState->getStates();
557                         int count = pStates.getLength();
558                         for( int iIndex = 0;iIndex < count;iIndex++ )
559                         {
560                             if( pStates[iIndex] == AccessibleStateType::EDITABLE )
561                             {
562                                 pStateSet->AddState (AccessibleStateType::EDITABLE);
563                                 pStateSet->AddState (AccessibleStateType::RESIZABLE);
564                                 pStateSet->AddState (AccessibleStateType::MOVEABLE);
565                                 break;
566                             }
567                         }
568                     }
569                 }
570             }
571             //-----IAccessibility2 Implementation 2009
572             // Create a copy of the state set that may be modified by the
573             // caller without affecting the current state set.
574             xStateSet = Reference<XAccessibleStateSet>(
575                 new ::utl::AccessibleStateSetHelper (*pStateSet));
576         }
577     }
578 //IAccessibility2 Implementation 2009-----
579     UpdateDocumentAllSelState(xStateSet);
580 //-----IAccessibility2 Implementation 2009
581     return xStateSet;
582 }
583 
584 
585 
586 
587 //=====  XAccessibleComponent  ================================================
588 
589 /** The implementation below is at the moment straightforward.  It iterates
590     over all children (and thereby instances all children which have not
591     been already instatiated) until a child covering the specifed point is
592     found.
593     This leaves room for improvement.  For instance, first iterate only over
594     the already instantiated children and only if no match is found
595     instantiate the remaining ones.
596 */
597 uno::Reference<XAccessible > SAL_CALL
598     AccessibleShape::getAccessibleAtPoint (
599         const awt::Point& aPoint)
600     throw (uno::RuntimeException)
601 {
602     ::osl::MutexGuard aGuard (maMutex);
603 
604     sal_Int32 nChildCount = getAccessibleChildCount ();
605     for (sal_Int32 i=0; i<nChildCount; ++i)
606     {
607         Reference<XAccessible> xChild (getAccessibleChild (i));
608         if (xChild.is())
609         {
610             Reference<XAccessibleComponent> xChildComponent (
611                 xChild->getAccessibleContext(), uno::UNO_QUERY);
612             if (xChildComponent.is())
613             {
614                 awt::Rectangle aBBox (xChildComponent->getBounds());
615                 if ( (aPoint.X >= aBBox.X)
616                     && (aPoint.Y >= aBBox.Y)
617                     && (aPoint.X < aBBox.X+aBBox.Width)
618                     && (aPoint.Y < aBBox.Y+aBBox.Height) )
619                     return xChild;
620             }
621         }
622     }
623 
624     // Have not found a child under the given point.  Returning empty
625     // reference to indicate this.
626     return uno::Reference<XAccessible>();
627 }
628 
629 
630 
631 
632 awt::Rectangle SAL_CALL AccessibleShape::getBounds (void)
633     throw (::com::sun::star::uno::RuntimeException)
634 {
635     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
636     ::osl::MutexGuard aGuard (maMutex);
637 
638     ThrowIfDisposed ();
639     awt::Rectangle aBoundingBox;
640     if ( mxShape.is() )
641     {
642 
643         static const OUString sBoundRectName (
644             RTL_CONSTASCII_USTRINGPARAM("BoundRect"));
645         static const OUString sAnchorPositionName (
646             RTL_CONSTASCII_USTRINGPARAM("AnchorPosition"));
647 
648         // Get the shape's bounding box in internal coordinates (in 100th of
649         // mm).  Use the property BoundRect.  Only if that is not supported ask
650         // the shape for its position and size directly.
651         Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY);
652         Reference<beans::XPropertySetInfo> xSetInfo;
653         bool bFoundBoundRect = false;
654         if (xSet.is())
655         {
656             xSetInfo = xSet->getPropertySetInfo ();
657             if (xSetInfo.is())
658             {
659                 if (xSetInfo->hasPropertyByName (sBoundRectName))
660                 {
661                     try
662                     {
663                         uno::Any aValue = xSet->getPropertyValue (sBoundRectName);
664                         aValue >>= aBoundingBox;
665                         bFoundBoundRect = true;
666                     }
667                     catch (beans::UnknownPropertyException e)
668                     {
669                         // Handled below (bFoundBoundRect stays false).
670                     }
671                 }
672                 else
673                     OSL_TRACE (" no property BoundRect");
674             }
675         }
676 
677         // Fallback when there is no BoundRect Property.
678         if ( ! bFoundBoundRect )
679         {
680             awt::Point aPosition (mxShape->getPosition());
681             awt::Size aSize (mxShape->getSize());
682             aBoundingBox = awt::Rectangle (
683                 aPosition.X, aPosition.Y,
684                 aSize.Width, aSize.Height);
685 
686             // While BoundRects have absolute positions, the position returned
687             // by XPosition::getPosition is relative.  Get the anchor position
688             // (usually not (0,0) for Writer shapes).
689             if (xSetInfo.is())
690             {
691                 if (xSetInfo->hasPropertyByName (sAnchorPositionName))
692                 {
693                     uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName);
694                     awt::Point aAnchorPosition;
695                     aPos >>= aAnchorPosition;
696                     aBoundingBox.X += aAnchorPosition.X;
697                     aBoundingBox.Y += aAnchorPosition.Y;
698                 }
699             }
700         }
701 
702         // Transform coordinates from internal to pixel.
703         if (maShapeTreeInfo.GetViewForwarder() == NULL)
704             throw uno::RuntimeException (::rtl::OUString (
705                 RTL_CONSTASCII_USTRINGPARAM(
706                     "AccessibleShape has no valid view forwarder")),
707                 static_cast<uno::XWeak*>(this));
708         ::Size aPixelSize = maShapeTreeInfo.GetViewForwarder()->LogicToPixel (
709             ::Size (aBoundingBox.Width, aBoundingBox.Height));
710         ::Point aPixelPosition = maShapeTreeInfo.GetViewForwarder()->LogicToPixel (
711             ::Point (aBoundingBox.X, aBoundingBox.Y));
712 
713         // Clip the shape's bounding box with the bounding box of its parent.
714         Reference<XAccessibleComponent> xParentComponent (
715             getAccessibleParent(), uno::UNO_QUERY);
716         if (xParentComponent.is())
717         {
718             // Make the coordinates relative to the parent.
719             awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
720             int x = aPixelPosition.getX() - aParentLocation.X;
721             int y = aPixelPosition.getY() - aParentLocation.Y;
722 
723             /*        //  The following block is a workarround for bug #99889# (property
724             //  BoundRect returnes coordinates relative to document window
725             //  instead of absolute coordinates for shapes in Writer).  Has to
726             //  be removed as soon as bug is fixed.
727 
728             // Use a non-null anchor position as flag that the shape is in a
729             // Writer document.
730             if (xSetInfo.is())
731                 if (xSetInfo->hasPropertyByName (sAnchorPositionName))
732                 {
733                     uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName);
734                     awt::Point aAnchorPosition;
735                     aPos >>= aAnchorPosition;
736                     if (aAnchorPosition.X > 0)
737                     {
738                         x = aPixelPosition.getX();
739                         y = aPixelPosition.getY();
740                     }
741                 }
742             //  End of workarround.
743             */
744             // Clip with parent (with coordinates relative to itself).
745             ::Rectangle aBBox (
746                 x, y, x + aPixelSize.getWidth(), y + aPixelSize.getHeight());
747             awt::Size aParentSize (xParentComponent->getSize());
748             ::Rectangle aParentBBox (0,0, aParentSize.Width, aParentSize.Height);
749             aBBox = aBBox.GetIntersection (aParentBBox);
750             aBoundingBox = awt::Rectangle (
751                 aBBox.getX(),
752                 aBBox.getY(),
753                 aBBox.getWidth(),
754                 aBBox.getHeight());
755         }
756         else
757         {
758             OSL_TRACE ("parent does not support component");
759             aBoundingBox = awt::Rectangle (
760                 aPixelPosition.getX(), aPixelPosition.getY(),
761                 aPixelSize.getWidth(), aPixelSize.getHeight());
762         }
763     }
764 
765     return aBoundingBox;
766 }
767 
768 
769 
770 
771 awt::Point SAL_CALL AccessibleShape::getLocation (void)
772     throw (::com::sun::star::uno::RuntimeException)
773 {
774     ThrowIfDisposed ();
775     awt::Rectangle aBoundingBox (getBounds());
776     return awt::Point (aBoundingBox.X, aBoundingBox.Y);
777 }
778 
779 
780 
781 
782 awt::Point SAL_CALL AccessibleShape::getLocationOnScreen (void)
783     throw (::com::sun::star::uno::RuntimeException)
784 {
785     ThrowIfDisposed ();
786 
787     // Get relative position...
788     awt::Point aLocation (getLocation ());
789 
790     // ... and add absolute position of the parent.
791     uno::Reference<XAccessibleComponent> xParentComponent (
792         getAccessibleParent(), uno::UNO_QUERY);
793     if (xParentComponent.is())
794     {
795         awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
796         aLocation.X += aParentLocation.X;
797         aLocation.Y += aParentLocation.Y;
798     }
799     else
800         OSL_TRACE ("getLocation: parent does not support XAccessibleComponent");
801     return aLocation;
802 }
803 
804 
805 
806 
807 awt::Size SAL_CALL AccessibleShape::getSize (void)
808     throw (uno::RuntimeException)
809 {
810     ThrowIfDisposed ();
811     awt::Rectangle aBoundingBox (getBounds());
812     return awt::Size (aBoundingBox.Width, aBoundingBox.Height);
813 }
814 
815 
816 
817 
818 sal_Int32 SAL_CALL AccessibleShape::getForeground (void)
819     throw (::com::sun::star::uno::RuntimeException)
820 {
821     ThrowIfDisposed ();
822     sal_Int32 nColor (0x0ffffffL);
823 
824     try
825     {
826         uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY);
827         if (aSet.is())
828         {
829             uno::Any aColor;
830             aColor = aSet->getPropertyValue (OUString::createFromAscii ("LineColor"));
831             aColor >>= nColor;
832         }
833     }
834     catch (::com::sun::star::beans::UnknownPropertyException)
835     {
836         // Ignore exception and return default color.
837     }
838     return nColor;
839 }
840 
841 
842 
843 
844 sal_Int32 SAL_CALL AccessibleShape::getBackground (void)
845     throw (::com::sun::star::uno::RuntimeException)
846 {
847     ThrowIfDisposed ();
848     sal_Int32 nColor (0L);
849 
850     try
851     {
852         uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY);
853         if (aSet.is())
854         {
855             uno::Any aColor;
856             aColor = aSet->getPropertyValue (OUString::createFromAscii ("FillColor"));
857             aColor >>= nColor;
858             //IAccessibility2 Implementation 2009-----
859             aColor = aSet->getPropertyValue (OUString::createFromAscii ("FillTransparence"));
860             short nTrans=0;
861             aColor >>= nTrans;
862             Color crBk(nColor);
863             if (nTrans == 0 )
864             {
865                 crBk.SetTransparency(0xff);
866             }
867             else
868             {
869                 nTrans = short(256 - nTrans / 100. * 256);
870                 crBk.SetTransparency(sal_uInt8(nTrans));
871             }
872             nColor = crBk.GetColor();
873             //-----IAccessibility2 Implementation 2009
874         }
875     }
876     catch (::com::sun::star::beans::UnknownPropertyException)
877     {
878         // Ignore exception and return default color.
879     }
880     return nColor;
881 }
882 
883 
884 
885 
886 //=====  XAccessibleEventBroadcaster  =========================================
887 
888 void SAL_CALL AccessibleShape::addEventListener (
889     const Reference<XAccessibleEventListener >& rxListener)
890     throw (uno::RuntimeException)
891 {
892     if (rBHelper.bDisposed || rBHelper.bInDispose)
893     {
894         uno::Reference<uno::XInterface> xThis (
895             (lang::XComponent *)this, uno::UNO_QUERY);
896         rxListener->disposing (lang::EventObject (xThis));
897     }
898     else
899     {
900         AccessibleContextBase::addEventListener (rxListener);
901         if (mpText != NULL)
902             mpText->AddEventListener (rxListener);
903     }
904 }
905 
906 
907 
908 
909 void SAL_CALL AccessibleShape::removeEventListener (
910     const Reference<XAccessibleEventListener >& rxListener)
911     throw (uno::RuntimeException)
912 {
913     AccessibleContextBase::removeEventListener (rxListener);
914     if (mpText != NULL)
915         mpText->RemoveEventListener (rxListener);
916 }
917 
918 
919 
920 
921 //=====  XInterface  ==========================================================
922 
923 com::sun::star::uno::Any SAL_CALL
924     AccessibleShape::queryInterface (const com::sun::star::uno::Type & rType)
925     throw (::com::sun::star::uno::RuntimeException)
926 {
927     ::com::sun::star::uno::Any aReturn = AccessibleContextBase::queryInterface (rType);
928     if ( ! aReturn.hasValue())
929         aReturn = ::cppu::queryInterface (rType,
930             static_cast<XAccessibleComponent*>(this),
931             static_cast<XAccessibleExtendedComponent*>(this),
932         //IAccessibility2 Implementation 2009-----
933             static_cast< ::com::sun::star::accessibility::XAccessibleSelection* >(this),
934 
935          static_cast< ::com::sun::star::accessibility::XAccessibleExtendedAttributes* >(this),
936          //-----IAccessibility2 Implementation 2009
937             static_cast<lang::XEventListener*>(this),
938             static_cast<document::XEventListener*>(this),
939             static_cast<lang::XUnoTunnel*>(this),
940     //IAccessibility2 Implementation 2009-----
941             static_cast<XAccessibleGroupPosition*>(this),
942             static_cast<XAccessibleHypertext*>(this)
943     //-----IAccessibility2 Implementation 2009
944             );
945     return aReturn;
946 }
947 
948 
949 
950 
951 void SAL_CALL
952     AccessibleShape::acquire (void)
953     throw ()
954 {
955     AccessibleContextBase::acquire ();
956 }
957 
958 
959 
960 
961 void SAL_CALL
962     AccessibleShape::release (void)
963     throw ()
964 {
965     AccessibleContextBase::release ();
966 }
967 //IAccessibility2 Implementation 2009-----
968 //
969 //=====  XAccessibleSelection  ============================================
970 //
971 
972 //--------------------------------------------------------------------------------
973 void SAL_CALL AccessibleShape::selectAccessibleChild( sal_Int32 )
974 throw ( IndexOutOfBoundsException, RuntimeException )
975 {
976 }
977 
978 //----------------------------------------------------------------------------------
979 sal_Bool SAL_CALL AccessibleShape::isAccessibleChildSelected( sal_Int32 nChildIndex )
980 throw ( IndexOutOfBoundsException,
981        RuntimeException )
982 {
983     uno::Reference<XAccessible> xAcc = getAccessibleChild( nChildIndex );
984     uno::Reference<XAccessibleContext> xContext;
985     if( xAcc.is() )
986     {
987         xContext = xAcc->getAccessibleContext();
988     }
989 
990     if( xContext.is() )
991     {
992         if( xContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
993         {
994             uno::Reference< ::com::sun::star::accessibility::XAccessibleText >
995                 xText(xAcc, uno::UNO_QUERY);
996             if( xText.is() )
997             {
998                 if( xText->getSelectionStart() >= 0 ) return sal_True;
999             }
1000         }
1001         else if( xContext->getAccessibleRole() == AccessibleRole::SHAPE )
1002         {
1003             Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet();
1004             if( !pRState.is() )
1005                 return sal_False;
1006 
1007             uno::Sequence<short> pStates = pRState->getStates();
1008             int nCount = pStates.getLength();
1009             for( int i = 0; i < nCount; i++ )
1010             {
1011                 if(pStates[i] == AccessibleStateType::SELECTED)
1012                     return sal_True;
1013             }
1014             return sal_False;
1015         }
1016     }
1017 
1018     return sal_False;
1019 }
1020 
1021 //---------------------------------------------------------------------
1022 void SAL_CALL AccessibleShape::clearAccessibleSelection(  )
1023 throw ( RuntimeException )
1024 {
1025 }
1026 
1027 //-------------------------------------------------------------------------
1028 void SAL_CALL AccessibleShape::selectAllAccessibleChildren(  )
1029 throw ( RuntimeException )
1030 {
1031 }
1032 
1033 //----------------------------------------------------------------------------
1034 sal_Int32 SAL_CALL AccessibleShape::getSelectedAccessibleChildCount()
1035 throw ( RuntimeException )
1036 {
1037     sal_Int32 nCount = 0;
1038     sal_Int32 TotalCount = getAccessibleChildCount();
1039     for( sal_Int32 i = 0; i < TotalCount; i++ )
1040         if( isAccessibleChildSelected(i) ) nCount++;
1041 
1042     return nCount;
1043 }
1044 
1045 //--------------------------------------------------------------------------------------
1046 Reference<XAccessible> SAL_CALL AccessibleShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
1047 throw ( IndexOutOfBoundsException, RuntimeException)
1048 {
1049     if ( nSelectedChildIndex > getSelectedAccessibleChildCount() )
1050         throw IndexOutOfBoundsException();
1051     sal_Int32 i1, i2;
1052     for( i1 = 0, i2 = 0; i1 < getAccessibleChildCount(); i1++ )
1053         if( isAccessibleChildSelected(i1) )
1054         {
1055             if( i2 == nSelectedChildIndex )
1056                 return getAccessibleChild( i1 );
1057             i2++;
1058         }
1059     return Reference<XAccessible>();
1060 }
1061 
1062 //----------------------------------------------------------------------------------
1063 void SAL_CALL AccessibleShape::deselectAccessibleChild( sal_Int32 )
1064                                                             throw ( IndexOutOfBoundsException,
1065                                                             RuntimeException )
1066 {
1067 
1068 }
1069 
1070 //=====  XAccessibleExtendedAttributes  ========================================================
1071 uno::Any SAL_CALL AccessibleShape::getExtendedAttributes()
1072         throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1073 {
1074     uno::Any strRet;
1075     ::rtl::OUString style;
1076     if( getAccessibleRole() != AccessibleRole::SHAPE ) return strRet;
1077     if( m_pShape )
1078     {
1079         //style = ::rtl::OUString::createFromAscii("style=");
1080         style = ::rtl::OUString::createFromAscii("style:");
1081         style += GetStyle();
1082     }
1083     style += ::rtl::OUString::createFromAscii(";");
1084     strRet <<= style;
1085     return strRet;
1086 }
1087 //-----IAccessibility2 Implementation 2009
1088 //=====  XServiceInfo  ========================================================
1089 
1090 ::rtl::OUString SAL_CALL
1091     AccessibleShape::getImplementationName (void)
1092     throw (::com::sun::star::uno::RuntimeException)
1093 {
1094     return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleShape"));
1095 }
1096 
1097 
1098 
1099 
1100 uno::Sequence<OUString> SAL_CALL
1101     AccessibleShape::getSupportedServiceNames (void)
1102     throw (::com::sun::star::uno::RuntimeException)
1103 {
1104     ThrowIfDisposed ();
1105     // Get list of supported service names from base class...
1106     uno::Sequence<OUString> aServiceNames =
1107         AccessibleContextBase::getSupportedServiceNames();
1108     sal_Int32 nCount (aServiceNames.getLength());
1109 
1110     // ...and add additional names.
1111     aServiceNames.realloc (nCount + 1);
1112     static const OUString sAdditionalServiceName (RTL_CONSTASCII_USTRINGPARAM(
1113         "com.sun.star.drawing.AccessibleShape"));
1114     aServiceNames[nCount] = sAdditionalServiceName;
1115 
1116     return aServiceNames;
1117 }
1118 
1119 
1120 
1121 
1122 
1123 //=====  XTypeProvider  ===================================================
1124 
1125 uno::Sequence<uno::Type> SAL_CALL
1126     AccessibleShape::getTypes (void)
1127     throw (uno::RuntimeException)
1128 {
1129     ThrowIfDisposed ();
1130     // Get list of types from the context base implementation, ...
1131     uno::Sequence<uno::Type> aTypeList (AccessibleContextBase::getTypes());
1132     // ... get list of types from component base implementation, ...
1133     uno::Sequence<uno::Type> aComponentTypeList (AccessibleComponentBase::getTypes());
1134     // ... define local types, ...
1135     const uno::Type aLangEventListenerType =
1136         ::getCppuType((const uno::Reference<lang::XEventListener>*)0);
1137     const uno::Type aDocumentEventListenerType =
1138         ::getCppuType((const uno::Reference<document::XEventListener>*)0);
1139     const uno::Type aUnoTunnelType =
1140         ::getCppuType((const uno::Reference<lang::XUnoTunnel>*)0);
1141     //    const uno::Type aStateSetType =
1142     //      ::getCppuType((const uno::Reference<XAccessibleStateSet>*)0);
1143 
1144     // ... and merge them all into one list.
1145     sal_Int32   nTypeCount (aTypeList.getLength()),
1146         nComponentTypeCount (aComponentTypeList.getLength());
1147     int         i;
1148 
1149     aTypeList.realloc (nTypeCount + nComponentTypeCount + 3);
1150 
1151     for (i=0; i<nComponentTypeCount; i++)
1152         aTypeList[nTypeCount + i] = aComponentTypeList[i];
1153 
1154     aTypeList[nTypeCount + i++ ] = aLangEventListenerType;
1155     aTypeList[nTypeCount + i++ ] = aDocumentEventListenerType;
1156     aTypeList[nTypeCount + i ] = aUnoTunnelType;
1157 
1158     return aTypeList;
1159 }
1160 
1161 
1162 
1163 
1164 //=====  lang::XEventListener  ================================================
1165 
1166 /** Disposing calls are accepted only from the model: Just reset the
1167     reference to the model in the shape tree info.  Otherwise this object
1168     remains functional.
1169 */
1170 void SAL_CALL
1171     AccessibleShape::disposing (const lang::EventObject& aEvent)
1172     throw (uno::RuntimeException)
1173 {
1174     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
1175     ::osl::MutexGuard aGuard (maMutex);
1176 
1177     try
1178     {
1179         if (aEvent.Source ==  maShapeTreeInfo.GetModelBroadcaster())
1180         {
1181             // Remove reference to model broadcaster to allow it to pass
1182             // away.
1183             maShapeTreeInfo.SetModelBroadcaster(NULL);
1184         }
1185 
1186     }
1187     catch (uno::RuntimeException e)
1188     {
1189         OSL_TRACE ("caught exception while disposing");
1190     }
1191 }
1192 
1193 
1194 
1195 
1196 //=====  document::XEventListener  ============================================
1197 
1198 void SAL_CALL
1199     AccessibleShape::notifyEvent (const document::EventObject& rEventObject)
1200     throw (uno::RuntimeException)
1201 {
1202     static const OUString sShapeModified (
1203         RTL_CONSTASCII_USTRINGPARAM("ShapeModified"));
1204 
1205     // First check if the event is for us.
1206     uno::Reference<drawing::XShape> xShape (
1207         rEventObject.Source, uno::UNO_QUERY);
1208     if ( xShape.get() == mxShape.get() )
1209     {
1210         if (rEventObject.EventName.equals (sShapeModified))
1211         {
1212             //Need to update text children when receiving ShapeModified hint when exiting edit mode for text box
1213             if (mpText)
1214                 mpText->UpdateChildren();
1215 
1216 
1217             // Some property of a shape has been modified.  Send an event
1218             // that indicates a change of the visible data to all listeners.
1219             CommitChange (
1220                 AccessibleEventId::VISIBLE_DATA_CHANGED,
1221                 uno::Any(),
1222                 uno::Any());
1223 
1224             // Name and Description may have changed.  Update the local
1225             // values accordingly.
1226             UpdateNameAndDescription();
1227         }
1228     }
1229 }
1230 
1231 
1232 
1233 
1234 //=====  lang::XUnoTunnel  ================================================
1235 
1236 const uno::Sequence< sal_Int8 >&
1237     AccessibleShape::getUnoTunnelImplementationId()
1238     throw()
1239 {
1240     static uno::Sequence< sal_Int8 >* pSeq = 0;
1241 
1242     if( !pSeq )
1243     {
1244         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
1245 
1246         if( !pSeq )
1247         {
1248             static uno::Sequence< sal_Int8 > aSeq( 16 );
1249             rtl_createUuid( (sal_uInt8*) aSeq.getArray(), 0, sal_True );
1250             pSeq = &aSeq;
1251         }
1252     }
1253 
1254     return( *pSeq );
1255 }
1256 
1257 //------------------------------------------------------------------------------
1258 AccessibleShape*
1259     AccessibleShape::getImplementation( const uno::Reference< uno::XInterface >& rxIFace )
1260     throw()
1261 {
1262     uno::Reference< lang::XUnoTunnel >  xTunnel( rxIFace, uno::UNO_QUERY );
1263     AccessibleShape*                    pReturn = NULL;
1264 
1265     if( xTunnel.is() )
1266         pReturn = reinterpret_cast< AccessibleShape* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) );
1267 
1268     return( pReturn );
1269 }
1270 
1271 //------------------------------------------------------------------------------
1272 sal_Int64 SAL_CALL
1273     AccessibleShape::getSomething( const uno::Sequence< sal_Int8 >& rIdentifier )
1274     throw(uno::RuntimeException)
1275 {
1276     sal_Int64 nReturn( 0 );
1277 
1278     if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) )
1279         nReturn = reinterpret_cast< sal_Int64 >( this );
1280 
1281     return( nReturn );
1282 }
1283 
1284 //=====  IAccessibleViewForwarderListener  ====================================
1285 
1286 void AccessibleShape::ViewForwarderChanged (ChangeType aChangeType,
1287         const IAccessibleViewForwarder* pViewForwarder)
1288 {
1289     // Inform all listeners that the graphical representation (i.e. size
1290     // and/or position) of the shape has changed.
1291     CommitChange (AccessibleEventId::VISIBLE_DATA_CHANGED,
1292         uno::Any(),
1293         uno::Any());
1294 
1295     // Tell children manager of the modified view forwarder.
1296     if (mpChildrenManager != NULL)
1297         mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder);
1298 
1299     // update our children that our screen position might have changed
1300     if( mpText )
1301         mpText->UpdateChildren();
1302 }
1303 
1304 
1305 
1306 
1307 //=====  protected internal  ==================================================
1308 /// Set this object's name if is different to the current name.
1309 ::rtl::OUString
1310     AccessibleShape::CreateAccessibleBaseName (void)
1311     throw (::com::sun::star::uno::RuntimeException)
1312 {
1313     return ShapeTypeHandler::CreateAccessibleBaseName( mxShape );
1314 }
1315 
1316 
1317 ::rtl::OUString
1318     AccessibleShape::CreateAccessibleName (void)
1319     throw (::com::sun::star::uno::RuntimeException)
1320 {
1321     //OUString sName (CreateAccessibleBaseName());
1322 //IAccessibility2 Implementation 2009-----
1323     OUString sName;
1324     sName = GetFullAccessibleName(this);
1325     return sName;
1326 }
1327 
1328 ::rtl::OUString
1329     AccessibleShape::GetFullAccessibleName (AccessibleShape *shape)
1330     throw (::com::sun::star::uno::RuntimeException)
1331 {
1332     OUString sName (shape->CreateAccessibleBaseName());
1333     // Append the shape's index to the name to disambiguate between shapes
1334     // of the same type.  If such an index where not given to the
1335     // constructor then use the z-order instead.  If even that does not exist
1336     // we throw an exception.
1337     //long nIndex = mnIndex;
1338     //if (nIndex == -1)
1339     //{
1340     //    try
1341     //    {
1342     //        uno::Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY);
1343     //        if (xSet.is())
1344     //        {
1345     //            uno::Any aZOrder (xSet->getPropertyValue (::rtl::OUString::createFromAscii ("ZOrder")));
1346     //            aZOrder >>= nIndex;
1347 
1348     //            // Add one to be not zero based.
1349     //            nIndex += 1;
1350     //        }
1351     //    }
1352     //    catch (beans::UnknownPropertyException)
1353     //    {
1354     //        // We throw our own exception that is a bit more informative.
1355     //        throw uno::RuntimeException (::rtl::OUString (
1356     //            RTL_CONSTASCII_USTRINGPARAM("AccessibleShape has invalid index and no ZOrder property")),
1357     //            static_cast<uno::XWeak*>(this));
1358     //    }
1359 
1360     //}
1361 
1362     //// Put a space between name and index because of Gnopernicus othewise
1363     //// spells the name.
1364     //sName += OUString (RTL_CONSTASCII_USTRINGPARAM(" ")) + OUString::valueOf (nIndex);
1365 
1366     //return sName;
1367 
1368     XubString nameStr;
1369     if(shape->m_pShape)
1370         nameStr = shape->m_pShape->GetName();
1371     if(nameStr.Len() == 0)
1372     {
1373         sName +=  OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
1374     }
1375     else
1376     {
1377         sName = nameStr;
1378     }
1379     /*
1380     sal_Int32 nChildCount = shape->getAccessibleChildCount();
1381     if(nChildCount > 0)
1382       {
1383         for (sal_Int32 i=0; i<nChildCount; ++i)
1384         {
1385             Reference<XAccessible> xChild (shape->getAccessibleChild (i));
1386             if (xChild.is())
1387             {
1388             uno::Reference <XAccessibleContext> xChildContext(xChild->getAccessibleContext());
1389             if (xChildContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
1390             {
1391                 uno::Reference<XAccessibleText> xText = uno::Reference<XAccessibleText> ( xChild, uno::UNO_QUERY );
1392                 sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )) + xText->getText();
1393             }
1394             else if (xChildContext->getAccessibleRole() == AccessibleRole::SHAPE)
1395             {
1396                 sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )) + GetFullAccessibleName(static_cast< AccessibleShape*>( xChild.get()));
1397             }
1398             }
1399         }
1400       }
1401      */
1402     //Solution:If the new produced name if not the same with last,notify name changed
1403     //         Event
1404     if( aAccName != sName && aAccName.getLength() != 0 )
1405     {
1406         uno::Any aOldValue, aNewValue;
1407         aOldValue <<= aAccName;
1408         aNewValue <<= sName;
1409         CommitChange(
1410             AccessibleEventId::NAME_CHANGED,
1411             aNewValue,
1412             aOldValue);
1413     }
1414     aAccName = sName;
1415     return sName;
1416 }
1417 //-----IAccessibility2 Implementation 2009
1418 ::rtl::OUString
1419     AccessibleShape::CreateAccessibleDescription (void)
1420     throw (::com::sun::star::uno::RuntimeException)
1421 {
1422     DescriptionGenerator aDG (mxShape);
1423     aDG.Initialize (CreateAccessibleBaseName());
1424     switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
1425     {
1426         case DRAWING_3D_CUBE:
1427         case DRAWING_3D_EXTRUDE:
1428         case DRAWING_3D_LATHE:
1429         case DRAWING_3D_SPHERE:
1430             aDG.Add3DProperties ();
1431             break;
1432 
1433         case DRAWING_3D_SCENE:
1434         case DRAWING_GROUP:
1435         case DRAWING_PAGE:
1436             // No further information is appended.
1437             break;
1438 
1439         case DRAWING_CAPTION:
1440         case DRAWING_CLOSED_BEZIER:
1441         case DRAWING_CLOSED_FREEHAND:
1442         case DRAWING_ELLIPSE:
1443         case DRAWING_POLY_POLYGON:
1444         case DRAWING_POLY_POLYGON_PATH:
1445         case DRAWING_RECTANGLE:
1446             aDG.AddLineProperties ();
1447             aDG.AddFillProperties ();
1448             break;
1449 
1450         case DRAWING_CONNECTOR:
1451         case DRAWING_LINE:
1452         case DRAWING_MEASURE:
1453         case DRAWING_OPEN_BEZIER:
1454         case DRAWING_OPEN_FREEHAND:
1455         case DRAWING_POLY_LINE:
1456         case DRAWING_POLY_LINE_PATH:
1457             aDG.AddLineProperties ();
1458             break;
1459 
1460         case DRAWING_CONTROL:
1461             aDG.AddProperty (OUString::createFromAscii ("ControlBackground"),
1462                 DescriptionGenerator::COLOR,
1463                 OUString());
1464             aDG.AddProperty (OUString::createFromAscii ("ControlBorder"),
1465                 DescriptionGenerator::INTEGER,
1466                 OUString());
1467             break;
1468 
1469         case DRAWING_TEXT:
1470             aDG.AddTextProperties ();
1471             break;
1472 
1473         default:
1474             aDG.Initialize (::rtl::OUString (
1475                                 RTL_CONSTASCII_USTRINGPARAM("Unknown accessible shape")));
1476             uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY);
1477             if (xDescriptor.is())
1478             {
1479                 aDG.AppendString (::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("service name=")));
1480                 aDG.AppendString (xDescriptor->getShapeType());
1481             }
1482     }
1483 
1484     return aDG();
1485 }
1486 
1487 
1488 
1489 
1490 uno::Reference< drawing::XShape > AccessibleShape::GetXShape()
1491 {
1492     return( mxShape );
1493 }
1494 
1495 
1496 
1497 // protected
1498 void AccessibleShape::disposing (void)
1499 {
1500     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
1501     ::osl::MutexGuard aGuard (maMutex);
1502 
1503     // Make sure to send an event that this object looses the focus in the
1504     // case that it has the focus.
1505     ::utl::AccessibleStateSetHelper* pStateSet =
1506           static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
1507     if (pStateSet != NULL)
1508         pStateSet->RemoveState (AccessibleStateType::FOCUSED);
1509 
1510     // Unregister from broadcasters.
1511     Reference<lang::XComponent> xComponent (mxShape, uno::UNO_QUERY);
1512     if (xComponent.is())
1513         xComponent->removeEventListener (this);
1514 
1515     // Unregister from model.
1516     if (maShapeTreeInfo.GetModelBroadcaster().is())
1517         maShapeTreeInfo.GetModelBroadcaster()->removeEventListener (
1518             static_cast<document::XEventListener*>(this));
1519 
1520     // Release the child containers.
1521     if (mpChildrenManager != NULL)
1522     {
1523         delete mpChildrenManager;
1524         mpChildrenManager = NULL;
1525     }
1526     if (mpText != NULL)
1527     {
1528         mpText->Dispose();
1529         delete mpText;
1530         mpText = NULL;
1531     }
1532 
1533     // Cleanup.  Remove references to objects to allow them to be
1534     // destroyed.
1535     mxShape = NULL;
1536     maShapeTreeInfo = AccessibleShapeTreeInfo();
1537 
1538     // Call base classes.
1539     AccessibleContextBase::dispose ();
1540 }
1541 
1542 sal_Int32 SAL_CALL
1543     AccessibleShape::getAccessibleIndexInParent (void)
1544     throw (::com::sun::star::uno::RuntimeException)
1545 {
1546     ThrowIfDisposed ();
1547     //  Use a simple but slow solution for now.  Optimize later.
1548 
1549     sal_Int32 nIndex = m_nIndexInParent;
1550     if ( -1 == nIndex )
1551         nIndex = AccessibleContextBase::getAccessibleIndexInParent();
1552     return nIndex;
1553 }
1554 
1555 
1556 
1557 
1558 void AccessibleShape::UpdateNameAndDescription (void)
1559 {
1560     // Ignore missing title, name, or description.  There are fallbacks for
1561     // them.
1562     try
1563     {
1564         Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY_THROW);
1565         OUString sString;
1566 
1567         // Get the accessible name.
1568         sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Title")));
1569         if (sString.getLength() > 0)
1570         {
1571             SetAccessibleName(sString, AccessibleContextBase::FromShape);
1572         }
1573         else
1574         {
1575             sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Name")));
1576             if (sString.getLength() > 0)
1577                 SetAccessibleName(sString, AccessibleContextBase::FromShape);
1578         }
1579 
1580         // Get the accessible description.
1581         sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Description")));
1582         if (sString.getLength() > 0)
1583             SetAccessibleDescription(sString, AccessibleContextBase::FromShape);
1584     }
1585     catch (uno::RuntimeException&)
1586     {
1587     }
1588 }
1589 //IAccessibility2 Implementation 2009-----
1590 //  Return this object's role.
1591 sal_Int16 SAL_CALL AccessibleShape::getAccessibleRole (void)
1592         throw (::com::sun::star::uno::RuntimeException)
1593 {
1594     sal_Int16 nAccessibleRole =  AccessibleRole::SHAPE ;
1595     switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
1596     {
1597         case     DRAWING_GRAPHIC_OBJECT:
1598                  nAccessibleRole =  AccessibleRole::GRAPHIC ;               break;
1599         case     DRAWING_OLE:
1600                  nAccessibleRole =  AccessibleRole::EMBEDDED_OBJECT ;       break;
1601 
1602         default:
1603             nAccessibleRole = AccessibleContextBase::getAccessibleRole();
1604             break;
1605     }
1606 
1607     return nAccessibleRole;
1608 }
1609 
1610 
1611 void AccessibleShape::UpdateDocumentAllSelState(Reference<XAccessibleStateSet> &xStateSet)
1612 {
1613     if (mpParent && mpParent->IsDocumentSelAll())
1614     {
1615         ::utl::AccessibleStateSetHelper* pStateSet =
1616             static_cast< ::utl::AccessibleStateSetHelper*>(xStateSet.get());
1617         pStateSet->AddState (AccessibleStateType::SELECTED);
1618 
1619         //uno::Any NewValue;
1620         //NewValue <<= AccessibleStateType::SELECTED;
1621 
1622         //CommitChange(AccessibleEventId::STATE_CHANGED,NewValue,uno::Any());
1623     }
1624 }
1625 
1626 //sort the drawing objects from up to down, from left to right
1627 struct XShapePosCompareHelper
1628 {
1629     bool operator() ( const uno::Reference<drawing::XShape>& xshape1,
1630         const uno::Reference<drawing::XShape>& xshape2 ) const
1631     {
1632         SdrObject* pObj1 = GetSdrObjectFromXShape(xshape1);
1633         SdrObject* pObj2 = GetSdrObjectFromXShape(xshape2);
1634         if(pObj1 && pObj2)
1635             return pObj1->GetOrdNum() < pObj2->GetOrdNum();
1636         else
1637             return 0;
1638     }
1639 };
1640 //end of group position
1641 
1642 //=====  XAccessibleGroupPosition  =========================================
1643 uno::Sequence< sal_Int32 > SAL_CALL
1644 AccessibleShape::getGroupPosition( const uno::Any& )
1645 throw (uno::RuntimeException)
1646 {
1647     // we will return the:
1648     // [0] group level
1649     // [1] similar items counts in the group
1650     // [2] the position of the object in the group
1651     uno::Sequence< sal_Int32 > aRet( 3 );
1652     aRet[0] = 0;
1653     aRet[1] = 0;
1654     aRet[2] = 0;
1655 
1656     ::com::sun::star::uno::Reference<XAccessible> xParent = getAccessibleParent();
1657     if (!xParent.is())
1658     {
1659         return aRet;
1660     }
1661     SdrObject *pObj = GetSdrObjectFromXShape(mxShape);
1662 
1663 
1664     if(pObj == NULL )
1665     {
1666         return aRet;
1667     }
1668 
1669     // Compute object's group level.
1670     sal_Int32 nGroupLevel = 0;
1671     SdrObject * pUper = pObj->GetUpGroup();
1672     while( pUper )
1673     {
1674         ++nGroupLevel;
1675         pUper = pUper->GetUpGroup();
1676     }
1677 
1678     ::com::sun::star::uno::Reference<XAccessibleContext> xParentContext = xParent->getAccessibleContext();
1679     if( xParentContext->getAccessibleRole()  == AccessibleRole::DOCUMENT)//Document
1680     {
1681         Reference< XAccessibleGroupPosition > xGroupPosition( xParent,uno::UNO_QUERY );
1682         if ( xGroupPosition.is() )
1683         {
1684             aRet = xGroupPosition->getGroupPosition( uno::makeAny( getAccessibleContext() ) );
1685         }
1686         return aRet;
1687     }
1688     if (xParentContext->getAccessibleRole() != AccessibleRole::SHAPE)
1689     {
1690         return aRet;
1691     }
1692 
1693     SdrObjList *pGrpList = NULL;
1694     if( pObj->GetUpGroup() )
1695         pGrpList = pObj->GetUpGroup()->GetSubList();
1696     else
1697         return aRet;
1698 
1699     std::vector< uno::Reference<drawing::XShape> > vXShapes;
1700     if (pGrpList)
1701     {
1702         const sal_Int32 nObj = pGrpList->GetObjCount();
1703         for(sal_Int32 i = 0 ; i < nObj ; ++i)
1704         {
1705             SdrObject *pSubObj = pGrpList->GetObj(i);
1706             //IAccessibility2 Implementation 2009-----
1707             if (pSubObj &&
1708                 xParentContext->getAccessibleChild(i)->getAccessibleContext()->getAccessibleRole() != AccessibleRole::GROUP_BOX)
1709             //-----IAccessibility2 Implementation 2009
1710             {
1711                 vXShapes.push_back( GetXShapeForSdrObject(pSubObj) );
1712             }
1713         }
1714     }
1715 
1716     std::sort( vXShapes.begin(), vXShapes.end(), XShapePosCompareHelper() );
1717 
1718     //get the the index of the selected object in the group
1719     std::vector< uno::Reference<drawing::XShape> >::iterator aIter;
1720     //we start counting position from 1
1721     sal_Int32 nPos = 1;
1722     for ( aIter = vXShapes.begin(); aIter != vXShapes.end(); aIter++, nPos++ )
1723     {
1724         if ( (*aIter).get() == mxShape.get() )
1725         {
1726             sal_Int32* pArray = aRet.getArray();
1727             pArray[0] = nGroupLevel;
1728             pArray[1] = vXShapes.size();
1729             pArray[2] = nPos;
1730             break;
1731         }
1732     }
1733 
1734     return aRet;
1735 }
1736 
1737 ::rtl::OUString AccessibleShape::getObjectLink( const uno::Any& )
1738     throw (uno::RuntimeException)
1739 {
1740     ::rtl::OUString aRet;
1741 
1742     SdrObject *pObj = GetSdrObjectFromXShape(mxShape);
1743     if(pObj == NULL )
1744     {
1745         return aRet;
1746     }
1747     if (maShapeTreeInfo.GetDocumentWindow().is())
1748     {
1749         Reference< XAccessibleGroupPosition > xGroupPosition( maShapeTreeInfo.GetDocumentWindow(), uno::UNO_QUERY );
1750         if (xGroupPosition.is())
1751         {
1752             aRet = xGroupPosition->getObjectLink( uno::makeAny( getAccessibleContext() ) );
1753         }
1754     }
1755     return aRet;
1756 }
1757 
1758 //=====  XAccesibleHypertext  ==================================================
1759 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkCount()
1760     throw (::com::sun::star::uno::RuntimeException)
1761 {
1762     // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile.
1763     // Code need to be adapted....
1764     return 0;
1765 
1766     /*
1767     SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this);
1768     if (pLink->IsValidHyperlink())
1769         return 1;
1770     else
1771         return 0;
1772     */
1773 }
1774 uno::Reference< XAccessibleHyperlink > SAL_CALL
1775     AccessibleShape::getHyperLink( sal_Int32 )
1776     throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1777 {
1778     uno::Reference< XAccessibleHyperlink > xRet;
1779     // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile.
1780     // Code need to be adapted....
1781     /*
1782     SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this);
1783     if (pLink->IsValidHyperlink())
1784         xRet = pLink;
1785     if( !xRet.is() )
1786         throw ::com::sun::star::lang::IndexOutOfBoundsException();
1787     */
1788     return xRet;
1789 }
1790 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkIndex( sal_Int32 )
1791 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1792 {
1793     sal_Int32 nRet = 0;
1794     return nRet;
1795 }
1796 //=====  XAccesibleText  ==================================================
1797 sal_Int32 SAL_CALL AccessibleShape::getCaretPosition(  ) throw (::com::sun::star::uno::RuntimeException){return 0;}
1798 sal_Bool SAL_CALL AccessibleShape::setCaretPosition( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;}
1799 sal_Unicode SAL_CALL AccessibleShape::getCharacter( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;}
1800 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleShape::getCharacterAttributes( sal_Int32, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1801 {
1802     uno::Sequence< ::com::sun::star::beans::PropertyValue > aValues(0);
1803     return aValues;
1804 }
1805 ::com::sun::star::awt::Rectangle SAL_CALL AccessibleShape::getCharacterBounds( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1806 {
1807     return com::sun::star::awt::Rectangle(0, 0, 0, 0 );
1808 }
1809 sal_Int32 SAL_CALL AccessibleShape::getCharacterCount(  ) throw (::com::sun::star::uno::RuntimeException){return 0;}
1810 sal_Int32 SAL_CALL AccessibleShape::getIndexAtPoint( const ::com::sun::star::awt::Point& ) throw (::com::sun::star::uno::RuntimeException){return 0;}
1811 ::rtl::OUString SAL_CALL AccessibleShape::getSelectedText(  ) throw (::com::sun::star::uno::RuntimeException){return OUString();}
1812 sal_Int32 SAL_CALL AccessibleShape::getSelectionStart(  ) throw (::com::sun::star::uno::RuntimeException){return 0;}
1813 sal_Int32 SAL_CALL AccessibleShape::getSelectionEnd(  ) throw (::com::sun::star::uno::RuntimeException){return 0;}
1814 sal_Bool SAL_CALL AccessibleShape::setSelection( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;}
1815 ::rtl::OUString SAL_CALL AccessibleShape::getText(  ) throw (::com::sun::star::uno::RuntimeException){return OUString();}
1816 ::rtl::OUString SAL_CALL AccessibleShape::getTextRange( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return OUString();}
1817 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleShape::getTextAtIndex( sal_Int32, sal_Int16 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1818 {
1819     ::com::sun::star::accessibility::TextSegment aResult;
1820     return aResult;
1821 }
1822 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleShape::getTextBeforeIndex( sal_Int32, sal_Int16 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1823 {
1824     ::com::sun::star::accessibility::TextSegment aResult;
1825     return aResult;
1826 }
1827 ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleShape::getTextBehindIndex( sal_Int32, sal_Int16 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1828 {
1829     ::com::sun::star::accessibility::TextSegment aResult;
1830     return aResult;
1831 }
1832 sal_Bool SAL_CALL AccessibleShape::copyText( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;}
1833 
1834 //-----IAccessibility2 Implementation 2009
1835 } // end of namespace accessibility
1836