22#include <com/sun/star/accessibility/AccessibleTextType.hpp>
23#include <com/sun/star/i18n/BreakIterator.hpp>
24#include <com/sun/star/i18n/CharacterIteratorMode.hpp>
25#include <com/sun/star/i18n/CharacterClassification.hpp>
26#include <com/sun/star/i18n/WordType.hpp>
27#include <com/sun/star/i18n/KCharacterType.hpp>
28#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
30#include <com/sun/star/accessibility/TextSegment.hpp>
84 return ( rBoundary.startPos >= 0 ) && ( rBoundary.startPos <
nLength ) && ( rBoundary.endPos >= 0 ) && ( rBoundary.endPos <=
nLength );
96 return ( nStartIndex >= 0 ) && ( nStartIndex <=
nLength ) && ( nEndIndex >= 0 ) && ( nEndIndex <=
nLength );
105 if ( xBreakIter.is() )
109 sal_Int32 nStartIndex = xBreakIter->previousCharacters( rText,
nIndex,
implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL,
nCount, nDone );
111 nStartIndex = xBreakIter->nextCharacters( rText, nStartIndex,
implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL,
nCount, nDone );
112 sal_Int32 nEndIndex = xBreakIter->nextCharacters( rText, nStartIndex,
implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL,
nCount, nDone );
115 rBoundary.startPos = nStartIndex;
116 rBoundary.endPos = nEndIndex;
122 rBoundary.startPos =
nIndex;
123 rBoundary.endPos =
nIndex;
135 if ( xBreakIter.is() )
137 rBoundary = xBreakIter->getWordBoundary( rText,
nIndex,
implGetLocale(), i18n::WordType::ANY_WORD,
true );
141 if ( xCharClass.is() )
143 sal_Int32
nType = xCharClass->getCharacterType( rText, rBoundary.startPos,
implGetLocale() );
144 if ( (
nType & ( i18n::KCharacterType::LETTER | i18n::KCharacterType::DIGIT ) ) != 0 )
151 rBoundary.startPos =
nIndex;
152 rBoundary.endPos =
nIndex;
165 if ( xBreakIter.is() )
167 rBoundary.endPos = xBreakIter->endOfSentence( rText,
nIndex, aLocale );
168 rBoundary.startPos = xBreakIter->beginOfSentence( rText, rBoundary.endPos, aLocale );
173 rBoundary.startPos =
nIndex;
174 rBoundary.endPos =
nIndex;
183 rBoundary.startPos = 0;
184 rBoundary.endPos = rText.getLength();
186 sal_Int32 nFound = rText.lastIndexOf(
'\n',
nIndex );
188 rBoundary.startPos = nFound + 1;
190 nFound = rText.indexOf(
'\n',
nIndex );
192 rBoundary.endPos = nFound + 1;
196 rBoundary.startPos =
nIndex;
197 rBoundary.endPos =
nIndex;
204 sal_Int32
nLength = rText.getLength();
208 rBoundary.startPos = 0;
213 rBoundary.startPos =
nIndex;
214 rBoundary.endPos =
nIndex;
222 throw IndexOutOfBoundsException();
230 sal_Int32 nStartIndex;
239 catch ( IndexOutOfBoundsException& )
249 sal_Int32 nStartIndex;
260 sal_Int32 nStartIndex;
273 throw IndexOutOfBoundsException();
275 sal_Int32 nMinIndex = std::min( nStartIndex, nEndIndex );
276 sal_Int32 nMaxIndex = std::max( nStartIndex, nEndIndex );
278 return OUString(rText.substr( nMinIndex, nMaxIndex - nMinIndex ));
284 sal_Int32
nLength = sText.getLength();
287 throw IndexOutOfBoundsException();
289 i18n::Boundary aBoundary;
291 aResult.SegmentStart = -1;
292 aResult.SegmentEnd = -1;
296 case AccessibleTextType::CHARACTER:
301 sText.iterateCodePoints(&nIndexEnd);
303 aResult.SegmentText = sText.copy(
nIndex, nIndexEnd -
nIndex );
304 aResult.SegmentStart =
nIndex;
305 aResult.SegmentEnd = nIndexEnd;
309 case AccessibleTextType::GLYPH:
315 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
316 aResult.SegmentStart = aBoundary.startPos;
317 aResult.SegmentEnd = aBoundary.endPos;
321 case AccessibleTextType::WORD:
327 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
328 aResult.SegmentStart = aBoundary.startPos;
329 aResult.SegmentEnd = aBoundary.endPos;
333 case AccessibleTextType::SENTENCE:
339 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
340 aResult.SegmentStart = aBoundary.startPos;
341 aResult.SegmentEnd = aBoundary.endPos;
345 case AccessibleTextType::PARAGRAPH:
351 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
352 aResult.SegmentStart = aBoundary.startPos;
353 aResult.SegmentEnd = aBoundary.endPos;
357 case AccessibleTextType::LINE:
363 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
364 aResult.SegmentStart = aBoundary.startPos;
365 aResult.SegmentEnd = aBoundary.endPos;
369 case AccessibleTextType::ATTRIBUTE_RUN:
373 aResult.SegmentText = sText;
374 aResult.SegmentStart = 0;
391 sal_Int32
nLength = sText.getLength();
394 throw IndexOutOfBoundsException();
396 i18n::Boundary aBoundary;
398 aResult.SegmentStart = -1;
399 aResult.SegmentEnd = -1;
403 case AccessibleTextType::CHARACTER:
407 sText.iterateCodePoints(&
nIndex, -1);
409 sText.iterateCodePoints(&nIndexEnd);
410 aResult.SegmentText = sText.copy(
nIndex, nIndexEnd -
nIndex);
411 aResult.SegmentStart =
nIndex;
412 aResult.SegmentEnd = nIndexEnd;
416 case AccessibleTextType::GLYPH:
421 if ( aBoundary.startPos > 0 )
426 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
427 aResult.SegmentStart = aBoundary.startPos;
428 aResult.SegmentEnd = aBoundary.endPos;
433 case AccessibleTextType::WORD:
439 while ( !bWord && aBoundary.startPos > 0 )
443 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
444 aResult.SegmentStart = aBoundary.startPos;
445 aResult.SegmentEnd = aBoundary.endPos;
449 case AccessibleTextType::SENTENCE:
454 if ( aBoundary.startPos > 0 )
459 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
460 aResult.SegmentStart = aBoundary.startPos;
461 aResult.SegmentEnd = aBoundary.endPos;
466 case AccessibleTextType::PARAGRAPH:
471 if ( aBoundary.startPos > 0 )
476 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
477 aResult.SegmentStart = aBoundary.startPos;
478 aResult.SegmentEnd = aBoundary.endPos;
483 case AccessibleTextType::LINE:
488 if ( aBoundary.startPos > 0 )
493 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
494 aResult.SegmentStart = aBoundary.startPos;
495 aResult.SegmentEnd = aBoundary.endPos;
500 case AccessibleTextType::ATTRIBUTE_RUN:
518 sal_Int32
nLength = sText.getLength();
521 throw IndexOutOfBoundsException();
523 i18n::Boundary aBoundary;
525 aResult.SegmentStart = -1;
526 aResult.SegmentEnd = -1;
530 case AccessibleTextType::CHARACTER:
534 sText.iterateCodePoints(&
nIndex);
536 sText.iterateCodePoints(&nIndexEnd);
537 aResult.SegmentText = sText.copy(
nIndex, nIndexEnd -
nIndex);
538 aResult.SegmentStart =
nIndex;
539 aResult.SegmentEnd = nIndexEnd;
543 case AccessibleTextType::GLYPH:
548 if ( aBoundary.endPos <
nLength )
553 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
554 aResult.SegmentStart = aBoundary.startPos;
555 aResult.SegmentEnd = aBoundary.endPos;
560 case AccessibleTextType::WORD:
566 while ( !bWord && aBoundary.endPos <
nLength )
570 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
571 aResult.SegmentStart = aBoundary.startPos;
572 aResult.SegmentEnd = aBoundary.endPos;
576 case AccessibleTextType::SENTENCE:
581 sal_Int32 nEnd = aBoundary.endPos;
582 sal_Int32 nI = aBoundary.endPos;
584 while ( !bFound && ++nI <
nLength )
587 bFound = ( aBoundary.endPos > nEnd );
591 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
592 aResult.SegmentStart = aBoundary.startPos;
593 aResult.SegmentEnd = aBoundary.endPos;
597 case AccessibleTextType::PARAGRAPH:
602 if ( aBoundary.endPos <
nLength )
607 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
608 aResult.SegmentStart = aBoundary.startPos;
609 aResult.SegmentEnd = aBoundary.endPos;
614 case AccessibleTextType::LINE:
619 if ( aBoundary.endPos <
nLength )
624 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
625 aResult.SegmentStart = aBoundary.startPos;
626 aResult.SegmentEnd = aBoundary.endPos;
631 case AccessibleTextType::ATTRIBUTE_RUN:
647 std::u16string_view rOldString,
648 std::u16string_view rNewString,
649 css::uno::Any& rDeleted,
650 css::uno::Any& rInserted)
652 size_t nLenOld = rOldString.size();
653 size_t nLenNew = rNewString.size();
656 if ((0 == nLenOld) && (0 == nLenNew))
659 TextSegment aDeletedText;
660 TextSegment aInsertedText;
662 aDeletedText.SegmentStart = -1;
663 aDeletedText.SegmentEnd = -1;
664 aInsertedText.SegmentStart = -1;
665 aInsertedText.SegmentEnd = -1;
668 if ((0 == nLenOld) && (nLenNew > 0))
670 aInsertedText.SegmentStart = 0;
671 aInsertedText.SegmentEnd = nLenNew;
672 aInsertedText.SegmentText = rNewString.substr( aInsertedText.SegmentStart, aInsertedText.SegmentEnd - aInsertedText.SegmentStart );
674 rInserted <<= aInsertedText;
679 if ((nLenOld > 0) && (0 == nLenNew))
681 aDeletedText.SegmentStart = 0;
682 aDeletedText.SegmentEnd = nLenOld;
683 aDeletedText.SegmentText = rOldString.substr( aDeletedText.SegmentStart, aDeletedText.SegmentEnd - aDeletedText.SegmentStart );
685 rDeleted <<= aDeletedText;
689 auto pFirstDiffOld = rOldString.begin();
690 auto pLastDiffOld = rOldString.end();
691 auto pFirstDiffNew = rNewString.begin();
692 auto pLastDiffNew = rNewString.end();
695 while ((pFirstDiffOld < pLastDiffOld) && (pFirstDiffNew < pLastDiffNew)
696 && (*pFirstDiffOld == *pFirstDiffNew))
703 if (pFirstDiffOld == pLastDiffOld && pFirstDiffNew == pLastDiffNew)
707 while ( ( pLastDiffOld > pFirstDiffOld) &&
708 ( pLastDiffNew > pFirstDiffNew) &&
709 (pLastDiffOld[-1] == pLastDiffNew[-1]))
715 if (pFirstDiffOld < pLastDiffOld)
717 aDeletedText.SegmentStart = pFirstDiffOld - rOldString.begin();
718 aDeletedText.SegmentEnd = pLastDiffOld - rOldString.begin();
719 aDeletedText.SegmentText = rOldString.substr( aDeletedText.SegmentStart, aDeletedText.SegmentEnd - aDeletedText.SegmentStart );
721 rDeleted <<= aDeletedText;
724 if (pFirstDiffNew < pLastDiffNew)
726 aInsertedText.SegmentStart = pFirstDiffNew - rNewString.begin();
727 aInsertedText.SegmentEnd = pLastDiffNew - rNewString.begin();
728 aInsertedText.SegmentText = rNewString.substr( aInsertedText.SegmentStart, aInsertedText.SegmentEnd - aInsertedText.SegmentStart );
730 rInserted <<= aInsertedText;
virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
virtual sal_Int32 SAL_CALL getSelectionEnd() override
virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
virtual sal_Int32 SAL_CALL getSelectionStart() override
virtual OUString SAL_CALL getSelectedText() override
css::uno::Reference< css::i18n::XBreakIterator > m_xBreakIter
css::accessibility::TextSegment getTextBeforeIndex(sal_Int32 nIndex, sal_Int16 aTextType)
static bool implIsValidBoundary(css::i18n::Boundary const &rBoundary, sal_Int32 nLength)
virtual void implGetParagraphBoundary(const OUString &rText, css::i18n::Boundary &rBoundary, sal_Int32 nIndex)
css::accessibility::TextSegment getTextAtIndex(sal_Int32 nIndex, sal_Int16 aTextType)
virtual OUString implGetText()=0
sal_Int32 getSelectionEnd()
static bool implIsValidIndex(sal_Int32 nIndex, sal_Int32 nLength)
virtual ~OCommonAccessibleText()
static bool implIsValidRange(sal_Int32 nStartIndex, sal_Int32 nEndIndex, sal_Int32 nLength)
css::uno::Reference< css::i18n::XBreakIterator > const & implGetBreakIterator()
virtual void implGetLineBoundary(const OUString &rText, css::i18n::Boundary &rBoundary, sal_Int32 nIndex)
css::uno::Reference< css::i18n::XCharacterClassification > const & implGetCharacterClassification()
bool implGetWordBoundary(const OUString &rText, css::i18n::Boundary &rBoundary, sal_Int32 nIndex)
OUString getSelectedText()
non-virtual versions of the methods
static bool implInitTextChangedEvent(std::u16string_view rOldString, std::u16string_view rNewString, css::uno::Any &rDeleted, css::uno::Any &rInserted)
Helper method, that detects the difference between two strings and returns the deleted selection and ...
virtual void implGetSelection(sal_Int32 &nStartIndex, sal_Int32 &nEndIndex)=0
static sal_Unicode implGetCharacter(std::u16string_view rText, sal_Int32 nIndex)
virtual css::lang::Locale implGetLocale()=0
css::uno::Reference< css::i18n::XCharacterClassification > m_xCharClass
void implGetGlyphBoundary(const OUString &rText, css::i18n::Boundary &rBoundary, sal_Int32 nIndex)
css::accessibility::TextSegment getTextBehindIndex(sal_Int32 nIndex, sal_Int16 aTextType)
sal_Int32 getSelectionStart()
void implGetSentenceBoundary(const OUString &rText, css::i18n::Boundary &rBoundary, sal_Int32 nIndex)
static OUString implGetTextRange(std::u16string_view rText, sal_Int32 nStartIndex, sal_Int32 nEndIndex)
Reference< XComponentContext > getProcessComponentContext()
This function gets the process service factory's default component context.