1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_comphelper.hxx"
31 // includes --------------------------------------------------------------
32 #include <comphelper/accessibletexthelper.hxx>
33 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
34 #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
35 #ifndef _COM_SUN_STAR_TEXT_WORDTYPE_HPP_
36 #include <com/sun/star/i18n/WordType.hpp>
38 #include <com/sun/star/i18n/KCharacterType.hpp>
39 #include <comphelper/processfactory.hxx>
40 #include <com/sun/star/accessibility/TextSegment.hpp>
44 //..............................................................................
47 //..............................................................................
49 using namespace ::com::sun::star
;
50 using namespace ::com::sun::star::uno
;
51 using namespace ::com::sun::star::lang
;
52 using namespace ::com::sun::star::beans
;
53 using namespace ::com::sun::star::accessibility
;
55 //==============================================================================
56 // OCommonAccessibleText
57 //==============================================================================
59 OCommonAccessibleText::OCommonAccessibleText()
63 // -----------------------------------------------------------------------------
65 OCommonAccessibleText::~OCommonAccessibleText()
69 // -----------------------------------------------------------------------------
71 Reference
< i18n::XBreakIterator
> OCommonAccessibleText::implGetBreakIterator()
73 if ( !m_xBreakIter
.is() )
75 Reference
< lang::XMultiServiceFactory
> xMSF
= ::comphelper::getProcessServiceFactory();
78 m_xBreakIter
= Reference
< i18n::XBreakIterator
>
79 ( xMSF
->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.BreakIterator" ) ) ), UNO_QUERY
);
86 // -----------------------------------------------------------------------------
88 Reference
< i18n::XCharacterClassification
> OCommonAccessibleText::implGetCharacterClassification()
90 if ( !m_xCharClass
.is() )
92 Reference
< lang::XMultiServiceFactory
> xMSF
= ::comphelper::getProcessServiceFactory();
95 m_xCharClass
= Reference
< i18n::XCharacterClassification
>
96 ( xMSF
->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.CharacterClassification" ) ) ), UNO_QUERY
);
103 // -----------------------------------------------------------------------------
105 sal_Bool
OCommonAccessibleText::implIsValidBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nLength
)
107 return ( rBoundary
.startPos
>= 0 ) && ( rBoundary
.startPos
< nLength
) && ( rBoundary
.endPos
>= 0 ) && ( rBoundary
.endPos
<= nLength
);
110 // -----------------------------------------------------------------------------
112 sal_Bool
OCommonAccessibleText::implIsValidIndex( sal_Int32 nIndex
, sal_Int32 nLength
)
114 return ( nIndex
>= 0 ) && ( nIndex
< nLength
);
117 // -----------------------------------------------------------------------------
119 sal_Bool
OCommonAccessibleText::implIsValidRange( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
, sal_Int32 nLength
)
121 return ( nStartIndex
>= 0 ) && ( nStartIndex
<= nLength
) && ( nEndIndex
>= 0 ) && ( nEndIndex
<= nLength
);
124 // -----------------------------------------------------------------------------
126 void OCommonAccessibleText::implGetGlyphBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
128 ::rtl::OUString
sText( implGetText() );
130 if ( implIsValidIndex( nIndex
, sText
.getLength() ) )
132 Reference
< i18n::XBreakIterator
> xBreakIter
= implGetBreakIterator();
133 if ( xBreakIter
.is() )
135 sal_Int32 nCount
= 1;
137 sal_Int32 nStartIndex
= xBreakIter
->previousCharacters( sText
, nIndex
, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL
, nCount
, nDone
);
139 nStartIndex
= xBreakIter
->nextCharacters( sText
, nStartIndex
, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL
, nCount
, nDone
);
140 sal_Int32 nEndIndex
= xBreakIter
->nextCharacters( sText
, nStartIndex
, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL
, nCount
, nDone
);
143 rBoundary
.startPos
= nStartIndex
;
144 rBoundary
.endPos
= nEndIndex
;
150 rBoundary
.startPos
= nIndex
;
151 rBoundary
.endPos
= nIndex
;
155 // -----------------------------------------------------------------------------
157 sal_Bool
OCommonAccessibleText::implGetWordBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
159 sal_Bool bWord
= sal_False
;
160 ::rtl::OUString
sText( implGetText() );
162 if ( implIsValidIndex( nIndex
, sText
.getLength() ) )
164 Reference
< i18n::XBreakIterator
> xBreakIter
= implGetBreakIterator();
165 if ( xBreakIter
.is() )
167 rBoundary
= xBreakIter
->getWordBoundary( sText
, nIndex
, implGetLocale(), i18n::WordType::ANY_WORD
, sal_True
);
169 // it's a word, if the first character is an alpha-numeric character
170 Reference
< i18n::XCharacterClassification
> xCharClass
= implGetCharacterClassification();
171 if ( xCharClass
.is() )
173 sal_Int32 nType
= xCharClass
->getCharacterType( sText
, rBoundary
.startPos
, implGetLocale() );
174 if ( ( nType
& ( i18n::KCharacterType::LETTER
| i18n::KCharacterType::DIGIT
) ) != 0 )
181 rBoundary
.startPos
= nIndex
;
182 rBoundary
.endPos
= nIndex
;
188 // -----------------------------------------------------------------------------
190 void OCommonAccessibleText::implGetSentenceBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
192 ::rtl::OUString
sText( implGetText() );
194 if ( implIsValidIndex( nIndex
, sText
.getLength() ) )
196 Locale aLocale
= implGetLocale();
197 Reference
< i18n::XBreakIterator
> xBreakIter
= implGetBreakIterator();
198 if ( xBreakIter
.is() )
200 rBoundary
.endPos
= xBreakIter
->endOfSentence( sText
, nIndex
, aLocale
);
201 rBoundary
.startPos
= xBreakIter
->beginOfSentence( sText
, rBoundary
.endPos
, aLocale
);
206 rBoundary
.startPos
= nIndex
;
207 rBoundary
.endPos
= nIndex
;
211 // -----------------------------------------------------------------------------
213 void OCommonAccessibleText::implGetParagraphBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
215 ::rtl::OUString
sText( implGetText() );
217 if ( implIsValidIndex( nIndex
, sText
.getLength() ) )
219 rBoundary
.startPos
= 0;
220 rBoundary
.endPos
= sText
.getLength();
222 sal_Int32 nFound
= sText
.lastIndexOf( (sal_Unicode
)'\n', nIndex
);
224 rBoundary
.startPos
= nFound
+ 1;
226 nFound
= sText
.indexOf( (sal_Unicode
)'\n', nIndex
);
228 rBoundary
.endPos
= nFound
+ 1;
232 rBoundary
.startPos
= nIndex
;
233 rBoundary
.endPos
= nIndex
;
237 // -----------------------------------------------------------------------------
239 void OCommonAccessibleText::implGetLineBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
241 ::rtl::OUString
sText( implGetText() );
242 sal_Int32 nLength
= sText
.getLength();
244 if ( implIsValidIndex( nIndex
, nLength
) || nIndex
== nLength
)
246 rBoundary
.startPos
= 0;
247 rBoundary
.endPos
= nLength
;
251 rBoundary
.startPos
= nIndex
;
252 rBoundary
.endPos
= nIndex
;
256 // -----------------------------------------------------------------------------
258 sal_Unicode
OCommonAccessibleText::getCharacter( sal_Int32 nIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
260 ::rtl::OUString
sText( implGetText() );
262 if ( !implIsValidIndex( nIndex
, sText
.getLength() ) )
263 throw IndexOutOfBoundsException();
265 return sText
.getStr()[nIndex
];
268 // -----------------------------------------------------------------------------
270 sal_Int32
OCommonAccessibleText::getCharacterCount() throw (RuntimeException
)
272 return implGetText().getLength();
275 // -----------------------------------------------------------------------------
277 ::rtl::OUString
OCommonAccessibleText::getSelectedText() throw (RuntimeException
)
279 ::rtl::OUString sText
;
280 sal_Int32 nStartIndex
;
283 implGetSelection( nStartIndex
, nEndIndex
);
287 sText
= getTextRange( nStartIndex
, nEndIndex
);
289 catch ( IndexOutOfBoundsException
& )
296 // -----------------------------------------------------------------------------
298 sal_Int32
OCommonAccessibleText::getSelectionStart() throw (RuntimeException
)
300 sal_Int32 nStartIndex
;
303 implGetSelection( nStartIndex
, nEndIndex
);
308 // -----------------------------------------------------------------------------
310 sal_Int32
OCommonAccessibleText::getSelectionEnd() throw (RuntimeException
)
312 sal_Int32 nStartIndex
;
315 implGetSelection( nStartIndex
, nEndIndex
);
320 // -----------------------------------------------------------------------------
322 ::rtl::OUString
OCommonAccessibleText::getText() throw (RuntimeException
)
324 return implGetText();
327 // -----------------------------------------------------------------------------
329 ::rtl::OUString
OCommonAccessibleText::getTextRange( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
331 ::rtl::OUString
sText( implGetText() );
333 if ( !implIsValidRange( nStartIndex
, nEndIndex
, sText
.getLength() ) )
334 throw IndexOutOfBoundsException();
336 sal_Int32 nMinIndex
= ::std::min( nStartIndex
, nEndIndex
);
337 sal_Int32 nMaxIndex
= ::std::max( nStartIndex
, nEndIndex
);
339 return sText
.copy( nMinIndex
, nMaxIndex
- nMinIndex
);
342 // -----------------------------------------------------------------------------
344 TextSegment
OCommonAccessibleText::getTextAtIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
346 ::rtl::OUString
sText( implGetText() );
347 sal_Int32 nLength
= sText
.getLength();
349 if ( !implIsValidIndex( nIndex
, nLength
) && nIndex
!= nLength
)
350 throw IndexOutOfBoundsException();
352 i18n::Boundary aBoundary
;
354 aResult
.SegmentStart
= -1;
355 aResult
.SegmentEnd
= -1;
359 case AccessibleTextType::CHARACTER
:
361 if ( implIsValidIndex( nIndex
, nLength
) )
363 aResult
.SegmentText
= sText
.copy( nIndex
, 1 );
364 aResult
.SegmentStart
= nIndex
;
365 aResult
.SegmentEnd
= nIndex
+1;
369 case AccessibleTextType::GLYPH
:
371 // get glyph at index
372 implGetGlyphBoundary( aBoundary
, nIndex
);
373 if ( implIsValidBoundary( aBoundary
, nLength
) )
375 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
376 aResult
.SegmentStart
= aBoundary
.startPos
;
377 aResult
.SegmentEnd
= aBoundary
.endPos
;
381 case AccessibleTextType::WORD
:
384 sal_Bool bWord
= implGetWordBoundary( aBoundary
, nIndex
);
385 if ( bWord
&& implIsValidBoundary( aBoundary
, nLength
) )
387 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
388 aResult
.SegmentStart
= aBoundary
.startPos
;
389 aResult
.SegmentEnd
= aBoundary
.endPos
;
393 case AccessibleTextType::SENTENCE
:
395 // get sentence at index
396 implGetSentenceBoundary( aBoundary
, nIndex
);
397 if ( implIsValidBoundary( aBoundary
, nLength
) )
399 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
400 aResult
.SegmentStart
= aBoundary
.startPos
;
401 aResult
.SegmentEnd
= aBoundary
.endPos
;
405 case AccessibleTextType::PARAGRAPH
:
407 // get paragraph at index
408 implGetParagraphBoundary( aBoundary
, nIndex
);
409 if ( implIsValidBoundary( aBoundary
, nLength
) )
411 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
412 aResult
.SegmentStart
= aBoundary
.startPos
;
413 aResult
.SegmentEnd
= aBoundary
.endPos
;
417 case AccessibleTextType::LINE
:
420 implGetLineBoundary( aBoundary
, nIndex
);
421 if ( implIsValidBoundary( aBoundary
, nLength
) )
423 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
424 aResult
.SegmentStart
= aBoundary
.startPos
;
425 aResult
.SegmentEnd
= aBoundary
.endPos
;
429 case AccessibleTextType::ATTRIBUTE_RUN
:
431 // TODO: implGetAttributeRunBoundary() (incompatible!)
433 aResult
.SegmentText
= sText
;
434 aResult
.SegmentStart
= 0;
435 aResult
.SegmentEnd
= nLength
;
447 // -----------------------------------------------------------------------------
449 TextSegment
OCommonAccessibleText::getTextBeforeIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
451 ::rtl::OUString
sText( implGetText() );
452 sal_Int32 nLength
= sText
.getLength();
454 if ( !implIsValidIndex( nIndex
, nLength
) && nIndex
!= nLength
)
455 throw IndexOutOfBoundsException();
457 i18n::Boundary aBoundary
;
459 aResult
.SegmentStart
= -1;
460 aResult
.SegmentEnd
= -1;
464 case AccessibleTextType::CHARACTER
:
466 if ( implIsValidIndex( nIndex
- 1, nLength
) )
468 aResult
.SegmentText
= sText
.copy( nIndex
- 1, 1 );
469 aResult
.SegmentStart
= nIndex
-1;
470 aResult
.SegmentEnd
= nIndex
;
474 case AccessibleTextType::GLYPH
:
476 // get glyph at index
477 implGetGlyphBoundary( aBoundary
, nIndex
);
478 // get previous glyph
479 if ( aBoundary
.startPos
> 0 )
481 implGetGlyphBoundary( aBoundary
, aBoundary
.startPos
- 1 );
482 if ( implIsValidBoundary( aBoundary
, nLength
) )
484 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
485 aResult
.SegmentStart
= aBoundary
.startPos
;
486 aResult
.SegmentEnd
= aBoundary
.endPos
;
491 case AccessibleTextType::WORD
:
494 implGetWordBoundary( aBoundary
, nIndex
);
496 sal_Bool bWord
= sal_False
;
497 while ( !bWord
&& aBoundary
.startPos
> 0 )
498 bWord
= implGetWordBoundary( aBoundary
, aBoundary
.startPos
- 1 );
499 if ( bWord
&& implIsValidBoundary( aBoundary
, nLength
) )
501 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
502 aResult
.SegmentStart
= aBoundary
.startPos
;
503 aResult
.SegmentEnd
= aBoundary
.endPos
;
507 case AccessibleTextType::SENTENCE
:
509 // get sentence at index
510 implGetSentenceBoundary( aBoundary
, nIndex
);
511 // get previous sentence
512 if ( aBoundary
.startPos
> 0 )
514 implGetSentenceBoundary( aBoundary
, aBoundary
.startPos
- 1 );
515 if ( implIsValidBoundary( aBoundary
, nLength
) )
517 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
518 aResult
.SegmentStart
= aBoundary
.startPos
;
519 aResult
.SegmentEnd
= aBoundary
.endPos
;
524 case AccessibleTextType::PARAGRAPH
:
526 // get paragraph at index
527 implGetParagraphBoundary( aBoundary
, nIndex
);
528 // get previous paragraph
529 if ( aBoundary
.startPos
> 0 )
531 implGetParagraphBoundary( aBoundary
, aBoundary
.startPos
- 1 );
532 if ( implIsValidBoundary( aBoundary
, nLength
) )
534 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
535 aResult
.SegmentStart
= aBoundary
.startPos
;
536 aResult
.SegmentEnd
= aBoundary
.endPos
;
541 case AccessibleTextType::LINE
:
544 implGetLineBoundary( aBoundary
, nIndex
);
546 if ( aBoundary
.startPos
> 0 )
548 implGetLineBoundary( aBoundary
, aBoundary
.startPos
- 1 );
549 if ( implIsValidBoundary( aBoundary
, nLength
) )
551 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
552 aResult
.SegmentStart
= aBoundary
.startPos
;
553 aResult
.SegmentEnd
= aBoundary
.endPos
;
558 case AccessibleTextType::ATTRIBUTE_RUN
:
560 // TODO: implGetAttributeRunBoundary() (incompatible!)
572 // -----------------------------------------------------------------------------
574 TextSegment
OCommonAccessibleText::getTextBehindIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
576 ::rtl::OUString
sText( implGetText() );
577 sal_Int32 nLength
= sText
.getLength();
579 if ( !implIsValidIndex( nIndex
, nLength
) && nIndex
!= nLength
)
580 throw IndexOutOfBoundsException();
582 i18n::Boundary aBoundary
;
584 aResult
.SegmentStart
= -1;
585 aResult
.SegmentEnd
= -1;
589 case AccessibleTextType::CHARACTER
:
591 if ( implIsValidIndex( nIndex
+ 1, nLength
) )
593 aResult
.SegmentText
= sText
.copy( nIndex
+ 1, 1 );
594 aResult
.SegmentStart
= nIndex
+1;
595 aResult
.SegmentEnd
= nIndex
+2;
599 case AccessibleTextType::GLYPH
:
601 // get glyph at index
602 implGetGlyphBoundary( aBoundary
, nIndex
);
604 if ( aBoundary
.endPos
< nLength
)
606 implGetGlyphBoundary( aBoundary
, aBoundary
.endPos
);
607 if ( implIsValidBoundary( aBoundary
, nLength
) )
609 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
610 aResult
.SegmentStart
= aBoundary
.startPos
;
611 aResult
.SegmentEnd
= aBoundary
.endPos
;
616 case AccessibleTextType::WORD
:
619 implGetWordBoundary( aBoundary
, nIndex
);
621 sal_Bool bWord
= sal_False
;
622 while ( !bWord
&& aBoundary
.endPos
< nLength
)
623 bWord
= implGetWordBoundary( aBoundary
, aBoundary
.endPos
);
624 if ( bWord
&& 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::SENTENCE
:
634 // get sentence at index
635 implGetSentenceBoundary( aBoundary
, nIndex
);
637 sal_Int32 nEnd
= aBoundary
.endPos
;
638 sal_Int32 nI
= aBoundary
.endPos
;
639 sal_Bool bFound
= sal_False
;
640 while ( !bFound
&& ++nI
< nLength
)
642 implGetSentenceBoundary( aBoundary
, nI
);
643 bFound
= ( aBoundary
.endPos
> nEnd
);
645 if ( bFound
&& implIsValidBoundary( aBoundary
, nLength
) )
647 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
648 aResult
.SegmentStart
= aBoundary
.startPos
;
649 aResult
.SegmentEnd
= aBoundary
.endPos
;
653 case AccessibleTextType::PARAGRAPH
:
655 // get paragraph at index
656 implGetParagraphBoundary( aBoundary
, nIndex
);
657 // get next paragraph
658 if ( aBoundary
.endPos
< nLength
)
660 implGetParagraphBoundary( aBoundary
, aBoundary
.endPos
);
661 if ( implIsValidBoundary( aBoundary
, nLength
) )
663 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
664 aResult
.SegmentStart
= aBoundary
.startPos
;
665 aResult
.SegmentEnd
= aBoundary
.endPos
;
670 case AccessibleTextType::LINE
:
673 implGetLineBoundary( aBoundary
, nIndex
);
675 if ( aBoundary
.endPos
< nLength
)
677 implGetLineBoundary( aBoundary
, aBoundary
.endPos
);
678 if ( implIsValidBoundary( aBoundary
, nLength
) )
680 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
681 aResult
.SegmentStart
= aBoundary
.startPos
;
682 aResult
.SegmentEnd
= aBoundary
.endPos
;
687 case AccessibleTextType::ATTRIBUTE_RUN
:
689 // TODO: implGetAttributeRunBoundary() (incompatible!)
701 // -----------------------------------------------------------------------------
702 bool OCommonAccessibleText::implInitTextChangedEvent(
703 const rtl::OUString
& rOldString
,
704 const rtl::OUString
& rNewString
,
705 ::com::sun::star::uno::Any
& rDeleted
,
706 ::com::sun::star::uno::Any
& rInserted
) // throw()
708 sal_uInt32 nLenOld
= rOldString
.getLength();
709 sal_uInt32 nLenNew
= rNewString
.getLength();
712 if ((0 == nLenOld
) && (0 == nLenNew
))
715 TextSegment aDeletedText
;
716 TextSegment aInsertedText
;
718 aDeletedText
.SegmentStart
= -1;
719 aDeletedText
.SegmentEnd
= -1;
720 aInsertedText
.SegmentStart
= -1;
721 aInsertedText
.SegmentEnd
= -1;
724 if ((0 == nLenOld
) && (nLenNew
> 0))
726 aInsertedText
.SegmentStart
= 0;
727 aInsertedText
.SegmentEnd
= nLenNew
;
728 aInsertedText
.SegmentText
= rNewString
.copy( aInsertedText
.SegmentStart
, aInsertedText
.SegmentEnd
- aInsertedText
.SegmentStart
);
730 rInserted
<<= aInsertedText
;
735 if ((nLenOld
> 0) && (0 == nLenNew
))
737 aDeletedText
.SegmentStart
= 0;
738 aDeletedText
.SegmentEnd
= nLenOld
;
739 aDeletedText
.SegmentText
= rOldString
.copy( aDeletedText
.SegmentStart
, aDeletedText
.SegmentEnd
- aDeletedText
.SegmentStart
);
741 rDeleted
<<= aDeletedText
;
745 const sal_Unicode
* pFirstDiffOld
= rOldString
.getStr();
746 const sal_Unicode
* pLastDiffOld
= rOldString
.getStr() + nLenOld
;
747 const sal_Unicode
* pFirstDiffNew
= rNewString
.getStr();
748 const sal_Unicode
* pLastDiffNew
= rNewString
.getStr() + nLenNew
;
750 // find first difference
751 while ((*pFirstDiffOld
== *pFirstDiffNew
) &&
752 (pFirstDiffOld
< pLastDiffOld
) &&
753 (pFirstDiffNew
< pLastDiffNew
))
760 if ((0 == *pFirstDiffOld
) && (0 == *pFirstDiffNew
))
763 // find last difference
764 while ( ( pLastDiffOld
> pFirstDiffOld
) &&
765 ( pLastDiffNew
> pFirstDiffNew
) &&
766 (pLastDiffOld
[-1] == pLastDiffNew
[-1]))
772 if (pFirstDiffOld
< pLastDiffOld
)
774 aDeletedText
.SegmentStart
= pFirstDiffOld
- rOldString
.getStr();
775 aDeletedText
.SegmentEnd
= pLastDiffOld
- rOldString
.getStr();
776 aDeletedText
.SegmentText
= rOldString
.copy( aDeletedText
.SegmentStart
, aDeletedText
.SegmentEnd
- aDeletedText
.SegmentStart
);
778 rDeleted
<<= aDeletedText
;
781 if (pFirstDiffNew
< pLastDiffNew
)
783 aInsertedText
.SegmentStart
= pFirstDiffNew
- rNewString
.getStr();
784 aInsertedText
.SegmentEnd
= pLastDiffNew
- rNewString
.getStr();
785 aInsertedText
.SegmentText
= rNewString
.copy( aInsertedText
.SegmentStart
, aInsertedText
.SegmentEnd
- aInsertedText
.SegmentStart
);
787 rInserted
<<= aInsertedText
;
792 //==============================================================================
793 // OAccessibleTextHelper
794 //==============================================================================
796 OAccessibleTextHelper::OAccessibleTextHelper()
800 // -----------------------------------------------------------------------------
802 OAccessibleTextHelper::OAccessibleTextHelper( IMutex
* _pExternalLock
)
803 :OAccessibleExtendedComponentHelper( _pExternalLock
)
807 // -----------------------------------------------------------------------------
809 // -----------------------------------------------------------------------------
811 IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleTextHelper
, OAccessibleExtendedComponentHelper
, OAccessibleTextHelper_Base
)
813 // -----------------------------------------------------------------------------
815 // -----------------------------------------------------------------------------
817 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleTextHelper
, OAccessibleExtendedComponentHelper
, OAccessibleTextHelper_Base
)
819 // -----------------------------------------------------------------------------
821 // -----------------------------------------------------------------------------
823 sal_Unicode
OAccessibleTextHelper::getCharacter( sal_Int32 nIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
825 OExternalLockGuard
aGuard( this );
827 return OCommonAccessibleText::getCharacter( nIndex
);
830 // -----------------------------------------------------------------------------
832 sal_Int32
OAccessibleTextHelper::getCharacterCount() throw (RuntimeException
)
834 OExternalLockGuard
aGuard( this );
836 return OCommonAccessibleText::getCharacterCount();
839 // -----------------------------------------------------------------------------
841 ::rtl::OUString
OAccessibleTextHelper::getSelectedText() throw (RuntimeException
)
843 OExternalLockGuard
aGuard( this );
845 return OCommonAccessibleText::getSelectedText();
848 // -----------------------------------------------------------------------------
850 sal_Int32
OAccessibleTextHelper::getSelectionStart() throw (RuntimeException
)
852 OExternalLockGuard
aGuard( this );
854 return OCommonAccessibleText::getSelectionStart();
857 // -----------------------------------------------------------------------------
859 sal_Int32
OAccessibleTextHelper::getSelectionEnd() throw (RuntimeException
)
861 OExternalLockGuard
aGuard( this );
863 return OCommonAccessibleText::getSelectionEnd();
866 // -----------------------------------------------------------------------------
868 ::rtl::OUString
OAccessibleTextHelper::getText() throw (RuntimeException
)
870 OExternalLockGuard
aGuard( this );
872 return OCommonAccessibleText::getText();
875 // -----------------------------------------------------------------------------
877 ::rtl::OUString
OAccessibleTextHelper::getTextRange( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
879 OExternalLockGuard
aGuard( this );
881 return OCommonAccessibleText::getTextRange( nStartIndex
, nEndIndex
);
884 // -----------------------------------------------------------------------------
886 TextSegment
OAccessibleTextHelper::getTextAtIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
888 OExternalLockGuard
aGuard( this );
890 return OCommonAccessibleText::getTextAtIndex( nIndex
, aTextType
);
893 // -----------------------------------------------------------------------------
895 TextSegment
OAccessibleTextHelper::getTextBeforeIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
897 OExternalLockGuard
aGuard( this );
899 return OCommonAccessibleText::getTextBeforeIndex( nIndex
, aTextType
);
902 // -----------------------------------------------------------------------------
904 TextSegment
OAccessibleTextHelper::getTextBehindIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
906 OExternalLockGuard
aGuard( this );
908 return OCommonAccessibleText::getTextBehindIndex( nIndex
, aTextType
);
911 // -----------------------------------------------------------------------------
913 //..............................................................................
914 } // namespace comphelper
915 //..............................................................................