xref: /trunk/main/comphelper/source/misc/accessibletexthelper.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1*dde7d3faSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*dde7d3faSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*dde7d3faSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*dde7d3faSAndrew Rist  * distributed with this work for additional information
6*dde7d3faSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*dde7d3faSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*dde7d3faSAndrew Rist  * "License"); you may not use this file except in compliance
9*dde7d3faSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*dde7d3faSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*dde7d3faSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*dde7d3faSAndrew Rist  * software distributed under the License is distributed on an
15*dde7d3faSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*dde7d3faSAndrew Rist  * KIND, either express or implied.  See the License for the
17*dde7d3faSAndrew Rist  * specific language governing permissions and limitations
18*dde7d3faSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*dde7d3faSAndrew Rist  *************************************************************/
21*dde7d3faSAndrew Rist 
22*dde7d3faSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_comphelper.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir // includes --------------------------------------------------------------
28cdf0e10cSrcweir #include <comphelper/accessibletexthelper.hxx>
29cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleTextType.hpp>
30cdf0e10cSrcweir #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
31cdf0e10cSrcweir #ifndef _COM_SUN_STAR_TEXT_WORDTYPE_HPP_
32cdf0e10cSrcweir #include <com/sun/star/i18n/WordType.hpp>
33cdf0e10cSrcweir #endif
34cdf0e10cSrcweir #include <com/sun/star/i18n/KCharacterType.hpp>
35cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
36cdf0e10cSrcweir #include <com/sun/star/accessibility/TextSegment.hpp>
37cdf0e10cSrcweir 
38cdf0e10cSrcweir #include <algorithm>
39cdf0e10cSrcweir 
40cdf0e10cSrcweir //..............................................................................
41cdf0e10cSrcweir namespace comphelper
42cdf0e10cSrcweir {
43cdf0e10cSrcweir //..............................................................................
44cdf0e10cSrcweir 
45cdf0e10cSrcweir     using namespace ::com::sun::star;
46cdf0e10cSrcweir     using namespace ::com::sun::star::uno;
47cdf0e10cSrcweir     using namespace ::com::sun::star::lang;
48cdf0e10cSrcweir     using namespace ::com::sun::star::beans;
49cdf0e10cSrcweir     using namespace ::com::sun::star::accessibility;
50cdf0e10cSrcweir 
51cdf0e10cSrcweir     //==============================================================================
52cdf0e10cSrcweir     // OCommonAccessibleText
53cdf0e10cSrcweir     //==============================================================================
54cdf0e10cSrcweir 
OCommonAccessibleText()55cdf0e10cSrcweir     OCommonAccessibleText::OCommonAccessibleText()
56cdf0e10cSrcweir     {
57cdf0e10cSrcweir     }
58cdf0e10cSrcweir 
59cdf0e10cSrcweir     // -----------------------------------------------------------------------------
60cdf0e10cSrcweir 
~OCommonAccessibleText()61cdf0e10cSrcweir     OCommonAccessibleText::~OCommonAccessibleText()
62cdf0e10cSrcweir     {
63cdf0e10cSrcweir     }
64cdf0e10cSrcweir 
65cdf0e10cSrcweir     // -----------------------------------------------------------------------------
66cdf0e10cSrcweir 
implGetBreakIterator()67cdf0e10cSrcweir     Reference < i18n::XBreakIterator > OCommonAccessibleText::implGetBreakIterator()
68cdf0e10cSrcweir     {
69cdf0e10cSrcweir         if ( !m_xBreakIter.is() )
70cdf0e10cSrcweir         {
71cdf0e10cSrcweir             Reference< lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
72cdf0e10cSrcweir             if ( xMSF.is() )
73cdf0e10cSrcweir             {
74cdf0e10cSrcweir                 m_xBreakIter = Reference< i18n::XBreakIterator >
75cdf0e10cSrcweir                     ( xMSF->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.BreakIterator" ) ) ), UNO_QUERY );
76cdf0e10cSrcweir             }
77cdf0e10cSrcweir         }
78cdf0e10cSrcweir 
79cdf0e10cSrcweir         return m_xBreakIter;
80cdf0e10cSrcweir     }
81cdf0e10cSrcweir 
82cdf0e10cSrcweir     // -----------------------------------------------------------------------------
83cdf0e10cSrcweir 
implGetCharacterClassification()84cdf0e10cSrcweir     Reference < i18n::XCharacterClassification > OCommonAccessibleText::implGetCharacterClassification()
85cdf0e10cSrcweir     {
86cdf0e10cSrcweir         if ( !m_xCharClass.is() )
87cdf0e10cSrcweir         {
88cdf0e10cSrcweir             Reference< lang::XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
89cdf0e10cSrcweir             if ( xMSF.is() )
90cdf0e10cSrcweir             {
91cdf0e10cSrcweir                 m_xCharClass = Reference< i18n::XCharacterClassification >
92cdf0e10cSrcweir                     ( xMSF->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.CharacterClassification" ) ) ), UNO_QUERY );
93cdf0e10cSrcweir             }
94cdf0e10cSrcweir         }
95cdf0e10cSrcweir 
96cdf0e10cSrcweir         return m_xCharClass;
97cdf0e10cSrcweir     }
98cdf0e10cSrcweir 
99cdf0e10cSrcweir     // -----------------------------------------------------------------------------
100cdf0e10cSrcweir 
implIsValidBoundary(i18n::Boundary & rBoundary,sal_Int32 nLength)101cdf0e10cSrcweir     sal_Bool OCommonAccessibleText::implIsValidBoundary( i18n::Boundary& rBoundary, sal_Int32 nLength )
102cdf0e10cSrcweir     {
103cdf0e10cSrcweir         return ( rBoundary.startPos >= 0 ) && ( rBoundary.startPos < nLength ) && ( rBoundary.endPos >= 0 ) && ( rBoundary.endPos <= nLength );
104cdf0e10cSrcweir     }
105cdf0e10cSrcweir 
106cdf0e10cSrcweir     // -----------------------------------------------------------------------------
107cdf0e10cSrcweir 
implIsValidIndex(sal_Int32 nIndex,sal_Int32 nLength)108cdf0e10cSrcweir     sal_Bool OCommonAccessibleText::implIsValidIndex( sal_Int32 nIndex, sal_Int32 nLength )
109cdf0e10cSrcweir     {
110cdf0e10cSrcweir         return ( nIndex >= 0 ) && ( nIndex < nLength );
111cdf0e10cSrcweir     }
112cdf0e10cSrcweir 
113cdf0e10cSrcweir     // -----------------------------------------------------------------------------
114cdf0e10cSrcweir 
implIsValidRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex,sal_Int32 nLength)115cdf0e10cSrcweir     sal_Bool OCommonAccessibleText::implIsValidRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex, sal_Int32 nLength )
116cdf0e10cSrcweir     {
117cdf0e10cSrcweir         return ( nStartIndex >= 0 ) && ( nStartIndex <= nLength ) && ( nEndIndex >= 0 ) && ( nEndIndex <= nLength );
118cdf0e10cSrcweir     }
119cdf0e10cSrcweir 
120cdf0e10cSrcweir     // -----------------------------------------------------------------------------
121cdf0e10cSrcweir 
implGetGlyphBoundary(i18n::Boundary & rBoundary,sal_Int32 nIndex)122cdf0e10cSrcweir     void OCommonAccessibleText::implGetGlyphBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex )
123cdf0e10cSrcweir     {
124cdf0e10cSrcweir         ::rtl::OUString sText( implGetText() );
125cdf0e10cSrcweir 
126cdf0e10cSrcweir         if ( implIsValidIndex( nIndex, sText.getLength() ) )
127cdf0e10cSrcweir         {
128cdf0e10cSrcweir             Reference < i18n::XBreakIterator > xBreakIter = implGetBreakIterator();
129cdf0e10cSrcweir             if ( xBreakIter.is() )
130cdf0e10cSrcweir             {
131cdf0e10cSrcweir                 sal_Int32 nCount = 1;
132cdf0e10cSrcweir                 sal_Int32 nDone;
133cdf0e10cSrcweir                 sal_Int32 nStartIndex = xBreakIter->previousCharacters( sText, nIndex, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL, nCount, nDone );
134cdf0e10cSrcweir                 if ( nDone != 0 )
135cdf0e10cSrcweir                     nStartIndex = xBreakIter->nextCharacters( sText, nStartIndex, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL, nCount, nDone );
136cdf0e10cSrcweir                 sal_Int32 nEndIndex = xBreakIter->nextCharacters( sText, nStartIndex, implGetLocale(), i18n::CharacterIteratorMode::SKIPCELL, nCount, nDone );
137cdf0e10cSrcweir                 if ( nDone != 0 )
138cdf0e10cSrcweir                 {
139cdf0e10cSrcweir                     rBoundary.startPos = nStartIndex;
140cdf0e10cSrcweir                     rBoundary.endPos = nEndIndex;
141cdf0e10cSrcweir                 }
142cdf0e10cSrcweir             }
143cdf0e10cSrcweir         }
144cdf0e10cSrcweir         else
145cdf0e10cSrcweir         {
146cdf0e10cSrcweir             rBoundary.startPos = nIndex;
147cdf0e10cSrcweir             rBoundary.endPos = nIndex;
148cdf0e10cSrcweir         }
149cdf0e10cSrcweir     }
150cdf0e10cSrcweir 
151cdf0e10cSrcweir     // -----------------------------------------------------------------------------
152cdf0e10cSrcweir 
implGetWordBoundary(i18n::Boundary & rBoundary,sal_Int32 nIndex)153cdf0e10cSrcweir     sal_Bool OCommonAccessibleText::implGetWordBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex )
154cdf0e10cSrcweir     {
155cdf0e10cSrcweir         sal_Bool bWord = sal_False;
156cdf0e10cSrcweir         ::rtl::OUString sText( implGetText() );
157cdf0e10cSrcweir 
158cdf0e10cSrcweir         if ( implIsValidIndex( nIndex, sText.getLength() ) )
159cdf0e10cSrcweir         {
160cdf0e10cSrcweir             Reference < i18n::XBreakIterator > xBreakIter = implGetBreakIterator();
161cdf0e10cSrcweir             if ( xBreakIter.is() )
162cdf0e10cSrcweir             {
163cdf0e10cSrcweir                 rBoundary = xBreakIter->getWordBoundary( sText, nIndex, implGetLocale(), i18n::WordType::ANY_WORD, sal_True );
164cdf0e10cSrcweir 
165cdf0e10cSrcweir                 // it's a word, if the first character is an alpha-numeric character
166cdf0e10cSrcweir                 Reference< i18n::XCharacterClassification > xCharClass = implGetCharacterClassification();
167cdf0e10cSrcweir                 if ( xCharClass.is() )
168cdf0e10cSrcweir                 {
169cdf0e10cSrcweir                     sal_Int32 nType = xCharClass->getCharacterType( sText, rBoundary.startPos, implGetLocale() );
170cdf0e10cSrcweir                     if ( ( nType & ( i18n::KCharacterType::LETTER | i18n::KCharacterType::DIGIT ) ) != 0 )
171cdf0e10cSrcweir                         bWord = sal_True;
172cdf0e10cSrcweir                 }
173cdf0e10cSrcweir             }
174cdf0e10cSrcweir         }
175cdf0e10cSrcweir         else
176cdf0e10cSrcweir         {
177cdf0e10cSrcweir             rBoundary.startPos = nIndex;
178cdf0e10cSrcweir             rBoundary.endPos = nIndex;
179cdf0e10cSrcweir         }
180cdf0e10cSrcweir 
181cdf0e10cSrcweir         return bWord;
182cdf0e10cSrcweir     }
183cdf0e10cSrcweir 
184cdf0e10cSrcweir     // -----------------------------------------------------------------------------
185cdf0e10cSrcweir 
implGetSentenceBoundary(i18n::Boundary & rBoundary,sal_Int32 nIndex)186cdf0e10cSrcweir     void OCommonAccessibleText::implGetSentenceBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex )
187cdf0e10cSrcweir     {
188cdf0e10cSrcweir         ::rtl::OUString sText( implGetText() );
189cdf0e10cSrcweir 
190cdf0e10cSrcweir         if ( implIsValidIndex( nIndex, sText.getLength() ) )
191cdf0e10cSrcweir         {
192cdf0e10cSrcweir             Locale aLocale = implGetLocale();
193cdf0e10cSrcweir             Reference < i18n::XBreakIterator > xBreakIter = implGetBreakIterator();
194cdf0e10cSrcweir             if ( xBreakIter.is() )
195cdf0e10cSrcweir             {
196cdf0e10cSrcweir                 rBoundary.endPos = xBreakIter->endOfSentence( sText, nIndex, aLocale );
197cdf0e10cSrcweir                 rBoundary.startPos = xBreakIter->beginOfSentence( sText, rBoundary.endPos, aLocale );
198cdf0e10cSrcweir             }
199cdf0e10cSrcweir         }
200cdf0e10cSrcweir         else
201cdf0e10cSrcweir         {
202cdf0e10cSrcweir             rBoundary.startPos = nIndex;
203cdf0e10cSrcweir             rBoundary.endPos = nIndex;
204cdf0e10cSrcweir         }
205cdf0e10cSrcweir     }
206cdf0e10cSrcweir 
207cdf0e10cSrcweir     // -----------------------------------------------------------------------------
208cdf0e10cSrcweir 
implGetParagraphBoundary(i18n::Boundary & rBoundary,sal_Int32 nIndex)209cdf0e10cSrcweir     void OCommonAccessibleText::implGetParagraphBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex )
210cdf0e10cSrcweir     {
211cdf0e10cSrcweir         ::rtl::OUString sText( implGetText() );
212cdf0e10cSrcweir 
213cdf0e10cSrcweir         if ( implIsValidIndex( nIndex, sText.getLength() ) )
214cdf0e10cSrcweir         {
215cdf0e10cSrcweir             rBoundary.startPos = 0;
216cdf0e10cSrcweir             rBoundary.endPos = sText.getLength();
217cdf0e10cSrcweir 
218cdf0e10cSrcweir             sal_Int32 nFound = sText.lastIndexOf( (sal_Unicode)'\n', nIndex );
219cdf0e10cSrcweir             if ( nFound != -1 )
220cdf0e10cSrcweir                 rBoundary.startPos = nFound + 1;
221cdf0e10cSrcweir 
222cdf0e10cSrcweir             nFound = sText.indexOf( (sal_Unicode)'\n', nIndex );
223cdf0e10cSrcweir             if ( nFound != -1 )
224cdf0e10cSrcweir                 rBoundary.endPos = nFound + 1;
225cdf0e10cSrcweir         }
226cdf0e10cSrcweir         else
227cdf0e10cSrcweir         {
228cdf0e10cSrcweir             rBoundary.startPos = nIndex;
229cdf0e10cSrcweir             rBoundary.endPos = nIndex;
230cdf0e10cSrcweir         }
231cdf0e10cSrcweir     }
232cdf0e10cSrcweir 
233cdf0e10cSrcweir     // -----------------------------------------------------------------------------
234cdf0e10cSrcweir 
implGetLineBoundary(i18n::Boundary & rBoundary,sal_Int32 nIndex)235cdf0e10cSrcweir     void OCommonAccessibleText::implGetLineBoundary( i18n::Boundary& rBoundary, sal_Int32 nIndex )
236cdf0e10cSrcweir     {
237cdf0e10cSrcweir         ::rtl::OUString sText( implGetText() );
238cdf0e10cSrcweir         sal_Int32 nLength = sText.getLength();
239cdf0e10cSrcweir 
240cdf0e10cSrcweir         if ( implIsValidIndex( nIndex, nLength ) || nIndex == nLength )
241cdf0e10cSrcweir         {
242cdf0e10cSrcweir             rBoundary.startPos = 0;
243cdf0e10cSrcweir             rBoundary.endPos = nLength;
244cdf0e10cSrcweir         }
245cdf0e10cSrcweir         else
246cdf0e10cSrcweir         {
247cdf0e10cSrcweir             rBoundary.startPos = nIndex;
248cdf0e10cSrcweir             rBoundary.endPos = nIndex;
249cdf0e10cSrcweir         }
250cdf0e10cSrcweir     }
251cdf0e10cSrcweir 
252cdf0e10cSrcweir     // -----------------------------------------------------------------------------
253cdf0e10cSrcweir 
getCharacter(sal_Int32 nIndex)254cdf0e10cSrcweir     sal_Unicode OCommonAccessibleText::getCharacter( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
255cdf0e10cSrcweir     {
256cdf0e10cSrcweir         ::rtl::OUString sText( implGetText() );
257cdf0e10cSrcweir 
258cdf0e10cSrcweir         if ( !implIsValidIndex( nIndex, sText.getLength() ) )
259cdf0e10cSrcweir             throw IndexOutOfBoundsException();
260cdf0e10cSrcweir 
261cdf0e10cSrcweir         return sText.getStr()[nIndex];
262cdf0e10cSrcweir     }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir     // -----------------------------------------------------------------------------
265cdf0e10cSrcweir 
getCharacterCount()266cdf0e10cSrcweir     sal_Int32 OCommonAccessibleText::getCharacterCount() throw (RuntimeException)
267cdf0e10cSrcweir     {
268cdf0e10cSrcweir         return implGetText().getLength();
269cdf0e10cSrcweir     }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir     // -----------------------------------------------------------------------------
272cdf0e10cSrcweir 
getSelectedText()273cdf0e10cSrcweir     ::rtl::OUString OCommonAccessibleText::getSelectedText() throw (RuntimeException)
274cdf0e10cSrcweir     {
275cdf0e10cSrcweir         ::rtl::OUString sText;
276cdf0e10cSrcweir         sal_Int32 nStartIndex;
277cdf0e10cSrcweir         sal_Int32 nEndIndex;
278cdf0e10cSrcweir 
279cdf0e10cSrcweir         implGetSelection( nStartIndex, nEndIndex );
280cdf0e10cSrcweir 
281cdf0e10cSrcweir         try
282cdf0e10cSrcweir         {
283cdf0e10cSrcweir             sText = getTextRange( nStartIndex, nEndIndex );
284cdf0e10cSrcweir         }
285cdf0e10cSrcweir         catch ( IndexOutOfBoundsException& )
286cdf0e10cSrcweir         {
287cdf0e10cSrcweir         }
288cdf0e10cSrcweir 
289cdf0e10cSrcweir         return sText;
290cdf0e10cSrcweir     }
291cdf0e10cSrcweir 
292cdf0e10cSrcweir     // -----------------------------------------------------------------------------
293cdf0e10cSrcweir 
getSelectionStart()294cdf0e10cSrcweir     sal_Int32 OCommonAccessibleText::getSelectionStart() throw (RuntimeException)
295cdf0e10cSrcweir     {
296cdf0e10cSrcweir         sal_Int32 nStartIndex;
297cdf0e10cSrcweir         sal_Int32 nEndIndex;
298cdf0e10cSrcweir 
299cdf0e10cSrcweir         implGetSelection( nStartIndex, nEndIndex );
300cdf0e10cSrcweir 
301cdf0e10cSrcweir         return nStartIndex;
302cdf0e10cSrcweir     }
303cdf0e10cSrcweir 
304cdf0e10cSrcweir     // -----------------------------------------------------------------------------
305cdf0e10cSrcweir 
getSelectionEnd()306cdf0e10cSrcweir     sal_Int32 OCommonAccessibleText::getSelectionEnd() throw (RuntimeException)
307cdf0e10cSrcweir     {
308cdf0e10cSrcweir         sal_Int32 nStartIndex;
309cdf0e10cSrcweir         sal_Int32 nEndIndex;
310cdf0e10cSrcweir 
311cdf0e10cSrcweir         implGetSelection( nStartIndex, nEndIndex );
312cdf0e10cSrcweir 
313cdf0e10cSrcweir         return nEndIndex;
314cdf0e10cSrcweir     }
315cdf0e10cSrcweir 
316cdf0e10cSrcweir     // -----------------------------------------------------------------------------
317cdf0e10cSrcweir 
getText()318cdf0e10cSrcweir     ::rtl::OUString OCommonAccessibleText::getText() throw (RuntimeException)
319cdf0e10cSrcweir     {
320cdf0e10cSrcweir         return implGetText();
321cdf0e10cSrcweir     }
322cdf0e10cSrcweir 
323cdf0e10cSrcweir     // -----------------------------------------------------------------------------
324cdf0e10cSrcweir 
getTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)325cdf0e10cSrcweir     ::rtl::OUString OCommonAccessibleText::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
326cdf0e10cSrcweir     {
327cdf0e10cSrcweir         ::rtl::OUString sText( implGetText() );
328cdf0e10cSrcweir 
329cdf0e10cSrcweir         if ( !implIsValidRange( nStartIndex, nEndIndex, sText.getLength() ) )
330cdf0e10cSrcweir             throw IndexOutOfBoundsException();
331cdf0e10cSrcweir 
332cdf0e10cSrcweir         sal_Int32 nMinIndex = ::std::min( nStartIndex, nEndIndex );
333cdf0e10cSrcweir         sal_Int32 nMaxIndex = ::std::max( nStartIndex, nEndIndex );
334cdf0e10cSrcweir 
335cdf0e10cSrcweir         return sText.copy( nMinIndex, nMaxIndex - nMinIndex );
336cdf0e10cSrcweir     }
337cdf0e10cSrcweir 
338cdf0e10cSrcweir     // -----------------------------------------------------------------------------
339cdf0e10cSrcweir 
getTextAtIndex(sal_Int32 nIndex,sal_Int16 aTextType)340cdf0e10cSrcweir     TextSegment OCommonAccessibleText::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException)
341cdf0e10cSrcweir     {
342cdf0e10cSrcweir         ::rtl::OUString sText( implGetText() );
343cdf0e10cSrcweir         sal_Int32 nLength = sText.getLength();
344cdf0e10cSrcweir 
345cdf0e10cSrcweir         if ( !implIsValidIndex( nIndex, nLength ) && nIndex != nLength )
346cdf0e10cSrcweir             throw IndexOutOfBoundsException();
347cdf0e10cSrcweir 
348cdf0e10cSrcweir         i18n::Boundary aBoundary;
349cdf0e10cSrcweir         TextSegment aResult;
350cdf0e10cSrcweir         aResult.SegmentStart = -1;
351cdf0e10cSrcweir         aResult.SegmentEnd = -1;
352cdf0e10cSrcweir 
353cdf0e10cSrcweir         switch ( aTextType )
354cdf0e10cSrcweir         {
355cdf0e10cSrcweir             case AccessibleTextType::CHARACTER:
356cdf0e10cSrcweir             {
357cdf0e10cSrcweir                 if ( implIsValidIndex( nIndex, nLength ) )
358cdf0e10cSrcweir                 {
359cdf0e10cSrcweir                     aResult.SegmentText = sText.copy( nIndex, 1 );
360cdf0e10cSrcweir                     aResult.SegmentStart = nIndex;
361cdf0e10cSrcweir                     aResult.SegmentEnd = nIndex+1;
362cdf0e10cSrcweir                 }
363cdf0e10cSrcweir             }
364cdf0e10cSrcweir             break;
365cdf0e10cSrcweir             case AccessibleTextType::GLYPH:
366cdf0e10cSrcweir             {
367cdf0e10cSrcweir                 // get glyph at index
368cdf0e10cSrcweir                 implGetGlyphBoundary( aBoundary, nIndex );
369cdf0e10cSrcweir                 if ( implIsValidBoundary( aBoundary, nLength ) )
370cdf0e10cSrcweir                 {
371cdf0e10cSrcweir                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
372cdf0e10cSrcweir                     aResult.SegmentStart = aBoundary.startPos;
373cdf0e10cSrcweir                     aResult.SegmentEnd = aBoundary.endPos;
374cdf0e10cSrcweir                 }
375cdf0e10cSrcweir             }
376cdf0e10cSrcweir             break;
377cdf0e10cSrcweir             case AccessibleTextType::WORD:
378cdf0e10cSrcweir             {
379cdf0e10cSrcweir                 // get word at index
380cdf0e10cSrcweir                 sal_Bool bWord = implGetWordBoundary( aBoundary, nIndex );
381cdf0e10cSrcweir                 if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
382cdf0e10cSrcweir                 {
383cdf0e10cSrcweir                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
384cdf0e10cSrcweir                     aResult.SegmentStart = aBoundary.startPos;
385cdf0e10cSrcweir                     aResult.SegmentEnd = aBoundary.endPos;
386cdf0e10cSrcweir                 }
387cdf0e10cSrcweir             }
388cdf0e10cSrcweir             break;
389cdf0e10cSrcweir             case AccessibleTextType::SENTENCE:
390cdf0e10cSrcweir             {
391cdf0e10cSrcweir                 // get sentence at index
392cdf0e10cSrcweir                 implGetSentenceBoundary( aBoundary, nIndex );
393cdf0e10cSrcweir                 if ( implIsValidBoundary( aBoundary, nLength ) )
394cdf0e10cSrcweir                 {
395cdf0e10cSrcweir                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
396cdf0e10cSrcweir                     aResult.SegmentStart = aBoundary.startPos;
397cdf0e10cSrcweir                     aResult.SegmentEnd = aBoundary.endPos;
398cdf0e10cSrcweir                 }
399cdf0e10cSrcweir             }
400cdf0e10cSrcweir             break;
401cdf0e10cSrcweir             case AccessibleTextType::PARAGRAPH:
402cdf0e10cSrcweir             {
403cdf0e10cSrcweir                 // get paragraph at index
404cdf0e10cSrcweir                 implGetParagraphBoundary( aBoundary, nIndex );
405cdf0e10cSrcweir                 if ( implIsValidBoundary( aBoundary, nLength ) )
406cdf0e10cSrcweir                 {
407cdf0e10cSrcweir                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
408cdf0e10cSrcweir                     aResult.SegmentStart = aBoundary.startPos;
409cdf0e10cSrcweir                     aResult.SegmentEnd = aBoundary.endPos;
410cdf0e10cSrcweir                 }
411cdf0e10cSrcweir             }
412cdf0e10cSrcweir             break;
413cdf0e10cSrcweir             case AccessibleTextType::LINE:
414cdf0e10cSrcweir             {
415cdf0e10cSrcweir                 // get line at index
416cdf0e10cSrcweir                 implGetLineBoundary( aBoundary, nIndex );
417cdf0e10cSrcweir                 if ( implIsValidBoundary( aBoundary, nLength ) )
418cdf0e10cSrcweir                 {
419cdf0e10cSrcweir                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
420cdf0e10cSrcweir                     aResult.SegmentStart = aBoundary.startPos;
421cdf0e10cSrcweir                     aResult.SegmentEnd = aBoundary.endPos;
422cdf0e10cSrcweir                 }
423cdf0e10cSrcweir             }
424cdf0e10cSrcweir             break;
425cdf0e10cSrcweir             case AccessibleTextType::ATTRIBUTE_RUN:
426cdf0e10cSrcweir             {
427cdf0e10cSrcweir                 // TODO: implGetAttributeRunBoundary() (incompatible!)
428cdf0e10cSrcweir 
429cdf0e10cSrcweir                 aResult.SegmentText = sText;
430cdf0e10cSrcweir                 aResult.SegmentStart = 0;
431cdf0e10cSrcweir                 aResult.SegmentEnd = nLength;
432cdf0e10cSrcweir             }
433cdf0e10cSrcweir             break;
434cdf0e10cSrcweir             default:
435cdf0e10cSrcweir             {
436cdf0e10cSrcweir                 // unknown text type
437cdf0e10cSrcweir             }
438cdf0e10cSrcweir         }
439cdf0e10cSrcweir 
440cdf0e10cSrcweir         return aResult;
441cdf0e10cSrcweir     }
442cdf0e10cSrcweir 
443cdf0e10cSrcweir     // -----------------------------------------------------------------------------
444cdf0e10cSrcweir 
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 aTextType)445cdf0e10cSrcweir     TextSegment OCommonAccessibleText::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException)
446cdf0e10cSrcweir     {
447cdf0e10cSrcweir         ::rtl::OUString sText( implGetText() );
448cdf0e10cSrcweir         sal_Int32 nLength = sText.getLength();
449cdf0e10cSrcweir 
450cdf0e10cSrcweir         if ( !implIsValidIndex( nIndex, nLength ) && nIndex != nLength )
451cdf0e10cSrcweir             throw IndexOutOfBoundsException();
452cdf0e10cSrcweir 
453cdf0e10cSrcweir         i18n::Boundary aBoundary;
454cdf0e10cSrcweir         TextSegment aResult;
455cdf0e10cSrcweir         aResult.SegmentStart = -1;
456cdf0e10cSrcweir         aResult.SegmentEnd = -1;
457cdf0e10cSrcweir 
458cdf0e10cSrcweir         switch ( aTextType )
459cdf0e10cSrcweir         {
460cdf0e10cSrcweir             case AccessibleTextType::CHARACTER:
461cdf0e10cSrcweir             {
462cdf0e10cSrcweir                 if ( implIsValidIndex( nIndex - 1, nLength ) )
463cdf0e10cSrcweir                 {
464cdf0e10cSrcweir                     aResult.SegmentText = sText.copy( nIndex - 1, 1 );
465cdf0e10cSrcweir                     aResult.SegmentStart = nIndex-1;
466cdf0e10cSrcweir                     aResult.SegmentEnd = nIndex;
467cdf0e10cSrcweir                 }
468cdf0e10cSrcweir             }
469cdf0e10cSrcweir             break;
470cdf0e10cSrcweir             case AccessibleTextType::GLYPH:
471cdf0e10cSrcweir             {
472cdf0e10cSrcweir                 // get glyph at index
473cdf0e10cSrcweir                 implGetGlyphBoundary( aBoundary, nIndex );
474cdf0e10cSrcweir                 // get previous glyph
475cdf0e10cSrcweir                 if ( aBoundary.startPos > 0 )
476cdf0e10cSrcweir                 {
477cdf0e10cSrcweir                     implGetGlyphBoundary( aBoundary, aBoundary.startPos - 1 );
478cdf0e10cSrcweir                     if ( implIsValidBoundary( aBoundary, nLength ) )
479cdf0e10cSrcweir                     {
480cdf0e10cSrcweir                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
481cdf0e10cSrcweir                         aResult.SegmentStart = aBoundary.startPos;
482cdf0e10cSrcweir                         aResult.SegmentEnd = aBoundary.endPos;
483cdf0e10cSrcweir                     }
484cdf0e10cSrcweir                 }
485cdf0e10cSrcweir             }
486cdf0e10cSrcweir             break;
487cdf0e10cSrcweir             case AccessibleTextType::WORD:
488cdf0e10cSrcweir             {
489cdf0e10cSrcweir                 // get word at index
490cdf0e10cSrcweir                 implGetWordBoundary( aBoundary, nIndex );
491cdf0e10cSrcweir                 // get previous word
492cdf0e10cSrcweir                 sal_Bool bWord = sal_False;
493cdf0e10cSrcweir                 while ( !bWord && aBoundary.startPos > 0 )
494cdf0e10cSrcweir                     bWord = implGetWordBoundary( aBoundary, aBoundary.startPos - 1 );
495cdf0e10cSrcweir                 if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
496cdf0e10cSrcweir                 {
497cdf0e10cSrcweir                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
498cdf0e10cSrcweir                     aResult.SegmentStart = aBoundary.startPos;
499cdf0e10cSrcweir                     aResult.SegmentEnd = aBoundary.endPos;
500cdf0e10cSrcweir                 }
501cdf0e10cSrcweir             }
502cdf0e10cSrcweir             break;
503cdf0e10cSrcweir             case AccessibleTextType::SENTENCE:
504cdf0e10cSrcweir             {
505cdf0e10cSrcweir                 // get sentence at index
506cdf0e10cSrcweir                 implGetSentenceBoundary( aBoundary, nIndex );
507cdf0e10cSrcweir                 // get previous sentence
508cdf0e10cSrcweir                 if ( aBoundary.startPos > 0 )
509cdf0e10cSrcweir                 {
510cdf0e10cSrcweir                     implGetSentenceBoundary( aBoundary, aBoundary.startPos - 1 );
511cdf0e10cSrcweir                     if ( implIsValidBoundary( aBoundary, nLength ) )
512cdf0e10cSrcweir                     {
513cdf0e10cSrcweir                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
514cdf0e10cSrcweir                         aResult.SegmentStart = aBoundary.startPos;
515cdf0e10cSrcweir                         aResult.SegmentEnd = aBoundary.endPos;
516cdf0e10cSrcweir                     }
517cdf0e10cSrcweir                 }
518cdf0e10cSrcweir             }
519cdf0e10cSrcweir             break;
520cdf0e10cSrcweir             case AccessibleTextType::PARAGRAPH:
521cdf0e10cSrcweir             {
522cdf0e10cSrcweir                 // get paragraph at index
523cdf0e10cSrcweir                 implGetParagraphBoundary( aBoundary, nIndex );
524cdf0e10cSrcweir                 // get previous paragraph
525cdf0e10cSrcweir                 if ( aBoundary.startPos > 0 )
526cdf0e10cSrcweir                 {
527cdf0e10cSrcweir                     implGetParagraphBoundary( aBoundary, aBoundary.startPos - 1 );
528cdf0e10cSrcweir                     if ( implIsValidBoundary( aBoundary, nLength ) )
529cdf0e10cSrcweir                     {
530cdf0e10cSrcweir                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
531cdf0e10cSrcweir                         aResult.SegmentStart = aBoundary.startPos;
532cdf0e10cSrcweir                         aResult.SegmentEnd = aBoundary.endPos;
533cdf0e10cSrcweir                     }
534cdf0e10cSrcweir                 }
535cdf0e10cSrcweir             }
536cdf0e10cSrcweir             break;
537cdf0e10cSrcweir             case AccessibleTextType::LINE:
538cdf0e10cSrcweir             {
539cdf0e10cSrcweir                 // get line at index
540cdf0e10cSrcweir                 implGetLineBoundary( aBoundary, nIndex );
541cdf0e10cSrcweir                 // get previous line
542cdf0e10cSrcweir                 if ( aBoundary.startPos > 0 )
543cdf0e10cSrcweir                 {
544cdf0e10cSrcweir                     implGetLineBoundary( aBoundary, aBoundary.startPos - 1 );
545cdf0e10cSrcweir                     if ( implIsValidBoundary( aBoundary, nLength ) )
546cdf0e10cSrcweir                     {
547cdf0e10cSrcweir                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
548cdf0e10cSrcweir                         aResult.SegmentStart = aBoundary.startPos;
549cdf0e10cSrcweir                         aResult.SegmentEnd = aBoundary.endPos;
550cdf0e10cSrcweir                     }
551cdf0e10cSrcweir                 }
552cdf0e10cSrcweir             }
553cdf0e10cSrcweir             break;
554cdf0e10cSrcweir             case AccessibleTextType::ATTRIBUTE_RUN:
555cdf0e10cSrcweir             {
556cdf0e10cSrcweir                 // TODO: implGetAttributeRunBoundary() (incompatible!)
557cdf0e10cSrcweir             }
558cdf0e10cSrcweir             break;
559cdf0e10cSrcweir             default:
560cdf0e10cSrcweir             {
561cdf0e10cSrcweir                 // unknown text type
562cdf0e10cSrcweir             }
563cdf0e10cSrcweir         }
564cdf0e10cSrcweir 
565cdf0e10cSrcweir         return aResult;
566cdf0e10cSrcweir     }
567cdf0e10cSrcweir 
568cdf0e10cSrcweir     // -----------------------------------------------------------------------------
569cdf0e10cSrcweir 
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 aTextType)570cdf0e10cSrcweir     TextSegment OCommonAccessibleText::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException)
571cdf0e10cSrcweir     {
572cdf0e10cSrcweir         ::rtl::OUString sText( implGetText() );
573cdf0e10cSrcweir         sal_Int32 nLength = sText.getLength();
574cdf0e10cSrcweir 
575cdf0e10cSrcweir         if ( !implIsValidIndex( nIndex, nLength ) && nIndex != nLength )
576cdf0e10cSrcweir             throw IndexOutOfBoundsException();
577cdf0e10cSrcweir 
578cdf0e10cSrcweir         i18n::Boundary aBoundary;
579cdf0e10cSrcweir         TextSegment aResult;
580cdf0e10cSrcweir         aResult.SegmentStart = -1;
581cdf0e10cSrcweir         aResult.SegmentEnd = -1;
582cdf0e10cSrcweir 
583cdf0e10cSrcweir         switch ( aTextType )
584cdf0e10cSrcweir         {
585cdf0e10cSrcweir             case AccessibleTextType::CHARACTER:
586cdf0e10cSrcweir             {
587cdf0e10cSrcweir                 if ( implIsValidIndex( nIndex + 1, nLength ) )
588cdf0e10cSrcweir                 {
589cdf0e10cSrcweir                     aResult.SegmentText = sText.copy( nIndex + 1, 1 );
590cdf0e10cSrcweir                     aResult.SegmentStart = nIndex+1;
591cdf0e10cSrcweir                     aResult.SegmentEnd = nIndex+2;
592cdf0e10cSrcweir                 }
593cdf0e10cSrcweir             }
594cdf0e10cSrcweir             break;
595cdf0e10cSrcweir             case AccessibleTextType::GLYPH:
596cdf0e10cSrcweir             {
597cdf0e10cSrcweir                 // get glyph at index
598cdf0e10cSrcweir                 implGetGlyphBoundary( aBoundary, nIndex );
599cdf0e10cSrcweir                 // get next glyph
600cdf0e10cSrcweir                 if ( aBoundary.endPos < nLength )
601cdf0e10cSrcweir                 {
602cdf0e10cSrcweir                     implGetGlyphBoundary( aBoundary, aBoundary.endPos );
603cdf0e10cSrcweir                     if ( implIsValidBoundary( aBoundary, nLength ) )
604cdf0e10cSrcweir                     {
605cdf0e10cSrcweir                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
606cdf0e10cSrcweir                         aResult.SegmentStart = aBoundary.startPos;
607cdf0e10cSrcweir                         aResult.SegmentEnd = aBoundary.endPos;
608cdf0e10cSrcweir                     }
609cdf0e10cSrcweir                 }
610cdf0e10cSrcweir             }
611cdf0e10cSrcweir             break;
612cdf0e10cSrcweir             case AccessibleTextType::WORD:
613cdf0e10cSrcweir             {
614cdf0e10cSrcweir                 // get word at index
615cdf0e10cSrcweir                 implGetWordBoundary( aBoundary, nIndex );
616cdf0e10cSrcweir                 // get next word
617cdf0e10cSrcweir                 sal_Bool bWord = sal_False;
618cdf0e10cSrcweir                 while ( !bWord && aBoundary.endPos < nLength )
619cdf0e10cSrcweir                     bWord = implGetWordBoundary( aBoundary, aBoundary.endPos );
620cdf0e10cSrcweir                 if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
621cdf0e10cSrcweir                 {
622cdf0e10cSrcweir                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
623cdf0e10cSrcweir                     aResult.SegmentStart = aBoundary.startPos;
624cdf0e10cSrcweir                     aResult.SegmentEnd = aBoundary.endPos;
625cdf0e10cSrcweir                 }
626cdf0e10cSrcweir             }
627cdf0e10cSrcweir             break;
628cdf0e10cSrcweir             case AccessibleTextType::SENTENCE:
629cdf0e10cSrcweir             {
630cdf0e10cSrcweir                 // get sentence at index
631cdf0e10cSrcweir                 implGetSentenceBoundary( aBoundary, nIndex );
632cdf0e10cSrcweir                 // get next sentence
633cdf0e10cSrcweir                 sal_Int32 nEnd = aBoundary.endPos;
634cdf0e10cSrcweir                 sal_Int32 nI = aBoundary.endPos;
635cdf0e10cSrcweir                 sal_Bool bFound = sal_False;
636cdf0e10cSrcweir                 while ( !bFound && ++nI < nLength )
637cdf0e10cSrcweir                 {
638cdf0e10cSrcweir                     implGetSentenceBoundary( aBoundary, nI );
639cdf0e10cSrcweir                     bFound = ( aBoundary.endPos > nEnd );
640cdf0e10cSrcweir                 }
641cdf0e10cSrcweir                 if ( bFound && implIsValidBoundary( aBoundary, nLength ) )
642cdf0e10cSrcweir                 {
643cdf0e10cSrcweir                     aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
644cdf0e10cSrcweir                     aResult.SegmentStart = aBoundary.startPos;
645cdf0e10cSrcweir                     aResult.SegmentEnd = aBoundary.endPos;
646cdf0e10cSrcweir                 }
647cdf0e10cSrcweir             }
648cdf0e10cSrcweir             break;
649cdf0e10cSrcweir             case AccessibleTextType::PARAGRAPH:
650cdf0e10cSrcweir             {
651cdf0e10cSrcweir                 // get paragraph at index
652cdf0e10cSrcweir                 implGetParagraphBoundary( aBoundary, nIndex );
653cdf0e10cSrcweir                 // get next paragraph
654cdf0e10cSrcweir                 if ( aBoundary.endPos < nLength )
655cdf0e10cSrcweir                 {
656cdf0e10cSrcweir                     implGetParagraphBoundary( aBoundary, aBoundary.endPos );
657cdf0e10cSrcweir                     if ( implIsValidBoundary( aBoundary, nLength ) )
658cdf0e10cSrcweir                     {
659cdf0e10cSrcweir                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
660cdf0e10cSrcweir                         aResult.SegmentStart = aBoundary.startPos;
661cdf0e10cSrcweir                         aResult.SegmentEnd = aBoundary.endPos;
662cdf0e10cSrcweir                     }
663cdf0e10cSrcweir                 }
664cdf0e10cSrcweir             }
665cdf0e10cSrcweir             break;
666cdf0e10cSrcweir             case AccessibleTextType::LINE:
667cdf0e10cSrcweir             {
668cdf0e10cSrcweir                 // get line at index
669cdf0e10cSrcweir                 implGetLineBoundary( aBoundary, nIndex );
670cdf0e10cSrcweir                 // get next line
671cdf0e10cSrcweir                 if ( aBoundary.endPos < nLength )
672cdf0e10cSrcweir                 {
673cdf0e10cSrcweir                     implGetLineBoundary( aBoundary, aBoundary.endPos );
674cdf0e10cSrcweir                     if ( implIsValidBoundary( aBoundary, nLength ) )
675cdf0e10cSrcweir                     {
676cdf0e10cSrcweir                         aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
677cdf0e10cSrcweir                         aResult.SegmentStart = aBoundary.startPos;
678cdf0e10cSrcweir                         aResult.SegmentEnd = aBoundary.endPos;
679cdf0e10cSrcweir                     }
680cdf0e10cSrcweir                 }
681cdf0e10cSrcweir             }
682cdf0e10cSrcweir             break;
683cdf0e10cSrcweir             case AccessibleTextType::ATTRIBUTE_RUN:
684cdf0e10cSrcweir             {
685cdf0e10cSrcweir                 // TODO: implGetAttributeRunBoundary() (incompatible!)
686cdf0e10cSrcweir             }
687cdf0e10cSrcweir             break;
688cdf0e10cSrcweir             default:
689cdf0e10cSrcweir             {
690cdf0e10cSrcweir                 // unknown text type
691cdf0e10cSrcweir             }
692cdf0e10cSrcweir         }
693cdf0e10cSrcweir 
694cdf0e10cSrcweir         return aResult;
695cdf0e10cSrcweir     }
696cdf0e10cSrcweir 
697cdf0e10cSrcweir     // -----------------------------------------------------------------------------
implInitTextChangedEvent(const rtl::OUString & rOldString,const rtl::OUString & rNewString,::com::sun::star::uno::Any & rDeleted,::com::sun::star::uno::Any & rInserted)698cdf0e10cSrcweir     bool OCommonAccessibleText::implInitTextChangedEvent(
699cdf0e10cSrcweir         const rtl::OUString& rOldString,
700cdf0e10cSrcweir         const rtl::OUString& rNewString,
701cdf0e10cSrcweir         ::com::sun::star::uno::Any& rDeleted,
702cdf0e10cSrcweir         ::com::sun::star::uno::Any& rInserted) // throw()
703cdf0e10cSrcweir     {
704cdf0e10cSrcweir         sal_uInt32 nLenOld = rOldString.getLength();
705cdf0e10cSrcweir         sal_uInt32 nLenNew = rNewString.getLength();
706cdf0e10cSrcweir 
707cdf0e10cSrcweir         // equal
708cdf0e10cSrcweir         if ((0 == nLenOld) && (0 == nLenNew))
709cdf0e10cSrcweir             return false;
710cdf0e10cSrcweir 
711cdf0e10cSrcweir         TextSegment aDeletedText;
712cdf0e10cSrcweir         TextSegment aInsertedText;
713cdf0e10cSrcweir 
714cdf0e10cSrcweir         aDeletedText.SegmentStart = -1;
715cdf0e10cSrcweir         aDeletedText.SegmentEnd = -1;
716cdf0e10cSrcweir         aInsertedText.SegmentStart = -1;
717cdf0e10cSrcweir         aInsertedText.SegmentEnd = -1;
718cdf0e10cSrcweir 
719cdf0e10cSrcweir         // insert only
720cdf0e10cSrcweir         if ((0 == nLenOld) && (nLenNew > 0))
721cdf0e10cSrcweir         {
722cdf0e10cSrcweir             aInsertedText.SegmentStart = 0;
723cdf0e10cSrcweir             aInsertedText.SegmentEnd = nLenNew;
724cdf0e10cSrcweir             aInsertedText.SegmentText = rNewString.copy( aInsertedText.SegmentStart, aInsertedText.SegmentEnd - aInsertedText.SegmentStart );
725cdf0e10cSrcweir 
726cdf0e10cSrcweir             rInserted <<= aInsertedText;
727cdf0e10cSrcweir             return true;
728cdf0e10cSrcweir         }
729cdf0e10cSrcweir 
730cdf0e10cSrcweir         // delete only
731cdf0e10cSrcweir         if ((nLenOld > 0) && (0 == nLenNew))
732cdf0e10cSrcweir         {
733cdf0e10cSrcweir             aDeletedText.SegmentStart = 0;
734cdf0e10cSrcweir             aDeletedText.SegmentEnd = nLenOld;
735cdf0e10cSrcweir             aDeletedText.SegmentText = rOldString.copy( aDeletedText.SegmentStart, aDeletedText.SegmentEnd - aDeletedText.SegmentStart );
736cdf0e10cSrcweir 
737cdf0e10cSrcweir             rDeleted <<= aDeletedText;
738cdf0e10cSrcweir             return true;
739cdf0e10cSrcweir         }
740cdf0e10cSrcweir 
741cdf0e10cSrcweir         const sal_Unicode* pFirstDiffOld = rOldString.getStr();
742cdf0e10cSrcweir         const sal_Unicode* pLastDiffOld  = rOldString.getStr() + nLenOld;
743cdf0e10cSrcweir         const sal_Unicode* pFirstDiffNew = rNewString.getStr();
744cdf0e10cSrcweir         const sal_Unicode* pLastDiffNew  = rNewString.getStr() + nLenNew;
745cdf0e10cSrcweir 
746cdf0e10cSrcweir         // find first difference
747cdf0e10cSrcweir         while ((*pFirstDiffOld == *pFirstDiffNew) &&
748cdf0e10cSrcweir                (pFirstDiffOld  <  pLastDiffOld) &&
749cdf0e10cSrcweir                (pFirstDiffNew  <  pLastDiffNew))
750cdf0e10cSrcweir         {
751cdf0e10cSrcweir             pFirstDiffOld++;
752cdf0e10cSrcweir             pFirstDiffNew++;
753cdf0e10cSrcweir         }
754cdf0e10cSrcweir 
755cdf0e10cSrcweir         // equality test
756cdf0e10cSrcweir         if ((0 == *pFirstDiffOld) && (0 == *pFirstDiffNew))
757cdf0e10cSrcweir             return false;
758cdf0e10cSrcweir 
759cdf0e10cSrcweir         // find last difference
760cdf0e10cSrcweir         while ( ( pLastDiffOld > pFirstDiffOld) &&
761cdf0e10cSrcweir                 ( pLastDiffNew > pFirstDiffNew) &&
762cdf0e10cSrcweir                 (pLastDiffOld[-1]  == pLastDiffNew[-1]))
763cdf0e10cSrcweir         {
764cdf0e10cSrcweir             pLastDiffOld--;
765cdf0e10cSrcweir             pLastDiffNew--;
766cdf0e10cSrcweir         }
767cdf0e10cSrcweir 
768cdf0e10cSrcweir         if (pFirstDiffOld < pLastDiffOld)
769cdf0e10cSrcweir         {
770cdf0e10cSrcweir             aDeletedText.SegmentStart = pFirstDiffOld - rOldString.getStr();
771cdf0e10cSrcweir             aDeletedText.SegmentEnd = pLastDiffOld  - rOldString.getStr();
772cdf0e10cSrcweir             aDeletedText.SegmentText = rOldString.copy( aDeletedText.SegmentStart, aDeletedText.SegmentEnd - aDeletedText.SegmentStart );
773cdf0e10cSrcweir 
774cdf0e10cSrcweir             rDeleted <<= aDeletedText;
775cdf0e10cSrcweir         }
776cdf0e10cSrcweir 
777cdf0e10cSrcweir         if (pFirstDiffNew < pLastDiffNew)
778cdf0e10cSrcweir         {
779cdf0e10cSrcweir             aInsertedText.SegmentStart = pFirstDiffNew - rNewString.getStr();
780cdf0e10cSrcweir             aInsertedText.SegmentEnd = pLastDiffNew  - rNewString.getStr();
781cdf0e10cSrcweir             aInsertedText.SegmentText = rNewString.copy( aInsertedText.SegmentStart, aInsertedText.SegmentEnd - aInsertedText.SegmentStart );
782cdf0e10cSrcweir 
783cdf0e10cSrcweir             rInserted <<= aInsertedText;
784cdf0e10cSrcweir         }
785cdf0e10cSrcweir         return true;
786cdf0e10cSrcweir     }
787cdf0e10cSrcweir 
788cdf0e10cSrcweir     //==============================================================================
789cdf0e10cSrcweir     // OAccessibleTextHelper
790cdf0e10cSrcweir     //==============================================================================
791cdf0e10cSrcweir 
OAccessibleTextHelper()792cdf0e10cSrcweir     OAccessibleTextHelper::OAccessibleTextHelper()
793cdf0e10cSrcweir     {
794cdf0e10cSrcweir     }
795cdf0e10cSrcweir 
796cdf0e10cSrcweir     // -----------------------------------------------------------------------------
797cdf0e10cSrcweir 
OAccessibleTextHelper(IMutex * _pExternalLock)798cdf0e10cSrcweir     OAccessibleTextHelper::OAccessibleTextHelper( IMutex* _pExternalLock )
799cdf0e10cSrcweir         :OAccessibleExtendedComponentHelper( _pExternalLock )
800cdf0e10cSrcweir     {
801cdf0e10cSrcweir     }
802cdf0e10cSrcweir 
803cdf0e10cSrcweir     // -----------------------------------------------------------------------------
804cdf0e10cSrcweir     // XInterface
805cdf0e10cSrcweir     // -----------------------------------------------------------------------------
806cdf0e10cSrcweir 
IMPLEMENT_FORWARD_XINTERFACE2(OAccessibleTextHelper,OAccessibleExtendedComponentHelper,OAccessibleTextHelper_Base)807cdf0e10cSrcweir     IMPLEMENT_FORWARD_XINTERFACE2( OAccessibleTextHelper, OAccessibleExtendedComponentHelper, OAccessibleTextHelper_Base )
808cdf0e10cSrcweir 
809cdf0e10cSrcweir     // -----------------------------------------------------------------------------
810cdf0e10cSrcweir     // XTypeProvider
811cdf0e10cSrcweir     // -----------------------------------------------------------------------------
812cdf0e10cSrcweir 
813cdf0e10cSrcweir     IMPLEMENT_FORWARD_XTYPEPROVIDER2( OAccessibleTextHelper, OAccessibleExtendedComponentHelper, OAccessibleTextHelper_Base )
814cdf0e10cSrcweir 
815cdf0e10cSrcweir     // -----------------------------------------------------------------------------
816cdf0e10cSrcweir     // XAccessibleText
817cdf0e10cSrcweir     // -----------------------------------------------------------------------------
818cdf0e10cSrcweir 
819cdf0e10cSrcweir     sal_Unicode OAccessibleTextHelper::getCharacter( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
820cdf0e10cSrcweir     {
821cdf0e10cSrcweir         OExternalLockGuard aGuard( this );
822cdf0e10cSrcweir 
823cdf0e10cSrcweir         return OCommonAccessibleText::getCharacter( nIndex );
824cdf0e10cSrcweir     }
825cdf0e10cSrcweir 
826cdf0e10cSrcweir     // -----------------------------------------------------------------------------
827cdf0e10cSrcweir 
getCharacterCount()828cdf0e10cSrcweir     sal_Int32 OAccessibleTextHelper::getCharacterCount() throw (RuntimeException)
829cdf0e10cSrcweir     {
830cdf0e10cSrcweir         OExternalLockGuard aGuard( this );
831cdf0e10cSrcweir 
832cdf0e10cSrcweir         return OCommonAccessibleText::getCharacterCount();
833cdf0e10cSrcweir     }
834cdf0e10cSrcweir 
835cdf0e10cSrcweir     // -----------------------------------------------------------------------------
836cdf0e10cSrcweir 
getSelectedText()837cdf0e10cSrcweir     ::rtl::OUString OAccessibleTextHelper::getSelectedText() throw (RuntimeException)
838cdf0e10cSrcweir     {
839cdf0e10cSrcweir         OExternalLockGuard aGuard( this );
840cdf0e10cSrcweir 
841cdf0e10cSrcweir         return OCommonAccessibleText::getSelectedText();
842cdf0e10cSrcweir     }
843cdf0e10cSrcweir 
844cdf0e10cSrcweir     // -----------------------------------------------------------------------------
845cdf0e10cSrcweir 
getSelectionStart()846cdf0e10cSrcweir     sal_Int32 OAccessibleTextHelper::getSelectionStart() throw (RuntimeException)
847cdf0e10cSrcweir     {
848cdf0e10cSrcweir         OExternalLockGuard aGuard( this );
849cdf0e10cSrcweir 
850cdf0e10cSrcweir         return OCommonAccessibleText::getSelectionStart();
851cdf0e10cSrcweir     }
852cdf0e10cSrcweir 
853cdf0e10cSrcweir     // -----------------------------------------------------------------------------
854cdf0e10cSrcweir 
getSelectionEnd()855cdf0e10cSrcweir     sal_Int32 OAccessibleTextHelper::getSelectionEnd() throw (RuntimeException)
856cdf0e10cSrcweir     {
857cdf0e10cSrcweir         OExternalLockGuard aGuard( this );
858cdf0e10cSrcweir 
859cdf0e10cSrcweir         return OCommonAccessibleText::getSelectionEnd();
860cdf0e10cSrcweir     }
861cdf0e10cSrcweir 
862cdf0e10cSrcweir     // -----------------------------------------------------------------------------
863cdf0e10cSrcweir 
getText()864cdf0e10cSrcweir     ::rtl::OUString OAccessibleTextHelper::getText() throw (RuntimeException)
865cdf0e10cSrcweir     {
866cdf0e10cSrcweir         OExternalLockGuard aGuard( this );
867cdf0e10cSrcweir 
868cdf0e10cSrcweir         return OCommonAccessibleText::getText();
869cdf0e10cSrcweir     }
870cdf0e10cSrcweir 
871cdf0e10cSrcweir     // -----------------------------------------------------------------------------
872cdf0e10cSrcweir 
getTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)873cdf0e10cSrcweir     ::rtl::OUString OAccessibleTextHelper::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
874cdf0e10cSrcweir     {
875cdf0e10cSrcweir         OExternalLockGuard aGuard( this );
876cdf0e10cSrcweir 
877cdf0e10cSrcweir         return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex );
878cdf0e10cSrcweir     }
879cdf0e10cSrcweir 
880cdf0e10cSrcweir     // -----------------------------------------------------------------------------
881cdf0e10cSrcweir 
getTextAtIndex(sal_Int32 nIndex,sal_Int16 aTextType)882cdf0e10cSrcweir     TextSegment OAccessibleTextHelper::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException)
883cdf0e10cSrcweir     {
884cdf0e10cSrcweir         OExternalLockGuard aGuard( this );
885cdf0e10cSrcweir 
886cdf0e10cSrcweir         return OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
887cdf0e10cSrcweir     }
888cdf0e10cSrcweir 
889cdf0e10cSrcweir     // -----------------------------------------------------------------------------
890cdf0e10cSrcweir 
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 aTextType)891cdf0e10cSrcweir     TextSegment OAccessibleTextHelper::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException)
892cdf0e10cSrcweir     {
893cdf0e10cSrcweir         OExternalLockGuard aGuard( this );
894cdf0e10cSrcweir 
895cdf0e10cSrcweir         return OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
896cdf0e10cSrcweir     }
897cdf0e10cSrcweir 
898cdf0e10cSrcweir     // -----------------------------------------------------------------------------
899cdf0e10cSrcweir 
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 aTextType)900cdf0e10cSrcweir     TextSegment OAccessibleTextHelper::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (IndexOutOfBoundsException, IllegalArgumentException, RuntimeException)
901cdf0e10cSrcweir     {
902cdf0e10cSrcweir         OExternalLockGuard aGuard( this );
903cdf0e10cSrcweir 
904cdf0e10cSrcweir         return OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
905cdf0e10cSrcweir     }
906cdf0e10cSrcweir 
907cdf0e10cSrcweir     // -----------------------------------------------------------------------------
908cdf0e10cSrcweir 
909cdf0e10cSrcweir //..............................................................................
910cdf0e10cSrcweir }   // namespace comphelper
911cdf0e10cSrcweir //..............................................................................
912