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