| /************************************************************** |
| * |
| * 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_editeng.hxx" |
| |
| //------------------------------------------------------------------------ |
| // |
| // Global header |
| // |
| //------------------------------------------------------------------------ |
| |
| #include <limits.h> |
| #include <vector> |
| #include <algorithm> |
| #include <vos/mutex.hxx> |
| #include <vcl/window.hxx> |
| #include <vcl/svapp.hxx> |
| #include <editeng/flditem.hxx> |
| #include <com/sun/star/uno/Any.hxx> |
| #include <com/sun/star/uno/Reference.hxx> |
| #include <com/sun/star/awt/Point.hpp> |
| #include <com/sun/star/awt/Rectangle.hpp> |
| #include <com/sun/star/lang/DisposedException.hpp> |
| #include <com/sun/star/accessibility/AccessibleRole.hpp> |
| #include <com/sun/star/accessibility/AccessibleTextType.hpp> |
| #include <com/sun/star/accessibility/AccessibleStateType.hpp> |
| #include <com/sun/star/accessibility/AccessibleEventId.hpp> |
| #include <comphelper/accessibleeventnotifier.hxx> |
| #include <comphelper/sequenceashashmap.hxx> |
| #include <unotools/accessiblestatesethelper.hxx> |
| #include <unotools/accessiblerelationsethelper.hxx> |
| #include <com/sun/star/accessibility/AccessibleRelationType.hpp> |
| #include <vcl/unohelp.hxx> |
| #include <editeng/editeng.hxx> |
| #include <editeng/unoprnms.hxx> |
| #include <editeng/unoipset.hxx> |
| #include <editeng/outliner.hxx> |
| #include <svl/intitem.hxx> |
| |
| //------------------------------------------------------------------------ |
| // |
| // Project-local header |
| // |
| //------------------------------------------------------------------------ |
| |
| #include <com/sun/star/beans/PropertyState.hpp> |
| |
| //!!!#include <svx/unoshape.hxx> |
| //!!!#include <svx/dialmgr.hxx> |
| //!!!#include "accessibility.hrc" |
| |
| #include <editeng/unolingu.hxx> |
| #include <editeng/unopracc.hxx> |
| #include "editeng/AccessibleEditableTextPara.hxx" |
| #include "AccessibleHyperlink.hxx" |
| |
| #include <svtools/colorcfg.hxx> |
| #include <algorithm> |
| using namespace std; |
| #include "editeng.hrc" |
| #include <editeng/eerdll.hxx> |
| #include <editeng/numitem.hxx> |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::accessibility; |
| |
| |
| //------------------------------------------------------------------------ |
| // |
| // AccessibleEditableTextPara implementation |
| // |
| //------------------------------------------------------------------------ |
| |
| namespace accessibility |
| { |
| |
| const SvxItemPropertySet* ImplGetSvxCharAndParaPropertiesSet() |
| { |
| // PropertyMap for character and paragraph properties |
| static const SfxItemPropertyMapEntry aPropMap[] = |
| { |
| SVX_UNOEDIT_OUTLINER_PROPERTIES, |
| SVX_UNOEDIT_CHAR_PROPERTIES, |
| SVX_UNOEDIT_PARA_PROPERTIES, |
| SVX_UNOEDIT_NUMBERING_PROPERTIE, |
| {MAP_CHAR_LEN("TextUserDefinedAttributes"), EE_CHAR_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0}, |
| {MAP_CHAR_LEN("ParaUserDefinedAttributes"), EE_PARA_XMLATTRIBS, &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0) , 0, 0}, |
| {0,0,0,0,0,0} |
| }; |
| static SvxItemPropertySet aPropSet( aPropMap, EditEngine::GetGlobalItemPool() ); |
| return &aPropSet; |
| } |
| |
| |
| DBG_NAME( AccessibleEditableTextPara ) |
| |
| // --> OD 2006-01-11 #i27138# - add parameter <_pParaManager> |
| AccessibleEditableTextPara::AccessibleEditableTextPara( |
| const uno::Reference< XAccessible >& rParent, |
| const AccessibleParaManager* _pParaManager ) |
| : AccessibleTextParaInterfaceBase( m_aMutex ), |
| mnParagraphIndex( 0 ), |
| mnIndexInParent( 0 ), |
| mpEditSource( NULL ), |
| maEEOffset( 0, 0 ), |
| mxParent( rParent ), |
| // well, that's strictly (UNO) exception safe, though not |
| // really robust. We rely on the fact that this member is |
| // constructed last, and that the constructor body catches |
| // exceptions, thus no chance for exceptions once the Id is |
| // fetched. Nevertheless, normally should employ RAII here... |
| mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient()), |
| // --> OD 2006-01-11 #i27138# |
| mpParaManager( _pParaManager ) |
| // <-- |
| { |
| #ifdef DBG_UTIL |
| DBG_CTOR( AccessibleEditableTextPara, NULL ); |
| OSL_TRACE( "AccessibleEditableTextPara received ID: %d\n", mnNotifierClientId ); |
| #endif |
| |
| try |
| { |
| // Create the state set. |
| ::utl::AccessibleStateSetHelper* pStateSet = new ::utl::AccessibleStateSetHelper (); |
| mxStateSet = pStateSet; |
| |
| // these are always on |
| pStateSet->AddState( AccessibleStateType::MULTI_LINE ); |
| pStateSet->AddState( AccessibleStateType::FOCUSABLE ); |
| pStateSet->AddState( AccessibleStateType::VISIBLE ); |
| pStateSet->AddState( AccessibleStateType::SHOWING ); |
| pStateSet->AddState( AccessibleStateType::ENABLED ); |
| pStateSet->AddState( AccessibleStateType::SENSITIVE ); |
| } |
| catch( const uno::Exception& ) {} |
| } |
| |
| AccessibleEditableTextPara::~AccessibleEditableTextPara() |
| { |
| DBG_DTOR( AccessibleEditableTextPara, NULL ); |
| |
| // sign off from event notifier |
| if( getNotifierClientId() != -1 ) |
| { |
| try |
| { |
| ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() ); |
| #ifdef DBG_UTIL |
| OSL_TRACE( "AccessibleEditableTextPara revoked ID: %d\n", mnNotifierClientId ); |
| #endif |
| } |
| catch( const uno::Exception& ) {} |
| } |
| } |
| |
| ::rtl::OUString AccessibleEditableTextPara::implGetText() |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return GetTextRange( 0, GetTextLen() ); |
| } |
| |
| ::com::sun::star::lang::Locale AccessibleEditableTextPara::implGetLocale() |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| lang::Locale aLocale; |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getLocale: paragraph index value overflow"); |
| |
| // return locale of first character in the paragraph |
| return SvxLanguageToLocale(aLocale, GetTextForwarder().GetLanguage( static_cast< sal_uInt16 >( GetParagraphIndex() ), 0 )); |
| } |
| |
| void AccessibleEditableTextPara::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| sal_uInt16 nStart, nEnd; |
| |
| if( GetSelection( nStart, nEnd ) ) |
| { |
| nStartIndex = nStart; |
| nEndIndex = nEnd; |
| } |
| else |
| { |
| // #102234# No exception, just set to 'invalid' |
| nStartIndex = -1; |
| nEndIndex = -1; |
| } |
| } |
| |
| void AccessibleEditableTextPara::implGetParagraphBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 /*nIndex*/ ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| DBG_WARNING( "AccessibleEditableTextPara::implGetParagraphBoundary: only a base implementation, ignoring the index" ); |
| |
| rBoundary.startPos = 0; |
| //rBoundary.endPos = GetTextLen(); |
| ::rtl::OUString sText( implGetText() ); |
| sal_Int32 nLength = sText.getLength(); |
| rBoundary.endPos = nLength; |
| } |
| |
| void AccessibleEditableTextPara::implGetLineBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| SvxTextForwarder& rCacheTF = GetTextForwarder(); |
| const sal_Int32 nParaIndex = GetParagraphIndex(); |
| |
| DBG_ASSERT(nParaIndex >= 0 && nParaIndex <= USHRT_MAX, |
| "AccessibleEditableTextPara::implGetLineBoundary: paragraph index value overflow"); |
| |
| const sal_Int32 nTextLen = rCacheTF.GetTextLen( static_cast< sal_uInt16 >( nParaIndex ) ); |
| |
| CheckPosition(nIndex); |
| |
| rBoundary.startPos = rBoundary.endPos = -1; |
| |
| const sal_uInt16 nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) ); |
| |
| if( nIndex == nTextLen ) |
| { |
| // #i17014# Special-casing one-behind-the-end character |
| if( nLineCount <= 1 ) |
| rBoundary.startPos = 0; |
| else |
| rBoundary.startPos = nTextLen - rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), |
| nLineCount-1 ); |
| |
| rBoundary.endPos = nTextLen; |
| } |
| else |
| { |
| // normal line search |
| sal_uInt16 nLine; |
| sal_Int32 nCurIndex; |
| for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine ) |
| { |
| nCurIndex += rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine); |
| |
| if( nCurIndex > nIndex ) |
| { |
| rBoundary.startPos = nCurIndex - rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); |
| rBoundary.endPos = nCurIndex; |
| break; |
| } |
| } |
| } |
| } |
| |
| int AccessibleEditableTextPara::getNotifierClientId() const |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return mnNotifierClientId; |
| } |
| |
| void AccessibleEditableTextPara::SetIndexInParent( sal_Int32 nIndex ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| mnIndexInParent = nIndex; |
| } |
| |
| sal_Int32 AccessibleEditableTextPara::GetIndexInParent() const |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return mnIndexInParent; |
| } |
| |
| void AccessibleEditableTextPara::SetParagraphIndex( sal_Int32 nIndex ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| sal_Int32 nOldIndex = mnParagraphIndex; |
| |
| mnParagraphIndex = nIndex; |
| |
| WeakBullet::HardRefType aChild( maImageBullet.get() ); |
| if( aChild.is() ) |
| aChild->SetParagraphIndex(mnParagraphIndex); |
| |
| try |
| { |
| if( nOldIndex != nIndex ) |
| { |
| uno::Any aOldDesc; |
| uno::Any aOldName; |
| |
| try |
| { |
| aOldDesc <<= getAccessibleDescription(); |
| aOldName <<= getAccessibleName(); |
| } |
| catch( const uno::Exception& ) {} // optional behaviour |
| // index and therefore description changed |
| FireEvent( AccessibleEventId::DESCRIPTION_CHANGED, uno::makeAny( getAccessibleDescription() ), aOldDesc ); |
| FireEvent( AccessibleEventId::NAME_CHANGED, uno::makeAny( getAccessibleName() ), aOldName ); |
| } |
| } |
| catch( const uno::Exception& ) {} // optional behaviour |
| } |
| |
| sal_Int32 AccessibleEditableTextPara::GetParagraphIndex() const SAL_THROW((uno::RuntimeException)) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return mnParagraphIndex; |
| } |
| |
| void AccessibleEditableTextPara::Dispose() |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| int nClientId( getNotifierClientId() ); |
| |
| // #108212# drop all references before notifying dispose |
| mxParent = NULL; |
| mnNotifierClientId = -1; |
| mpEditSource = NULL; |
| |
| // notify listeners |
| if( nClientId != -1 ) |
| { |
| try |
| { |
| uno::Reference < XAccessibleContext > xThis = getAccessibleContext(); |
| |
| // #106234# Delegate to EventNotifier |
| ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, xThis ); |
| #ifdef DBG_UTIL |
| OSL_TRACE( "Disposed ID: %d\n", nClientId ); |
| #endif |
| } |
| catch( const uno::Exception& ) {} |
| } |
| } |
| |
| void AccessibleEditableTextPara::SetEditSource( SvxEditSourceAdapter* pEditSource ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| WeakBullet::HardRefType aChild( maImageBullet.get() ); |
| if( aChild.is() ) |
| aChild->SetEditSource(pEditSource); |
| |
| if( !pEditSource ) |
| { |
| // going defunc |
| UnSetState( AccessibleStateType::SHOWING ); |
| UnSetState( AccessibleStateType::VISIBLE ); |
| SetState( AccessibleStateType::INVALID ); |
| SetState( AccessibleStateType::DEFUNC ); |
| |
| Dispose(); |
| } |
| mpEditSource = pEditSource; |
| // #108900# Init last text content |
| try |
| { |
| TextChanged(); |
| } |
| catch( const uno::RuntimeException& ) {} |
| } |
| |
| ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| // check overflow |
| DBG_ASSERT(nStartEEIndex >= 0 && nStartEEIndex <= USHRT_MAX && |
| nEndEEIndex >= 0 && nEndEEIndex <= USHRT_MAX && |
| GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::MakeSelection: index value overflow"); |
| |
| sal_uInt16 nParaIndex = static_cast< sal_uInt16 >( GetParagraphIndex() ); |
| return ESelection( nParaIndex, static_cast< sal_uInt16 >( nStartEEIndex ), |
| nParaIndex, static_cast< sal_uInt16 >( nEndEEIndex ) ); |
| } |
| |
| ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nEEIndex ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return MakeSelection( nEEIndex, nEEIndex+1 ); |
| } |
| |
| ESelection AccessibleEditableTextPara::MakeCursor( sal_Int32 nEEIndex ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return MakeSelection( nEEIndex, nEEIndex ); |
| } |
| |
| void AccessibleEditableTextPara::CheckIndex( sal_Int32 nIndex ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException)) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| if( nIndex < 0 || nIndex >= getCharacterCount() ) |
| throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleEditableTextPara: character index out of bounds")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy |
| } |
| |
| void AccessibleEditableTextPara::CheckPosition( sal_Int32 nIndex ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException)) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| if( nIndex < 0 || nIndex > getCharacterCount() ) |
| throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleEditableTextPara: character position out of bounds")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > (this) ) ); // disambiguate hierarchy |
| } |
| |
| void AccessibleEditableTextPara::CheckRange( sal_Int32 nStart, sal_Int32 nEnd ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException)) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| CheckPosition( nStart ); |
| CheckPosition( nEnd ); |
| } |
| |
| sal_Bool AccessibleEditableTextPara::GetSelection( sal_uInt16& nStartPos, sal_uInt16& nEndPos ) SAL_THROW((uno::RuntimeException)) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ESelection aSelection; |
| sal_uInt16 nPara = static_cast< sal_uInt16 > ( GetParagraphIndex() ); |
| if( !GetEditViewForwarder().GetSelection( aSelection ) ) |
| return sal_False; |
| |
| if( aSelection.nStartPara < aSelection.nEndPara ) |
| { |
| if( aSelection.nStartPara > nPara || |
| aSelection.nEndPara < nPara ) |
| return sal_False; |
| |
| if( nPara == aSelection.nStartPara ) |
| nStartPos = aSelection.nStartPos; |
| else |
| nStartPos = 0; |
| |
| if( nPara == aSelection.nEndPara ) |
| nEndPos = aSelection.nEndPos; |
| else |
| nEndPos = GetTextLen(); |
| } |
| else |
| { |
| if( aSelection.nStartPara < nPara || |
| aSelection.nEndPara > nPara ) |
| return sal_False; |
| |
| if( nPara == aSelection.nStartPara ) |
| nStartPos = aSelection.nStartPos; |
| else |
| nStartPos = GetTextLen(); |
| |
| if( nPara == aSelection.nEndPara ) |
| nEndPos = aSelection.nEndPos; |
| else |
| nEndPos = 0; |
| } |
| |
| return sal_True; |
| } |
| |
| String AccessibleEditableTextPara::GetText( sal_Int32 nIndex ) SAL_THROW((uno::RuntimeException)) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return GetTextForwarder().GetText( MakeSelection(nIndex) ); |
| } |
| |
| String AccessibleEditableTextPara::GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) SAL_THROW((uno::RuntimeException)) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return GetTextForwarder().GetText( MakeSelection(nStartIndex, nEndIndex) ); |
| } |
| |
| sal_uInt16 AccessibleEditableTextPara::GetTextLen() const SAL_THROW((uno::RuntimeException)) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return GetTextForwarder().GetTextLen( static_cast< sal_uInt16 >( GetParagraphIndex() ) ); |
| } |
| |
| sal_Bool AccessibleEditableTextPara::IsVisible() const |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return mpEditSource ? sal_True : sal_False ; |
| } |
| |
| uno::Reference< XAccessibleText > AccessibleEditableTextPara::GetParaInterface( sal_Int32 nIndex ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| uno::Reference< XAccessible > xParent = getAccessibleParent(); |
| if( xParent.is() ) |
| { |
| uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext(); |
| if( xParentContext.is() ) |
| { |
| uno::Reference< XAccessible > xPara = xParentContext->getAccessibleChild( nIndex ); |
| if( xPara.is() ) |
| { |
| return uno::Reference< XAccessibleText > ( xPara, uno::UNO_QUERY ); |
| } |
| } |
| } |
| |
| return uno::Reference< XAccessibleText >(); |
| } |
| |
| SvxEditSourceAdapter& AccessibleEditableTextPara::GetEditSource() const SAL_THROW((uno::RuntimeException)) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| if( mpEditSource ) |
| return *mpEditSource; |
| else |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No edit source, object is defunct")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > |
| ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy |
| } |
| |
| SvxAccessibleTextAdapter& AccessibleEditableTextPara::GetTextForwarder() const SAL_THROW((uno::RuntimeException)) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| SvxEditSourceAdapter& rEditSource = GetEditSource(); |
| SvxAccessibleTextAdapter* pTextForwarder = rEditSource.GetTextForwarderAdapter(); |
| |
| if( !pTextForwarder ) |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch text forwarder, object is defunct")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > |
| ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy |
| |
| if( pTextForwarder->IsValid() ) |
| return *pTextForwarder; |
| else |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text forwarder is invalid, object is defunct")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > |
| ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy |
| } |
| |
| SvxViewForwarder& AccessibleEditableTextPara::GetViewForwarder() const SAL_THROW((uno::RuntimeException)) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| SvxEditSource& rEditSource = GetEditSource(); |
| SvxViewForwarder* pViewForwarder = rEditSource.GetViewForwarder(); |
| |
| if( !pViewForwarder ) |
| { |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, object is defunct")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > |
| ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy |
| } |
| |
| if( pViewForwarder->IsValid() ) |
| return *pViewForwarder; |
| else |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object is defunct")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > |
| ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy |
| } |
| |
| SvxAccessibleTextEditViewAdapter& AccessibleEditableTextPara::GetEditViewForwarder( sal_Bool bCreate ) const SAL_THROW((uno::RuntimeException)) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| SvxEditSourceAdapter& rEditSource = GetEditSource(); |
| SvxAccessibleTextEditViewAdapter* pTextEditViewForwarder = rEditSource.GetEditViewForwarderAdapter( bCreate ); |
| |
| if( !pTextEditViewForwarder ) |
| { |
| if( bCreate ) |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, object is defunct")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > |
| ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy |
| else |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No view forwarder, object not in edit mode")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > |
| ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy |
| } |
| |
| if( pTextEditViewForwarder->IsValid() ) |
| return *pTextEditViewForwarder; |
| else |
| { |
| if( bCreate ) |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object is defunct")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > |
| ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy |
| else |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object not in edit mode")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > |
| ( const_cast< AccessibleEditableTextPara* > (this) ) ) ); // disambiguate hierarchy |
| } |
| } |
| |
| sal_Bool AccessibleEditableTextPara::HaveEditView() const |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| SvxEditSource& rEditSource = GetEditSource(); |
| SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder(); |
| |
| if( !pViewForwarder ) |
| return sal_False; |
| |
| if( !pViewForwarder->IsValid() ) |
| return sal_False; |
| |
| return sal_True; |
| } |
| |
| sal_Bool AccessibleEditableTextPara::HaveChildren() |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::HaveChildren: paragraph index value overflow"); |
| |
| return GetTextForwarder().HaveImageBullet( static_cast< sal_uInt16 >(GetParagraphIndex()) ); |
| } |
| |
| sal_Bool AccessibleEditableTextPara::IsActive() const SAL_THROW((uno::RuntimeException)) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| SvxEditSource& rEditSource = GetEditSource(); |
| SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder(); |
| |
| if( !pViewForwarder ) |
| return sal_False; |
| |
| if( pViewForwarder->IsValid() ) |
| return sal_False; |
| else |
| return sal_True; |
| } |
| |
| Rectangle AccessibleEditableTextPara::LogicToPixel( const Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder& rForwarder ) |
| { |
| // convert to screen coordinates |
| return Rectangle( rForwarder.LogicToPixel( rRect.TopLeft(), rMapMode ), |
| rForwarder.LogicToPixel( rRect.BottomRight(), rMapMode ) ); |
| } |
| |
| const Point& AccessibleEditableTextPara::GetEEOffset() const |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return maEEOffset; |
| } |
| |
| void AccessibleEditableTextPara::SetEEOffset( const Point& rOffset ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| WeakBullet::HardRefType aChild( maImageBullet.get() ); |
| if( aChild.is() ) |
| aChild->SetEEOffset(rOffset); |
| |
| maEEOffset = rOffset; |
| } |
| |
| void AccessibleEditableTextPara::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue) const |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| uno::Reference < XAccessibleContext > xThis( const_cast< AccessibleEditableTextPara* > (this)->getAccessibleContext() ); |
| |
| AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue); |
| |
| // #102261# Call global queue for focus events |
| if( nEventId == AccessibleEventId::STATE_CHANGED ) |
| vcl::unohelper::NotifyAccessibleStateEventGlobally( aEvent ); |
| |
| // #106234# Delegate to EventNotifier |
| if( getNotifierClientId() != -1 ) |
| ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(), |
| aEvent ); |
| } |
| |
| void AccessibleEditableTextPara::GotPropertyEvent( const uno::Any& rNewValue, const sal_Int16 nEventId ) const |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| FireEvent( nEventId, rNewValue ); |
| } |
| |
| void AccessibleEditableTextPara::LostPropertyEvent( const uno::Any& rOldValue, const sal_Int16 nEventId ) const |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| FireEvent( nEventId, uno::Any(), rOldValue ); |
| } |
| |
| bool AccessibleEditableTextPara::HasState( const sal_Int16 nStateId ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); |
| if( pStateSet != NULL ) |
| return pStateSet->contains(nStateId) ? true : false; |
| |
| return false; |
| } |
| |
| void AccessibleEditableTextPara::SetState( const sal_Int16 nStateId ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); |
| if( pStateSet != NULL && |
| !pStateSet->contains(nStateId) ) |
| { |
| pStateSet->AddState( nStateId ); |
| // MT: Removed method IsShapeParaFocusable which was introduced with IA2 - basically it was only about figuring out wether or not the window has the focus, should be solved differently |
| // if(IsShapeParaFocusable()) |
| GotPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED ); |
| } |
| } |
| |
| void AccessibleEditableTextPara::UnSetState( const sal_Int16 nStateId ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); |
| if( pStateSet != NULL && |
| pStateSet->contains(nStateId) ) |
| { |
| pStateSet->RemoveState( nStateId ); |
| LostPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED ); |
| } |
| } |
| |
| void AccessibleEditableTextPara::TextChanged() |
| { |
| ::rtl::OUString aCurrentString( OCommonAccessibleText::getText() ); |
| uno::Any aDeleted; |
| uno::Any aInserted; |
| if( OCommonAccessibleText::implInitTextChangedEvent( maLastTextString, aCurrentString, |
| aDeleted, aInserted) ) |
| { |
| FireEvent( AccessibleEventId::TEXT_CHANGED, aInserted, aDeleted ); |
| maLastTextString = aCurrentString; |
| } |
| } |
| |
| sal_Bool AccessibleEditableTextPara::GetAttributeRun( sal_uInt16& nStartIndex, sal_uInt16& nEndIndex, sal_Int32 nIndex ) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| DBG_ASSERT(nIndex >= 0 && nIndex <= USHRT_MAX, |
| "AccessibleEditableTextPara::GetAttributeRun: index value overflow"); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getLocale: paragraph index value overflow"); |
| |
| return GetTextForwarder().GetAttributeRun( nStartIndex, |
| nEndIndex, |
| static_cast< sal_uInt16 >(GetParagraphIndex()), |
| static_cast< sal_uInt16 >(nIndex) ); |
| } |
| |
| uno::Any SAL_CALL AccessibleEditableTextPara::queryInterface (const uno::Type & rType) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| uno::Any aRet; |
| |
| // must provide XAccesibleText by hand, since it comes publicly inherited by XAccessibleEditableText |
| if ( rType == ::getCppuType((uno::Reference< XAccessibleText > *)0) ) |
| { |
| uno::Reference< XAccessibleText > aAccText = static_cast< XAccessibleEditableText * >(this); |
| aRet <<= aAccText; |
| } |
| else if ( rType == ::getCppuType((uno::Reference< XAccessibleEditableText > *)0) ) |
| { |
| uno::Reference< XAccessibleEditableText > aAccEditText = this; |
| aRet <<= aAccEditText; |
| } |
| else if ( rType == ::getCppuType((uno::Reference< XAccessibleHypertext > *)0) ) |
| { |
| uno::Reference< XAccessibleHypertext > aAccHyperText = this; |
| aRet <<= aAccHyperText; |
| } |
| else |
| { |
| aRet = AccessibleTextParaInterfaceBase::queryInterface(rType); |
| } |
| |
| return aRet; |
| } |
| |
| // XAccessible |
| uno::Reference< XAccessibleContext > SAL_CALL AccessibleEditableTextPara::getAccessibleContext() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| // We implement the XAccessibleContext interface in the same object |
| return uno::Reference< XAccessibleContext > ( this ); |
| } |
| |
| // XAccessibleContext |
| sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleChildCount() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| return HaveChildren() ? 1 : 0; |
| } |
| |
| uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| if( !HaveChildren() ) |
| throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No childs available")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy |
| |
| if( i != 0 ) |
| throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid child index")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > (this) ) ); // static_cast: disambiguate hierarchy |
| |
| WeakBullet::HardRefType aChild( maImageBullet.get() ); |
| |
| if( !aChild.is() ) |
| { |
| // there is no hard reference available, create object then |
| AccessibleImageBullet* pChild = new AccessibleImageBullet( uno::Reference< XAccessible >( this ) ); |
| uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY ); |
| |
| if( !xChild.is() ) |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Child creation failed")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< ::cppu::OWeakObject* > (this) ) ); |
| |
| aChild = WeakBullet::HardRefType( xChild, pChild ); |
| |
| aChild->SetEditSource( &GetEditSource() ); |
| aChild->SetParagraphIndex( GetParagraphIndex() ); |
| aChild->SetIndexInParent( i ); |
| |
| maImageBullet = aChild; |
| } |
| |
| return aChild.getRef(); |
| } |
| |
| uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleParent() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| #ifdef DBG_UTIL |
| if( !mxParent.is() ) |
| DBG_TRACE( "AccessibleEditableTextPara::getAccessibleParent: no frontend set, did somebody forgot to call AccessibleTextHelper::SetEventSource()?"); |
| #endif |
| |
| return mxParent; |
| } |
| |
| sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleIndexInParent() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return mnIndexInParent; |
| } |
| |
| sal_Int16 SAL_CALL AccessibleEditableTextPara::getAccessibleRole() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return AccessibleRole::PARAGRAPH; |
| } |
| |
| ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleDescription() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| // append first 40 characters from text, or first line, if shorter |
| // (writer takes first sentence here, but that's not supported |
| // from EditEngine) |
| // throws if defunc |
| ::rtl::OUString aLine; |
| |
| if( getCharacterCount() ) |
| aLine = getTextAtIndex(0, AccessibleTextType::LINE).SegmentText; |
| |
| // Get the string from the resource for the specified id. |
| String sStr = ::rtl::OUString( String( EditResId (RID_SVXSTR_A11Y_PARAGRAPH_DESCRIPTION ) ) ); |
| String sParaIndex = ::rtl::OUString::valueOf( GetParagraphIndex() ); |
| sStr.SearchAndReplace( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "$(ARG)" )), |
| sParaIndex ); |
| |
| if( aLine.getLength() > MaxDescriptionLen ) |
| { |
| ::rtl::OUString aCurrWord; |
| sal_Int32 i; |
| |
| // search backward from MaxDescriptionLen for previous word start |
| for( aCurrWord=getTextAtIndex(MaxDescriptionLen, AccessibleTextType::WORD).SegmentText, |
| i=MaxDescriptionLen, |
| aLine=::rtl::OUString(); |
| i>=0; |
| --i ) |
| { |
| if( getTextAtIndex(i, AccessibleTextType::WORD).SegmentText != aCurrWord ) |
| { |
| if( i == 0 ) |
| // prevent completely empty string |
| aLine = getTextAtIndex(0, AccessibleTextType::WORD).SegmentText; |
| else |
| aLine = getTextRange(0, i); |
| } |
| } |
| } |
| |
| return ::rtl::OUString( sStr ) + aLine; |
| } |
| |
| ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleName() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| // throws if defunc |
| sal_Int32 nPara( GetParagraphIndex() ); |
| |
| // Get the string from the resource for the specified id. |
| String sStr = ::rtl::OUString( String( EditResId (RID_SVXSTR_A11Y_PARAGRAPH_NAME) ) ); |
| String sParaIndex = ::rtl::OUString::valueOf( nPara ); |
| sStr.SearchAndReplace( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "$(ARG)" )), |
| sParaIndex ); |
| |
| return ::rtl::OUString( sStr ); |
| } |
| |
| uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleEditableTextPara::getAccessibleRelationSet() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| // --> OD 2006-01-11 #i27138# - provide relations CONTENT_FLOWS_FROM |
| // and CONTENT_FLOWS_TO |
| if ( mpParaManager ) |
| { |
| utl::AccessibleRelationSetHelper* pAccRelSetHelper = |
| new utl::AccessibleRelationSetHelper(); |
| sal_Int32 nMyParaIndex( GetParagraphIndex() ); |
| // relation CONTENT_FLOWS_FROM |
| if ( nMyParaIndex > 0 && |
| mpParaManager->IsReferencable( nMyParaIndex - 1 ) ) |
| { |
| uno::Sequence<uno::Reference<XInterface> > aSequence(1); |
| aSequence[0] = |
| mpParaManager->GetChild( nMyParaIndex - 1 ).first.get().getRef(); |
| AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_FROM, |
| aSequence ); |
| pAccRelSetHelper->AddRelation( aAccRel ); |
| } |
| |
| // relation CONTENT_FLOWS_TO |
| if ( (nMyParaIndex + 1) < (sal_Int32)mpParaManager->GetNum() && |
| mpParaManager->IsReferencable( nMyParaIndex + 1 ) ) |
| { |
| uno::Sequence<uno::Reference<XInterface> > aSequence(1); |
| aSequence[0] = |
| mpParaManager->GetChild( nMyParaIndex + 1 ).first.get().getRef(); |
| AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_TO, |
| aSequence ); |
| pAccRelSetHelper->AddRelation( aAccRel ); |
| } |
| |
| return pAccRelSetHelper; |
| } |
| else |
| { |
| // no relations, therefore empty |
| return uno::Reference< XAccessibleRelationSet >(); |
| } |
| // <-- |
| } |
| |
| uno::Reference< XAccessibleStateSet > SAL_CALL AccessibleEditableTextPara::getAccessibleStateSet() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| // Create a copy of the state set and return it. |
| ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get()); |
| |
| if( !pStateSet ) |
| return uno::Reference<XAccessibleStateSet>(); |
| uno::Reference<XAccessibleStateSet> xParentStates; |
| if (getAccessibleParent().is()) |
| { |
| uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext(); |
| xParentStates = xParentContext->getAccessibleStateSet(); |
| } |
| if (xParentStates.is() && xParentStates->contains(AccessibleStateType::EDITABLE) ) |
| { |
| pStateSet->AddState(AccessibleStateType::EDITABLE); |
| } |
| return uno::Reference<XAccessibleStateSet>( new ::utl::AccessibleStateSetHelper (*pStateSet) ); |
| } |
| |
| lang::Locale SAL_CALL AccessibleEditableTextPara::getLocale() throw (IllegalAccessibleComponentStateException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| return implGetLocale(); |
| } |
| |
| void SAL_CALL AccessibleEditableTextPara::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| if( getNotifierClientId() != -1 ) |
| ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener ); |
| } |
| |
| void SAL_CALL AccessibleEditableTextPara::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| if( getNotifierClientId() != -1 ) |
| ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener ); |
| } |
| |
| // XAccessibleComponent |
| sal_Bool SAL_CALL AccessibleEditableTextPara::containsPoint( const awt::Point& aTmpPoint ) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::contains: index value overflow"); |
| |
| awt::Rectangle aTmpRect = getBounds(); |
| Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) ); |
| Point aPoint( aTmpPoint.X, aTmpPoint.Y ); |
| |
| return aRect.IsInside( aPoint ); |
| } |
| |
| uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleAtPoint( const awt::Point& _aPoint ) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| if( HaveChildren() ) |
| { |
| // #103862# No longer need to make given position relative |
| Point aPoint( _aPoint.X, _aPoint.Y ); |
| |
| // respect EditEngine offset to surrounding shape/cell |
| aPoint -= GetEEOffset(); |
| |
| // convert to EditEngine coordinate system |
| SvxTextForwarder& rCacheTF = GetTextForwarder(); |
| Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) ); |
| |
| EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 > (GetParagraphIndex()) ); |
| |
| if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && |
| aBulletInfo.bVisible && |
| aBulletInfo.nType == SVX_NUM_BITMAP ) |
| { |
| Rectangle aRect = aBulletInfo.aBounds; |
| |
| if( aRect.IsInside( aLogPoint ) ) |
| return getAccessibleChild(0); |
| } |
| } |
| |
| // no children at all, or none at given position |
| return uno::Reference< XAccessible >(); |
| } |
| |
| awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getBounds: index value overflow"); |
| |
| SvxTextForwarder& rCacheTF = GetTextForwarder(); |
| Rectangle aRect = rCacheTF.GetParaBounds( static_cast< sal_uInt16 >( GetParagraphIndex() ) ); |
| |
| // convert to screen coordinates |
| Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect, |
| rCacheTF.GetMapMode(), |
| GetViewForwarder() ); |
| |
| // offset from shape/cell |
| Point aOffset = GetEEOffset(); |
| |
| return awt::Rectangle( aScreenRect.Left() + aOffset.X(), |
| aScreenRect.Top() + aOffset.Y(), |
| aScreenRect.GetSize().Width(), |
| aScreenRect.GetSize().Height() ); |
| } |
| |
| awt::Point SAL_CALL AccessibleEditableTextPara::getLocation( ) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| awt::Rectangle aRect = getBounds(); |
| |
| return awt::Point( aRect.X, aRect.Y ); |
| } |
| |
| awt::Point SAL_CALL AccessibleEditableTextPara::getLocationOnScreen( ) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| // relate us to parent |
| uno::Reference< XAccessible > xParent = getAccessibleParent(); |
| if( xParent.is() ) |
| { |
| uno::Reference< XAccessibleComponent > xParentComponent( xParent, uno::UNO_QUERY ); |
| if( xParentComponent.is() ) |
| { |
| awt::Point aRefPoint = xParentComponent->getLocationOnScreen(); |
| awt::Point aPoint = getLocation(); |
| aPoint.X += aRefPoint.X; |
| aPoint.Y += aRefPoint.Y; |
| |
| return aPoint; |
| } |
| // --> OD 2009-12-16 #i88070# |
| // fallback to parent's <XAccessibleContext> instance |
| else |
| { |
| uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext(); |
| if ( xParentContext.is() ) |
| { |
| uno::Reference< XAccessibleComponent > xParentContextComponent( xParentContext, uno::UNO_QUERY ); |
| if( xParentContextComponent.is() ) |
| { |
| awt::Point aRefPoint = xParentContextComponent->getLocationOnScreen(); |
| awt::Point aPoint = getLocation(); |
| aPoint.X += aRefPoint.X; |
| aPoint.Y += aRefPoint.Y; |
| |
| return aPoint; |
| } |
| } |
| } |
| // <-- |
| } |
| |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot access parent")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy |
| } |
| |
| awt::Size SAL_CALL AccessibleEditableTextPara::getSize( ) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| awt::Rectangle aRect = getBounds(); |
| |
| return awt::Size( aRect.Width, aRect.Height ); |
| } |
| |
| void SAL_CALL AccessibleEditableTextPara::grabFocus( ) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| // set cursor to this paragraph |
| setSelection(0,0); |
| } |
| |
| sal_Int32 SAL_CALL AccessibleEditableTextPara::getForeground( ) throw (::com::sun::star::uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| // #104444# Added to XAccessibleComponent interface |
| svtools::ColorConfig aColorConfig; |
| sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor; |
| return static_cast<sal_Int32>(nColor); |
| } |
| |
| sal_Int32 SAL_CALL AccessibleEditableTextPara::getBackground( ) throw (::com::sun::star::uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| // #104444# Added to XAccessibleComponent interface |
| Color aColor( Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor() ); |
| |
| // the background is transparent |
| aColor.SetTransparency( 0xFF); |
| |
| return static_cast<sal_Int32>( aColor.GetColor() ); |
| } |
| |
| // XAccessibleText |
| sal_Int32 SAL_CALL AccessibleEditableTextPara::getCaretPosition() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| if( !HaveEditView() ) |
| return -1; |
| |
| ESelection aSelection; |
| if( GetEditViewForwarder().GetSelection( aSelection ) && |
| GetParagraphIndex() == aSelection.nEndPara ) |
| { |
| // caret is always nEndPara,nEndPos |
| EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); |
| if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && |
| aBulletInfo.bVisible && |
| aBulletInfo.nType != SVX_NUM_BITMAP ) |
| { |
| sal_Int32 nBulletLen = aBulletInfo.aText.Len(); |
| if( aSelection.nEndPos - nBulletLen >= 0 ) |
| return aSelection.nEndPos - nBulletLen; |
| } |
| return aSelection.nEndPos; |
| } |
| |
| // not within this paragraph |
| return -1; |
| } |
| |
| sal_Bool SAL_CALL AccessibleEditableTextPara::setCaretPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return setSelection(nIndex, nIndex); |
| } |
| |
| sal_Unicode SAL_CALL AccessibleEditableTextPara::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getCharacter: index value overflow"); |
| |
| return OCommonAccessibleText::getCharacter( nIndex ); |
| } |
| static uno::Sequence< ::rtl::OUString > getAttributeNames() |
| { |
| static uno::Sequence< ::rtl::OUString >* pNames = NULL; |
| |
| if( pNames == NULL ) |
| { |
| uno::Sequence< ::rtl::OUString >* pSeq = new uno::Sequence< ::rtl::OUString >( 21 ); |
| ::rtl::OUString* pStrings = pSeq->getArray(); |
| sal_Int32 i = 0; |
| #define STR(x) pStrings[i++] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(x)) |
| //STR("CharBackColor"); |
| STR("CharColor"); |
| STR("CharContoured"); |
| STR("CharEmphasis"); |
| STR("CharEscapement"); |
| STR("CharFontName"); |
| STR("CharHeight"); |
| STR("CharPosture"); |
| STR("CharShadowed"); |
| STR("CharStrikeout"); |
| STR("CharUnderline"); |
| STR("CharUnderlineColor"); |
| STR("CharWeight"); |
| STR("NumberingLevel"); |
| STR("NumberingRules"); |
| STR("ParaAdjust"); |
| STR("ParaBottomMargin"); |
| STR("ParaFirstLineIndent"); |
| STR("ParaLeftMargin"); |
| STR("ParaLineSpacing"); |
| STR("ParaRightMargin"); |
| STR("ParaTabStops"); |
| #undef STR |
| DBG_ASSERT( i == pSeq->getLength(), "Please adjust length" ); |
| if( i != pSeq->getLength() ) |
| pSeq->realloc( i ); |
| pNames = pSeq; |
| } |
| return *pNames; |
| } |
| struct IndexCompare |
| { |
| const PropertyValue* pValues; |
| IndexCompare( const PropertyValue* pVals ) : pValues(pVals) {} |
| bool operator() ( const sal_Int32& a, const sal_Int32& b ) const |
| { |
| return (pValues[a].Name < pValues[b].Name) ? true : false; |
| } |
| }; |
| |
| String AccessibleEditableTextPara::GetFieldTypeNameAtIndex(sal_Int32 nIndex) |
| { |
| String strFldType; |
| SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); |
| //For field object info |
| sal_Int32 nParaIndex = GetParagraphIndex(); |
| sal_Int32 nAllFieldLen = 0; |
| sal_Int32 nField = rCacheTF.GetFieldCount(sal_uInt16(nParaIndex)), nFoundFieldIndex = -1; |
| EFieldInfo ree; |
| sal_Int32 reeBegin, reeEnd; |
| sal_Int32 nFieldType = -1; |
| for(sal_uInt16 j = 0; j < nField; j++) |
| { |
| ree = rCacheTF.GetFieldInfo(sal_uInt16(nParaIndex), j); |
| reeBegin = ree.aPosition.nIndex + nAllFieldLen; |
| reeEnd = reeBegin + ree.aCurrentText.Len(); |
| nAllFieldLen += (ree.aCurrentText.Len() - 1); |
| if( reeBegin > nIndex ) |
| { |
| break; |
| } |
| if( nIndex >= reeBegin && nIndex < reeEnd ) |
| { |
| nFoundFieldIndex = j; |
| break; |
| } |
| } |
| if( nFoundFieldIndex >= 0 ) |
| { |
| // So we get a field, check its type now. |
| nFieldType = ree.pFieldItem->GetField()->GetClassId() ; |
| } |
| switch(nFieldType) |
| { |
| case SVX_DATEFIELD: |
| { |
| const SvxDateField* pDateField = static_cast< const SvxDateField* >(ree.pFieldItem->GetField()); |
| if (pDateField) |
| { |
| if (pDateField->GetType() == SVXDATETYPE_FIX) |
| strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("date (fixed)")); |
| else if (pDateField->GetType() == SVXDATETYPE_VAR) |
| strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("date (variable)")); |
| } |
| } |
| break; |
| case SVX_PAGEFIELD: |
| strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("page-number")); |
| break; |
| //support the sheet name & pages fields |
| case SVX_PAGESFIELD: |
| strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("page-count")); |
| break; |
| case SVX_TABLEFIELD: |
| strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sheet-name")); |
| break; |
| //End |
| case SVX_TIMEFIELD: |
| strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time")); |
| break; |
| case SVX_EXT_TIMEFIELD: |
| { |
| const SvxExtTimeField* pTimeField = static_cast< const SvxExtTimeField* >(ree.pFieldItem->GetField()); |
| if (pTimeField) |
| { |
| if (pTimeField->GetType() == SVXTIMETYPE_FIX) |
| strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time (fixed)")); |
| else if (pTimeField->GetType() == SVXTIMETYPE_VAR) |
| strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time (variable)")); |
| } |
| } |
| break; |
| case SVX_AUTHORFIELD: |
| strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("author")); |
| break; |
| case SVX_EXT_FILEFIELD: |
| case SVX_FILEFIELD: |
| strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file name")); |
| default: |
| break; |
| } |
| return strFldType; |
| } |
| |
| uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rRequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| //Skip the bullet range to ingnore the bullet text |
| SvxTextForwarder& rCacheTF = GetTextForwarder(); |
| EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); |
| if (aBulletInfo.bVisible) |
| nIndex += aBulletInfo.aText.Len(); |
| if (nIndex != 0 && nIndex >= getCharacterCount()) |
| nIndex = getCharacterCount()-1; |
| // |
| if (nIndex != 0) |
| CheckIndex(nIndex); // may throw IndexOutOfBoundsException |
| |
| bool bSupplementalMode = false; |
| uno::Sequence< ::rtl::OUString > aPropertyNames = rRequestedAttributes; |
| if (aPropertyNames.getLength() == 0) |
| { |
| bSupplementalMode = true; |
| aPropertyNames = getAttributeNames(); |
| } |
| // get default attribues... |
| ::comphelper::SequenceAsHashMap aPropHashMap( getDefaultAttributes( aPropertyNames ) ); |
| |
| // ... and override them with the direct attributes from the specific position |
| uno::Sequence< beans::PropertyValue > aRunAttribs( getRunAttributes( nIndex, aPropertyNames ) ); |
| sal_Int32 nRunAttribs = aRunAttribs.getLength(); |
| const beans::PropertyValue *pRunAttrib = aRunAttribs.getConstArray(); |
| for (sal_Int32 k = 0; k < nRunAttribs; ++k) |
| { |
| const beans::PropertyValue &rRunAttrib = pRunAttrib[k]; |
| aPropHashMap[ rRunAttrib.Name ] = rRunAttrib.Value; //!! should not only be the value !! |
| } |
| #ifdef TL_DEBUG |
| { |
| uno::Sequence< rtl::OUString > aNames(1); |
| aNames.getArray()[0] = rtl::OUString::createFromAscii("CharHeight"); |
| const rtl::OUString *pNames = aNames.getConstArray(); |
| const uno::Sequence< beans::PropertyValue > aAttribs( getRunAttributes( nIndex, aNames ) ); |
| const beans::PropertyValue *pAttribs = aAttribs.getConstArray(); |
| double d1 = -1.0; |
| float f1 = -1.0; |
| if (aAttribs.getLength()) |
| { |
| uno::Any aAny( pAttribs[0].Value ); |
| aAny >>= d1; |
| aAny >>= f1; |
| } |
| int i = 3; |
| } |
| #endif |
| |
| // get resulting sequence |
| uno::Sequence< beans::PropertyValue > aRes; |
| aPropHashMap >> aRes; |
| |
| // since SequenceAsHashMap ignores property handles and property state |
| // we have to restore the property state here (property handles are |
| // of no use to the accessibility API). |
| sal_Int32 nRes = aRes.getLength(); |
| beans::PropertyValue *pRes = aRes.getArray(); |
| for (sal_Int32 i = 0; i < nRes; ++i) |
| { |
| beans::PropertyValue &rRes = pRes[i]; |
| sal_Bool bIsDirectVal = sal_False; |
| for (sal_Int32 k = 0; k < nRunAttribs && !bIsDirectVal; ++k) |
| { |
| if (rRes.Name == pRunAttrib[k].Name) |
| bIsDirectVal = sal_True; |
| } |
| rRes.Handle = -1; |
| rRes.State = bIsDirectVal ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE; |
| } |
| if( bSupplementalMode ) |
| { |
| _correctValues( nIndex, aRes ); |
| // NumberingPrefix |
| nRes = aRes.getLength(); |
| aRes.realloc( nRes + 1 ); |
| pRes = aRes.getArray(); |
| beans::PropertyValue &rRes = pRes[nRes]; |
| rRes.Name = rtl::OUString::createFromAscii("NumberingPrefix"); |
| ::rtl::OUString numStr; |
| if (aBulletInfo.nType != SVX_NUM_CHAR_SPECIAL && aBulletInfo.nType != SVX_NUM_BITMAP) |
| numStr = (::rtl::OUString)aBulletInfo.aText; |
| rRes.Value <<= numStr; |
| rRes.Handle = -1; |
| rRes.State = PropertyState_DIRECT_VALUE; |
| //For field object. |
| String strFieldType = GetFieldTypeNameAtIndex(nIndex); |
| if (strFieldType.Len() > 0) |
| { |
| nRes = aRes.getLength(); |
| aRes.realloc( nRes + 1 ); |
| pRes = aRes.getArray(); |
| beans::PropertyValue &rResField = pRes[nRes]; |
| beans::PropertyValue aFieldType; |
| rResField.Name = rtl::OUString::createFromAscii("FieldType"); |
| rResField.Value <<= rtl::OUString(strFieldType.ToLowerAscii()); |
| rResField.Handle = -1; |
| rResField.State = PropertyState_DIRECT_VALUE; |
| } |
| //sort property values |
| // build sorted index array |
| sal_Int32 nLength = aRes.getLength(); |
| const beans::PropertyValue* pPairs = aRes.getConstArray(); |
| sal_Int32* pIndices = new sal_Int32[nLength]; |
| sal_Int32 i = 0; |
| for( i = 0; i < nLength; i++ ) |
| pIndices[i] = i; |
| sort( &pIndices[0], &pIndices[nLength], IndexCompare(pPairs) ); |
| // create sorted sequences accoring to index array |
| uno::Sequence<beans::PropertyValue> aNewValues( nLength ); |
| beans::PropertyValue* pNewValues = aNewValues.getArray(); |
| for( i = 0; i < nLength; i++ ) |
| { |
| pNewValues[i] = pPairs[pIndices[i]]; |
| } |
| delete[] pIndices; |
| // |
| return aNewValues; |
| } |
| return aRes; |
| } |
| |
| awt::Rectangle SAL_CALL AccessibleEditableTextPara::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getCharacterBounds: index value overflow"); |
| |
| // #108900# Have position semantics now for nIndex, as |
| // one-past-the-end values are legal, too. |
| CheckPosition( nIndex ); |
| |
| SvxTextForwarder& rCacheTF = GetTextForwarder(); |
| Rectangle aRect = rCacheTF.GetCharBounds( static_cast< sal_uInt16 >( GetParagraphIndex() ), static_cast< sal_uInt16 >( nIndex ) ); |
| |
| // convert to screen |
| Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect, |
| rCacheTF.GetMapMode(), |
| GetViewForwarder() ); |
| // #109864# offset from parent (paragraph), but in screen |
| // coordinates. This makes sure the internal text offset in |
| // the outline view forwarder gets cancelled out here |
| awt::Rectangle aParaRect( getBounds() ); |
| aScreenRect.Move( -aParaRect.X, -aParaRect.Y ); |
| |
| // offset from shape/cell |
| Point aOffset = GetEEOffset(); |
| |
| return awt::Rectangle( aScreenRect.Left() + aOffset.X(), |
| aScreenRect.Top() + aOffset.Y(), |
| aScreenRect.GetSize().Width(), |
| aScreenRect.GetSize().Height() ); |
| } |
| |
| sal_Int32 SAL_CALL AccessibleEditableTextPara::getCharacterCount() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getCharacterCount: index value overflow"); |
| |
| return OCommonAccessibleText::getCharacterCount(); |
| } |
| |
| sal_Int32 SAL_CALL AccessibleEditableTextPara::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| if ((rPoint.X <= 0) && (rPoint.Y <= 0)) |
| return 0; |
| sal_uInt16 nPara, nIndex; |
| |
| // offset from surrounding cell/shape |
| Point aOffset( GetEEOffset() ); |
| Point aPoint( rPoint.X - aOffset.X(), rPoint.Y - aOffset.Y() ); |
| |
| // convert to logical coordinates |
| SvxTextForwarder& rCacheTF = GetTextForwarder(); |
| Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) ); |
| |
| // re-offset to parent (paragraph) |
| Rectangle aParaRect = rCacheTF.GetParaBounds( static_cast< sal_uInt16 >( GetParagraphIndex() ) ); |
| aLogPoint.Move( aParaRect.Left(), aParaRect.Top() ); |
| |
| if( rCacheTF.GetIndexAtPoint( aLogPoint, nPara, nIndex ) && |
| GetParagraphIndex() == nPara ) |
| { |
| // #102259# Double-check if we're _really_ on the given character |
| try |
| { |
| awt::Rectangle aRect1( getCharacterBounds(nIndex) ); |
| Rectangle aRect2( aRect1.X, aRect1.Y, |
| aRect1.Width + aRect1.X, aRect1.Height + aRect1.Y ); |
| if( aRect2.IsInside( Point( rPoint.X, rPoint.Y ) ) ) |
| return nIndex; |
| else |
| return -1; |
| } |
| catch( const lang::IndexOutOfBoundsException& ) |
| { |
| // #103927# Don't throw for invalid nIndex values |
| return -1; |
| } |
| } |
| else |
| { |
| // not within our paragraph |
| return -1; |
| } |
| } |
| |
| ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getSelectedText() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getSelectedText: index value overflow"); |
| |
| if( !HaveEditView() ) |
| return ::rtl::OUString(); |
| |
| return OCommonAccessibleText::getSelectedText(); |
| } |
| |
| sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionStart() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getSelectionStart: index value overflow"); |
| |
| if( !HaveEditView() ) |
| return -1; |
| |
| return OCommonAccessibleText::getSelectionStart(); |
| } |
| |
| sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionEnd() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getSelectionEnd: index value overflow"); |
| |
| if( !HaveEditView() ) |
| return -1; |
| |
| return OCommonAccessibleText::getSelectionEnd(); |
| } |
| |
| sal_Bool SAL_CALL AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::setSelection: paragraph index value overflow"); |
| |
| CheckRange(nStartIndex, nEndIndex); |
| |
| try |
| { |
| SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); |
| return rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); |
| } |
| catch( const uno::RuntimeException& ) |
| { |
| return sal_False; |
| } |
| } |
| |
| ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getText() throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getText: paragraph index value overflow"); |
| |
| return OCommonAccessibleText::getText(); |
| } |
| |
| ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getTextRange: paragraph index value overflow"); |
| |
| return OCommonAccessibleText::getTextRange(nStartIndex, nEndIndex); |
| } |
| void AccessibleEditableTextPara::_correctValues( const sal_Int32 /* nIndex */, |
| uno::Sequence< PropertyValue >& rValues) |
| { |
| SvxTextForwarder& rCacheTF = GetTextForwarder(); |
| sal_Int32 nRes = rValues.getLength(); |
| beans::PropertyValue *pRes = rValues.getArray(); |
| for (sal_Int32 i = 0; i < nRes; ++i) |
| { |
| beans::PropertyValue &rRes = pRes[i]; |
| // Char color |
| if (rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharColor"))==0) |
| { |
| uno::Any &anyChar = rRes.Value; |
| sal_uInt32 crChar = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved)); |
| if (COL_AUTO == crChar ) |
| { |
| uno::Reference< ::com::sun::star::accessibility::XAccessibleComponent > xComponent; |
| if (mxParent.is()) |
| { |
| xComponent.set(mxParent,uno::UNO_QUERY); |
| } |
| else |
| { |
| xComponent.set(m_xAccInfo,uno::UNO_QUERY); |
| } |
| if (xComponent.is()) |
| { |
| uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY); |
| if (xContext->getAccessibleRole() == AccessibleRole::SHAPE |
| || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL) |
| { |
| anyChar <<= COL_BLACK; |
| } |
| else |
| { |
| Color cr(xComponent->getBackground()); |
| crChar = cr.IsDark() ? COL_WHITE : COL_BLACK; |
| anyChar <<= crChar; |
| } |
| } |
| } |
| continue; |
| } |
| // Underline |
| if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharUnderline"))==0) |
| { |
| /* |
| // MT: Implement XAccessibleTextMarkup, mark with TextMarkupType::SPELLCHECK. This way done in SW. |
| if (IsCurrentEditorEnableAutoSpell( mxParent )) |
| { |
| try |
| { |
| SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_False ); |
| sal_Bool bWrong = rCacheVF.IsWrongSpelledWordAtPos( GetParagraphIndex(), nIndex ); |
| if ( bWrong ) |
| { |
| uno::Any &anyUnderLine = pRes[9].Value; |
| // MT IA2: Not needed? sal_uInt16 crUnderLine = (sal_uInt16)(anyUnderLine.pReserved); |
| anyUnderLine <<= (sal_uInt16)UNDERLINE_WAVE; |
| } |
| } |
| catch( const uno::RuntimeException& ) |
| { |
| } |
| } |
| */ |
| continue; |
| } |
| // Underline color && Mis-spell |
| if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharUnderlineColor"))==0) |
| { |
| uno::Any &anyCharUnderLine = rRes.Value; |
| sal_uInt32 crCharUnderLine = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>( anyCharUnderLine.pReserved)); |
| if (COL_AUTO == crCharUnderLine ) |
| { |
| uno::Reference< ::com::sun::star::accessibility::XAccessibleComponent > xComponent; |
| if (mxParent.is()) |
| { |
| xComponent.set(mxParent,uno::UNO_QUERY); |
| } |
| else |
| { |
| xComponent.set(m_xAccInfo,uno::UNO_QUERY); |
| } |
| if (xComponent.is()) |
| { |
| uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY); |
| if (xContext->getAccessibleRole() == AccessibleRole::SHAPE |
| || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL) |
| { |
| anyCharUnderLine <<= COL_BLACK; |
| } |
| else |
| { |
| Color cr(xComponent->getBackground()); |
| crCharUnderLine = cr.IsDark() ? COL_WHITE : COL_BLACK; |
| anyCharUnderLine <<= crCharUnderLine; |
| } |
| } |
| } |
| // MT: Implement XAccessibleTextMarkup, mark with TextMarkupType::SPELLCHECK. This way done in SW. |
| /* |
| if (IsCurrentEditorEnableAutoSpell( mxParent )) |
| { |
| try |
| { |
| SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_False ); |
| sal_Bool bWrong = rCacheVF.IsWrongSpelledWordAtPos( GetParagraphIndex(), nIndex ); |
| if ( bWrong ) |
| { |
| uno::Any &anyUnderLineColor = rRes.Value; |
| // MT IA2: Not needed? sal_uInt16 crUnderLineColor = (sal_uInt16)(anyUnderLineColor.pReserved); |
| anyUnderLineColor <<= COL_LIGHTRED; |
| } |
| } |
| catch( const uno::RuntimeException& ) |
| { |
| } |
| } |
| */ |
| continue; |
| } |
| // NumberingLevel |
| if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("NumberingLevel"))==0) |
| { |
| const SvxNumBulletItem& rNumBullet = ( SvxNumBulletItem& )rCacheTF.GetParaAttribs(static_cast< sal_uInt16 >(GetParagraphIndex())).Get(EE_PARA_NUMBULLET); |
| if(rNumBullet.GetNumRule()->GetLevelCount()==0) |
| { |
| rRes.Value <<= (sal_Int16)-1; |
| rRes.Handle = -1; |
| rRes.State = PropertyState_DIRECT_VALUE; |
| } |
| else |
| { |
| // SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), |
| // ImplGetSvxCharAndParaPropertiesMap() ); |
| // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap |
| SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() ); |
| |
| aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) ); |
| rRes.Value = aPropSet._getPropertyValue( rRes.Name, mnParagraphIndex ); |
| rRes.State = aPropSet._getPropertyState( rRes.Name, mnParagraphIndex ); |
| rRes.Handle = -1; |
| } |
| continue; |
| } |
| // NumberingRules |
| if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("NumberingRules"))==0) |
| { |
| SfxItemSet aAttribs = rCacheTF.GetParaAttribs( static_cast< sal_uInt16 >(GetParagraphIndex()) ); |
| sal_Bool bVis = ((const SfxUInt16Item&)aAttribs.Get( EE_PARA_BULLETSTATE )).GetValue() ? sal_True : sal_False; |
| if(bVis) |
| { |
| rRes.Value <<= (sal_Int16)-1; |
| rRes.Handle = -1; |
| rRes.State = PropertyState_DIRECT_VALUE; |
| } |
| else |
| { |
| // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap |
| SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() ); |
| aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) ); |
| rRes.Value = aPropSet._getPropertyValue( rRes.Name, mnParagraphIndex ); |
| rRes.State = aPropSet._getPropertyState( rRes.Name, mnParagraphIndex ); |
| rRes.Handle = -1; |
| } |
| continue; |
| } |
| } |
| } |
| sal_Int32 AccessibleEditableTextPara::SkipField(sal_Int32 nIndex, sal_Bool bForward) |
| { |
| sal_Int32 nParaIndex = GetParagraphIndex(); |
| SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); |
| sal_Int32 nAllFieldLen = 0; |
| sal_Int32 nField = rCacheTF.GetFieldCount(sal_uInt16(nParaIndex)), nFoundFieldIndex = -1; |
| EFieldInfo ree; |
| sal_Int32 reeBegin=0, reeEnd=0; |
| for(sal_uInt16 j = 0; j < nField; j++) |
| { |
| ree = rCacheTF.GetFieldInfo(sal_uInt16(nParaIndex), j); |
| reeBegin = ree.aPosition.nIndex + nAllFieldLen; |
| reeEnd = reeBegin + ree.aCurrentText.Len(); |
| nAllFieldLen += (ree.aCurrentText.Len() - 1); |
| if( reeBegin > nIndex ) |
| { |
| break; |
| } |
| if( nIndex >= reeBegin && nIndex < reeEnd ) |
| { |
| if(ree.pFieldItem->GetField()->GetClassId() != SVX_URLFIELD) |
| { |
| nFoundFieldIndex = j; |
| break; |
| } |
| } |
| } |
| if( nFoundFieldIndex >= 0 ) |
| { |
| if( bForward ) |
| return reeEnd - 1; |
| else |
| return reeBegin; |
| } |
| return nIndex; |
| } |
| sal_Bool AccessibleEditableTextPara::ExtendByField( ::com::sun::star::accessibility::TextSegment& Segment ) |
| { |
| sal_Int32 nParaIndex = GetParagraphIndex(); |
| SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); |
| sal_Int32 nAllFieldLen = 0; |
| sal_Int32 nField = rCacheTF.GetFieldCount(sal_uInt16(nParaIndex)), nFoundFieldIndex = -1; |
| EFieldInfo ree; |
| sal_Int32 reeBegin=0, reeEnd=0; |
| for(sal_uInt16 j = 0; j < nField; j++) |
| { |
| ree = rCacheTF.GetFieldInfo(sal_uInt16(nParaIndex), j); |
| reeBegin = ree.aPosition.nIndex + nAllFieldLen; |
| reeEnd = reeBegin + ree.aCurrentText.Len(); |
| nAllFieldLen += (ree.aCurrentText.Len() - 1); |
| if( reeBegin > Segment.SegmentEnd ) |
| { |
| break; |
| } |
| if( (Segment.SegmentEnd > reeBegin && Segment.SegmentEnd <= reeEnd) || |
| (Segment.SegmentStart >= reeBegin && Segment.SegmentStart < reeEnd) ) |
| { |
| if(ree.pFieldItem->GetField()->GetClassId() != SVX_URLFIELD) |
| { |
| nFoundFieldIndex = j; |
| break; |
| } |
| } |
| } |
| sal_Bool bExtend = sal_False; |
| if( nFoundFieldIndex >= 0 ) |
| { |
| if( Segment.SegmentEnd < reeEnd ) |
| { |
| Segment.SegmentEnd = reeEnd; |
| bExtend = sal_True; |
| } |
| if( Segment.SegmentStart > reeBegin ) |
| { |
| Segment.SegmentStart = reeBegin; |
| bExtend = sal_True; |
| } |
| if( bExtend ) |
| { |
| //If there is a bullet before the field, should add the bullet length into the segment. |
| EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(sal_uInt16(nParaIndex)); |
| int nBulletLen = aBulletInfo.aText.Len(); |
| if (nBulletLen > 0) |
| { |
| Segment.SegmentEnd += nBulletLen; |
| if (nFoundFieldIndex > 0) |
| Segment.SegmentStart += nBulletLen; |
| Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd); |
| //After get the correct field name, should restore the offset value which don't contain the bullet. |
| Segment.SegmentEnd -= nBulletLen; |
| if (nFoundFieldIndex > 0) |
| Segment.SegmentStart -= nBulletLen; |
| } |
| else |
| Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd); |
| } |
| } |
| return bExtend; |
| } |
| ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getTextAtIndex: paragraph index value overflow"); |
| |
| ::com::sun::star::accessibility::TextSegment aResult; |
| aResult.SegmentStart = -1; |
| aResult.SegmentEnd = -1; |
| |
| switch( aTextType ) |
| { |
| case AccessibleTextType::CHARACTER: |
| case AccessibleTextType::WORD: |
| { |
| aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType ); |
| ExtendByField( aResult ); |
| break; |
| } |
| // Not yet handled by OCommonAccessibleText. Missing |
| // implGetAttributeRunBoundary() method there |
| case AccessibleTextType::ATTRIBUTE_RUN: |
| { |
| const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( static_cast< sal_uInt16 >( GetParagraphIndex() ) ); |
| |
| if( nIndex == nTextLen ) |
| { |
| // #i17014# Special-casing one-behind-the-end character |
| aResult.SegmentStart = aResult.SegmentEnd = nTextLen; |
| } |
| else |
| { |
| sal_uInt16 nStartIndex, nEndIndex; |
| //For the bullet paragraph, the bullet string is ingnored for IAText::attributes() function. |
| SvxTextForwarder& rCacheTF = GetTextForwarder(); |
| // MT IA2: Not used? sal_Int32 nBulletLen = 0; |
| EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); |
| if (aBulletInfo.bVisible) |
| nIndex += aBulletInfo.aText.Len(); |
| if (nIndex != 0 && nIndex >= getCharacterCount()) |
| nIndex = getCharacterCount()-1; |
| CheckPosition(nIndex); |
| if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) ) |
| { |
| aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex); |
| if (aBulletInfo.bVisible) |
| { |
| nStartIndex -= aBulletInfo.aText.Len(); |
| nEndIndex -= aBulletInfo.aText.Len(); |
| } |
| aResult.SegmentStart = nStartIndex; |
| aResult.SegmentEnd = nEndIndex; |
| } |
| } |
| break; |
| } |
| case AccessibleTextType::LINE: |
| { |
| SvxTextForwarder& rCacheTF = GetTextForwarder(); |
| sal_Int32 nParaIndex = GetParagraphIndex(); |
| // MT IA2: Not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( static_cast< sal_uInt16 >( nParaIndex ) ); |
| CheckPosition(nIndex); |
| if (nIndex != 0 && nIndex == getCharacterCount()) |
| --nIndex; |
| sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) ); |
| sal_Int32 nCurIndex; |
| //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line, |
| //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed |
| //by the IAText::attributes(). So here must do special support for bullet line. |
| sal_Int32 nBulletLen = 0; |
| for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine ) |
| { |
| if (nLine == 0) |
| { |
| EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(nParaIndex) ); |
| if (aBulletInfo.bVisible) |
| { |
| //in bullet or numbering; |
| nBulletLen = aBulletInfo.aText.Len(); |
| } |
| } |
| //nCurIndex += rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine); |
| sal_Int32 nLineLen = rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine); |
| if (nLine == 0) |
| nCurIndex += nLineLen - nBulletLen; |
| else |
| nCurIndex += nLineLen; |
| if( nCurIndex > nIndex ) |
| { |
| if (nLine ==0) |
| { |
| //aResult.SegmentStart = nCurIndex - rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); |
| aResult.SegmentStart = 0; |
| aResult.SegmentEnd = nCurIndex; |
| //aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd ); |
| aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen); |
| break; |
| } |
| else |
| { |
| //aResult.SegmentStart = nCurIndex - rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); |
| aResult.SegmentStart = nCurIndex - nLineLen; |
| aResult.SegmentEnd = nCurIndex; |
| //aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd ); |
| aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen); |
| break; |
| } |
| } |
| } |
| break; |
| } |
| default: |
| aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType ); |
| break; |
| } /* end of switch( aTextType ) */ |
| |
| return aResult; |
| } |
| |
| ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getTextBeforeIndex: paragraph index value overflow"); |
| |
| ::com::sun::star::accessibility::TextSegment aResult; |
| aResult.SegmentStart = -1; |
| aResult.SegmentEnd = -1; |
| i18n::Boundary aBoundary; |
| switch( aTextType ) |
| { |
| // Not yet handled by OCommonAccessibleText. Missing |
| // implGetAttributeRunBoundary() method there |
| case AccessibleTextType::ATTRIBUTE_RUN: |
| { |
| const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( static_cast< sal_uInt16 >( GetParagraphIndex() ) ); |
| sal_uInt16 nStartIndex, nEndIndex; |
| |
| if( nIndex == nTextLen ) |
| { |
| // #i17014# Special-casing one-behind-the-end character |
| if( nIndex > 0 && |
| GetAttributeRun(nStartIndex, nEndIndex, nIndex-1) ) |
| { |
| aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex); |
| aResult.SegmentStart = nStartIndex; |
| aResult.SegmentEnd = nEndIndex; |
| } |
| } |
| else |
| { |
| if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) ) |
| { |
| // already at the left border? If not, query |
| // one index further left |
| if( nStartIndex > 0 && |
| GetAttributeRun(nStartIndex, nEndIndex, nStartIndex-1) ) |
| { |
| aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex); |
| aResult.SegmentStart = nStartIndex; |
| aResult.SegmentEnd = nEndIndex; |
| } |
| } |
| } |
| break; |
| } |
| case AccessibleTextType::LINE: |
| { |
| SvxTextForwarder& rCacheTF = GetTextForwarder(); |
| sal_Int32 nParaIndex = GetParagraphIndex(); |
| // MT IA2 not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( static_cast< sal_uInt16 >( nParaIndex ) ); |
| |
| CheckPosition(nIndex); |
| |
| sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) ); |
| //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line, |
| //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed |
| //by the IAText::attributes(). So here must do special support for bullet line. |
| sal_Int32 nCurIndex=0, nLastIndex=0, nCurLineLen=0; |
| sal_Int32 nLastLineLen = 0, nBulletLen = 0;; |
| // get the line before the line the index points into |
| for( nLine=0, nCurIndex=0, nLastIndex=0; nLine<nLineCount; ++nLine ) |
| { |
| nLastIndex = nCurIndex; |
| if (nLine == 0) |
| { |
| EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(nParaIndex) ); |
| if (aBulletInfo.bVisible) |
| { |
| //in bullet or numbering; |
| nBulletLen = aBulletInfo.aText.Len(); |
| } |
| } |
| if (nLine == 1) |
| nLastLineLen = nCurLineLen - nBulletLen; |
| else |
| nLastLineLen = nCurLineLen; |
| nCurLineLen = rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); |
| //nCurIndex += nCurLineLen; |
| if (nLine == 0) |
| nCurIndex += nCurLineLen - nBulletLen; |
| else |
| nCurIndex += nCurLineLen; |
| |
| //if( nCurIndex > nIndex && |
| //nLastIndex > nCurLineLen ) |
| if (nCurIndex > nIndex) |
| { |
| if (nLine == 0) |
| { |
| break; |
| } |
| else if (nLine == 1) |
| { |
| aResult.SegmentStart = 0; |
| aResult.SegmentEnd = static_cast< sal_uInt16 >( nLastIndex ); |
| aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen); |
| break; |
| } |
| else |
| { |
| //aResult.SegmentStart = nLastIndex - nCurLineLen; |
| aResult.SegmentStart = nLastIndex - nLastLineLen; |
| aResult.SegmentEnd = static_cast< sal_uInt16 >( nLastIndex ); |
| aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen); |
| break; |
| } |
| } |
| } |
| |
| break; |
| } |
| case AccessibleTextType::WORD: |
| { |
| nIndex = SkipField( nIndex, sal_False); |
| ::rtl::OUString sText( implGetText() ); |
| sal_Int32 nLength = sText.getLength(); |
| |
| // get word at index |
| implGetWordBoundary( aBoundary, nIndex ); |
| |
| |
| //sal_Int32 curWordStart = aBoundary.startPos; |
| //sal_Int32 preWordStart = curWordStart; |
| sal_Int32 curWordStart , preWordStart; |
| if( aBoundary.startPos == -1 || aBoundary.startPos > nIndex) |
| curWordStart = preWordStart = nIndex; |
| else |
| curWordStart = preWordStart = aBoundary.startPos; |
| |
| // get previous word |
| |
| sal_Bool bWord = sal_False; |
| |
| //while ( preWordStart > 0 && aBoundary.startPos == curWordStart) |
| while ( (preWordStart >= 0 && !bWord ) || ( aBoundary.endPos > curWordStart ) ) |
| { |
| preWordStart--; |
| bWord = implGetWordBoundary( aBoundary, preWordStart ); |
| } |
| if ( bWord && implIsValidBoundary( aBoundary, nLength ) ) |
| { |
| aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); |
| aResult.SegmentStart = aBoundary.startPos; |
| aResult.SegmentEnd = aBoundary.endPos; |
| ExtendByField( aResult ); |
| } |
| } |
| break; |
| case AccessibleTextType::CHARACTER: |
| { |
| nIndex = SkipField( nIndex, sal_False); |
| aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType ); |
| ExtendByField( aResult ); |
| break; |
| } |
| default: |
| aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType ); |
| break; |
| } /* end of switch( aTextType ) */ |
| |
| return aResult; |
| } |
| |
| ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getTextBehindIndex: paragraph index value overflow"); |
| |
| ::com::sun::star::accessibility::TextSegment aResult; |
| aResult.SegmentStart = -1; |
| aResult.SegmentEnd = -1; |
| i18n::Boundary aBoundary; |
| switch( aTextType ) |
| { |
| case AccessibleTextType::ATTRIBUTE_RUN: |
| { |
| sal_uInt16 nStartIndex, nEndIndex; |
| |
| if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) ) |
| { |
| // already at the right border? |
| if( nEndIndex < GetTextLen() ) |
| { |
| if( GetAttributeRun(nStartIndex, nEndIndex, nEndIndex) ) |
| { |
| aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex); |
| aResult.SegmentStart = nStartIndex; |
| aResult.SegmentEnd = nEndIndex; |
| } |
| } |
| } |
| break; |
| } |
| |
| case AccessibleTextType::LINE: |
| { |
| SvxTextForwarder& rCacheTF = GetTextForwarder(); |
| sal_Int32 nParaIndex = GetParagraphIndex(); |
| // MT IA2 not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( static_cast< sal_uInt16 >( nParaIndex ) ); |
| |
| CheckPosition(nIndex); |
| |
| sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) ); |
| sal_Int32 nCurIndex; |
| //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line, |
| //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed |
| //by the IAText::attributes(). So here must do special support for bullet line. |
| sal_Int32 nBulletLen = 0; |
| // get the line after the line the index points into |
| for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine ) |
| { |
| if (nLine == 0) |
| { |
| EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(nParaIndex) ); |
| if (aBulletInfo.bVisible) |
| { |
| //in bullet or numbering; |
| nBulletLen = aBulletInfo.aText.Len(); |
| } |
| } |
| //nCurIndex += rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine); |
| sal_Int32 nLineLen = rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine); |
| |
| if (nLine == 0) |
| nCurIndex += nLineLen - nBulletLen; |
| else |
| nCurIndex += nLineLen; |
| |
| if( nCurIndex > nIndex && |
| nLine < nLineCount-1 ) |
| { |
| aResult.SegmentStart = nCurIndex; |
| aResult.SegmentEnd = nCurIndex + rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine+1); |
| aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen); |
| break; |
| } |
| } |
| |
| break; |
| } |
| case AccessibleTextType::WORD: |
| { |
| nIndex = SkipField( nIndex, sal_True); |
| ::rtl::OUString sText( implGetText() ); |
| sal_Int32 nLength = sText.getLength(); |
| |
| // get word at index |
| sal_Bool bWord = implGetWordBoundary( aBoundary, nIndex ); |
| |
| // real current world |
| sal_Int32 nextWord = nIndex; |
| //if( nIndex >= aBoundary.startPos && nIndex <= aBoundary.endPos ) |
| if( nIndex <= aBoundary.endPos ) |
| { |
| nextWord = aBoundary.endPos; |
| if( sText.getStr()[nextWord] == sal_Unicode(' ') ) nextWord++; |
| bWord = implGetWordBoundary( aBoundary, nextWord ); |
| } |
| |
| if ( bWord && implIsValidBoundary( aBoundary, nLength ) ) |
| { |
| aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos ); |
| aResult.SegmentStart = aBoundary.startPos; |
| aResult.SegmentEnd = aBoundary.endPos; |
| |
| // If the end position of aBoundary is inside a field, extend the result to the end of the field |
| |
| ExtendByField( aResult ); |
| } |
| } |
| break; |
| |
| case AccessibleTextType::CHARACTER: |
| { |
| nIndex = SkipField( nIndex, sal_True); |
| aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType ); |
| ExtendByField( aResult ); |
| break; |
| } |
| default: |
| aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType ); |
| break; |
| } /* end of switch( aTextType ) */ |
| |
| return aResult; |
| } |
| |
| sal_Bool SAL_CALL AccessibleEditableTextPara::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| try |
| { |
| SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); |
| #if OSL_DEBUG_LEVEL > 0 |
| SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs |
| (void)rCacheTF; |
| #else |
| GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs |
| #endif |
| |
| sal_Bool aRetVal; |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::copyText: index value overflow"); |
| |
| CheckRange(nStartIndex, nEndIndex); |
| |
| //Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet |
| sal_Int32 nBulletLen = 0; |
| EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); |
| if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) |
| nBulletLen = aBulletInfo.aText.Len(); |
| // save current selection |
| ESelection aOldSelection; |
| |
| rCacheVF.GetSelection( aOldSelection ); |
| //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); |
| rCacheVF.SetSelection( MakeSelection(nStartIndex + nBulletLen, nEndIndex + nBulletLen) ); |
| aRetVal = rCacheVF.Copy(); |
| rCacheVF.SetSelection( aOldSelection ); // restore |
| |
| return aRetVal; |
| } |
| catch( const uno::RuntimeException& ) |
| { |
| return sal_False; |
| } |
| } |
| |
| // XAccessibleEditableText |
| sal_Bool SAL_CALL AccessibleEditableTextPara::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| try |
| { |
| SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); |
| SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::cutText: index value overflow"); |
| |
| CheckRange(nStartIndex, nEndIndex); |
| |
| // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet |
| sal_Int32 nBulletLen = 0; |
| EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); |
| if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) |
| nBulletLen = aBulletInfo.aText.Len(); |
| ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen); |
| if( !rCacheTF.IsEditable( aSelection ) ) |
| return sal_False; // non-editable area selected |
| |
| // don't save selection, might become invalid after cut! |
| //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); |
| rCacheVF.SetSelection( aSelection ); |
| |
| return rCacheVF.Cut(); |
| } |
| catch( const uno::RuntimeException& ) |
| { |
| return sal_False; |
| } |
| } |
| |
| sal_Bool SAL_CALL AccessibleEditableTextPara::pasteText( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| try |
| { |
| SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True ); |
| SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::pasteText: index value overflow"); |
| |
| CheckPosition(nIndex); |
| |
| // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet |
| sal_Int32 nBulletLen = 0; |
| EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); |
| if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) |
| nBulletLen = aBulletInfo.aText.Len(); |
| //if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) ) |
| if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) ) |
| return sal_False; // non-editable area selected |
| |
| // #104400# set empty selection (=> cursor) to given index |
| //rCacheVF.SetSelection( MakeCursor(nIndex) ); |
| rCacheVF.SetSelection( MakeCursor(nIndex + nBulletLen) ); |
| |
| return rCacheVF.Paste(); |
| } |
| catch( const uno::RuntimeException& ) |
| { |
| return sal_False; |
| } |
| } |
| |
| sal_Bool SAL_CALL AccessibleEditableTextPara::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| try |
| { |
| // #102710# Request edit view when doing changes |
| // AccessibleEmptyEditSource relies on this behaviour |
| GetEditViewForwarder( sal_True ); |
| SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::deleteText: index value overflow"); |
| |
| CheckRange(nStartIndex, nEndIndex); |
| |
| // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet |
| sal_Int32 nBulletLen = 0; |
| EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); |
| if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) |
| nBulletLen = aBulletInfo.aText.Len(); |
| ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen); |
| |
| //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) |
| if( !rCacheTF.IsEditable( aSelection ) ) |
| return sal_False; // non-editable area selected |
| |
| //sal_Bool bRet = rCacheTF.Delete( MakeSelection(nStartIndex, nEndIndex) ); |
| sal_Bool bRet = rCacheTF.Delete( aSelection ); |
| |
| GetEditSource().UpdateData(); |
| |
| return bRet; |
| } |
| catch( const uno::RuntimeException& ) |
| { |
| return sal_False; |
| } |
| } |
| |
| sal_Bool SAL_CALL AccessibleEditableTextPara::insertText( const ::rtl::OUString& sText, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| try |
| { |
| // #102710# Request edit view when doing changes |
| // AccessibleEmptyEditSource relies on this behaviour |
| GetEditViewForwarder( sal_True ); |
| SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::insertText: index value overflow"); |
| |
| CheckPosition(nIndex); |
| |
| // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet |
| sal_Int32 nBulletLen = 0; |
| EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); |
| if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) |
| nBulletLen = aBulletInfo.aText.Len(); |
| |
| //if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) ) |
| if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) ) |
| return sal_False; // non-editable area selected |
| |
| // #104400# insert given text at empty selection (=> cursor) |
| //sal_Bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex) ); |
| sal_Bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex + nBulletLen) ); |
| |
| rCacheTF.QuickFormatDoc(); |
| GetEditSource().UpdateData(); |
| |
| return bRet; |
| } |
| catch( const uno::RuntimeException& ) |
| { |
| return sal_False; |
| } |
| } |
| |
| sal_Bool SAL_CALL AccessibleEditableTextPara::replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const ::rtl::OUString& sReplacement ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| try |
| { |
| // #102710# Request edit view when doing changes |
| // AccessibleEmptyEditSource relies on this behaviour |
| GetEditViewForwarder( sal_True ); |
| SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::replaceText: index value overflow"); |
| |
| CheckRange(nStartIndex, nEndIndex); |
| |
| // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet |
| sal_Int32 nBulletLen = 0; |
| EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) ); |
| if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible ) |
| nBulletLen = aBulletInfo.aText.Len(); |
| ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen); |
| |
| //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) |
| if( !rCacheTF.IsEditable( aSelection ) ) |
| return sal_False; // non-editable area selected |
| |
| // insert given text into given range => replace |
| //sal_Bool bRet = rCacheTF.InsertText( sReplacement, MakeSelection(nStartIndex, nEndIndex) ); |
| sal_Bool bRet = rCacheTF.InsertText( sReplacement, aSelection ); |
| |
| rCacheTF.QuickFormatDoc(); |
| GetEditSource().UpdateData(); |
| |
| return bRet; |
| } |
| catch( const uno::RuntimeException& ) |
| { |
| return sal_False; |
| } |
| } |
| |
| sal_Bool SAL_CALL AccessibleEditableTextPara::setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const uno::Sequence< beans::PropertyValue >& aAttributeSet ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| try |
| { |
| // #102710# Request edit view when doing changes |
| // AccessibleEmptyEditSource relies on this behaviour |
| GetEditViewForwarder( sal_True ); |
| SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs |
| sal_uInt16 nPara = static_cast< sal_uInt16 >( GetParagraphIndex() ); |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::setAttributes: index value overflow"); |
| |
| CheckRange(nStartIndex, nEndIndex); |
| |
| if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) ) |
| return sal_False; // non-editable area selected |
| |
| // do the indices span the whole paragraph? Then use the outliner map |
| // TODO: hold it as a member? |
| SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), |
| 0 == nStartIndex && |
| rCacheTF.GetTextLen(nPara) == nEndIndex ? |
| ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() : |
| ImplGetSvxTextPortionSvxPropertySet() ); |
| |
| aPropSet.SetSelection( MakeSelection(nStartIndex, nEndIndex) ); |
| |
| // convert from PropertyValue to Any |
| sal_Int32 i, nLength( aAttributeSet.getLength() ); |
| const beans::PropertyValue* pPropArray = aAttributeSet.getConstArray(); |
| for(i=0; i<nLength; ++i) |
| { |
| try |
| { |
| aPropSet.setPropertyValue(pPropArray->Name, pPropArray->Value); |
| } |
| catch( const uno::Exception& ) |
| { |
| DBG_ERROR("AccessibleEditableTextPara::setAttributes exception in setPropertyValue"); |
| } |
| |
| ++pPropArray; |
| } |
| |
| rCacheTF.QuickFormatDoc(); |
| GetEditSource().UpdateData(); |
| |
| return sal_True; |
| } |
| catch( const uno::RuntimeException& ) |
| { |
| return sal_False; |
| } |
| } |
| |
| sal_Bool SAL_CALL AccessibleEditableTextPara::setText( const ::rtl::OUString& sText ) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| return replaceText(0, getCharacterCount(), sText); |
| } |
| |
| // XAccessibleTextAttributes |
| uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getDefaultAttributes( |
| const uno::Sequence< ::rtl::OUString >& rRequestedAttributes ) |
| throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| #if OSL_DEBUG_LEVEL > 0 |
| SvxAccessibleTextAdapter& rCacheTF = |
| #endif |
| GetTextForwarder(); |
| |
| #if OSL_DEBUG_LEVEL > 0 |
| (void)rCacheTF; |
| #endif |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getCharacterAttributes: index value overflow"); |
| |
| // get XPropertySetInfo for paragraph attributes and |
| // character attributes that span all the paragraphs text. |
| SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), |
| ImplGetSvxCharAndParaPropertiesSet() ); |
| aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) ); |
| uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo(); |
| if (!xPropSetInfo.is()) |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot query XPropertySetInfo")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy |
| |
| // build sequence of available properties to check |
| sal_Int32 nLenReqAttr = rRequestedAttributes.getLength(); |
| uno::Sequence< beans::Property > aProperties; |
| if (nLenReqAttr) |
| { |
| const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray(); |
| |
| aProperties.realloc( nLenReqAttr ); |
| beans::Property *pProperties = aProperties.getArray(); |
| sal_Int32 nCurLen = 0; |
| for (sal_Int32 i = 0; i < nLenReqAttr; ++i) |
| { |
| beans::Property aProp; |
| try |
| { |
| aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] ); |
| } |
| catch (beans::UnknownPropertyException &) |
| { |
| continue; |
| } |
| pProperties[ nCurLen++ ] = aProp; |
| } |
| aProperties.realloc( nCurLen ); |
| } |
| else |
| aProperties = xPropSetInfo->getProperties(); |
| |
| sal_Int32 nLength = aProperties.getLength(); |
| const beans::Property *pProperties = aProperties.getConstArray(); |
| |
| // build resulting sequence |
| uno::Sequence< beans::PropertyValue > aOutSequence( nLength ); |
| beans::PropertyValue* pOutSequence = aOutSequence.getArray(); |
| sal_Int32 nOutLen = 0; |
| for (sal_Int32 i = 0; i < nLength; ++i) |
| { |
| // calling implementation functions: |
| // _getPropertyState and _getPropertyValue (see below) to provide |
| // the proper paragraph number when retrieving paragraph attributes |
| PropertyState eState = aPropSet._getPropertyState( pProperties->Name, mnParagraphIndex ); |
| if ( eState == PropertyState_AMBIGUOUS_VALUE ) |
| { |
| OSL_ENSURE( false, "ambiguous property value encountered" ); |
| } |
| |
| //if (eState == PropertyState_DIRECT_VALUE) |
| // per definition all paragraph properties and all character |
| // properties spanning the whole paragraph should be returned |
| // and declared as default value |
| { |
| pOutSequence->Name = pProperties->Name; |
| pOutSequence->Handle = pProperties->Handle; |
| pOutSequence->Value = aPropSet._getPropertyValue( pProperties->Name, mnParagraphIndex ); |
| pOutSequence->State = PropertyState_DEFAULT_VALUE; |
| |
| ++pOutSequence; |
| ++nOutLen; |
| } |
| ++pProperties; |
| } |
| aOutSequence.realloc( nOutLen ); |
| |
| return aOutSequence; |
| } |
| |
| |
| uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getRunAttributes( |
| sal_Int32 nIndex, |
| const uno::Sequence< ::rtl::OUString >& rRequestedAttributes ) |
| throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::vos::OGuard aGuard( Application::GetSolarMutex() ); |
| |
| #if OSL_DEBUG_LEVEL > 0 |
| SvxAccessibleTextAdapter& rCacheTF = |
| #endif |
| GetTextForwarder(); |
| |
| #if OSL_DEBUG_LEVEL > 0 |
| (void)rCacheTF; |
| #endif |
| |
| DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX, |
| "AccessibleEditableTextPara::getCharacterAttributes: index value overflow"); |
| |
| if( getCharacterCount() > 0 ) |
| CheckIndex(nIndex); |
| else |
| CheckPosition(nIndex); |
| |
| SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), |
| ImplGetSvxCharAndParaPropertiesSet() ); |
| aPropSet.SetSelection( MakeSelection( nIndex ) ); |
| uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo(); |
| if (!xPropSetInfo.is()) |
| throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot query XPropertySetInfo")), |
| uno::Reference< uno::XInterface > |
| ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy |
| |
| // build sequence of available properties to check |
| sal_Int32 nLenReqAttr = rRequestedAttributes.getLength(); |
| uno::Sequence< beans::Property > aProperties; |
| if (nLenReqAttr) |
| { |
| const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray(); |
| |
| aProperties.realloc( nLenReqAttr ); |
| beans::Property *pProperties = aProperties.getArray(); |
| sal_Int32 nCurLen = 0; |
| for (sal_Int32 i = 0; i < nLenReqAttr; ++i) |
| { |
| beans::Property aProp; |
| try |
| { |
| aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] ); |
| } |
| catch (beans::UnknownPropertyException &) |
| { |
| continue; |
| } |
| pProperties[ nCurLen++ ] = aProp; |
| } |
| aProperties.realloc( nCurLen ); |
| } |
| else |
| aProperties = xPropSetInfo->getProperties(); |
| |
| sal_Int32 nLength = aProperties.getLength(); |
| const beans::Property *pProperties = aProperties.getConstArray(); |
| |
| // build resulting sequence |
| uno::Sequence< beans::PropertyValue > aOutSequence( nLength ); |
| beans::PropertyValue* pOutSequence = aOutSequence.getArray(); |
| sal_Int32 nOutLen = 0; |
| for (sal_Int32 i = 0; i < nLength; ++i) |
| { |
| // calling 'regular' functions that will operate on the selection |
| PropertyState eState = aPropSet.getPropertyState( pProperties->Name ); |
| if (eState == PropertyState_DIRECT_VALUE) |
| { |
| pOutSequence->Name = pProperties->Name; |
| pOutSequence->Handle = pProperties->Handle; |
| pOutSequence->Value = aPropSet.getPropertyValue( pProperties->Name ); |
| pOutSequence->State = eState; |
| |
| ++pOutSequence; |
| ++nOutLen; |
| } |
| ++pProperties; |
| } |
| aOutSequence.realloc( nOutLen ); |
| |
| return aOutSequence; |
| } |
| |
| // XAccessibleHypertext |
| ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkCount( ) throw (::com::sun::star::uno::RuntimeException) |
| { |
| SvxAccessibleTextAdapter& rT = GetTextForwarder(); |
| const sal_Int32 nPara = GetParagraphIndex(); |
| |
| sal_uInt16 nHyperLinks = 0; |
| sal_uInt16 nFields = rT.GetFieldCount( nPara ); |
| for ( sal_uInt16 n = 0; n < nFields; n++ ) |
| { |
| EFieldInfo aField = rT.GetFieldInfo( nPara, n ); |
| if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) ) |
| nHyperLinks++; |
| } |
| return nHyperLinks; |
| } |
| |
| ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleHyperlink > SAL_CALL AccessibleEditableTextPara::getHyperLink( ::sal_Int32 nLinkIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) |
| { |
| ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleHyperlink > xRef; |
| |
| SvxAccessibleTextAdapter& rT = GetTextForwarder(); |
| const sal_Int32 nPara = GetParagraphIndex(); |
| |
| sal_uInt16 nHyperLink = 0; |
| sal_uInt16 nFields = rT.GetFieldCount( nPara ); |
| for ( sal_uInt16 n = 0; n < nFields; n++ ) |
| { |
| EFieldInfo aField = rT.GetFieldInfo( nPara, n ); |
| if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) ) |
| { |
| if ( nHyperLink == nLinkIndex ) |
| { |
| sal_uInt16 nEEStart = aField.aPosition.nIndex; |
| |
| // Translate EE Index to accessible index |
| sal_uInt16 nStart = rT.CalcEditEngineIndex( nPara, nEEStart ); |
| sal_uInt16 nEnd = nStart + aField.aCurrentText.Len(); |
| xRef = new AccessibleHyperlink( rT, new SvxFieldItem( *aField.pFieldItem ), nPara, nEEStart, nStart, nEnd, aField.aCurrentText ); |
| break; |
| } |
| nHyperLink++; |
| } |
| } |
| |
| return xRef; |
| } |
| |
| ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkIndex( ::sal_Int32 nCharIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException) |
| { |
| const sal_Int32 nPara = GetParagraphIndex(); |
| SvxAccessibleTextAdapter& rT = GetTextForwarder(); |
| |
| // SvxAccessibleTextIndex aIndex; |
| // aIndex.SetIndex(nPara, nCharIndex, rT); |
| // const sal_uInt16 nEEIndex = aIndex.GetEEIndex(); |
| |
| const sal_uInt16 nEEIndex = rT.CalcEditEngineIndex( nPara, nCharIndex ); |
| sal_Int32 nHLIndex = -1; //i123620 |
| sal_uInt16 nHyperLink = 0; |
| sal_uInt16 nFields = rT.GetFieldCount( nPara ); |
| for ( sal_uInt16 n = 0; n < nFields; n++ ) |
| { |
| EFieldInfo aField = rT.GetFieldInfo( nPara, n ); |
| if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) ) |
| { |
| if ( aField.aPosition.nIndex == nEEIndex ) |
| { |
| nHLIndex = nHyperLink; |
| break; |
| } |
| nHyperLink++; |
| } |
| } |
| |
| return nHLIndex; |
| } |
| |
| // XAccessibleMultiLineText |
| sal_Int32 SAL_CALL AccessibleEditableTextPara::getLineNumberAtIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| sal_Int32 nRes = -1; |
| sal_Int32 nPara = GetParagraphIndex(); |
| |
| SvxTextForwarder &rCacheTF = GetTextForwarder(); |
| const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount(); |
| DBG_ASSERT( bValidPara, "getLineNumberAtIndex: current paragraph index out of range" ); |
| if (bValidPara) |
| { |
| // we explicitly allow for the index to point at the character right behind the text |
| if (0 <= nIndex && nIndex <= rCacheTF.GetTextLen( static_cast< sal_uInt16 >(nPara) )) |
| nRes = rCacheTF.GetLineNumberAtIndex( static_cast< sal_uInt16 >(nPara), static_cast< sal_uInt16 >(nIndex) ); |
| else |
| throw lang::IndexOutOfBoundsException(); |
| } |
| return nRes; |
| } |
| |
| // XAccessibleMultiLineText |
| ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineNumber( sal_Int32 nLineNo ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::com::sun::star::accessibility::TextSegment aResult; |
| sal_Int32 nPara = GetParagraphIndex(); |
| SvxTextForwarder &rCacheTF = GetTextForwarder(); |
| const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount(); |
| DBG_ASSERT( bValidPara, "getTextAtLineNumber: current paragraph index out of range" ); |
| if (bValidPara) |
| { |
| if (0 <= nLineNo && nLineNo < rCacheTF.GetLineCount( static_cast< sal_uInt16 >(nPara) )) |
| { |
| sal_uInt16 nStart = 0, nEnd = 0; |
| rCacheTF.GetLineBoundaries( nStart, nEnd, static_cast< sal_uInt16 >(nPara), static_cast< sal_uInt16 >(nLineNo) ); |
| if (nStart != 0xFFFF && nEnd != 0xFFFF) |
| { |
| try |
| { |
| aResult.SegmentText = getTextRange( nStart, nEnd ); |
| aResult.SegmentStart = nStart; |
| aResult.SegmentEnd = nEnd; |
| } |
| catch (lang::IndexOutOfBoundsException) |
| { |
| // this is not the exception that should be raised in this function ... |
| DBG_ASSERT( 0, "unexpected exception" ); |
| } |
| } |
| } |
| else |
| throw lang::IndexOutOfBoundsException(); |
| } |
| return aResult; |
| } |
| |
| // XAccessibleMultiLineText |
| ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineWithCaret( ) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| ::com::sun::star::accessibility::TextSegment aResult; |
| try |
| { |
| aResult = getTextAtLineNumber( getNumberOfLineWithCaret() ); |
| } |
| catch (lang::IndexOutOfBoundsException &) |
| { |
| // this one needs to be catched since this interface does not allow for it. |
| } |
| return aResult; |
| } |
| |
| // XAccessibleMultiLineText |
| sal_Int32 SAL_CALL AccessibleEditableTextPara::getNumberOfLineWithCaret( ) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| sal_Int32 nRes = -1; |
| try |
| { |
| nRes = getLineNumberAtIndex( getCaretPosition() ); |
| } |
| catch (lang::IndexOutOfBoundsException &) |
| { |
| // this one needs to be catched since this interface does not allow for it. |
| } |
| return nRes; |
| } |
| |
| |
| // XServiceInfo |
| ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getImplementationName (void) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("AccessibleEditableTextPara")); |
| } |
| |
| sal_Bool SAL_CALL AccessibleEditableTextPara::supportsService (const ::rtl::OUString& sServiceName) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| // Iterate over all supported service names and return true if on of them |
| // matches the given name. |
| uno::Sequence< ::rtl::OUString> aSupportedServices ( |
| getSupportedServiceNames ()); |
| for (int i=0; i<aSupportedServices.getLength(); i++) |
| if (sServiceName == aSupportedServices[i]) |
| return sal_True; |
| return sal_False; |
| } |
| |
| uno::Sequence< ::rtl::OUString> SAL_CALL AccessibleEditableTextPara::getSupportedServiceNames (void) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| const ::rtl::OUString sServiceName( getServiceName() ); |
| return uno::Sequence< ::rtl::OUString > (&sServiceName, 1); |
| } |
| |
| // XServiceName |
| ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getServiceName (void) throw (uno::RuntimeException) |
| { |
| DBG_CHKTHIS( AccessibleEditableTextPara, NULL ); |
| |
| // #105185# Using correct service now |
| return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.AccessibleParagraphView")); |
| } |
| |
| } // end of namespace accessibility |
| |
| //------------------------------------------------------------------------ |