1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: accessibletexthelper.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_comphelper.hxx"
34 // includes --------------------------------------------------------------
35 #include <comphelper/accessibletexthelper.hxx>
36 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
37 #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
38 #ifndef _COM_SUN_STAR_TEXT_WORDTYPE_HPP_
39 #include <com/sun/star/i18n/WordType.hpp>
41 #include <com/sun/star/i18n/KCharacterType.hpp>
42 #include <comphelper/processfactory.hxx>
43 #include <com/sun/star/accessibility/TextSegment.hpp>
47 //..............................................................................
50 //..............................................................................
52 using namespace ::com::sun::star
;
53 using namespace ::com::sun::star::uno
;
54 using namespace ::com::sun::star::lang
;
55 using namespace ::com::sun::star::beans
;
56 using namespace ::com::sun::star::accessibility
;
58 //==============================================================================
59 // OCommonAccessibleText
60 //==============================================================================
62 OCommonAccessibleText::OCommonAccessibleText()
66 // -----------------------------------------------------------------------------
68 OCommonAccessibleText::~OCommonAccessibleText()
72 // -----------------------------------------------------------------------------
74 Reference
< i18n::XBreakIterator
> OCommonAccessibleText::implGetBreakIterator()
76 if ( !m_xBreakIter
.is() )
78 Reference
< lang::XMultiServiceFactory
> xMSF
= ::comphelper::getProcessServiceFactory();
81 m_xBreakIter
= Reference
< i18n::XBreakIterator
>
82 ( xMSF
->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.BreakIterator" ) ) ), UNO_QUERY
);
89 // -----------------------------------------------------------------------------
91 Reference
< i18n::XCharacterClassification
> OCommonAccessibleText::implGetCharacterClassification()
93 if ( !m_xCharClass
.is() )
95 Reference
< lang::XMultiServiceFactory
> xMSF
= ::comphelper::getProcessServiceFactory();
98 m_xCharClass
= Reference
< i18n::XCharacterClassification
>
99 ( xMSF
->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.CharacterClassification" ) ) ), UNO_QUERY
);
106 // -----------------------------------------------------------------------------
108 sal_Bool
OCommonAccessibleText::implIsValidBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nLength
)
110 return ( rBoundary
.startPos
>= 0 ) && ( rBoundary
.startPos
< nLength
) && ( rBoundary
.endPos
>= 0 ) && ( rBoundary
.endPos
<= nLength
);
113 // -----------------------------------------------------------------------------
115 sal_Bool
OCommonAccessibleText::implIsValidIndex( sal_Int32 nIndex
, sal_Int32 nLength
)
117 return ( nIndex
>= 0 ) && ( nIndex
< nLength
);
120 // -----------------------------------------------------------------------------
122 sal_Bool
OCommonAccessibleText::implIsValidRange( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
, sal_Int32 nLength
)
124 return ( nStartIndex
>= 0 ) && ( nStartIndex
<= nLength
) && ( nEndIndex
>= 0 ) && ( nEndIndex
<= nLength
);
127 // -----------------------------------------------------------------------------
129 void OCommonAccessibleText::implGetGlyphBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
131 ::rtl::OUString
sText( implGetText() );
133 if ( implIsValidIndex( nIndex
, sText
.getLength() ) )
135 Reference
< i18n::XBreakIterator
> xBreakIter
= implGetBreakIterator();
136 if ( xBreakIter
.is() )
138 sal_Int32 nCount
= 1;
140 sal_Int32 nStartIndex
= xBreakIter
->previousCharacters( sText
, nIndex
, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL
, nCount
, nDone
);
142 nStartIndex
= xBreakIter
->nextCharacters( sText
, nStartIndex
, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL
, nCount
, nDone
);
143 sal_Int32 nEndIndex
= xBreakIter
->nextCharacters( sText
, nStartIndex
, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL
, nCount
, nDone
);
146 rBoundary
.startPos
= nStartIndex
;
147 rBoundary
.endPos
= nEndIndex
;
153 rBoundary
.startPos
= nIndex
;
154 rBoundary
.endPos
= nIndex
;
158 // -----------------------------------------------------------------------------
160 sal_Bool
OCommonAccessibleText::implGetWordBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
162 sal_Bool bWord
= sal_False
;
163 ::rtl::OUString
sText( implGetText() );
165 if ( implIsValidIndex( nIndex
, sText
.getLength() ) )
167 Reference
< i18n::XBreakIterator
> xBreakIter
= implGetBreakIterator();
168 if ( xBreakIter
.is() )
170 rBoundary
= xBreakIter
->getWordBoundary( sText
, nIndex
, implGetLocale(), i18n::WordType::ANY_WORD
, sal_True
);
172 // it's a word, if the first character is an alpha-numeric character
173 Reference
< i18n::XCharacterClassification
> xCharClass
= implGetCharacterClassification();
174 if ( xCharClass
.is() )
176 sal_Int32 nType
= xCharClass
->getCharacterType( sText
, rBoundary
.startPos
, implGetLocale() );
177 if ( ( nType
& ( i18n::KCharacterType::LETTER
| i18n::KCharacterType::DIGIT
) ) != 0 )
184 rBoundary
.startPos
= nIndex
;
185 rBoundary
.endPos
= nIndex
;
191 // -----------------------------------------------------------------------------
193 void OCommonAccessibleText::implGetSentenceBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
195 ::rtl::OUString
sText( implGetText() );
197 if ( implIsValidIndex( nIndex
, sText
.getLength() ) )
199 Locale aLocale
= implGetLocale();
200 Reference
< i18n::XBreakIterator
> xBreakIter
= implGetBreakIterator();
201 if ( xBreakIter
.is() )
203 rBoundary
.endPos
= xBreakIter
->endOfSentence( sText
, nIndex
, aLocale
);
204 rBoundary
.startPos
= xBreakIter
->beginOfSentence( sText
, rBoundary
.endPos
, aLocale
);
209 rBoundary
.startPos
= nIndex
;
210 rBoundary
.endPos
= nIndex
;
214 // -----------------------------------------------------------------------------
216 void OCommonAccessibleText::implGetParagraphBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
218 ::rtl::OUString
sText( implGetText() );
220 if ( implIsValidIndex( nIndex
, sText
.getLength() ) )
222 rBoundary
.startPos
= 0;
223 rBoundary
.endPos
= sText
.getLength();
225 sal_Int32 nFound
= sText
.lastIndexOf( (sal_Unicode
)'\n', nIndex
);
227 rBoundary
.startPos
= nFound
+ 1;
229 nFound
= sText
.indexOf( (sal_Unicode
)'\n', nIndex
);
231 rBoundary
.endPos
= nFound
+ 1;
235 rBoundary
.startPos
= nIndex
;
236 rBoundary
.endPos
= nIndex
;
240 // -----------------------------------------------------------------------------
242 void OCommonAccessibleText::implGetLineBoundary( i18n::Boundary
& rBoundary
, sal_Int32 nIndex
)
244 ::rtl::OUString
sText( implGetText() );
245 sal_Int32 nLength
= sText
.getLength();
247 if ( implIsValidIndex( nIndex
, nLength
) || nIndex
== nLength
)
249 rBoundary
.startPos
= 0;
250 rBoundary
.endPos
= nLength
;
254 rBoundary
.startPos
= nIndex
;
255 rBoundary
.endPos
= nIndex
;
259 // -----------------------------------------------------------------------------
261 sal_Unicode
OCommonAccessibleText::getCharacter( sal_Int32 nIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
263 ::rtl::OUString
sText( implGetText() );
265 if ( !implIsValidIndex( nIndex
, sText
.getLength() ) )
266 throw IndexOutOfBoundsException();
268 return sText
.getStr()[nIndex
];
271 // -----------------------------------------------------------------------------
273 sal_Int32
OCommonAccessibleText::getCharacterCount() throw (RuntimeException
)
275 return implGetText().getLength();
278 // -----------------------------------------------------------------------------
280 ::rtl::OUString
OCommonAccessibleText::getSelectedText() throw (RuntimeException
)
282 ::rtl::OUString sText
;
283 sal_Int32 nStartIndex
;
286 implGetSelection( nStartIndex
, nEndIndex
);
290 sText
= getTextRange( nStartIndex
, nEndIndex
);
292 catch ( IndexOutOfBoundsException
& )
299 // -----------------------------------------------------------------------------
301 sal_Int32
OCommonAccessibleText::getSelectionStart() throw (RuntimeException
)
303 sal_Int32 nStartIndex
;
306 implGetSelection( nStartIndex
, nEndIndex
);
311 // -----------------------------------------------------------------------------
313 sal_Int32
OCommonAccessibleText::getSelectionEnd() throw (RuntimeException
)
315 sal_Int32 nStartIndex
;
318 implGetSelection( nStartIndex
, nEndIndex
);
323 // -----------------------------------------------------------------------------
325 ::rtl::OUString
OCommonAccessibleText::getText() throw (RuntimeException
)
327 return implGetText();
330 // -----------------------------------------------------------------------------
332 ::rtl::OUString
OCommonAccessibleText::getTextRange( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
334 ::rtl::OUString
sText( implGetText() );
336 if ( !implIsValidRange( nStartIndex
, nEndIndex
, sText
.getLength() ) )
337 throw IndexOutOfBoundsException();
339 sal_Int32 nMinIndex
= ::std::min( nStartIndex
, nEndIndex
);
340 sal_Int32 nMaxIndex
= ::std::max( nStartIndex
, nEndIndex
);
342 return sText
.copy( nMinIndex
, nMaxIndex
- nMinIndex
);
345 // -----------------------------------------------------------------------------
347 TextSegment
OCommonAccessibleText::getTextAtIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
349 ::rtl::OUString
sText( implGetText() );
350 sal_Int32 nLength
= sText
.getLength();
352 if ( !implIsValidIndex( nIndex
, nLength
) && nIndex
!= nLength
)
353 throw IndexOutOfBoundsException();
355 i18n::Boundary aBoundary
;
357 aResult
.SegmentStart
= -1;
358 aResult
.SegmentEnd
= -1;
362 case AccessibleTextType::CHARACTER
:
364 if ( implIsValidIndex( nIndex
, nLength
) )
366 aResult
.SegmentText
= sText
.copy( nIndex
, 1 );
367 aResult
.SegmentStart
= nIndex
;
368 aResult
.SegmentEnd
= nIndex
+1;
372 case AccessibleTextType::GLYPH
:
374 // get glyph at index
375 implGetGlyphBoundary( 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::WORD
:
387 sal_Bool bWord
= implGetWordBoundary( aBoundary
, nIndex
);
388 if ( bWord
&& 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::SENTENCE
:
398 // get sentence at index
399 implGetSentenceBoundary( 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::PARAGRAPH
:
410 // get paragraph at index
411 implGetParagraphBoundary( aBoundary
, nIndex
);
412 if ( implIsValidBoundary( aBoundary
, nLength
) )
414 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
415 aResult
.SegmentStart
= aBoundary
.startPos
;
416 aResult
.SegmentEnd
= aBoundary
.endPos
;
420 case AccessibleTextType::LINE
:
423 implGetLineBoundary( aBoundary
, nIndex
);
424 if ( implIsValidBoundary( aBoundary
, nLength
) )
426 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
427 aResult
.SegmentStart
= aBoundary
.startPos
;
428 aResult
.SegmentEnd
= aBoundary
.endPos
;
432 case AccessibleTextType::ATTRIBUTE_RUN
:
434 // TODO: implGetAttributeRunBoundary() (incompatible!)
436 aResult
.SegmentText
= sText
;
437 aResult
.SegmentStart
= 0;
438 aResult
.SegmentEnd
= nLength
;
450 // -----------------------------------------------------------------------------
452 TextSegment
OCommonAccessibleText::getTextBeforeIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
454 ::rtl::OUString
sText( implGetText() );
455 sal_Int32 nLength
= sText
.getLength();
457 if ( !implIsValidIndex( nIndex
, nLength
) && nIndex
!= nLength
)
458 throw IndexOutOfBoundsException();
460 i18n::Boundary aBoundary
;
462 aResult
.SegmentStart
= -1;
463 aResult
.SegmentEnd
= -1;
467 case AccessibleTextType::CHARACTER
:
469 if ( implIsValidIndex( nIndex
- 1, nLength
) )
471 aResult
.SegmentText
= sText
.copy( nIndex
- 1, 1 );
472 aResult
.SegmentStart
= nIndex
-1;
473 aResult
.SegmentEnd
= nIndex
;
477 case AccessibleTextType::GLYPH
:
479 // get glyph at index
480 implGetGlyphBoundary( aBoundary
, nIndex
);
481 // get previous glyph
482 if ( aBoundary
.startPos
> 0 )
484 implGetGlyphBoundary( aBoundary
, aBoundary
.startPos
- 1 );
485 if ( implIsValidBoundary( aBoundary
, nLength
) )
487 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
488 aResult
.SegmentStart
= aBoundary
.startPos
;
489 aResult
.SegmentEnd
= aBoundary
.endPos
;
494 case AccessibleTextType::WORD
:
497 implGetWordBoundary( aBoundary
, nIndex
);
499 sal_Bool bWord
= sal_False
;
500 while ( !bWord
&& aBoundary
.startPos
> 0 )
501 bWord
= implGetWordBoundary( aBoundary
, aBoundary
.startPos
- 1 );
502 if ( bWord
&& implIsValidBoundary( aBoundary
, nLength
) )
504 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
505 aResult
.SegmentStart
= aBoundary
.startPos
;
506 aResult
.SegmentEnd
= aBoundary
.endPos
;
510 case AccessibleTextType::SENTENCE
:
512 // get sentence at index
513 implGetSentenceBoundary( aBoundary
, nIndex
);
514 // get previous sentence
515 if ( aBoundary
.startPos
> 0 )
517 implGetSentenceBoundary( aBoundary
, aBoundary
.startPos
- 1 );
518 if ( implIsValidBoundary( aBoundary
, nLength
) )
520 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
521 aResult
.SegmentStart
= aBoundary
.startPos
;
522 aResult
.SegmentEnd
= aBoundary
.endPos
;
527 case AccessibleTextType::PARAGRAPH
:
529 // get paragraph at index
530 implGetParagraphBoundary( aBoundary
, nIndex
);
531 // get previous paragraph
532 if ( aBoundary
.startPos
> 0 )
534 implGetParagraphBoundary( aBoundary
, aBoundary
.startPos
- 1 );
535 if ( implIsValidBoundary( aBoundary
, nLength
) )
537 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
538 aResult
.SegmentStart
= aBoundary
.startPos
;
539 aResult
.SegmentEnd
= aBoundary
.endPos
;
544 case AccessibleTextType::LINE
:
547 implGetLineBoundary( aBoundary
, nIndex
);
549 if ( aBoundary
.startPos
> 0 )
551 implGetLineBoundary( aBoundary
, aBoundary
.startPos
- 1 );
552 if ( implIsValidBoundary( aBoundary
, nLength
) )
554 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
555 aResult
.SegmentStart
= aBoundary
.startPos
;
556 aResult
.SegmentEnd
= aBoundary
.endPos
;
561 case AccessibleTextType::ATTRIBUTE_RUN
:
563 // TODO: implGetAttributeRunBoundary() (incompatible!)
575 // -----------------------------------------------------------------------------
577 TextSegment
OCommonAccessibleText::getTextBehindIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
579 ::rtl::OUString
sText( implGetText() );
580 sal_Int32 nLength
= sText
.getLength();
582 if ( !implIsValidIndex( nIndex
, nLength
) && nIndex
!= nLength
)
583 throw IndexOutOfBoundsException();
585 i18n::Boundary aBoundary
;
587 aResult
.SegmentStart
= -1;
588 aResult
.SegmentEnd
= -1;
592 case AccessibleTextType::CHARACTER
:
594 if ( implIsValidIndex( nIndex
+ 1, nLength
) )
596 aResult
.SegmentText
= sText
.copy( nIndex
+ 1, 1 );
597 aResult
.SegmentStart
= nIndex
+1;
598 aResult
.SegmentEnd
= nIndex
+2;
602 case AccessibleTextType::GLYPH
:
604 // get glyph at index
605 implGetGlyphBoundary( aBoundary
, nIndex
);
607 if ( aBoundary
.endPos
< nLength
)
609 implGetGlyphBoundary( aBoundary
, aBoundary
.endPos
);
610 if ( implIsValidBoundary( aBoundary
, nLength
) )
612 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
613 aResult
.SegmentStart
= aBoundary
.startPos
;
614 aResult
.SegmentEnd
= aBoundary
.endPos
;
619 case AccessibleTextType::WORD
:
622 implGetWordBoundary( aBoundary
, nIndex
);
624 sal_Bool bWord
= sal_False
;
625 while ( !bWord
&& aBoundary
.endPos
< nLength
)
626 bWord
= implGetWordBoundary( aBoundary
, aBoundary
.endPos
);
627 if ( bWord
&& implIsValidBoundary( aBoundary
, nLength
) )
629 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
630 aResult
.SegmentStart
= aBoundary
.startPos
;
631 aResult
.SegmentEnd
= aBoundary
.endPos
;
635 case AccessibleTextType::SENTENCE
:
637 // get sentence at index
638 implGetSentenceBoundary( aBoundary
, nIndex
);
640 sal_Int32 nEnd
= aBoundary
.endPos
;
641 sal_Int32 nI
= aBoundary
.endPos
;
642 sal_Bool bFound
= sal_False
;
643 while ( !bFound
&& ++nI
< nLength
)
645 implGetSentenceBoundary( aBoundary
, nI
);
646 bFound
= ( aBoundary
.endPos
> nEnd
);
648 if ( bFound
&& implIsValidBoundary( aBoundary
, nLength
) )
650 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
651 aResult
.SegmentStart
= aBoundary
.startPos
;
652 aResult
.SegmentEnd
= aBoundary
.endPos
;
656 case AccessibleTextType::PARAGRAPH
:
658 // get paragraph at index
659 implGetParagraphBoundary( aBoundary
, nIndex
);
660 // get next paragraph
661 if ( aBoundary
.endPos
< nLength
)
663 implGetParagraphBoundary( aBoundary
, aBoundary
.endPos
);
664 if ( implIsValidBoundary( aBoundary
, nLength
) )
666 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
667 aResult
.SegmentStart
= aBoundary
.startPos
;
668 aResult
.SegmentEnd
= aBoundary
.endPos
;
673 case AccessibleTextType::LINE
:
676 implGetLineBoundary( aBoundary
, nIndex
);
678 if ( aBoundary
.endPos
< nLength
)
680 implGetLineBoundary( aBoundary
, aBoundary
.endPos
);
681 if ( implIsValidBoundary( aBoundary
, nLength
) )
683 aResult
.SegmentText
= sText
.copy( aBoundary
.startPos
, aBoundary
.endPos
- aBoundary
.startPos
);
684 aResult
.SegmentStart
= aBoundary
.startPos
;
685 aResult
.SegmentEnd
= aBoundary
.endPos
;
690 case AccessibleTextType::ATTRIBUTE_RUN
:
692 // TODO: implGetAttributeRunBoundary() (incompatible!)
704 // -----------------------------------------------------------------------------
705 bool OCommonAccessibleText::implInitTextChangedEvent(
706 const rtl::OUString
& rOldString
,
707 const rtl::OUString
& rNewString
,
708 ::com::sun::star::uno::Any
& rDeleted
,
709 ::com::sun::star::uno::Any
& rInserted
) // throw()
711 sal_uInt32 nLenOld
= rOldString
.getLength();
712 sal_uInt32 nLenNew
= rNewString
.getLength();
715 if ((0 == nLenOld
) && (0 == nLenNew
))
718 TextSegment aDeletedText
;
719 TextSegment aInsertedText
;
721 aDeletedText
.SegmentStart
= -1;
722 aDeletedText
.SegmentEnd
= -1;
723 aInsertedText
.SegmentStart
= -1;
724 aInsertedText
.SegmentEnd
= -1;
727 if ((0 == nLenOld
) && (nLenNew
> 0))
729 aInsertedText
.SegmentStart
= 0;
730 aInsertedText
.SegmentEnd
= nLenNew
;
731 aInsertedText
.SegmentText
= rNewString
.copy( aInsertedText
.SegmentStart
, aInsertedText
.SegmentEnd
- aInsertedText
.SegmentStart
);
733 rInserted
<<= aInsertedText
;
738 if ((nLenOld
> 0) && (0 == nLenNew
))
740 aDeletedText
.SegmentStart
= 0;
741 aDeletedText
.SegmentEnd
= nLenOld
;
742 aDeletedText
.SegmentText
= rOldString
.copy( aDeletedText
.SegmentStart
, aDeletedText
.SegmentEnd
- aDeletedText
.SegmentStart
);
744 rDeleted
<<= aDeletedText
;
748 const sal_Unicode
* pFirstDiffOld
= rOldString
.getStr();
749 const sal_Unicode
* pLastDiffOld
= rOldString
.getStr() + nLenOld
;
750 const sal_Unicode
* pFirstDiffNew
= rNewString
.getStr();
751 const sal_Unicode
* pLastDiffNew
= rNewString
.getStr() + nLenNew
;
753 // find first difference
754 while ((*pFirstDiffOld
== *pFirstDiffNew
) &&
755 (pFirstDiffOld
< pLastDiffOld
) &&
756 (pFirstDiffNew
< pLastDiffNew
))
763 if ((0 == *pFirstDiffOld
) && (0 == *pFirstDiffNew
))
766 // find last difference
767 while ( ( pLastDiffOld
> pFirstDiffOld
) &&
768 ( pLastDiffNew
> pFirstDiffNew
) &&
769 (pLastDiffOld
[-1] == pLastDiffNew
[-1]))
775 if (pFirstDiffOld
< pLastDiffOld
)
777 aDeletedText
.SegmentStart
= pFirstDiffOld
- rOldString
.getStr();
778 aDeletedText
.SegmentEnd
= pLastDiffOld
- rOldString
.getStr();
779 aDeletedText
.SegmentText
= rOldString
.copy( aDeletedText
.SegmentStart
, aDeletedText
.SegmentEnd
- aDeletedText
.SegmentStart
);
781 rDeleted
<<= aDeletedText
;
784 if (pFirstDiffNew
< pLastDiffNew
)
786 aInsertedText
.SegmentStart
= pFirstDiffNew
- rNewString
.getStr();
787 aInsertedText
.SegmentEnd
= pLastDiffNew
- rNewString
.getStr();
788 aInsertedText
.SegmentText
= rNewString
.copy( aInsertedText
.SegmentStart
, aInsertedText
.SegmentEnd
- aInsertedText
.SegmentStart
);
790 rInserted
<<= aInsertedText
;
795 //==============================================================================
796 // OAccessibleTextHelper
797 //==============================================================================
799 OAccessibleTextHelper::OAccessibleTextHelper()
803 // -----------------------------------------------------------------------------
805 OAccessibleTextHelper::OAccessibleTextHelper( IMutex
* _pExternalLock
)
806 :OAccessibleExtendedComponentHelper( _pExternalLock
)
810 // -----------------------------------------------------------------------------
812 // -----------------------------------------------------------------------------
814 IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleTextHelper
, OAccessibleExtendedComponentHelper
, OAccessibleTextHelper_Base
)
816 // -----------------------------------------------------------------------------
818 // -----------------------------------------------------------------------------
820 IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleTextHelper
, OAccessibleExtendedComponentHelper
, OAccessibleTextHelper_Base
)
822 // -----------------------------------------------------------------------------
824 // -----------------------------------------------------------------------------
826 sal_Unicode
OAccessibleTextHelper::getCharacter( sal_Int32 nIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
828 OExternalLockGuard
aGuard( this );
830 return OCommonAccessibleText::getCharacter( nIndex
);
833 // -----------------------------------------------------------------------------
835 sal_Int32
OAccessibleTextHelper::getCharacterCount() throw (RuntimeException
)
837 OExternalLockGuard
aGuard( this );
839 return OCommonAccessibleText::getCharacterCount();
842 // -----------------------------------------------------------------------------
844 ::rtl::OUString
OAccessibleTextHelper::getSelectedText() throw (RuntimeException
)
846 OExternalLockGuard
aGuard( this );
848 return OCommonAccessibleText::getSelectedText();
851 // -----------------------------------------------------------------------------
853 sal_Int32
OAccessibleTextHelper::getSelectionStart() throw (RuntimeException
)
855 OExternalLockGuard
aGuard( this );
857 return OCommonAccessibleText::getSelectionStart();
860 // -----------------------------------------------------------------------------
862 sal_Int32
OAccessibleTextHelper::getSelectionEnd() throw (RuntimeException
)
864 OExternalLockGuard
aGuard( this );
866 return OCommonAccessibleText::getSelectionEnd();
869 // -----------------------------------------------------------------------------
871 ::rtl::OUString
OAccessibleTextHelper::getText() throw (RuntimeException
)
873 OExternalLockGuard
aGuard( this );
875 return OCommonAccessibleText::getText();
878 // -----------------------------------------------------------------------------
880 ::rtl::OUString
OAccessibleTextHelper::getTextRange( sal_Int32 nStartIndex
, sal_Int32 nEndIndex
) throw (IndexOutOfBoundsException
, RuntimeException
)
882 OExternalLockGuard
aGuard( this );
884 return OCommonAccessibleText::getTextRange( nStartIndex
, nEndIndex
);
887 // -----------------------------------------------------------------------------
889 TextSegment
OAccessibleTextHelper::getTextAtIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
891 OExternalLockGuard
aGuard( this );
893 return OCommonAccessibleText::getTextAtIndex( nIndex
, aTextType
);
896 // -----------------------------------------------------------------------------
898 TextSegment
OAccessibleTextHelper::getTextBeforeIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
900 OExternalLockGuard
aGuard( this );
902 return OCommonAccessibleText::getTextBeforeIndex( nIndex
, aTextType
);
905 // -----------------------------------------------------------------------------
907 TextSegment
OAccessibleTextHelper::getTextBehindIndex( sal_Int32 nIndex
, sal_Int16 aTextType
) throw (IndexOutOfBoundsException
, IllegalArgumentException
, RuntimeException
)
909 OExternalLockGuard
aGuard( this );
911 return OCommonAccessibleText::getTextBehindIndex( nIndex
, aTextType
);
914 // -----------------------------------------------------------------------------
916 //..............................................................................
917 } // namespace comphelper
918 //..............................................................................