xref: /AOO41X/main/comphelper/source/misc/accessibletexthelper.cxx (revision dde7d3faf6dcd9cbeb7b48ba6d0cea5ffcc883d0)
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