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