bump product version to 5.0.4.1
[LibreOffice.git] / svx / source / accessibility / AccessibleShape.cxx
blob2f9c3741a50eb13051c9b13d86add1f0b139c0c1
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 <cppuhelper/queryinterface.hxx>
55 #include <comphelper/servicehelper.hxx>
56 #include "AccessibleEmptyEditSource.hxx"
58 #include <algorithm>
59 #include <memory>
60 #include <utility>
62 using namespace ::com::sun::star;
63 using namespace ::com::sun::star::accessibility;
64 using ::com::sun::star::uno::Reference;
65 using ::com::sun::star::lang::IndexOutOfBoundsException;
66 using ::com::sun::star::uno::RuntimeException;
68 namespace accessibility {
70 namespace {
72 OUString GetOptionalProperty (
73 const Reference<beans::XPropertySet>& rxSet,
74 const OUString& rsPropertyName)
76 OUString sValue;
78 if (rxSet.is())
80 const Reference<beans::XPropertySetInfo> xInfo (rxSet->getPropertySetInfo());
81 if ( ! xInfo.is() || xInfo->hasPropertyByName(rsPropertyName))
83 try
85 rxSet->getPropertyValue(rsPropertyName) >>= sValue;
87 catch (beans::UnknownPropertyException&)
89 // This exception should only be thrown when the property
90 // does not exits (of course) and the XPropertySetInfo is
91 // not available.
95 return sValue;
98 } // end of anonymous namespace
100 // internal
101 AccessibleShape::AccessibleShape (
102 const AccessibleShapeInfo& rShapeInfo,
103 const AccessibleShapeTreeInfo& rShapeTreeInfo)
104 : AccessibleContextBase (rShapeInfo.mxParent,AccessibleRole::SHAPE),
105 mpChildrenManager(NULL),
106 mxShape (rShapeInfo.mxShape),
107 maShapeTreeInfo (rShapeTreeInfo),
108 mnIndex (rShapeInfo.mnIndex),
109 m_nIndexInParent(-1),
110 mpText (NULL),
111 mpParent (rShapeInfo.mpChildrenManager)
113 m_pShape = GetSdrObjectFromXShape(mxShape);
114 UpdateNameAndDescription();
117 AccessibleShape::~AccessibleShape()
119 delete mpChildrenManager;
120 delete mpText;
121 OSL_TRACE ("~AccessibleShape");
123 // Unregistering from the various broadcasters should be unnecessary
124 // since this destructor would not have been called if one of the
125 // broadcasters would still hold a strong reference to this object.
128 void AccessibleShape::Init()
130 // Update the OPAQUE and SELECTED shape.
131 UpdateStates ();
133 // Create a children manager when this shape has children of its own.
134 Reference<drawing::XShapes> xShapes (mxShape, uno::UNO_QUERY);
135 if (xShapes.is() && xShapes->getCount() > 0)
136 mpChildrenManager = new ChildrenManager (
137 this, xShapes, maShapeTreeInfo, *this);
138 if (mpChildrenManager != NULL)
139 mpChildrenManager->Update();
141 // Register at model as document::XEventListener.
142 if (maShapeTreeInfo.GetModelBroadcaster().is())
143 maShapeTreeInfo.GetModelBroadcaster()->addEventListener (
144 static_cast<document::XEventListener*>(this));
146 // Beware! Here we leave the paths of the UNO API and descend into the
147 // depths of the core. Necessary for making the edit engine
148 // accessible.
149 Reference<text::XText> xText (mxShape, uno::UNO_QUERY);
150 if (xText.is())
152 SdrView* pView = maShapeTreeInfo.GetSdrView ();
153 const vcl::Window* pWindow = maShapeTreeInfo.GetWindow ();
154 if (pView != NULL && pWindow != NULL && mxShape.is())
156 // #107948# Determine whether shape text is empty
157 SdrObject* pSdrObject = GetSdrObjectFromXShape(mxShape);
158 if( pSdrObject )
160 SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, pSdrObject );
161 OutlinerParaObject* pOutlinerParaObject = NULL;
163 if( pTextObj )
164 pOutlinerParaObject = pTextObj->GetEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active
166 bool bOwnParaObj = pOutlinerParaObject != NULL;
168 if( !pOutlinerParaObject && pSdrObject )
169 pOutlinerParaObject = pSdrObject->GetOutlinerParaObject();
171 // create AccessibleTextHelper to handle this shape's text
172 if( !pOutlinerParaObject )
174 // empty text -> use proxy edit source to delay creation of EditEngine
175 ::std::unique_ptr<SvxEditSource> pEditSource( new AccessibleEmptyEditSource ( *pSdrObject, *pView, *pWindow) );
176 mpText = new AccessibleTextHelper( std::move(pEditSource) );
178 else
180 // non-empty text -> use full-fledged edit source right away
181 ::std::unique_ptr<SvxEditSource> pEditSource( new SvxTextEditSource ( *pSdrObject, 0, *pView, *pWindow) );
182 mpText = new AccessibleTextHelper( std::move(pEditSource) );
185 if( bOwnParaObj )
186 delete pOutlinerParaObject;
188 mpText->SetEventSource(this);
197 void AccessibleShape::UpdateStates()
199 ::utl::AccessibleStateSetHelper* pStateSet =
200 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
201 if (pStateSet == NULL)
202 return;
204 // Set the opaque state for certain shape types when their fill style is
205 // solid.
206 bool bShapeIsOpaque = false;
207 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
209 case DRAWING_PAGE:
210 case DRAWING_RECTANGLE:
211 case DRAWING_TEXT:
213 uno::Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY);
214 if (xSet.is())
218 drawing::FillStyle aFillStyle;
219 bShapeIsOpaque = ( xSet->getPropertyValue ("FillStyle") >>= aFillStyle)
220 && aFillStyle == drawing::FillStyle_SOLID;
222 catch (::com::sun::star::beans::UnknownPropertyException&)
224 // Ignore.
229 if (bShapeIsOpaque)
230 pStateSet->AddState (AccessibleStateType::OPAQUE);
231 else
232 pStateSet->RemoveState (AccessibleStateType::OPAQUE);
234 // Set the selected state.
235 bool bShapeIsSelected = false;
236 // XXX fix_me this has to be done with an extra interface later on
237 if ( m_pShape && maShapeTreeInfo.GetSdrView() )
239 bShapeIsSelected = maShapeTreeInfo.GetSdrView()->IsObjMarked(m_pShape);
242 if (bShapeIsSelected)
243 pStateSet->AddState (AccessibleStateType::SELECTED);
244 else
245 pStateSet->RemoveState (AccessibleStateType::SELECTED);
248 OUString AccessibleShape::GetStyle()
250 return ShapeTypeHandler::CreateAccessibleBaseName( mxShape );
253 bool AccessibleShape::operator== (const AccessibleShape& rShape)
255 return this==&rShape;
261 bool AccessibleShape::SetState (sal_Int16 aState)
263 bool bStateHasChanged = false;
265 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
267 // Offer FOCUSED state to edit engine and detect whether the state
268 // changes.
269 bool bIsFocused = mpText->HaveFocus ();
270 mpText->SetFocus (true);
271 bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
273 else
274 bStateHasChanged = AccessibleContextBase::SetState (aState);
276 return bStateHasChanged;
282 bool AccessibleShape::ResetState (sal_Int16 aState)
284 bool bStateHasChanged = false;
286 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
288 // Try to remove FOCUSED state from the edit engine and detect
289 // whether the state changes.
290 bool bIsFocused = mpText->HaveFocus ();
291 mpText->SetFocus (false);
292 bStateHasChanged = (bIsFocused != mpText->HaveFocus ());
294 else
295 bStateHasChanged = AccessibleContextBase::ResetState (aState);
297 return bStateHasChanged;
303 bool AccessibleShape::GetState (sal_Int16 aState)
305 if (aState == AccessibleStateType::FOCUSED && mpText != NULL)
307 // Just delegate the call to the edit engine. The state is not
308 // merged into the state set.
309 return mpText->HaveFocus();
311 else
312 return AccessibleContextBase::GetState (aState);
315 // OverWrite the parent's getAccessibleName method
316 OUString SAL_CALL AccessibleShape::getAccessibleName()
317 throw (::com::sun::star::uno::RuntimeException, std::exception)
319 ThrowIfDisposed ();
320 if (m_pShape && !m_pShape->GetTitle().isEmpty())
321 return CreateAccessibleName() + " " + m_pShape->GetTitle();
322 else
323 return CreateAccessibleName();
326 OUString SAL_CALL AccessibleShape::getAccessibleDescription()
327 throw (::com::sun::star::uno::RuntimeException, std::exception)
329 ThrowIfDisposed ();
330 if( m_pShape && !m_pShape->GetDescription().isEmpty())
331 return m_pShape->GetDescription() ;
332 else
333 return OUString(" ");
336 // XAccessibleContext
337 /** The children of this shape come from two sources: The children from
338 group or scene shapes and the paragraphs of text.
340 sal_Int32 SAL_CALL
341 AccessibleShape::getAccessibleChildCount ()
342 throw (::com::sun::star::uno::RuntimeException, std::exception)
344 ThrowIfDisposed ();
345 sal_Int32 nChildCount = 0;
347 // Add the number of shapes that are children of this shape.
348 if (mpChildrenManager != NULL)
349 nChildCount += mpChildrenManager->GetChildCount ();
350 // Add the number text paragraphs.
351 if (mpText != NULL)
352 nChildCount += mpText->GetChildCount ();
354 return nChildCount;
360 /** Forward the request to the shape. Return the requested shape or throw
361 an exception for a wrong index.
363 uno::Reference<XAccessible> SAL_CALL
364 AccessibleShape::getAccessibleChild (sal_Int32 nIndex)
365 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
367 ThrowIfDisposed ();
369 uno::Reference<XAccessible> xChild;
371 // Depending on the index decide whether to delegate this call to the
372 // children manager or the edit engine.
373 if ((mpChildrenManager != NULL)
374 && (nIndex < mpChildrenManager->GetChildCount()))
376 xChild = mpChildrenManager->GetChild (nIndex);
378 else if (mpText != NULL)
380 sal_Int32 nI = nIndex;
381 if (mpChildrenManager != NULL)
382 nI -= mpChildrenManager->GetChildCount();
383 xChild = mpText->GetChild (nI);
385 else
386 throw lang::IndexOutOfBoundsException (
387 "shape has no child with index " + OUString::number(nIndex),
388 static_cast<uno::XWeak*>(this));
390 return xChild;
393 uno::Reference<XAccessibleRelationSet> SAL_CALL
394 AccessibleShape::getAccessibleRelationSet()
395 throw (::com::sun::star::uno::RuntimeException, std::exception)
397 ::osl::MutexGuard aGuard (maMutex);
398 if (mpParent == NULL)
399 return uno::Reference<XAccessibleRelationSet>();
401 ::utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper;
403 //this mxshape is the captioned shape
404 uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1);
405 aSequence[0] = mpParent->GetAccessibleCaption(mxShape);
406 if(aSequence[0].get())
408 pRelationSet->AddRelation(
409 AccessibleRelation( AccessibleRelationType::DESCRIBED_BY, aSequence ) );
411 return uno::Reference<XAccessibleRelationSet>(pRelationSet);
414 /** Return a copy of the state set.
415 Possible states are:
416 ENABLED
417 SHOWING
418 VISIBLE
420 uno::Reference<XAccessibleStateSet> SAL_CALL
421 AccessibleShape::getAccessibleStateSet()
422 throw (::com::sun::star::uno::RuntimeException, std::exception)
424 ::osl::MutexGuard aGuard (maMutex);
425 Reference<XAccessibleStateSet> xStateSet;
427 if (rBHelper.bDisposed || mpText == NULL)
428 // Return a minimal state set that only contains the DEFUNC state.
430 xStateSet = AccessibleContextBase::getAccessibleStateSet ();
431 ::utl::AccessibleStateSetHelper* pStateSet =
432 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
433 ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent();
434 if( xTempAcc.is() )
436 ::com::sun::star::uno::Reference<XAccessibleContext>
437 xTempAccContext = xTempAcc->getAccessibleContext();
438 if( xTempAccContext.is() )
440 ::com::sun::star::uno::Reference<XAccessibleStateSet> rState =
441 xTempAccContext->getAccessibleStateSet();
442 if( rState.is() ) {
443 com::sun::star::uno::Sequence<short> pStates = rState->getStates();
444 int count = pStates.getLength();
445 for( int iIndex = 0;iIndex < count;iIndex++ )
447 if( pStates[iIndex] == AccessibleStateType::EDITABLE )
449 pStateSet->AddState (AccessibleStateType::EDITABLE);
450 pStateSet->AddState (AccessibleStateType::RESIZABLE);
451 pStateSet->AddState (AccessibleStateType::MOVEABLE);
452 break;
458 xStateSet = Reference<XAccessibleStateSet>(
459 new ::utl::AccessibleStateSetHelper (*pStateSet));
460 }else
462 ::utl::AccessibleStateSetHelper* pStateSet =
463 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
465 if (pStateSet != NULL)
467 // Merge current FOCUSED state from edit engine.
468 if (mpText != NULL)
470 if (mpText->HaveFocus())
471 pStateSet->AddState (AccessibleStateType::FOCUSED);
472 else
473 pStateSet->RemoveState (AccessibleStateType::FOCUSED);
475 //Just when the document is not read-only,set states EDITABLE,RESIZABLE,MOVEABLE
476 ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent();
477 if( xTempAcc.is() )
479 ::com::sun::star::uno::Reference<XAccessibleContext>
480 xTempAccContext = xTempAcc->getAccessibleContext();
481 if( xTempAccContext.is() )
483 ::com::sun::star::uno::Reference<XAccessibleStateSet> rState =
484 xTempAccContext->getAccessibleStateSet();
485 if( rState.is() ) {
486 com::sun::star::uno::Sequence<short> pStates = rState->getStates();
487 int count = pStates.getLength();
488 for( int iIndex = 0;iIndex < count;iIndex++ )
490 if( pStates[iIndex] == AccessibleStateType::EDITABLE )
492 pStateSet->AddState (AccessibleStateType::EDITABLE);
493 pStateSet->AddState (AccessibleStateType::RESIZABLE);
494 pStateSet->AddState (AccessibleStateType::MOVEABLE);
495 break;
501 // Create a copy of the state set that may be modified by the
502 // caller without affecting the current state set.
503 xStateSet = Reference<XAccessibleStateSet>(
504 new ::utl::AccessibleStateSetHelper (*pStateSet));
507 UpdateDocumentAllSelState(xStateSet);
508 return xStateSet;
511 // XAccessibleComponent
512 /** The implementation below is at the moment straightforward. It iterates
513 over all children (and thereby instances all children which have not
514 been already instatiated) until a child covering the specifed point is
515 found.
516 This leaves room for improvement. For instance, first iterate only over
517 the already instantiated children and only if no match is found
518 instantiate the remaining ones.
520 uno::Reference<XAccessible > SAL_CALL
521 AccessibleShape::getAccessibleAtPoint (
522 const awt::Point& aPoint)
523 throw (uno::RuntimeException, std::exception)
525 ::osl::MutexGuard aGuard (maMutex);
527 sal_Int32 nChildCount = getAccessibleChildCount ();
528 for (sal_Int32 i=0; i<nChildCount; ++i)
530 Reference<XAccessible> xChild (getAccessibleChild (i));
531 if (xChild.is())
533 Reference<XAccessibleComponent> xChildComponent (
534 xChild->getAccessibleContext(), uno::UNO_QUERY);
535 if (xChildComponent.is())
537 awt::Rectangle aBBox (xChildComponent->getBounds());
538 if ( (aPoint.X >= aBBox.X)
539 && (aPoint.Y >= aBBox.Y)
540 && (aPoint.X < aBBox.X+aBBox.Width)
541 && (aPoint.Y < aBBox.Y+aBBox.Height) )
542 return xChild;
547 // Have not found a child under the given point. Returning empty
548 // reference to indicate this.
549 return uno::Reference<XAccessible>();
555 awt::Rectangle SAL_CALL AccessibleShape::getBounds()
556 throw (::com::sun::star::uno::RuntimeException, std::exception)
558 SolarMutexGuard aSolarGuard;
559 ::osl::MutexGuard aGuard (maMutex);
561 ThrowIfDisposed ();
562 awt::Rectangle aBoundingBox;
563 if ( mxShape.is() )
566 static const char sBoundRectName[] = "BoundRect";
567 static const char sAnchorPositionName[] = "AnchorPosition";
569 // Get the shape's bounding box in internal coordinates (in 100th of
570 // mm). Use the property BoundRect. Only if that is not supported ask
571 // the shape for its position and size directly.
572 Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY);
573 Reference<beans::XPropertySetInfo> xSetInfo;
574 bool bFoundBoundRect = false;
575 if (xSet.is())
577 xSetInfo = xSet->getPropertySetInfo ();
578 if (xSetInfo.is())
580 if (xSetInfo->hasPropertyByName (sBoundRectName))
584 uno::Any aValue = xSet->getPropertyValue (sBoundRectName);
585 aValue >>= aBoundingBox;
586 bFoundBoundRect = true;
588 catch (beans::UnknownPropertyException const&)
590 // Handled below (bFoundBoundRect stays false).
593 else
594 OSL_TRACE (" no property BoundRect");
598 // Fallback when there is no BoundRect Property.
599 if ( ! bFoundBoundRect )
601 awt::Point aPosition (mxShape->getPosition());
602 awt::Size aSize (mxShape->getSize());
603 aBoundingBox = awt::Rectangle (
604 aPosition.X, aPosition.Y,
605 aSize.Width, aSize.Height);
607 // While BoundRects have absolute positions, the position returned
608 // by XPosition::getPosition is relative. Get the anchor position
609 // (usually not (0,0) for Writer shapes).
610 if (xSetInfo.is())
612 if (xSetInfo->hasPropertyByName (sAnchorPositionName))
614 uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName);
615 awt::Point aAnchorPosition;
616 aPos >>= aAnchorPosition;
617 aBoundingBox.X += aAnchorPosition.X;
618 aBoundingBox.Y += aAnchorPosition.Y;
623 // Transform coordinates from internal to pixel.
624 if (maShapeTreeInfo.GetViewForwarder() == NULL)
625 throw uno::RuntimeException (OUString (
626 "AccessibleShape has no valid view forwarder"),
627 static_cast<uno::XWeak*>(this));
628 ::Size aPixelSize = maShapeTreeInfo.GetViewForwarder()->LogicToPixel (
629 ::Size (aBoundingBox.Width, aBoundingBox.Height));
630 ::Point aPixelPosition = maShapeTreeInfo.GetViewForwarder()->LogicToPixel (
631 ::Point (aBoundingBox.X, aBoundingBox.Y));
633 // Clip the shape's bounding box with the bounding box of its parent.
634 Reference<XAccessibleComponent> xParentComponent (
635 getAccessibleParent(), uno::UNO_QUERY);
636 if (xParentComponent.is())
638 // Make the coordinates relative to the parent.
639 awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
640 int x = aPixelPosition.getX() - aParentLocation.X;
641 int y = aPixelPosition.getY() - aParentLocation.Y;
643 // Clip with parent (with coordinates relative to itself).
644 ::Rectangle aBBox (
645 x, y, x + aPixelSize.getWidth(), y + aPixelSize.getHeight());
646 awt::Size aParentSize (xParentComponent->getSize());
647 ::Rectangle aParentBBox (0,0, aParentSize.Width, aParentSize.Height);
648 aBBox = aBBox.GetIntersection (aParentBBox);
649 aBoundingBox = awt::Rectangle (
650 aBBox.getX(),
651 aBBox.getY(),
652 aBBox.getWidth(),
653 aBBox.getHeight());
655 else
657 OSL_TRACE ("parent does not support component");
658 aBoundingBox = awt::Rectangle (
659 aPixelPosition.getX(), aPixelPosition.getY(),
660 aPixelSize.getWidth(), aPixelSize.getHeight());
664 return aBoundingBox;
670 awt::Point SAL_CALL AccessibleShape::getLocation()
671 throw (::com::sun::star::uno::RuntimeException, std::exception)
673 ThrowIfDisposed ();
674 awt::Rectangle aBoundingBox (getBounds());
675 return awt::Point (aBoundingBox.X, aBoundingBox.Y);
681 awt::Point SAL_CALL AccessibleShape::getLocationOnScreen()
682 throw (::com::sun::star::uno::RuntimeException, std::exception)
684 ThrowIfDisposed ();
686 // Get relative position...
687 awt::Point aLocation (getLocation ());
689 // ... and add absolute position of the parent.
690 uno::Reference<XAccessibleComponent> xParentComponent (
691 getAccessibleParent(), uno::UNO_QUERY);
692 if (xParentComponent.is())
694 awt::Point aParentLocation (xParentComponent->getLocationOnScreen());
695 aLocation.X += aParentLocation.X;
696 aLocation.Y += aParentLocation.Y;
698 else
699 OSL_TRACE ("getLocation: parent does not support XAccessibleComponent");
700 return aLocation;
706 awt::Size SAL_CALL AccessibleShape::getSize()
707 throw (uno::RuntimeException, std::exception)
709 ThrowIfDisposed ();
710 awt::Rectangle aBoundingBox (getBounds());
711 return awt::Size (aBoundingBox.Width, aBoundingBox.Height);
717 sal_Int32 SAL_CALL AccessibleShape::getForeground()
718 throw (::com::sun::star::uno::RuntimeException, std::exception)
720 ThrowIfDisposed ();
721 sal_Int32 nColor (0x0ffffffL);
725 uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY);
726 if (aSet.is())
728 uno::Any aColor;
729 aColor = aSet->getPropertyValue ("LineColor");
730 aColor >>= nColor;
733 catch (const ::com::sun::star::beans::UnknownPropertyException &)
735 // Ignore exception and return default color.
737 return nColor;
743 sal_Int32 SAL_CALL AccessibleShape::getBackground()
744 throw (::com::sun::star::uno::RuntimeException, std::exception)
746 ThrowIfDisposed ();
747 sal_Int32 nColor (0L);
751 uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY);
752 if (aSet.is())
754 uno::Any aColor;
755 aColor = aSet->getPropertyValue ("FillColor");
756 aColor >>= nColor;
757 aColor = aSet->getPropertyValue ("FillTransparence");
758 short nTrans=0;
759 aColor >>= nTrans;
760 Color crBk(nColor);
761 if (nTrans == 0 )
763 crBk.SetTransparency(0xff);
765 else
767 nTrans = short(256 - nTrans / 100. * 256);
768 crBk.SetTransparency(sal_uInt8(nTrans));
770 nColor = crBk.GetColor();
773 catch (const ::com::sun::star::beans::UnknownPropertyException &)
775 // Ignore exception and return default color.
777 return nColor;
780 // XAccessibleEventBroadcaster
781 void SAL_CALL AccessibleShape::addAccessibleEventListener (
782 const Reference<XAccessibleEventListener >& rxListener)
783 throw (uno::RuntimeException, std::exception)
785 if (rBHelper.bDisposed || rBHelper.bInDispose)
787 uno::Reference<uno::XInterface> xThis (
788 (lang::XComponent *)this, uno::UNO_QUERY);
789 rxListener->disposing (lang::EventObject (xThis));
791 else
793 AccessibleContextBase::addAccessibleEventListener (rxListener);
794 if (mpText != NULL)
795 mpText->AddEventListener (rxListener);
802 void SAL_CALL AccessibleShape::removeAccessibleEventListener (
803 const Reference<XAccessibleEventListener >& rxListener)
804 throw (uno::RuntimeException, std::exception)
806 AccessibleContextBase::removeAccessibleEventListener (rxListener);
807 if (mpText != NULL)
808 mpText->RemoveEventListener (rxListener);
811 // XInterface
812 com::sun::star::uno::Any SAL_CALL
813 AccessibleShape::queryInterface (const com::sun::star::uno::Type & rType)
814 throw (::com::sun::star::uno::RuntimeException, std::exception)
816 ::com::sun::star::uno::Any aReturn = AccessibleContextBase::queryInterface (rType);
817 if ( ! aReturn.hasValue())
818 aReturn = ::cppu::queryInterface (rType,
819 static_cast<XAccessibleComponent*>(this),
820 static_cast<XAccessibleExtendedComponent*>(this),
821 static_cast< ::com::sun::star::accessibility::XAccessibleSelection* >(this),
822 static_cast< ::com::sun::star::accessibility::XAccessibleExtendedAttributes* >(this),
823 static_cast<lang::XEventListener*>(this),
824 static_cast<document::XEventListener*>(this),
825 static_cast<lang::XUnoTunnel*>(this),
826 static_cast<XAccessibleGroupPosition*>(this),
827 static_cast<XAccessibleHypertext*>(this)
829 return aReturn;
835 void SAL_CALL
836 AccessibleShape::acquire()
837 throw ()
839 AccessibleContextBase::acquire ();
845 void SAL_CALL
846 AccessibleShape::release()
847 throw ()
849 AccessibleContextBase::release ();
852 // XAccessibleSelection
853 void SAL_CALL AccessibleShape::selectAccessibleChild( sal_Int32 )
854 throw ( IndexOutOfBoundsException, RuntimeException, std::exception )
859 sal_Bool SAL_CALL AccessibleShape::isAccessibleChildSelected( sal_Int32 nChildIndex )
860 throw ( IndexOutOfBoundsException,
861 RuntimeException, std::exception )
863 uno::Reference<XAccessible> xAcc = getAccessibleChild( nChildIndex );
864 uno::Reference<XAccessibleContext> xContext;
865 if( xAcc.is() )
867 xContext = xAcc->getAccessibleContext();
870 if( xContext.is() )
872 if( xContext->getAccessibleRole() == AccessibleRole::PARAGRAPH )
874 uno::Reference< ::com::sun::star::accessibility::XAccessibleText >
875 xText(xAcc, uno::UNO_QUERY);
876 if( xText.is() )
878 if( xText->getSelectionStart() >= 0 ) return sal_True;
881 else if( xContext->getAccessibleRole() == AccessibleRole::SHAPE )
883 Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet();
884 if( !pRState.is() )
885 return sal_False;
887 uno::Sequence<short> pStates = pRState->getStates();
888 int nCount = pStates.getLength();
889 for( int i = 0; i < nCount; i++ )
891 if(pStates[i] == AccessibleStateType::SELECTED)
892 return sal_True;
894 return sal_False;
898 return sal_False;
902 void SAL_CALL AccessibleShape::clearAccessibleSelection( )
903 throw ( RuntimeException, std::exception )
908 void SAL_CALL AccessibleShape::selectAllAccessibleChildren( )
909 throw ( RuntimeException, std::exception )
914 sal_Int32 SAL_CALL AccessibleShape::getSelectedAccessibleChildCount()
915 throw ( RuntimeException, std::exception )
917 sal_Int32 nCount = 0;
918 sal_Int32 TotalCount = getAccessibleChildCount();
919 for( sal_Int32 i = 0; i < TotalCount; i++ )
920 if( isAccessibleChildSelected(i) ) nCount++;
922 return nCount;
926 Reference<XAccessible> SAL_CALL AccessibleShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex )
927 throw ( IndexOutOfBoundsException, RuntimeException, std::exception)
929 if ( nSelectedChildIndex > getSelectedAccessibleChildCount() )
930 throw IndexOutOfBoundsException();
931 sal_Int32 i1, i2;
932 for( i1 = 0, i2 = 0; i1 < getAccessibleChildCount(); i1++ )
933 if( isAccessibleChildSelected(i1) )
935 if( i2 == nSelectedChildIndex )
936 return getAccessibleChild( i1 );
937 i2++;
939 return Reference<XAccessible>();
943 void SAL_CALL AccessibleShape::deselectAccessibleChild( sal_Int32 )
944 throw ( IndexOutOfBoundsException,
945 RuntimeException, std::exception )
950 // XAccessibleExtendedAttributes
951 uno::Any SAL_CALL AccessibleShape::getExtendedAttributes()
952 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
954 uno::Any strRet;
955 OUString style;
956 if( getAccessibleRole() != AccessibleRole::SHAPE ) return strRet;
957 if( m_pShape )
959 style = "style:" + GetStyle();
961 style += ";";
962 strRet <<= style;
963 return strRet;
966 // XServiceInfo
967 OUString SAL_CALL
968 AccessibleShape::getImplementationName()
969 throw (::com::sun::star::uno::RuntimeException, std::exception)
971 return OUString("AccessibleShape");
977 uno::Sequence<OUString> SAL_CALL
978 AccessibleShape::getSupportedServiceNames()
979 throw (::com::sun::star::uno::RuntimeException, std::exception)
981 ThrowIfDisposed ();
982 // Get list of supported service names from base class...
983 uno::Sequence<OUString> aServiceNames =
984 AccessibleContextBase::getSupportedServiceNames();
985 sal_Int32 nCount (aServiceNames.getLength());
987 // ...and add additional names.
988 aServiceNames.realloc (nCount + 1);
989 aServiceNames[nCount] = "com.sun.star.drawing.AccessibleShape";
991 return aServiceNames;
994 // XTypeProvider
995 uno::Sequence<uno::Type> SAL_CALL
996 AccessibleShape::getTypes()
997 throw (uno::RuntimeException, std::exception)
999 ThrowIfDisposed ();
1000 // Get list of types from the context base implementation, ...
1001 uno::Sequence<uno::Type> aTypeList (AccessibleContextBase::getTypes());
1002 // ... get list of types from component base implementation, ...
1003 uno::Sequence<uno::Type> aComponentTypeList (AccessibleComponentBase::getTypes());
1004 // ... define local types, ...
1005 const uno::Type aLangEventListenerType =
1006 cppu::UnoType<lang::XEventListener>::get();
1007 const uno::Type aDocumentEventListenerType =
1008 cppu::UnoType<document::XEventListener>::get();
1009 const uno::Type aUnoTunnelType =
1010 cppu::UnoType<lang::XUnoTunnel>::get();
1012 // ... and merge them all into one list.
1013 sal_Int32 nTypeCount (aTypeList.getLength()),
1014 nComponentTypeCount (aComponentTypeList.getLength());
1015 int i;
1017 aTypeList.realloc (nTypeCount + nComponentTypeCount + 3);
1019 for (i=0; i<nComponentTypeCount; i++)
1020 aTypeList[nTypeCount + i] = aComponentTypeList[i];
1022 aTypeList[nTypeCount + i++ ] = aLangEventListenerType;
1023 aTypeList[nTypeCount + i++ ] = aDocumentEventListenerType;
1024 aTypeList[nTypeCount + i ] = aUnoTunnelType;
1026 return aTypeList;
1029 // lang::XEventListener
1030 /** Disposing calls are accepted only from the model: Just reset the
1031 reference to the model in the shape tree info. Otherwise this object
1032 remains functional.
1034 void SAL_CALL
1035 AccessibleShape::disposing (const lang::EventObject& aEvent)
1036 throw (uno::RuntimeException, std::exception)
1038 SolarMutexGuard aSolarGuard;
1039 ::osl::MutexGuard aGuard (maMutex);
1043 if (aEvent.Source == maShapeTreeInfo.GetModelBroadcaster())
1045 // Remove reference to model broadcaster to allow it to pass
1046 // away.
1047 maShapeTreeInfo.SetModelBroadcaster(NULL);
1051 catch (uno::RuntimeException const&)
1053 OSL_TRACE ("caught exception while disposing");
1057 // document::XEventListener
1058 void SAL_CALL
1059 AccessibleShape::notifyEvent (const document::EventObject& rEventObject)
1060 throw (uno::RuntimeException, std::exception)
1062 // First check if the event is for us.
1063 uno::Reference<drawing::XShape> xShape (
1064 rEventObject.Source, uno::UNO_QUERY);
1065 if ( xShape.get() == mxShape.get() )
1067 if (rEventObject.EventName == "ShapeModified")
1069 //Need to update text children when receiving ShapeModified hint when exiting edit mode for text box
1070 if (mpText)
1071 mpText->UpdateChildren();
1074 // Some property of a shape has been modified. Send an event
1075 // that indicates a change of the visible data to all listeners.
1076 CommitChange (
1077 AccessibleEventId::VISIBLE_DATA_CHANGED,
1078 uno::Any(),
1079 uno::Any());
1081 // Name and Description may have changed. Update the local
1082 // values accordingly.
1083 UpdateNameAndDescription();
1088 // lang::XUnoTunnel
1089 namespace
1091 class theAccessibleShapeImplementationId : public rtl::Static< UnoTunnelIdInit, theAccessibleShapeImplementationId > {};
1094 const uno::Sequence< sal_Int8 >&
1095 AccessibleShape::getUnoTunnelImplementationId()
1096 throw()
1098 return theAccessibleShapeImplementationId::get().getSeq();
1102 AccessibleShape*
1103 AccessibleShape::getImplementation( const uno::Reference< uno::XInterface >& rxIFace )
1104 throw()
1106 uno::Reference< lang::XUnoTunnel > xTunnel( rxIFace, uno::UNO_QUERY );
1107 AccessibleShape* pReturn = NULL;
1109 if( xTunnel.is() )
1110 pReturn = reinterpret_cast< AccessibleShape* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) );
1112 return pReturn;
1116 sal_Int64 SAL_CALL
1117 AccessibleShape::getSomething( const uno::Sequence< sal_Int8 >& rIdentifier )
1118 throw(uno::RuntimeException, std::exception)
1120 sal_Int64 nReturn( 0 );
1122 if( ( rIdentifier.getLength() == 16 ) && ( 0 == memcmp( getUnoTunnelImplementationId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) )
1123 nReturn = reinterpret_cast< sal_Int64 >( this );
1125 return nReturn;
1128 // IAccessibleViewForwarderListener
1129 void AccessibleShape::ViewForwarderChanged (ChangeType aChangeType,
1130 const IAccessibleViewForwarder* pViewForwarder)
1132 // Inform all listeners that the graphical representation (i.e. size
1133 // and/or position) of the shape has changed.
1134 CommitChange (AccessibleEventId::VISIBLE_DATA_CHANGED,
1135 uno::Any(),
1136 uno::Any());
1138 // Tell children manager of the modified view forwarder.
1139 if (mpChildrenManager != NULL)
1140 mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder);
1142 // update our children that our screen position might have changed
1143 if( mpText )
1144 mpText->UpdateChildren();
1147 // protected internal
1148 // Set this object's name if is different to the current name.
1149 OUString AccessibleShape::CreateAccessibleBaseName()
1150 throw (::com::sun::star::uno::RuntimeException)
1152 return ShapeTypeHandler::CreateAccessibleBaseName( mxShape );
1156 OUString AccessibleShape::CreateAccessibleName()
1157 throw (::com::sun::star::uno::RuntimeException)
1159 return GetFullAccessibleName(this);
1162 OUString AccessibleShape::GetFullAccessibleName (AccessibleShape *shape)
1163 throw (::com::sun::star::uno::RuntimeException)
1165 OUString sName (shape->CreateAccessibleBaseName());
1166 // Append the shape's index to the name to disambiguate between shapes
1167 // of the same type. If such an index where not given to the
1168 // constructor then use the z-order instead. If even that does not exist
1169 // we throw an exception.
1170 OUString nameStr;
1171 if (shape->m_pShape)
1172 nameStr = shape->m_pShape->GetName();
1173 if (nameStr.isEmpty())
1175 sName += " ";
1177 else
1179 sName = nameStr;
1182 //If the new produced name if not the same with last,notify name changed
1183 //Event
1184 if (aAccName != sName && !aAccName.isEmpty())
1186 uno::Any aOldValue, aNewValue;
1187 aOldValue <<= aAccName;
1188 aNewValue <<= sName;
1189 CommitChange(
1190 AccessibleEventId::NAME_CHANGED,
1191 aNewValue,
1192 aOldValue);
1194 aAccName = sName;
1195 return sName;
1198 OUString
1199 AccessibleShape::CreateAccessibleDescription()
1200 throw (::com::sun::star::uno::RuntimeException)
1202 DescriptionGenerator aDG (mxShape);
1203 aDG.Initialize (CreateAccessibleBaseName());
1204 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
1206 case DRAWING_3D_CUBE:
1207 case DRAWING_3D_EXTRUDE:
1208 case DRAWING_3D_LATHE:
1209 case DRAWING_3D_SPHERE:
1210 aDG.Add3DProperties ();
1211 break;
1213 case DRAWING_3D_SCENE:
1214 case DRAWING_GROUP:
1215 case DRAWING_PAGE:
1216 // No further information is appended.
1217 break;
1219 case DRAWING_CAPTION:
1220 case DRAWING_CLOSED_BEZIER:
1221 case DRAWING_CLOSED_FREEHAND:
1222 case DRAWING_ELLIPSE:
1223 case DRAWING_POLY_POLYGON:
1224 case DRAWING_POLY_POLYGON_PATH:
1225 case DRAWING_RECTANGLE:
1226 aDG.AddLineProperties ();
1227 aDG.AddFillProperties ();
1228 break;
1230 case DRAWING_CONNECTOR:
1231 case DRAWING_LINE:
1232 case DRAWING_MEASURE:
1233 case DRAWING_OPEN_BEZIER:
1234 case DRAWING_OPEN_FREEHAND:
1235 case DRAWING_POLY_LINE:
1236 case DRAWING_POLY_LINE_PATH:
1237 aDG.AddLineProperties ();
1238 break;
1240 case DRAWING_CONTROL:
1241 aDG.AddProperty ("ControlBackground", DescriptionGenerator::COLOR, "");
1242 aDG.AddProperty ("ControlBorder", DescriptionGenerator::INTEGER, "");
1243 break;
1245 case DRAWING_TEXT:
1246 aDG.AddTextProperties ();
1247 break;
1249 default:
1250 aDG.Initialize ("Unknown accessible shape");
1251 uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY);
1252 if (xDescriptor.is())
1254 aDG.AppendString ("service name=");
1255 aDG.AppendString (xDescriptor->getShapeType());
1259 return aDG();
1268 // protected
1269 void AccessibleShape::disposing()
1271 SolarMutexGuard aSolarGuard;
1272 ::osl::MutexGuard aGuard (maMutex);
1274 // Make sure to send an event that this object loses the focus in the
1275 // case that it has the focus.
1276 ::utl::AccessibleStateSetHelper* pStateSet =
1277 static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
1278 if (pStateSet != NULL)
1279 pStateSet->RemoveState (AccessibleStateType::FOCUSED);
1281 // Unregister from broadcasters.
1282 Reference<lang::XComponent> xComponent (mxShape, uno::UNO_QUERY);
1283 if (xComponent.is())
1284 xComponent->removeEventListener (this);
1286 // Unregister from model.
1287 if (maShapeTreeInfo.GetModelBroadcaster().is())
1288 maShapeTreeInfo.GetModelBroadcaster()->removeEventListener (
1289 static_cast<document::XEventListener*>(this));
1291 // Release the child containers.
1292 if (mpChildrenManager != NULL)
1294 delete mpChildrenManager;
1295 mpChildrenManager = NULL;
1297 if (mpText != NULL)
1299 mpText->Dispose();
1300 delete mpText;
1301 mpText = NULL;
1304 // Cleanup. Remove references to objects to allow them to be
1305 // destroyed.
1306 mxShape = NULL;
1307 maShapeTreeInfo = AccessibleShapeTreeInfo();
1309 // Call base classes.
1310 AccessibleContextBase::dispose ();
1313 sal_Int32 SAL_CALL
1314 AccessibleShape::getAccessibleIndexInParent()
1315 throw (::com::sun::star::uno::RuntimeException, std::exception)
1317 ThrowIfDisposed ();
1318 // Use a simple but slow solution for now. Optimize later.
1320 sal_Int32 nIndex = m_nIndexInParent;
1321 if ( -1 == nIndex )
1322 nIndex = AccessibleContextBase::getAccessibleIndexInParent();
1323 return nIndex;
1329 void AccessibleShape::UpdateNameAndDescription()
1331 // Ignore missing title, name, or description. There are fallbacks for
1332 // them.
1335 Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY_THROW);
1336 OUString sString;
1338 // Get the accessible name.
1339 sString = GetOptionalProperty(xSet, "Title");
1340 if (!sString.isEmpty())
1342 SetAccessibleName(sString, AccessibleContextBase::FromShape);
1344 else
1346 sString = GetOptionalProperty(xSet, "Name");
1347 if (!sString.isEmpty())
1348 SetAccessibleName(sString, AccessibleContextBase::FromShape);
1351 // Get the accessible description.
1352 sString = GetOptionalProperty(xSet, "Description");
1353 if (!sString.isEmpty())
1354 SetAccessibleDescription(sString, AccessibleContextBase::FromShape);
1356 catch (uno::RuntimeException&)
1361 // Return this object's role.
1362 sal_Int16 SAL_CALL AccessibleShape::getAccessibleRole()
1363 throw (::com::sun::star::uno::RuntimeException, std::exception)
1365 sal_Int16 nAccessibleRole = AccessibleRole::SHAPE ;
1366 switch (ShapeTypeHandler::Instance().GetTypeId (mxShape))
1368 case DRAWING_GRAPHIC_OBJECT:
1369 nAccessibleRole = AccessibleRole::GRAPHIC ; break;
1370 case DRAWING_OLE:
1371 nAccessibleRole = AccessibleRole::EMBEDDED_OBJECT ; break;
1373 default:
1374 nAccessibleRole = AccessibleContextBase::getAccessibleRole();
1375 break;
1378 return nAccessibleRole;
1382 void AccessibleShape::UpdateDocumentAllSelState(Reference<XAccessibleStateSet> &xStateSet)
1384 if (mpParent && mpParent->IsDocumentSelAll())
1386 ::utl::AccessibleStateSetHelper* pStateSet =
1387 static_cast< ::utl::AccessibleStateSetHelper*>(xStateSet.get());
1388 pStateSet->AddState (AccessibleStateType::SELECTED);
1390 //uno::Any NewValue;
1391 //NewValue <<= AccessibleStateType::SELECTED;
1393 //CommitChange(AccessibleEventId::STATE_CHANGED,NewValue,uno::Any());
1397 //sort the drawing objects from up to down, from left to right
1398 struct XShapePosCompareHelper
1400 bool operator() ( const uno::Reference<drawing::XShape>& xshape1,
1401 const uno::Reference<drawing::XShape>& xshape2 ) const
1403 SdrObject* pObj1 = GetSdrObjectFromXShape(xshape1);
1404 SdrObject* pObj2 = GetSdrObjectFromXShape(xshape2);
1405 if(pObj1 && pObj2)
1406 return pObj1->GetOrdNum() < pObj2->GetOrdNum();
1407 else
1408 return false;
1411 //end of group position
1413 // XAccessibleGroupPosition
1414 uno::Sequence< sal_Int32 > SAL_CALL
1415 AccessibleShape::getGroupPosition( const uno::Any& )
1416 throw (uno::RuntimeException, std::exception)
1418 // we will return the:
1419 // [0] group level
1420 // [1] similar items counts in the group
1421 // [2] the position of the object in the group
1422 uno::Sequence< sal_Int32 > aRet( 3 );
1423 aRet[0] = 0;
1424 aRet[1] = 0;
1425 aRet[2] = 0;
1427 ::com::sun::star::uno::Reference<XAccessible> xParent = getAccessibleParent();
1428 if (!xParent.is())
1430 return aRet;
1432 SdrObject *pObj = GetSdrObjectFromXShape(mxShape);
1435 if(pObj == NULL )
1437 return aRet;
1440 // Compute object's group level.
1441 sal_Int32 nGroupLevel = 0;
1442 SdrObject * pUper = pObj->GetUpGroup();
1443 while( pUper )
1445 ++nGroupLevel;
1446 pUper = pUper->GetUpGroup();
1449 ::com::sun::star::uno::Reference<XAccessibleContext> xParentContext = xParent->getAccessibleContext();
1450 if( xParentContext->getAccessibleRole() == AccessibleRole::DOCUMENT ||
1451 xParentContext->getAccessibleRole() == AccessibleRole::DOCUMENT_PRESENTATION ||
1452 xParentContext->getAccessibleRole() == AccessibleRole::DOCUMENT_SPREADSHEET ||
1453 xParentContext->getAccessibleRole() == AccessibleRole::DOCUMENT_TEXT )//Document
1455 Reference< XAccessibleGroupPosition > xGroupPosition( xParent,uno::UNO_QUERY );
1456 if ( xGroupPosition.is() )
1458 aRet = xGroupPosition->getGroupPosition( uno::makeAny( getAccessibleContext() ) );
1460 return aRet;
1462 if (xParentContext->getAccessibleRole() != AccessibleRole::SHAPE)
1464 return aRet;
1467 SdrObjList *pGrpList = NULL;
1468 if( pObj->GetUpGroup() )
1469 pGrpList = pObj->GetUpGroup()->GetSubList();
1470 else
1471 return aRet;
1473 std::vector< uno::Reference<drawing::XShape> > vXShapes;
1474 if (pGrpList)
1476 const size_t nObj = pGrpList->GetObjCount();
1477 for(size_t i = 0 ; i < nObj ; ++i)
1479 SdrObject *pSubObj = pGrpList->GetObj(i);
1480 if (pSubObj &&
1481 xParentContext->getAccessibleChild(i)->getAccessibleContext()->getAccessibleRole() != AccessibleRole::GROUP_BOX)
1483 vXShapes.push_back( GetXShapeForSdrObject(pSubObj) );
1488 std::sort( vXShapes.begin(), vXShapes.end(), XShapePosCompareHelper() );
1490 //get the index of the selected object in the group
1491 std::vector< uno::Reference<drawing::XShape> >::iterator aIter;
1492 //we start counting position from 1
1493 sal_Int32 nPos = 1;
1494 for ( aIter = vXShapes.begin(); aIter != vXShapes.end(); ++aIter, nPos++ )
1496 if ( (*aIter).get() == mxShape.get() )
1498 sal_Int32* pArray = aRet.getArray();
1499 pArray[0] = nGroupLevel;
1500 pArray[1] = vXShapes.size();
1501 pArray[2] = nPos;
1502 break;
1506 return aRet;
1509 OUString AccessibleShape::getObjectLink( const uno::Any& )
1510 throw (uno::RuntimeException, std::exception)
1512 OUString aRet;
1514 SdrObject *pObj = GetSdrObjectFromXShape(mxShape);
1515 if(pObj == NULL )
1517 return aRet;
1519 if (maShapeTreeInfo.GetDocumentWindow().is())
1521 Reference< XAccessibleGroupPosition > xGroupPosition( maShapeTreeInfo.GetDocumentWindow(), uno::UNO_QUERY );
1522 if (xGroupPosition.is())
1524 aRet = xGroupPosition->getObjectLink( uno::makeAny( getAccessibleContext() ) );
1527 return aRet;
1530 // XAccesibleHypertext
1531 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkCount()
1532 throw (::com::sun::star::uno::RuntimeException, std::exception)
1534 // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile.
1535 // Code need to be adapted....
1536 return 0;
1539 SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this);
1540 if (pLink->IsValidHyperlink())
1541 return 1;
1542 else
1543 return 0;
1546 uno::Reference< XAccessibleHyperlink > SAL_CALL
1547 AccessibleShape::getHyperLink( sal_Int32 )
1548 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
1550 uno::Reference< XAccessibleHyperlink > xRet;
1551 // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile.
1552 // Code need to be adapted....
1554 SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this);
1555 if (pLink->IsValidHyperlink())
1556 xRet = pLink;
1557 if( !xRet.is() )
1558 throw ::com::sun::star::lang::IndexOutOfBoundsException();
1560 return xRet;
1562 sal_Int32 SAL_CALL AccessibleShape::getHyperLinkIndex( sal_Int32 )
1563 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
1565 sal_Int32 nRet = 0;
1566 return nRet;
1568 // XAccesibleText
1569 sal_Int32 SAL_CALL AccessibleShape::getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1570 sal_Bool SAL_CALL AccessibleShape::setCaretPosition( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1571 sal_Unicode SAL_CALL AccessibleShape::getCharacter( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1572 ::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)
1574 uno::Sequence< ::com::sun::star::beans::PropertyValue > aValues(0);
1575 return aValues;
1577 ::com::sun::star::awt::Rectangle SAL_CALL AccessibleShape::getCharacterBounds( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception)
1579 return com::sun::star::awt::Rectangle(0, 0, 0, 0 );
1581 sal_Int32 SAL_CALL AccessibleShape::getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1582 sal_Int32 SAL_CALL AccessibleShape::getIndexAtPoint( const ::com::sun::star::awt::Point& ) throw (::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1583 OUString SAL_CALL AccessibleShape::getSelectedText( ) throw (::com::sun::star::uno::RuntimeException, std::exception){return OUString();}
1584 sal_Int32 SAL_CALL AccessibleShape::getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1585 sal_Int32 SAL_CALL AccessibleShape::getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException, std::exception){return 0;}
1586 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;}
1587 OUString SAL_CALL AccessibleShape::getText( ) throw (::com::sun::star::uno::RuntimeException, std::exception){return OUString();}
1588 OUString SAL_CALL AccessibleShape::getTextRange( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException, std::exception){return OUString();}
1589 ::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)
1591 ::com::sun::star::accessibility::TextSegment aResult;
1592 return aResult;
1594 ::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)
1596 ::com::sun::star::accessibility::TextSegment aResult;
1597 return aResult;
1599 ::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)
1601 ::com::sun::star::accessibility::TextSegment aResult;
1602 return aResult;
1604 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;}
1606 } // end of namespace accessibility
1608 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */