1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
27 #include <vcl/window.hxx>
28 #include <vcl/svapp.hxx>
29 #include <tools/diagnose_ex.h>
30 #include <sal/log.hxx>
31 #include <editeng/flditem.hxx>
32 #include <com/sun/star/uno/Any.hxx>
33 #include <com/sun/star/uno/Reference.hxx>
34 #include <com/sun/star/awt/Point.hpp>
35 #include <com/sun/star/awt/Rectangle.hpp>
36 #include <com/sun/star/container/XNameContainer.hpp>
37 #include <com/sun/star/lang/DisposedException.hpp>
38 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
39 #include <com/sun/star/i18n/Boundary.hpp>
40 #include <com/sun/star/accessibility/AccessibleRole.hpp>
41 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
42 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
43 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
44 #include <comphelper/accessibleeventnotifier.hxx>
45 #include <comphelper/sequenceashashmap.hxx>
46 #include <cppuhelper/supportsservice.hxx>
47 #include <unotools/accessiblestatesethelper.hxx>
48 #include <unotools/accessiblerelationsethelper.hxx>
49 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
50 #include <vcl/unohelp.hxx>
51 #include <vcl/settings.hxx>
52 #include <i18nlangtag/languagetag.hxx>
54 #include <editeng/AccessibleImageBullet.hxx>
55 #include <editeng/editeng.hxx>
56 #include <editeng/unoprnms.hxx>
57 #include <editeng/unoipset.hxx>
58 #include <editeng/outliner.hxx>
59 #include <editeng/unoedprx.hxx>
60 #include <editeng/unoedsrc.hxx>
61 #include <svl/intitem.hxx>
62 #include <svl/eitem.hxx>
65 // Project-local header
68 #include <com/sun/star/beans/PropertyState.hpp>
70 #include <editeng/unolingu.hxx>
71 #include <editeng/unopracc.hxx>
72 #include <editeng/AccessibleEditableTextPara.hxx>
73 #include "AccessibleHyperlink.hxx"
75 #include <svtools/colorcfg.hxx>
77 #include <editeng/editrids.hrc>
78 #include <editeng/eerdll.hxx>
79 #include <editeng/numitem.hxx>
82 using namespace ::com::sun::star
;
83 using namespace ::com::sun::star::beans
;
84 using namespace ::com::sun::star::accessibility
;
87 // AccessibleEditableTextPara implementation
90 namespace accessibility
92 static const SvxItemPropertySet
* ImplGetSvxCharAndParaPropertiesSet()
94 // PropertyMap for character and paragraph properties
95 static const SfxItemPropertyMapEntry aPropMap
[] =
97 SVX_UNOEDIT_OUTLINER_PROPERTIES
,
98 SVX_UNOEDIT_CHAR_PROPERTIES
,
99 SVX_UNOEDIT_PARA_PROPERTIES
,
100 SVX_UNOEDIT_NUMBERING_PROPERTIE
,
101 { OUString("TextUserDefinedAttributes"), EE_CHAR_XMLATTRIBS
, cppu::UnoType
<css::container::XNameContainer
>::get(), 0, 0},
102 { OUString("ParaUserDefinedAttributes"), EE_PARA_XMLATTRIBS
, cppu::UnoType
<css::container::XNameContainer
>::get(), 0, 0},
103 { OUString(), 0, css::uno::Type(), 0, 0 }
105 static SvxItemPropertySet
aPropSet( aPropMap
, EditEngine::GetGlobalItemPool() );
109 // #i27138# - add parameter <_pParaManager>
110 AccessibleEditableTextPara::AccessibleEditableTextPara(
111 const uno::Reference
< XAccessible
>& rParent
,
112 const AccessibleParaManager
* _pParaManager
)
113 : AccessibleTextParaInterfaceBase( m_aMutex
),
114 mnParagraphIndex( 0 ),
115 mnIndexInParent( 0 ),
116 mpEditSource( nullptr ),
119 // well, that's strictly (UNO) exception safe, though not
120 // really robust. We rely on the fact that this member is
121 // constructed last, and that the constructor body catches
122 // exceptions, thus no chance for exceptions once the Id is
123 // fetched. Nevertheless, normally should employ RAII here...
124 mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient()),
126 mpParaManager( _pParaManager
)
131 // Create the state set.
132 ::utl::AccessibleStateSetHelper
* pStateSet
= new ::utl::AccessibleStateSetHelper ();
133 mxStateSet
= pStateSet
;
135 // these are always on
136 pStateSet
->AddState( AccessibleStateType::MULTI_LINE
);
137 pStateSet
->AddState( AccessibleStateType::FOCUSABLE
);
138 pStateSet
->AddState( AccessibleStateType::VISIBLE
);
139 pStateSet
->AddState( AccessibleStateType::SHOWING
);
140 pStateSet
->AddState( AccessibleStateType::ENABLED
);
141 pStateSet
->AddState( AccessibleStateType::SENSITIVE
);
143 catch (const uno::Exception
&)
148 AccessibleEditableTextPara::~AccessibleEditableTextPara()
150 // sign off from event notifier
151 if( getNotifierClientId() != -1 )
155 ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() );
157 catch (const uno::Exception
&)
163 OUString
AccessibleEditableTextPara::implGetText()
165 return GetTextRange( 0, GetTextLen() );
168 css::lang::Locale
AccessibleEditableTextPara::implGetLocale()
170 DBG_ASSERT(GetParagraphIndex() >= 0,
171 "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
173 // return locale of first character in the paragraph
174 return LanguageTag(GetTextForwarder().GetLanguage( GetParagraphIndex(), 0 )).getLocale();
177 void AccessibleEditableTextPara::implGetSelection( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
)
179 sal_Int32 nStart
, nEnd
;
181 if( GetSelection( nStart
, nEnd
) )
183 nStartIndex
= nStart
;
188 // #102234# No exception, just set to 'invalid'
194 void AccessibleEditableTextPara::implGetParagraphBoundary( const OUString
& rText
, css::i18n::Boundary
& rBoundary
, sal_Int32
/*nIndex*/ )
196 SAL_INFO( "editeng", "AccessibleEditableTextPara::implGetParagraphBoundary: only a base implementation, ignoring the index" );
198 rBoundary
.startPos
= 0;
199 rBoundary
.endPos
= rText
.getLength();
202 void AccessibleEditableTextPara::implGetLineBoundary( const OUString
&, css::i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
204 SvxTextForwarder
& rCacheTF
= GetTextForwarder();
205 const sal_Int32 nParaIndex
= GetParagraphIndex();
207 DBG_ASSERT(nParaIndex
>= 0,
208 "AccessibleEditableTextPara::implGetLineBoundary: paragraph index value overflow");
210 const sal_Int32 nTextLen
= rCacheTF
.GetTextLen( nParaIndex
);
212 CheckPosition(nIndex
);
214 rBoundary
.startPos
= rBoundary
.endPos
= -1;
216 const sal_Int32 nLineCount
=rCacheTF
.GetLineCount( nParaIndex
);
218 if( nIndex
== nTextLen
)
220 // #i17014# Special-casing one-behind-the-end character
221 if( nLineCount
<= 1 )
222 rBoundary
.startPos
= 0;
224 rBoundary
.startPos
= nTextLen
- rCacheTF
.GetLineLen( nParaIndex
,
227 rBoundary
.endPos
= nTextLen
;
231 // normal line search
234 for( nLine
=0, nCurIndex
=0; nLine
<nLineCount
; ++nLine
)
236 nCurIndex
+= rCacheTF
.GetLineLen( nParaIndex
, nLine
);
238 if( nCurIndex
> nIndex
)
240 rBoundary
.startPos
= nCurIndex
- rCacheTF
.GetLineLen( nParaIndex
, nLine
);
241 rBoundary
.endPos
= nCurIndex
;
249 void AccessibleEditableTextPara::SetIndexInParent( sal_Int32 nIndex
)
251 mnIndexInParent
= nIndex
;
255 void AccessibleEditableTextPara::SetParagraphIndex( sal_Int32 nIndex
)
257 sal_Int32 nOldIndex
= mnParagraphIndex
;
259 mnParagraphIndex
= nIndex
;
261 auto aChild( maImageBullet
.get() );
263 aChild
->SetParagraphIndex(mnParagraphIndex
);
267 if( nOldIndex
!= nIndex
)
274 aOldDesc
<<= getAccessibleDescription();
275 aOldName
<<= getAccessibleName();
277 catch (const uno::Exception
&) // optional behaviour
280 // index and therefore description changed
281 FireEvent( AccessibleEventId::DESCRIPTION_CHANGED
, uno::makeAny( getAccessibleDescription() ), aOldDesc
);
282 FireEvent( AccessibleEventId::NAME_CHANGED
, uno::makeAny( getAccessibleName() ), aOldName
);
285 catch (const uno::Exception
&) // optional behaviour
291 void AccessibleEditableTextPara::Dispose()
293 int nClientId( getNotifierClientId() );
295 // #108212# drop all references before notifying dispose
297 mnNotifierClientId
= -1;
298 mpEditSource
= nullptr;
301 if( nClientId
!= -1 )
305 uno::Reference
< XAccessibleContext
> xThis
= getAccessibleContext();
307 // #106234# Delegate to EventNotifier
308 ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId
, xThis
);
310 catch (const uno::Exception
&)
316 void AccessibleEditableTextPara::SetEditSource( SvxEditSourceAdapter
* pEditSource
)
318 auto aChild( maImageBullet
.get() );
320 aChild
->SetEditSource(pEditSource
);
325 UnSetState( AccessibleStateType::SHOWING
);
326 UnSetState( AccessibleStateType::VISIBLE
);
327 SetState( AccessibleStateType::INVALID
);
328 SetState( AccessibleStateType::DEFUNC
);
332 mpEditSource
= pEditSource
;
333 // #108900# Init last text content
338 catch (const uno::RuntimeException
&)
343 ESelection
AccessibleEditableTextPara::MakeSelection( sal_Int32 nStartEEIndex
, sal_Int32 nEndEEIndex
)
346 DBG_ASSERT(nStartEEIndex
>= 0 &&
348 GetParagraphIndex() >= 0,
349 "AccessibleEditableTextPara::MakeSelection: index value overflow");
351 sal_Int32 nParaIndex
= GetParagraphIndex();
352 return ESelection(nParaIndex
, nStartEEIndex
, nParaIndex
, nEndEEIndex
);
355 ESelection
AccessibleEditableTextPara::MakeSelection( sal_Int32 nEEIndex
)
357 return MakeSelection( nEEIndex
, nEEIndex
+1 );
360 ESelection
AccessibleEditableTextPara::MakeCursor( sal_Int32 nEEIndex
)
362 return MakeSelection( nEEIndex
, nEEIndex
);
365 void AccessibleEditableTextPara::CheckIndex( sal_Int32 nIndex
)
367 if( nIndex
< 0 || nIndex
>= getCharacterCount() )
368 throw lang::IndexOutOfBoundsException("AccessibleEditableTextPara: character index out of bounds",
369 uno::Reference
< uno::XInterface
>
370 ( static_cast< ::cppu::OWeakObject
* > (this) ) ); // disambiguate hierarchy
373 void AccessibleEditableTextPara::CheckPosition( sal_Int32 nIndex
)
375 if( nIndex
< 0 || nIndex
> getCharacterCount() )
376 throw lang::IndexOutOfBoundsException("AccessibleEditableTextPara: character position out of bounds",
377 uno::Reference
< uno::XInterface
>
378 ( static_cast< ::cppu::OWeakObject
* > (this) ) ); // disambiguate hierarchy
381 void AccessibleEditableTextPara::CheckRange( sal_Int32 nStart
, sal_Int32 nEnd
)
383 CheckPosition( nStart
);
384 CheckPosition( nEnd
);
387 bool AccessibleEditableTextPara::GetSelection(sal_Int32
&nStartPos
, sal_Int32
&nEndPos
)
389 ESelection aSelection
;
390 sal_Int32 nPara
= GetParagraphIndex();
391 if( !GetEditViewForwarder().GetSelection( aSelection
) )
394 if( aSelection
.nStartPara
< aSelection
.nEndPara
)
396 if( aSelection
.nStartPara
> nPara
||
397 aSelection
.nEndPara
< nPara
)
400 if( nPara
== aSelection
.nStartPara
)
401 nStartPos
= aSelection
.nStartPos
;
405 if( nPara
== aSelection
.nEndPara
)
406 nEndPos
= aSelection
.nEndPos
;
408 nEndPos
= GetTextLen();
412 if( aSelection
.nStartPara
< nPara
||
413 aSelection
.nEndPara
> nPara
)
416 if( nPara
== aSelection
.nStartPara
)
417 nStartPos
= aSelection
.nStartPos
;
419 nStartPos
= GetTextLen();
421 if( nPara
== aSelection
.nEndPara
)
422 nEndPos
= aSelection
.nEndPos
;
430 OUString
AccessibleEditableTextPara::GetTextRange( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
)
432 return GetTextForwarder().GetText( MakeSelection(nStartIndex
, nEndIndex
) );
435 sal_Int32
AccessibleEditableTextPara::GetTextLen() const
437 return GetTextForwarder().GetTextLen(GetParagraphIndex());
440 SvxEditSourceAdapter
& AccessibleEditableTextPara::GetEditSource() const
443 throw uno::RuntimeException("No edit source, object is defunct",
444 uno::Reference
< uno::XInterface
>
445 ( static_cast< ::cppu::OWeakObject
* >
446 ( const_cast< AccessibleEditableTextPara
* > (this) ) ) ); // disambiguate hierarchy
447 return *mpEditSource
;
450 SvxAccessibleTextAdapter
& AccessibleEditableTextPara::GetTextForwarder() const
452 SvxEditSourceAdapter
& rEditSource
= GetEditSource();
453 SvxAccessibleTextAdapter
* pTextForwarder
= rEditSource
.GetTextForwarderAdapter();
455 if( !pTextForwarder
)
456 throw uno::RuntimeException("Unable to fetch text forwarder, object is defunct",
457 uno::Reference
< uno::XInterface
>
458 ( static_cast< ::cppu::OWeakObject
* >
459 ( const_cast< AccessibleEditableTextPara
* > (this) ) ) ); // disambiguate hierarchy
461 if( !pTextForwarder
->IsValid() )
462 throw uno::RuntimeException("Text forwarder is invalid, object is defunct",
463 uno::Reference
< uno::XInterface
>
464 ( static_cast< ::cppu::OWeakObject
* >
465 ( const_cast< AccessibleEditableTextPara
* > (this) ) ) ); // disambiguate hierarchy
466 return *pTextForwarder
;
469 SvxViewForwarder
& AccessibleEditableTextPara::GetViewForwarder() const
471 SvxEditSource
& rEditSource
= GetEditSource();
472 SvxViewForwarder
* pViewForwarder
= rEditSource
.GetViewForwarder();
474 if( !pViewForwarder
)
476 throw uno::RuntimeException("Unable to fetch view forwarder, object is defunct",
477 uno::Reference
< uno::XInterface
>
478 ( static_cast< ::cppu::OWeakObject
* >
479 ( const_cast< AccessibleEditableTextPara
* > (this) ) ) ); // disambiguate hierarchy
482 if( !pViewForwarder
->IsValid() )
483 throw uno::RuntimeException("View forwarder is invalid, object is defunct",
484 uno::Reference
< uno::XInterface
>
485 ( static_cast< ::cppu::OWeakObject
* >
486 ( const_cast< AccessibleEditableTextPara
* > (this) ) ) ); // disambiguate hierarchy
487 return *pViewForwarder
;
490 SvxAccessibleTextEditViewAdapter
& AccessibleEditableTextPara::GetEditViewForwarder( bool bCreate
) const
492 SvxEditSourceAdapter
& rEditSource
= GetEditSource();
493 SvxAccessibleTextEditViewAdapter
* pTextEditViewForwarder
= rEditSource
.GetEditViewForwarderAdapter( bCreate
);
495 if( !pTextEditViewForwarder
)
498 throw uno::RuntimeException("Unable to fetch view forwarder, object is defunct",
499 uno::Reference
< uno::XInterface
>
500 ( static_cast< ::cppu::OWeakObject
* >
501 ( const_cast< AccessibleEditableTextPara
* > (this) ) ) ); // disambiguate hierarchy
503 throw uno::RuntimeException("No view forwarder, object not in edit mode",
504 uno::Reference
< uno::XInterface
>
505 ( static_cast< ::cppu::OWeakObject
* >
506 ( const_cast< AccessibleEditableTextPara
* > (this) ) ) ); // disambiguate hierarchy
509 if( pTextEditViewForwarder
->IsValid() )
510 return *pTextEditViewForwarder
;
514 throw uno::RuntimeException("View forwarder is invalid, object is defunct",
515 uno::Reference
< uno::XInterface
>
516 ( static_cast< ::cppu::OWeakObject
* >
517 ( const_cast< AccessibleEditableTextPara
* > (this) ) ) ); // disambiguate hierarchy
519 throw uno::RuntimeException("View forwarder is invalid, object not in edit mode",
520 uno::Reference
< uno::XInterface
>
521 ( static_cast< ::cppu::OWeakObject
* >
522 ( const_cast< AccessibleEditableTextPara
* > (this) ) ) ); // disambiguate hierarchy
526 bool AccessibleEditableTextPara::HaveEditView() const
528 SvxEditSource
& rEditSource
= GetEditSource();
529 SvxEditViewForwarder
* pViewForwarder
= rEditSource
.GetEditViewForwarder();
531 if( !pViewForwarder
)
534 if( !pViewForwarder
->IsValid() )
540 bool AccessibleEditableTextPara::HaveChildren()
542 DBG_ASSERT(GetParagraphIndex() >= 0,
543 "AccessibleEditableTextPara::HaveChildren: paragraph index value overflow");
545 return GetTextForwarder().HaveImageBullet( GetParagraphIndex() );
548 tools::Rectangle
AccessibleEditableTextPara::LogicToPixel( const tools::Rectangle
& rRect
, const MapMode
& rMapMode
, SvxViewForwarder
const & rForwarder
)
550 // convert to screen coordinates
551 return tools::Rectangle( rForwarder
.LogicToPixel( rRect
.TopLeft(), rMapMode
),
552 rForwarder
.LogicToPixel( rRect
.BottomRight(), rMapMode
) );
556 void AccessibleEditableTextPara::SetEEOffset( const Point
& rOffset
)
558 auto aChild( maImageBullet
.get() );
560 aChild
->SetEEOffset(rOffset
);
562 maEEOffset
= rOffset
;
565 void AccessibleEditableTextPara::FireEvent(const sal_Int16 nEventId
, const uno::Any
& rNewValue
, const uno::Any
& rOldValue
) const
567 uno::Reference
< XAccessibleContext
> xThis( const_cast< AccessibleEditableTextPara
* > (this)->getAccessibleContext() );
569 AccessibleEventObject
aEvent(xThis
, nEventId
, rNewValue
, rOldValue
);
571 // #102261# Call global queue for focus events
572 if( nEventId
== AccessibleEventId::STATE_CHANGED
)
573 vcl::unohelper::NotifyAccessibleStateEventGlobally( aEvent
);
575 // #106234# Delegate to EventNotifier
576 if( getNotifierClientId() != -1 )
577 ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(),
581 void AccessibleEditableTextPara::SetState( const sal_Int16 nStateId
)
583 ::utl::AccessibleStateSetHelper
* pStateSet
= static_cast< ::utl::AccessibleStateSetHelper
*>(mxStateSet
.get());
584 if( pStateSet
!= nullptr &&
585 !pStateSet
->contains(nStateId
) )
587 pStateSet
->AddState( nStateId
);
588 FireEvent( AccessibleEventId::STATE_CHANGED
, uno::makeAny( nStateId
) );
592 void AccessibleEditableTextPara::UnSetState( const sal_Int16 nStateId
)
594 ::utl::AccessibleStateSetHelper
* pStateSet
= static_cast< ::utl::AccessibleStateSetHelper
*>(mxStateSet
.get());
595 if( pStateSet
!= nullptr &&
596 pStateSet
->contains(nStateId
) )
598 pStateSet
->RemoveState( nStateId
);
599 FireEvent( AccessibleEventId::STATE_CHANGED
, uno::Any(), uno::makeAny( nStateId
) );
603 void AccessibleEditableTextPara::TextChanged()
605 OUString
aCurrentString( implGetText() );
608 if( OCommonAccessibleText::implInitTextChangedEvent( maLastTextString
, aCurrentString
,
609 aDeleted
, aInserted
) )
611 FireEvent( AccessibleEventId::TEXT_CHANGED
, aInserted
, aDeleted
);
612 maLastTextString
= aCurrentString
;
616 bool AccessibleEditableTextPara::GetAttributeRun( sal_Int32
& nStartIndex
, sal_Int32
& nEndIndex
, sal_Int32 nIndex
)
618 DBG_ASSERT(nIndex
>= 0,
619 "AccessibleEditableTextPara::GetAttributeRun: index value overflow");
621 DBG_ASSERT(GetParagraphIndex() >= 0,
622 "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
624 return GetTextForwarder().GetAttributeRun( nStartIndex
,
630 uno::Any SAL_CALL
AccessibleEditableTextPara::queryInterface (const uno::Type
& rType
)
634 // must provide XAccessibleText by hand, since it comes publicly inherited by XAccessibleEditableText
635 if ( rType
== cppu::UnoType
<XAccessibleText
>::get())
637 uno::Reference
< XAccessibleText
> aAccText
= static_cast< XAccessibleEditableText
* >(this);
640 else if ( rType
== cppu::UnoType
<XAccessibleEditableText
>::get())
642 uno::Reference
< XAccessibleEditableText
> aAccEditText
= this;
643 aRet
<<= aAccEditText
;
645 else if ( rType
== cppu::UnoType
<XAccessibleHypertext
>::get())
647 uno::Reference
< XAccessibleHypertext
> aAccHyperText
= this;
648 aRet
<<= aAccHyperText
;
652 aRet
= AccessibleTextParaInterfaceBase::queryInterface(rType
);
659 uno::Reference
< XAccessibleContext
> SAL_CALL
AccessibleEditableTextPara::getAccessibleContext()
661 // We implement the XAccessibleContext interface in the same object
662 return uno::Reference
< XAccessibleContext
> ( this );
665 // XAccessibleContext
666 sal_Int32 SAL_CALL
AccessibleEditableTextPara::getAccessibleChildCount()
668 SolarMutexGuard aGuard
;
670 return HaveChildren() ? 1 : 0;
673 uno::Reference
< XAccessible
> SAL_CALL
AccessibleEditableTextPara::getAccessibleChild( sal_Int32 i
)
675 SolarMutexGuard aGuard
;
677 if( !HaveChildren() )
678 throw lang::IndexOutOfBoundsException("No children available",
679 uno::Reference
< uno::XInterface
>
680 ( static_cast< ::cppu::OWeakObject
* > (this) ) ); // static_cast: disambiguate hierarchy
683 throw lang::IndexOutOfBoundsException("Invalid child index",
684 uno::Reference
< uno::XInterface
>
685 ( static_cast< ::cppu::OWeakObject
* > (this) ) ); // static_cast: disambiguate hierarchy
687 auto aChild( maImageBullet
.get() );
691 // there is no hard reference available, create object then
692 aChild
= new AccessibleImageBullet(this);
694 aChild
->SetEditSource( &GetEditSource() );
695 aChild
->SetParagraphIndex( GetParagraphIndex() );
696 aChild
->SetIndexInParent( i
);
698 maImageBullet
= aChild
;
704 uno::Reference
< XAccessible
> SAL_CALL
AccessibleEditableTextPara::getAccessibleParent()
706 SAL_WARN_IF(!mxParent
.is(), "editeng", "AccessibleEditableTextPara::getAccessibleParent: no frontend set, did somebody forgot to call AccessibleTextHelper::SetEventSource()?");
711 sal_Int32 SAL_CALL
AccessibleEditableTextPara::getAccessibleIndexInParent()
713 return mnIndexInParent
;
716 sal_Int16 SAL_CALL
AccessibleEditableTextPara::getAccessibleRole()
718 return AccessibleRole::PARAGRAPH
;
721 OUString SAL_CALL
AccessibleEditableTextPara::getAccessibleDescription()
723 SolarMutexGuard aGuard
;
725 // append first 40 characters from text, or first line, if shorter
726 // (writer takes first sentence here, but that's not supported
731 if( getCharacterCount() )
732 aLine
= getTextAtIndex(0, AccessibleTextType::LINE
).SegmentText
;
734 // Get the string from the resource for the specified id.
735 OUString
sStr(EditResId(RID_SVXSTR_A11Y_PARAGRAPH_DESCRIPTION
));
736 OUString sParaIndex
= OUString::number(GetParagraphIndex());
737 sStr
= sStr
.replaceFirst("$(ARG)", sParaIndex
);
739 if( aLine
.getLength() > MaxDescriptionLen
)
744 // search backward from MaxDescriptionLen for previous word start
745 for( aCurrWord
=getTextAtIndex(MaxDescriptionLen
, AccessibleTextType::WORD
).SegmentText
,
751 if( getTextAtIndex(i
, AccessibleTextType::WORD
).SegmentText
!= aCurrWord
)
754 // prevent completely empty string
755 aLine
= getTextAtIndex(0, AccessibleTextType::WORD
).SegmentText
;
757 aLine
= getTextRange(0, i
);
765 OUString SAL_CALL
AccessibleEditableTextPara::getAccessibleName()
767 //See tdf#101003 before implementing a body
771 uno::Reference
< XAccessibleRelationSet
> SAL_CALL
AccessibleEditableTextPara::getAccessibleRelationSet()
773 // #i27138# - provide relations CONTENT_FLOWS_FROM
774 // and CONTENT_FLOWS_TO
777 utl::AccessibleRelationSetHelper
* pAccRelSetHelper
=
778 new utl::AccessibleRelationSetHelper();
779 sal_Int32
nMyParaIndex( GetParagraphIndex() );
780 // relation CONTENT_FLOWS_FROM
781 if ( nMyParaIndex
> 0 &&
782 mpParaManager
->IsReferencable( nMyParaIndex
- 1 ) )
784 uno::Sequence
<uno::Reference
<XInterface
> > aSequence
785 { static_cast<cppu::OWeakObject
*>(mpParaManager
->GetChild( nMyParaIndex
- 1 ).first
.get().get()) };
786 AccessibleRelation
aAccRel( AccessibleRelationType::CONTENT_FLOWS_FROM
,
788 pAccRelSetHelper
->AddRelation( aAccRel
);
791 // relation CONTENT_FLOWS_TO
792 if ( (nMyParaIndex
+ 1) < mpParaManager
->GetNum() &&
793 mpParaManager
->IsReferencable( nMyParaIndex
+ 1 ) )
795 uno::Sequence
<uno::Reference
<XInterface
> > aSequence
796 { static_cast<cppu::OWeakObject
*>(mpParaManager
->GetChild( nMyParaIndex
+ 1 ).first
.get().get()) };
797 AccessibleRelation
aAccRel( AccessibleRelationType::CONTENT_FLOWS_TO
,
799 pAccRelSetHelper
->AddRelation( aAccRel
);
802 return pAccRelSetHelper
;
806 // no relations, therefore empty
807 return uno::Reference
< XAccessibleRelationSet
>();
811 static uno::Sequence
< OUString
> const & getAttributeNames()
813 static const uno::Sequence
<OUString
> aNames
{
825 "CharUnderlineColor",
831 "ParaFirstLineIndent",
842 const PropertyValue
* pValues
;
843 explicit IndexCompare( const PropertyValue
* pVals
) : pValues(pVals
) {}
844 bool operator() ( sal_Int32 a
, sal_Int32 b
) const
846 return pValues
[a
].Name
< pValues
[b
].Name
;
853 OUString
GetFieldTypeNameFromField(EFieldInfo
const &ree
)
856 sal_Int32 nFieldType
= -1;
859 // So we get a field, check its type now.
860 nFieldType
= ree
.pFieldItem
->GetField()->GetClassId() ;
864 case text::textfield::Type::DATE
:
866 const SvxDateField
* pDateField
= static_cast< const SvxDateField
* >(ree
.pFieldItem
->GetField());
869 if (pDateField
->GetType() == SvxDateType::Fix
)
870 strFldType
= "date (fixed)";
871 else if (pDateField
->GetType() == SvxDateType::Var
)
872 strFldType
= "date (variable)";
876 case text::textfield::Type::PAGE
:
877 strFldType
= "page-number";
879 //support the sheet name & pages fields
880 case text::textfield::Type::PAGES
:
881 strFldType
= "page-count";
883 case text::textfield::Type::TABLE
:
884 strFldType
= "sheet-name";
887 case text::textfield::Type::TIME
:
890 case text::textfield::Type::EXTENDED_TIME
:
892 const SvxExtTimeField
* pTimeField
= static_cast< const SvxExtTimeField
* >(ree
.pFieldItem
->GetField());
895 if (pTimeField
->GetType() == SvxTimeType::Fix
)
896 strFldType
= "time (fixed)";
897 else if (pTimeField
->GetType() == SvxTimeType::Var
)
898 strFldType
= "time (variable)";
902 case text::textfield::Type::AUTHOR
:
903 strFldType
= "author";
905 case text::textfield::Type::EXTENDED_FILE
:
906 case text::textfield::Type::DOCINFO_TITLE
:
907 strFldType
= "file name";
909 case text::textfield::Type::DOCINFO_CUSTOM
:
910 strFldType
= "custom document property";
919 namespace accessibility
921 OUString
AccessibleEditableTextPara::GetFieldTypeNameAtIndex(sal_Int32 nIndex
)
923 SvxAccessibleTextAdapter
& rCacheTF
= GetTextForwarder();
924 //For field object info
925 sal_Int32 nParaIndex
= GetParagraphIndex();
926 sal_Int32 nAllFieldLen
= 0;
927 sal_Int32 nField
= rCacheTF
.GetFieldCount(nParaIndex
);
928 for (sal_Int32 j
= 0; j
< nField
; ++j
)
930 EFieldInfo ree
= rCacheTF
.GetFieldInfo(nParaIndex
, j
);
931 sal_Int32 reeBegin
= ree
.aPosition
.nIndex
+ nAllFieldLen
;
932 sal_Int32 reeEnd
= reeBegin
+ ree
.aCurrentText
.getLength();
933 nAllFieldLen
+= (ree
.aCurrentText
.getLength() - 1);
934 if (nIndex
< reeBegin
)
937 return GetFieldTypeNameFromField(ree
);
942 uno::Reference
< XAccessibleStateSet
> SAL_CALL
AccessibleEditableTextPara::getAccessibleStateSet()
944 SolarMutexGuard aGuard
;
946 // Create a copy of the state set and return it.
947 ::utl::AccessibleStateSetHelper
* pStateSet
= static_cast< ::utl::AccessibleStateSetHelper
*>(mxStateSet
.get());
950 return uno::Reference
<XAccessibleStateSet
>();
951 uno::Reference
<XAccessibleStateSet
> xParentStates
;
952 if (getAccessibleParent().is())
954 uno::Reference
<XAccessibleContext
> xParentContext
= getAccessibleParent()->getAccessibleContext();
955 xParentStates
= xParentContext
->getAccessibleStateSet();
957 if (xParentStates
.is() && xParentStates
->contains(AccessibleStateType::EDITABLE
) )
959 pStateSet
->AddState(AccessibleStateType::EDITABLE
);
961 return uno::Reference
<XAccessibleStateSet
>( new ::utl::AccessibleStateSetHelper (*pStateSet
) );
964 lang::Locale SAL_CALL
AccessibleEditableTextPara::getLocale()
966 SolarMutexGuard aGuard
;
968 return implGetLocale();
971 void SAL_CALL
AccessibleEditableTextPara::addAccessibleEventListener( const uno::Reference
< XAccessibleEventListener
>& xListener
)
973 if( getNotifierClientId() != -1 )
974 ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener
);
977 void SAL_CALL
AccessibleEditableTextPara::removeAccessibleEventListener( const uno::Reference
< XAccessibleEventListener
>& xListener
)
979 if( getNotifierClientId() != -1 )
981 const sal_Int32 nListenerCount
= ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener
);
982 if ( !nListenerCount
)
984 // no listeners anymore
985 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
986 // and at least to us not firing any events anymore, in case somebody calls
987 // NotifyAccessibleEvent, again
988 ::comphelper::AccessibleEventNotifier::TClientId
nId( getNotifierClientId() );
989 mnNotifierClientId
= -1;
990 ::comphelper::AccessibleEventNotifier::revokeClient( nId
);
995 // XAccessibleComponent
996 sal_Bool SAL_CALL
AccessibleEditableTextPara::containsPoint( const awt::Point
& aTmpPoint
)
998 SolarMutexGuard aGuard
;
1000 DBG_ASSERT(GetParagraphIndex() >= 0,
1001 "AccessibleEditableTextPara::contains: index value overflow");
1003 awt::Rectangle aTmpRect
= getBounds();
1004 tools::Rectangle
aRect( Point(aTmpRect
.X
, aTmpRect
.Y
), Size(aTmpRect
.Width
, aTmpRect
.Height
) );
1005 Point
aPoint( aTmpPoint
.X
, aTmpPoint
.Y
);
1007 return aRect
.IsInside( aPoint
);
1010 uno::Reference
< XAccessible
> SAL_CALL
AccessibleEditableTextPara::getAccessibleAtPoint( const awt::Point
& _aPoint
)
1012 SolarMutexGuard aGuard
;
1014 if( HaveChildren() )
1016 // #103862# No longer need to make given position relative
1017 Point
aPoint( _aPoint
.X
, _aPoint
.Y
);
1019 // respect EditEngine offset to surrounding shape/cell
1020 aPoint
-= GetEEOffset();
1022 // convert to EditEngine coordinate system
1023 SvxTextForwarder
& rCacheTF
= GetTextForwarder();
1024 Point
aLogPoint( GetViewForwarder().PixelToLogic( aPoint
, rCacheTF
.GetMapMode() ) );
1026 EBulletInfo aBulletInfo
= rCacheTF
.GetBulletInfo(GetParagraphIndex());
1028 if( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&&
1029 aBulletInfo
.bVisible
&&
1030 aBulletInfo
.nType
== SVX_NUM_BITMAP
)
1032 tools::Rectangle aRect
= aBulletInfo
.aBounds
;
1034 if( aRect
.IsInside( aLogPoint
) )
1035 return getAccessibleChild(0);
1039 // no children at all, or none at given position
1040 return uno::Reference
< XAccessible
>();
1043 awt::Rectangle SAL_CALL
AccessibleEditableTextPara::getBounds()
1045 SolarMutexGuard aGuard
;
1047 DBG_ASSERT(GetParagraphIndex() >= 0,
1048 "AccessibleEditableTextPara::getBounds: index value overflow");
1050 SvxTextForwarder
& rCacheTF
= GetTextForwarder();
1051 tools::Rectangle aRect
= rCacheTF
.GetParaBounds( GetParagraphIndex() );
1053 // convert to screen coordinates
1054 tools::Rectangle aScreenRect
= AccessibleEditableTextPara::LogicToPixel( aRect
,
1055 rCacheTF
.GetMapMode(),
1056 GetViewForwarder() );
1058 // offset from shape/cell
1059 Point aOffset
= GetEEOffset();
1061 return awt::Rectangle( aScreenRect
.Left() + aOffset
.X(),
1062 aScreenRect
.Top() + aOffset
.Y(),
1063 aScreenRect
.GetSize().Width(),
1064 aScreenRect
.GetSize().Height() );
1067 awt::Point SAL_CALL
AccessibleEditableTextPara::getLocation( )
1069 SolarMutexGuard aGuard
;
1071 awt::Rectangle aRect
= getBounds();
1073 return awt::Point( aRect
.X
, aRect
.Y
);
1076 awt::Point SAL_CALL
AccessibleEditableTextPara::getLocationOnScreen( )
1078 SolarMutexGuard aGuard
;
1080 // relate us to parent
1081 uno::Reference
< XAccessible
> xParent
= getAccessibleParent();
1084 uno::Reference
< XAccessibleComponent
> xParentComponent( xParent
, uno::UNO_QUERY
);
1085 if( xParentComponent
.is() )
1087 awt::Point aRefPoint
= xParentComponent
->getLocationOnScreen();
1088 awt::Point aPoint
= getLocation();
1089 aPoint
.X
+= aRefPoint
.X
;
1090 aPoint
.Y
+= aRefPoint
.Y
;
1095 // fallback to parent's <XAccessibleContext> instance
1098 uno::Reference
< XAccessibleContext
> xParentContext
= xParent
->getAccessibleContext();
1099 if ( xParentContext
.is() )
1101 uno::Reference
< XAccessibleComponent
> xParentContextComponent( xParentContext
, uno::UNO_QUERY
);
1102 if( xParentContextComponent
.is() )
1104 awt::Point aRefPoint
= xParentContextComponent
->getLocationOnScreen();
1105 awt::Point aPoint
= getLocation();
1106 aPoint
.X
+= aRefPoint
.X
;
1107 aPoint
.Y
+= aRefPoint
.Y
;
1115 throw uno::RuntimeException("Cannot access parent",
1116 uno::Reference
< uno::XInterface
>
1117 ( static_cast< XAccessible
* > (this) ) ); // disambiguate hierarchy
1120 awt::Size SAL_CALL
AccessibleEditableTextPara::getSize( )
1122 SolarMutexGuard aGuard
;
1124 awt::Rectangle aRect
= getBounds();
1126 return awt::Size( aRect
.Width
, aRect
.Height
);
1129 void SAL_CALL
AccessibleEditableTextPara::grabFocus( )
1131 // set cursor to this paragraph
1135 sal_Int32 SAL_CALL
AccessibleEditableTextPara::getForeground( )
1137 // #104444# Added to XAccessibleComponent interface
1138 svtools::ColorConfig aColorConfig
;
1139 Color nColor
= aColorConfig
.GetColorValue( svtools::FONTCOLOR
).nColor
;
1140 return static_cast<sal_Int32
>(nColor
);
1143 sal_Int32 SAL_CALL
AccessibleEditableTextPara::getBackground( )
1145 // #104444# Added to XAccessibleComponent interface
1146 Color
aColor( Application::GetSettings().GetStyleSettings().GetWindowColor() );
1148 // the background is transparent
1149 aColor
.SetTransparency( 0xFF);
1151 return static_cast<sal_Int32
>( aColor
);
1155 sal_Int32 SAL_CALL
AccessibleEditableTextPara::getCaretPosition()
1157 SolarMutexGuard aGuard
;
1159 if( !HaveEditView() )
1162 ESelection aSelection
;
1163 if( GetEditViewForwarder().GetSelection( aSelection
) &&
1164 GetParagraphIndex() == aSelection
.nEndPara
)
1166 // caret is always nEndPara,nEndPos
1167 EBulletInfo aBulletInfo
= GetTextForwarder().GetBulletInfo(GetParagraphIndex());
1168 if( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&&
1169 aBulletInfo
.bVisible
&&
1170 aBulletInfo
.nType
!= SVX_NUM_BITMAP
)
1172 sal_Int32 nBulletLen
= aBulletInfo
.aText
.getLength();
1173 if( aSelection
.nEndPos
- nBulletLen
>= 0 )
1174 return aSelection
.nEndPos
- nBulletLen
;
1176 return aSelection
.nEndPos
;
1179 // not within this paragraph
1183 sal_Bool SAL_CALL
AccessibleEditableTextPara::setCaretPosition( sal_Int32 nIndex
)
1185 return setSelection(nIndex
, nIndex
);
1188 sal_Unicode SAL_CALL
AccessibleEditableTextPara::getCharacter( sal_Int32 nIndex
)
1190 SolarMutexGuard aGuard
;
1192 DBG_ASSERT(GetParagraphIndex() >= 0,
1193 "AccessibleEditableTextPara::getCharacter: index value overflow");
1195 return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex
);
1198 uno::Sequence
< beans::PropertyValue
> SAL_CALL
AccessibleEditableTextPara::getCharacterAttributes( sal_Int32 nIndex
, const css::uno::Sequence
< OUString
>& rRequestedAttributes
)
1200 SolarMutexGuard aGuard
;
1202 //Skip the bullet range to ignore the bullet text
1203 SvxTextForwarder
& rCacheTF
= GetTextForwarder();
1204 EBulletInfo aBulletInfo
= rCacheTF
.GetBulletInfo(GetParagraphIndex());
1205 if (aBulletInfo
.bVisible
)
1206 nIndex
+= aBulletInfo
.aText
.getLength();
1207 CheckIndex(nIndex
); // may throw IndexOutOfBoundsException
1209 bool bSupplementalMode
= false;
1210 uno::Sequence
< OUString
> aPropertyNames
= rRequestedAttributes
;
1211 if (!aPropertyNames
.hasElements())
1213 bSupplementalMode
= true;
1214 aPropertyNames
= getAttributeNames();
1217 // get default attributes...
1218 ::comphelper::SequenceAsHashMap
aPropHashMap( getDefaultAttributes( aPropertyNames
) );
1220 // ... and override them with the direct attributes from the specific position
1221 const uno::Sequence
< beans::PropertyValue
> aRunAttribs( getRunAttributes( nIndex
, aPropertyNames
) );
1222 for (auto const& rRunAttrib
: aRunAttribs
)
1224 aPropHashMap
[ rRunAttrib
.Name
] = rRunAttrib
.Value
; //!! should not only be the value !!
1227 // get resulting sequence
1228 uno::Sequence
< beans::PropertyValue
> aRes
;
1229 aPropHashMap
>> aRes
;
1231 // since SequenceAsHashMap ignores property handles and property state
1232 // we have to restore the property state here (property handles are
1233 // of no use to the accessibility API).
1234 for (beans::PropertyValue
& rRes
: aRes
)
1236 bool bIsDirectVal
= false;
1237 for (auto const& rRunAttrib
: aRunAttribs
)
1239 bIsDirectVal
= rRes
.Name
== rRunAttrib
.Name
;
1244 rRes
.State
= bIsDirectVal
? PropertyState_DIRECT_VALUE
: PropertyState_DEFAULT_VALUE
;
1246 if( bSupplementalMode
)
1248 _correctValues( aRes
);
1250 sal_Int32 nRes
= aRes
.getLength();
1251 aRes
.realloc( nRes
+ 1 );
1252 beans::PropertyValue
&rRes
= aRes
[nRes
];
1253 rRes
.Name
= "NumberingPrefix";
1255 if (aBulletInfo
.nType
!= SVX_NUM_CHAR_SPECIAL
&& aBulletInfo
.nType
!= SVX_NUM_BITMAP
)
1256 numStr
= aBulletInfo
.aText
;
1257 rRes
.Value
<<= numStr
;
1259 rRes
.State
= PropertyState_DIRECT_VALUE
;
1261 OUString strFieldType
= GetFieldTypeNameAtIndex(nIndex
);
1262 if (!strFieldType
.isEmpty())
1264 nRes
= aRes
.getLength();
1265 aRes
.realloc( nRes
+ 1 );
1266 beans::PropertyValue
&rResField
= aRes
[nRes
];
1267 rResField
.Name
= "FieldType";
1268 rResField
.Value
<<= strFieldType
.toAsciiLowerCase();
1269 rResField
.Handle
= -1;
1270 rResField
.State
= PropertyState_DIRECT_VALUE
;
1272 //sort property values
1273 // build sorted index array
1274 sal_Int32 nLength
= aRes
.getLength();
1275 const beans::PropertyValue
* pPairs
= aRes
.getConstArray();
1276 std::unique_ptr
<sal_Int32
[]> pIndices(new sal_Int32
[nLength
]);
1278 for( i
= 0; i
< nLength
; i
++ )
1280 sort( &pIndices
[0], &pIndices
[nLength
], IndexCompare(pPairs
) );
1281 // create sorted sequences according to index array
1282 uno::Sequence
<beans::PropertyValue
> aNewValues( nLength
);
1283 beans::PropertyValue
* pNewValues
= aNewValues
.getArray();
1284 for( i
= 0; i
< nLength
; i
++ )
1286 pNewValues
[i
] = pPairs
[pIndices
[i
]];
1294 awt::Rectangle SAL_CALL
AccessibleEditableTextPara::getCharacterBounds( sal_Int32 nIndex
)
1296 SolarMutexGuard aGuard
;
1298 DBG_ASSERT(GetParagraphIndex() >= 0,
1299 "AccessibleEditableTextPara::getCharacterBounds: index value overflow");
1301 // #108900# Have position semantics now for nIndex, as
1302 // one-past-the-end values are legal, too.
1303 CheckPosition( nIndex
);
1305 SvxTextForwarder
& rCacheTF
= GetTextForwarder();
1306 tools::Rectangle aRect
= rCacheTF
.GetCharBounds(GetParagraphIndex(), nIndex
);
1308 // convert to screen
1309 tools::Rectangle aScreenRect
= AccessibleEditableTextPara::LogicToPixel( aRect
,
1310 rCacheTF
.GetMapMode(),
1311 GetViewForwarder() );
1312 // #109864# offset from parent (paragraph), but in screen
1313 // coordinates. This makes sure the internal text offset in
1314 // the outline view forwarder gets cancelled out here
1315 awt::Rectangle
aParaRect( getBounds() );
1316 aScreenRect
.Move( -aParaRect
.X
, -aParaRect
.Y
);
1318 // offset from shape/cell
1319 Point aOffset
= GetEEOffset();
1321 return awt::Rectangle( aScreenRect
.Left() + aOffset
.X(),
1322 aScreenRect
.Top() + aOffset
.Y(),
1323 aScreenRect
.GetSize().Width(),
1324 aScreenRect
.GetSize().Height() );
1327 sal_Int32 SAL_CALL
AccessibleEditableTextPara::getCharacterCount()
1329 SolarMutexGuard aGuard
;
1331 DBG_ASSERT(GetParagraphIndex() >= 0,
1332 "AccessibleEditableTextPara::getCharacterCount: index value overflow");
1334 return implGetText().getLength();
1337 sal_Int32 SAL_CALL
AccessibleEditableTextPara::getIndexAtPoint( const awt::Point
& rPoint
)
1339 SolarMutexGuard aGuard
;
1344 // offset from surrounding cell/shape
1345 Point
aOffset( GetEEOffset() );
1346 Point
aPoint( rPoint
.X
- aOffset
.X(), rPoint
.Y
- aOffset
.Y() );
1348 // convert to logical coordinates
1349 SvxTextForwarder
& rCacheTF
= GetTextForwarder();
1350 Point
aLogPoint( GetViewForwarder().PixelToLogic( aPoint
, rCacheTF
.GetMapMode() ) );
1352 // re-offset to parent (paragraph)
1353 tools::Rectangle aParaRect
= rCacheTF
.GetParaBounds( GetParagraphIndex() );
1354 aLogPoint
.Move( aParaRect
.Left(), aParaRect
.Top() );
1356 if( rCacheTF
.GetIndexAtPoint( aLogPoint
, nPara
, nIndex
) &&
1357 GetParagraphIndex() == nPara
)
1359 // #102259# Double-check if we're _really_ on the given character
1362 awt::Rectangle
aRect1( getCharacterBounds(nIndex
) );
1363 tools::Rectangle
aRect2( aRect1
.X
, aRect1
.Y
,
1364 aRect1
.Width
+ aRect1
.X
, aRect1
.Height
+ aRect1
.Y
);
1365 if( aRect2
.IsInside( Point( rPoint
.X
, rPoint
.Y
) ) )
1370 catch (const lang::IndexOutOfBoundsException
&)
1372 // #103927# Don't throw for invalid nIndex values
1378 // not within our paragraph
1383 OUString SAL_CALL
AccessibleEditableTextPara::getSelectedText()
1385 SolarMutexGuard aGuard
;
1387 DBG_ASSERT(GetParagraphIndex() >= 0,
1388 "AccessibleEditableTextPara::getSelectedText: index value overflow");
1390 if( !HaveEditView() )
1393 return OCommonAccessibleText::getSelectedText();
1396 sal_Int32 SAL_CALL
AccessibleEditableTextPara::getSelectionStart()
1398 SolarMutexGuard aGuard
;
1400 DBG_ASSERT(GetParagraphIndex() >= 0,
1401 "AccessibleEditableTextPara::getSelectionStart: index value overflow");
1403 if( !HaveEditView() )
1406 return OCommonAccessibleText::getSelectionStart();
1409 sal_Int32 SAL_CALL
AccessibleEditableTextPara::getSelectionEnd()
1411 SolarMutexGuard aGuard
;
1413 DBG_ASSERT(GetParagraphIndex() >= 0,
1414 "AccessibleEditableTextPara::getSelectionEnd: index value overflow");
1416 if( !HaveEditView() )
1419 return OCommonAccessibleText::getSelectionEnd();
1422 sal_Bool SAL_CALL
AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
)
1424 SolarMutexGuard aGuard
;
1426 DBG_ASSERT(GetParagraphIndex() >= 0,
1427 "AccessibleEditableTextPara::setSelection: paragraph index value overflow");
1429 CheckRange(nStartIndex
, nEndIndex
);
1433 SvxEditViewForwarder
& rCacheVF
= GetEditViewForwarder( true );
1434 return rCacheVF
.SetSelection( MakeSelection(nStartIndex
, nEndIndex
) );
1436 catch (const uno::RuntimeException
&)
1442 OUString SAL_CALL
AccessibleEditableTextPara::getText()
1444 SolarMutexGuard aGuard
;
1446 DBG_ASSERT(GetParagraphIndex() >= 0,
1447 "AccessibleEditableTextPara::getText: paragraph index value overflow");
1449 return implGetText();
1452 OUString SAL_CALL
AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
)
1454 SolarMutexGuard aGuard
;
1456 DBG_ASSERT(GetParagraphIndex() >= 0,
1457 "AccessibleEditableTextPara::getTextRange: paragraph index value overflow");
1459 return OCommonAccessibleText::implGetTextRange(implGetText(), nStartIndex
, nEndIndex
);
1462 void AccessibleEditableTextPara::_correctValues( uno::Sequence
< PropertyValue
>& rValues
)
1464 SvxTextForwarder
& rCacheTF
= GetTextForwarder();
1465 sal_Int32 nRes
= rValues
.getLength();
1466 beans::PropertyValue
*pRes
= rValues
.getArray();
1467 for (sal_Int32 i
= 0; i
< nRes
; ++i
)
1469 beans::PropertyValue
&rRes
= pRes
[i
];
1471 if (rRes
.Name
== "CharColor")
1473 uno::Any
&anyChar
= rRes
.Value
;
1474 Color crChar
= static_cast<sal_uInt32
>( reinterpret_cast<sal_uIntPtr
>(anyChar
.pReserved
));
1475 if (COL_AUTO
== crChar
)
1477 uno::Reference
< css::accessibility::XAccessibleComponent
> xComponent(mxParent
,uno::UNO_QUERY
);
1478 if (xComponent
.is())
1480 uno::Reference
< css::accessibility::XAccessibleContext
> xContext(xComponent
,uno::UNO_QUERY
);
1481 if (xContext
->getAccessibleRole() == AccessibleRole::SHAPE
1482 || xContext
->getAccessibleRole() == AccessibleRole::TABLE_CELL
)
1484 anyChar
<<= COL_BLACK
;
1488 Color
cr(xComponent
->getBackground());
1489 crChar
= cr
.IsDark() ? COL_WHITE
: COL_BLACK
;
1497 if (rRes
.Name
== "CharUnderline")
1501 // Underline color && Mis-spell
1502 if (rRes
.Name
== "CharUnderlineColor")
1504 uno::Any
&anyCharUnderLine
= rRes
.Value
;
1505 Color crCharUnderLine
= static_cast<sal_uInt32
>( reinterpret_cast<sal_uIntPtr
>( anyCharUnderLine
.pReserved
));
1506 if (COL_AUTO
== crCharUnderLine
)
1508 uno::Reference
< css::accessibility::XAccessibleComponent
> xComponent(mxParent
,uno::UNO_QUERY
);
1509 if (xComponent
.is())
1511 uno::Reference
< css::accessibility::XAccessibleContext
> xContext(xComponent
,uno::UNO_QUERY
);
1512 if (xContext
->getAccessibleRole() == AccessibleRole::SHAPE
1513 || xContext
->getAccessibleRole() == AccessibleRole::TABLE_CELL
)
1515 anyCharUnderLine
<<= COL_BLACK
;
1519 Color
cr(xComponent
->getBackground());
1520 crCharUnderLine
= cr
.IsDark() ? COL_WHITE
: COL_BLACK
;
1521 anyCharUnderLine
<<= crCharUnderLine
;
1528 if (rRes
.Name
== "NumberingLevel")
1530 const SvxNumBulletItem
& rNumBullet
= rCacheTF
.GetParaAttribs(GetParagraphIndex()).Get(EE_PARA_NUMBULLET
);
1531 if(rNumBullet
.GetNumRule()->GetLevelCount()==0)
1533 rRes
.Value
<<= sal_Int16(-1);
1535 rRes
.State
= PropertyState_DIRECT_VALUE
;
1539 // SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
1540 // ImplGetSvxCharAndParaPropertiesMap() );
1541 // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap
1542 rtl::Reference
< SvxAccessibleTextPropertySet
> xPropSet( new SvxAccessibleTextPropertySet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() ) );
1544 xPropSet
->SetSelection( MakeSelection( 0, GetTextLen() ) );
1545 rRes
.Value
= xPropSet
->_getPropertyValue( rRes
.Name
, mnParagraphIndex
);
1546 rRes
.State
= xPropSet
->_getPropertyState( rRes
.Name
, mnParagraphIndex
);
1552 if (rRes
.Name
== "NumberingRules")
1554 SfxItemSet aAttribs
= rCacheTF
.GetParaAttribs(GetParagraphIndex());
1555 bool bVis
= aAttribs
.Get( EE_PARA_BULLETSTATE
).GetValue();
1558 rRes
.Value
<<= sal_Int16(-1);
1560 rRes
.State
= PropertyState_DIRECT_VALUE
;
1564 // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap
1565 rtl::Reference
< SvxAccessibleTextPropertySet
> xPropSet( new SvxAccessibleTextPropertySet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() ) );
1566 xPropSet
->SetSelection( MakeSelection( 0, GetTextLen() ) );
1567 rRes
.Value
= xPropSet
->_getPropertyValue( rRes
.Name
, mnParagraphIndex
);
1568 rRes
.State
= xPropSet
->_getPropertyState( rRes
.Name
, mnParagraphIndex
);
1575 sal_Int32
AccessibleEditableTextPara::SkipField(sal_Int32 nIndex
, bool bForward
)
1577 sal_Int32 nParaIndex
= GetParagraphIndex();
1578 SvxAccessibleTextAdapter
& rCacheTF
= GetTextForwarder();
1579 sal_Int32 nAllFieldLen
= 0;
1580 sal_Int32 nField
= rCacheTF
.GetFieldCount(nParaIndex
), nFoundFieldIndex
= -1;
1581 sal_Int32 reeBegin
=0, reeEnd
=0;
1582 for (sal_Int32 j
= 0; j
< nField
; ++j
)
1584 EFieldInfo ree
= rCacheTF
.GetFieldInfo(nParaIndex
, j
);
1585 reeBegin
= ree
.aPosition
.nIndex
+ nAllFieldLen
;
1586 reeEnd
= reeBegin
+ ree
.aCurrentText
.getLength();
1587 nAllFieldLen
+= (ree
.aCurrentText
.getLength() - 1);
1588 if (nIndex
< reeBegin
)
1590 if (!ree
.pFieldItem
)
1592 if (nIndex
< reeEnd
)
1594 if (ree
.pFieldItem
->GetField()->GetClassId() != text::textfield::Type::URL
)
1596 nFoundFieldIndex
= j
;
1601 if( nFoundFieldIndex
>= 0 )
1610 void AccessibleEditableTextPara::ExtendByField( css::accessibility::TextSegment
& Segment
)
1612 sal_Int32 nParaIndex
= GetParagraphIndex();
1613 SvxAccessibleTextAdapter
& rCacheTF
= GetTextForwarder();
1614 sal_Int32 nAllFieldLen
= 0;
1615 sal_Int32 nField
= rCacheTF
.GetFieldCount(nParaIndex
), nFoundFieldIndex
= -1;
1616 sal_Int32 reeBegin
=0, reeEnd
=0;
1617 for (sal_Int32 j
= 0; j
< nField
; ++j
)
1619 EFieldInfo ree
= rCacheTF
.GetFieldInfo(nParaIndex
, j
);
1620 reeBegin
= ree
.aPosition
.nIndex
+ nAllFieldLen
;
1621 reeEnd
= reeBegin
+ ree
.aCurrentText
.getLength();
1622 nAllFieldLen
+= (ree
.aCurrentText
.getLength() - 1);
1623 if( reeBegin
> Segment
.SegmentEnd
)
1627 if (!ree
.pFieldItem
)
1629 if( (Segment
.SegmentEnd
> reeBegin
&& Segment
.SegmentEnd
<= reeEnd
) ||
1630 (Segment
.SegmentStart
>= reeBegin
&& Segment
.SegmentStart
< reeEnd
) )
1632 if(ree
.pFieldItem
->GetField()->GetClassId() != text::textfield::Type::URL
)
1634 nFoundFieldIndex
= j
;
1639 if( nFoundFieldIndex
>= 0 )
1641 bool bExtend
= false;
1642 if( Segment
.SegmentEnd
< reeEnd
)
1644 Segment
.SegmentEnd
= reeEnd
;
1647 if( Segment
.SegmentStart
> reeBegin
)
1649 Segment
.SegmentStart
= reeBegin
;
1654 //If there is a bullet before the field, should add the bullet length into the segment.
1655 EBulletInfo aBulletInfo
= rCacheTF
.GetBulletInfo(nParaIndex
);
1656 sal_Int32 nBulletLen
= aBulletInfo
.aText
.getLength();
1659 Segment
.SegmentEnd
+= nBulletLen
;
1660 if (nFoundFieldIndex
> 0)
1661 Segment
.SegmentStart
+= nBulletLen
;
1662 Segment
.SegmentText
= GetTextRange(Segment
.SegmentStart
, Segment
.SegmentEnd
);
1663 //After get the correct field name, should restore the offset value which don't contain the bullet.
1664 Segment
.SegmentEnd
-= nBulletLen
;
1665 if (nFoundFieldIndex
> 0)
1666 Segment
.SegmentStart
-= nBulletLen
;
1669 Segment
.SegmentText
= GetTextRange(Segment
.SegmentStart
, Segment
.SegmentEnd
);
1674 css::accessibility::TextSegment SAL_CALL
AccessibleEditableTextPara::getTextAtIndex( sal_Int32 nIndex
, sal_Int16 aTextType
)
1676 SolarMutexGuard aGuard
;
1678 DBG_ASSERT(GetParagraphIndex() >= 0,
1679 "AccessibleEditableTextPara::getTextAtIndex: paragraph index value overflow");
1681 css::accessibility::TextSegment aResult
;
1682 aResult
.SegmentStart
= -1;
1683 aResult
.SegmentEnd
= -1;
1687 case AccessibleTextType::CHARACTER
:
1688 case AccessibleTextType::WORD
:
1690 aResult
= OCommonAccessibleText::getTextAtIndex( nIndex
, aTextType
);
1691 ExtendByField( aResult
);
1694 // Not yet handled by OCommonAccessibleText. Missing
1695 // implGetAttributeRunBoundary() method there
1696 case AccessibleTextType::ATTRIBUTE_RUN
:
1698 const sal_Int32 nTextLen
= GetTextForwarder().GetTextLen( GetParagraphIndex() );
1700 if( nIndex
== nTextLen
)
1702 // #i17014# Special-casing one-behind-the-end character
1703 aResult
.SegmentStart
= aResult
.SegmentEnd
= nTextLen
;
1707 sal_Int32 nStartIndex
, nEndIndex
;
1708 //For the bullet paragraph, the bullet string is ignored for IAText::attributes() function.
1709 SvxTextForwarder
& rCacheTF
= GetTextForwarder();
1710 // MT IA2: Not used? sal_Int32 nBulletLen = 0;
1711 EBulletInfo aBulletInfo
= rCacheTF
.GetBulletInfo(GetParagraphIndex());
1712 if (aBulletInfo
.bVisible
)
1713 nIndex
+= aBulletInfo
.aText
.getLength();
1714 if (nIndex
!= 0 && nIndex
>= getCharacterCount())
1715 nIndex
= getCharacterCount()-1;
1716 CheckPosition(nIndex
);
1717 if( GetAttributeRun(nStartIndex
, nEndIndex
, nIndex
) )
1719 aResult
.SegmentText
= GetTextRange(nStartIndex
, nEndIndex
);
1720 if (aBulletInfo
.bVisible
)
1722 nStartIndex
-= aBulletInfo
.aText
.getLength();
1723 nEndIndex
-= aBulletInfo
.aText
.getLength();
1725 aResult
.SegmentStart
= nStartIndex
;
1726 aResult
.SegmentEnd
= nEndIndex
;
1731 case AccessibleTextType::LINE
:
1733 SvxTextForwarder
& rCacheTF
= GetTextForwarder();
1734 sal_Int32 nParaIndex
= GetParagraphIndex();
1735 CheckPosition(nIndex
);
1736 if (nIndex
!= 0 && nIndex
== getCharacterCount())
1738 sal_Int32 nLine
, nLineCount
=rCacheTF
.GetLineCount( nParaIndex
);
1739 sal_Int32 nCurIndex
;
1740 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
1741 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
1742 //by the IAText::attributes(). So here must do special support for bullet line.
1743 sal_Int32 nBulletLen
= 0;
1744 for( nLine
=0, nCurIndex
=0; nLine
<nLineCount
; ++nLine
)
1748 EBulletInfo aBulletInfo
= rCacheTF
.GetBulletInfo( nParaIndex
);
1749 if (aBulletInfo
.bVisible
)
1751 //in bullet or numbering;
1752 nBulletLen
= aBulletInfo
.aText
.getLength();
1755 sal_Int32 nLineLen
= rCacheTF
.GetLineLen(nParaIndex
, nLine
);
1757 nCurIndex
+= nLineLen
- nBulletLen
;
1759 nCurIndex
+= nLineLen
;
1760 if( nCurIndex
> nIndex
)
1764 aResult
.SegmentStart
= 0;
1765 aResult
.SegmentEnd
= nCurIndex
;
1766 aResult
.SegmentText
= GetTextRange( aResult
.SegmentStart
, aResult
.SegmentEnd
+ nBulletLen
);
1771 aResult
.SegmentStart
= nCurIndex
- nLineLen
;
1772 aResult
.SegmentEnd
= nCurIndex
;
1773 //aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd );
1774 aResult
.SegmentText
= GetTextRange( aResult
.SegmentStart
+ nBulletLen
, aResult
.SegmentEnd
+ nBulletLen
);
1782 aResult
= OCommonAccessibleText::getTextAtIndex( nIndex
, aTextType
);
1784 } /* end of switch( aTextType ) */
1789 css::accessibility::TextSegment SAL_CALL
AccessibleEditableTextPara::getTextBeforeIndex( sal_Int32 nIndex
, sal_Int16 aTextType
)
1791 SolarMutexGuard aGuard
;
1793 DBG_ASSERT(GetParagraphIndex() >= 0,
1794 "AccessibleEditableTextPara::getTextBeforeIndex: paragraph index value overflow");
1796 css::accessibility::TextSegment aResult
;
1797 aResult
.SegmentStart
= -1;
1798 aResult
.SegmentEnd
= -1;
1799 i18n::Boundary aBoundary
;
1802 // Not yet handled by OCommonAccessibleText. Missing
1803 // implGetAttributeRunBoundary() method there
1804 case AccessibleTextType::ATTRIBUTE_RUN
:
1806 const sal_Int32 nTextLen
= GetTextForwarder().GetTextLen( GetParagraphIndex() );
1807 sal_Int32 nStartIndex
, nEndIndex
;
1809 if( nIndex
== nTextLen
)
1811 // #i17014# Special-casing one-behind-the-end character
1813 GetAttributeRun(nStartIndex
, nEndIndex
, nIndex
-1) )
1815 aResult
.SegmentText
= GetTextRange(nStartIndex
, nEndIndex
);
1816 aResult
.SegmentStart
= nStartIndex
;
1817 aResult
.SegmentEnd
= nEndIndex
;
1822 if( GetAttributeRun(nStartIndex
, nEndIndex
, nIndex
) )
1824 // already at the left border? If not, query
1825 // one index further left
1826 if( nStartIndex
> 0 &&
1827 GetAttributeRun(nStartIndex
, nEndIndex
, nStartIndex
-1) )
1829 aResult
.SegmentText
= GetTextRange(nStartIndex
, nEndIndex
);
1830 aResult
.SegmentStart
= nStartIndex
;
1831 aResult
.SegmentEnd
= nEndIndex
;
1837 case AccessibleTextType::LINE
:
1839 SvxTextForwarder
& rCacheTF
= GetTextForwarder();
1840 sal_Int32 nParaIndex
= GetParagraphIndex();
1842 CheckPosition(nIndex
);
1844 sal_Int32 nLine
, nLineCount
=rCacheTF
.GetLineCount( nParaIndex
);
1845 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
1846 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
1847 //by the IAText::attributes(). So here must do special support for bullet line.
1848 sal_Int32 nCurIndex
=0, nLastIndex
=0, nCurLineLen
=0;
1849 sal_Int32 nLastLineLen
= 0, nBulletLen
= 0;
1850 // get the line before the line the index points into
1851 for( nLine
=0, nCurIndex
=0, nLastIndex
=0; nLine
<nLineCount
; ++nLine
)
1853 nLastIndex
= nCurIndex
;
1856 EBulletInfo aBulletInfo
= rCacheTF
.GetBulletInfo(nParaIndex
);
1857 if (aBulletInfo
.bVisible
)
1859 //in bullet or numbering;
1860 nBulletLen
= aBulletInfo
.aText
.getLength();
1864 nLastLineLen
= nCurLineLen
- nBulletLen
;
1866 nLastLineLen
= nCurLineLen
;
1867 nCurLineLen
= rCacheTF
.GetLineLen( nParaIndex
, nLine
);
1868 //nCurIndex += nCurLineLen;
1870 nCurIndex
+= nCurLineLen
- nBulletLen
;
1872 nCurIndex
+= nCurLineLen
;
1874 //if( nCurIndex > nIndex &&
1875 //nLastIndex > nCurLineLen )
1876 if (nCurIndex
> nIndex
)
1882 else if (nLine
== 1)
1884 aResult
.SegmentStart
= 0;
1885 aResult
.SegmentEnd
= nLastIndex
;
1886 aResult
.SegmentText
= GetTextRange( aResult
.SegmentStart
, aResult
.SegmentEnd
+ nBulletLen
);
1891 //aResult.SegmentStart = nLastIndex - nCurLineLen;
1892 aResult
.SegmentStart
= nLastIndex
- nLastLineLen
;
1893 aResult
.SegmentEnd
= nLastIndex
;
1894 aResult
.SegmentText
= GetTextRange( aResult
.SegmentStart
+ nBulletLen
, aResult
.SegmentEnd
+ nBulletLen
);
1902 case AccessibleTextType::WORD
:
1904 nIndex
= SkipField( nIndex
, false);
1905 OUString
sText( implGetText() );
1906 sal_Int32 nLength
= sText
.getLength();
1908 // get word at index
1909 implGetWordBoundary( sText
, aBoundary
, nIndex
);
1912 //sal_Int32 curWordStart = aBoundary.startPos;
1913 //sal_Int32 preWordStart = curWordStart;
1914 sal_Int32 curWordStart
, preWordStart
;
1915 if( aBoundary
.startPos
== -1 || aBoundary
.startPos
> nIndex
)
1916 curWordStart
= preWordStart
= nIndex
;
1918 curWordStart
= preWordStart
= aBoundary
.startPos
;
1920 // get previous word
1924 //while ( preWordStart > 0 && aBoundary.startPos == curWordStart)
1925 while ( (preWordStart
>= 0 && !bWord
) || ( aBoundary
.endPos
> curWordStart
) )
1928 bWord
= implGetWordBoundary( sText
, aBoundary
, preWordStart
);
1930 if ( bWord
&& implIsValidBoundary( aBoundary
, nLength
) )
1932 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
1933 aResult
.SegmentStart
= aBoundary
.startPos
;
1934 aResult
.SegmentEnd
= aBoundary
.endPos
;
1935 ExtendByField( aResult
);
1939 case AccessibleTextType::CHARACTER
:
1941 nIndex
= SkipField( nIndex
, false);
1942 aResult
= OCommonAccessibleText::getTextBeforeIndex( nIndex
, aTextType
);
1943 ExtendByField( aResult
);
1947 aResult
= OCommonAccessibleText::getTextBeforeIndex( nIndex
, aTextType
);
1949 } /* end of switch( aTextType ) */
1954 css::accessibility::TextSegment SAL_CALL
AccessibleEditableTextPara::getTextBehindIndex( sal_Int32 nIndex
, sal_Int16 aTextType
)
1956 SolarMutexGuard aGuard
;
1958 DBG_ASSERT(GetParagraphIndex() >= 0,
1959 "AccessibleEditableTextPara::getTextBehindIndex: paragraph index value overflow");
1961 css::accessibility::TextSegment aResult
;
1962 aResult
.SegmentStart
= -1;
1963 aResult
.SegmentEnd
= -1;
1964 i18n::Boundary aBoundary
;
1967 case AccessibleTextType::ATTRIBUTE_RUN
:
1969 sal_Int32 nStartIndex
, nEndIndex
;
1971 if( GetAttributeRun(nStartIndex
, nEndIndex
, nIndex
) )
1973 // already at the right border?
1974 if( nEndIndex
< GetTextLen() )
1976 if( GetAttributeRun(nStartIndex
, nEndIndex
, nEndIndex
) )
1978 aResult
.SegmentText
= GetTextRange(nStartIndex
, nEndIndex
);
1979 aResult
.SegmentStart
= nStartIndex
;
1980 aResult
.SegmentEnd
= nEndIndex
;
1987 case AccessibleTextType::LINE
:
1989 SvxTextForwarder
& rCacheTF
= GetTextForwarder();
1990 sal_Int32 nParaIndex
= GetParagraphIndex();
1992 CheckPosition(nIndex
);
1994 sal_Int32 nLine
, nLineCount
= rCacheTF
.GetLineCount( nParaIndex
);
1995 sal_Int32 nCurIndex
;
1996 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
1997 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
1998 //by the IAText::attributes(). So here must do special support for bullet line.
1999 sal_Int32 nBulletLen
= 0;
2000 // get the line after the line the index points into
2001 for( nLine
=0, nCurIndex
=0; nLine
<nLineCount
; ++nLine
)
2005 EBulletInfo aBulletInfo
= rCacheTF
.GetBulletInfo(nParaIndex
);
2006 if (aBulletInfo
.bVisible
)
2008 //in bullet or numbering;
2009 nBulletLen
= aBulletInfo
.aText
.getLength();
2012 sal_Int32 nLineLen
= rCacheTF
.GetLineLen( nParaIndex
, nLine
);
2015 nCurIndex
+= nLineLen
- nBulletLen
;
2017 nCurIndex
+= nLineLen
;
2019 if( nCurIndex
> nIndex
&&
2020 nLine
< nLineCount
-1 )
2022 aResult
.SegmentStart
= nCurIndex
;
2023 aResult
.SegmentEnd
= nCurIndex
+ rCacheTF
.GetLineLen( nParaIndex
, nLine
+1);
2024 aResult
.SegmentText
= GetTextRange( aResult
.SegmentStart
+ nBulletLen
, aResult
.SegmentEnd
+ nBulletLen
);
2031 case AccessibleTextType::WORD
:
2033 nIndex
= SkipField( nIndex
, true);
2034 OUString
sText( implGetText() );
2035 sal_Int32 nLength
= sText
.getLength();
2037 // get word at index
2038 bool bWord
= implGetWordBoundary( sText
, aBoundary
, nIndex
);
2040 // real current world
2041 sal_Int32 nextWord
= nIndex
;
2042 //if( nIndex >= aBoundary.startPos && nIndex <= aBoundary.endPos )
2043 if( nIndex
<= aBoundary
.endPos
)
2045 nextWord
= aBoundary
.endPos
;
2046 if (nextWord
< sText
.getLength() && sText
[nextWord
] == u
' ') nextWord
++;
2047 bWord
= implGetWordBoundary( sText
, aBoundary
, nextWord
);
2050 if ( bWord
&& implIsValidBoundary( aBoundary
, nLength
) )
2052 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
2053 aResult
.SegmentStart
= aBoundary
.startPos
;
2054 aResult
.SegmentEnd
= aBoundary
.endPos
;
2056 // If the end position of aBoundary is inside a field, extend the result to the end of the field
2058 ExtendByField( aResult
);
2063 case AccessibleTextType::CHARACTER
:
2065 nIndex
= SkipField( nIndex
, true);
2066 aResult
= OCommonAccessibleText::getTextBehindIndex( nIndex
, aTextType
);
2067 ExtendByField( aResult
);
2071 aResult
= OCommonAccessibleText::getTextBehindIndex( nIndex
, aTextType
);
2073 } /* end of switch( aTextType ) */
2078 sal_Bool SAL_CALL
AccessibleEditableTextPara::copyText( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
)
2080 SolarMutexGuard aGuard
;
2084 SvxEditViewForwarder
& rCacheVF
= GetEditViewForwarder( true );
2085 GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2089 DBG_ASSERT(GetParagraphIndex() >= 0,
2090 "AccessibleEditableTextPara::copyText: index value overflow");
2092 CheckRange(nStartIndex
, nEndIndex
);
2094 //Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2095 sal_Int32 nBulletLen
= 0;
2096 EBulletInfo aBulletInfo
= GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2097 if( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&& aBulletInfo
.bVisible
)
2098 nBulletLen
= aBulletInfo
.aText
.getLength();
2099 // save current selection
2100 ESelection aOldSelection
;
2102 rCacheVF
.GetSelection( aOldSelection
);
2103 //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2104 rCacheVF
.SetSelection( MakeSelection(nStartIndex
+ nBulletLen
, nEndIndex
+ nBulletLen
) );
2105 aRetVal
= rCacheVF
.Copy();
2106 rCacheVF
.SetSelection( aOldSelection
); // restore
2110 catch (const uno::RuntimeException
&)
2116 // XAccessibleEditableText
2117 sal_Bool SAL_CALL
AccessibleEditableTextPara::cutText( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
)
2120 SolarMutexGuard aGuard
;
2124 SvxEditViewForwarder
& rCacheVF
= GetEditViewForwarder( true );
2125 SvxAccessibleTextAdapter
& rCacheTF
= GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2127 DBG_ASSERT(GetParagraphIndex() >= 0,
2128 "AccessibleEditableTextPara::cutText: index value overflow");
2130 CheckRange(nStartIndex
, nEndIndex
);
2132 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2133 sal_Int32 nBulletLen
= 0;
2134 EBulletInfo aBulletInfo
= GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2135 if( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&& aBulletInfo
.bVisible
)
2136 nBulletLen
= aBulletInfo
.aText
.getLength();
2137 ESelection aSelection
= MakeSelection (nStartIndex
+ nBulletLen
, nEndIndex
+ nBulletLen
);
2138 //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2139 if( !rCacheTF
.IsEditable( aSelection
) )
2140 return false; // non-editable area selected
2142 // don't save selection, might become invalid after cut!
2143 //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2144 rCacheVF
.SetSelection( aSelection
);
2146 return rCacheVF
.Cut();
2148 catch (const uno::RuntimeException
&)
2154 sal_Bool SAL_CALL
AccessibleEditableTextPara::pasteText( sal_Int32 nIndex
)
2157 SolarMutexGuard aGuard
;
2161 SvxEditViewForwarder
& rCacheVF
= GetEditViewForwarder( true );
2162 SvxAccessibleTextAdapter
& rCacheTF
= GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2164 DBG_ASSERT(GetParagraphIndex() >= 0,
2165 "AccessibleEditableTextPara::pasteText: index value overflow");
2167 CheckPosition(nIndex
);
2169 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2170 sal_Int32 nBulletLen
= 0;
2171 EBulletInfo aBulletInfo
= GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2172 if( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&& aBulletInfo
.bVisible
)
2173 nBulletLen
= aBulletInfo
.aText
.getLength();
2174 if( !rCacheTF
.IsEditable( MakeSelection(nIndex
+ nBulletLen
) ) )
2175 return false; // non-editable area selected
2177 // #104400# set empty selection (=> cursor) to given index
2178 //rCacheVF.SetSelection( MakeCursor(nIndex) );
2179 rCacheVF
.SetSelection( MakeCursor(nIndex
+ nBulletLen
) );
2181 return rCacheVF
.Paste();
2183 catch (const uno::RuntimeException
&)
2189 sal_Bool SAL_CALL
AccessibleEditableTextPara::deleteText( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
)
2192 SolarMutexGuard aGuard
;
2196 // #102710# Request edit view when doing changes
2197 // AccessibleEmptyEditSource relies on this behaviour
2198 GetEditViewForwarder( true );
2199 SvxAccessibleTextAdapter
& rCacheTF
= GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2201 DBG_ASSERT(GetParagraphIndex() >= 0,
2202 "AccessibleEditableTextPara::deleteText: index value overflow");
2204 CheckRange(nStartIndex
, nEndIndex
);
2206 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2207 sal_Int32 nBulletLen
= 0;
2208 EBulletInfo aBulletInfo
= GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2209 if( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&& aBulletInfo
.bVisible
)
2210 nBulletLen
= aBulletInfo
.aText
.getLength();
2211 ESelection aSelection
= MakeSelection (nStartIndex
+ nBulletLen
, nEndIndex
+ nBulletLen
);
2213 //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2214 if( !rCacheTF
.IsEditable( aSelection
) )
2215 return false; // non-editable area selected
2217 //sal_Bool bRet = rCacheTF.Delete( MakeSelection(nStartIndex, nEndIndex) );
2218 bool bRet
= rCacheTF
.Delete( aSelection
);
2220 GetEditSource().UpdateData();
2224 catch (const uno::RuntimeException
&)
2230 sal_Bool SAL_CALL
AccessibleEditableTextPara::insertText( const OUString
& sText
, sal_Int32 nIndex
)
2233 SolarMutexGuard aGuard
;
2237 // #102710# Request edit view when doing changes
2238 // AccessibleEmptyEditSource relies on this behaviour
2239 GetEditViewForwarder( true );
2240 SvxAccessibleTextAdapter
& rCacheTF
= GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2242 DBG_ASSERT(GetParagraphIndex() >= 0,
2243 "AccessibleEditableTextPara::insertText: index value overflow");
2245 CheckPosition(nIndex
);
2247 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2248 sal_Int32 nBulletLen
= 0;
2249 EBulletInfo aBulletInfo
= GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2250 if( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&& aBulletInfo
.bVisible
)
2251 nBulletLen
= aBulletInfo
.aText
.getLength();
2253 if( !rCacheTF
.IsEditable( MakeSelection(nIndex
+ nBulletLen
) ) )
2254 return false; // non-editable area selected
2256 // #104400# insert given text at empty selection (=> cursor)
2257 bool bRet
= rCacheTF
.InsertText( sText
, MakeCursor(nIndex
+ nBulletLen
) );
2259 rCacheTF
.QuickFormatDoc();
2260 GetEditSource().UpdateData();
2264 catch (const uno::RuntimeException
&)
2270 sal_Bool SAL_CALL
AccessibleEditableTextPara::replaceText( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
, const OUString
& sReplacement
)
2273 SolarMutexGuard aGuard
;
2277 // #102710# Request edit view when doing changes
2278 // AccessibleEmptyEditSource relies on this behaviour
2279 GetEditViewForwarder( true );
2280 SvxAccessibleTextAdapter
& rCacheTF
= GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2282 DBG_ASSERT(GetParagraphIndex() >= 0,
2283 "AccessibleEditableTextPara::replaceText: index value overflow");
2285 CheckRange(nStartIndex
, nEndIndex
);
2287 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2288 sal_Int32 nBulletLen
= 0;
2289 EBulletInfo aBulletInfo
= GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2290 if( aBulletInfo
.nParagraph
!= EE_PARA_NOT_FOUND
&& aBulletInfo
.bVisible
)
2291 nBulletLen
= aBulletInfo
.aText
.getLength();
2292 ESelection aSelection
= MakeSelection (nStartIndex
+ nBulletLen
, nEndIndex
+ nBulletLen
);
2294 //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2295 if( !rCacheTF
.IsEditable( aSelection
) )
2296 return false; // non-editable area selected
2298 // insert given text into given range => replace
2299 //sal_Bool bRet = rCacheTF.InsertText( sReplacement, MakeSelection(nStartIndex, nEndIndex) );
2300 bool bRet
= rCacheTF
.InsertText( sReplacement
, aSelection
);
2302 rCacheTF
.QuickFormatDoc();
2303 GetEditSource().UpdateData();
2307 catch (const uno::RuntimeException
&)
2313 sal_Bool SAL_CALL
AccessibleEditableTextPara::setAttributes( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
, const uno::Sequence
< beans::PropertyValue
>& aAttributeSet
)
2316 SolarMutexGuard aGuard
;
2320 // #102710# Request edit view when doing changes
2321 // AccessibleEmptyEditSource relies on this behaviour
2322 GetEditViewForwarder( true );
2323 SvxAccessibleTextAdapter
& rCacheTF
= GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2324 sal_Int32 nPara
= GetParagraphIndex();
2326 DBG_ASSERT(GetParagraphIndex() >= 0,
2327 "AccessibleEditableTextPara::setAttributes: index value overflow");
2329 CheckRange(nStartIndex
, nEndIndex
);
2331 if( !rCacheTF
.IsEditable( MakeSelection(nStartIndex
, nEndIndex
) ) )
2332 return false; // non-editable area selected
2334 // do the indices span the whole paragraph? Then use the outliner map
2335 // TODO: hold it as a member?
2336 rtl::Reference
< SvxAccessibleTextPropertySet
> xPropSet( new SvxAccessibleTextPropertySet( &GetEditSource(),
2338 rCacheTF
.GetTextLen(nPara
) == nEndIndex
?
2339 ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() :
2340 ImplGetSvxTextPortionSvxPropertySet() ) );
2342 xPropSet
->SetSelection( MakeSelection(nStartIndex
, nEndIndex
) );
2344 // convert from PropertyValue to Any
2345 for(const beans::PropertyValue
& rProp
: aAttributeSet
)
2349 xPropSet
->setPropertyValue(rProp
.Name
, rProp
.Value
);
2351 catch (const uno::Exception
&)
2353 OSL_FAIL("AccessibleEditableTextPara::setAttributes exception in setPropertyValue");
2357 rCacheTF
.QuickFormatDoc();
2358 GetEditSource().UpdateData();
2362 catch (const uno::RuntimeException
&)
2368 sal_Bool SAL_CALL
AccessibleEditableTextPara::setText( const OUString
& sText
)
2371 SolarMutexGuard aGuard
;
2373 return replaceText(0, getCharacterCount(), sText
);
2376 // XAccessibleTextAttributes
2377 uno::Sequence
< beans::PropertyValue
> SAL_CALL
AccessibleEditableTextPara::getDefaultAttributes(
2378 const uno::Sequence
< OUString
>& rRequestedAttributes
)
2380 SolarMutexGuard aGuard
;
2384 DBG_ASSERT(GetParagraphIndex() >= 0,
2385 "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
2387 // get XPropertySetInfo for paragraph attributes and
2388 // character attributes that span all the paragraphs text.
2389 rtl::Reference
< SvxAccessibleTextPropertySet
> xPropSet( new SvxAccessibleTextPropertySet( &GetEditSource(),
2390 ImplGetSvxCharAndParaPropertiesSet() ) );
2391 xPropSet
->SetSelection( MakeSelection( 0, GetTextLen() ) );
2392 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo
= xPropSet
->getPropertySetInfo();
2393 if (!xPropSetInfo
.is())
2394 throw uno::RuntimeException("Cannot query XPropertySetInfo",
2395 uno::Reference
< uno::XInterface
>
2396 ( static_cast< XAccessible
* > (this) ) ); // disambiguate hierarchy
2398 // build sequence of available properties to check
2399 uno::Sequence
< beans::Property
> aProperties
;
2400 if (const sal_Int32 nLenReqAttr
= rRequestedAttributes
.getLength())
2402 aProperties
.realloc( nLenReqAttr
);
2403 beans::Property
*pProperties
= aProperties
.getArray();
2404 sal_Int32 nCurLen
= 0;
2405 for (const OUString
& rRequestedAttribute
: rRequestedAttributes
)
2407 beans::Property aProp
;
2410 aProp
= xPropSetInfo
->getPropertyByName( rRequestedAttribute
);
2412 catch (const beans::UnknownPropertyException
&)
2416 pProperties
[ nCurLen
++ ] = aProp
;
2418 aProperties
.realloc( nCurLen
);
2421 aProperties
= xPropSetInfo
->getProperties();
2423 // build resulting sequence
2424 uno::Sequence
< beans::PropertyValue
> aOutSequence( aProperties
.getLength() );
2425 beans::PropertyValue
* pOutSequence
= aOutSequence
.getArray();
2426 sal_Int32 nOutLen
= 0;
2427 for (const beans::Property
& rProperty
: std::as_const(aProperties
))
2429 // calling implementation functions:
2430 // _getPropertyState and _getPropertyValue (see below) to provide
2431 // the proper paragraph number when retrieving paragraph attributes
2432 PropertyState eState
= xPropSet
->_getPropertyState( rProperty
.Name
, mnParagraphIndex
);
2433 if ( eState
== PropertyState_AMBIGUOUS_VALUE
)
2435 OSL_FAIL( "ambiguous property value encountered" );
2438 //if (eState == PropertyState_DIRECT_VALUE)
2439 // per definition all paragraph properties and all character
2440 // properties spanning the whole paragraph should be returned
2441 // and declared as default value
2443 pOutSequence
->Name
= rProperty
.Name
;
2444 pOutSequence
->Handle
= rProperty
.Handle
;
2445 pOutSequence
->Value
= xPropSet
->_getPropertyValue( rProperty
.Name
, mnParagraphIndex
);
2446 pOutSequence
->State
= PropertyState_DEFAULT_VALUE
;
2452 aOutSequence
.realloc( nOutLen
);
2454 return aOutSequence
;
2458 uno::Sequence
< beans::PropertyValue
> SAL_CALL
AccessibleEditableTextPara::getRunAttributes(
2460 const uno::Sequence
< OUString
>& rRequestedAttributes
)
2463 SolarMutexGuard aGuard
;
2467 DBG_ASSERT(GetParagraphIndex() >= 0,
2468 "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
2470 if( getCharacterCount() > 0 )
2473 CheckPosition(nIndex
);
2475 rtl::Reference
< SvxAccessibleTextPropertySet
> xPropSet( new SvxAccessibleTextPropertySet( &GetEditSource(),
2476 ImplGetSvxCharAndParaPropertiesSet() ) );
2477 xPropSet
->SetSelection( MakeSelection( nIndex
) );
2478 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo
= xPropSet
->getPropertySetInfo();
2479 if (!xPropSetInfo
.is())
2480 throw uno::RuntimeException("Cannot query XPropertySetInfo",
2481 uno::Reference
< uno::XInterface
>
2482 ( static_cast< XAccessible
* > (this) ) ); // disambiguate hierarchy
2484 // build sequence of available properties to check
2485 uno::Sequence
< beans::Property
> aProperties
;
2486 if (const sal_Int32 nLenReqAttr
= rRequestedAttributes
.getLength())
2488 aProperties
.realloc( nLenReqAttr
);
2489 beans::Property
*pProperties
= aProperties
.getArray();
2490 sal_Int32 nCurLen
= 0;
2491 for (const OUString
& rRequestedAttribute
: rRequestedAttributes
)
2493 beans::Property aProp
;
2496 aProp
= xPropSetInfo
->getPropertyByName( rRequestedAttribute
);
2498 catch (const beans::UnknownPropertyException
&)
2502 pProperties
[ nCurLen
++ ] = aProp
;
2504 aProperties
.realloc( nCurLen
);
2507 aProperties
= xPropSetInfo
->getProperties();
2509 // build resulting sequence
2510 uno::Sequence
< beans::PropertyValue
> aOutSequence( aProperties
.getLength() );
2511 beans::PropertyValue
* pOutSequence
= aOutSequence
.getArray();
2512 sal_Int32 nOutLen
= 0;
2513 for (const beans::Property
& rProperty
: std::as_const(aProperties
))
2515 // calling 'regular' functions that will operate on the selection
2516 PropertyState eState
= xPropSet
->getPropertyState( rProperty
.Name
);
2517 if (eState
== PropertyState_DIRECT_VALUE
)
2519 pOutSequence
->Name
= rProperty
.Name
;
2520 pOutSequence
->Handle
= rProperty
.Handle
;
2521 pOutSequence
->Value
= xPropSet
->getPropertyValue( rProperty
.Name
);
2522 pOutSequence
->State
= eState
;
2528 aOutSequence
.realloc( nOutLen
);
2530 return aOutSequence
;
2533 // XAccessibleHypertext
2534 ::sal_Int32 SAL_CALL
AccessibleEditableTextPara::getHyperLinkCount( )
2536 SvxAccessibleTextAdapter
& rT
= GetTextForwarder();
2537 const sal_Int32 nPara
= GetParagraphIndex();
2539 sal_Int32 nHyperLinks
= 0;
2540 sal_Int32 nFields
= rT
.GetFieldCount( nPara
);
2541 for (sal_Int32 n
= 0; n
< nFields
; ++n
)
2543 EFieldInfo aField
= rT
.GetFieldInfo( nPara
, n
);
2544 if ( dynamic_cast<const SvxURLField
* >(aField
.pFieldItem
->GetField() ) != nullptr)
2550 css::uno::Reference
< css::accessibility::XAccessibleHyperlink
> SAL_CALL
AccessibleEditableTextPara::getHyperLink( ::sal_Int32 nLinkIndex
)
2552 css::uno::Reference
< css::accessibility::XAccessibleHyperlink
> xRef
;
2554 SvxAccessibleTextAdapter
& rT
= GetTextForwarder();
2555 const sal_Int32 nPara
= GetParagraphIndex();
2557 sal_Int32 nHyperLink
= 0;
2558 sal_Int32 nFields
= rT
.GetFieldCount( nPara
);
2559 for (sal_Int32 n
= 0; n
< nFields
; ++n
)
2561 EFieldInfo aField
= rT
.GetFieldInfo( nPara
, n
);
2562 if ( dynamic_cast<const SvxURLField
* >(aField
.pFieldItem
->GetField()) != nullptr )
2564 if ( nHyperLink
== nLinkIndex
)
2566 sal_Int32 nEEStart
= aField
.aPosition
.nIndex
;
2568 // Translate EE Index to accessible index
2569 sal_Int32 nStart
= rT
.CalcEditEngineIndex( nPara
, nEEStart
);
2570 sal_Int32 nEnd
= nStart
+ aField
.aCurrentText
.getLength();
2571 xRef
= new AccessibleHyperlink( rT
, new SvxFieldItem( *aField
.pFieldItem
), nStart
, nEnd
, aField
.aCurrentText
);
2581 ::sal_Int32 SAL_CALL
AccessibleEditableTextPara::getHyperLinkIndex( ::sal_Int32 nCharIndex
)
2583 const sal_Int32 nPara
= GetParagraphIndex();
2584 SvxAccessibleTextAdapter
& rT
= GetTextForwarder();
2586 const sal_Int32 nEEIndex
= rT
.CalcEditEngineIndex( nPara
, nCharIndex
);
2587 sal_Int32 nHLIndex
= -1; //i123620
2588 sal_Int32 nHyperLink
= 0;
2589 sal_Int32 nFields
= rT
.GetFieldCount( nPara
);
2590 for (sal_Int32 n
= 0; n
< nFields
; ++n
)
2592 EFieldInfo aField
= rT
.GetFieldInfo( nPara
, n
);
2593 if ( dynamic_cast<const SvxURLField
* >( aField
.pFieldItem
->GetField() ) != nullptr)
2595 if ( aField
.aPosition
.nIndex
== nEEIndex
)
2597 nHLIndex
= nHyperLink
;
2607 // XAccessibleMultiLineText
2608 sal_Int32 SAL_CALL
AccessibleEditableTextPara::getLineNumberAtIndex( sal_Int32 nIndex
)
2611 sal_Int32 nRes
= -1;
2612 sal_Int32 nPara
= GetParagraphIndex();
2614 SvxTextForwarder
&rCacheTF
= GetTextForwarder();
2615 const bool bValidPara
= 0 <= nPara
&& nPara
< rCacheTF
.GetParagraphCount();
2616 DBG_ASSERT( bValidPara
, "getLineNumberAtIndex: current paragraph index out of range" );
2619 // we explicitly allow for the index to point at the character right behind the text
2620 if (0 > nIndex
|| nIndex
> rCacheTF
.GetTextLen( nPara
))
2621 throw lang::IndexOutOfBoundsException();
2622 nRes
= rCacheTF
.GetLineNumberAtIndex( nPara
, nIndex
);
2627 // XAccessibleMultiLineText
2628 css::accessibility::TextSegment SAL_CALL
AccessibleEditableTextPara::getTextAtLineNumber( sal_Int32 nLineNo
)
2631 css::accessibility::TextSegment aResult
;
2632 sal_Int32 nPara
= GetParagraphIndex();
2633 SvxTextForwarder
&rCacheTF
= GetTextForwarder();
2634 const bool bValidPara
= 0 <= nPara
&& nPara
< rCacheTF
.GetParagraphCount();
2635 DBG_ASSERT( bValidPara
, "getTextAtLineNumber: current paragraph index out of range" );
2638 if (0 > nLineNo
|| nLineNo
>= rCacheTF
.GetLineCount( nPara
))
2639 throw lang::IndexOutOfBoundsException();
2640 sal_Int32 nStart
= 0, nEnd
= 0;
2641 rCacheTF
.GetLineBoundaries( nStart
, nEnd
, nPara
, nLineNo
);
2642 if (nStart
>= 0 && nEnd
>= 0)
2646 aResult
.SegmentText
= getTextRange( nStart
, nEnd
);
2647 aResult
.SegmentStart
= nStart
;
2648 aResult
.SegmentEnd
= nEnd
;
2650 catch (const lang::IndexOutOfBoundsException
&)
2652 // this is not the exception that should be raised in this function ...
2653 DBG_UNHANDLED_EXCEPTION("editeng");
2660 // XAccessibleMultiLineText
2661 css::accessibility::TextSegment SAL_CALL
AccessibleEditableTextPara::getTextAtLineWithCaret( )
2664 css::accessibility::TextSegment aResult
;
2667 aResult
= getTextAtLineNumber( getNumberOfLineWithCaret() );
2669 catch (const lang::IndexOutOfBoundsException
&)
2671 // this one needs to be caught since this interface does not allow for it.
2676 // XAccessibleMultiLineText
2677 sal_Int32 SAL_CALL
AccessibleEditableTextPara::getNumberOfLineWithCaret( )
2680 sal_Int32 nRes
= -1;
2683 nRes
= getLineNumberAtIndex( getCaretPosition() );
2685 catch (const lang::IndexOutOfBoundsException
&)
2687 // this one needs to be caught since this interface does not allow for it.
2694 OUString SAL_CALL
AccessibleEditableTextPara::getImplementationName()
2697 return "AccessibleEditableTextPara";
2700 sal_Bool SAL_CALL
AccessibleEditableTextPara::supportsService (const OUString
& sServiceName
)
2703 return cppu::supportsService(this, sServiceName
);
2706 uno::Sequence
< OUString
> SAL_CALL
AccessibleEditableTextPara::getSupportedServiceNames()
2708 // #105185# Using correct service now
2709 return { OUString("com.sun.star.text.AccessibleParagraphView") };
2712 } // end of namespace accessibility
2715 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */