21 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
22 #include <com/sun/star/i18n/BreakIterator.hpp>
23 #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
24 #include <com/sun/star/i18n/CharacterClassification.hpp>
25 #include <com/sun/star/i18n/WordType.hpp>
26 #include <com/sun/star/i18n/KCharacterType.hpp>
27 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
29 #include <com/sun/star/accessibility/TextSegment.hpp>
83 return ( rBoundary.startPos >= 0 ) && ( rBoundary.startPos < nLength ) && ( rBoundary.endPos >= 0 ) && ( rBoundary.endPos <= nLength );
89 return ( nIndex >= 0 ) && ( nIndex < nLength );
95 return ( nStartIndex >= 0 ) && ( nStartIndex <= nLength ) && ( nEndIndex >= 0 ) && ( nEndIndex <= nLength );
104 if ( xBreakIter.is() )
108 sal_Int32 nStartIndex = xBreakIter->previousCharacters( rText, nIndex,
implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL, nCount, nDone );
110 nStartIndex = xBreakIter->nextCharacters( rText, nStartIndex,
implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL, nCount, nDone );
111 sal_Int32 nEndIndex = xBreakIter->nextCharacters( rText, nStartIndex,
implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL, nCount, nDone );
114 rBoundary.startPos = nStartIndex;
115 rBoundary.endPos = nEndIndex;
121 rBoundary.startPos = nIndex;
122 rBoundary.endPos = nIndex;
134 if ( xBreakIter.is() )
136 rBoundary = xBreakIter->getWordBoundary( rText, nIndex,
implGetLocale(), i18n::WordType::ANY_WORD,
true );
140 if ( xCharClass.is() )
142 sal_Int32
nType = xCharClass->getCharacterType( rText, rBoundary.startPos,
implGetLocale() );
143 if ( ( nType & ( i18n::KCharacterType::LETTER | i18n::KCharacterType::DIGIT ) ) != 0 )
150 rBoundary.startPos = nIndex;
151 rBoundary.endPos = nIndex;
164 if ( xBreakIter.is() )
166 rBoundary.endPos = xBreakIter->endOfSentence( rText, nIndex, aLocale );
167 rBoundary.startPos = xBreakIter->beginOfSentence( rText, rBoundary.endPos, aLocale );
172 rBoundary.startPos = nIndex;
173 rBoundary.endPos = nIndex;
182 rBoundary.startPos = 0;
183 rBoundary.endPos = rText.getLength();
185 sal_Int32 nFound = rText.lastIndexOf(
'\n', nIndex );
187 rBoundary.startPos = nFound + 1;
189 nFound = rText.indexOf(
'\n', nIndex );
191 rBoundary.endPos = nFound + 1;
195 rBoundary.startPos = nIndex;
196 rBoundary.endPos = nIndex;
203 sal_Int32
nLength = rText.getLength();
207 rBoundary.startPos = 0;
208 rBoundary.endPos = nLength;
212 rBoundary.startPos = nIndex;
213 rBoundary.endPos = nIndex;
221 throw IndexOutOfBoundsException();
223 return rText[nIndex];
229 sal_Int32 nStartIndex;
238 catch ( IndexOutOfBoundsException& )
248 sal_Int32 nStartIndex;
259 sal_Int32 nStartIndex;
272 throw IndexOutOfBoundsException();
274 sal_Int32 nMinIndex = std::min( nStartIndex, nEndIndex );
275 sal_Int32 nMaxIndex = std::max( nStartIndex, nEndIndex );
277 return OUString(rText.substr( nMinIndex, nMaxIndex - nMinIndex ));
283 sal_Int32
nLength = sText.getLength();
286 throw IndexOutOfBoundsException();
288 i18n::Boundary aBoundary;
290 aResult.SegmentStart = -1;
291 aResult.SegmentEnd = -1;
295 case AccessibleTextType::CHARACTER:
299 aResult.SegmentText = sText.copy( nIndex, 1 );
300 aResult.SegmentStart = nIndex;
301 aResult.SegmentEnd = nIndex+1;
305 case AccessibleTextType::GLYPH:
311 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
312 aResult.SegmentStart = aBoundary.startPos;
313 aResult.SegmentEnd = aBoundary.endPos;
317 case AccessibleTextType::WORD:
323 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
324 aResult.SegmentStart = aBoundary.startPos;
325 aResult.SegmentEnd = aBoundary.endPos;
329 case AccessibleTextType::SENTENCE:
335 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
336 aResult.SegmentStart = aBoundary.startPos;
337 aResult.SegmentEnd = aBoundary.endPos;
341 case AccessibleTextType::PARAGRAPH:
347 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
348 aResult.SegmentStart = aBoundary.startPos;
349 aResult.SegmentEnd = aBoundary.endPos;
353 case AccessibleTextType::LINE:
359 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
360 aResult.SegmentStart = aBoundary.startPos;
361 aResult.SegmentEnd = aBoundary.endPos;
365 case AccessibleTextType::ATTRIBUTE_RUN:
369 aResult.SegmentText = sText;
370 aResult.SegmentStart = 0;
371 aResult.SegmentEnd = nLength;
387 sal_Int32
nLength = sText.getLength();
390 throw IndexOutOfBoundsException();
392 i18n::Boundary aBoundary;
394 aResult.SegmentStart = -1;
395 aResult.SegmentEnd = -1;
399 case AccessibleTextType::CHARACTER:
403 aResult.SegmentText = sText.copy( nIndex - 1, 1 );
404 aResult.SegmentStart = nIndex-1;
405 aResult.SegmentEnd = nIndex;
409 case AccessibleTextType::GLYPH:
414 if ( aBoundary.startPos > 0 )
419 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
420 aResult.SegmentStart = aBoundary.startPos;
421 aResult.SegmentEnd = aBoundary.endPos;
426 case AccessibleTextType::WORD:
432 while ( !bWord && aBoundary.startPos > 0 )
436 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
437 aResult.SegmentStart = aBoundary.startPos;
438 aResult.SegmentEnd = aBoundary.endPos;
442 case AccessibleTextType::SENTENCE:
447 if ( aBoundary.startPos > 0 )
452 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
453 aResult.SegmentStart = aBoundary.startPos;
454 aResult.SegmentEnd = aBoundary.endPos;
459 case AccessibleTextType::PARAGRAPH:
464 if ( aBoundary.startPos > 0 )
469 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
470 aResult.SegmentStart = aBoundary.startPos;
471 aResult.SegmentEnd = aBoundary.endPos;
476 case AccessibleTextType::LINE:
481 if ( aBoundary.startPos > 0 )
486 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
487 aResult.SegmentStart = aBoundary.startPos;
488 aResult.SegmentEnd = aBoundary.endPos;
493 case AccessibleTextType::ATTRIBUTE_RUN:
511 sal_Int32
nLength = sText.getLength();
514 throw IndexOutOfBoundsException();
516 i18n::Boundary aBoundary;
518 aResult.SegmentStart = -1;
519 aResult.SegmentEnd = -1;
523 case AccessibleTextType::CHARACTER:
527 aResult.SegmentText = sText.copy( nIndex + 1, 1 );
528 aResult.SegmentStart = nIndex+1;
529 aResult.SegmentEnd = nIndex+2;
533 case AccessibleTextType::GLYPH:
538 if ( aBoundary.endPos < nLength )
543 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
544 aResult.SegmentStart = aBoundary.startPos;
545 aResult.SegmentEnd = aBoundary.endPos;
550 case AccessibleTextType::WORD:
556 while ( !bWord && aBoundary.endPos < nLength )
560 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
561 aResult.SegmentStart = aBoundary.startPos;
562 aResult.SegmentEnd = aBoundary.endPos;
566 case AccessibleTextType::SENTENCE:
571 sal_Int32 nEnd = aBoundary.endPos;
572 sal_Int32 nI = aBoundary.endPos;
574 while ( !bFound && ++nI < nLength )
577 bFound = ( aBoundary.endPos > nEnd );
581 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
582 aResult.SegmentStart = aBoundary.startPos;
583 aResult.SegmentEnd = aBoundary.endPos;
587 case AccessibleTextType::PARAGRAPH:
592 if ( aBoundary.endPos < nLength )
597 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
598 aResult.SegmentStart = aBoundary.startPos;
599 aResult.SegmentEnd = aBoundary.endPos;
604 case AccessibleTextType::LINE:
609 if ( aBoundary.endPos < nLength )
614 aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
615 aResult.SegmentStart = aBoundary.startPos;
616 aResult.SegmentEnd = aBoundary.endPos;
621 case AccessibleTextType::ATTRIBUTE_RUN:
637 std::u16string_view rOldString,
638 std::u16string_view rNewString,
639 css::uno::Any& rDeleted,
640 css::uno::Any& rInserted)
642 size_t nLenOld = rOldString.size();
643 size_t nLenNew = rNewString.size();
646 if ((0 == nLenOld) && (0 == nLenNew))
649 TextSegment aDeletedText;
650 TextSegment aInsertedText;
652 aDeletedText.SegmentStart = -1;
653 aDeletedText.SegmentEnd = -1;
654 aInsertedText.SegmentStart = -1;
655 aInsertedText.SegmentEnd = -1;
658 if ((0 == nLenOld) && (nLenNew > 0))
660 aInsertedText.SegmentStart = 0;
661 aInsertedText.SegmentEnd = nLenNew;
662 aInsertedText.SegmentText = rNewString.substr( aInsertedText.SegmentStart, aInsertedText.SegmentEnd - aInsertedText.SegmentStart );
664 rInserted <<= aInsertedText;
669 if ((nLenOld > 0) && (0 == nLenNew))
671 aDeletedText.SegmentStart = 0;
672 aDeletedText.SegmentEnd = nLenOld;
673 aDeletedText.SegmentText = rOldString.substr( aDeletedText.SegmentStart, aDeletedText.SegmentEnd - aDeletedText.SegmentStart );
675 rDeleted <<= aDeletedText;
679 auto pFirstDiffOld = rOldString.begin();
680 auto pLastDiffOld = rOldString.end();
681 auto pFirstDiffNew = rNewString.begin();
682 auto pLastDiffNew = rNewString.end();
685 while ((pFirstDiffOld < pLastDiffOld) && (pFirstDiffNew < pLastDiffNew)
686 && (*pFirstDiffOld == *pFirstDiffNew))
693 if (pFirstDiffOld == pLastDiffOld && pFirstDiffNew == pLastDiffNew)
697 while ( ( pLastDiffOld > pFirstDiffOld) &&
698 ( pLastDiffNew > pFirstDiffNew) &&
699 (pLastDiffOld[-1] == pLastDiffNew[-1]))
705 if (pFirstDiffOld < pLastDiffOld)
707 aDeletedText.SegmentStart = pFirstDiffOld - rOldString.begin();
708 aDeletedText.SegmentEnd = pLastDiffOld - rOldString.begin();
709 aDeletedText.SegmentText = rOldString.substr( aDeletedText.SegmentStart, aDeletedText.SegmentEnd - aDeletedText.SegmentStart );
711 rDeleted <<= aDeletedText;
714 if (pFirstDiffNew < pLastDiffNew)
716 aInsertedText.SegmentStart = pFirstDiffNew - rNewString.begin();
717 aInsertedText.SegmentEnd = pLastDiffNew - rNewString.begin();
718 aInsertedText.SegmentText = rNewString.substr( aInsertedText.SegmentStart, aInsertedText.SegmentEnd - aInsertedText.SegmentStart );
720 rInserted <<= aInsertedText;
749 OUString OAccessibleTextHelper::getSelectedText()
virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
static bool implIsValidRange(sal_Int32 nStartIndex, sal_Int32 nEndIndex, sal_Int32 nLength)
bool implGetWordBoundary(const OUString &rText, css::i18n::Boundary &rBoundary, sal_Int32 nIndex)
virtual ~OCommonAccessibleText()
virtual void implGetLineBoundary(const OUString &rText, css::i18n::Boundary &rBoundary, sal_Int32 nIndex)
static sal_Unicode implGetCharacter(std::u16string_view rText, sal_Int32 nIndex)
virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
sal_Int32 getSelectionStart()
static bool implIsValidBoundary(css::i18n::Boundary const &rBoundary, sal_Int32 nLength)
#define IMPLEMENT_FORWARD_XTYPEPROVIDER2(classname, baseclass1, baseclass2)
css::accessibility::TextSegment getTextAtIndex(sal_Int32 nIndex, sal_Int16 aTextType)
css::accessibility::TextSegment getTextBehindIndex(sal_Int32 nIndex, sal_Int16 aTextType)
virtual sal_Int32 SAL_CALL getSelectionEnd() override
virtual css::lang::Locale implGetLocale()=0
css::uno::Reference< css::i18n::XCharacterClassification > const & implGetCharacterClassification()
static OUString implGetTextRange(std::u16string_view rText, sal_Int32 nStartIndex, sal_Int32 nEndIndex)
a helper class for implementing an AccessibleExtendedComponent which at the same time supports an XAc...
virtual void implGetParagraphBoundary(const OUString &rText, css::i18n::Boundary &rBoundary, sal_Int32 nIndex)
css::uno::Reference< css::i18n::XBreakIterator > m_xBreakIter
void implGetGlyphBoundary(const OUString &rText, css::i18n::Boundary &rBoundary, sal_Int32 nIndex)
css::uno::Reference< css::i18n::XCharacterClassification > m_xCharClass
css::accessibility::TextSegment getTextBeforeIndex(sal_Int32 nIndex, sal_Int16 aTextType)
OUString getSelectedText()
non-virtual versions of the methods
static bool implIsValidIndex(sal_Int32 nIndex, sal_Int32 nLength)
#define IMPLEMENT_FORWARD_XINTERFACE2(classname, refcountbase, baseclass2)
css::uno::Reference< css::i18n::XBreakIterator > const & implGetBreakIterator()
sal_Int32 getSelectionEnd()
a helper class for implementing an AccessibleContext which at the same time supports an XAccessibleEx...
Reference< XComponentContext > getProcessComponentContext()
This function gets the process service factory's default component context.
virtual OUString implGetText()=0
void implGetSentenceBoundary(const OUString &rText, css::i18n::Boundary &rBoundary, sal_Int32 nIndex)
virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
virtual void implGetSelection(sal_Int32 &nStartIndex, sal_Int32 &nEndIndex)=0
virtual sal_Int32 SAL_CALL getSelectionStart() override
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 ...