tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / editeng / source / accessibility / AccessibleEditableTextPara.cxx
bloba5c4c3b3bdb37c45e714b6acdedaf23953844635
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 // Global header
24 #include <algorithm>
25 #include <utility>
26 #include <vcl/svapp.hxx>
27 #include <tools/debug.hxx>
28 #include <comphelper/diagnose_ex.hxx>
29 #include <sal/log.hxx>
30 #include <editeng/flditem.hxx>
31 #include <com/sun/star/uno/Any.hxx>
32 #include <com/sun/star/uno/Reference.hxx>
33 #include <com/sun/star/awt/Point.hpp>
34 #include <com/sun/star/awt/Rectangle.hpp>
35 #include <com/sun/star/container/XNameContainer.hpp>
36 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
37 #include <com/sun/star/i18n/Boundary.hpp>
38 #include <com/sun/star/accessibility/AccessibleRole.hpp>
39 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
40 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
41 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
42 #include <comphelper/accessibleeventnotifier.hxx>
43 #include <comphelper/sequenceashashmap.hxx>
44 #include <cppuhelper/supportsservice.hxx>
45 #include <unotools/accessiblerelationsethelper.hxx>
46 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
47 #include <vcl/unohelp.hxx>
48 #include <vcl/settings.hxx>
49 #include <i18nlangtag/languagetag.hxx>
51 #include <editeng/editeng.hxx>
52 #include <editeng/unoprnms.hxx>
53 #include <editeng/unoipset.hxx>
54 #include <editeng/outliner.hxx>
55 #include <editeng/unoedprx.hxx>
56 #include <editeng/unoedsrc.hxx>
57 #include <svl/eitem.hxx>
60 // Project-local header
63 #include <com/sun/star/beans/PropertyState.hpp>
65 #include <unopracc.hxx>
66 #include <editeng/AccessibleEditableTextPara.hxx>
67 #include "AccessibleHyperlink.hxx"
68 #include "AccessibleImageBullet.hxx"
70 #include <svtools/colorcfg.hxx>
71 #include <editeng/editrids.hrc>
72 #include <editeng/eerdll.hxx>
73 #include <editeng/numitem.hxx>
74 #include <memory>
76 using namespace ::com::sun::star;
77 using namespace ::com::sun::star::beans;
78 using namespace ::com::sun::star::accessibility;
81 // AccessibleEditableTextPara implementation
84 namespace accessibility
86 static const SvxItemPropertySet* ImplGetSvxCharAndParaPropertiesSet()
88 // PropertyMap for character and paragraph properties
89 static const SfxItemPropertyMapEntry aPropMap[] =
91 SVX_UNOEDIT_OUTLINER_PROPERTIES,
92 SVX_UNOEDIT_CHAR_PROPERTIES,
93 SVX_UNOEDIT_PARA_PROPERTIES,
94 SVX_UNOEDIT_NUMBERING_PROPERTY,
95 { u"TextUserDefinedAttributes"_ustr, EE_CHAR_XMLATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0},
96 { u"ParaUserDefinedAttributes"_ustr, EE_PARA_XMLATTRIBS, cppu::UnoType<css::container::XNameContainer>::get(), 0, 0},
98 static SvxItemPropertySet aPropSet( aPropMap, EditEngine::GetGlobalItemPool() );
99 return &aPropSet;
102 // #i27138# - add parameter <_pParaManager>
103 AccessibleEditableTextPara::AccessibleEditableTextPara(
104 uno::Reference< XAccessible > xParent,
105 const AccessibleParaManager* _pParaManager )
106 : mnParagraphIndex( 0 ),
107 mnIndexInParent( 0 ),
108 mpEditSource( nullptr ),
109 maEEOffset( 0, 0 ),
110 mxParent(std::move( xParent )),
111 // well, that's strictly (UNO) exception safe, though not
112 // really robust. We rely on the fact that this member is
113 // constructed last, and that the constructor body catches
114 // exceptions, thus no chance for exceptions once the Id is
115 // fetched. Nevertheless, normally should employ RAII here...
116 mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient()),
117 // #i27138#
118 mpParaManager( _pParaManager )
121 // Create the state set.
122 mnStateSet = 0;
124 // these are always on
125 mnStateSet |= AccessibleStateType::MULTI_LINE;
126 mnStateSet |= AccessibleStateType::FOCUSABLE;
127 mnStateSet |= AccessibleStateType::VISIBLE;
128 mnStateSet |= AccessibleStateType::SHOWING;
129 mnStateSet |= AccessibleStateType::ENABLED;
130 mnStateSet |= AccessibleStateType::SENSITIVE;
133 AccessibleEditableTextPara::~AccessibleEditableTextPara()
135 // sign off from event notifier
136 if( getNotifierClientId() != -1 )
140 ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() );
142 catch (const uno::Exception&)
148 OUString AccessibleEditableTextPara::implGetText()
150 return GetTextRange( 0, GetTextLen() );
153 css::lang::Locale AccessibleEditableTextPara::implGetLocale()
155 DBG_ASSERT(GetParagraphIndex() >= 0,
156 "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
158 // return locale of first character in the paragraph
159 return LanguageTag(GetTextForwarder().GetLanguage( GetParagraphIndex(), 0 )).getLocale();
162 void AccessibleEditableTextPara::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
164 sal_Int32 nStart, nEnd;
166 if( GetSelection( nStart, nEnd ) )
168 nStartIndex = nStart;
169 nEndIndex = nEnd;
171 else
173 // #102234# No exception, just set to 'invalid'
174 nStartIndex = -1;
175 nEndIndex = -1;
179 void AccessibleEditableTextPara::implGetParagraphBoundary( const OUString& rText, css::i18n::Boundary& rBoundary, sal_Int32 /*nIndex*/ )
181 SAL_INFO( "editeng", "AccessibleEditableTextPara::implGetParagraphBoundary: only a base implementation, ignoring the index" );
183 rBoundary.startPos = 0;
184 rBoundary.endPos = rText.getLength();
187 void AccessibleEditableTextPara::implGetLineBoundary( const OUString&, css::i18n::Boundary& rBoundary, sal_Int32 nIndex )
189 SvxTextForwarder& rCacheTF = GetTextForwarder();
190 const sal_Int32 nParaIndex = GetParagraphIndex();
192 DBG_ASSERT(nParaIndex >= 0,
193 "AccessibleEditableTextPara::implGetLineBoundary: paragraph index value overflow");
195 const sal_Int32 nTextLen = rCacheTF.GetTextLen( nParaIndex );
197 CheckPosition(nIndex);
199 rBoundary.startPos = rBoundary.endPos = -1;
201 const sal_Int32 nLineCount=rCacheTF.GetLineCount( nParaIndex );
203 if( nIndex == nTextLen )
205 // #i17014# Special-casing one-behind-the-end character
206 if( nLineCount <= 1 )
207 rBoundary.startPos = 0;
208 else
209 rBoundary.startPos = nTextLen - rCacheTF.GetLineLen( nParaIndex,
210 nLineCount-1 );
212 rBoundary.endPos = nTextLen;
214 else
216 // normal line search
217 sal_Int32 nLine;
218 sal_Int32 nCurIndex;
219 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
221 nCurIndex += rCacheTF.GetLineLen( nParaIndex, nLine);
223 if( nCurIndex > nIndex )
225 rBoundary.startPos = nCurIndex - rCacheTF.GetLineLen( nParaIndex, nLine);
226 rBoundary.endPos = nCurIndex;
227 break;
234 void AccessibleEditableTextPara::SetIndexInParent( sal_Int32 nIndex )
236 mnIndexInParent = nIndex;
240 void AccessibleEditableTextPara::SetParagraphIndex( sal_Int32 nIndex )
242 sal_Int32 nOldIndex = mnParagraphIndex;
244 mnParagraphIndex = nIndex;
246 auto aChild( maImageBullet.get() );
247 if( aChild.is() )
248 aChild->SetParagraphIndex(mnParagraphIndex);
252 if( nOldIndex != nIndex )
254 uno::Any aOldDesc;
255 uno::Any aOldName;
259 aOldDesc <<= getAccessibleDescription();
260 aOldName <<= getAccessibleName();
262 catch (const uno::Exception&) // optional behaviour
265 // index and therefore description changed
266 FireEvent( AccessibleEventId::DESCRIPTION_CHANGED, uno::Any( getAccessibleDescription() ), aOldDesc );
267 FireEvent( AccessibleEventId::NAME_CHANGED, uno::Any( getAccessibleName() ), aOldName );
270 catch (const uno::Exception&) // optional behaviour
276 void AccessibleEditableTextPara::Dispose()
278 int nClientId( getNotifierClientId() );
280 // #108212# drop all references before notifying dispose
281 mxParent = nullptr;
282 mnNotifierClientId = -1;
283 mpEditSource = nullptr;
285 // notify listeners
286 if( nClientId == -1 )
287 return;
291 uno::Reference < XAccessibleContext > xThis = getAccessibleContext();
293 // #106234# Delegate to EventNotifier
294 ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, xThis );
296 catch (const uno::Exception&)
301 void AccessibleEditableTextPara::SetEditSource( SvxEditSourceAdapter* pEditSource )
303 auto aChild( maImageBullet.get() );
304 if( aChild.is() )
305 aChild->SetEditSource(pEditSource);
307 if( !pEditSource )
309 // going defunc
310 UnSetState( AccessibleStateType::SHOWING );
311 UnSetState( AccessibleStateType::VISIBLE );
312 SetState( AccessibleStateType::INVALID );
313 SetState( AccessibleStateType::DEFUNC );
315 Dispose();
317 mpEditSource = pEditSource;
318 // #108900# Init last text content
321 TextChanged();
323 catch (const uno::RuntimeException&)
328 ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex )
330 // check overflow
331 DBG_ASSERT(nStartEEIndex >= 0 &&
332 nEndEEIndex >= 0 &&
333 GetParagraphIndex() >= 0,
334 "AccessibleEditableTextPara::MakeSelection: index value overflow");
336 sal_Int32 nParaIndex = GetParagraphIndex();
337 return ESelection(nParaIndex, nStartEEIndex, nParaIndex, nEndEEIndex);
340 ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nEEIndex )
342 return MakeSelection( nEEIndex, nEEIndex+1 );
345 ESelection AccessibleEditableTextPara::MakeCursor( sal_Int32 nEEIndex )
347 return MakeSelection( nEEIndex, nEEIndex );
350 void AccessibleEditableTextPara::CheckIndex( sal_Int32 nIndex )
352 if( nIndex < 0 || nIndex >= getCharacterCount() )
353 throw lang::IndexOutOfBoundsException(u"AccessibleEditableTextPara: character index out of bounds"_ustr,
354 getXWeak() );
357 void AccessibleEditableTextPara::CheckPosition( sal_Int32 nIndex )
359 if( nIndex < 0 || nIndex > getCharacterCount() )
360 throw lang::IndexOutOfBoundsException(u"AccessibleEditableTextPara: character position out of bounds"_ustr,
361 getXWeak() );
364 void AccessibleEditableTextPara::CheckRange( sal_Int32 nStart, sal_Int32 nEnd )
366 CheckPosition( nStart );
367 CheckPosition( nEnd );
370 bool AccessibleEditableTextPara::GetSelection(sal_Int32 &nStartPos, sal_Int32 &nEndPos)
372 ESelection aSelection;
373 sal_Int32 nPara = GetParagraphIndex();
374 if( !GetEditViewForwarder().GetSelection( aSelection ) )
375 return false;
377 if( aSelection.start.nPara < aSelection.end.nPara )
379 if( aSelection.start.nPara > nPara ||
380 aSelection.end.nPara < nPara )
381 return false;
383 if( nPara == aSelection.start.nPara )
384 nStartPos = aSelection.start.nIndex;
385 else
386 nStartPos = 0;
388 if( nPara == aSelection.end.nPara )
389 nEndPos = aSelection.end.nIndex;
390 else
391 nEndPos = GetTextLen();
393 else
395 if( aSelection.start.nPara < nPara ||
396 aSelection.end.nPara > nPara )
397 return false;
399 if( nPara == aSelection.start.nPara )
400 nStartPos = aSelection.start.nIndex;
401 else
402 nStartPos = GetTextLen();
404 if( nPara == aSelection.end.nPara )
405 nEndPos = aSelection.end.nIndex;
406 else
407 nEndPos = 0;
410 return true;
413 OUString AccessibleEditableTextPara::GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
415 return GetTextForwarder().GetText( MakeSelection(nStartIndex, nEndIndex) );
418 sal_Int32 AccessibleEditableTextPara::GetTextLen() const
420 return GetTextForwarder().GetTextLen(GetParagraphIndex());
423 SvxEditSourceAdapter& AccessibleEditableTextPara::GetEditSource() const
425 if( !mpEditSource )
426 throw uno::RuntimeException(u"No edit source, object is defunct"_ustr,
427 const_cast< AccessibleEditableTextPara* > (this)->getXWeak() );
428 return *mpEditSource;
431 SvxAccessibleTextAdapter& AccessibleEditableTextPara::GetTextForwarder() const
433 SvxEditSourceAdapter& rEditSource = GetEditSource();
434 SvxAccessibleTextAdapter* pTextForwarder = rEditSource.GetTextForwarderAdapter();
436 if( !pTextForwarder )
437 throw uno::RuntimeException(u"Unable to fetch text forwarder, object is defunct"_ustr,
438 const_cast< AccessibleEditableTextPara* > (this)->getXWeak() );
440 if( !pTextForwarder->IsValid() )
441 throw uno::RuntimeException(u"Text forwarder is invalid, object is defunct"_ustr,
442 const_cast< AccessibleEditableTextPara* > (this)->getXWeak() );
443 return *pTextForwarder;
446 SvxViewForwarder& AccessibleEditableTextPara::GetViewForwarder() const
448 SvxEditSource& rEditSource = GetEditSource();
449 SvxViewForwarder* pViewForwarder = rEditSource.GetViewForwarder();
451 if( !pViewForwarder )
453 throw uno::RuntimeException(u"Unable to fetch view forwarder, object is defunct"_ustr,
454 const_cast< AccessibleEditableTextPara* > (this)->getXWeak() );
457 if( !pViewForwarder->IsValid() )
458 throw uno::RuntimeException(u"View forwarder is invalid, object is defunct"_ustr,
459 const_cast< AccessibleEditableTextPara* > (this)->getXWeak() );
460 return *pViewForwarder;
463 SvxAccessibleTextEditViewAdapter& AccessibleEditableTextPara::GetEditViewForwarder( bool bCreate ) const
465 SvxEditSourceAdapter& rEditSource = GetEditSource();
466 SvxAccessibleTextEditViewAdapter* pTextEditViewForwarder = rEditSource.GetEditViewForwarderAdapter( bCreate );
468 if( !pTextEditViewForwarder )
470 if( bCreate )
471 throw uno::RuntimeException(u"Unable to fetch view forwarder, object is defunct"_ustr,
472 const_cast< AccessibleEditableTextPara* > (this)->getXWeak() );
473 else
474 throw uno::RuntimeException(u"No view forwarder, object not in edit mode"_ustr,
475 const_cast< AccessibleEditableTextPara* > (this)->getXWeak() );
478 if( pTextEditViewForwarder->IsValid() )
479 return *pTextEditViewForwarder;
480 else
482 if( bCreate )
483 throw uno::RuntimeException(u"View forwarder is invalid, object is defunct"_ustr,
484 const_cast< AccessibleEditableTextPara* > (this)->getXWeak() );
485 else
486 throw uno::RuntimeException(u"View forwarder is invalid, object not in edit mode"_ustr,
487 const_cast< AccessibleEditableTextPara* > (this)->getXWeak() );
491 bool AccessibleEditableTextPara::HaveEditView() const
493 SvxEditSource& rEditSource = GetEditSource();
494 SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder();
496 if( !pViewForwarder )
497 return false;
499 if( !pViewForwarder->IsValid() )
500 return false;
502 return true;
505 bool AccessibleEditableTextPara::HaveChildren()
507 DBG_ASSERT(GetParagraphIndex() >= 0,
508 "AccessibleEditableTextPara::HaveChildren: paragraph index value overflow");
510 return GetTextForwarder().HaveImageBullet( GetParagraphIndex() );
513 tools::Rectangle AccessibleEditableTextPara::LogicToPixel( const tools::Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder const & rForwarder )
515 // convert to screen coordinates
516 return tools::Rectangle( rForwarder.LogicToPixel( rRect.TopLeft(), rMapMode ),
517 rForwarder.LogicToPixel( rRect.BottomRight(), rMapMode ) );
521 void AccessibleEditableTextPara::SetEEOffset( const Point& rOffset )
523 auto aChild( maImageBullet.get() );
524 if( aChild.is() )
525 aChild->SetEEOffset(rOffset);
527 maEEOffset = rOffset;
530 void AccessibleEditableTextPara::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue) const
532 uno::Reference < XAccessibleContext > xThis( const_cast< AccessibleEditableTextPara* > (this)->getAccessibleContext() );
534 AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue, -1);
536 // #106234# Delegate to EventNotifier
537 if( getNotifierClientId() != -1 )
538 ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(),
539 aEvent );
542 void AccessibleEditableTextPara::SetState( const sal_Int64 nStateId )
544 if( !(mnStateSet & nStateId) )
546 mnStateSet |= nStateId;
547 FireEvent( AccessibleEventId::STATE_CHANGED, uno::Any( nStateId ) );
551 void AccessibleEditableTextPara::UnSetState( const sal_Int64 nStateId )
553 if( mnStateSet & nStateId )
555 mnStateSet &= ~nStateId;
556 FireEvent( AccessibleEventId::STATE_CHANGED, uno::Any(), uno::Any( nStateId ) );
560 void AccessibleEditableTextPara::TextChanged()
562 OUString aCurrentString( implGetText() );
563 uno::Any aDeleted;
564 uno::Any aInserted;
565 if( OCommonAccessibleText::implInitTextChangedEvent( maLastTextString, aCurrentString,
566 aDeleted, aInserted) )
568 FireEvent( AccessibleEventId::TEXT_CHANGED, aInserted, aDeleted );
569 maLastTextString = aCurrentString;
573 bool AccessibleEditableTextPara::GetAttributeRun( sal_Int32& nStartIndex, sal_Int32& nEndIndex, sal_Int32 nIndex )
575 DBG_ASSERT(nIndex >= 0,
576 "AccessibleEditableTextPara::GetAttributeRun: index value overflow");
578 DBG_ASSERT(GetParagraphIndex() >= 0,
579 "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
581 return GetTextForwarder().GetAttributeRun( nStartIndex,
582 nEndIndex,
583 GetParagraphIndex(),
584 nIndex );
587 uno::Any SAL_CALL AccessibleEditableTextPara::queryInterface (const uno::Type & rType)
589 uno::Any aRet;
591 // must provide XAccessibleText by hand, since it comes publicly inherited by XAccessibleEditableText
592 if ( rType == cppu::UnoType<XAccessibleText>::get())
594 uno::Reference< XAccessibleText > aAccText = static_cast< XAccessibleEditableText * >(this);
595 aRet <<= aAccText;
597 else if ( rType == cppu::UnoType<XAccessibleEditableText>::get())
599 uno::Reference< XAccessibleEditableText > aAccEditText = this;
600 aRet <<= aAccEditText;
602 else if ( rType == cppu::UnoType<XAccessibleHypertext>::get())
604 uno::Reference< XAccessibleHypertext > aAccHyperText = this;
605 aRet <<= aAccHyperText;
607 else
609 aRet = AccessibleTextParaInterfaceBase::queryInterface(rType);
612 return aRet;
615 // XAccessible
616 uno::Reference< XAccessibleContext > SAL_CALL AccessibleEditableTextPara::getAccessibleContext()
618 // We implement the XAccessibleContext interface in the same object
619 return uno::Reference< XAccessibleContext > ( this );
622 // XAccessibleContext
623 sal_Int64 SAL_CALL AccessibleEditableTextPara::getAccessibleChildCount()
625 SolarMutexGuard aGuard;
627 return HaveChildren() ? 1 : 0;
630 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleChild( sal_Int64 i )
632 SolarMutexGuard aGuard;
634 if( !HaveChildren() )
635 throw lang::IndexOutOfBoundsException(u"No children available"_ustr,
636 getXWeak() );
638 if( i != 0 )
639 throw lang::IndexOutOfBoundsException(u"Invalid child index"_ustr,
640 getXWeak() );
642 auto aChild( maImageBullet.get() );
644 if( !aChild.is() )
646 // there is no hard reference available, create object then
647 aChild = new AccessibleImageBullet(this);
649 aChild->SetEditSource( &GetEditSource() );
650 aChild->SetParagraphIndex( GetParagraphIndex() );
651 aChild->SetIndexInParent( i );
653 maImageBullet = aChild;
656 return aChild;
659 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleParent()
661 SAL_WARN_IF(!mxParent.is(), "editeng", "AccessibleEditableTextPara::getAccessibleParent: no frontend set, did somebody forgot to call AccessibleTextHelper::SetEventSource()?");
663 return mxParent;
666 sal_Int64 SAL_CALL AccessibleEditableTextPara::getAccessibleIndexInParent()
668 return mnIndexInParent;
671 sal_Int16 SAL_CALL AccessibleEditableTextPara::getAccessibleRole()
673 return AccessibleRole::PARAGRAPH;
676 OUString SAL_CALL AccessibleEditableTextPara::getAccessibleDescription()
678 SolarMutexGuard aGuard;
680 // append first 40 characters from text, or first line, if shorter
681 // (writer takes first sentence here, but that's not supported
682 // from EditEngine)
683 // throws if defunc
684 OUString aLine;
686 if( getCharacterCount() )
687 aLine = getTextAtIndex(0, AccessibleTextType::LINE).SegmentText;
689 // Get the string from the resource for the specified id.
690 OUString sStr(EditResId(RID_SVXSTR_A11Y_PARAGRAPH_DESCRIPTION));
691 OUString sParaIndex = OUString::number(GetParagraphIndex());
692 sStr = sStr.replaceFirst("$(ARG)", sParaIndex);
694 if( aLine.getLength() > MaxDescriptionLen )
696 OUString aCurrWord;
697 sal_Int32 i;
699 // search backward from MaxDescriptionLen for previous word start
700 for( aCurrWord=getTextAtIndex(MaxDescriptionLen, AccessibleTextType::WORD).SegmentText,
701 i=MaxDescriptionLen,
702 aLine=OUString();
703 i>=0;
704 --i )
706 if( getTextAtIndex(i, AccessibleTextType::WORD).SegmentText != aCurrWord )
708 if( i == 0 )
709 // prevent completely empty string
710 aLine = getTextAtIndex(0, AccessibleTextType::WORD).SegmentText;
711 else
712 aLine = getTextRange(0, i);
717 return sStr + aLine;
720 OUString SAL_CALL AccessibleEditableTextPara::getAccessibleName()
722 //See tdf#101003 before implementing a body
723 return OUString();
726 uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleEditableTextPara::getAccessibleRelationSet()
728 // #i27138# - provide relations CONTENT_FLOWS_FROM
729 // and CONTENT_FLOWS_TO
730 if ( mpParaManager )
732 rtl::Reference<utl::AccessibleRelationSetHelper> pAccRelSetHelper =
733 new utl::AccessibleRelationSetHelper();
734 sal_Int32 nMyParaIndex( GetParagraphIndex() );
735 // relation CONTENT_FLOWS_FROM
736 if ( nMyParaIndex > 0 &&
737 mpParaManager->IsReferencable( nMyParaIndex - 1 ) )
739 uno::Sequence<uno::Reference<XAccessible>> aSequence
740 { mpParaManager->GetChild( nMyParaIndex - 1 ).first.get() };
741 AccessibleRelation aAccRel(AccessibleRelationType_CONTENT_FLOWS_FROM,
742 aSequence );
743 pAccRelSetHelper->AddRelation( aAccRel );
746 // relation CONTENT_FLOWS_TO
747 if ( (nMyParaIndex + 1) < mpParaManager->GetNum() &&
748 mpParaManager->IsReferencable( nMyParaIndex + 1 ) )
750 uno::Sequence<uno::Reference<XAccessible>> aSequence
751 { mpParaManager->GetChild( nMyParaIndex + 1 ).first.get() };
752 AccessibleRelation aAccRel(AccessibleRelationType_CONTENT_FLOWS_TO,
753 aSequence );
754 pAccRelSetHelper->AddRelation( aAccRel );
757 return pAccRelSetHelper;
759 else
761 // no relations, therefore empty
762 return uno::Reference< XAccessibleRelationSet >();
766 static uno::Sequence< OUString > const & getAttributeNames()
768 static const uno::Sequence<OUString> aNames{
769 u"CharColor"_ustr,
770 u"CharContoured"_ustr,
771 u"CharEmphasis"_ustr,
772 u"CharEscapement"_ustr,
773 u"CharFontName"_ustr,
774 u"CharHeight"_ustr,
775 u"CharPosture"_ustr,
776 u"CharShadowed"_ustr,
777 u"CharStrikeout"_ustr,
778 u"CharCaseMap"_ustr,
779 u"CharUnderline"_ustr,
780 u"CharUnderlineColor"_ustr,
781 u"CharWeight"_ustr,
782 u"NumberingLevel"_ustr,
783 u"NumberingRules"_ustr,
784 u"ParaAdjust"_ustr,
785 u"ParaBottomMargin"_ustr,
786 u"ParaFirstLineIndent"_ustr,
787 u"ParaLeftMargin"_ustr,
788 u"ParaLineSpacing"_ustr,
789 u"ParaRightMargin"_ustr,
790 u"ParaTabStops"_ustr};
792 return aNames;
795 namespace {
797 struct IndexCompare
799 const uno::Sequence<beans::PropertyValue>& m_rValues;
800 explicit IndexCompare(const uno::Sequence<beans::PropertyValue>& rValues)
801 : m_rValues(rValues)
804 bool operator() ( sal_Int32 a, sal_Int32 b ) const
806 return m_rValues[a].Name < m_rValues[b].Name;
813 namespace
815 OUString GetFieldTypeNameFromField(EFieldInfo const &ree)
817 OUString strFldType;
818 sal_Int32 nFieldType = -1;
819 if (ree.pFieldItem)
821 // So we get a field, check its type now.
822 nFieldType = ree.pFieldItem->GetField()->GetClassId() ;
824 switch (nFieldType)
826 case text::textfield::Type::DATE:
828 const SvxDateField* pDateField = static_cast< const SvxDateField* >(ree.pFieldItem->GetField());
829 if (pDateField)
831 if (pDateField->GetType() == SvxDateType::Fix)
832 strFldType = "date (fixed)";
833 else if (pDateField->GetType() == SvxDateType::Var)
834 strFldType = "date (variable)";
836 break;
838 case text::textfield::Type::PAGE:
839 strFldType = "page-number";
840 break;
841 //support the sheet name & pages fields
842 case text::textfield::Type::PAGES:
843 strFldType = "page-count";
844 break;
845 case text::textfield::Type::TABLE:
846 strFldType = "sheet-name";
847 break;
848 //End
849 case text::textfield::Type::TIME:
850 strFldType = "time";
851 break;
852 case text::textfield::Type::EXTENDED_TIME:
854 const SvxExtTimeField* pTimeField = static_cast< const SvxExtTimeField* >(ree.pFieldItem->GetField());
855 if (pTimeField)
857 if (pTimeField->GetType() == SvxTimeType::Fix)
858 strFldType = "time (fixed)";
859 else if (pTimeField->GetType() == SvxTimeType::Var)
860 strFldType = "time (variable)";
862 break;
864 case text::textfield::Type::AUTHOR:
865 strFldType = "author";
866 break;
867 case text::textfield::Type::EXTENDED_FILE:
868 case text::textfield::Type::DOCINFO_TITLE:
869 strFldType = "file name";
870 break;
871 case text::textfield::Type::DOCINFO_CUSTOM:
872 strFldType = "custom document property";
873 break;
874 default:
875 break;
877 return strFldType;
881 namespace accessibility
883 OUString AccessibleEditableTextPara::GetFieldTypeNameAtIndex(sal_Int32 nIndex)
885 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();
886 //For field object info
887 sal_Int32 nParaIndex = GetParagraphIndex();
888 sal_Int32 nAllFieldLen = 0;
889 std::vector<EFieldInfo> aFieldInfos = rCacheTF.GetFieldInfo(nParaIndex);
890 for (const EFieldInfo& ree : aFieldInfos)
892 sal_Int32 reeBegin = ree.aPosition.nIndex + nAllFieldLen;
893 sal_Int32 reeEnd = reeBegin + ree.aCurrentText.getLength();
894 nAllFieldLen += (ree.aCurrentText.getLength() - 1);
895 if (nIndex < reeBegin)
896 break;
897 if (nIndex < reeEnd)
898 return GetFieldTypeNameFromField(ree);
900 return OUString();
903 sal_Int64 SAL_CALL AccessibleEditableTextPara::getAccessibleStateSet()
905 SolarMutexGuard aGuard;
907 // Create a copy of the state set and return it.
909 sal_Int64 nParentStates = 0;
910 if (getAccessibleParent().is())
912 uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
913 nParentStates = xParentContext->getAccessibleStateSet();
915 if (nParentStates & AccessibleStateType::EDITABLE)
917 mnStateSet |= AccessibleStateType::EDITABLE;
919 return mnStateSet;
922 lang::Locale SAL_CALL AccessibleEditableTextPara::getLocale()
924 SolarMutexGuard aGuard;
926 return implGetLocale();
929 void SAL_CALL AccessibleEditableTextPara::addAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
931 if( getNotifierClientId() != -1 )
932 ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener );
935 void SAL_CALL AccessibleEditableTextPara::removeAccessibleEventListener( const uno::Reference< XAccessibleEventListener >& xListener )
937 if( getNotifierClientId() == -1 )
938 return;
940 const sal_Int32 nListenerCount = ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener );
941 if ( !nListenerCount )
943 // no listeners anymore
944 // -> revoke ourself. This may lead to the notifier thread dying (if we were the last client),
945 // and at least to us not firing any events anymore, in case somebody calls
946 // NotifyAccessibleEvent, again
947 ::comphelper::AccessibleEventNotifier::TClientId nId( getNotifierClientId() );
948 mnNotifierClientId = -1;
949 ::comphelper::AccessibleEventNotifier::revokeClient( nId );
953 // XAccessibleComponent
954 sal_Bool SAL_CALL AccessibleEditableTextPara::containsPoint( const awt::Point& aTmpPoint )
956 SolarMutexGuard aGuard;
958 DBG_ASSERT(GetParagraphIndex() >= 0,
959 "AccessibleEditableTextPara::contains: index value overflow");
961 awt::Rectangle aTmpRect = getBounds();
962 tools::Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) );
963 Point aPoint( aTmpPoint.X, aTmpPoint.Y );
965 return aRect.Contains( aPoint );
968 uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleAtPoint( const awt::Point& _aPoint )
970 SolarMutexGuard aGuard;
972 if( HaveChildren() )
974 // #103862# No longer need to make given position relative
975 Point aPoint( _aPoint.X, _aPoint.Y );
977 // respect EditEngine offset to surrounding shape/cell
978 aPoint -= GetEEOffset();
980 // convert to EditEngine coordinate system
981 SvxTextForwarder& rCacheTF = GetTextForwarder();
982 Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
984 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(GetParagraphIndex());
986 if( aBulletInfo.nParagraph != EE_PARA_MAX &&
987 aBulletInfo.bVisible &&
988 aBulletInfo.nType == SVX_NUM_BITMAP )
990 tools::Rectangle aRect = aBulletInfo.aBounds;
992 if( aRect.Contains( aLogPoint ) )
993 return getAccessibleChild(0);
997 // no children at all, or none at given position
998 return uno::Reference< XAccessible >();
1001 awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds()
1003 SolarMutexGuard aGuard;
1005 DBG_ASSERT(GetParagraphIndex() >= 0,
1006 "AccessibleEditableTextPara::getBounds: index value overflow");
1008 SvxTextForwarder& rCacheTF = GetTextForwarder();
1009 tools::Rectangle aRect = rCacheTF.GetParaBounds( GetParagraphIndex() );
1011 // convert to screen coordinates
1012 tools::Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect,
1013 rCacheTF.GetMapMode(),
1014 GetViewForwarder() );
1016 // offset from shape/cell
1017 Point aOffset = GetEEOffset();
1019 return awt::Rectangle( aScreenRect.Left() + aOffset.X(),
1020 aScreenRect.Top() + aOffset.Y(),
1021 aScreenRect.GetSize().Width(),
1022 aScreenRect.GetSize().Height() );
1025 awt::Point SAL_CALL AccessibleEditableTextPara::getLocation( )
1027 SolarMutexGuard aGuard;
1029 awt::Rectangle aRect = getBounds();
1031 return awt::Point( aRect.X, aRect.Y );
1034 awt::Point SAL_CALL AccessibleEditableTextPara::getLocationOnScreen( )
1036 SolarMutexGuard aGuard;
1038 // relate us to parent
1039 uno::Reference< XAccessible > xParent = getAccessibleParent();
1040 if( xParent.is() )
1042 uno::Reference< XAccessibleComponent > xParentComponent( xParent, uno::UNO_QUERY );
1043 if( xParentComponent.is() )
1045 awt::Point aRefPoint = xParentComponent->getLocationOnScreen();
1046 awt::Point aPoint = getLocation();
1047 aPoint.X += aRefPoint.X;
1048 aPoint.Y += aRefPoint.Y;
1050 return aPoint;
1052 // #i88070#
1053 // fallback to parent's <XAccessibleContext> instance
1054 else
1056 uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext();
1057 if ( xParentContext.is() )
1059 uno::Reference< XAccessibleComponent > xParentContextComponent( xParentContext, uno::UNO_QUERY );
1060 if( xParentContextComponent.is() )
1062 awt::Point aRefPoint = xParentContextComponent->getLocationOnScreen();
1063 awt::Point aPoint = getLocation();
1064 aPoint.X += aRefPoint.X;
1065 aPoint.Y += aRefPoint.Y;
1067 return aPoint;
1073 throw uno::RuntimeException(u"Cannot access parent"_ustr,
1074 uno::Reference< uno::XInterface >
1075 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
1078 awt::Size SAL_CALL AccessibleEditableTextPara::getSize( )
1080 SolarMutexGuard aGuard;
1082 awt::Rectangle aRect = getBounds();
1084 return awt::Size( aRect.Width, aRect.Height );
1087 void SAL_CALL AccessibleEditableTextPara::grabFocus( )
1089 // set cursor to this paragraph
1090 setSelection(0,0);
1093 sal_Int32 SAL_CALL AccessibleEditableTextPara::getForeground( )
1095 // #104444# Added to XAccessibleComponent interface
1096 svtools::ColorConfig aColorConfig;
1097 Color nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor;
1098 return static_cast<sal_Int32>(nColor);
1101 sal_Int32 SAL_CALL AccessibleEditableTextPara::getBackground( )
1103 // #104444# Added to XAccessibleComponent interface
1104 Color aColor( Application::GetSettings().GetStyleSettings().GetWindowColor() );
1106 // the background is transparent
1107 aColor.SetAlpha(0);
1109 return static_cast<sal_Int32>( aColor );
1112 // XAccessibleText
1113 sal_Int32 SAL_CALL AccessibleEditableTextPara::getCaretPosition()
1115 SolarMutexGuard aGuard;
1117 if( !HaveEditView() )
1118 return -1;
1120 ESelection aSelection;
1121 if( GetEditViewForwarder().GetSelection( aSelection ) &&
1122 GetParagraphIndex() == aSelection.end.nPara )
1124 // caret is always nEndPara,nEndPos
1125 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex());
1126 if( aBulletInfo.nParagraph != EE_PARA_MAX &&
1127 aBulletInfo.bVisible &&
1128 aBulletInfo.nType != SVX_NUM_BITMAP )
1130 sal_Int32 nBulletLen = aBulletInfo.aText.getLength();
1131 if( aSelection.end.nIndex - nBulletLen >= 0 )
1132 return aSelection.end.nIndex - nBulletLen;
1134 return aSelection.end.nIndex;
1137 // not within this paragraph
1138 return -1;
1141 sal_Bool SAL_CALL AccessibleEditableTextPara::setCaretPosition( sal_Int32 nIndex )
1143 return setSelection(nIndex, nIndex);
1146 sal_Unicode SAL_CALL AccessibleEditableTextPara::getCharacter( sal_Int32 nIndex )
1148 SolarMutexGuard aGuard;
1150 DBG_ASSERT(GetParagraphIndex() >= 0,
1151 "AccessibleEditableTextPara::getCharacter: index value overflow");
1153 return OCommonAccessibleText::implGetCharacter( implGetText(), nIndex );
1156 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& rRequestedAttributes )
1158 SolarMutexGuard aGuard;
1160 //Skip the bullet range to ignore the bullet text
1161 SvxTextForwarder& rCacheTF = GetTextForwarder();
1162 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(GetParagraphIndex());
1163 if (aBulletInfo.bVisible)
1164 nIndex += aBulletInfo.aText.getLength();
1165 CheckIndex(nIndex); // may throw IndexOutOfBoundsException
1167 bool bSupplementalMode = false;
1168 uno::Sequence< OUString > aPropertyNames = rRequestedAttributes;
1169 if (!aPropertyNames.hasElements())
1171 bSupplementalMode = true;
1172 aPropertyNames = getAttributeNames();
1175 // get default attributes...
1176 ::comphelper::SequenceAsHashMap aPropHashMap( getDefaultAttributes( aPropertyNames ) );
1178 // ... and override them with the direct attributes from the specific position
1179 const uno::Sequence< beans::PropertyValue > aRunAttribs( getRunAttributes( nIndex, aPropertyNames ) );
1180 for (auto const& rRunAttrib : aRunAttribs)
1182 aPropHashMap[ rRunAttrib.Name ] = rRunAttrib.Value; //!! should not only be the value !!
1185 // get resulting sequence
1186 uno::Sequence< beans::PropertyValue > aRes;
1187 aPropHashMap >> aRes;
1189 // since SequenceAsHashMap ignores property handles and property state
1190 // we have to restore the property state here (property handles are
1191 // of no use to the accessibility API).
1192 for (beans::PropertyValue & rRes : asNonConstRange(aRes))
1194 bool bIsDirectVal = false;
1195 for (auto const& rRunAttrib : aRunAttribs)
1197 bIsDirectVal = rRes.Name == rRunAttrib.Name;
1198 if (bIsDirectVal)
1199 break;
1201 rRes.Handle = -1;
1202 rRes.State = bIsDirectVal ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
1204 if( bSupplementalMode )
1206 _correctValues( aRes );
1207 // NumberingPrefix
1208 sal_Int32 nRes = aRes.getLength();
1209 aRes.realloc( nRes + 1 );
1210 beans::PropertyValue &rRes = aRes.getArray()[nRes];
1211 rRes.Name = "NumberingPrefix";
1212 OUString numStr;
1213 if (aBulletInfo.nType != SVX_NUM_CHAR_SPECIAL && aBulletInfo.nType != SVX_NUM_BITMAP)
1214 numStr = aBulletInfo.aText;
1215 rRes.Value <<= numStr;
1216 rRes.Handle = -1;
1217 rRes.State = PropertyState_DIRECT_VALUE;
1218 //For field object.
1219 OUString strFieldType = GetFieldTypeNameAtIndex(nIndex);
1220 if (!strFieldType.isEmpty())
1222 nRes = aRes.getLength();
1223 aRes.realloc( nRes + 1 );
1224 beans::PropertyValue &rResField = aRes.getArray()[nRes];
1225 rResField.Name = "FieldType";
1226 rResField.Value <<= strFieldType.toAsciiLowerCase();
1227 rResField.Handle = -1;
1228 rResField.State = PropertyState_DIRECT_VALUE;
1230 //sort property values
1231 // build sorted index array
1232 sal_Int32 nLength = aRes.getLength();
1233 std::vector<sal_Int32> indices(nLength);
1234 std::iota(indices.begin(), indices.end(), 0);
1235 std::sort(indices.begin(), indices.end(), IndexCompare(aRes));
1236 // create sorted sequences according to index array
1237 uno::Sequence<beans::PropertyValue> aNewValues( nLength );
1238 std::transform(indices.begin(), indices.end(), aNewValues.getArray(),
1239 [&aRes](sal_Int32 index) -> const beans::PropertyValue& { return aRes[index]; });
1241 return aNewValues;
1243 return aRes;
1246 awt::Rectangle SAL_CALL AccessibleEditableTextPara::getCharacterBounds( sal_Int32 nIndex )
1248 SolarMutexGuard aGuard;
1250 DBG_ASSERT(GetParagraphIndex() >= 0,
1251 "AccessibleEditableTextPara::getCharacterBounds: index value overflow");
1253 // #108900# Have position semantics now for nIndex, as
1254 // one-past-the-end values are legal, too.
1255 CheckPosition( nIndex );
1257 SvxTextForwarder& rCacheTF = GetTextForwarder();
1258 tools::Rectangle aRect = rCacheTF.GetCharBounds(GetParagraphIndex(), nIndex);
1260 // convert to screen
1261 tools::Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect,
1262 rCacheTF.GetMapMode(),
1263 GetViewForwarder() );
1264 // #109864# offset from parent (paragraph), but in screen
1265 // coordinates. This makes sure the internal text offset in
1266 // the outline view forwarder gets cancelled out here
1267 awt::Rectangle aParaRect( getBounds() );
1268 aScreenRect.Move( -aParaRect.X, -aParaRect.Y );
1270 // offset from shape/cell
1271 Point aOffset = GetEEOffset();
1273 return awt::Rectangle( aScreenRect.Left() + aOffset.X(),
1274 aScreenRect.Top() + aOffset.Y(),
1275 aScreenRect.GetSize().Width(),
1276 aScreenRect.GetSize().Height() );
1279 sal_Int32 SAL_CALL AccessibleEditableTextPara::getCharacterCount()
1281 SolarMutexGuard aGuard;
1283 DBG_ASSERT(GetParagraphIndex() >= 0,
1284 "AccessibleEditableTextPara::getCharacterCount: index value overflow");
1286 return implGetText().getLength();
1289 sal_Int32 SAL_CALL AccessibleEditableTextPara::getIndexAtPoint( const awt::Point& rPoint )
1291 SolarMutexGuard aGuard;
1293 sal_Int32 nPara;
1294 sal_Int32 nIndex;
1296 // offset from surrounding cell/shape
1297 Point aOffset( GetEEOffset() );
1298 Point aPoint( rPoint.X - aOffset.X(), rPoint.Y - aOffset.Y() );
1300 // convert to logical coordinates
1301 SvxTextForwarder& rCacheTF = GetTextForwarder();
1302 Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
1304 // re-offset to parent (paragraph)
1305 tools::Rectangle aParaRect = rCacheTF.GetParaBounds( GetParagraphIndex() );
1306 aLogPoint.Move( aParaRect.Left(), aParaRect.Top() );
1308 if( rCacheTF.GetIndexAtPoint( aLogPoint, nPara, nIndex ) &&
1309 GetParagraphIndex() == nPara )
1311 // #102259# Double-check if we're _really_ on the given character
1314 awt::Rectangle aRect1( getCharacterBounds(nIndex) );
1315 tools::Rectangle aRect2( aRect1.X, aRect1.Y,
1316 aRect1.Width + aRect1.X, aRect1.Height + aRect1.Y );
1317 if( aRect2.Contains( Point( rPoint.X, rPoint.Y ) ) )
1318 return nIndex;
1319 else
1320 return -1;
1322 catch (const lang::IndexOutOfBoundsException&)
1324 // #103927# Don't throw for invalid nIndex values
1325 return -1;
1328 else
1330 // not within our paragraph
1331 return -1;
1335 OUString SAL_CALL AccessibleEditableTextPara::getSelectedText()
1337 SolarMutexGuard aGuard;
1339 DBG_ASSERT(GetParagraphIndex() >= 0,
1340 "AccessibleEditableTextPara::getSelectedText: index value overflow");
1342 if( !HaveEditView() )
1343 return OUString();
1345 return OCommonAccessibleText::getSelectedText();
1348 sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionStart()
1350 SolarMutexGuard aGuard;
1352 DBG_ASSERT(GetParagraphIndex() >= 0,
1353 "AccessibleEditableTextPara::getSelectionStart: index value overflow");
1355 if( !HaveEditView() )
1356 return -1;
1358 return OCommonAccessibleText::getSelectionStart();
1361 sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionEnd()
1363 SolarMutexGuard aGuard;
1365 DBG_ASSERT(GetParagraphIndex() >= 0,
1366 "AccessibleEditableTextPara::getSelectionEnd: index value overflow");
1368 if( !HaveEditView() )
1369 return -1;
1371 return OCommonAccessibleText::getSelectionEnd();
1374 sal_Bool SAL_CALL AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
1376 SolarMutexGuard aGuard;
1378 DBG_ASSERT(GetParagraphIndex() >= 0,
1379 "AccessibleEditableTextPara::setSelection: paragraph index value overflow");
1381 CheckRange(nStartIndex, nEndIndex);
1385 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( true );
1386 return rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
1388 catch (const uno::RuntimeException&)
1390 return false;
1394 OUString SAL_CALL AccessibleEditableTextPara::getText()
1396 SolarMutexGuard aGuard;
1398 DBG_ASSERT(GetParagraphIndex() >= 0,
1399 "AccessibleEditableTextPara::getText: paragraph index value overflow");
1401 return implGetText();
1404 OUString SAL_CALL AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
1406 SolarMutexGuard aGuard;
1408 DBG_ASSERT(GetParagraphIndex() >= 0,
1409 "AccessibleEditableTextPara::getTextRange: paragraph index value overflow");
1411 return OCommonAccessibleText::implGetTextRange(implGetText(), nStartIndex, nEndIndex);
1414 void AccessibleEditableTextPara::_correctValues( uno::Sequence< PropertyValue >& rValues)
1416 SvxTextForwarder& rCacheTF = GetTextForwarder();
1417 sal_Int32 nRes = rValues.getLength();
1418 beans::PropertyValue *pRes = rValues.getArray();
1419 for (sal_Int32 i = 0; i < nRes; ++i)
1421 beans::PropertyValue &rRes = pRes[i];
1422 // Char color
1423 if (rRes.Name == "CharColor")
1425 uno::Any &anyChar = rRes.Value;
1426 Color crChar(ColorTransparency, static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved)));
1427 if (COL_AUTO == crChar )
1429 uno::Reference< css::accessibility::XAccessibleComponent > xComponent(mxParent,uno::UNO_QUERY);
1430 if (xComponent.is())
1432 uno::Reference< css::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY);
1433 if (xContext->getAccessibleRole() == AccessibleRole::SHAPE
1434 || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL)
1436 anyChar <<= COL_BLACK;
1438 else
1440 Color cr(ColorTransparency, xComponent->getBackground());
1441 crChar = cr.IsDark() ? COL_WHITE : COL_BLACK;
1442 anyChar <<= crChar;
1446 continue;
1448 // Underline
1449 if (rRes.Name == "CharUnderline")
1451 continue;
1453 // Underline color && Mis-spell
1454 if (rRes.Name == "CharUnderlineColor")
1456 uno::Any &anyCharUnderLine = rRes.Value;
1457 Color crCharUnderLine(ColorTransparency, static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>( anyCharUnderLine.pReserved)));
1458 if (COL_AUTO == crCharUnderLine )
1460 uno::Reference< css::accessibility::XAccessibleComponent > xComponent(mxParent,uno::UNO_QUERY);
1461 if (xComponent.is())
1463 uno::Reference< css::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY);
1464 if (xContext->getAccessibleRole() == AccessibleRole::SHAPE
1465 || xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL)
1467 anyCharUnderLine <<= COL_BLACK;
1469 else
1471 Color cr(ColorTransparency, xComponent->getBackground());
1472 crCharUnderLine = cr.IsDark() ? COL_WHITE : COL_BLACK;
1473 anyCharUnderLine <<= crCharUnderLine;
1477 continue;
1479 // NumberingLevel
1480 if (rRes.Name == "NumberingLevel")
1482 if(rCacheTF.GetParaAttribs(GetParagraphIndex()).Get(EE_PARA_NUMBULLET).GetNumRule().GetLevelCount()==0)
1484 rRes.Value <<= sal_Int16(-1);
1485 rRes.Handle = -1;
1486 rRes.State = PropertyState_DIRECT_VALUE;
1488 else
1490 // SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
1491 // ImplGetSvxCharAndParaPropertiesMap() );
1492 // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap
1493 rtl::Reference< SvxAccessibleTextPropertySet > xPropSet( new SvxAccessibleTextPropertySet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() ) );
1495 xPropSet->SetSelection( MakeSelection( 0, GetTextLen() ) );
1496 rRes.Value = xPropSet->_getPropertyValue( rRes.Name, mnParagraphIndex );
1497 rRes.State = xPropSet->_getPropertyState( rRes.Name, mnParagraphIndex );
1498 rRes.Handle = -1;
1500 continue;
1502 // NumberingRules
1503 if (rRes.Name == "NumberingRules")
1505 SfxItemSet aAttribs = rCacheTF.GetParaAttribs(GetParagraphIndex());
1506 bool bVis = aAttribs.Get( EE_PARA_BULLETSTATE ).GetValue();
1507 if(bVis)
1509 rRes.Value <<= sal_Int16(-1);
1510 rRes.Handle = -1;
1511 rRes.State = PropertyState_DIRECT_VALUE;
1513 else
1515 // MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap
1516 rtl::Reference< SvxAccessibleTextPropertySet > xPropSet( new SvxAccessibleTextPropertySet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() ) );
1517 xPropSet->SetSelection( MakeSelection( 0, GetTextLen() ) );
1518 rRes.Value = xPropSet->_getPropertyValue( rRes.Name, mnParagraphIndex );
1519 rRes.State = xPropSet->_getPropertyState( rRes.Name, mnParagraphIndex );
1520 rRes.Handle = -1;
1522 continue;
1526 sal_Int32 AccessibleEditableTextPara::SkipField(sal_Int32 nIndex, bool bForward)
1528 sal_Int32 nParaIndex = GetParagraphIndex();
1529 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();
1530 sal_Int32 nAllFieldLen = 0;
1531 sal_Int32 nFoundFieldIndex = -1;
1532 std::vector<EFieldInfo> aFieldInfos = rCacheTF.GetFieldInfo(nParaIndex);
1533 sal_Int32 reeBegin=0, reeEnd=0;
1534 sal_Int32 j = 0;
1535 for (const EFieldInfo& ree : aFieldInfos)
1537 reeBegin = ree.aPosition.nIndex + nAllFieldLen;
1538 reeEnd = reeBegin + ree.aCurrentText.getLength();
1539 nAllFieldLen += (ree.aCurrentText.getLength() - 1);
1540 if (nIndex < reeBegin)
1541 break;
1542 if (!ree.pFieldItem)
1543 continue;
1544 if (nIndex < reeEnd)
1546 if (ree.pFieldItem->GetField()->GetClassId() != text::textfield::Type::URL)
1548 nFoundFieldIndex = j;
1549 break;
1552 j++;
1554 if( nFoundFieldIndex >= 0 )
1556 if( bForward )
1557 return reeEnd - 1;
1558 else
1559 return reeBegin;
1561 return nIndex;
1563 void AccessibleEditableTextPara::ExtendByField( css::accessibility::TextSegment& Segment )
1565 sal_Int32 nParaIndex = GetParagraphIndex();
1566 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();
1567 std::vector<EFieldInfo> aFieldInfos = rCacheTF.GetFieldInfo(nParaIndex);
1568 sal_Int32 nAllFieldLen = 0;
1569 sal_Int32 nField = aFieldInfos.size(), nFoundFieldIndex = -1;
1570 sal_Int32 reeBegin=0, reeEnd=0;
1571 for (sal_Int32 j = 0; j < nField; ++j)
1573 const EFieldInfo& ree = aFieldInfos[j];
1574 reeBegin = ree.aPosition.nIndex + nAllFieldLen;
1575 reeEnd = reeBegin + ree.aCurrentText.getLength();
1576 nAllFieldLen += (ree.aCurrentText.getLength() - 1);
1577 if( reeBegin > Segment.SegmentEnd )
1579 break;
1581 if (!ree.pFieldItem)
1582 continue;
1583 if( (Segment.SegmentEnd > reeBegin && Segment.SegmentEnd <= reeEnd) ||
1584 (Segment.SegmentStart >= reeBegin && Segment.SegmentStart < reeEnd) )
1586 if(ree.pFieldItem->GetField()->GetClassId() != text::textfield::Type::URL)
1588 nFoundFieldIndex = j;
1589 break;
1593 if( nFoundFieldIndex < 0 )
1594 return;
1596 bool bExtend = false;
1597 if( Segment.SegmentEnd < reeEnd )
1599 Segment.SegmentEnd = reeEnd;
1600 bExtend = true;
1602 if( Segment.SegmentStart > reeBegin )
1604 Segment.SegmentStart = reeBegin;
1605 bExtend = true;
1607 if( !bExtend )
1608 return;
1610 //If there is a bullet before the field, should add the bullet length into the segment.
1611 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(nParaIndex);
1612 sal_Int32 nBulletLen = aBulletInfo.aText.getLength();
1613 if (nBulletLen > 0)
1615 Segment.SegmentEnd += nBulletLen;
1616 if (nFoundFieldIndex > 0)
1617 Segment.SegmentStart += nBulletLen;
1618 Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd);
1619 //After get the correct field name, should restore the offset value which don't contain the bullet.
1620 Segment.SegmentEnd -= nBulletLen;
1621 if (nFoundFieldIndex > 0)
1622 Segment.SegmentStart -= nBulletLen;
1624 else
1625 Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd);
1628 css::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType )
1630 SolarMutexGuard aGuard;
1632 DBG_ASSERT(GetParagraphIndex() >= 0,
1633 "AccessibleEditableTextPara::getTextAtIndex: paragraph index value overflow");
1635 css::accessibility::TextSegment aResult;
1636 aResult.SegmentStart = -1;
1637 aResult.SegmentEnd = -1;
1639 switch( aTextType )
1641 case AccessibleTextType::CHARACTER:
1642 case AccessibleTextType::WORD:
1644 aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
1645 ExtendByField( aResult );
1646 break;
1648 // Not yet handled by OCommonAccessibleText. Missing
1649 // implGetAttributeRunBoundary() method there
1650 case AccessibleTextType::ATTRIBUTE_RUN:
1652 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( GetParagraphIndex() );
1654 if( nIndex == nTextLen )
1656 // #i17014# Special-casing one-behind-the-end character
1657 aResult.SegmentStart = aResult.SegmentEnd = nTextLen;
1659 else
1661 sal_Int32 nStartIndex, nEndIndex;
1662 //For the bullet paragraph, the bullet string is ignored for IAText::attributes() function.
1663 SvxTextForwarder& rCacheTF = GetTextForwarder();
1664 // MT IA2: Not used? sal_Int32 nBulletLen = 0;
1665 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(GetParagraphIndex());
1666 if (aBulletInfo.bVisible)
1667 nIndex += aBulletInfo.aText.getLength();
1668 if (nIndex != 0 && nIndex >= getCharacterCount())
1669 nIndex = getCharacterCount()-1;
1670 CheckPosition(nIndex);
1671 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
1673 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1674 if (aBulletInfo.bVisible)
1676 nStartIndex -= aBulletInfo.aText.getLength();
1677 nEndIndex -= aBulletInfo.aText.getLength();
1679 aResult.SegmentStart = nStartIndex;
1680 aResult.SegmentEnd = nEndIndex;
1683 break;
1685 case AccessibleTextType::LINE:
1687 SvxTextForwarder& rCacheTF = GetTextForwarder();
1688 sal_Int32 nParaIndex = GetParagraphIndex();
1689 CheckPosition(nIndex);
1690 if (nIndex != 0 && nIndex == getCharacterCount())
1691 --nIndex;
1692 sal_Int32 nLine, nLineCount=rCacheTF.GetLineCount( nParaIndex );
1693 sal_Int32 nCurIndex;
1694 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
1695 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
1696 //by the IAText::attributes(). So here must do special support for bullet line.
1697 sal_Int32 nBulletLen = 0;
1698 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
1700 if (nLine == 0)
1702 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( nParaIndex );
1703 if (aBulletInfo.bVisible)
1705 //in bullet or numbering;
1706 nBulletLen = aBulletInfo.aText.getLength();
1709 sal_Int32 nLineLen = rCacheTF.GetLineLen(nParaIndex, nLine);
1710 if (nLine == 0)
1711 nCurIndex += nLineLen - nBulletLen;
1712 else
1713 nCurIndex += nLineLen;
1714 if( nCurIndex > nIndex )
1716 if (nLine ==0)
1718 aResult.SegmentStart = 0;
1719 aResult.SegmentEnd = nCurIndex;
1720 aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen);
1721 break;
1723 else
1725 aResult.SegmentStart = nCurIndex - nLineLen;
1726 aResult.SegmentEnd = nCurIndex;
1727 //aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd );
1728 aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen);
1729 break;
1733 break;
1735 default:
1736 aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
1737 break;
1738 } /* end of switch( aTextType ) */
1740 return aResult;
1743 css::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType )
1745 SolarMutexGuard aGuard;
1747 DBG_ASSERT(GetParagraphIndex() >= 0,
1748 "AccessibleEditableTextPara::getTextBeforeIndex: paragraph index value overflow");
1750 css::accessibility::TextSegment aResult;
1751 aResult.SegmentStart = -1;
1752 aResult.SegmentEnd = -1;
1753 i18n::Boundary aBoundary;
1754 switch( aTextType )
1756 // Not yet handled by OCommonAccessibleText. Missing
1757 // implGetAttributeRunBoundary() method there
1758 case AccessibleTextType::ATTRIBUTE_RUN:
1760 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( GetParagraphIndex() );
1761 sal_Int32 nStartIndex, nEndIndex;
1763 if( nIndex == nTextLen )
1765 // #i17014# Special-casing one-behind-the-end character
1766 if( nIndex > 0 &&
1767 GetAttributeRun(nStartIndex, nEndIndex, nIndex-1) )
1769 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1770 aResult.SegmentStart = nStartIndex;
1771 aResult.SegmentEnd = nEndIndex;
1774 else
1776 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
1778 // already at the left border? If not, query
1779 // one index further left
1780 if( nStartIndex > 0 &&
1781 GetAttributeRun(nStartIndex, nEndIndex, nStartIndex-1) )
1783 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1784 aResult.SegmentStart = nStartIndex;
1785 aResult.SegmentEnd = nEndIndex;
1789 break;
1791 case AccessibleTextType::LINE:
1793 SvxTextForwarder& rCacheTF = GetTextForwarder();
1794 sal_Int32 nParaIndex = GetParagraphIndex();
1796 CheckPosition(nIndex);
1798 sal_Int32 nLine, nLineCount=rCacheTF.GetLineCount( nParaIndex );
1799 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
1800 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
1801 //by the IAText::attributes(). So here must do special support for bullet line.
1802 sal_Int32 nCurIndex=0, nLastIndex=0, nCurLineLen=0;
1803 sal_Int32 nLastLineLen = 0, nBulletLen = 0;
1804 // get the line before the line the index points into
1805 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
1807 nLastIndex = nCurIndex;
1808 if (nLine == 0)
1810 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(nParaIndex);
1811 if (aBulletInfo.bVisible)
1813 //in bullet or numbering;
1814 nBulletLen = aBulletInfo.aText.getLength();
1817 if (nLine == 1)
1818 nLastLineLen = nCurLineLen - nBulletLen;
1819 else
1820 nLastLineLen = nCurLineLen;
1821 nCurLineLen = rCacheTF.GetLineLen( nParaIndex, nLine);
1822 //nCurIndex += nCurLineLen;
1823 if (nLine == 0)
1824 nCurIndex += nCurLineLen - nBulletLen;
1825 else
1826 nCurIndex += nCurLineLen;
1828 //if( nCurIndex > nIndex &&
1829 //nLastIndex > nCurLineLen )
1830 if (nCurIndex > nIndex)
1832 if (nLine == 0)
1834 break;
1836 else if (nLine == 1)
1838 aResult.SegmentStart = 0;
1839 aResult.SegmentEnd = nLastIndex;
1840 aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen);
1841 break;
1843 else
1845 //aResult.SegmentStart = nLastIndex - nCurLineLen;
1846 aResult.SegmentStart = nLastIndex - nLastLineLen;
1847 aResult.SegmentEnd = nLastIndex;
1848 aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen);
1849 break;
1854 break;
1856 case AccessibleTextType::WORD:
1858 nIndex = SkipField( nIndex, false);
1859 OUString sText( implGetText() );
1860 sal_Int32 nLength = sText.getLength();
1862 // get word at index
1863 implGetWordBoundary( sText, aBoundary, nIndex );
1866 //sal_Int32 curWordStart = aBoundary.startPos;
1867 //sal_Int32 preWordStart = curWordStart;
1868 sal_Int32 curWordStart , preWordStart;
1869 if( aBoundary.startPos == -1 || aBoundary.startPos > nIndex)
1870 curWordStart = preWordStart = nIndex;
1871 else
1872 curWordStart = preWordStart = aBoundary.startPos;
1874 // get previous word
1876 bool bWord = false;
1878 //while ( preWordStart > 0 && aBoundary.startPos == curWordStart)
1879 while ( (preWordStart >= 0 && !bWord ) || ( aBoundary.endPos > curWordStart ) )
1881 preWordStart--;
1882 bWord = implGetWordBoundary( sText, aBoundary, preWordStart );
1884 if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
1886 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
1887 aResult.SegmentStart = aBoundary.startPos;
1888 aResult.SegmentEnd = aBoundary.endPos;
1889 ExtendByField( aResult );
1892 break;
1893 case AccessibleTextType::CHARACTER:
1895 nIndex = SkipField( nIndex, false);
1896 aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
1897 ExtendByField( aResult );
1898 break;
1900 default:
1901 aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
1902 break;
1903 } /* end of switch( aTextType ) */
1905 return aResult;
1908 css::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType )
1910 SolarMutexGuard aGuard;
1912 DBG_ASSERT(GetParagraphIndex() >= 0,
1913 "AccessibleEditableTextPara::getTextBehindIndex: paragraph index value overflow");
1915 css::accessibility::TextSegment aResult;
1916 aResult.SegmentStart = -1;
1917 aResult.SegmentEnd = -1;
1918 i18n::Boundary aBoundary;
1919 switch( aTextType )
1921 case AccessibleTextType::ATTRIBUTE_RUN:
1923 sal_Int32 nStartIndex, nEndIndex;
1925 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
1927 // already at the right border?
1928 if( nEndIndex < GetTextLen() )
1930 if( GetAttributeRun(nStartIndex, nEndIndex, nEndIndex) )
1932 aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
1933 aResult.SegmentStart = nStartIndex;
1934 aResult.SegmentEnd = nEndIndex;
1938 break;
1941 case AccessibleTextType::LINE:
1943 SvxTextForwarder& rCacheTF = GetTextForwarder();
1944 sal_Int32 nParaIndex = GetParagraphIndex();
1946 CheckPosition(nIndex);
1948 sal_Int32 nLine, nLineCount = rCacheTF.GetLineCount( nParaIndex );
1949 sal_Int32 nCurIndex;
1950 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
1951 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
1952 //by the IAText::attributes(). So here must do special support for bullet line.
1953 sal_Int32 nBulletLen = 0;
1954 // get the line after the line the index points into
1955 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
1957 if (nLine == 0)
1959 EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(nParaIndex);
1960 if (aBulletInfo.bVisible)
1962 //in bullet or numbering;
1963 nBulletLen = aBulletInfo.aText.getLength();
1966 sal_Int32 nLineLen = rCacheTF.GetLineLen( nParaIndex, nLine);
1968 if (nLine == 0)
1969 nCurIndex += nLineLen - nBulletLen;
1970 else
1971 nCurIndex += nLineLen;
1973 if( nCurIndex > nIndex &&
1974 nLine < nLineCount-1 )
1976 aResult.SegmentStart = nCurIndex;
1977 aResult.SegmentEnd = nCurIndex + rCacheTF.GetLineLen( nParaIndex, nLine+1);
1978 aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen);
1979 break;
1983 break;
1985 case AccessibleTextType::WORD:
1987 nIndex = SkipField( nIndex, true);
1988 OUString sText( implGetText() );
1989 sal_Int32 nLength = sText.getLength();
1991 // get word at index
1992 bool bWord = implGetWordBoundary( sText, aBoundary, nIndex );
1994 // real current world
1995 sal_Int32 nextWord = nIndex;
1996 //if( nIndex >= aBoundary.startPos && nIndex <= aBoundary.endPos )
1997 if( nIndex <= aBoundary.endPos )
1999 nextWord = aBoundary.endPos;
2000 if (nextWord < sText.getLength() && sText[nextWord] == u' ') nextWord++;
2001 bWord = implGetWordBoundary( sText, aBoundary, nextWord );
2004 if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
2006 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
2007 aResult.SegmentStart = aBoundary.startPos;
2008 aResult.SegmentEnd = aBoundary.endPos;
2010 // If the end position of aBoundary is inside a field, extend the result to the end of the field
2012 ExtendByField( aResult );
2015 break;
2017 case AccessibleTextType::CHARACTER:
2019 nIndex = SkipField( nIndex, true);
2020 aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
2021 ExtendByField( aResult );
2022 break;
2024 default:
2025 aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
2026 break;
2027 } /* end of switch( aTextType ) */
2029 return aResult;
2032 sal_Bool SAL_CALL AccessibleEditableTextPara::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2034 SolarMutexGuard aGuard;
2038 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( true );
2039 GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2041 bool aRetVal;
2043 DBG_ASSERT(GetParagraphIndex() >= 0,
2044 "AccessibleEditableTextPara::copyText: index value overflow");
2046 CheckRange(nStartIndex, nEndIndex);
2048 //Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2049 sal_Int32 nBulletLen = 0;
2050 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2051 if( aBulletInfo.nParagraph != EE_PARA_MAX && aBulletInfo.bVisible )
2052 nBulletLen = aBulletInfo.aText.getLength();
2053 // save current selection
2054 ESelection aOldSelection;
2056 rCacheVF.GetSelection( aOldSelection );
2057 //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2058 rCacheVF.SetSelection( MakeSelection(nStartIndex + nBulletLen, nEndIndex + nBulletLen) );
2059 aRetVal = rCacheVF.Copy();
2060 rCacheVF.SetSelection( aOldSelection ); // restore
2062 return aRetVal;
2064 catch (const uno::RuntimeException&)
2066 return false;
2070 sal_Bool SAL_CALL AccessibleEditableTextPara::scrollSubstringTo( sal_Int32, sal_Int32, AccessibleScrollType )
2072 return false;
2075 // XAccessibleEditableText
2076 sal_Bool SAL_CALL AccessibleEditableTextPara::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2079 SolarMutexGuard aGuard;
2083 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( true );
2084 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2086 DBG_ASSERT(GetParagraphIndex() >= 0,
2087 "AccessibleEditableTextPara::cutText: index value overflow");
2089 CheckRange(nStartIndex, nEndIndex);
2091 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2092 sal_Int32 nBulletLen = 0;
2093 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2094 if( aBulletInfo.nParagraph != EE_PARA_MAX && aBulletInfo.bVisible )
2095 nBulletLen = aBulletInfo.aText.getLength();
2096 ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen);
2097 //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2098 if( !rCacheTF.IsEditable( aSelection ) )
2099 return false; // non-editable area selected
2101 // don't save selection, might become invalid after cut!
2102 //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2103 rCacheVF.SetSelection( aSelection );
2105 return rCacheVF.Cut();
2107 catch (const uno::RuntimeException&)
2109 return false;
2113 sal_Bool SAL_CALL AccessibleEditableTextPara::pasteText( sal_Int32 nIndex )
2116 SolarMutexGuard aGuard;
2120 SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( true );
2121 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2123 DBG_ASSERT(GetParagraphIndex() >= 0,
2124 "AccessibleEditableTextPara::pasteText: index value overflow");
2126 CheckPosition(nIndex);
2128 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2129 sal_Int32 nBulletLen = 0;
2130 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2131 if( aBulletInfo.nParagraph != EE_PARA_MAX && aBulletInfo.bVisible )
2132 nBulletLen = aBulletInfo.aText.getLength();
2133 if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) )
2134 return false; // non-editable area selected
2136 // #104400# set empty selection (=> cursor) to given index
2137 //rCacheVF.SetSelection( MakeCursor(nIndex) );
2138 rCacheVF.SetSelection( MakeCursor(nIndex + nBulletLen) );
2140 return rCacheVF.Paste();
2142 catch (const uno::RuntimeException&)
2144 return false;
2148 sal_Bool SAL_CALL AccessibleEditableTextPara::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2151 SolarMutexGuard aGuard;
2155 // #102710# Request edit view when doing changes
2156 // AccessibleEmptyEditSource relies on this behaviour
2157 GetEditViewForwarder( true );
2158 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2160 DBG_ASSERT(GetParagraphIndex() >= 0,
2161 "AccessibleEditableTextPara::deleteText: index value overflow");
2163 CheckRange(nStartIndex, nEndIndex);
2165 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2166 sal_Int32 nBulletLen = 0;
2167 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2168 if( aBulletInfo.nParagraph != EE_PARA_MAX && aBulletInfo.bVisible )
2169 nBulletLen = aBulletInfo.aText.getLength();
2170 ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen);
2172 //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2173 if( !rCacheTF.IsEditable( aSelection ) )
2174 return false; // non-editable area selected
2176 //sal_Bool bRet = rCacheTF.Delete( MakeSelection(nStartIndex, nEndIndex) );
2177 bool bRet = rCacheTF.Delete( aSelection );
2179 GetEditSource().UpdateData();
2181 return bRet;
2183 catch (const uno::RuntimeException&)
2185 return false;
2189 sal_Bool SAL_CALL AccessibleEditableTextPara::insertText( const OUString& sText, sal_Int32 nIndex )
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::insertText: index value overflow");
2204 CheckPosition(nIndex);
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_MAX && aBulletInfo.bVisible )
2210 nBulletLen = aBulletInfo.aText.getLength();
2212 if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) )
2213 return false; // non-editable area selected
2215 // #104400# insert given text at empty selection (=> cursor)
2216 bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex + nBulletLen) );
2218 rCacheTF.QuickFormatDoc();
2219 GetEditSource().UpdateData();
2221 return bRet;
2223 catch (const uno::RuntimeException&)
2225 return false;
2229 sal_Bool SAL_CALL AccessibleEditableTextPara::replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const OUString& sReplacement )
2232 SolarMutexGuard aGuard;
2236 // #102710# Request edit view when doing changes
2237 // AccessibleEmptyEditSource relies on this behaviour
2238 GetEditViewForwarder( true );
2239 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2241 DBG_ASSERT(GetParagraphIndex() >= 0,
2242 "AccessibleEditableTextPara::replaceText: index value overflow");
2244 CheckRange(nStartIndex, nEndIndex);
2246 // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2247 sal_Int32 nBulletLen = 0;
2248 EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo(GetParagraphIndex());
2249 if( aBulletInfo.nParagraph != EE_PARA_MAX && aBulletInfo.bVisible )
2250 nBulletLen = aBulletInfo.aText.getLength();
2251 ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen);
2253 //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2254 if( !rCacheTF.IsEditable( aSelection ) )
2255 return false; // non-editable area selected
2257 // insert given text into given range => replace
2258 //sal_Bool bRet = rCacheTF.InsertText( sReplacement, MakeSelection(nStartIndex, nEndIndex) );
2259 bool bRet = rCacheTF.InsertText( sReplacement, aSelection );
2261 rCacheTF.QuickFormatDoc();
2262 GetEditSource().UpdateData();
2264 return bRet;
2266 catch (const uno::RuntimeException&)
2268 return false;
2272 sal_Bool SAL_CALL AccessibleEditableTextPara::setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const uno::Sequence< beans::PropertyValue >& aAttributeSet )
2275 SolarMutexGuard aGuard;
2279 // #102710# Request edit view when doing changes
2280 // AccessibleEmptyEditSource relies on this behaviour
2281 GetEditViewForwarder( true );
2282 SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder(); // MUST be after GetEditViewForwarder(), see method docs
2283 sal_Int32 nPara = GetParagraphIndex();
2285 DBG_ASSERT(GetParagraphIndex() >= 0,
2286 "AccessibleEditableTextPara::setAttributes: index value overflow");
2288 CheckRange(nStartIndex, nEndIndex);
2290 if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2291 return false; // non-editable area selected
2293 // do the indices span the whole paragraph? Then use the outliner map
2294 // TODO: hold it as a member?
2295 rtl::Reference< SvxAccessibleTextPropertySet > xPropSet( new SvxAccessibleTextPropertySet( &GetEditSource(),
2296 0 == nStartIndex &&
2297 rCacheTF.GetTextLen(nPara) == nEndIndex ?
2298 ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() :
2299 ImplGetSvxTextPortionSvxPropertySet() ) );
2301 xPropSet->SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2303 // convert from PropertyValue to Any
2304 for(const beans::PropertyValue& rProp : aAttributeSet)
2308 xPropSet->setPropertyValue(rProp.Name, rProp.Value);
2310 catch (const uno::Exception&)
2312 TOOLS_WARN_EXCEPTION( "dbaccess", "AccessibleEditableTextPara::setAttributes exception in setPropertyValue");
2316 rCacheTF.QuickFormatDoc();
2317 GetEditSource().UpdateData();
2319 return true;
2321 catch (const uno::RuntimeException&)
2323 return false;
2327 sal_Bool SAL_CALL AccessibleEditableTextPara::setText( const OUString& sText )
2330 SolarMutexGuard aGuard;
2332 return replaceText(0, getCharacterCount(), sText);
2335 // XAccessibleTextAttributes
2336 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getDefaultAttributes(
2337 const uno::Sequence< OUString >& rRequestedAttributes )
2339 SolarMutexGuard aGuard;
2341 GetTextForwarder();
2343 DBG_ASSERT(GetParagraphIndex() >= 0,
2344 "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
2346 // get XPropertySetInfo for paragraph attributes and
2347 // character attributes that span all the paragraphs text.
2348 rtl::Reference< SvxAccessibleTextPropertySet > xPropSet( new SvxAccessibleTextPropertySet( &GetEditSource(),
2349 ImplGetSvxCharAndParaPropertiesSet() ) );
2350 xPropSet->SetSelection( MakeSelection( 0, GetTextLen() ) );
2351 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
2352 if (!xPropSetInfo.is())
2353 throw uno::RuntimeException(u"Cannot query XPropertySetInfo"_ustr,
2354 uno::Reference< uno::XInterface >
2355 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
2357 // build sequence of available properties to check
2358 uno::Sequence< beans::Property > aProperties;
2359 if (const sal_Int32 nLenReqAttr = rRequestedAttributes.getLength())
2361 aProperties.realloc( nLenReqAttr );
2362 beans::Property *pProperties = aProperties.getArray();
2363 sal_Int32 nCurLen = 0;
2364 for (const OUString& rRequestedAttribute : rRequestedAttributes)
2366 beans::Property aProp;
2369 aProp = xPropSetInfo->getPropertyByName( rRequestedAttribute );
2371 catch (const beans::UnknownPropertyException&)
2373 continue;
2375 pProperties[nCurLen++] = std::move(aProp);
2377 aProperties.realloc( nCurLen );
2379 else
2380 aProperties = xPropSetInfo->getProperties();
2382 // build resulting sequence
2383 uno::Sequence< beans::PropertyValue > aOutSequence( aProperties.getLength() );
2384 beans::PropertyValue* pOutSequence = aOutSequence.getArray();
2385 sal_Int32 nOutLen = 0;
2386 for (const beans::Property& rProperty : aProperties)
2388 // calling implementation functions:
2389 // _getPropertyState and _getPropertyValue (see below) to provide
2390 // the proper paragraph number when retrieving paragraph attributes
2391 PropertyState eState = xPropSet->_getPropertyState( rProperty.Name, mnParagraphIndex );
2392 if ( eState == PropertyState_AMBIGUOUS_VALUE )
2394 OSL_FAIL( "ambiguous property value encountered" );
2397 //if (eState == PropertyState_DIRECT_VALUE)
2398 // per definition all paragraph properties and all character
2399 // properties spanning the whole paragraph should be returned
2400 // and declared as default value
2402 pOutSequence->Name = rProperty.Name;
2403 pOutSequence->Handle = rProperty.Handle;
2404 pOutSequence->Value = xPropSet->_getPropertyValue( rProperty.Name, mnParagraphIndex );
2405 pOutSequence->State = PropertyState_DEFAULT_VALUE;
2407 ++pOutSequence;
2408 ++nOutLen;
2411 aOutSequence.realloc( nOutLen );
2413 return aOutSequence;
2417 uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getRunAttributes(
2418 sal_Int32 nIndex,
2419 const uno::Sequence< OUString >& rRequestedAttributes )
2422 SolarMutexGuard aGuard;
2424 GetTextForwarder();
2426 DBG_ASSERT(GetParagraphIndex() >= 0,
2427 "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
2429 if( getCharacterCount() > 0 )
2430 CheckIndex(nIndex);
2431 else
2432 CheckPosition(nIndex);
2434 rtl::Reference< SvxAccessibleTextPropertySet > xPropSet( new SvxAccessibleTextPropertySet( &GetEditSource(),
2435 ImplGetSvxCharAndParaPropertiesSet() ) );
2436 xPropSet->SetSelection( MakeSelection( nIndex ) );
2437 uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
2438 if (!xPropSetInfo.is())
2439 throw uno::RuntimeException(u"Cannot query XPropertySetInfo"_ustr,
2440 uno::Reference< uno::XInterface >
2441 ( static_cast< XAccessible* > (this) ) ); // disambiguate hierarchy
2443 // build sequence of available properties to check
2444 uno::Sequence< beans::Property > aProperties;
2445 if (const sal_Int32 nLenReqAttr = rRequestedAttributes.getLength())
2447 aProperties.realloc( nLenReqAttr );
2448 beans::Property *pProperties = aProperties.getArray();
2449 sal_Int32 nCurLen = 0;
2450 for (const OUString& rRequestedAttribute : rRequestedAttributes)
2452 beans::Property aProp;
2455 aProp = xPropSetInfo->getPropertyByName( rRequestedAttribute );
2457 catch (const beans::UnknownPropertyException&)
2459 continue;
2461 pProperties[ nCurLen++ ] = std::move(aProp);
2463 aProperties.realloc( nCurLen );
2465 else
2466 aProperties = xPropSetInfo->getProperties();
2468 // build resulting sequence
2469 uno::Sequence< beans::PropertyValue > aOutSequence( aProperties.getLength() );
2470 beans::PropertyValue* pOutSequence = aOutSequence.getArray();
2471 sal_Int32 nOutLen = 0;
2472 for (const beans::Property& rProperty : aProperties)
2474 // calling 'regular' functions that will operate on the selection
2475 PropertyState eState = xPropSet->getPropertyState( rProperty.Name );
2476 if (eState == PropertyState_DIRECT_VALUE)
2478 pOutSequence->Name = rProperty.Name;
2479 pOutSequence->Handle = rProperty.Handle;
2480 pOutSequence->Value = xPropSet->getPropertyValue( rProperty.Name );
2481 pOutSequence->State = eState;
2483 ++pOutSequence;
2484 ++nOutLen;
2487 aOutSequence.realloc( nOutLen );
2489 return aOutSequence;
2492 // XAccessibleHypertext
2493 ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkCount( )
2495 SvxAccessibleTextAdapter& rT = GetTextForwarder();
2496 const sal_Int32 nPara = GetParagraphIndex();
2498 std::vector<EFieldInfo> aFieldInfos = rT.GetFieldInfo( nPara );
2499 sal_Int32 nHyperLinks = 0;
2500 sal_Int32 nFields = aFieldInfos.size();
2501 for (sal_Int32 n = 0; n < nFields; ++n)
2503 if ( dynamic_cast<const SvxURLField* >(aFieldInfos[n].pFieldItem->GetField() ) != nullptr)
2504 nHyperLinks++;
2506 return nHyperLinks;
2509 css::uno::Reference< css::accessibility::XAccessibleHyperlink > SAL_CALL AccessibleEditableTextPara::getHyperLink( ::sal_Int32 nLinkIndex )
2511 css::uno::Reference< css::accessibility::XAccessibleHyperlink > xRef;
2513 SvxAccessibleTextAdapter& rT = GetTextForwarder();
2514 const sal_Int32 nPara = GetParagraphIndex();
2516 sal_Int32 nHyperLink = 0;
2517 for (const EFieldInfo& rField : rT.GetFieldInfo( nPara ))
2519 if ( dynamic_cast<const SvxURLField* >(rField.pFieldItem->GetField()) != nullptr )
2521 if ( nHyperLink == nLinkIndex )
2523 sal_Int32 nEEStart = rField.aPosition.nIndex;
2525 // Translate EE Index to accessible index
2526 sal_Int32 nStart = rT.CalcEditEngineIndex( nPara, nEEStart );
2527 sal_Int32 nEnd = nStart + rField.aCurrentText.getLength();
2528 xRef = new AccessibleHyperlink( rT, new SvxFieldItem( *rField.pFieldItem ), nStart, nEnd, rField.aCurrentText );
2529 break;
2531 nHyperLink++;
2535 return xRef;
2538 ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkIndex( ::sal_Int32 nCharIndex )
2540 const sal_Int32 nPara = GetParagraphIndex();
2541 SvxAccessibleTextAdapter& rT = GetTextForwarder();
2543 const sal_Int32 nEEIndex = rT.CalcEditEngineIndex( nPara, nCharIndex );
2544 sal_Int32 nHLIndex = -1; //i123620
2545 sal_Int32 nHyperLink = 0;
2546 for (const EFieldInfo & rField : rT.GetFieldInfo( nPara ))
2548 if ( dynamic_cast<const SvxURLField* >( rField.pFieldItem->GetField() ) != nullptr)
2550 if ( rField.aPosition.nIndex == nEEIndex )
2552 nHLIndex = nHyperLink;
2553 break;
2555 nHyperLink++;
2559 return nHLIndex;
2562 // XAccessibleMultiLineText
2563 sal_Int32 SAL_CALL AccessibleEditableTextPara::getLineNumberAtIndex( sal_Int32 nIndex )
2566 sal_Int32 nRes = -1;
2567 sal_Int32 nPara = GetParagraphIndex();
2569 SvxTextForwarder &rCacheTF = GetTextForwarder();
2570 const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
2571 DBG_ASSERT( bValidPara, "getLineNumberAtIndex: current paragraph index out of range" );
2572 if (bValidPara)
2574 // we explicitly allow for the index to point at the character right behind the text
2575 if (0 > nIndex || nIndex > rCacheTF.GetTextLen( nPara ))
2576 throw lang::IndexOutOfBoundsException();
2577 nRes = rCacheTF.GetLineNumberAtIndex( nPara, nIndex );
2579 return nRes;
2582 // XAccessibleMultiLineText
2583 css::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineNumber( sal_Int32 nLineNo )
2586 css::accessibility::TextSegment aResult;
2587 sal_Int32 nPara = GetParagraphIndex();
2588 SvxTextForwarder &rCacheTF = GetTextForwarder();
2589 const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
2590 DBG_ASSERT( bValidPara, "getTextAtLineNumber: current paragraph index out of range" );
2591 if (bValidPara)
2593 if (0 > nLineNo || nLineNo >= rCacheTF.GetLineCount( nPara ))
2594 throw lang::IndexOutOfBoundsException();
2595 sal_Int32 nStart = 0, nEnd = 0;
2596 rCacheTF.GetLineBoundaries( nStart, nEnd, nPara, nLineNo );
2597 if (nStart >= 0 && nEnd >= 0)
2601 aResult.SegmentText = getTextRange( nStart, nEnd );
2602 aResult.SegmentStart = nStart;
2603 aResult.SegmentEnd = nEnd;
2605 catch (const lang::IndexOutOfBoundsException&)
2607 // this is not the exception that should be raised in this function ...
2608 DBG_UNHANDLED_EXCEPTION("editeng");
2612 return aResult;
2615 // XAccessibleMultiLineText
2616 css::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineWithCaret( )
2619 css::accessibility::TextSegment aResult;
2622 aResult = getTextAtLineNumber( getNumberOfLineWithCaret() );
2624 catch (const lang::IndexOutOfBoundsException&)
2626 // this one needs to be caught since this interface does not allow for it.
2628 return aResult;
2631 // XAccessibleMultiLineText
2632 sal_Int32 SAL_CALL AccessibleEditableTextPara::getNumberOfLineWithCaret( )
2635 sal_Int32 nRes = -1;
2638 nRes = getLineNumberAtIndex( getCaretPosition() );
2640 catch (const lang::IndexOutOfBoundsException&)
2642 // this one needs to be caught since this interface does not allow for it.
2644 return nRes;
2648 // XServiceInfo
2649 OUString SAL_CALL AccessibleEditableTextPara::getImplementationName()
2652 return u"AccessibleEditableTextPara"_ustr;
2655 sal_Bool SAL_CALL AccessibleEditableTextPara::supportsService (const OUString& sServiceName)
2658 return cppu::supportsService(this, sServiceName);
2661 uno::Sequence< OUString> SAL_CALL AccessibleEditableTextPara::getSupportedServiceNames()
2663 // #105185# Using correct service now
2664 return { u"com.sun.star.text.AccessibleParagraphView"_ustr };
2667 } // end of namespace accessibility
2670 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */