xref: /trunk/main/svx/source/accessibility/AccessibleShape.cxx (revision 7f80ef068fa6a941ed7fbb70f09acae371a498e0)
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     {
478         xStateSet = AccessibleContextBase::getAccessibleStateSet ();
479         ::utl::AccessibleStateSetHelper* pStateSet =
480               static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
481             ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent();
482             if( xTempAcc.is() )
483             {
484                 ::com::sun::star::uno::Reference<XAccessibleContext>
485                                         xTempAccContext = xTempAcc->getAccessibleContext();
486                 if( xTempAccContext.is() )
487                 {
488                     ::com::sun::star::uno::Reference<XAccessibleStateSet> rState =
489                         xTempAccContext->getAccessibleStateSet();
490                     if( rState.is() )           {
491                         com::sun::star::uno::Sequence<short> pStates = rState->getStates();
492                         int count = pStates.getLength();
493                         for( int iIndex = 0;iIndex < count;iIndex++ )
494                         {
495                             if( pStates[iIndex] == AccessibleStateType::EDITABLE )
496                             {
497                                 pStateSet->AddState (AccessibleStateType::EDITABLE);
498                                 pStateSet->AddState (AccessibleStateType::RESIZABLE);
499                                 pStateSet->AddState (AccessibleStateType::MOVEABLE);
500                                 break;
501                             }
502                         }
503                     }
504                 }
505             }
506             xStateSet = Reference<XAccessibleStateSet>(
507                 new ::utl::AccessibleStateSetHelper (*pStateSet));
508     }else
509     {
510         ::utl::AccessibleStateSetHelper* pStateSet =
511               static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
512 
513         if (pStateSet != NULL)
514         {
515             // Merge current FOCUSED state from edit engine.
516             if (mpText != NULL)
517             {
518                 if (mpText->HaveFocus())
519                     pStateSet->AddState (AccessibleStateType::FOCUSED);
520                 else
521                     pStateSet->RemoveState (AccessibleStateType::FOCUSED);
522             }
523             //Solution:Just when the document is not read-only,set states EDITABLE,RESIZABLE,MOVEABLE
524             ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent();
525             if( xTempAcc.is() )
526             {
527                 ::com::sun::star::uno::Reference<XAccessibleContext>
528                                         xTempAccContext = xTempAcc->getAccessibleContext();
529                 if( xTempAccContext.is() )
530                 {
531                     ::com::sun::star::uno::Reference<XAccessibleStateSet> rState =
532                         xTempAccContext->getAccessibleStateSet();
533                     if( rState.is() )           {
534                         com::sun::star::uno::Sequence<short> pStates = rState->getStates();
535                         int count = pStates.getLength();
536                         for( int iIndex = 0;iIndex < count;iIndex++ )
537                         {
538                             if( pStates[iIndex] == AccessibleStateType::EDITABLE )
539                             {
540                                 pStateSet->AddState (AccessibleStateType::EDITABLE);
541                                 pStateSet->AddState (AccessibleStateType::RESIZABLE);
542                                 pStateSet->AddState (AccessibleStateType::MOVEABLE);
543                                 break;
544                             }
545                         }
546                     }
547                 }
548             }
549             // Create a copy of the state set that may be modified by the
550             // caller without affecting the current state set.
551             xStateSet = Reference<XAccessibleStateSet>(
552                 new ::utl::AccessibleStateSetHelper (*pStateSet));
553         }
554     }
555     UpdateDocumentAllSelState(xStateSet);
556     return xStateSet;
557 }
558 
559 
560 
561 
562 //=====  XAccessibleComponent  ================================================
563 
564 /** The implementation below is at the moment straightforward.  It iterates
565     over all children (and thereby instances all children which have not
566     been already instatiated) until a child covering the specifed point is
567     found.
568     This leaves room for improvement.  For instance, first iterate only over
569     the already instantiated children and only if no match is found
570     instantiate the remaining ones.
571 */
572 uno::Reference<XAccessible > SAL_CALL
573     AccessibleShape::getAccessibleAtPoint (
574         const awt::Point& aPoint)
575     throw (uno::RuntimeException)
576 {
577     ::osl::MutexGuard aGuard (maMutex);
578 
579     sal_Int32 nChildCount = getAccessibleChildCount ();
580     for (sal_Int32 i=0; i<nChildCount; ++i)
581     {
582         Reference<XAccessible> xChild (getAccessibleChild (i));
583         if (xChild.is())
584         {
585             Reference<XAccessibleComponent> xChildComponent (
586                 xChild->getAccessibleContext(), uno::UNO_QUERY);
587             if (xChildComponent.is())
588             {
589                 awt::Rectangle aBBox (xChildComponent->getBounds());
590                 if ( (aPoint.X >= aBBox.X)
591                     && (aPoint.Y >= aBBox.Y)
592                     && (aPoint.X < aBBox.X+aBBox.Width)
593                     && (aPoint.Y < aBBox.Y+aBBox.Height) )
594                     return xChild;
595             }
596         }
597     }
598 
599     // Have not found a child under the given point.  Returning empty
600     // reference to indicate this.
601     return uno::Reference<XAccessible>();
602 }
603 
604 
605 
606 
607 awt::Rectangle SAL_CALL AccessibleShape::getBounds (void)
608     throw (::com::sun::star::uno::RuntimeException)
609 {
610     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
611     ::osl::MutexGuard aGuard (maMutex);
612 
613     ThrowIfDisposed ();
614     awt::Rectangle aBoundingBox;
615     if ( mxShape.is() )
616     {
617 
618         static const OUString sBoundRectName (
619             RTL_CONSTASCII_USTRINGPARAM("BoundRect"));
620         static const OUString sAnchorPositionName (
621             RTL_CONSTASCII_USTRINGPARAM("AnchorPosition"));
622 
623         // Get the shape's bounding box in internal coordinates (in 100th of
624         // mm).  Use the property BoundRect.  Only if that is not supported ask
625         // the shape for its position and size directly.
626         Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY);
627         Reference<beans::XPropertySetInfo> xSetInfo;
628         bool bFoundBoundRect = false;
629         if (xSet.is())
630         {
631             xSetInfo = xSet->getPropertySetInfo ();
632             if (xSetInfo.is())
633             {
634                 if (xSetInfo->hasPropertyByName (sBoundRectName))
635                 {
636                     try
637                     {
638                         uno::Any aValue = xSet->getPropertyValue (sBoundRectName);
639                         aValue >>= aBoundingBox;
640                         bFoundBoundRect = true;
641                     }
642                     catch (beans::UnknownPropertyException e)
643                     {
644                         // Handled below (bFoundBoundRect stays false).
645                     }
646                 }
647                 else
648                     OSL_TRACE (" no property BoundRect");
649             }
650         }
651 
652         // Fallback when there is no BoundRect Property.
653         if ( ! bFoundBoundRect )
654         {
655             awt::Point aPosition (mxShape->getPosition());
656             awt::Size aSize (mxShape->getSize());
657             aBoundingBox = awt::Rectangle (
658                 aPosition.X, aPosition.Y,
659                 aSize.Width, aSize.Height);
660 
661             // While BoundRects have absolute positions, the position returned
662             // by XPosition::getPosition is relative.  Get the anchor position
663             // (usually not (0,0) for Writer shapes).
664             if (xSetInfo.is())
665             {
666                 if (xSetInfo->hasPropertyByName (sAnchorPositionName))
667                 {
668                     uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName);
669                     awt::Point aAnchorPosition;
670                     aPos >>= aAnchorPosition;
671                     aBoundingBox.X += aAnchorPosition.X;
672                     aBoundingBox.Y += aAnchorPosition.Y;
673                 }
674             }
675         }
676 
677         // Transform coordinates from internal to pixel.
678         if (maShapeTreeInfo.GetViewForwarder() == NULL)
679             throw uno::RuntimeException (::rtl::OUString (
680                 RTL_CONSTASCII_USTRINGPARAM(
681                     "AccessibleShape has no valid view forwarder")),
682                 static_cast<uno::XWeak*>(this));
683         ::Size aPixelSize = maShapeTreeInfo.GetViewForwarder()->LogicToPixel (
684             ::Size (aBoundingBox.Width, aBoundingBox.Height));
685         ::Point aPixelPosition = maShapeTreeInfo.GetViewForwarder()->LogicToPixel (
686             ::Point (aBoundingBox.X, aBoundingBox.Y));
687 
688         // Clip the shape's bounding box with the bounding box of its parent.
689         Reference<XAccessibleComponent> xParentComponent (
690             getAccessibleParent(), uno::UNO_QUERY);
691         if (xParentComponent.is())
692         {
693             // Make the coordinates relative to the parent.
694             awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
695             int x = aPixelPosition.getX() - aParentLocation.X;
696             int y = aPixelPosition.getY() - aParentLocation.Y;
697 
698             /*        //  The following block is a workarround for bug #99889# (property
699             //  BoundRect returnes coordinates relative to document window
700             //  instead of absolute coordinates for shapes in Writer).  Has to
701             //  be removed as soon as bug is fixed.
702 
703             // Use a non-null anchor position as flag that the shape is in a
704             // Writer document.
705             if (xSetInfo.is())
706                 if (xSetInfo->hasPropertyByName (sAnchorPositionName))
707                 {
708                     uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName);
709                     awt::Point aAnchorPosition;
710                     aPos >>= aAnchorPosition;
711                     if (aAnchorPosition.X > 0)
712                     {
713                         x = aPixelPosition.getX();
714                         y = aPixelPosition.getY();
715                     }
716                 }
717             //  End of workarround.
718             */
719             // Clip with parent (with coordinates relative to itself).
720             ::Rectangle aBBox (
721                 x, y, x + aPixelSize.getWidth(), y + aPixelSize.getHeight());
722             awt::Size aParentSize (xParentComponent->getSize());
723             ::Rectangle aParentBBox (0,0, aParentSize.Width, aParentSize.Height);
724             aBBox = aBBox.GetIntersection (aParentBBox);
725             aBoundingBox = awt::Rectangle (
726                 aBBox.getX(),
727                 aBBox.getY(),
728                 aBBox.getWidth(),
729                 aBBox.getHeight());
730         }
731         else
732         {
733             OSL_TRACE ("parent does not support component");
734             aBoundingBox = awt::Rectangle (
735                 aPixelPosition.getX(), aPixelPosition.getY(),
736                 aPixelSize.getWidth(), aPixelSize.getHeight());
737         }
738     }
739 
740     return aBoundingBox;
741 }
742 
743 
744 
745 
746 awt::Point SAL_CALL AccessibleShape::getLocation (void)
747     throw (::com::sun::star::uno::RuntimeException)
748 {
749     ThrowIfDisposed ();
750     awt::Rectangle aBoundingBox (getBounds());
751     return awt::Point (aBoundingBox.X, aBoundingBox.Y);
752 }
753 
754 
755 
756 
757 awt::Point SAL_CALL AccessibleShape::getLocationOnScreen (void)
758     throw (::com::sun::star::uno::RuntimeException)
759 {
760     ThrowIfDisposed ();
761 
762     // Get relative position...
763     awt::Point aLocation (getLocation ());
764 
765     // ... and add absolute position of the parent.
766     uno::Reference<XAccessibleComponent> xParentComponent (
767         getAccessibleParent(), uno::UNO_QUERY);
768     if (xParentComponent.is())
769     {
770         awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
771         aLocation.X += aParentLocation.X;
772         aLocation.Y += aParentLocation.Y;
773     }
774     else
775         OSL_TRACE ("getLocation: parent does not support XAccessibleComponent");
776     return aLocation;
777 }
778 
779 
780 
781 
782 awt::Size SAL_CALL AccessibleShape::getSize (void)
783     throw (uno::RuntimeException)
784 {
785     ThrowIfDisposed ();
786     awt::Rectangle aBoundingBox (getBounds());
787     return awt::Size (aBoundingBox.Width, aBoundingBox.Height);
788 }
789 
790 
791 
792 
793 sal_Int32 SAL_CALL AccessibleShape::getForeground (void)
794     throw (::com::sun::star::uno::RuntimeException)
795 {
796     ThrowIfDisposed ();
797     sal_Int32 nColor (0x0ffffffL);
798 
799     try
800     {
801         uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY);
802         if (aSet.is())
803         {
804             uno::Any aColor;
805             aColor = aSet->getPropertyValue (OUString::createFromAscii ("LineColor"));
806             aColor >>= nColor;
807         }
808     }
809     catch (::com::sun::star::beans::UnknownPropertyException)
810     {
811         // Ignore exception and return default color.
812     }
813     return nColor;
814 }
815 
816 
817 
818 
819 sal_Int32 SAL_CALL AccessibleShape::getBackground (void)
820     throw (::com::sun::star::uno::RuntimeException)
821 {
822     ThrowIfDisposed ();
823     sal_Int32 nColor (0L);
824 
825     try
826     {
827         uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY);
828         if (aSet.is())
829         {
830             uno::Any aColor;
831             aColor = aSet->getPropertyValue (OUString::createFromAscii ("FillColor"));
832             aColor >>= nColor;
833             aColor = aSet->getPropertyValue (OUString::createFromAscii ("FillTransparence"));
834             short nTrans=0;
835             aColor >>= nTrans;
836             Color crBk(nColor);
837             if (nTrans == 0 )
838             {
839                 crBk.SetTransparency(0xff);
840             }
841             else
842             {
843                 nTrans = short(256 - nTrans / 100. * 256);
844                 crBk.SetTransparency(sal_uInt8(nTrans));
845             }
846             nColor = crBk.GetColor();
847         }
848     }
849     catch (::com::sun::star::beans::UnknownPropertyException)
850     {
851         // Ignore exception and return default color.
852     }
853     return nColor;
854 }
855 
856 
857 
858 
859 //=====  XAccessibleEventBroadcaster  =========================================
860 
861 void SAL_CALL AccessibleShape::addEventListener (
862     const Reference<XAccessibleEventListener >& rxListener)
863     throw (uno::RuntimeException)
864 {
865     if (rBHelper.bDisposed || rBHelper.bInDispose)
866     {
867         uno::Reference<uno::XInterface> xThis (
868             (lang::XComponent *)this, uno::UNO_QUERY);
869         rxListener->disposing (lang::EventObject (xThis));
870     }
871     else
872     {
873         AccessibleContextBase::addEventListener (rxListener);
874         if (mpText != NULL)
875             mpText->AddEventListener (rxListener);
876     }
877 }
878 
879 
880 
881 
882 void SAL_CALL AccessibleShape::removeEventListener (
883     const Reference<XAccessibleEventListener >& rxListener)
884     throw (uno::RuntimeException)
885 {
886     AccessibleContextBase::removeEventListener (rxListener);
887     if (mpText != NULL)
888         mpText->RemoveEventListener (rxListener);
889 }
890 
891 
892 
893 
894 //=====  XInterface  ==========================================================
895 
896 com::sun::star::uno::Any SAL_CALL
897     AccessibleShape::queryInterface (const com::sun::star::uno::Type & rType)
898     throw (::com::sun::star::uno::RuntimeException)
899 {
900     ::com::sun::star::uno::Any aReturn = AccessibleContextBase::queryInterface (rType);
901     if ( ! aReturn.hasValue())
902         aReturn = ::cppu::queryInterface (rType,
903             static_cast<XAccessibleComponent*>(this),
904             static_cast<XAccessibleExtendedComponent*>(this),
905             static_cast< ::com::sun::star::accessibility::XAccessibleSelection* >(this),
906 
907          static_cast< ::com::sun::star::accessibility::XAccessibleExtendedAttributes* >(this),
908             static_cast<lang::XEventListener*>(this),
909             static_cast<document::XEventListener*>(this),
910             static_cast<lang::XUnoTunnel*>(this),
911             static_cast<XAccessibleGroupPosition*>(this),
912             static_cast<XAccessibleHypertext*>(this)
913             );
914     return aReturn;
915 }
916 
917 
918 
919 
920 void SAL_CALL
921     AccessibleShape::acquire (void)
922     throw ()
923 {
924     AccessibleContextBase::acquire ();
925 }
926 
927 
928 
929 
930 void SAL_CALL
931     AccessibleShape::release (void)
932     throw ()
933 {
934     AccessibleContextBase::release ();
935 }
936 //
937 //=====  XAccessibleSelection  ============================================
938 //
939 
940 //--------------------------------------------------------------------------------
941 void SAL_CALL AccessibleShape::selectAccessibleChild( sal_Int32 )
942 throw ( IndexOutOfBoundsException, RuntimeException )
943 {
944 }
945 
946 //----------------------------------------------------------------------------------
947 sal_Bool SAL_CALL AccessibleShape::isAccessibleChildSelected( sal_Int32 nChildIndex )
948 throw ( IndexOutOfBoundsException,
949        RuntimeException )
950 {
951     uno::Reference<XAccessible> xAcc = getAccessibleChild( nChildIndex );
952     uno::Reference<XAccessibleContext> xContext;
953     if( xAcc.is() )
954     {
955         xContext = xAcc->getAccessibleContext();
956     }
957 
958     if( xContext.is() )
959     {
960         if( xContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
961         {
962             uno::Reference< ::com::sun::star::accessibility::XAccessibleText >
963                 xText(xAcc, uno::UNO_QUERY);
964             if( xText.is() )
965             {
966                 if( xText->getSelectionStart() >= 0 ) return sal_True;
967             }
968         }
969         else if( xContext->getAccessibleRole() == AccessibleRole::SHAPE )
970         {
971             Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet();
972             if( !pRState.is() )
973                 return sal_False;
974 
975             uno::Sequence<short> pStates = pRState->getStates();
976             int nCount = pStates.getLength();
977             for( int i = 0; i < nCount; i++ )
978             {
979                 if(pStates[i] == AccessibleStateType::SELECTED)
980                     return sal_True;
981             }
982             return sal_False;
983         }
984     }
985 
986     return sal_False;
987 }
988 
989 //---------------------------------------------------------------------
990 void SAL_CALL AccessibleShape::clearAccessibleSelection(  )
991 throw ( RuntimeException )
992 {
993 }
994 
995 //-------------------------------------------------------------------------
996 void SAL_CALL AccessibleShape::selectAllAccessibleChildren(  )
997 throw ( RuntimeException )
998 {
999 }
1000 
1001 //----------------------------------------------------------------------------
1002 sal_Int32 SAL_CALL AccessibleShape::getSelectedAccessibleChildCount()
1003 throw ( RuntimeException )
1004 {
1005     sal_Int32 nCount = 0;
1006     sal_Int32 TotalCount = getAccessibleChildCount();
1007     for( sal_Int32 i = 0; i < TotalCount; i++ )
1008         if( isAccessibleChildSelected(i) ) nCount++;
1009 
1010     return nCount;
1011 }
1012 
1013 //--------------------------------------------------------------------------------------
1014 Reference<XAccessible> SAL_CALL AccessibleShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
1015 throw ( IndexOutOfBoundsException, RuntimeException)
1016 {
1017     if ( nSelectedChildIndex > getSelectedAccessibleChildCount() )
1018         throw IndexOutOfBoundsException();
1019     sal_Int32 i1, i2;
1020     for( i1 = 0, i2 = 0; i1 < getAccessibleChildCount(); i1++ )
1021         if( isAccessibleChildSelected(i1) )
1022         {
1023             if( i2 == nSelectedChildIndex )
1024                 return getAccessibleChild( i1 );
1025             i2++;
1026         }
1027     return Reference<XAccessible>();
1028 }
1029 
1030 //----------------------------------------------------------------------------------
1031 void SAL_CALL AccessibleShape::deselectAccessibleChild( sal_Int32 )
1032                                                             throw ( IndexOutOfBoundsException,
1033                                                             RuntimeException )
1034 {
1035 
1036 }
1037 
1038 //=====  XAccessibleExtendedAttributes  ========================================================
1039 uno::Any SAL_CALL AccessibleShape::getExtendedAttributes()
1040         throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1041 {
1042     uno::Any strRet;
1043     ::rtl::OUString style;
1044     if( getAccessibleRole() != AccessibleRole::SHAPE ) return strRet;
1045     if( m_pShape )
1046     {
1047         //style = ::rtl::OUString::createFromAscii("style=");
1048         style = ::rtl::OUString::createFromAscii("style:");
1049         style += GetStyle();
1050     }
1051     style += ::rtl::OUString::createFromAscii(";");
1052     strRet <<= style;
1053     return strRet;
1054 }
1055 //=====  XServiceInfo  ========================================================
1056 
1057 ::rtl::OUString SAL_CALL
1058     AccessibleShape::getImplementationName (void)
1059     throw (::com::sun::star::uno::RuntimeException)
1060 {
1061     return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleShape"));
1062 }
1063 
1064 
1065 
1066 
1067 uno::Sequence<OUString> SAL_CALL
1068     AccessibleShape::getSupportedServiceNames (void)
1069     throw (::com::sun::star::uno::RuntimeException)
1070 {
1071     ThrowIfDisposed ();
1072     // Get list of supported service names from base class...
1073     uno::Sequence<OUString> aServiceNames =
1074         AccessibleContextBase::getSupportedServiceNames();
1075     sal_Int32 nCount (aServiceNames.getLength());
1076 
1077     // ...and add additional names.
1078     aServiceNames.realloc (nCount + 1);
1079     static const OUString sAdditionalServiceName (RTL_CONSTASCII_USTRINGPARAM(
1080         "com.sun.star.drawing.AccessibleShape"));
1081     aServiceNames[nCount] = sAdditionalServiceName;
1082 
1083     return aServiceNames;
1084 }
1085 
1086 
1087 
1088 
1089 
1090 //=====  XTypeProvider  ===================================================
1091 
1092 uno::Sequence<uno::Type> SAL_CALL
1093     AccessibleShape::getTypes (void)
1094     throw (uno::RuntimeException)
1095 {
1096     ThrowIfDisposed ();
1097     // Get list of types from the context base implementation, ...
1098     uno::Sequence<uno::Type> aTypeList (AccessibleContextBase::getTypes());
1099     // ... get list of types from component base implementation, ...
1100     uno::Sequence<uno::Type> aComponentTypeList (AccessibleComponentBase::getTypes());
1101     // ... define local types, ...
1102     const uno::Type aLangEventListenerType =
1103         ::getCppuType((const uno::Reference<lang::XEventListener>*)0);
1104     const uno::Type aDocumentEventListenerType =
1105         ::getCppuType((const uno::Reference<document::XEventListener>*)0);
1106     const uno::Type aUnoTunnelType =
1107         ::getCppuType((const uno::Reference<lang::XUnoTunnel>*)0);
1108     //    const uno::Type aStateSetType =
1109     //      ::getCppuType((const uno::Reference<XAccessibleStateSet>*)0);
1110 
1111     // ... and merge them all into one list.
1112     sal_Int32   nTypeCount (aTypeList.getLength()),
1113         nComponentTypeCount (aComponentTypeList.getLength());
1114     int         i;
1115 
1116     aTypeList.realloc (nTypeCount + nComponentTypeCount + 3);
1117 
1118     for (i=0; i<nComponentTypeCount; i++)
1119         aTypeList[nTypeCount + i] = aComponentTypeList[i];
1120 
1121     aTypeList[nTypeCount + i++ ] = aLangEventListenerType;
1122     aTypeList[nTypeCount + i++ ] = aDocumentEventListenerType;
1123     aTypeList[nTypeCount + i ] = aUnoTunnelType;
1124 
1125     return aTypeList;
1126 }
1127 
1128 
1129 
1130 
1131 //=====  lang::XEventListener  ================================================
1132 
1133 /** Disposing calls are accepted only from the model: Just reset the
1134     reference to the model in the shape tree info.  Otherwise this object
1135     remains functional.
1136 */
1137 void SAL_CALL
1138     AccessibleShape::disposing (const lang::EventObject& aEvent)
1139     throw (uno::RuntimeException)
1140 {
1141     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
1142     ::osl::MutexGuard aGuard (maMutex);
1143 
1144     try
1145     {
1146         if (aEvent.Source ==  maShapeTreeInfo.GetModelBroadcaster())
1147         {
1148             // Remove reference to model broadcaster to allow it to pass
1149             // away.
1150             maShapeTreeInfo.SetModelBroadcaster(NULL);
1151         }
1152 
1153     }
1154     catch (uno::RuntimeException e)
1155     {
1156         OSL_TRACE ("caught exception while disposing");
1157     }
1158 }
1159 
1160 
1161 
1162 
1163 //=====  document::XEventListener  ============================================
1164 
1165 void SAL_CALL
1166     AccessibleShape::notifyEvent (const document::EventObject& rEventObject)
1167     throw (uno::RuntimeException)
1168 {
1169     static const OUString sShapeModified (
1170         RTL_CONSTASCII_USTRINGPARAM("ShapeModified"));
1171 
1172     // First check if the event is for us.
1173     uno::Reference<drawing::XShape> xShape (
1174         rEventObject.Source, uno::UNO_QUERY);
1175     if ( xShape.get() == mxShape.get() )
1176     {
1177         if (rEventObject.EventName.equals (sShapeModified))
1178         {
1179             //Need to update text children when receiving ShapeModified hint when exiting edit mode for text box
1180             if (mpText)
1181                 mpText->UpdateChildren();
1182 
1183 
1184             // Some property of a shape has been modified.  Send an event
1185             // that indicates a change of the visible data to all listeners.
1186             CommitChange (
1187                 AccessibleEventId::VISIBLE_DATA_CHANGED,
1188                 uno::Any(),
1189                 uno::Any());
1190 
1191             // Name and Description may have changed.  Update the local
1192             // values accordingly.
1193             UpdateNameAndDescription();
1194         }
1195     }
1196 }
1197 
1198 
1199 
1200 
1201 //=====  lang::XUnoTunnel  ================================================
1202 
1203 const uno::Sequence< sal_Int8 >&
1204     AccessibleShape::getUnoTunnelImplementationId()
1205     throw()
1206 {
1207     static uno::Sequence< sal_Int8 >* pSeq = 0;
1208 
1209     if( !pSeq )
1210     {
1211         ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
1212 
1213         if( !pSeq )
1214         {
1215             static uno::Sequence< sal_Int8 > aSeq( 16 );
1216             rtl_createUuid( (sal_uInt8*) aSeq.getArray(), 0, sal_True );
1217             pSeq = &aSeq;
1218         }
1219     }
1220 
1221     return( *pSeq );
1222 }
1223 
1224 //------------------------------------------------------------------------------
1225 AccessibleShape*
1226     AccessibleShape::getImplementation( const uno::Reference< uno::XInterface >& rxIFace )
1227     throw()
1228 {
1229     uno::Reference< lang::XUnoTunnel >  xTunnel( rxIFace, uno::UNO_QUERY );
1230     AccessibleShape*                    pReturn = NULL;
1231 
1232     if( xTunnel.is() )
1233         pReturn = reinterpret_cast< AccessibleShape* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) );
1234 
1235     return( pReturn );
1236 }
1237 
1238 //------------------------------------------------------------------------------
1239 sal_Int64 SAL_CALL
1240     AccessibleShape::getSomething( const uno::Sequence< sal_Int8 >& rIdentifier )
1241     throw(uno::RuntimeException)
1242 {
1243     sal_Int64 nReturn( 0 );
1244 
1245     if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) )
1246         nReturn = reinterpret_cast< sal_Int64 >( this );
1247 
1248     return( nReturn );
1249 }
1250 
1251 //=====  IAccessibleViewForwarderListener  ====================================
1252 
1253 void AccessibleShape::ViewForwarderChanged (ChangeType aChangeType,
1254         const IAccessibleViewForwarder* pViewForwarder)
1255 {
1256     // Inform all listeners that the graphical representation (i.e. size
1257     // and/or position) of the shape has changed.
1258     CommitChange (AccessibleEventId::VISIBLE_DATA_CHANGED,
1259         uno::Any(),
1260         uno::Any());
1261 
1262     // Tell children manager of the modified view forwarder.
1263     if (mpChildrenManager != NULL)
1264         mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder);
1265 
1266     // update our children that our screen position might have changed
1267     if( mpText )
1268         mpText->UpdateChildren();
1269 }
1270 
1271 
1272 
1273 
1274 //=====  protected internal  ==================================================
1275 /// Set this object's name if is different to the current name.
1276 ::rtl::OUString
1277     AccessibleShape::CreateAccessibleBaseName (void)
1278     throw (::com::sun::star::uno::RuntimeException)
1279 {
1280     return ShapeTypeHandler::CreateAccessibleBaseName( mxShape );
1281 }
1282 
1283 
1284 ::rtl::OUString
1285     AccessibleShape::CreateAccessibleName (void)
1286     throw (::com::sun::star::uno::RuntimeException)
1287 {
1288     //OUString sName (CreateAccessibleBaseName());
1289     OUString sName;
1290     sName = GetFullAccessibleName(this);
1291     return sName;
1292 }
1293 
1294 ::rtl::OUString
1295     AccessibleShape::GetFullAccessibleName (AccessibleShape *shape)
1296     throw (::com::sun::star::uno::RuntimeException)
1297 {
1298     OUString sName (shape->CreateAccessibleBaseName());
1299     // Append the shape's index to the name to disambiguate between shapes
1300     // of the same type.  If such an index where not given to the
1301     // constructor then use the z-order instead.  If even that does not exist
1302     // we throw an exception.
1303     //long nIndex = mnIndex;
1304     //if (nIndex == -1)
1305     //{
1306     //    try
1307     //    {
1308     //        uno::Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY);
1309     //        if (xSet.is())
1310     //        {
1311     //            uno::Any aZOrder (xSet->getPropertyValue (::rtl::OUString::createFromAscii ("ZOrder")));
1312     //            aZOrder >>= nIndex;
1313 
1314     //            // Add one to be not zero based.
1315     //            nIndex += 1;
1316     //        }
1317     //    }
1318     //    catch (beans::UnknownPropertyException)
1319     //    {
1320     //        // We throw our own exception that is a bit more informative.
1321     //        throw uno::RuntimeException (::rtl::OUString (
1322     //            RTL_CONSTASCII_USTRINGPARAM("AccessibleShape has invalid index and no ZOrder property")),
1323     //            static_cast<uno::XWeak*>(this));
1324     //    }
1325 
1326     //}
1327 
1328     //// Put a space between name and index because of Gnopernicus othewise
1329     //// spells the name.
1330     //sName += OUString (RTL_CONSTASCII_USTRINGPARAM(" ")) + OUString::valueOf (nIndex);
1331 
1332     //return sName;
1333 
1334     XubString nameStr;
1335     if(shape->m_pShape)
1336         nameStr = shape->m_pShape->GetName();
1337     if(nameStr.Len() == 0)
1338     {
1339         sName +=  OUString( RTL_CONSTASCII_USTRINGPARAM( " " ));
1340     }
1341     else
1342     {
1343         sName = nameStr;
1344     }
1345     /*
1346     sal_Int32 nChildCount = shape->getAccessibleChildCount();
1347     if(nChildCount > 0)
1348       {
1349         for (sal_Int32 i=0; i<nChildCount; ++i)
1350         {
1351             Reference<XAccessible> xChild (shape->getAccessibleChild (i));
1352             if (xChild.is())
1353             {
1354             uno::Reference <XAccessibleContext> xChildContext(xChild->getAccessibleContext());
1355             if (xChildContext->getAccessibleRole() == AccessibleRole::PARAGRAPH)
1356             {
1357                 uno::Reference<XAccessibleText> xText = uno::Reference<XAccessibleText> ( xChild, uno::UNO_QUERY );
1358                 sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )) + xText->getText();
1359             }
1360             else if (xChildContext->getAccessibleRole() == AccessibleRole::SHAPE)
1361             {
1362                 sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )) + GetFullAccessibleName(static_cast< AccessibleShape*>( xChild.get()));
1363             }
1364             }
1365         }
1366       }
1367      */
1368     //Solution:If the new produced name if not the same with last,notify name changed
1369     //         Event
1370     if( aAccName != sName && aAccName.getLength() != 0 )
1371     {
1372         uno::Any aOldValue, aNewValue;
1373         aOldValue <<= aAccName;
1374         aNewValue <<= sName;
1375         CommitChange(
1376             AccessibleEventId::NAME_CHANGED,
1377             aNewValue,
1378             aOldValue);
1379     }
1380     aAccName = sName;
1381     return sName;
1382 }
1383 ::rtl::OUString
1384     AccessibleShape::CreateAccessibleDescription (void)
1385     throw (::com::sun::star::uno::RuntimeException)
1386 {
1387     DescriptionGenerator aDG (mxShape);
1388     aDG.Initialize (CreateAccessibleBaseName());
1389     switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
1390     {
1391         case DRAWING_3D_CUBE:
1392         case DRAWING_3D_EXTRUDE:
1393         case DRAWING_3D_LATHE:
1394         case DRAWING_3D_SPHERE:
1395             aDG.Add3DProperties ();
1396             break;
1397 
1398         case DRAWING_3D_SCENE:
1399         case DRAWING_GROUP:
1400         case DRAWING_PAGE:
1401             // No further information is appended.
1402             break;
1403 
1404         case DRAWING_CAPTION:
1405         case DRAWING_CLOSED_BEZIER:
1406         case DRAWING_CLOSED_FREEHAND:
1407         case DRAWING_ELLIPSE:
1408         case DRAWING_POLY_POLYGON:
1409         case DRAWING_POLY_POLYGON_PATH:
1410         case DRAWING_RECTANGLE:
1411             aDG.AddLineProperties ();
1412             aDG.AddFillProperties ();
1413             break;
1414 
1415         case DRAWING_CONNECTOR:
1416         case DRAWING_LINE:
1417         case DRAWING_MEASURE:
1418         case DRAWING_OPEN_BEZIER:
1419         case DRAWING_OPEN_FREEHAND:
1420         case DRAWING_POLY_LINE:
1421         case DRAWING_POLY_LINE_PATH:
1422             aDG.AddLineProperties ();
1423             break;
1424 
1425         case DRAWING_CONTROL:
1426             aDG.AddProperty (OUString::createFromAscii ("ControlBackground"),
1427                 DescriptionGenerator::COLOR,
1428                 OUString());
1429             aDG.AddProperty (OUString::createFromAscii ("ControlBorder"),
1430                 DescriptionGenerator::INTEGER,
1431                 OUString());
1432             break;
1433 
1434         case DRAWING_TEXT:
1435             aDG.AddTextProperties ();
1436             break;
1437 
1438         default:
1439             aDG.Initialize (::rtl::OUString (
1440                                 RTL_CONSTASCII_USTRINGPARAM("Unknown accessible shape")));
1441             uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY);
1442             if (xDescriptor.is())
1443             {
1444                 aDG.AppendString (::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("service name=")));
1445                 aDG.AppendString (xDescriptor->getShapeType());
1446             }
1447     }
1448 
1449     return aDG();
1450 }
1451 
1452 
1453 
1454 
1455 uno::Reference< drawing::XShape > AccessibleShape::GetXShape()
1456 {
1457     return( mxShape );
1458 }
1459 
1460 
1461 
1462 // protected
1463 void AccessibleShape::disposing (void)
1464 {
1465     ::vos::OGuard aSolarGuard (::Application::GetSolarMutex());
1466     ::osl::MutexGuard aGuard (maMutex);
1467 
1468     // Make sure to send an event that this object looses the focus in the
1469     // case that it has the focus.
1470     ::utl::AccessibleStateSetHelper* pStateSet =
1471           static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
1472     if (pStateSet != NULL)
1473         pStateSet->RemoveState (AccessibleStateType::FOCUSED);
1474 
1475     // Unregister from broadcasters.
1476     Reference<lang::XComponent> xComponent (mxShape, uno::UNO_QUERY);
1477     if (xComponent.is())
1478         xComponent->removeEventListener (this);
1479 
1480     // Unregister from model.
1481     if (maShapeTreeInfo.GetModelBroadcaster().is())
1482         maShapeTreeInfo.GetModelBroadcaster()->removeEventListener (
1483             static_cast<document::XEventListener*>(this));
1484 
1485     // Release the child containers.
1486     if (mpChildrenManager != NULL)
1487     {
1488         delete mpChildrenManager;
1489         mpChildrenManager = NULL;
1490     }
1491     if (mpText != NULL)
1492     {
1493         mpText->Dispose();
1494         delete mpText;
1495         mpText = NULL;
1496     }
1497 
1498     // Cleanup.  Remove references to objects to allow them to be
1499     // destroyed.
1500     mxShape = NULL;
1501     maShapeTreeInfo = AccessibleShapeTreeInfo();
1502 
1503     // Call base classes.
1504     AccessibleContextBase::dispose ();
1505 }
1506 
1507 sal_Int32 SAL_CALL
1508     AccessibleShape::getAccessibleIndexInParent (void)
1509     throw (::com::sun::star::uno::RuntimeException)
1510 {
1511     ThrowIfDisposed ();
1512     //  Use a simple but slow solution for now.  Optimize later.
1513 
1514     sal_Int32 nIndex = m_nIndexInParent;
1515     if ( -1 == nIndex )
1516         nIndex = AccessibleContextBase::getAccessibleIndexInParent();
1517     return nIndex;
1518 }
1519 
1520 
1521 
1522 
1523 void AccessibleShape::UpdateNameAndDescription (void)
1524 {
1525     // Ignore missing title, name, or description.  There are fallbacks for
1526     // them.
1527     try
1528     {
1529         Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY_THROW);
1530         OUString sString;
1531 
1532         // Get the accessible name.
1533         sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Title")));
1534         if (sString.getLength() > 0)
1535         {
1536             SetAccessibleName(sString, AccessibleContextBase::FromShape);
1537         }
1538         else
1539         {
1540             sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Name")));
1541             if (sString.getLength() > 0)
1542                 SetAccessibleName(sString, AccessibleContextBase::FromShape);
1543         }
1544 
1545         // Get the accessible description.
1546         sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Description")));
1547         if (sString.getLength() > 0)
1548             SetAccessibleDescription(sString, AccessibleContextBase::FromShape);
1549     }
1550     catch (uno::RuntimeException&)
1551     {
1552     }
1553 }
1554 //  Return this object's role.
1555 sal_Int16 SAL_CALL AccessibleShape::getAccessibleRole (void)
1556         throw (::com::sun::star::uno::RuntimeException)
1557 {
1558     sal_Int16 nAccessibleRole =  AccessibleRole::SHAPE ;
1559     switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
1560     {
1561         case     DRAWING_GRAPHIC_OBJECT:
1562                  nAccessibleRole =  AccessibleRole::GRAPHIC ;               break;
1563         case     DRAWING_OLE:
1564                  nAccessibleRole =  AccessibleRole::EMBEDDED_OBJECT ;       break;
1565 
1566         default:
1567             nAccessibleRole = AccessibleContextBase::getAccessibleRole();
1568             break;
1569     }
1570 
1571     return nAccessibleRole;
1572 }
1573 
1574 
1575 void AccessibleShape::UpdateDocumentAllSelState(Reference<XAccessibleStateSet> &xStateSet)
1576 {
1577     if (mpParent && mpParent->IsDocumentSelAll())
1578     {
1579         ::utl::AccessibleStateSetHelper* pStateSet =
1580             static_cast< ::utl::AccessibleStateSetHelper*>(xStateSet.get());
1581         pStateSet->AddState (AccessibleStateType::SELECTED);
1582 
1583         //uno::Any NewValue;
1584         //NewValue <<= AccessibleStateType::SELECTED;
1585 
1586         //CommitChange(AccessibleEventId::STATE_CHANGED,NewValue,uno::Any());
1587     }
1588 }
1589 
1590 //sort the drawing objects from up to down, from left to right
1591 struct XShapePosCompareHelper
1592 {
1593     bool operator() ( const uno::Reference<drawing::XShape>& xshape1,
1594         const uno::Reference<drawing::XShape>& xshape2 ) const
1595     {
1596         SdrObject* pObj1 = GetSdrObjectFromXShape(xshape1);
1597         SdrObject* pObj2 = GetSdrObjectFromXShape(xshape2);
1598         if(pObj1 && pObj2)
1599             return pObj1->GetOrdNum() < pObj2->GetOrdNum();
1600         else
1601             return 0;
1602     }
1603 };
1604 //end of group position
1605 
1606 //=====  XAccessibleGroupPosition  =========================================
1607 uno::Sequence< sal_Int32 > SAL_CALL
1608 AccessibleShape::getGroupPosition( const uno::Any& )
1609 throw (uno::RuntimeException)
1610 {
1611     // we will return the:
1612     // [0] group level
1613     // [1] similar items counts in the group
1614     // [2] the position of the object in the group
1615     uno::Sequence< sal_Int32 > aRet( 3 );
1616     aRet[0] = 0;
1617     aRet[1] = 0;
1618     aRet[2] = 0;
1619 
1620     ::com::sun::star::uno::Reference<XAccessible> xParent = getAccessibleParent();
1621     if (!xParent.is())
1622     {
1623         return aRet;
1624     }
1625     SdrObject *pObj = GetSdrObjectFromXShape(mxShape);
1626 
1627 
1628     if(pObj == NULL )
1629     {
1630         return aRet;
1631     }
1632 
1633     // Compute object's group level.
1634     sal_Int32 nGroupLevel = 0;
1635     SdrObject * pUper = pObj->GetUpGroup();
1636     while( pUper )
1637     {
1638         ++nGroupLevel;
1639         pUper = pUper->GetUpGroup();
1640     }
1641 
1642     ::com::sun::star::uno::Reference<XAccessibleContext> xParentContext = xParent->getAccessibleContext();
1643     if( xParentContext->getAccessibleRole()  == AccessibleRole::DOCUMENT)//Document
1644     {
1645         Reference< XAccessibleGroupPosition > xGroupPosition( xParent,uno::UNO_QUERY );
1646         if ( xGroupPosition.is() )
1647         {
1648             aRet = xGroupPosition->getGroupPosition( uno::makeAny( getAccessibleContext() ) );
1649         }
1650         return aRet;
1651     }
1652     if (xParentContext->getAccessibleRole() != AccessibleRole::SHAPE)
1653     {
1654         return aRet;
1655     }
1656 
1657     SdrObjList *pGrpList = NULL;
1658     if( pObj->GetUpGroup() )
1659         pGrpList = pObj->GetUpGroup()->GetSubList();
1660     else
1661         return aRet;
1662 
1663     std::vector< uno::Reference<drawing::XShape> > vXShapes;
1664     if (pGrpList)
1665     {
1666         const sal_Int32 nObj = pGrpList->GetObjCount();
1667         for(sal_Int32 i = 0 ; i < nObj ; ++i)
1668         {
1669             SdrObject *pSubObj = pGrpList->GetObj(i);
1670             if (pSubObj &&
1671                 xParentContext->getAccessibleChild(i)->getAccessibleContext()->getAccessibleRole() != AccessibleRole::GROUP_BOX)
1672             {
1673                 vXShapes.push_back( GetXShapeForSdrObject(pSubObj) );
1674             }
1675         }
1676     }
1677 
1678     std::sort( vXShapes.begin(), vXShapes.end(), XShapePosCompareHelper() );
1679 
1680     //get the the index of the selected object in the group
1681     std::vector< uno::Reference<drawing::XShape> >::iterator aIter;
1682     //we start counting position from 1
1683     sal_Int32 nPos = 1;
1684     for ( aIter = vXShapes.begin(); aIter != vXShapes.end(); aIter++, nPos++ )
1685     {
1686         if ( (*aIter).get() == mxShape.get() )
1687         {
1688             sal_Int32* pArray = aRet.getArray();
1689             pArray[0] = nGroupLevel;
1690             pArray[1] = vXShapes.size();
1691             pArray[2] = nPos;
1692             break;
1693         }
1694     }
1695 
1696     return aRet;
1697 }
1698 
1699 ::rtl::OUString AccessibleShape::getObjectLink( const uno::Any& )
1700     throw (uno::RuntimeException)
1701 {
1702     ::rtl::OUString aRet;
1703 
1704     SdrObject *pObj = GetSdrObjectFromXShape(mxShape);
1705     if(pObj == NULL )
1706     {
1707         return aRet;
1708     }
1709     if (maShapeTreeInfo.GetDocumentWindow().is())
1710     {
1711         Reference< XAccessibleGroupPosition > xGroupPosition( maShapeTreeInfo.GetDocumentWindow(), uno::UNO_QUERY );
1712         if (xGroupPosition.is())
1713         {
1714             aRet = xGroupPosition->getObjectLink( uno::makeAny( getAccessibleContext() ) );
1715         }
1716     }
1717     return aRet;
1718 }
1719 
1720 //=====  XAccesibleHypertext  ==================================================
1721 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkCount()
1722     throw (::com::sun::star::uno::RuntimeException)
1723 {
1724     // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile.
1725     // Code need to be adapted....
1726     return 0;
1727 
1728     /*
1729     SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this);
1730     if (pLink->IsValidHyperlink())
1731         return 1;
1732     else
1733         return 0;
1734     */
1735 }
1736 uno::Reference< XAccessibleHyperlink > SAL_CALL
1737     AccessibleShape::getHyperLink( sal_Int32 )
1738     throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1739 {
1740     uno::Reference< XAccessibleHyperlink > xRet;
1741     // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile.
1742     // Code need to be adapted....
1743     /*
1744     SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this);
1745     if (pLink->IsValidHyperlink())
1746         xRet = pLink;
1747     if( !xRet.is() )
1748         throw ::com::sun::star::lang::IndexOutOfBoundsException();
1749     */
1750     return xRet;
1751 }
1752 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkIndex( sal_Int32 )
1753 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1754 {
1755     sal_Int32 nRet = 0;
1756     return nRet;
1757 }
1758 //=====  XAccesibleText  ==================================================
1759 sal_Int32 SAL_CALL AccessibleShape::getCaretPosition(  ) throw (::com::sun::star::uno::RuntimeException){return 0;}
1760 sal_Bool SAL_CALL AccessibleShape::setCaretPosition( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;}
1761 sal_Unicode SAL_CALL AccessibleShape::getCharacter( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;}
1762 ::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)
1763 {
1764     uno::Sequence< ::com::sun::star::beans::PropertyValue > aValues(0);
1765     return aValues;
1766 }
1767 ::com::sun::star::awt::Rectangle SAL_CALL AccessibleShape::getCharacterBounds( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
1768 {
1769     return com::sun::star::awt::Rectangle(0, 0, 0, 0 );
1770 }
1771 sal_Int32 SAL_CALL AccessibleShape::getCharacterCount(  ) throw (::com::sun::star::uno::RuntimeException){return 0;}
1772 sal_Int32 SAL_CALL AccessibleShape::getIndexAtPoint( const ::com::sun::star::awt::Point& ) throw (::com::sun::star::uno::RuntimeException){return 0;}
1773 ::rtl::OUString SAL_CALL AccessibleShape::getSelectedText(  ) throw (::com::sun::star::uno::RuntimeException){return OUString();}
1774 sal_Int32 SAL_CALL AccessibleShape::getSelectionStart(  ) throw (::com::sun::star::uno::RuntimeException){return 0;}
1775 sal_Int32 SAL_CALL AccessibleShape::getSelectionEnd(  ) throw (::com::sun::star::uno::RuntimeException){return 0;}
1776 sal_Bool SAL_CALL AccessibleShape::setSelection( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;}
1777 ::rtl::OUString SAL_CALL AccessibleShape::getText(  ) throw (::com::sun::star::uno::RuntimeException){return OUString();}
1778 ::rtl::OUString SAL_CALL AccessibleShape::getTextRange( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return OUString();}
1779 ::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)
1780 {
1781     ::com::sun::star::accessibility::TextSegment aResult;
1782     return aResult;
1783 }
1784 ::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)
1785 {
1786     ::com::sun::star::accessibility::TextSegment aResult;
1787     return aResult;
1788 }
1789 ::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)
1790 {
1791     ::com::sun::star::accessibility::TextSegment aResult;
1792     return aResult;
1793 }
1794 sal_Bool SAL_CALL AccessibleShape::copyText( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;}
1795 
1796 } // end of namespace accessibility
1797