| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svx.hxx" |
| #include <svx/AccessibleShape.hxx> |
| #include "svx/DescriptionGenerator.hxx" |
| #include <svx/AccessibleShapeInfo.hxx> |
| #include <com/sun/star/view/XSelectionSupplier.hpp> |
| #include <rtl/uuid.h> |
| #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLE_ROLE_HPP_ |
| #include <com/sun/star/accessibility/AccessibleRole.hpp> |
| #endif |
| #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLETEXTTYPE_HPP_ |
| #include <com/sun/star/accessibility/AccessibleTextType.hpp> |
| #endif |
| #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLE_STATE_TYPE_HPP_ |
| #include <com/sun/star/accessibility/AccessibleStateType.hpp> |
| #endif |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <com/sun/star/container/XChild.hpp> |
| #include <com/sun/star/drawing/XShapes.hpp> |
| #include <com/sun/star/drawing/XShapeDescriptor.hpp> |
| #include <com/sun/star/lang/IndexOutOfBoundsException.hpp> |
| #include <com/sun/star/drawing/FillStyle.hpp> |
| #include <com/sun/star/text/XText.hpp> |
| #include <editeng/outlobj.hxx> |
| #include <rtl/ref.hxx> |
| #include <editeng/unoedsrc.hxx> |
| #include <svx/unoshtxt.hxx> |
| #include <svx/svdobj.hxx> |
| #include <svx/svdmodel.hxx> |
| #include "svx/unoapi.hxx" |
| #include <com/sun/star/uno/Exception.hpp> |
| #include <svx/ShapeTypeHandler.hxx> |
| #include <svx/SvxShapeTypes.hxx> |
| |
| #ifndef _SVX_ACCESSIBILITY_HRC |
| #include "accessibility.hrc" |
| #endif |
| #include "svx/svdstr.hrc" |
| #include <svx/dialmgr.hxx> |
| #include <vcl/svapp.hxx> |
| #include <unotools/accessiblestatesethelper.hxx> |
| #include <svx/svdview.hxx> |
| #include "AccessibleEmptyEditSource.hxx" |
| #include <svx/svdpage.hxx> |
| #ifndef _COM_SUN_STAR_ACCESSIBILITY_ACCESSIBLERELATIONTYPE_HPP_ |
| #include <com/sun/star/accessibility/AccessibleRelationType.hpp> |
| #endif |
| #ifndef _UTL_ACCESSIBLERELATIONSETHELPER_HXX_ |
| #include <unotools/accessiblerelationsethelper.hxx> |
| #endif |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::accessibility; |
| using ::com::sun::star::lang::IndexOutOfBoundsException; |
| using ::com::sun::star::uno::RuntimeException; |
| using ::com::sun::star::uno::Reference; |
| using ::rtl::OUString; |
| #include <algorithm> |
| |
| // #include <Accessiblehyperlink.hxx> |
| namespace accessibility { |
| |
| namespace { |
| |
| OUString GetOptionalProperty ( |
| const Reference<beans::XPropertySet>& rxSet, |
| const OUString& rsPropertyName) |
| { |
| OUString sValue; |
| |
| if (rxSet.is()) |
| { |
| const Reference<beans::XPropertySetInfo> xInfo (rxSet->getPropertySetInfo()); |
| if ( ! xInfo.is() || xInfo->hasPropertyByName(rsPropertyName)) |
| { |
| try |
| { |
| rxSet->getPropertyValue(rsPropertyName) >>= sValue; |
| } |
| catch (beans::UnknownPropertyException&) |
| { |
| // This exception should only be thrown when the property |
| // does not exits (of course) and the XPropertySetInfo is |
| // not available. |
| } |
| } |
| } |
| return sValue; |
| } |
| |
| } // end of anonymous namespace |
| |
| |
| |
| |
| //===== internal ============================================================ |
| |
| AccessibleShape::AccessibleShape ( |
| const AccessibleShapeInfo& rShapeInfo, |
| const AccessibleShapeTreeInfo& rShapeTreeInfo) |
| : AccessibleContextBase (rShapeInfo.mxParent,AccessibleRole::SHAPE), |
| mpChildrenManager(NULL), |
| mxShape (rShapeInfo.mxShape), |
| maShapeTreeInfo (rShapeTreeInfo), |
| mnIndex (rShapeInfo.mnIndex), |
| m_nIndexInParent(-1), |
| mpText (NULL), |
| mpParent (rShapeInfo.mpChildrenManager) |
| { |
| m_pShape = GetSdrObjectFromXShape(mxShape); |
| UpdateNameAndDescription(); |
| } |
| AccessibleShape::AccessibleShape ( |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::drawing::XShape>& rxShape, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::accessibility::XAccessible>& rxParent, |
| const AccessibleShapeTreeInfo& rShapeTreeInfo, |
| sal_Int32 nIndex) |
| : AccessibleContextBase (rxParent,AccessibleRole::SHAPE), |
| mpChildrenManager(NULL), |
| mxShape (rxShape), |
| maShapeTreeInfo (rShapeTreeInfo), |
| mnIndex (nIndex), |
| m_nIndexInParent(-1), |
| mpText (NULL), |
| mpParent (NULL) |
| { |
| m_pShape = GetSdrObjectFromXShape(mxShape); |
| } |
| AccessibleShape::~AccessibleShape (void) |
| { |
| if (mpChildrenManager != NULL) |
| delete mpChildrenManager; |
| if (mpText != NULL) |
| delete mpText; |
| OSL_TRACE ("~AccessibleShape"); |
| |
| // Unregistering from the various broadcasters should be unnecessary |
| // since this destructor would not have been called if one of the |
| // broadcasters would still hold a strong reference to this object. |
| } |
| |
| |
| |
| |
| void AccessibleShape::Init (void) |
| { |
| // Update the OPAQUE and SELECTED shape. |
| UpdateStates (); |
| |
| // Create a children manager when this shape has children of its own. |
| Reference<drawing::XShapes> xShapes (mxShape, uno::UNO_QUERY); |
| if (xShapes.is() && xShapes->getCount() > 0) |
| mpChildrenManager = new ChildrenManager ( |
| this, xShapes, maShapeTreeInfo, *this); |
| if (mpChildrenManager != NULL) |
| mpChildrenManager->Update(); |
| |
| // Register at model as document::XEventListener. |
| if (maShapeTreeInfo.GetModelBroadcaster().is()) |
| maShapeTreeInfo.GetModelBroadcaster()->addEventListener ( |
| static_cast<document::XEventListener*>(this)); |
| |
| // Beware! Here we leave the paths of the UNO API and descend into the |
| // depths of the core. Necessary for makeing the edit engine |
| // accessible. |
| Reference<text::XText> xText (mxShape, uno::UNO_QUERY); |
| if (xText.is()) |
| { |
| SdrView* pView = maShapeTreeInfo.GetSdrView (); |
| const Window* pWindow = maShapeTreeInfo.GetWindow (); |
| if (pView != NULL && pWindow != NULL && mxShape.is()) |
| { |
| // #107948# Determine whether shape text is empty |
| SdrObject* pSdrObject = GetSdrObjectFromXShape(mxShape); |
| if( pSdrObject ) |
| { |
| SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, pSdrObject ); |
| OutlinerParaObject* pOutlinerParaObject = NULL; |
| |
| if( pTextObj ) |
| pOutlinerParaObject = pTextObj->GetEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active |
| |
| bool bOwnParaObj = pOutlinerParaObject != NULL; |
| |
| if( !pOutlinerParaObject && pSdrObject ) |
| pOutlinerParaObject = pSdrObject->GetOutlinerParaObject(); |
| |
| // create AccessibleTextHelper to handle this shape's text |
| if( !pOutlinerParaObject ) |
| { |
| // empty text -> use proxy edit source to delay creation of EditEngine |
| ::std::auto_ptr<SvxEditSource> pEditSource( new AccessibleEmptyEditSource ( *pSdrObject, *pView, *pWindow) ); |
| mpText = new AccessibleTextHelper( pEditSource ); |
| } |
| else |
| { |
| // non-empty text -> use full-fledged edit source right away |
| ::std::auto_ptr<SvxEditSource> pEditSource( new SvxTextEditSource ( *pSdrObject, 0, *pView, *pWindow) ); |
| mpText = new AccessibleTextHelper( pEditSource ); |
| } |
| |
| if( bOwnParaObj ) |
| delete pOutlinerParaObject; |
| |
| mpText->SetEventSource(this); |
| } |
| } |
| } |
| } |
| |
| |
| |
| |
| void AccessibleShape::UpdateStates (void) |
| { |
| ::utl::AccessibleStateSetHelper* pStateSet = |
| static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); |
| if (pStateSet == NULL) |
| return; |
| |
| // Set the opaque state for certain shape types when their fill style is |
| // solid. |
| bool bShapeIsOpaque = false; |
| switch (ShapeTypeHandler::Instance().GetTypeId (mxShape)) |
| { |
| case DRAWING_PAGE: |
| case DRAWING_RECTANGLE: |
| case DRAWING_TEXT: |
| { |
| uno::Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY); |
| if (xSet.is()) |
| { |
| try |
| { |
| drawing::FillStyle aFillStyle; |
| bShapeIsOpaque = ( xSet->getPropertyValue (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("FillStyle"))) >>= aFillStyle) |
| && aFillStyle == drawing::FillStyle_SOLID; |
| } |
| catch (::com::sun::star::beans::UnknownPropertyException&) |
| { |
| // Ignore. |
| } |
| } |
| } |
| } |
| if (bShapeIsOpaque) |
| pStateSet->AddState (AccessibleStateType::OPAQUE); |
| else |
| pStateSet->RemoveState (AccessibleStateType::OPAQUE); |
| |
| // Set the selected state. |
| bool bShapeIsSelected = false; |
| // XXX fix_me this has to be done with an extra interface later on |
| if ( m_pShape && maShapeTreeInfo.GetSdrView() ) |
| { |
| bShapeIsSelected = maShapeTreeInfo.GetSdrView()->IsObjMarked(m_pShape) == sal_True; |
| } |
| |
| if (bShapeIsSelected) |
| pStateSet->AddState (AccessibleStateType::SELECTED); |
| else |
| pStateSet->RemoveState (AccessibleStateType::SELECTED); |
| } |
| ::rtl::OUString AccessibleShape::GetStyle() |
| { |
| return ShapeTypeHandler::CreateAccessibleBaseName( mxShape ); |
| } |
| |
| bool AccessibleShape::operator== (const AccessibleShape& rShape) |
| { |
| return this==&rShape; |
| } |
| |
| |
| |
| |
| sal_Bool AccessibleShape::SetState (sal_Int16 aState) |
| { |
| sal_Bool bStateHasChanged = sal_False; |
| |
| if (aState == AccessibleStateType::FOCUSED && mpText != NULL) |
| { |
| // Offer FOCUSED state to edit engine and detect whether the state |
| // changes. |
| sal_Bool bIsFocused = mpText->HaveFocus (); |
| mpText->SetFocus (sal_True); |
| bStateHasChanged = (bIsFocused != mpText->HaveFocus ()); |
| } |
| else |
| bStateHasChanged = AccessibleContextBase::SetState (aState); |
| |
| return bStateHasChanged; |
| } |
| |
| |
| |
| |
| sal_Bool AccessibleShape::ResetState (sal_Int16 aState) |
| { |
| sal_Bool bStateHasChanged = sal_False; |
| |
| if (aState == AccessibleStateType::FOCUSED && mpText != NULL) |
| { |
| // Try to remove FOCUSED state from the edit engine and detect |
| // whether the state changes. |
| sal_Bool bIsFocused = mpText->HaveFocus (); |
| mpText->SetFocus (sal_False); |
| bStateHasChanged = (bIsFocused != mpText->HaveFocus ()); |
| } |
| else |
| bStateHasChanged = AccessibleContextBase::ResetState (aState); |
| |
| return bStateHasChanged; |
| } |
| |
| |
| |
| |
| sal_Bool AccessibleShape::GetState (sal_Int16 aState) |
| { |
| if (aState == AccessibleStateType::FOCUSED && mpText != NULL) |
| { |
| // Just delegate the call to the edit engine. The state is not |
| // merged into the state set. |
| return mpText->HaveFocus(); |
| } |
| else |
| return AccessibleContextBase::GetState (aState); |
| } |
| // Solution: OverWrite the parent's getAccessibleName method |
| ::rtl::OUString SAL_CALL AccessibleShape::getAccessibleName (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| ThrowIfDisposed (); |
| if( m_pShape && m_pShape->GetTitle().Len() > 0) |
| return CreateAccessibleName() + ::rtl::OUString(' ') + m_pShape->GetTitle(); |
| else |
| return CreateAccessibleName(); |
| } |
| |
| ::rtl::OUString SAL_CALL AccessibleShape::getAccessibleDescription (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| ThrowIfDisposed (); |
| if( m_pShape && m_pShape->GetDescription().Len() > 0) |
| return m_pShape->GetDescription() ; |
| else |
| return OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); |
| } |
| //===== XAccessibleContext ================================================== |
| |
| /** The children of this shape come from two sources: The children from |
| group or scene shapes and the paragraphs of text. |
| */ |
| sal_Int32 SAL_CALL |
| AccessibleShape::getAccessibleChildCount () |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| ThrowIfDisposed (); |
| sal_Int32 nChildCount = 0; |
| |
| // Add the number of shapes that are children of this shape. |
| if (mpChildrenManager != NULL) |
| nChildCount += mpChildrenManager->GetChildCount (); |
| // Add the number text paragraphs. |
| if (mpText != NULL) |
| nChildCount += mpText->GetChildCount (); |
| |
| return nChildCount; |
| } |
| |
| |
| |
| |
| /** Forward the request to the shape. Return the requested shape or throw |
| an exception for a wrong index. |
| */ |
| uno::Reference<XAccessible> SAL_CALL |
| AccessibleShape::getAccessibleChild (sal_Int32 nIndex) |
| throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) |
| { |
| ThrowIfDisposed (); |
| |
| uno::Reference<XAccessible> xChild; |
| |
| // Depending on the index decide whether to delegate this call to the |
| // children manager or the edit engine. |
| if ((mpChildrenManager != NULL) |
| && (nIndex < mpChildrenManager->GetChildCount())) |
| { |
| xChild = mpChildrenManager->GetChild (nIndex); |
| } |
| else if (mpText != NULL) |
| { |
| sal_Int32 nI = nIndex; |
| if (mpChildrenManager != NULL) |
| nI -= mpChildrenManager->GetChildCount(); |
| xChild = mpText->GetChild (nI); |
| } |
| else |
| throw lang::IndexOutOfBoundsException ( |
| ::rtl::OUString::createFromAscii ("shape has no child with index ") |
| + rtl::OUString::valueOf(nIndex), |
| static_cast<uno::XWeak*>(this)); |
| |
| return xChild; |
| } |
| |
| uno::Reference<XAccessibleRelationSet> SAL_CALL |
| AccessibleShape::getAccessibleRelationSet (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| ::osl::MutexGuard aGuard (maMutex); |
| ::utl::AccessibleRelationSetHelper* pRelationSet = new utl::AccessibleRelationSetHelper; |
| |
| //this mxshape is the captioned shape, only for sw |
| if (pRelationSet != NULL) |
| { |
| uno::Sequence< uno::Reference< uno::XInterface > > aSequence(1); |
| aSequence[0] = mpParent->GetAccessibleCaption(mxShape); |
| if(aSequence[0].get()) |
| { |
| pRelationSet->AddRelation( |
| AccessibleRelation( AccessibleRelationType::DESCRIBED_BY, aSequence ) ); |
| } |
| return uno::Reference<XAccessibleRelationSet> ( |
| new ::utl::AccessibleRelationSetHelper (*pRelationSet)); |
| } |
| else |
| { |
| return uno::Reference<XAccessibleRelationSet>(NULL); |
| } |
| } |
| |
| /** Return a copy of the state set. |
| Possible states are: |
| ENABLED |
| SHOWING |
| VISIBLE |
| */ |
| uno::Reference<XAccessibleStateSet> SAL_CALL |
| AccessibleShape::getAccessibleStateSet (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| ::osl::MutexGuard aGuard (maMutex); |
| Reference<XAccessibleStateSet> xStateSet; |
| |
| if (rBHelper.bDisposed || mpText == NULL) |
| // Return a minimal state set that only contains the DEFUNC state. |
| { |
| xStateSet = AccessibleContextBase::getAccessibleStateSet (); |
| ::utl::AccessibleStateSetHelper* pStateSet = |
| static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); |
| ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent(); |
| if( xTempAcc.is() ) |
| { |
| ::com::sun::star::uno::Reference<XAccessibleContext> |
| xTempAccContext = xTempAcc->getAccessibleContext(); |
| if( xTempAccContext.is() ) |
| { |
| ::com::sun::star::uno::Reference<XAccessibleStateSet> rState = |
| xTempAccContext->getAccessibleStateSet(); |
| if( rState.is() ) { |
| com::sun::star::uno::Sequence<short> pStates = rState->getStates(); |
| int count = pStates.getLength(); |
| for( int iIndex = 0;iIndex < count;iIndex++ ) |
| { |
| if( pStates[iIndex] == AccessibleStateType::EDITABLE ) |
| { |
| pStateSet->AddState (AccessibleStateType::EDITABLE); |
| pStateSet->AddState (AccessibleStateType::RESIZABLE); |
| pStateSet->AddState (AccessibleStateType::MOVEABLE); |
| break; |
| } |
| } |
| } |
| } |
| } |
| xStateSet = Reference<XAccessibleStateSet>( |
| new ::utl::AccessibleStateSetHelper (*pStateSet)); |
| }else |
| { |
| ::utl::AccessibleStateSetHelper* pStateSet = |
| static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); |
| |
| if (pStateSet != NULL) |
| { |
| // Merge current FOCUSED state from edit engine. |
| if (mpText != NULL) |
| { |
| if (mpText->HaveFocus()) |
| pStateSet->AddState (AccessibleStateType::FOCUSED); |
| else |
| pStateSet->RemoveState (AccessibleStateType::FOCUSED); |
| } |
| //Solution:Just when the document is not read-only,set states EDITABLE,RESIZABLE,MOVEABLE |
| ::com::sun::star::uno::Reference<XAccessible> xTempAcc = getAccessibleParent(); |
| if( xTempAcc.is() ) |
| { |
| ::com::sun::star::uno::Reference<XAccessibleContext> |
| xTempAccContext = xTempAcc->getAccessibleContext(); |
| if( xTempAccContext.is() ) |
| { |
| ::com::sun::star::uno::Reference<XAccessibleStateSet> rState = |
| xTempAccContext->getAccessibleStateSet(); |
| if( rState.is() ) { |
| com::sun::star::uno::Sequence<short> pStates = rState->getStates(); |
| int count = pStates.getLength(); |
| for( int iIndex = 0;iIndex < count;iIndex++ ) |
| { |
| if( pStates[iIndex] == AccessibleStateType::EDITABLE ) |
| { |
| pStateSet->AddState (AccessibleStateType::EDITABLE); |
| pStateSet->AddState (AccessibleStateType::RESIZABLE); |
| pStateSet->AddState (AccessibleStateType::MOVEABLE); |
| break; |
| } |
| } |
| } |
| } |
| } |
| // Create a copy of the state set that may be modified by the |
| // caller without affecting the current state set. |
| xStateSet = Reference<XAccessibleStateSet>( |
| new ::utl::AccessibleStateSetHelper (*pStateSet)); |
| } |
| } |
| UpdateDocumentAllSelState(xStateSet); |
| return xStateSet; |
| } |
| |
| |
| |
| |
| //===== XAccessibleComponent ================================================ |
| |
| /** The implementation below is at the moment straightforward. It iterates |
| over all children (and thereby instances all children which have not |
| been already instatiated) until a child covering the specifed point is |
| found. |
| This leaves room for improvement. For instance, first iterate only over |
| the already instantiated children and only if no match is found |
| instantiate the remaining ones. |
| */ |
| uno::Reference<XAccessible > SAL_CALL |
| AccessibleShape::getAccessibleAtPoint ( |
| const awt::Point& aPoint) |
| throw (uno::RuntimeException) |
| { |
| ::osl::MutexGuard aGuard (maMutex); |
| |
| sal_Int32 nChildCount = getAccessibleChildCount (); |
| for (sal_Int32 i=0; i<nChildCount; ++i) |
| { |
| Reference<XAccessible> xChild (getAccessibleChild (i)); |
| if (xChild.is()) |
| { |
| Reference<XAccessibleComponent> xChildComponent ( |
| xChild->getAccessibleContext(), uno::UNO_QUERY); |
| if (xChildComponent.is()) |
| { |
| awt::Rectangle aBBox (xChildComponent->getBounds()); |
| if ( (aPoint.X >= aBBox.X) |
| && (aPoint.Y >= aBBox.Y) |
| && (aPoint.X < aBBox.X+aBBox.Width) |
| && (aPoint.Y < aBBox.Y+aBBox.Height) ) |
| return xChild; |
| } |
| } |
| } |
| |
| // Have not found a child under the given point. Returning empty |
| // reference to indicate this. |
| return uno::Reference<XAccessible>(); |
| } |
| |
| |
| |
| |
| awt::Rectangle SAL_CALL AccessibleShape::getBounds (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); |
| ::osl::MutexGuard aGuard (maMutex); |
| |
| ThrowIfDisposed (); |
| awt::Rectangle aBoundingBox; |
| if ( mxShape.is() ) |
| { |
| |
| static const OUString sBoundRectName ( |
| RTL_CONSTASCII_USTRINGPARAM("BoundRect")); |
| static const OUString sAnchorPositionName ( |
| RTL_CONSTASCII_USTRINGPARAM("AnchorPosition")); |
| |
| // Get the shape's bounding box in internal coordinates (in 100th of |
| // mm). Use the property BoundRect. Only if that is not supported ask |
| // the shape for its position and size directly. |
| Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY); |
| Reference<beans::XPropertySetInfo> xSetInfo; |
| bool bFoundBoundRect = false; |
| if (xSet.is()) |
| { |
| xSetInfo = xSet->getPropertySetInfo (); |
| if (xSetInfo.is()) |
| { |
| if (xSetInfo->hasPropertyByName (sBoundRectName)) |
| { |
| try |
| { |
| uno::Any aValue = xSet->getPropertyValue (sBoundRectName); |
| aValue >>= aBoundingBox; |
| bFoundBoundRect = true; |
| } |
| catch (beans::UnknownPropertyException e) |
| { |
| // Handled below (bFoundBoundRect stays false). |
| } |
| } |
| else |
| OSL_TRACE (" no property BoundRect"); |
| } |
| } |
| |
| // Fallback when there is no BoundRect Property. |
| if ( ! bFoundBoundRect ) |
| { |
| awt::Point aPosition (mxShape->getPosition()); |
| awt::Size aSize (mxShape->getSize()); |
| aBoundingBox = awt::Rectangle ( |
| aPosition.X, aPosition.Y, |
| aSize.Width, aSize.Height); |
| |
| // While BoundRects have absolute positions, the position returned |
| // by XPosition::getPosition is relative. Get the anchor position |
| // (usually not (0,0) for Writer shapes). |
| if (xSetInfo.is()) |
| { |
| if (xSetInfo->hasPropertyByName (sAnchorPositionName)) |
| { |
| uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName); |
| awt::Point aAnchorPosition; |
| aPos >>= aAnchorPosition; |
| aBoundingBox.X += aAnchorPosition.X; |
| aBoundingBox.Y += aAnchorPosition.Y; |
| } |
| } |
| } |
| |
| // Transform coordinates from internal to pixel. |
| if (maShapeTreeInfo.GetViewForwarder() == NULL) |
| throw uno::RuntimeException (::rtl::OUString ( |
| RTL_CONSTASCII_USTRINGPARAM( |
| "AccessibleShape has no valid view forwarder")), |
| static_cast<uno::XWeak*>(this)); |
| ::Size aPixelSize = maShapeTreeInfo.GetViewForwarder()->LogicToPixel ( |
| ::Size (aBoundingBox.Width, aBoundingBox.Height)); |
| ::Point aPixelPosition = maShapeTreeInfo.GetViewForwarder()->LogicToPixel ( |
| ::Point (aBoundingBox.X, aBoundingBox.Y)); |
| |
| // Clip the shape's bounding box with the bounding box of its parent. |
| Reference<XAccessibleComponent> xParentComponent ( |
| getAccessibleParent(), uno::UNO_QUERY); |
| if (xParentComponent.is()) |
| { |
| // Make the coordinates relative to the parent. |
| awt::Point aParentLocation (xParentComponent->getLocationOnScreen()); |
| int x = aPixelPosition.getX() - aParentLocation.X; |
| int y = aPixelPosition.getY() - aParentLocation.Y; |
| |
| /* // The following block is a workarround for bug #99889# (property |
| // BoundRect returnes coordinates relative to document window |
| // instead of absolute coordinates for shapes in Writer). Has to |
| // be removed as soon as bug is fixed. |
| |
| // Use a non-null anchor position as flag that the shape is in a |
| // Writer document. |
| if (xSetInfo.is()) |
| if (xSetInfo->hasPropertyByName (sAnchorPositionName)) |
| { |
| uno::Any aPos = xSet->getPropertyValue (sAnchorPositionName); |
| awt::Point aAnchorPosition; |
| aPos >>= aAnchorPosition; |
| if (aAnchorPosition.X > 0) |
| { |
| x = aPixelPosition.getX(); |
| y = aPixelPosition.getY(); |
| } |
| } |
| // End of workarround. |
| */ |
| // Clip with parent (with coordinates relative to itself). |
| ::Rectangle aBBox ( |
| x, y, x + aPixelSize.getWidth(), y + aPixelSize.getHeight()); |
| awt::Size aParentSize (xParentComponent->getSize()); |
| ::Rectangle aParentBBox (0,0, aParentSize.Width, aParentSize.Height); |
| aBBox = aBBox.GetIntersection (aParentBBox); |
| aBoundingBox = awt::Rectangle ( |
| aBBox.getX(), |
| aBBox.getY(), |
| aBBox.getWidth(), |
| aBBox.getHeight()); |
| } |
| else |
| { |
| OSL_TRACE ("parent does not support component"); |
| aBoundingBox = awt::Rectangle ( |
| aPixelPosition.getX(), aPixelPosition.getY(), |
| aPixelSize.getWidth(), aPixelSize.getHeight()); |
| } |
| } |
| |
| return aBoundingBox; |
| } |
| |
| |
| |
| |
| awt::Point SAL_CALL AccessibleShape::getLocation (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| ThrowIfDisposed (); |
| awt::Rectangle aBoundingBox (getBounds()); |
| return awt::Point (aBoundingBox.X, aBoundingBox.Y); |
| } |
| |
| |
| |
| |
| awt::Point SAL_CALL AccessibleShape::getLocationOnScreen (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| ThrowIfDisposed (); |
| |
| // Get relative position... |
| awt::Point aLocation (getLocation ()); |
| |
| // ... and add absolute position of the parent. |
| uno::Reference<XAccessibleComponent> xParentComponent ( |
| getAccessibleParent(), uno::UNO_QUERY); |
| if (xParentComponent.is()) |
| { |
| awt::Point aParentLocation (xParentComponent->getLocationOnScreen()); |
| aLocation.X += aParentLocation.X; |
| aLocation.Y += aParentLocation.Y; |
| } |
| else |
| OSL_TRACE ("getLocation: parent does not support XAccessibleComponent"); |
| return aLocation; |
| } |
| |
| |
| |
| |
| awt::Size SAL_CALL AccessibleShape::getSize (void) |
| throw (uno::RuntimeException) |
| { |
| ThrowIfDisposed (); |
| awt::Rectangle aBoundingBox (getBounds()); |
| return awt::Size (aBoundingBox.Width, aBoundingBox.Height); |
| } |
| |
| |
| |
| |
| sal_Int32 SAL_CALL AccessibleShape::getForeground (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| ThrowIfDisposed (); |
| sal_Int32 nColor (0x0ffffffL); |
| |
| try |
| { |
| uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY); |
| if (aSet.is()) |
| { |
| uno::Any aColor; |
| aColor = aSet->getPropertyValue (OUString::createFromAscii ("LineColor")); |
| aColor >>= nColor; |
| } |
| } |
| catch (::com::sun::star::beans::UnknownPropertyException) |
| { |
| // Ignore exception and return default color. |
| } |
| return nColor; |
| } |
| |
| |
| |
| |
| sal_Int32 SAL_CALL AccessibleShape::getBackground (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| ThrowIfDisposed (); |
| sal_Int32 nColor (0L); |
| |
| try |
| { |
| uno::Reference<beans::XPropertySet> aSet (mxShape, uno::UNO_QUERY); |
| if (aSet.is()) |
| { |
| uno::Any aColor; |
| aColor = aSet->getPropertyValue (OUString::createFromAscii ("FillColor")); |
| aColor >>= nColor; |
| aColor = aSet->getPropertyValue (OUString::createFromAscii ("FillTransparence")); |
| short nTrans=0; |
| aColor >>= nTrans; |
| Color crBk(nColor); |
| if (nTrans == 0 ) |
| { |
| crBk.SetTransparency(0xff); |
| } |
| else |
| { |
| nTrans = short(256 - nTrans / 100. * 256); |
| crBk.SetTransparency(sal_uInt8(nTrans)); |
| } |
| nColor = crBk.GetColor(); |
| } |
| } |
| catch (::com::sun::star::beans::UnknownPropertyException) |
| { |
| // Ignore exception and return default color. |
| } |
| return nColor; |
| } |
| |
| |
| |
| |
| //===== XAccessibleEventBroadcaster ========================================= |
| |
| void SAL_CALL AccessibleShape::addEventListener ( |
| const Reference<XAccessibleEventListener >& rxListener) |
| throw (uno::RuntimeException) |
| { |
| if (rBHelper.bDisposed || rBHelper.bInDispose) |
| { |
| uno::Reference<uno::XInterface> xThis ( |
| (lang::XComponent *)this, uno::UNO_QUERY); |
| rxListener->disposing (lang::EventObject (xThis)); |
| } |
| else |
| { |
| AccessibleContextBase::addEventListener (rxListener); |
| if (mpText != NULL) |
| mpText->AddEventListener (rxListener); |
| } |
| } |
| |
| |
| |
| |
| void SAL_CALL AccessibleShape::removeEventListener ( |
| const Reference<XAccessibleEventListener >& rxListener) |
| throw (uno::RuntimeException) |
| { |
| AccessibleContextBase::removeEventListener (rxListener); |
| if (mpText != NULL) |
| mpText->RemoveEventListener (rxListener); |
| } |
| |
| |
| |
| |
| //===== XInterface ========================================================== |
| |
| com::sun::star::uno::Any SAL_CALL |
| AccessibleShape::queryInterface (const com::sun::star::uno::Type & rType) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| ::com::sun::star::uno::Any aReturn = AccessibleContextBase::queryInterface (rType); |
| if ( ! aReturn.hasValue()) |
| aReturn = ::cppu::queryInterface (rType, |
| static_cast<XAccessibleComponent*>(this), |
| static_cast<XAccessibleExtendedComponent*>(this), |
| static_cast< ::com::sun::star::accessibility::XAccessibleSelection* >(this), |
| |
| static_cast< ::com::sun::star::accessibility::XAccessibleExtendedAttributes* >(this), |
| static_cast<lang::XEventListener*>(this), |
| static_cast<document::XEventListener*>(this), |
| static_cast<lang::XUnoTunnel*>(this), |
| static_cast<XAccessibleGroupPosition*>(this), |
| static_cast<XAccessibleHypertext*>(this) |
| ); |
| return aReturn; |
| } |
| |
| |
| |
| |
| void SAL_CALL |
| AccessibleShape::acquire (void) |
| throw () |
| { |
| AccessibleContextBase::acquire (); |
| } |
| |
| |
| |
| |
| void SAL_CALL |
| AccessibleShape::release (void) |
| throw () |
| { |
| AccessibleContextBase::release (); |
| } |
| // |
| //===== XAccessibleSelection ============================================ |
| // |
| |
| //-------------------------------------------------------------------------------- |
| void SAL_CALL AccessibleShape::selectAccessibleChild( sal_Int32 ) |
| throw ( IndexOutOfBoundsException, RuntimeException ) |
| { |
| } |
| |
| //---------------------------------------------------------------------------------- |
| sal_Bool SAL_CALL AccessibleShape::isAccessibleChildSelected( sal_Int32 nChildIndex ) |
| throw ( IndexOutOfBoundsException, |
| RuntimeException ) |
| { |
| uno::Reference<XAccessible> xAcc = getAccessibleChild( nChildIndex ); |
| uno::Reference<XAccessibleContext> xContext; |
| if( xAcc.is() ) |
| { |
| xContext = xAcc->getAccessibleContext(); |
| } |
| |
| if( xContext.is() ) |
| { |
| if( xContext->getAccessibleRole() == AccessibleRole::PARAGRAPH ) |
| { |
| uno::Reference< ::com::sun::star::accessibility::XAccessibleText > |
| xText(xAcc, uno::UNO_QUERY); |
| if( xText.is() ) |
| { |
| if( xText->getSelectionStart() >= 0 ) return sal_True; |
| } |
| } |
| else if( xContext->getAccessibleRole() == AccessibleRole::SHAPE ) |
| { |
| Reference< XAccessibleStateSet > pRState = xContext->getAccessibleStateSet(); |
| if( !pRState.is() ) |
| return sal_False; |
| |
| uno::Sequence<short> pStates = pRState->getStates(); |
| int nCount = pStates.getLength(); |
| for( int i = 0; i < nCount; i++ ) |
| { |
| if(pStates[i] == AccessibleStateType::SELECTED) |
| return sal_True; |
| } |
| return sal_False; |
| } |
| } |
| |
| return sal_False; |
| } |
| |
| //--------------------------------------------------------------------- |
| void SAL_CALL AccessibleShape::clearAccessibleSelection( ) |
| throw ( RuntimeException ) |
| { |
| } |
| |
| //------------------------------------------------------------------------- |
| void SAL_CALL AccessibleShape::selectAllAccessibleChildren( ) |
| throw ( RuntimeException ) |
| { |
| } |
| |
| //---------------------------------------------------------------------------- |
| sal_Int32 SAL_CALL AccessibleShape::getSelectedAccessibleChildCount() |
| throw ( RuntimeException ) |
| { |
| sal_Int32 nCount = 0; |
| sal_Int32 TotalCount = getAccessibleChildCount(); |
| for( sal_Int32 i = 0; i < TotalCount; i++ ) |
| if( isAccessibleChildSelected(i) ) nCount++; |
| |
| return nCount; |
| } |
| |
| //-------------------------------------------------------------------------------------- |
| Reference<XAccessible> SAL_CALL AccessibleShape::getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) |
| throw ( IndexOutOfBoundsException, RuntimeException) |
| { |
| if ( nSelectedChildIndex > getSelectedAccessibleChildCount() ) |
| throw IndexOutOfBoundsException(); |
| sal_Int32 i1, i2; |
| for( i1 = 0, i2 = 0; i1 < getAccessibleChildCount(); i1++ ) |
| if( isAccessibleChildSelected(i1) ) |
| { |
| if( i2 == nSelectedChildIndex ) |
| return getAccessibleChild( i1 ); |
| i2++; |
| } |
| return Reference<XAccessible>(); |
| } |
| |
| //---------------------------------------------------------------------------------- |
| void SAL_CALL AccessibleShape::deselectAccessibleChild( sal_Int32 ) |
| throw ( IndexOutOfBoundsException, |
| RuntimeException ) |
| { |
| |
| } |
| |
| //===== XAccessibleExtendedAttributes ======================================================== |
| uno::Any SAL_CALL AccessibleShape::getExtendedAttributes() |
| throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) |
| { |
| uno::Any strRet; |
| ::rtl::OUString style; |
| if( getAccessibleRole() != AccessibleRole::SHAPE ) return strRet; |
| if( m_pShape ) |
| { |
| //style = ::rtl::OUString::createFromAscii("style="); |
| style = ::rtl::OUString::createFromAscii("style:"); |
| style += GetStyle(); |
| } |
| style += ::rtl::OUString::createFromAscii(";"); |
| strRet <<= style; |
| return strRet; |
| } |
| //===== XServiceInfo ======================================================== |
| |
| ::rtl::OUString SAL_CALL |
| AccessibleShape::getImplementationName (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleShape")); |
| } |
| |
| |
| |
| |
| uno::Sequence<OUString> SAL_CALL |
| AccessibleShape::getSupportedServiceNames (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| ThrowIfDisposed (); |
| // Get list of supported service names from base class... |
| uno::Sequence<OUString> aServiceNames = |
| AccessibleContextBase::getSupportedServiceNames(); |
| sal_Int32 nCount (aServiceNames.getLength()); |
| |
| // ...and add additional names. |
| aServiceNames.realloc (nCount + 1); |
| static const OUString sAdditionalServiceName (RTL_CONSTASCII_USTRINGPARAM( |
| "com.sun.star.drawing.AccessibleShape")); |
| aServiceNames[nCount] = sAdditionalServiceName; |
| |
| return aServiceNames; |
| } |
| |
| |
| |
| |
| |
| //===== XTypeProvider =================================================== |
| |
| uno::Sequence<uno::Type> SAL_CALL |
| AccessibleShape::getTypes (void) |
| throw (uno::RuntimeException) |
| { |
| ThrowIfDisposed (); |
| // Get list of types from the context base implementation, ... |
| uno::Sequence<uno::Type> aTypeList (AccessibleContextBase::getTypes()); |
| // ... get list of types from component base implementation, ... |
| uno::Sequence<uno::Type> aComponentTypeList (AccessibleComponentBase::getTypes()); |
| // ... define local types, ... |
| const uno::Type aLangEventListenerType = |
| ::getCppuType((const uno::Reference<lang::XEventListener>*)0); |
| const uno::Type aDocumentEventListenerType = |
| ::getCppuType((const uno::Reference<document::XEventListener>*)0); |
| const uno::Type aUnoTunnelType = |
| ::getCppuType((const uno::Reference<lang::XUnoTunnel>*)0); |
| // const uno::Type aStateSetType = |
| // ::getCppuType((const uno::Reference<XAccessibleStateSet>*)0); |
| |
| // ... and merge them all into one list. |
| sal_Int32 nTypeCount (aTypeList.getLength()), |
| nComponentTypeCount (aComponentTypeList.getLength()); |
| int i; |
| |
| aTypeList.realloc (nTypeCount + nComponentTypeCount + 3); |
| |
| for (i=0; i<nComponentTypeCount; i++) |
| aTypeList[nTypeCount + i] = aComponentTypeList[i]; |
| |
| aTypeList[nTypeCount + i++ ] = aLangEventListenerType; |
| aTypeList[nTypeCount + i++ ] = aDocumentEventListenerType; |
| aTypeList[nTypeCount + i ] = aUnoTunnelType; |
| |
| return aTypeList; |
| } |
| |
| |
| |
| |
| //===== lang::XEventListener ================================================ |
| |
| /** Disposing calls are accepted only from the model: Just reset the |
| reference to the model in the shape tree info. Otherwise this object |
| remains functional. |
| */ |
| void SAL_CALL |
| AccessibleShape::disposing (const lang::EventObject& aEvent) |
| throw (uno::RuntimeException) |
| { |
| ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); |
| ::osl::MutexGuard aGuard (maMutex); |
| |
| try |
| { |
| if (aEvent.Source == maShapeTreeInfo.GetModelBroadcaster()) |
| { |
| // Remove reference to model broadcaster to allow it to pass |
| // away. |
| maShapeTreeInfo.SetModelBroadcaster(NULL); |
| } |
| |
| } |
| catch (uno::RuntimeException e) |
| { |
| OSL_TRACE ("caught exception while disposing"); |
| } |
| } |
| |
| |
| |
| |
| //===== document::XEventListener ============================================ |
| |
| void SAL_CALL |
| AccessibleShape::notifyEvent (const document::EventObject& rEventObject) |
| throw (uno::RuntimeException) |
| { |
| static const OUString sShapeModified ( |
| RTL_CONSTASCII_USTRINGPARAM("ShapeModified")); |
| |
| // First check if the event is for us. |
| uno::Reference<drawing::XShape> xShape ( |
| rEventObject.Source, uno::UNO_QUERY); |
| if ( xShape.get() == mxShape.get() ) |
| { |
| if (rEventObject.EventName.equals (sShapeModified)) |
| { |
| //Need to update text children when receiving ShapeModified hint when exiting edit mode for text box |
| if (mpText) |
| mpText->UpdateChildren(); |
| |
| |
| // Some property of a shape has been modified. Send an event |
| // that indicates a change of the visible data to all listeners. |
| CommitChange ( |
| AccessibleEventId::VISIBLE_DATA_CHANGED, |
| uno::Any(), |
| uno::Any()); |
| |
| // Name and Description may have changed. Update the local |
| // values accordingly. |
| UpdateNameAndDescription(); |
| } |
| } |
| } |
| |
| |
| |
| |
| //===== lang::XUnoTunnel ================================================ |
| |
| const uno::Sequence< sal_Int8 >& |
| AccessibleShape::getUnoTunnelImplementationId() |
| throw() |
| { |
| static uno::Sequence< sal_Int8 >* pSeq = 0; |
| |
| if( !pSeq ) |
| { |
| ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); |
| |
| if( !pSeq ) |
| { |
| static uno::Sequence< sal_Int8 > aSeq( 16 ); |
| rtl_createUuid( (sal_uInt8*) aSeq.getArray(), 0, sal_True ); |
| pSeq = &aSeq; |
| } |
| } |
| |
| return( *pSeq ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| AccessibleShape* |
| AccessibleShape::getImplementation( const uno::Reference< uno::XInterface >& rxIFace ) |
| throw() |
| { |
| uno::Reference< lang::XUnoTunnel > xTunnel( rxIFace, uno::UNO_QUERY ); |
| AccessibleShape* pReturn = NULL; |
| |
| if( xTunnel.is() ) |
| pReturn = reinterpret_cast< AccessibleShape* >( xTunnel->getSomething( getUnoTunnelImplementationId() ) ); |
| |
| return( pReturn ); |
| } |
| |
| //------------------------------------------------------------------------------ |
| sal_Int64 SAL_CALL |
| AccessibleShape::getSomething( const uno::Sequence< sal_Int8 >& rIdentifier ) |
| throw(uno::RuntimeException) |
| { |
| sal_Int64 nReturn( 0 ); |
| |
| if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) ) |
| nReturn = reinterpret_cast< sal_Int64 >( this ); |
| |
| return( nReturn ); |
| } |
| |
| //===== IAccessibleViewForwarderListener ==================================== |
| |
| void AccessibleShape::ViewForwarderChanged (ChangeType aChangeType, |
| const IAccessibleViewForwarder* pViewForwarder) |
| { |
| // Inform all listeners that the graphical representation (i.e. size |
| // and/or position) of the shape has changed. |
| CommitChange (AccessibleEventId::VISIBLE_DATA_CHANGED, |
| uno::Any(), |
| uno::Any()); |
| |
| // Tell children manager of the modified view forwarder. |
| if (mpChildrenManager != NULL) |
| mpChildrenManager->ViewForwarderChanged (aChangeType, pViewForwarder); |
| |
| // update our children that our screen position might have changed |
| if( mpText ) |
| mpText->UpdateChildren(); |
| } |
| |
| |
| |
| |
| //===== protected internal ================================================== |
| /// Set this object's name if is different to the current name. |
| ::rtl::OUString |
| AccessibleShape::CreateAccessibleBaseName (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| return ShapeTypeHandler::CreateAccessibleBaseName( mxShape ); |
| } |
| |
| |
| ::rtl::OUString |
| AccessibleShape::CreateAccessibleName (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| //OUString sName (CreateAccessibleBaseName()); |
| OUString sName; |
| sName = GetFullAccessibleName(this); |
| return sName; |
| } |
| |
| ::rtl::OUString |
| AccessibleShape::GetFullAccessibleName (AccessibleShape *shape) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| OUString sName (shape->CreateAccessibleBaseName()); |
| // Append the shape's index to the name to disambiguate between shapes |
| // of the same type. If such an index where not given to the |
| // constructor then use the z-order instead. If even that does not exist |
| // we throw an exception. |
| //long nIndex = mnIndex; |
| //if (nIndex == -1) |
| //{ |
| // try |
| // { |
| // uno::Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY); |
| // if (xSet.is()) |
| // { |
| // uno::Any aZOrder (xSet->getPropertyValue (::rtl::OUString::createFromAscii ("ZOrder"))); |
| // aZOrder >>= nIndex; |
| |
| // // Add one to be not zero based. |
| // nIndex += 1; |
| // } |
| // } |
| // catch (beans::UnknownPropertyException) |
| // { |
| // // We throw our own exception that is a bit more informative. |
| // throw uno::RuntimeException (::rtl::OUString ( |
| // RTL_CONSTASCII_USTRINGPARAM("AccessibleShape has invalid index and no ZOrder property")), |
| // static_cast<uno::XWeak*>(this)); |
| // } |
| |
| //} |
| |
| //// Put a space between name and index because of Gnopernicus othewise |
| //// spells the name. |
| //sName += OUString (RTL_CONSTASCII_USTRINGPARAM(" ")) + OUString::valueOf (nIndex); |
| |
| //return sName; |
| |
| XubString nameStr; |
| if(shape->m_pShape) |
| nameStr = shape->m_pShape->GetName(); |
| if(nameStr.Len() == 0) |
| { |
| sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )); |
| } |
| else |
| { |
| sName = nameStr; |
| } |
| /* |
| sal_Int32 nChildCount = shape->getAccessibleChildCount(); |
| if(nChildCount > 0) |
| { |
| for (sal_Int32 i=0; i<nChildCount; ++i) |
| { |
| Reference<XAccessible> xChild (shape->getAccessibleChild (i)); |
| if (xChild.is()) |
| { |
| uno::Reference <XAccessibleContext> xChildContext(xChild->getAccessibleContext()); |
| if (xChildContext->getAccessibleRole() == AccessibleRole::PARAGRAPH) |
| { |
| uno::Reference<XAccessibleText> xText = uno::Reference<XAccessibleText> ( xChild, uno::UNO_QUERY ); |
| sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )) + xText->getText(); |
| } |
| else if (xChildContext->getAccessibleRole() == AccessibleRole::SHAPE) |
| { |
| sName += OUString( RTL_CONSTASCII_USTRINGPARAM( " " )) + GetFullAccessibleName(static_cast< AccessibleShape*>( xChild.get())); |
| } |
| } |
| } |
| } |
| */ |
| //Solution:If the new produced name if not the same with last,notify name changed |
| // Event |
| if( aAccName != sName && aAccName.getLength() != 0 ) |
| { |
| uno::Any aOldValue, aNewValue; |
| aOldValue <<= aAccName; |
| aNewValue <<= sName; |
| CommitChange( |
| AccessibleEventId::NAME_CHANGED, |
| aNewValue, |
| aOldValue); |
| } |
| aAccName = sName; |
| return sName; |
| } |
| ::rtl::OUString |
| AccessibleShape::CreateAccessibleDescription (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| DescriptionGenerator aDG (mxShape); |
| aDG.Initialize (CreateAccessibleBaseName()); |
| switch (ShapeTypeHandler::Instance().GetTypeId (mxShape)) |
| { |
| case DRAWING_3D_CUBE: |
| case DRAWING_3D_EXTRUDE: |
| case DRAWING_3D_LATHE: |
| case DRAWING_3D_SPHERE: |
| aDG.Add3DProperties (); |
| break; |
| |
| case DRAWING_3D_SCENE: |
| case DRAWING_GROUP: |
| case DRAWING_PAGE: |
| // No further information is appended. |
| break; |
| |
| case DRAWING_CAPTION: |
| case DRAWING_CLOSED_BEZIER: |
| case DRAWING_CLOSED_FREEHAND: |
| case DRAWING_ELLIPSE: |
| case DRAWING_POLY_POLYGON: |
| case DRAWING_POLY_POLYGON_PATH: |
| case DRAWING_RECTANGLE: |
| aDG.AddLineProperties (); |
| aDG.AddFillProperties (); |
| break; |
| |
| case DRAWING_CONNECTOR: |
| case DRAWING_LINE: |
| case DRAWING_MEASURE: |
| case DRAWING_OPEN_BEZIER: |
| case DRAWING_OPEN_FREEHAND: |
| case DRAWING_POLY_LINE: |
| case DRAWING_POLY_LINE_PATH: |
| aDG.AddLineProperties (); |
| break; |
| |
| case DRAWING_CONTROL: |
| aDG.AddProperty (OUString::createFromAscii ("ControlBackground"), |
| DescriptionGenerator::COLOR, |
| OUString()); |
| aDG.AddProperty (OUString::createFromAscii ("ControlBorder"), |
| DescriptionGenerator::INTEGER, |
| OUString()); |
| break; |
| |
| case DRAWING_TEXT: |
| aDG.AddTextProperties (); |
| break; |
| |
| default: |
| aDG.Initialize (::rtl::OUString ( |
| RTL_CONSTASCII_USTRINGPARAM("Unknown accessible shape"))); |
| uno::Reference<drawing::XShapeDescriptor> xDescriptor (mxShape, uno::UNO_QUERY); |
| if (xDescriptor.is()) |
| { |
| aDG.AppendString (::rtl::OUString (RTL_CONSTASCII_USTRINGPARAM("service name="))); |
| aDG.AppendString (xDescriptor->getShapeType()); |
| } |
| } |
| |
| return aDG(); |
| } |
| |
| |
| |
| |
| uno::Reference< drawing::XShape > AccessibleShape::GetXShape() |
| { |
| return( mxShape ); |
| } |
| |
| |
| |
| // protected |
| void AccessibleShape::disposing (void) |
| { |
| ::vos::OGuard aSolarGuard (::Application::GetSolarMutex()); |
| ::osl::MutexGuard aGuard (maMutex); |
| |
| // Make sure to send an event that this object looses the focus in the |
| // case that it has the focus. |
| ::utl::AccessibleStateSetHelper* pStateSet = |
| static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); |
| if (pStateSet != NULL) |
| pStateSet->RemoveState (AccessibleStateType::FOCUSED); |
| |
| // Unregister from broadcasters. |
| Reference<lang::XComponent> xComponent (mxShape, uno::UNO_QUERY); |
| if (xComponent.is()) |
| xComponent->removeEventListener (this); |
| |
| // Unregister from model. |
| if (maShapeTreeInfo.GetModelBroadcaster().is()) |
| maShapeTreeInfo.GetModelBroadcaster()->removeEventListener ( |
| static_cast<document::XEventListener*>(this)); |
| |
| // Release the child containers. |
| if (mpChildrenManager != NULL) |
| { |
| delete mpChildrenManager; |
| mpChildrenManager = NULL; |
| } |
| if (mpText != NULL) |
| { |
| mpText->Dispose(); |
| delete mpText; |
| mpText = NULL; |
| } |
| |
| // Cleanup. Remove references to objects to allow them to be |
| // destroyed. |
| mxShape = NULL; |
| maShapeTreeInfo = AccessibleShapeTreeInfo(); |
| |
| // Call base classes. |
| AccessibleContextBase::dispose (); |
| } |
| |
| sal_Int32 SAL_CALL |
| AccessibleShape::getAccessibleIndexInParent (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| ThrowIfDisposed (); |
| // Use a simple but slow solution for now. Optimize later. |
| |
| sal_Int32 nIndex = m_nIndexInParent; |
| if ( -1 == nIndex ) |
| nIndex = AccessibleContextBase::getAccessibleIndexInParent(); |
| return nIndex; |
| } |
| |
| |
| |
| |
| void AccessibleShape::UpdateNameAndDescription (void) |
| { |
| // Ignore missing title, name, or description. There are fallbacks for |
| // them. |
| try |
| { |
| Reference<beans::XPropertySet> xSet (mxShape, uno::UNO_QUERY_THROW); |
| OUString sString; |
| |
| // Get the accessible name. |
| sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Title"))); |
| if (sString.getLength() > 0) |
| { |
| SetAccessibleName(sString, AccessibleContextBase::FromShape); |
| } |
| else |
| { |
| sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Name"))); |
| if (sString.getLength() > 0) |
| SetAccessibleName(sString, AccessibleContextBase::FromShape); |
| } |
| |
| // Get the accessible description. |
| sString = GetOptionalProperty(xSet, OUString(RTL_CONSTASCII_USTRINGPARAM("Description"))); |
| if (sString.getLength() > 0) |
| SetAccessibleDescription(sString, AccessibleContextBase::FromShape); |
| } |
| catch (uno::RuntimeException&) |
| { |
| } |
| } |
| // Return this object's role. |
| sal_Int16 SAL_CALL AccessibleShape::getAccessibleRole (void) |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| sal_Int16 nAccessibleRole = AccessibleRole::SHAPE ; |
| switch (ShapeTypeHandler::Instance().GetTypeId (mxShape)) |
| { |
| case DRAWING_GRAPHIC_OBJECT: |
| nAccessibleRole = AccessibleRole::GRAPHIC ; break; |
| case DRAWING_OLE: |
| nAccessibleRole = AccessibleRole::EMBEDDED_OBJECT ; break; |
| |
| default: |
| nAccessibleRole = AccessibleContextBase::getAccessibleRole(); |
| break; |
| } |
| |
| return nAccessibleRole; |
| } |
| |
| |
| void AccessibleShape::UpdateDocumentAllSelState(Reference<XAccessibleStateSet> &xStateSet) |
| { |
| if (mpParent && mpParent->IsDocumentSelAll()) |
| { |
| ::utl::AccessibleStateSetHelper* pStateSet = |
| static_cast< ::utl::AccessibleStateSetHelper*>(xStateSet.get()); |
| pStateSet->AddState (AccessibleStateType::SELECTED); |
| |
| //uno::Any NewValue; |
| //NewValue <<= AccessibleStateType::SELECTED; |
| |
| //CommitChange(AccessibleEventId::STATE_CHANGED,NewValue,uno::Any()); |
| } |
| } |
| |
| //sort the drawing objects from up to down, from left to right |
| struct XShapePosCompareHelper |
| { |
| bool operator() ( const uno::Reference<drawing::XShape>& xshape1, |
| const uno::Reference<drawing::XShape>& xshape2 ) const |
| { |
| SdrObject* pObj1 = GetSdrObjectFromXShape(xshape1); |
| SdrObject* pObj2 = GetSdrObjectFromXShape(xshape2); |
| if(pObj1 && pObj2) |
| return pObj1->GetOrdNum() < pObj2->GetOrdNum(); |
| else |
| return 0; |
| } |
| }; |
| //end of group position |
| |
| //===== XAccessibleGroupPosition ========================================= |
| uno::Sequence< sal_Int32 > SAL_CALL |
| AccessibleShape::getGroupPosition( const uno::Any& ) |
| throw (uno::RuntimeException) |
| { |
| // we will return the: |
| // [0] group level |
| // [1] similar items counts in the group |
| // [2] the position of the object in the group |
| uno::Sequence< sal_Int32 > aRet( 3 ); |
| aRet[0] = 0; |
| aRet[1] = 0; |
| aRet[2] = 0; |
| |
| ::com::sun::star::uno::Reference<XAccessible> xParent = getAccessibleParent(); |
| if (!xParent.is()) |
| { |
| return aRet; |
| } |
| SdrObject *pObj = GetSdrObjectFromXShape(mxShape); |
| |
| |
| if(pObj == NULL ) |
| { |
| return aRet; |
| } |
| |
| // Compute object's group level. |
| sal_Int32 nGroupLevel = 0; |
| SdrObject * pUper = pObj->GetUpGroup(); |
| while( pUper ) |
| { |
| ++nGroupLevel; |
| pUper = pUper->GetUpGroup(); |
| } |
| |
| ::com::sun::star::uno::Reference<XAccessibleContext> xParentContext = xParent->getAccessibleContext(); |
| if( xParentContext->getAccessibleRole() == AccessibleRole::DOCUMENT)//Document |
| { |
| Reference< XAccessibleGroupPosition > xGroupPosition( xParent,uno::UNO_QUERY ); |
| if ( xGroupPosition.is() ) |
| { |
| aRet = xGroupPosition->getGroupPosition( uno::makeAny( getAccessibleContext() ) ); |
| } |
| return aRet; |
| } |
| if (xParentContext->getAccessibleRole() != AccessibleRole::SHAPE) |
| { |
| return aRet; |
| } |
| |
| SdrObjList *pGrpList = NULL; |
| if( pObj->GetUpGroup() ) |
| pGrpList = pObj->GetUpGroup()->GetSubList(); |
| else |
| return aRet; |
| |
| std::vector< uno::Reference<drawing::XShape> > vXShapes; |
| if (pGrpList) |
| { |
| const sal_Int32 nObj = pGrpList->GetObjCount(); |
| for(sal_Int32 i = 0 ; i < nObj ; ++i) |
| { |
| SdrObject *pSubObj = pGrpList->GetObj(i); |
| if (pSubObj && |
| xParentContext->getAccessibleChild(i)->getAccessibleContext()->getAccessibleRole() != AccessibleRole::GROUP_BOX) |
| { |
| vXShapes.push_back( GetXShapeForSdrObject(pSubObj) ); |
| } |
| } |
| } |
| |
| std::sort( vXShapes.begin(), vXShapes.end(), XShapePosCompareHelper() ); |
| |
| //get the the index of the selected object in the group |
| std::vector< uno::Reference<drawing::XShape> >::iterator aIter; |
| //we start counting position from 1 |
| sal_Int32 nPos = 1; |
| for ( aIter = vXShapes.begin(); aIter != vXShapes.end(); aIter++, nPos++ ) |
| { |
| if ( (*aIter).get() == mxShape.get() ) |
| { |
| sal_Int32* pArray = aRet.getArray(); |
| pArray[0] = nGroupLevel; |
| pArray[1] = vXShapes.size(); |
| pArray[2] = nPos; |
| break; |
| } |
| } |
| |
| return aRet; |
| } |
| |
| ::rtl::OUString AccessibleShape::getObjectLink( const uno::Any& ) |
| throw (uno::RuntimeException) |
| { |
| ::rtl::OUString aRet; |
| |
| SdrObject *pObj = GetSdrObjectFromXShape(mxShape); |
| if(pObj == NULL ) |
| { |
| return aRet; |
| } |
| if (maShapeTreeInfo.GetDocumentWindow().is()) |
| { |
| Reference< XAccessibleGroupPosition > xGroupPosition( maShapeTreeInfo.GetDocumentWindow(), uno::UNO_QUERY ); |
| if (xGroupPosition.is()) |
| { |
| aRet = xGroupPosition->getObjectLink( uno::makeAny( getAccessibleContext() ) ); |
| } |
| } |
| return aRet; |
| } |
| |
| //===== XAccesibleHypertext ================================================== |
| sal_Int32 SAL_CALL AccessibleShape::getHyperLinkCount() |
| throw (::com::sun::star::uno::RuntimeException) |
| { |
| // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile. |
| // Code need to be adapted.... |
| return 0; |
| |
| /* |
| SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this); |
| if (pLink->IsValidHyperlink()) |
| return 1; |
| else |
| return 0; |
| */ |
| } |
| uno::Reference< XAccessibleHyperlink > SAL_CALL |
| AccessibleShape::getHyperLink( sal_Int32 ) |
| throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) |
| { |
| uno::Reference< XAccessibleHyperlink > xRet; |
| // MT: Introduced with IA2 CWS, but SvxAccessibleHyperlink was redundant to svx::AccessibleHyperlink which we introduced meanwhile. |
| // Code need to be adapted.... |
| /* |
| SvxAccessibleHyperlink* pLink = new SvxAccessibleHyperlink(m_pShape,this); |
| if (pLink->IsValidHyperlink()) |
| xRet = pLink; |
| if( !xRet.is() ) |
| throw ::com::sun::star::lang::IndexOutOfBoundsException(); |
| */ |
| return xRet; |
| } |
| sal_Int32 SAL_CALL AccessibleShape::getHyperLinkIndex( sal_Int32 ) |
| throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) |
| { |
| sal_Int32 nRet = 0; |
| return nRet; |
| } |
| //===== XAccesibleText ================================================== |
| sal_Int32 SAL_CALL AccessibleShape::getCaretPosition( ) throw (::com::sun::star::uno::RuntimeException){return 0;} |
| sal_Bool SAL_CALL AccessibleShape::setCaretPosition( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;} |
| sal_Unicode SAL_CALL AccessibleShape::getCharacter( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return 0;} |
| ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > SAL_CALL AccessibleShape::getCharacterAttributes( sal_Int32, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) |
| { |
| uno::Sequence< ::com::sun::star::beans::PropertyValue > aValues(0); |
| return aValues; |
| } |
| ::com::sun::star::awt::Rectangle SAL_CALL AccessibleShape::getCharacterBounds( sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) |
| { |
| return com::sun::star::awt::Rectangle(0, 0, 0, 0 ); |
| } |
| sal_Int32 SAL_CALL AccessibleShape::getCharacterCount( ) throw (::com::sun::star::uno::RuntimeException){return 0;} |
| sal_Int32 SAL_CALL AccessibleShape::getIndexAtPoint( const ::com::sun::star::awt::Point& ) throw (::com::sun::star::uno::RuntimeException){return 0;} |
| ::rtl::OUString SAL_CALL AccessibleShape::getSelectedText( ) throw (::com::sun::star::uno::RuntimeException){return OUString();} |
| sal_Int32 SAL_CALL AccessibleShape::getSelectionStart( ) throw (::com::sun::star::uno::RuntimeException){return 0;} |
| sal_Int32 SAL_CALL AccessibleShape::getSelectionEnd( ) throw (::com::sun::star::uno::RuntimeException){return 0;} |
| sal_Bool SAL_CALL AccessibleShape::setSelection( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;} |
| ::rtl::OUString SAL_CALL AccessibleShape::getText( ) throw (::com::sun::star::uno::RuntimeException){return OUString();} |
| ::rtl::OUString SAL_CALL AccessibleShape::getTextRange( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return OUString();} |
| ::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) |
| { |
| ::com::sun::star::accessibility::TextSegment aResult; |
| return aResult; |
| } |
| ::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) |
| { |
| ::com::sun::star::accessibility::TextSegment aResult; |
| return aResult; |
| } |
| ::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) |
| { |
| ::com::sun::star::accessibility::TextSegment aResult; |
| return aResult; |
| } |
| sal_Bool SAL_CALL AccessibleShape::copyText( sal_Int32, sal_Int32 ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException){return sal_True;} |
| |
| } // end of namespace accessibility |