Version 4.3.0.0.beta1, tag libreoffice-4.3.0.0.beta1
[LibreOffice.git] / svx / source / accessibility / AccessibleShape.cxx
blob49c1a1d4c3100925f5e42af7619b65ea297d6685
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/AccessibleShape.hxx>
21 #include "svx/DescriptionGenerator.hxx"
22 #include <svx/AccessibleShapeInfo.hxx>
23 #include <com/sun/star/view/XSelectionSupplier.hpp>
24 #include <com/sun/star/accessibility/AccessibleRole.hpp>
25 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
26 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
27 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/container/XChild.hpp>
30 #include <com/sun/star/drawing/XShapes.hpp>
31 #include <com/sun/star/drawing/XShapeDescriptor.hpp>
32 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
33 #include <com/sun/star/drawing/FillStyle.hpp>
34 #include <com/sun/star/text/XText.hpp>
35 #include <editeng/outlobj.hxx>
36 #include <rtl/ref.hxx>
37 #include <editeng/unoedsrc.hxx>
38 #include <svx/unoshtxt.hxx>
39 #include <svx/svdobj.hxx>
40 #include <svx/svdmodel.hxx>
41 #include <svx/unoapi.hxx>
42 #include <svx/svdpage.hxx>
43 #include <com/sun/star/uno/Exception.hpp>
44 #include <svx/ShapeTypeHandler.hxx>
45 #include <svx/SvxShapeTypes.hxx>
47 #include "accessibility.hrc"
48 #include "svx/svdstr.hrc"
49 #include <svx/dialmgr.hxx>
50 #include <vcl/svapp.hxx>
51 #include <unotools/accessiblestatesethelper.hxx>
52 #include <unotools/accessiblerelationsethelper.hxx>
53 #include <svx/svdview.hxx>
54 #include <comphelper/servicehelper.hxx>
55 #include "AccessibleEmptyEditSource.hxx"
57 #include <algorithm>
59 using namespace ::com::sun::star;
60 using namespace ::com::sun::star::accessibility;
61 using ::com::sun::star::uno::Reference;
62 using ::com::sun::star::lang::IndexOutOfBoundsException;
63 using ::com::sun::star::uno::RuntimeException;
65 namespace accessibility {
67 namespace {
69 OUString GetOptionalProperty (
70 const Reference<beans::XPropertySet>& rxSet,
71 const OUString& rsPropertyName)
73 OUString sValue;
75 if (rxSet.is())
77 const Reference<beans::XPropertySetInfo> xInfo (rxSet->getPropertySetInfo());
78 if ( ! xInfo.is() || xInfo->hasPropertyByName(rsPropertyName))
80 try
82 rxSet->getPropertyValue(rsPropertyName) >>= sValue;
84 catch (beans::UnknownPropertyException&)
86 // This exception should only be thrown when the property
87 // does not exits (of course) and the XPropertySetInfo is
88 // not available.
92 return sValue;
95 } // end of anonymous namespace
100 //===== internal ============================================================
102 AccessibleShape::AccessibleShape (
103 const AccessibleShapeInfo& rShapeInfo,
104 const AccessibleShapeTreeInfo& rShapeTreeInfo)
105 : AccessibleContextBase (rShapeInfo.mxParent,AccessibleRole::SHAPE),
106 mpChildrenManager(NULL),
107 mxShape (rShapeInfo.mxShape),
108 maShapeTreeInfo (rShapeTreeInfo),
109 mnIndex (rShapeInfo.mnIndex),
110 m_nIndexInParent(-1),
111 mpText (NULL),
112 mpParent (rShapeInfo.mpChildrenManager)
114 m_pShape = GetSdrObjectFromXShape(mxShape);
115 UpdateNameAndDescription();
118 AccessibleShape::~AccessibleShape (void)
120 delete mpChildrenManager;
121 delete mpText;
122 OSL_TRACE ("~AccessibleShape");
124 // Unregistering from the various broadcasters should be unnecessary
125 // since this destructor would not have been called if one of the
126 // broadcasters would still hold a strong reference to this object.
129 void AccessibleShape::Init (void)
131 // Update the OPAQUE and SELECTED shape.
132 UpdateStates ();
134 // Create a children manager when this shape has children of its own.
135 Reference<drawing::XShapes> xShapes (mxShape, uno::UNO_QUERY);
136 if (xShapes.is() && xShapes->getCount() > 0)
137 mpChildrenManager = new ChildrenManager (
138 this, xShapes, maShapeTreeInfo, *this);
139 if (mpChildrenManager != NULL)
140 mpChildrenManager->Update();
142 // Register at model as document::XEventListener.
143 if (maShapeTreeInfo.GetModelBroadcaster().is())
144 maShapeTreeInfo.GetModelBroadcaster()->addEventListener (
145 static_cast<document::XEventListener*>(this));
147 // Beware! Here we leave the paths of the UNO API and descend into the
148 // depths of the core. Necessary for making the edit engine
149 // accessible.
150 Reference<text::XText> xText (mxShape, uno::UNO_QUERY);
151 if (xText.is())
153 SdrView* pView = maShapeTreeInfo.GetSdrView ();
154 const Window* pWindow = maShapeTreeInfo.GetWindow ();
155 if (pView != NULL && pWindow != NULL && mxShape.is())
157 // #107948# Determine whether shape text is empty
158 SdrObject* pSdrObject = GetSdrObjectFromXShape(mxShape);
159 if( pSdrObject )
161 SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, pSdrObject );
162 OutlinerParaObject* pOutlinerParaObject = NULL;
164 if( pTextObj )
165 pOutlinerParaObject = pTextObj->GetEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active
167 bool bOwnParaObj = pOutlinerParaObject != NULL;
169 if( !pOutlinerParaObject && pSdrObject )
170 pOutlinerParaObject = pSdrObject->GetOutlinerParaObject();
172 // create AccessibleTextHelper to handle this shape's text
173 if( !pOutlinerParaObject )
175 // empty text -> use proxy edit source to delay creation of EditEngine
176 SAL_WNODEPRECATED_DECLARATIONS_PUSH
177 ::std::auto_ptr<SvxEditSource> pEditSource( new AccessibleEmptyEditSource ( *pSdrObject, *pView, *pWindow) );
178 SAL_WNODEPRECATED_DECLARATIONS_POP
179 mpText = new AccessibleTextHelper( pEditSource );
181 else
183 // non-empty text -> use full-fledged edit source right away
184 SAL_WNODEPRECATED_DECLARATIONS_PUSH
185 ::std::auto_ptr<SvxEditSource> pEditSource( new SvxTextEditSource ( *pSdrObject, 0, *pView, *pWindow) );
186 SAL_WNODEPRECATED_DECLARATIONS_POP
187 mpText = new AccessibleTextHelper( pEditSource );
190 if( bOwnParaObj )
191 delete pOutlinerParaObject;
193 mpText->SetEventSource(this);
202 void AccessibleShape::UpdateStates (void)
204 ::utl::AccessibleStateSetHelper* pStateSet =
205 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
206 if (pStateSet == NULL)
207 return;
209 // Set the opaque state for certain shape types when their fill style is
210 // solid.
211 bool bShapeIsOpaque = false;
212 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
214 case DRAWING_PAGE:
215 case DRAWING_RECTANGLE:
216 case DRAWING_TEXT:
218 uno::Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY);
219 if (xSet.is())
223 drawing::FillStyle aFillStyle;
224 bShapeIsOpaque = ( xSet->getPropertyValue ("FillStyle") >>= aFillStyle)
225 && aFillStyle == drawing::FillStyle_SOLID;
227 catch (::com::sun::star::beans::UnknownPropertyException&)
229 // Ignore.
234 if (bShapeIsOpaque)
235 pStateSet->AddState (AccessibleStateType::OPAQUE);
236 else
237 pStateSet->RemoveState (AccessibleStateType::OPAQUE);
239 // Set the selected state.
240 bool bShapeIsSelected = false;
241 // XXX fix_me this has to be done with an extra interface later on
242 if ( m_pShape && maShapeTreeInfo.GetSdrView() )
244 bShapeIsSelected = maShapeTreeInfo.GetSdrView()->IsObjMarked(m_pShape);
247 if (bShapeIsSelected)
248 pStateSet->AddState (AccessibleStateType::SELECTED);
249 else
250 pStateSet->RemoveState (AccessibleStateType::SELECTED);
253 OUString AccessibleShape::GetStyle()
255 return ShapeTypeHandler::CreateAccessibleBaseName( mxShape );
258 bool AccessibleShape::operator== (const AccessibleShape& rShape)
260 return this==&rShape;
266 bool AccessibleShape::SetState (sal_Int16 aState)
268 bool bStateHasChanged = false;
270 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
272 // Offer FOCUSED state to edit engine and detect whether the state
273 // changes.
274 bool bIsFocused = mpText->HaveFocus ();
275 mpText->SetFocus (true);
276 bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
278 else
279 bStateHasChanged = AccessibleContextBase::SetState (aState);
281 return bStateHasChanged;
287 bool AccessibleShape::ResetState (sal_Int16 aState)
289 bool bStateHasChanged = false;
291 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
293 // Try to remove FOCUSED state from the edit engine and detect
294 // whether the state changes.
295 bool bIsFocused = mpText->HaveFocus ();
296 mpText->SetFocus (false);
297 bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
299 else
300 bStateHasChanged = AccessibleContextBase::ResetState (aState);
302 return bStateHasChanged;
308 bool AccessibleShape::GetState (sal_Int16 aState)
310 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
312 // Just delegate the call to the edit engine. The state is not
313 // merged into the state set.
314 return mpText->HaveFocus();
316 else
317 return AccessibleContextBase::GetState (aState);
320 // OverWrite the parent's getAccessibleName method
321 OUString SAL_CALL AccessibleShape::getAccessibleName (void)
322 throw (::com::sun::star::uno::RuntimeException, std::exception)
324 ThrowIfDisposed ();
325 if (m_pShape && !m_pShape->GetTitle().isEmpty())
326 return CreateAccessibleName() + " " + m_pShape->GetTitle();
327 else
328 return CreateAccessibleName();
331 OUString SAL_CALL AccessibleShape::getAccessibleDescription (void)
332 throw (::com::sun::star::uno::RuntimeException, std::exception)
334 ThrowIfDisposed ();
335 if( m_pShape && !m_pShape->GetDescription().isEmpty())
336 return m_pShape->GetDescription() ;
337 else
338 return OUString(" ");
341 //===== XAccessibleContext ==================================================
343 /** The children of this shape come from two sources: The children from
344 group or scene shapes and the paragraphs of text.
346 sal_Int32 SAL_CALL
347 AccessibleShape::getAccessibleChildCount ()
348 throw (::com::sun::star::uno::RuntimeException, std::exception)
350 ThrowIfDisposed ();
351 sal_Int32 nChildCount = 0;
353 // Add the number of shapes that are children of this shape.
354 if (mpChildrenManager != NULL)
355 nChildCount += mpChildrenManager->GetChildCount ();
356 // Add the number text paragraphs.
357 if (mpText != NULL)
358 nChildCount += mpText->GetChildCount ();
360 return nChildCount;
366 /** Forward the request to the shape. Return the requested shape or throw
367 an exception for a wrong index.
369 uno::Reference<XAccessible> SAL_CALL
370 AccessibleShape::getAccessibleChild (sal_Int32 nIndex)
371 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
373 ThrowIfDisposed ();
375 uno::Reference<XAccessible> xChild;
377 // Depending on the index decide whether to delegate this call to the
378 // children manager or the edit engine.
379 if ((mpChildrenManager != NULL)
380 && (nIndex < mpChildrenManager->GetChildCount()))
382 xChild = mpChildrenManager->GetChild (nIndex);
384 else if (mpText != NULL)
386 sal_Int32 nI = nIndex;
387 if (mpChildrenManager != NULL)
388 nI -= mpChildrenManager->GetChildCount();
389 xChild = mpText->GetChild (nI);
391 else
392 throw lang::IndexOutOfBoundsException (
393 OUString("shape has no child with index ")
394 + OUString::number(nIndex),
395 static_cast<uno::XWeak*>(this));
397 return xChild;
400 uno::Reference<XAccessibleRelationSet> SAL_CALL
401 AccessibleShape::getAccessibleRelationSet (void)
402 throw (::com::sun::star::uno::RuntimeException, std::exception)
404 ::osl::MutexGuard aGuard (maMutex);
405 if (mpParent == NULL)
406 return uno::Reference<XAccessibleRelationSet>();
408 ::utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper;
410 //this mxshape is the captioned shape
411 uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
412 aSequence[0] = mpParent->GetAccessibleCaption(mxShape);
413 if(aSequence[0].get())
415 pRelationSet->AddRelation(
416 AccessibleRelation( AccessibleRelationType::DESCRIBED_BY, aSequence ) );
418 return uno::Reference<XAccessibleRelationSet>(pRelationSet);
421 /** Return a copy of the state set.
422 Possible states are:
423 ENABLED
424 SHOWING
425 VISIBLE
427 uno::Reference<XAccessibleStateSet> SAL_CALL
428 AccessibleShape::getAccessibleStateSet (void)
429 throw (::com::sun::star::uno::RuntimeException, std::exception)
431 ::osl::MutexGuard aGuard (maMutex);
432 Reference<XAccessibleStateSet> xStateSet;
434 if (rBHelper.bDisposed || mpText == NULL)
435 // Return a minimal state set that only contains the DEFUNC state.
437 xStateSet = AccessibleContextBase::getAccessibleStateSet ();
438 ::utl::AccessibleStateSetHelper* pStateSet =
439 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
440 ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent();
441 if( xTempAcc.is() )
443 ::com::sun::star::uno::Reference<XAccessibleContext>
444 xTempAccContext = xTempAcc->getAccessibleContext();
445 if( xTempAccContext.is() )
447 ::com::sun::star::uno::Reference<XAccessibleStateSet> rState =
448 xTempAccContext->getAccessibleStateSet();
449 if( rState.is() ) {
450 com::sun::star::uno::Sequence<short> pStates = rState->getStates();
451 int count = pStates.getLength();
452 for( int iIndex = 0;iIndex < count;iIndex++ )
454 if( pStates[iIndex] == AccessibleStateType::EDITABLE )
456 pStateSet->AddState (AccessibleStateType::EDITABLE);
457 pStateSet->AddState (AccessibleStateType::RESIZABLE);
458 pStateSet->AddState (AccessibleStateType::MOVEABLE);
459 break;
465 xStateSet = Reference<XAccessibleStateSet>(
466 new ::utl::AccessibleStateSetHelper (*pStateSet));
467 }else
469 ::utl::AccessibleStateSetHelper* pStateSet =
470 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
472 if (pStateSet != NULL)
474 // Merge current FOCUSED state from edit engine.
475 if (mpText != NULL)
477 if (mpText->HaveFocus())
478 pStateSet->AddState (AccessibleStateType::FOCUSED);
479 else
480 pStateSet->RemoveState (AccessibleStateType::FOCUSED);
482 //Just when the document is not read-only,set states EDITABLE,RESIZABLE,MOVEABLE
483 ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent();
484 if( xTempAcc.is() )
486 ::com::sun::star::uno::Reference<XAccessibleContext>
487 xTempAccContext = xTempAcc->getAccessibleContext();
488 if( xTempAccContext.is() )
490 ::com::sun::star::uno::Reference<XAccessibleStateSet> rState =
491 xTempAccContext->getAccessibleStateSet();
492 if( rState.is() ) {
493 com::sun::star::uno::Sequence<short> pStates = rState->getStates();
494 int count = pStates.getLength();
495 for( int iIndex = 0;iIndex < count;iIndex++ )
497 if( pStates[iIndex] == AccessibleStateType::EDITABLE )
499 pStateSet->AddState (AccessibleStateType::EDITABLE);
500 pStateSet->AddState (AccessibleStateType::RESIZABLE);
501 pStateSet->AddState (AccessibleStateType::MOVEABLE);
502 break;
508 // Create a copy of the state set that may be modified by the
509 // caller without affecting the current state set.
510 xStateSet = Reference<XAccessibleStateSet>(
511 new ::utl::AccessibleStateSetHelper (*pStateSet));
514 UpdateDocumentAllSelState(xStateSet);
515 return xStateSet;
521 //===== XAccessibleComponent ================================================
523 /** The implementation below is at the moment straightforward. It iterates
524 over all children (and thereby instances all children which have not
525 been already instatiated) until a child covering the specifed point is
526 found.
527 This leaves room for improvement. For instance, first iterate only over
528 the already instantiated children and only if no match is found
529 instantiate the remaining ones.
531 uno::Reference<XAccessible > SAL_CALL
532 AccessibleShape::getAccessibleAtPoint (
533 const awt::Point& aPoint)
534 throw (uno::RuntimeException, std::exception)
536 ::osl::MutexGuard aGuard (maMutex);
538 sal_Int32 nChildCount = getAccessibleChildCount ();
539 for (sal_Int32 i=0; i<nChildCount; ++i)
541 Reference<XAccessible> xChild (getAccessibleChild (i));
542 if (xChild.is())
544 Reference<XAccessibleComponent> xChildComponent (
545 xChild->getAccessibleContext(), uno::UNO_QUERY);
546 if (xChildComponent.is())
548 awt::Rectangle aBBox (xChildComponent->getBounds());
549 if ( (aPoint.X >= aBBox.X)
550 && (aPoint.Y >= aBBox.Y)
551 && (aPoint.X < aBBox.X+aBBox.Width)
552 && (aPoint.Y < aBBox.Y+aBBox.Height) )
553 return xChild;
558 // Have not found a child under the given point. Returning empty
559 // reference to indicate this.
560 return uno::Reference<XAccessible>();
566 awt::Rectangle SAL_CALL AccessibleShape::getBounds (void)
567 throw (::com::sun::star::uno::RuntimeException, std::exception)
569 SolarMutexGuard aSolarGuard;
570 ::osl::MutexGuard aGuard (maMutex);
572 ThrowIfDisposed ();
573 awt::Rectangle aBoundingBox;
574 if ( mxShape.is() )
577 static const OUString sBoundRectName ("BoundRect");
578 static const OUString sAnchorPositionName ("AnchorPosition");
580 // Get the shape's bounding box in internal coordinates (in 100th of
581 // mm). Use the property BoundRect. Only if that is not supported ask
582 // the shape for its position and size directly.
583 Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY);
584 Reference<beans::XPropertySetInfo> xSetInfo;
585 bool bFoundBoundRect = false;
586 if (xSet.is())
588 xSetInfo = xSet->getPropertySetInfo ();
589 if (xSetInfo.is())
591 if (xSetInfo->hasPropertyByName (sBoundRectName))
595 uno::Any aValue = xSet->getPropertyValue (sBoundRectName);
596 aValue >>= aBoundingBox;
597 bFoundBoundRect = true;
599 catch (beans::UnknownPropertyException const&)
601 // Handled below (bFoundBoundRect stays false).
604 else
605 OSL_TRACE (" no property BoundRect");
609 // Fallback when there is no BoundRect Property.
610 if ( ! bFoundBoundRect )
612 awt::Point aPosition (mxShape->getPosition());
613 awt::Size aSize (mxShape->getSize());
614 aBoundingBox = awt::Rectangle (
615 aPosition.X, aPosition.Y,
616 aSize.Width, aSize.Height);
618 // While BoundRects have absolute positions, the position returned
619 // by XPosition::getPosition is relative. Get the anchor position
620 // (usually not (0,0) for Writer shapes).
621 if (xSetInfo.is())
623 if (xSetInfo->hasPropertyByName (sAnchorPositionName))
625 uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName);
626 awt::Point aAnchorPosition;
627 aPos >>= aAnchorPosition;
628 aBoundingBox.X += aAnchorPosition.X;
629 aBoundingBox.Y += aAnchorPosition.Y;
634 // Transform coordinates from internal to pixel.
635 if (maShapeTreeInfo.GetViewForwarder() == NULL)
636 throw uno::RuntimeException (OUString (
637 "AccessibleShape has no valid view forwarder"),
638 static_cast<uno::XWeak*>(this));
639 ::Size aPixelSize = maShapeTreeInfo.GetViewForwarder()->LogicToPixel (
640 ::Size (aBoundingBox.Width, aBoundingBox.Height));
641 ::Point aPixelPosition = maShapeTreeInfo.GetViewForwarder()->LogicToPixel (
642 ::Point (aBoundingBox.X, aBoundingBox.Y));
644 // Clip the shape's bounding box with the bounding box of its parent.
645 Reference<XAccessibleComponent> xParentComponent (
646 getAccessibleParent(), uno::UNO_QUERY);
647 if (xParentComponent.is())
649 // Make the coordinates relative to the parent.
650 awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
651 int x = aPixelPosition.getX() - aParentLocation.X;
652 int y = aPixelPosition.getY() - aParentLocation.Y;
654 // Clip with parent (with coordinates relative to itself).
655 ::Rectangle aBBox (
656 x, y, x + aPixelSize.getWidth(), y + aPixelSize.getHeight());
657 awt::Size aParentSize (xParentComponent->getSize());
658 ::Rectangle aParentBBox (0,0, aParentSize.Width, aParentSize.Height);
659 aBBox = aBBox.GetIntersection (aParentBBox);
660 aBoundingBox = awt::Rectangle (
661 aBBox.getX(),
662 aBBox.getY(),
663 aBBox.getWidth(),
664 aBBox.getHeight());
666 else
668 OSL_TRACE ("parent does not support component");
669 aBoundingBox = awt::Rectangle (
670 aPixelPosition.getX(), aPixelPosition.getY(),
671 aPixelSize.getWidth(), aPixelSize.getHeight());
675 return aBoundingBox;
681 awt::Point SAL_CALL AccessibleShape::getLocation (void)
682 throw (::com::sun::star::uno::RuntimeException, std::exception)
684 ThrowIfDisposed ();
685 awt::Rectangle aBoundingBox (getBounds());
686 return awt::Point (aBoundingBox.X, aBoundingBox.Y);
692 awt::Point SAL_CALL AccessibleShape::getLocationOnScreen (void)
693 throw (::com::sun::star::uno::RuntimeException, std::exception)
695 ThrowIfDisposed ();
697 // Get relative position...
698 awt::Point aLocation (getLocation ());
700 // ... and add absolute position of the parent.
701 uno::Reference<XAccessibleComponent> xParentComponent (
702 getAccessibleParent(), uno::UNO_QUERY);
703 if (xParentComponent.is())
705 awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
706 aLocation.X += aParentLocation.X;
707 aLocation.Y += aParentLocation.Y;
709 else
710 OSL_TRACE ("getLocation: parent does not support XAccessibleComponent");
711 return aLocation;
717 awt::Size SAL_CALL AccessibleShape::getSize (void)
718 throw (uno::RuntimeException, std::exception)
720 ThrowIfDisposed ();
721 awt::Rectangle aBoundingBox (getBounds());
722 return awt::Size (aBoundingBox.Width, aBoundingBox.Height);
728 sal_Int32 SAL_CALL AccessibleShape::getForeground (void)
729 throw (::com::sun::star::uno::RuntimeException, std::exception)
731 ThrowIfDisposed ();
732 sal_Int32 nColor (0x0ffffffL);
736 uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY);
737 if (aSet.is())
739 uno::Any aColor;
740 aColor = aSet->getPropertyValue ("LineColor");
741 aColor >>= nColor;
744 catch (const ::com::sun::star::beans::UnknownPropertyException &)
746 // Ignore exception and return default color.
748 return nColor;
754 sal_Int32 SAL_CALL AccessibleShape::getBackground (void)
755 throw (::com::sun::star::uno::RuntimeException, std::exception)
757 ThrowIfDisposed ();
758 sal_Int32 nColor (0L);
762 uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY);
763 if (aSet.is())
765 uno::Any aColor;
766 aColor = aSet->getPropertyValue ("FillColor");
767 aColor >>= nColor;
768 aColor = aSet->getPropertyValue (OUString::createFromAscii ("FillTransparence"));
769 short nTrans=0;
770 aColor >>= nTrans;
771 Color crBk(nColor);
772 if (nTrans == 0 )
774 crBk.SetTransparency(0xff);
776 else
778 nTrans = short(256 - nTrans / 100. * 256);
779 crBk.SetTransparency(sal_uInt8(nTrans));
781 nColor = crBk.GetColor();
784 catch (const ::com::sun::star::beans::UnknownPropertyException &)
786 // Ignore exception and return default color.
788 return nColor;
794 //===== XAccessibleEventBroadcaster =========================================
796 void SAL_CALL AccessibleShape::addAccessibleEventListener (
797 const Reference<XAccessibleEventListener >& rxListener)
798 throw (uno::RuntimeException, std::exception)
800 if (rBHelper.bDisposed || rBHelper.bInDispose)
802 uno::Reference<uno::XInterface> xThis (
803 (lang::XComponent *)this, uno::UNO_QUERY);
804 rxListener->disposing (lang::EventObject (xThis));
806 else
808 AccessibleContextBase::addAccessibleEventListener (rxListener);
809 if (mpText != NULL)
810 mpText->AddEventListener (rxListener);
817 void SAL_CALL AccessibleShape::removeAccessibleEventListener (
818 const Reference<XAccessibleEventListener >& rxListener)
819 throw (uno::RuntimeException, std::exception)
821 AccessibleContextBase::removeAccessibleEventListener (rxListener);
822 if (mpText != NULL)
823 mpText->RemoveEventListener (rxListener);
829 //===== XInterface ==========================================================
831 com::sun::star::uno::Any SAL_CALL
832 AccessibleShape::queryInterface (const com::sun::star::uno::Type & rType)
833 throw (::com::sun::star::uno::RuntimeException, std::exception)
835 ::com::sun::star::uno::Any aReturn = AccessibleContextBase::queryInterface (rType);
836 if ( ! aReturn.hasValue())
837 aReturn = ::cppu::queryInterface (rType,
838 static_cast<XAccessibleComponent*>(this),
839 static_cast<XAccessibleExtendedComponent*>(this),
840 static_cast< ::com::sun::star::accessibility::XAccessibleSelection* >(this),
841 static_cast< ::com::sun::star::accessibility::XAccessibleExtendedAttributes* >(this),
842 static_cast<lang::XEventListener*>(this),
843 static_cast<document::XEventListener*>(this),
844 static_cast<lang::XUnoTunnel*>(this),
845 static_cast<XAccessibleGroupPosition*>(this),
846 static_cast<XAccessibleHypertext*>(this)
848 return aReturn;
854 void SAL_CALL
855 AccessibleShape::acquire (void)
856 throw ()
858 AccessibleContextBase::acquire ();
864 void SAL_CALL
865 AccessibleShape::release (void)
866 throw ()
868 AccessibleContextBase::release ();
871 //===== XAccessibleSelection ============================================
875 void SAL_CALL AccessibleShape::selectAccessibleChild( sal_Int32 )
876 throw ( IndexOutOfBoundsException, RuntimeException, std::exception )
881 sal_Bool SAL_CALL AccessibleShape::isAccessibleChildSelected( sal_Int32 nChildIndex )
882 throw ( IndexOutOfBoundsException,
883 RuntimeException, std::exception )
885 uno::Reference<XAccessible> xAcc = getAccessibleChild( nChildIndex );
886 uno::Reference<XAccessibleContext> xContext;
887 if( xAcc.is() )
889 xContext = xAcc->getAccessibleContext();
892 if( xContext.is() )
894 if( xContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
896 uno::Reference< ::com::sun::star::accessibility::XAccessibleText >
897 xText(xAcc, uno::UNO_QUERY);
898 if( xText.is() )
900 if( xText->getSelectionStart() >= 0 ) return sal_True;
903 else if( xContext->getAccessibleRole() == AccessibleRole::SHAPE )
905 Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet();
906 if( !pRState.is() )
907 return sal_False;
909 uno::Sequence<short> pStates = pRState->getStates();
910 int nCount = pStates.getLength();
911 for( int i = 0; i < nCount; i++ )
913 if(pStates[i] == AccessibleStateType::SELECTED)
914 return sal_True;
916 return sal_False;
920 return sal_False;
924 void SAL_CALL AccessibleShape::clearAccessibleSelection( )
925 throw ( RuntimeException, std::exception )
930 void SAL_CALL AccessibleShape::selectAllAccessibleChildren( )
931 throw ( RuntimeException, std::exception )
936 sal_Int32 SAL_CALL AccessibleShape::getSelectedAccessibleChildCount()
937 throw ( RuntimeException, std::exception )
939 sal_Int32 nCount = 0;
940 sal_Int32 TotalCount = getAccessibleChildCount();
941 for( sal_Int32 i = 0; i < TotalCount; i++ )
942 if( isAccessibleChildSelected(i) ) nCount++;
944 return nCount;
948 Reference<XAccessible> SAL_CALL AccessibleShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
949 throw ( IndexOutOfBoundsException, RuntimeException, std::exception)
951 if ( nSelectedChildIndex > getSelectedAccessibleChildCount() )
952 throw IndexOutOfBoundsException();
953 sal_Int32 i1, i2;
954 for( i1 = 0, i2 = 0; i1 < getAccessibleChildCount(); i1++ )
955 if( isAccessibleChildSelected(i1) )
957 if( i2 == nSelectedChildIndex )
958 return getAccessibleChild( i1 );
959 i2++;
961 return Reference<XAccessible>();
965 void SAL_CALL AccessibleShape::deselectAccessibleChild( sal_Int32 )
966 throw ( IndexOutOfBoundsException,
967 RuntimeException, std::exception )
972 //===== XAccessibleExtendedAttributes ========================================================
973 uno::Any SAL_CALL AccessibleShape::getExtendedAttributes()
974 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
976 uno::Any strRet;
977 OUString style;
978 if( getAccessibleRole() != AccessibleRole::SHAPE ) return strRet;
979 if( m_pShape )
981 style = "style:" + GetStyle();
983 style += ";";
984 strRet <<= style;
985 return strRet;
988 //===== XServiceInfo ========================================================
990 OUString SAL_CALL
991 AccessibleShape::getImplementationName (void)
992 throw (::com::sun::star::uno::RuntimeException, std::exception)
994 return OUString("AccessibleShape");
1000 uno::Sequence<OUString> SAL_CALL
1001 AccessibleShape::getSupportedServiceNames (void)
1002 throw (::com::sun::star::uno::RuntimeException, std::exception)
1004 ThrowIfDisposed ();
1005 // Get list of supported service names from base class...
1006 uno::Sequence<OUString> aServiceNames =
1007 AccessibleContextBase::getSupportedServiceNames();
1008 sal_Int32 nCount (aServiceNames.getLength());
1010 // ...and add additional names.
1011 aServiceNames.realloc (nCount + 1);
1012 static const OUString sAdditionalServiceName ("com.sun.star.drawing.AccessibleShape");
1013 aServiceNames[nCount] = sAdditionalServiceName;
1015 return aServiceNames;
1022 //===== XTypeProvider ===================================================
1024 uno::Sequence<uno::Type> SAL_CALL
1025 AccessibleShape::getTypes (void)
1026 throw (uno::RuntimeException, std::exception)
1028 ThrowIfDisposed ();
1029 // Get list of types from the context base implementation, ...
1030 uno::Sequence<uno::Type> aTypeList (AccessibleContextBase::getTypes());
1031 // ... get list of types from component base implementation, ...
1032 uno::Sequence<uno::Type> aComponentTypeList (AccessibleComponentBase::getTypes());
1033 // ... define local types, ...
1034 const uno::Type aLangEventListenerType =
1035 cppu::UnoType<lang::XEventListener>::get();
1036 const uno::Type aDocumentEventListenerType =
1037 cppu::UnoType<document::XEventListener>::get();
1038 const uno::Type aUnoTunnelType =
1039 cppu::UnoType<lang::XUnoTunnel>::get();
1041 // ... and merge them all into one list.
1042 sal_Int32 nTypeCount (aTypeList.getLength()),
1043 nComponentTypeCount (aComponentTypeList.getLength());
1044 int i;
1046 aTypeList.realloc (nTypeCount + nComponentTypeCount + 3);
1048 for (i=0; i<nComponentTypeCount; i++)
1049 aTypeList[nTypeCount + i] = aComponentTypeList[i];
1051 aTypeList[nTypeCount + i++ ] = aLangEventListenerType;
1052 aTypeList[nTypeCount + i++ ] = aDocumentEventListenerType;
1053 aTypeList[nTypeCount + i ] = aUnoTunnelType;
1055 return aTypeList;
1061 //===== lang::XEventListener ================================================
1063 /** Disposing calls are accepted only from the model: Just reset the
1064 reference to the model in the shape tree info. Otherwise this object
1065 remains functional.
1067 void SAL_CALL
1068 AccessibleShape::disposing (const lang::EventObject& aEvent)
1069 throw (uno::RuntimeException, std::exception)
1071 SolarMutexGuard aSolarGuard;
1072 ::osl::MutexGuard aGuard (maMutex);
1076 if (aEvent.Source == maShapeTreeInfo.GetModelBroadcaster())
1078 // Remove reference to model broadcaster to allow it to pass
1079 // away.
1080 maShapeTreeInfo.SetModelBroadcaster(NULL);
1084 catch (uno::RuntimeException const&)
1086 OSL_TRACE ("caught exception while disposing");
1093 //===== document::XEventListener ============================================
1095 void SAL_CALL
1096 AccessibleShape::notifyEvent (const document::EventObject& rEventObject)
1097 throw (uno::RuntimeException, std::exception)
1099 static const OUString sShapeModified ("ShapeModified");
1101 // First check if the event is for us.
1102 uno::Reference<drawing::XShape> xShape (
1103 rEventObject.Source, uno::UNO_QUERY);
1104 if ( xShape.get() == mxShape.get() )
1106 if (rEventObject.EventName.equals (sShapeModified))
1108 //Need to update text children when receiving ShapeModified hint when exiting edit mode for text box
1109 if (mpText)
1110 mpText->UpdateChildren();
1113 // Some property of a shape has been modified. Send an event
1114 // that indicates a change of the visible data to all listeners.
1115 CommitChange (
1116 AccessibleEventId::VISIBLE_DATA_CHANGED,
1117 uno::Any(),
1118 uno::Any());
1120 // Name and Description may have changed. Update the local
1121 // values accordingly.
1122 UpdateNameAndDescription();
1127 //===== lang::XUnoTunnel ================================================
1129 namespace
1131 class theAccessibleShapeImplementationId : public rtl::Static< UnoTunnelIdInit, theAccessibleShapeImplementationId > {};
1134 const uno::Sequence< sal_Int8 >&
1135 AccessibleShape::getUnoTunnelImplementationId()
1136 throw()
1138 return theAccessibleShapeImplementationId::get().getSeq();
1142 AccessibleShape*
1143 AccessibleShape::getImplementation( const uno::Reference< uno::XInterface >& rxIFace )
1144 throw()
1146 uno::Reference< lang::XUnoTunnel > xTunnel( rxIFace, uno::UNO_QUERY );
1147 AccessibleShape* pReturn = NULL;
1149 if( xTunnel.is() )
1150 pReturn = reinterpret_cast< AccessibleShape* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) );
1152 return( pReturn );
1156 sal_Int64 SAL_CALL
1157 AccessibleShape::getSomething( const uno::Sequence< sal_Int8 >& rIdentifier )
1158 throw(uno::RuntimeException, std::exception)
1160 sal_Int64 nReturn( 0 );
1162 if( ( rIdentifier.getLength() == 16 ) && ( 0 == memcmp( getUnoTunnelImplementationId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) )
1163 nReturn = reinterpret_cast< sal_Int64 >( this );
1165 return( nReturn );
1168 //===== IAccessibleViewForwarderListener ====================================
1170 void AccessibleShape::ViewForwarderChanged (ChangeType aChangeType,
1171 const IAccessibleViewForwarder* pViewForwarder)
1173 // Inform all listeners that the graphical representation (i.e. size
1174 // and/or position) of the shape has changed.
1175 CommitChange (AccessibleEventId::VISIBLE_DATA_CHANGED,
1176 uno::Any(),
1177 uno::Any());
1179 // Tell children manager of the modified view forwarder.
1180 if (mpChildrenManager != NULL)
1181 mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder);
1183 // update our children that our screen position might have changed
1184 if( mpText )
1185 mpText->UpdateChildren();
1191 //===== protected internal ==================================================
1192 /// Set this object's name if is different to the current name.
1193 OUString AccessibleShape::CreateAccessibleBaseName (void)
1194 throw (::com::sun::star::uno::RuntimeException)
1196 return ShapeTypeHandler::CreateAccessibleBaseName( mxShape );
1200 OUString AccessibleShape::CreateAccessibleName (void)
1201 throw (::com::sun::star::uno::RuntimeException)
1203 return GetFullAccessibleName(this);
1206 OUString AccessibleShape::GetFullAccessibleName (AccessibleShape *shape)
1207 throw (::com::sun::star::uno::RuntimeException)
1209 OUString sName (shape->CreateAccessibleBaseName());
1210 // Append the shape's index to the name to disambiguate between shapes
1211 // of the same type. If such an index where not given to the
1212 // constructor then use the z-order instead. If even that does not exist
1213 // we throw an exception.
1214 OUString nameStr;
1215 if (shape->m_pShape)
1216 nameStr = shape->m_pShape->GetName();
1217 if (nameStr.isEmpty())
1219 sName += " ";
1221 else
1223 sName = nameStr;
1226 //If the new produced name if not the same with last,notify name changed
1227 //Event
1228 if (aAccName != sName && !aAccName.isEmpty())
1230 uno::Any aOldValue, aNewValue;
1231 aOldValue <<= aAccName;
1232 aNewValue <<= sName;
1233 CommitChange(
1234 AccessibleEventId::NAME_CHANGED,
1235 aNewValue,
1236 aOldValue);
1238 aAccName = sName;
1239 return sName;
1242 OUString
1243 AccessibleShape::CreateAccessibleDescription (void)
1244 throw (::com::sun::star::uno::RuntimeException)
1246 DescriptionGenerator aDG (mxShape);
1247 aDG.Initialize (CreateAccessibleBaseName());
1248 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
1250 case DRAWING_3D_CUBE:
1251 case DRAWING_3D_EXTRUDE:
1252 case DRAWING_3D_LATHE:
1253 case DRAWING_3D_SPHERE:
1254 aDG.Add3DProperties ();
1255 break;
1257 case DRAWING_3D_SCENE:
1258 case DRAWING_GROUP:
1259 case DRAWING_PAGE:
1260 // No further information is appended.
1261 break;
1263 case DRAWING_CAPTION:
1264 case DRAWING_CLOSED_BEZIER:
1265 case DRAWING_CLOSED_FREEHAND:
1266 case DRAWING_ELLIPSE:
1267 case DRAWING_POLY_POLYGON:
1268 case DRAWING_POLY_POLYGON_PATH:
1269 case DRAWING_RECTANGLE:
1270 aDG.AddLineProperties ();
1271 aDG.AddFillProperties ();
1272 break;
1274 case DRAWING_CONNECTOR:
1275 case DRAWING_LINE:
1276 case DRAWING_MEASURE:
1277 case DRAWING_OPEN_BEZIER:
1278 case DRAWING_OPEN_FREEHAND:
1279 case DRAWING_POLY_LINE:
1280 case DRAWING_POLY_LINE_PATH:
1281 aDG.AddLineProperties ();
1282 break;
1284 case DRAWING_CONTROL:
1285 aDG.AddProperty ("ControlBackground", DescriptionGenerator::COLOR, "");
1286 aDG.AddProperty ("ControlBorder", DescriptionGenerator::INTEGER, "");
1287 break;
1289 case DRAWING_TEXT:
1290 aDG.AddTextProperties ();
1291 break;
1293 default:
1294 aDG.Initialize ("Unknown accessible shape");
1295 uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY);
1296 if (xDescriptor.is())
1298 aDG.AppendString ("service name=");
1299 aDG.AppendString (xDescriptor->getShapeType());
1303 return aDG();
1309 uno::Reference< drawing::XShape > AccessibleShape::GetXShape()
1311 return( mxShape );
1316 // protected
1317 void AccessibleShape::disposing (void)
1319 SolarMutexGuard aSolarGuard;
1320 ::osl::MutexGuard aGuard (maMutex);
1322 // Make sure to send an event that this object loses the focus in the
1323 // case that it has the focus.
1324 ::utl::AccessibleStateSetHelper* pStateSet =
1325 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
1326 if (pStateSet != NULL)
1327 pStateSet->RemoveState (AccessibleStateType::FOCUSED);
1329 // Unregister from broadcasters.
1330 Reference<lang::XComponent> xComponent (mxShape, uno::UNO_QUERY);
1331 if (xComponent.is())
1332 xComponent->removeEventListener (this);
1334 // Unregister from model.
1335 if (maShapeTreeInfo.GetModelBroadcaster().is())
1336 maShapeTreeInfo.GetModelBroadcaster()->removeEventListener (
1337 static_cast<document::XEventListener*>(this));
1339 // Release the child containers.
1340 if (mpChildrenManager != NULL)
1342 delete mpChildrenManager;
1343 mpChildrenManager = NULL;
1345 if (mpText != NULL)
1347 mpText->Dispose();
1348 delete mpText;
1349 mpText = NULL;
1352 // Cleanup. Remove references to objects to allow them to be
1353 // destroyed.
1354 mxShape = NULL;
1355 maShapeTreeInfo = AccessibleShapeTreeInfo();
1357 // Call base classes.
1358 AccessibleContextBase::dispose ();
1361 sal_Int32 SAL_CALL
1362 AccessibleShape::getAccessibleIndexInParent (void)
1363 throw (::com::sun::star::uno::RuntimeException, std::exception)
1365 ThrowIfDisposed ();
1366 // Use a simple but slow solution for now. Optimize later.
1368 sal_Int32 nIndex = m_nIndexInParent;
1369 if ( -1 == nIndex )
1370 nIndex = AccessibleContextBase::getAccessibleIndexInParent();
1371 return nIndex;
1377 void AccessibleShape::UpdateNameAndDescription (void)
1379 // Ignore missing title, name, or description. There are fallbacks for
1380 // them.
1383 Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY_THROW);
1384 OUString sString;
1386 // Get the accessible name.
1387 sString = GetOptionalProperty(xSet, "Title");
1388 if (!sString.isEmpty())
1390 SetAccessibleName(sString, AccessibleContextBase::FromShape);
1392 else
1394 sString = GetOptionalProperty(xSet, "Name");
1395 if (!sString.isEmpty())
1396 SetAccessibleName(sString, AccessibleContextBase::FromShape);
1399 // Get the accessible description.
1400 sString = GetOptionalProperty(xSet, "Description");
1401 if (!sString.isEmpty())
1402 SetAccessibleDescription(sString, AccessibleContextBase::FromShape);
1404 catch (uno::RuntimeException&)
1409 // Return this object's role.
1410 sal_Int16 SAL_CALL AccessibleShape::getAccessibleRole (void)
1411 throw (::com::sun::star::uno::RuntimeException, std::exception)
1413 sal_Int16 nAccessibleRole = AccessibleRole::SHAPE ;
1414 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
1416 case DRAWING_GRAPHIC_OBJECT:
1417 nAccessibleRole = AccessibleRole::GRAPHIC ; break;
1418 case DRAWING_OLE:
1419 nAccessibleRole = AccessibleRole::EMBEDDED_OBJECT ; break;
1421 default:
1422 nAccessibleRole = AccessibleContextBase::getAccessibleRole();
1423 break;
1426 return nAccessibleRole;
1430 void AccessibleShape::UpdateDocumentAllSelState(Reference<XAccessibleStateSet> &xStateSet)
1432 if (mpParent && mpParent->IsDocumentSelAll())
1434 ::utl::AccessibleStateSetHelper* pStateSet =
1435 static_cast< ::utl::AccessibleStateSetHelper*>(xStateSet.get());
1436 pStateSet->AddState (AccessibleStateType::SELECTED);
1438 //uno::Any NewValue;
1439 //NewValue <<= AccessibleStateType::SELECTED;
1441 //CommitChange(AccessibleEventId::STATE_CHANGED,NewValue,uno::Any());
1445 //sort the drawing objects from up to down, from left to right
1446 struct XShapePosCompareHelper
1448 bool operator() ( const uno::Reference<drawing::XShape>& xshape1,
1449 const uno::Reference<drawing::XShape>& xshape2 ) const
1451 SdrObject* pObj1 = GetSdrObjectFromXShape(xshape1);
1452 SdrObject* pObj2 = GetSdrObjectFromXShape(xshape2);
1453 if(pObj1 && pObj2)
1454 return pObj1->GetOrdNum() < pObj2->GetOrdNum();
1455 else
1456 return false;
1459 //end of group position
1461 //===== XAccessibleGroupPosition =========================================
1462 uno::Sequence< sal_Int32 > SAL_CALL
1463 AccessibleShape::getGroupPosition( const uno::Any& )
1464 throw (uno::RuntimeException, std::exception)
1466 // we will return the:
1467 // [0] group level
1468 // [1] similar items counts in the group
1469 // [2] the position of the object in the group
1470 uno::Sequence< sal_Int32 > aRet( 3 );
1471 aRet[0] = 0;
1472 aRet[1] = 0;
1473 aRet[2] = 0;
1475 ::com::sun::star::uno::Reference<XAccessible> xParent = getAccessibleParent();
1476 if (!xParent.is())
1478 return aRet;
1480 SdrObject *pObj = GetSdrObjectFromXShape(mxShape);
1483 if(pObj == NULL )
1485 return aRet;
1488 // Compute object's group level.
1489 sal_Int32 nGroupLevel = 0;
1490 SdrObject * pUper = pObj->GetUpGroup();
1491 while( pUper )
1493 ++nGroupLevel;
1494 pUper = pUper->GetUpGroup();
1497 ::com::sun::star::uno::Reference<XAccessibleContext> xParentContext = xParent->getAccessibleContext();
1498 if( xParentContext->getAccessibleRole() == AccessibleRole::DOCUMENT ||
1499 xParentContext->getAccessibleRole() == AccessibleRole::DOCUMENT_PRESENTATION ||
1500 xParentContext->getAccessibleRole() == AccessibleRole::DOCUMENT_SPREADSHEET ||
1501 xParentContext->getAccessibleRole() == AccessibleRole::DOCUMENT_TEXT )//Document
1503 Reference< XAccessibleGroupPosition > xGroupPosition( xParent,uno::UNO_QUERY );
1504 if ( xGroupPosition.is() )
1506 aRet = xGroupPosition->getGroupPosition( uno::makeAny( getAccessibleContext() ) );
1508 return aRet;
1510 if (xParentContext->getAccessibleRole() != AccessibleRole::SHAPE)
1512 return aRet;
1515 SdrObjList *pGrpList = NULL;
1516 if( pObj->GetUpGroup() )
1517 pGrpList = pObj->GetUpGroup()->GetSubList();
1518 else
1519 return aRet;
1521 std::vector< uno::Reference<drawing::XShape> > vXShapes;
1522 if (pGrpList)
1524 const sal_Int32 nObj = pGrpList->GetObjCount();
1525 for(sal_Int32 i = 0 ; i < nObj ; ++i)
1527 SdrObject *pSubObj = pGrpList->GetObj(i);
1528 if (pSubObj &&
1529 xParentContext->getAccessibleChild(i)->getAccessibleContext()->getAccessibleRole() != AccessibleRole::GROUP_BOX)
1531 vXShapes.push_back( GetXShapeForSdrObject(pSubObj) );
1536 std::sort( vXShapes.begin(), vXShapes.end(), XShapePosCompareHelper() );
1538 //get the the index of the selected object in the group
1539 std::vector< uno::Reference<drawing::XShape> >::iterator aIter;
1540 //we start counting position from 1
1541 sal_Int32 nPos = 1;
1542 for ( aIter = vXShapes.begin(); aIter != vXShapes.end(); ++aIter, nPos++ )
1544 if ( (*aIter).get() == mxShape.get() )
1546 sal_Int32* pArray = aRet.getArray();
1547 pArray[0] = nGroupLevel;
1548 pArray[1] = vXShapes.size();
1549 pArray[2] = nPos;
1550 break;
1554 return aRet;
1557 OUString AccessibleShape::getObjectLink( const uno::Any& )
1558 throw (uno::RuntimeException, std::exception)
1560 OUString aRet;
1562 SdrObject *pObj = GetSdrObjectFromXShape(mxShape);
1563 if(pObj == NULL )
1565 return aRet;
1567 if (maShapeTreeInfo.GetDocumentWindow().is())
1569 Reference< XAccessibleGroupPosition > xGroupPosition( maShapeTreeInfo.GetDocumentWindow(), uno::UNO_QUERY );
1570 if (xGroupPosition.is())
1572 aRet = xGroupPosition->getObjectLink( uno::makeAny( getAccessibleContext() ) );
1575 return aRet;
1578 //===== XAccesibleHypertext ==================================================
1579 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkCount()
1580 throw (::com::sun::star::uno::RuntimeException, std::exception)
1582 // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile.
1583 // Code need to be adapted....
1584 return 0;
1587 SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this);
1588 if (pLink->IsValidHyperlink())
1589 return 1;
1590 else
1591 return 0;
1594 uno::Reference< XAccessibleHyperlink > SAL_CALL
1595 AccessibleShape::getHyperLink( sal_Int32 )
1596 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
1598 uno::Reference< XAccessibleHyperlink > xRet;
1599 // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile.
1600 // Code need to be adapted....
1602 SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this);
1603 if (pLink->IsValidHyperlink())
1604 xRet = pLink;
1605 if( !xRet.is() )
1606 throw ::com::sun::star::lang::IndexOutOfBoundsException();
1608 return xRet;
1610 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkIndex( sal_Int32 )
1611 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
1613 sal_Int32 nRet = 0;
1614 return nRet;
1616 //===== XAccesibleText ==================================================
1617 sal_Int32 SAL_CALL AccessibleShape::getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1618 sal_Bool SAL_CALL AccessibleShape::setCaretPosition( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1619 sal_Unicode SAL_CALL AccessibleShape::getCharacter( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1620 ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleShape::getCharacterAttributes( sal_Int32, const ::com::sun::star::uno::Sequence< OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
1622 uno::Sequence< ::com::sun::star::beans::PropertyValue > aValues(0);
1623 return aValues;
1625 ::com::sun::star::awt::Rectangle SAL_CALL AccessibleShape::getCharacterBounds( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
1627 return com::sun::star::awt::Rectangle(0, 0, 0, 0 );
1629 sal_Int32 SAL_CALL AccessibleShape::getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1630 sal_Int32 SAL_CALL AccessibleShape::getIndexAtPoint( const ::com::sun::star::awt::Point& ) throw (::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1631 OUString SAL_CALL AccessibleShape::getSelectedText( ) throw (::com::sun::star::uno::RuntimeException, std::exception){return OUString();}
1632 sal_Int32 SAL_CALL AccessibleShape::getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1633 sal_Int32 SAL_CALL AccessibleShape::getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1634 sal_Bool SAL_CALL AccessibleShape::setSelection( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception){return sal_True;}
1635 OUString SAL_CALL AccessibleShape::getText( ) throw (::com::sun::star::uno::RuntimeException, std::exception){return OUString();}
1636 OUString SAL_CALL AccessibleShape::getTextRange( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception){return OUString();}
1637 ::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, std::exception)
1639 ::com::sun::star::accessibility::TextSegment aResult;
1640 return aResult;
1642 ::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, std::exception)
1644 ::com::sun::star::accessibility::TextSegment aResult;
1645 return aResult;
1647 ::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, std::exception)
1649 ::com::sun::star::accessibility::TextSegment aResult;
1650 return aResult;
1652 sal_Bool SAL_CALL AccessibleShape::copyText( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception){return sal_True;}
1654 } // end of namespace accessibility
1656 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */