1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <comphelper/accessibletexthelper.hxx>
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 <comphelper/processfactory.hxx>
28 #include <com/sun/star/accessibility/TextSegment.hpp>
32 //..............................................................................
35 //..............................................................................
37 using namespace ::com::sun::star
;
38 using namespace ::com::sun::star::uno
;
39 using namespace ::com::sun::star::lang
;
40 using namespace ::com::sun::star::beans
;
41 using namespace ::com::sun::star::accessibility
;
43 //==============================================================================
44 // OCommonAccessibleText
45 //==============================================================================
47 OCommonAccessibleText::OCommonAccessibleText()
51 // -----------------------------------------------------------------------------
53 OCommonAccessibleText::~OCommonAccessibleText()
57 // -----------------------------------------------------------------------------
59 Reference
< i18n::XBreakIterator
> OCommonAccessibleText::implGetBreakIterator()
61 if ( !m_xBreakIter
.is() )
63 Reference
< uno::XComponentContext
> xContext
= ::comphelper::getProcessComponentContext();
64 m_xBreakIter
= i18n::BreakIterator::create(xContext
);
70 // -----------------------------------------------------------------------------
72 Reference
< i18n::XCharacterClassification
> OCommonAccessibleText::implGetCharacterClassification()
74 if ( !m_xCharClass
.is() )
76 m_xCharClass
= i18n::CharacterClassification::create( ::comphelper::getProcessComponentContext() );
82 // -----------------------------------------------------------------------------
84 sal_Bool
OCommonAccessibleText::implIsValidBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nLength
)
86 return ( rBoundary
.startPos
>= 0 ) && ( rBoundary
.startPos
< nLength
) && ( rBoundary
.endPos
>= 0 ) && ( rBoundary
.endPos
<= nLength
);
89 // -----------------------------------------------------------------------------
91 sal_Bool
OCommonAccessibleText::implIsValidIndex( sal_Int32 nIndex
, sal_Int32 nLength
)
93 return ( nIndex
>= 0 ) && ( nIndex
< nLength
);
96 // -----------------------------------------------------------------------------
98 sal_Bool
OCommonAccessibleText::implIsValidRange( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
, sal_Int32 nLength
)
100 return ( nStartIndex
>= 0 ) && ( nStartIndex
<= nLength
) && ( nEndIndex
>= 0 ) && ( nEndIndex
<= nLength
);
103 // -----------------------------------------------------------------------------
105 void OCommonAccessibleText::implGetGlyphBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
107 ::rtl::OUString
sText( implGetText() );
109 if ( implIsValidIndex( nIndex
, sText
.getLength() ) )
111 Reference
< i18n::XBreakIterator
> xBreakIter
= implGetBreakIterator();
112 if ( xBreakIter
.is() )
114 sal_Int32 nCount
= 1;
116 sal_Int32 nStartIndex
= xBreakIter
->previousCharacters( sText
, nIndex
, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL
, nCount
, nDone
);
118 nStartIndex
= xBreakIter
->nextCharacters( sText
, nStartIndex
, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL
, nCount
, nDone
);
119 sal_Int32 nEndIndex
= xBreakIter
->nextCharacters( sText
, nStartIndex
, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL
, nCount
, nDone
);
122 rBoundary
.startPos
= nStartIndex
;
123 rBoundary
.endPos
= nEndIndex
;
129 rBoundary
.startPos
= nIndex
;
130 rBoundary
.endPos
= nIndex
;
134 // -----------------------------------------------------------------------------
136 sal_Bool
OCommonAccessibleText::implGetWordBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
138 sal_Bool bWord
= sal_False
;
139 ::rtl::OUString
sText( implGetText() );
141 if ( implIsValidIndex( nIndex
, sText
.getLength() ) )
143 Reference
< i18n::XBreakIterator
> xBreakIter
= implGetBreakIterator();
144 if ( xBreakIter
.is() )
146 rBoundary
= xBreakIter
->getWordBoundary( sText
, nIndex
, implGetLocale(), i18n::WordType::ANY_WORD
, sal_True
);
148 // it's a word, if the first character is an alpha-numeric character
149 Reference
< i18n::XCharacterClassification
> xCharClass
= implGetCharacterClassification();
150 if ( xCharClass
.is() )
152 sal_Int32 nType
= xCharClass
->getCharacterType( sText
, rBoundary
.startPos
, implGetLocale() );
153 if ( ( nType
& ( i18n::KCharacterType::LETTER
| i18n::KCharacterType::DIGIT
) ) != 0 )
160 rBoundary
.startPos
= nIndex
;
161 rBoundary
.endPos
= nIndex
;
167 // -----------------------------------------------------------------------------
169 void OCommonAccessibleText::implGetSentenceBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
171 ::rtl::OUString
sText( implGetText() );
173 if ( implIsValidIndex( nIndex
, sText
.getLength() ) )
175 Locale aLocale
= implGetLocale();
176 Reference
< i18n::XBreakIterator
> xBreakIter
= implGetBreakIterator();
177 if ( xBreakIter
.is() )
179 rBoundary
.endPos
= xBreakIter
->endOfSentence( sText
, nIndex
, aLocale
);
180 rBoundary
.startPos
= xBreakIter
->beginOfSentence( sText
, rBoundary
.endPos
, aLocale
);
185 rBoundary
.startPos
= nIndex
;
186 rBoundary
.endPos
= nIndex
;
190 // -----------------------------------------------------------------------------
192 void OCommonAccessibleText::implGetParagraphBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
194 ::rtl::OUString
sText( implGetText() );
196 if ( implIsValidIndex( nIndex
, sText
.getLength() ) )
198 rBoundary
.startPos
= 0;
199 rBoundary
.endPos
= sText
.getLength();
201 sal_Int32 nFound
= sText
.lastIndexOf( (sal_Unicode
)'\n', nIndex
);
203 rBoundary
.startPos
= nFound
+ 1;
205 nFound
= sText
.indexOf( (sal_Unicode
)'\n', nIndex
);
207 rBoundary
.endPos
= nFound
+ 1;
211 rBoundary
.startPos
= nIndex
;
212 rBoundary
.endPos
= nIndex
;
216 // -----------------------------------------------------------------------------
218 void OCommonAccessibleText::implGetLineBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
220 ::rtl::OUString
sText( implGetText() );
221 sal_Int32 nLength
= sText
.getLength();
223 if ( implIsValidIndex( nIndex
, nLength
) || nIndex
== nLength
)
225 rBoundary
.startPos
= 0;
226 rBoundary
.endPos
= nLength
;
230 rBoundary
.startPos
= nIndex
;
231 rBoundary
.endPos
= nIndex
;
235 // -----------------------------------------------------------------------------
237 sal_Unicode
OCommonAccessibleText::getCharacter( sal_Int32 nIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
239 ::rtl::OUString
sText( implGetText() );
241 if ( !implIsValidIndex( nIndex
, sText
.getLength() ) )
242 throw IndexOutOfBoundsException();
244 return sText
.getStr()[nIndex
];
247 // -----------------------------------------------------------------------------
249 sal_Int32
OCommonAccessibleText::getCharacterCount() throw (RuntimeException
)
251 return implGetText().getLength();
254 // -----------------------------------------------------------------------------
256 ::rtl::OUString
OCommonAccessibleText::getSelectedText() throw (RuntimeException
)
258 ::rtl::OUString sText
;
259 sal_Int32 nStartIndex
;
262 implGetSelection( nStartIndex
, nEndIndex
);
266 sText
= getTextRange( nStartIndex
, nEndIndex
);
268 catch ( IndexOutOfBoundsException
& )
275 // -----------------------------------------------------------------------------
277 sal_Int32
OCommonAccessibleText::getSelectionStart() throw (RuntimeException
)
279 sal_Int32 nStartIndex
;
282 implGetSelection( nStartIndex
, nEndIndex
);
287 // -----------------------------------------------------------------------------
289 sal_Int32
OCommonAccessibleText::getSelectionEnd() throw (RuntimeException
)
291 sal_Int32 nStartIndex
;
294 implGetSelection( nStartIndex
, nEndIndex
);
299 // -----------------------------------------------------------------------------
301 ::rtl::OUString
OCommonAccessibleText::getText() throw (RuntimeException
)
303 return implGetText();
306 // -----------------------------------------------------------------------------
308 ::rtl::OUString
OCommonAccessibleText::getTextRange( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
310 ::rtl::OUString
sText( implGetText() );
312 if ( !implIsValidRange( nStartIndex
, nEndIndex
, sText
.getLength() ) )
313 throw IndexOutOfBoundsException();
315 sal_Int32 nMinIndex
= ::std::min( nStartIndex
, nEndIndex
);
316 sal_Int32 nMaxIndex
= ::std::max( nStartIndex
, nEndIndex
);
318 return sText
.copy( nMinIndex
, nMaxIndex
- nMinIndex
);
321 // -----------------------------------------------------------------------------
323 TextSegment
OCommonAccessibleText::getTextAtIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
325 ::rtl::OUString
sText( implGetText() );
326 sal_Int32 nLength
= sText
.getLength();
328 if ( !implIsValidIndex( nIndex
, nLength
) && nIndex
!= nLength
)
329 throw IndexOutOfBoundsException();
331 i18n::Boundary aBoundary
;
333 aResult
.SegmentStart
= -1;
334 aResult
.SegmentEnd
= -1;
338 case AccessibleTextType::CHARACTER
:
340 if ( implIsValidIndex( nIndex
, nLength
) )
342 aResult
.SegmentText
= sText
.copy( nIndex
, 1 );
343 aResult
.SegmentStart
= nIndex
;
344 aResult
.SegmentEnd
= nIndex
+1;
348 case AccessibleTextType::GLYPH
:
350 // get glyph at index
351 implGetGlyphBoundary( aBoundary
, nIndex
);
352 if ( implIsValidBoundary( aBoundary
, nLength
) )
354 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
355 aResult
.SegmentStart
= aBoundary
.startPos
;
356 aResult
.SegmentEnd
= aBoundary
.endPos
;
360 case AccessibleTextType::WORD
:
363 sal_Bool bWord
= implGetWordBoundary( aBoundary
, nIndex
);
364 if ( bWord
&& implIsValidBoundary( aBoundary
, nLength
) )
366 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
367 aResult
.SegmentStart
= aBoundary
.startPos
;
368 aResult
.SegmentEnd
= aBoundary
.endPos
;
372 case AccessibleTextType::SENTENCE
:
374 // get sentence at index
375 implGetSentenceBoundary( aBoundary
, nIndex
);
376 if ( implIsValidBoundary( aBoundary
, nLength
) )
378 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
379 aResult
.SegmentStart
= aBoundary
.startPos
;
380 aResult
.SegmentEnd
= aBoundary
.endPos
;
384 case AccessibleTextType::PARAGRAPH
:
386 // get paragraph at index
387 implGetParagraphBoundary( aBoundary
, nIndex
);
388 if ( implIsValidBoundary( aBoundary
, nLength
) )
390 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
391 aResult
.SegmentStart
= aBoundary
.startPos
;
392 aResult
.SegmentEnd
= aBoundary
.endPos
;
396 case AccessibleTextType::LINE
:
399 implGetLineBoundary( aBoundary
, nIndex
);
400 if ( implIsValidBoundary( aBoundary
, nLength
) )
402 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
403 aResult
.SegmentStart
= aBoundary
.startPos
;
404 aResult
.SegmentEnd
= aBoundary
.endPos
;
408 case AccessibleTextType::ATTRIBUTE_RUN
:
410 // TODO: implGetAttributeRunBoundary() (incompatible!)
412 aResult
.SegmentText
= sText
;
413 aResult
.SegmentStart
= 0;
414 aResult
.SegmentEnd
= nLength
;
426 // -----------------------------------------------------------------------------
428 TextSegment
OCommonAccessibleText::getTextBeforeIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
430 ::rtl::OUString
sText( implGetText() );
431 sal_Int32 nLength
= sText
.getLength();
433 if ( !implIsValidIndex( nIndex
, nLength
) && nIndex
!= nLength
)
434 throw IndexOutOfBoundsException();
436 i18n::Boundary aBoundary
;
438 aResult
.SegmentStart
= -1;
439 aResult
.SegmentEnd
= -1;
443 case AccessibleTextType::CHARACTER
:
445 if ( implIsValidIndex( nIndex
- 1, nLength
) )
447 aResult
.SegmentText
= sText
.copy( nIndex
- 1, 1 );
448 aResult
.SegmentStart
= nIndex
-1;
449 aResult
.SegmentEnd
= nIndex
;
453 case AccessibleTextType::GLYPH
:
455 // get glyph at index
456 implGetGlyphBoundary( aBoundary
, nIndex
);
457 // get previous glyph
458 if ( aBoundary
.startPos
> 0 )
460 implGetGlyphBoundary( aBoundary
, aBoundary
.startPos
- 1 );
461 if ( implIsValidBoundary( aBoundary
, nLength
) )
463 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
464 aResult
.SegmentStart
= aBoundary
.startPos
;
465 aResult
.SegmentEnd
= aBoundary
.endPos
;
470 case AccessibleTextType::WORD
:
473 implGetWordBoundary( aBoundary
, nIndex
);
475 sal_Bool bWord
= sal_False
;
476 while ( !bWord
&& aBoundary
.startPos
> 0 )
477 bWord
= implGetWordBoundary( aBoundary
, aBoundary
.startPos
- 1 );
478 if ( bWord
&& implIsValidBoundary( aBoundary
, nLength
) )
480 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
481 aResult
.SegmentStart
= aBoundary
.startPos
;
482 aResult
.SegmentEnd
= aBoundary
.endPos
;
486 case AccessibleTextType::SENTENCE
:
488 // get sentence at index
489 implGetSentenceBoundary( aBoundary
, nIndex
);
490 // get previous sentence
491 if ( aBoundary
.startPos
> 0 )
493 implGetSentenceBoundary( aBoundary
, aBoundary
.startPos
- 1 );
494 if ( implIsValidBoundary( aBoundary
, nLength
) )
496 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
497 aResult
.SegmentStart
= aBoundary
.startPos
;
498 aResult
.SegmentEnd
= aBoundary
.endPos
;
503 case AccessibleTextType::PARAGRAPH
:
505 // get paragraph at index
506 implGetParagraphBoundary( aBoundary
, nIndex
);
507 // get previous paragraph
508 if ( aBoundary
.startPos
> 0 )
510 implGetParagraphBoundary( aBoundary
, aBoundary
.startPos
- 1 );
511 if ( implIsValidBoundary( aBoundary
, nLength
) )
513 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
514 aResult
.SegmentStart
= aBoundary
.startPos
;
515 aResult
.SegmentEnd
= aBoundary
.endPos
;
520 case AccessibleTextType::LINE
:
523 implGetLineBoundary( aBoundary
, nIndex
);
525 if ( aBoundary
.startPos
> 0 )
527 implGetLineBoundary( aBoundary
, aBoundary
.startPos
- 1 );
528 if ( implIsValidBoundary( aBoundary
, nLength
) )
530 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
531 aResult
.SegmentStart
= aBoundary
.startPos
;
532 aResult
.SegmentEnd
= aBoundary
.endPos
;
537 case AccessibleTextType::ATTRIBUTE_RUN
:
539 // TODO: implGetAttributeRunBoundary() (incompatible!)
551 // -----------------------------------------------------------------------------
553 TextSegment
OCommonAccessibleText::getTextBehindIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
555 ::rtl::OUString
sText( implGetText() );
556 sal_Int32 nLength
= sText
.getLength();
558 if ( !implIsValidIndex( nIndex
, nLength
) && nIndex
!= nLength
)
559 throw IndexOutOfBoundsException();
561 i18n::Boundary aBoundary
;
563 aResult
.SegmentStart
= -1;
564 aResult
.SegmentEnd
= -1;
568 case AccessibleTextType::CHARACTER
:
570 if ( implIsValidIndex( nIndex
+ 1, nLength
) )
572 aResult
.SegmentText
= sText
.copy( nIndex
+ 1, 1 );
573 aResult
.SegmentStart
= nIndex
+1;
574 aResult
.SegmentEnd
= nIndex
+2;
578 case AccessibleTextType::GLYPH
:
580 // get glyph at index
581 implGetGlyphBoundary( aBoundary
, nIndex
);
583 if ( aBoundary
.endPos
< nLength
)
585 implGetGlyphBoundary( aBoundary
, aBoundary
.endPos
);
586 if ( implIsValidBoundary( aBoundary
, nLength
) )
588 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
589 aResult
.SegmentStart
= aBoundary
.startPos
;
590 aResult
.SegmentEnd
= aBoundary
.endPos
;
595 case AccessibleTextType::WORD
:
598 implGetWordBoundary( aBoundary
, nIndex
);
600 sal_Bool bWord
= sal_False
;
601 while ( !bWord
&& aBoundary
.endPos
< nLength
)
602 bWord
= implGetWordBoundary( aBoundary
, aBoundary
.endPos
);
603 if ( bWord
&& implIsValidBoundary( aBoundary
, nLength
) )
605 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
606 aResult
.SegmentStart
= aBoundary
.startPos
;
607 aResult
.SegmentEnd
= aBoundary
.endPos
;
611 case AccessibleTextType::SENTENCE
:
613 // get sentence at index
614 implGetSentenceBoundary( aBoundary
, nIndex
);
616 sal_Int32 nEnd
= aBoundary
.endPos
;
617 sal_Int32 nI
= aBoundary
.endPos
;
618 sal_Bool bFound
= sal_False
;
619 while ( !bFound
&& ++nI
< nLength
)
621 implGetSentenceBoundary( aBoundary
, nI
);
622 bFound
= ( aBoundary
.endPos
> nEnd
);
624 if ( bFound
&& implIsValidBoundary( aBoundary
, nLength
) )
626 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
627 aResult
.SegmentStart
= aBoundary
.startPos
;
628 aResult
.SegmentEnd
= aBoundary
.endPos
;
632 case AccessibleTextType::PARAGRAPH
:
634 // get paragraph at index
635 implGetParagraphBoundary( aBoundary
, nIndex
);
636 // get next paragraph
637 if ( aBoundary
.endPos
< nLength
)
639 implGetParagraphBoundary( aBoundary
, aBoundary
.endPos
);
640 if ( implIsValidBoundary( aBoundary
, nLength
) )
642 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
643 aResult
.SegmentStart
= aBoundary
.startPos
;
644 aResult
.SegmentEnd
= aBoundary
.endPos
;
649 case AccessibleTextType::LINE
:
652 implGetLineBoundary( aBoundary
, nIndex
);
654 if ( aBoundary
.endPos
< nLength
)
656 implGetLineBoundary( aBoundary
, aBoundary
.endPos
);
657 if ( implIsValidBoundary( aBoundary
, nLength
) )
659 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
660 aResult
.SegmentStart
= aBoundary
.startPos
;
661 aResult
.SegmentEnd
= aBoundary
.endPos
;
666 case AccessibleTextType::ATTRIBUTE_RUN
:
668 // TODO: implGetAttributeRunBoundary() (incompatible!)
680 // -----------------------------------------------------------------------------
681 bool OCommonAccessibleText::implInitTextChangedEvent(
682 const rtl::OUString
& rOldString
,
683 const rtl::OUString
& rNewString
,
684 ::com::sun::star::uno::Any
& rDeleted
,
685 ::com::sun::star::uno::Any
& rInserted
) // throw()
687 sal_uInt32 nLenOld
= rOldString
.getLength();
688 sal_uInt32 nLenNew
= rNewString
.getLength();
691 if ((0 == nLenOld
) && (0 == nLenNew
))
694 TextSegment aDeletedText
;
695 TextSegment aInsertedText
;
697 aDeletedText
.SegmentStart
= -1;
698 aDeletedText
.SegmentEnd
= -1;
699 aInsertedText
.SegmentStart
= -1;
700 aInsertedText
.SegmentEnd
= -1;
703 if ((0 == nLenOld
) && (nLenNew
> 0))
705 aInsertedText
.SegmentStart
= 0;
706 aInsertedText
.SegmentEnd
= nLenNew
;
707 aInsertedText
.SegmentText
= rNewString
.copy( aInsertedText
.SegmentStart
, aInsertedText
.SegmentEnd
- aInsertedText
.SegmentStart
);
709 rInserted
<<= aInsertedText
;
714 if ((nLenOld
> 0) && (0 == nLenNew
))
716 aDeletedText
.SegmentStart
= 0;
717 aDeletedText
.SegmentEnd
= nLenOld
;
718 aDeletedText
.SegmentText
= rOldString
.copy( aDeletedText
.SegmentStart
, aDeletedText
.SegmentEnd
- aDeletedText
.SegmentStart
);
720 rDeleted
<<= aDeletedText
;
724 const sal_Unicode
* pFirstDiffOld
= rOldString
.getStr();
725 const sal_Unicode
* pLastDiffOld
= rOldString
.getStr() + nLenOld
;
726 const sal_Unicode
* pFirstDiffNew
= rNewString
.getStr();
727 const sal_Unicode
* pLastDiffNew
= rNewString
.getStr() + nLenNew
;
729 // find first difference
730 while ((*pFirstDiffOld
== *pFirstDiffNew
) &&
731 (pFirstDiffOld
< pLastDiffOld
) &&
732 (pFirstDiffNew
< pLastDiffNew
))
739 if ((0 == *pFirstDiffOld
) && (0 == *pFirstDiffNew
))
742 // find last difference
743 while ( ( pLastDiffOld
> pFirstDiffOld
) &&
744 ( pLastDiffNew
> pFirstDiffNew
) &&
745 (pLastDiffOld
[-1] == pLastDiffNew
[-1]))
751 if (pFirstDiffOld
< pLastDiffOld
)
753 aDeletedText
.SegmentStart
= pFirstDiffOld
- rOldString
.getStr();
754 aDeletedText
.SegmentEnd
= pLastDiffOld
- rOldString
.getStr();
755 aDeletedText
.SegmentText
= rOldString
.copy( aDeletedText
.SegmentStart
, aDeletedText
.SegmentEnd
- aDeletedText
.SegmentStart
);
757 rDeleted
<<= aDeletedText
;
760 if (pFirstDiffNew
< pLastDiffNew
)
762 aInsertedText
.SegmentStart
= pFirstDiffNew
- rNewString
.getStr();
763 aInsertedText
.SegmentEnd
= pLastDiffNew
- rNewString
.getStr();
764 aInsertedText
.SegmentText
= rNewString
.copy( aInsertedText
.SegmentStart
, aInsertedText
.SegmentEnd
- aInsertedText
.SegmentStart
);
766 rInserted
<<= aInsertedText
;
771 //==============================================================================
772 // OAccessibleTextHelper
773 //==============================================================================
775 OAccessibleTextHelper::OAccessibleTextHelper( IMutex
* _pExternalLock
)
776 :OAccessibleExtendedComponentHelper( _pExternalLock
)
780 // -----------------------------------------------------------------------------
782 // -----------------------------------------------------------------------------
784 IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleTextHelper
, OAccessibleExtendedComponentHelper
, OAccessibleTextHelper_Base
)
786 // -----------------------------------------------------------------------------
788 // -----------------------------------------------------------------------------
790 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleTextHelper
, OAccessibleExtendedComponentHelper
, OAccessibleTextHelper_Base
)
792 // -----------------------------------------------------------------------------
794 // -----------------------------------------------------------------------------
796 sal_Unicode
OAccessibleTextHelper::getCharacter( sal_Int32 nIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
798 OExternalLockGuard
aGuard( this );
800 return OCommonAccessibleText::getCharacter( nIndex
);
803 // -----------------------------------------------------------------------------
805 sal_Int32
OAccessibleTextHelper::getCharacterCount() throw (RuntimeException
)
807 OExternalLockGuard
aGuard( this );
809 return OCommonAccessibleText::getCharacterCount();
812 // -----------------------------------------------------------------------------
814 ::rtl::OUString
OAccessibleTextHelper::getSelectedText() throw (RuntimeException
)
816 OExternalLockGuard
aGuard( this );
818 return OCommonAccessibleText::getSelectedText();
821 // -----------------------------------------------------------------------------
823 sal_Int32
OAccessibleTextHelper::getSelectionStart() throw (RuntimeException
)
825 OExternalLockGuard
aGuard( this );
827 return OCommonAccessibleText::getSelectionStart();
830 // -----------------------------------------------------------------------------
832 sal_Int32
OAccessibleTextHelper::getSelectionEnd() throw (RuntimeException
)
834 OExternalLockGuard
aGuard( this );
836 return OCommonAccessibleText::getSelectionEnd();
839 // -----------------------------------------------------------------------------
841 ::rtl::OUString
OAccessibleTextHelper::getText() throw (RuntimeException
)
843 OExternalLockGuard
aGuard( this );
845 return OCommonAccessibleText::getText();
848 // -----------------------------------------------------------------------------
850 ::rtl::OUString
OAccessibleTextHelper::getTextRange( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
852 OExternalLockGuard
aGuard( this );
854 return OCommonAccessibleText::getTextRange( nStartIndex
, nEndIndex
);
857 // -----------------------------------------------------------------------------
859 TextSegment
OAccessibleTextHelper::getTextAtIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
861 OExternalLockGuard
aGuard( this );
863 return OCommonAccessibleText::getTextAtIndex( nIndex
, aTextType
);
866 // -----------------------------------------------------------------------------
868 TextSegment
OAccessibleTextHelper::getTextBeforeIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
870 OExternalLockGuard
aGuard( this );
872 return OCommonAccessibleText::getTextBeforeIndex( nIndex
, aTextType
);
875 // -----------------------------------------------------------------------------
877 TextSegment
OAccessibleTextHelper::getTextBehindIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
879 OExternalLockGuard
aGuard( this );
881 return OCommonAccessibleText::getTextBehindIndex( nIndex
, aTextType
);
884 // -----------------------------------------------------------------------------
886 //..............................................................................
887 } // namespace comphelper
888 //..............................................................................
890 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */