1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright IBM Corporation 2010.
6  * Copyright 2000, 2010 Oracle and/or its affiliates.
7  *
8  * OpenOffice.org - a multi-platform office productivity suite
9  *
10  * This file is part of OpenOffice.org.
11  *
12  * OpenOffice.org is free software: you can redistribute it and/or modify
13  * it under the terms of the GNU Lesser General Public License version 3
14  * only, as published by the Free Software Foundation.
15  *
16  * OpenOffice.org is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU Lesser General Public License version 3 for more details
20  * (a copy is included in the LICENSE file that accompanied this code).
21  *
22  * You should have received a copy of the GNU Lesser General Public License
23  * version 3 along with OpenOffice.org.  If not, see
24  * <http://www.openoffice.org/license.html>
25  * for a copy of the LGPLv3 License.
26  *
27  ************************************************************************/
28 
29 //////////////////////////////////////////////////////////////////////
30 // AccTextBase.cpp: implementation of the CAccTextBase class.
31 //////////////////////////////////////////////////////////////////////
32 #include "stdafx.h"
33 #include <string>
34 #define WNT
35 
36 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
37 #include "AccTextBase.h"
38 #include <com/sun/star/accessibility/XAccessible.hpp>
39 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
40 #include <com/sun/star/accessibility/XAccessibleComponent.hpp>
41 #include <com/sun/star/accessibility/XAccessibleTextSelection.hpp>
42 #include "MAccessible.h"
43 
44 using namespace com::sun::star::accessibility;
45 using namespace com::sun::star::uno;
46 using namespace rtl;
47 
48 //////////////////////////////////////////////////////////////////////
49 // Construction/Destruction
50 //////////////////////////////////////////////////////////////////////
51 
52 OUString ReplaceFourChar(OUString oldOUString);
53 
54 CAccTextBase::CAccTextBase()
55 {}
56 
57 CAccTextBase::~CAccTextBase()
58 {}
59 
60 
61 /**
62    * Get special selection.
63    * @param startOffset Start selection offset.
64    * @param endOffset   End selection offset.
65    * @param success     Variant to accept the result of if the method call is successful.
66    * @return Result.
67 */
68 STDMETHODIMP CAccTextBase::get_addSelection(long startOffset, long endOffset)
69 {
70 
71 	CHECK_ENABLE_INF
72 
73     ENTER_PROTECTED_BLOCK
74 
75     // #CHECK XInterface#
76     if(pUNOInterface == NULL)
77         return E_FAIL;
78 
79     Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
80 
81     Reference< XAccessibleTextSelection > pRExtension(pRContext,UNO_QUERY);
82 
83     if( pRExtension.is() )
84     {
85         pRExtension->addSelection(0, startOffset, endOffset);
86         return S_OK;
87     }
88     else
89     {
90         GetXInterface()->setSelection(startOffset, endOffset);
91         return S_OK;
92     }
93 
94     return E_FAIL;
95 
96     LEAVE_PROTECTED_BLOCK
97 }
98 
99 /**
100    * Get special attributes.
101    * @param offset Offset.
102    * @param startOffset Variant to accept start offset.
103    * @param endOffset   Variant to accept end offset.
104    * @param textAttributes     Variant to accept attributes.
105    * @return Result.
106 */
107 STDMETHODIMP CAccTextBase::get_attributes(long offset, long * startOffset, long * endOffset, BSTR * textAttributes)
108 {
109 
110 	CHECK_ENABLE_INF
111 
112     ENTER_PROTECTED_BLOCK
113 
114     if (startOffset == NULL || endOffset == NULL || textAttributes == NULL)
115         return E_INVALIDARG;
116     // #CHECK XInterface#
117     if(!pRXText.is())
118     {
119         return E_FAIL;
120     }
121 
122     if( offset < 0 || offset > GetXInterface()->getCharacterCount() )
123         return E_FAIL;
124 
125 	std::wstring strAttrs;
126 
127     strAttrs += L"Version:1;";
128 
129     Sequence< ::com::sun::star::beans::PropertyValue > pValues = GetXInterface()->getCharacterAttributes(offset, Sequence< rtl::OUString >());
130     int nCount = pValues.getLength();
131 
132     short numberingLevel = 0;
133     OUString numberingPrefix;
134 	Any anyNumRule;
135     bool bHaveNumberingPrefixAttr = false;
136 	bool bHaveNumberingLevel = false;
137 	bool bHaveNumberingRules = false;
138     for(int i =0; i<nCount; i++)
139     {
140 
141         ::com::sun::star::beans::PropertyValue &pValue = pValues[i];
142         if(pValue.Name.compareTo(OUString::createFromAscii("NumberingLevel"))==0)
143         {
144 			if (pValue.Value != Any())
145 				pValue.Value >>= numberingLevel;
146 			else
147 				numberingLevel = -1;
148 			bHaveNumberingLevel = true;
149             continue;
150         }
151         if(pValue.Name.compareTo(OUString::createFromAscii("NumberingPrefix"))==0)
152         {
153             pValue.Value >>=numberingPrefix;
154             bHaveNumberingPrefixAttr = true;
155             continue;
156         }
157         if(pValue.Name.compareTo(OUString::createFromAscii("NumberingRules"))==0)
158         {
159 			bHaveNumberingRules = true;
160 			anyNumRule = pValue.Value;
161 			continue;
162         }
163 		if (bHaveNumberingLevel && bHaveNumberingRules && bHaveNumberingPrefixAttr)
164 		{
165 			OLECHAR numProps[512] = {0};
166 			strAttrs+=L";";
167 			numberingPrefix = ReplaceFourChar(numberingPrefix);
168 			CMAccessible::get_OLECHAR4Numbering(anyNumRule,numberingLevel,numberingPrefix,numProps);
169 			strAttrs += numProps;
170 			bHaveNumberingLevel = 0;
171 			bHaveNumberingRules = 0;
172 		}
173 		if( (bHaveNumberingPrefixAttr && i > 1 ) ||
174 			(!bHaveNumberingPrefixAttr && i > 0 ) ) //element 0 is NumberingPrefix, not write alone
175 		{
176 			strAttrs+=L";";
177 		}
178         strAttrs += pValue.Name.getStr();
179         strAttrs += L":";
180 
181         OLECHAR pTemp[2048] = {0};
182 
183         if (pValue.Name.compareTo(OUString::createFromAscii("CharBackColor"))==0 ||
184                 pValue.Name.compareTo(OUString::createFromAscii("CharColor"))==0 ||
185                 pValue.Name.compareTo(OUString::createFromAscii("CharUnderlineColor"))==0 )
186         {
187             unsigned long nColor;
188             pValue.Value >>= nColor;
189             OLECHAR pBuf[64];
190             swprintf( pBuf, L"%08X", nColor );
191             pTemp[0]=L'#';
192             wcscat( pTemp, pBuf );
193 
194         }
195         else
196         {
197             CMAccessible::get_OLECHARFromAny(pValue.Value,pTemp);
198         }
199 
200         strAttrs +=pTemp;
201     }
202 	strAttrs +=L";";
203     // #CHECK#
204     if(*textAttributes)
205         SysFreeString(*textAttributes);
206     *textAttributes = SysAllocString(strAttrs.c_str());
207 
208     if( offset < GetXInterface()->getCharacterCount() )
209     {
210         TextSegment textSeg = GetXInterface()->getTextAtIndex(offset, AccessibleTextType::ATTRIBUTE_RUN);
211         *startOffset = textSeg.SegmentStart;
212         *endOffset = textSeg.SegmentEnd;
213     }
214     else
215     {
216         *startOffset = offset;
217         *endOffset = offset;
218     }
219 
220     return S_OK;
221 
222     LEAVE_PROTECTED_BLOCK
223 }
224 
225 /**
226    * Get caret position.
227    * @param offset     Variant to accept caret offset.
228    * @return Result.
229 */
230 STDMETHODIMP CAccTextBase::get_caretOffset(long * offset)
231 {
232 
233 	CHECK_ENABLE_INF
234 
235     ENTER_PROTECTED_BLOCK
236 
237     if (offset == NULL)
238         return E_INVALIDARG;
239     // #CHECK XInterface#
240     if(!pRXText.is())
241     {
242         *offset = 0;
243         return S_OK;
244     }
245 
246     *offset = GetXInterface()->getCaretPosition();
247     return S_OK;
248 
249     LEAVE_PROTECTED_BLOCK
250 }
251 
252 /**
253    * Get character count.
254    * @param nCharacters  Variant to accept character count.
255    * @return Result.
256 */
257 STDMETHODIMP CAccTextBase::get_characterCount(long * nCharacters)
258 {
259 
260 	CHECK_ENABLE_INF
261 
262     ENTER_PROTECTED_BLOCK
263 
264     if (nCharacters == NULL)
265         return E_INVALIDARG;
266     // #CHECK XInterface#
267     if(!pRXText.is())
268     {
269         *nCharacters = 0;
270         return S_OK;
271     }
272 
273     *nCharacters = GetXInterface()->getCharacterCount();
274     return S_OK;
275 
276     LEAVE_PROTECTED_BLOCK
277 }
278 
279 /**
280    * Get character extents.
281    * @param offset  Offset.
282    * @param x Variant to accept x position.
283    * @param y Variant to accept y position.
284    * @param width Variant to accept width.
285    * @param Height Variant to accept height.
286    * @return Result.
287 */
288 STDMETHODIMP CAccTextBase::get_characterExtents(long offset, IA2CoordinateType coordType, long * x, long * y, long * width, long * height)
289 {
290 
291 	CHECK_ENABLE_INF
292 
293     ENTER_PROTECTED_BLOCK
294 
295     if (x == NULL || height == NULL || y == NULL || width == NULL)
296         return E_INVALIDARG;
297     // #CHECK XInterface#
298     if(!pRXText.is())
299         return E_FAIL;
300 
301     if(offset < 0 || offset > GetXInterface()->getCharacterCount() )
302         return E_FAIL;
303 
304     com::sun::star::awt::Rectangle rectangle;
305     rectangle = GetXInterface()->getCharacterBounds(offset);
306 
307     //IA2Point aPoint;
308     com::sun::star::awt::Point aPoint;
309 
310     Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
311     if( !pRContext.is() )
312     {
313         return E_FAIL;
314     }
315     Reference<XAccessibleComponent> pRComp(pRContext,UNO_QUERY);
316     if( pRComp.is() )
317     {
318         if(coordType == IA2_COORDTYPE_SCREEN_RELATIVE)
319         {
320             ::com::sun::star::awt::Point pt = pRComp->getLocationOnScreen();
321             aPoint.X = pt.X;
322             aPoint.Y = pt.Y;
323         }
324         else if(coordType == IA2_COORDTYPE_PARENT_RELATIVE)
325         {
326             ::com::sun::star::awt::Point pt = pRComp->getLocation();
327             aPoint.X = pt.X;
328             aPoint.Y = pt.Y;
329         }
330     }
331     rectangle.X = rectangle.X + aPoint.X;
332     rectangle.Y = rectangle.Y + aPoint.Y;
333 
334     *x = rectangle.X;
335     *y = rectangle.Y;
336 
337     // GetXInterface()->getCharacterBounds() have different implement in different acc component
338     // But we need return the width/height == 1 for every component when offset == text length.
339     // So we ignore the return result of GetXInterface()->getCharacterBounds() when offset == text length.
340     if( offset == GetXInterface()->getCharacterCount() )
341     {
342         *width = 1;
343         *height = 1;
344     }
345     else
346     {
347         *width = rectangle.Width;
348         *height = rectangle.Height;
349     }
350 
351     return S_OK;
352 
353     LEAVE_PROTECTED_BLOCK
354 }
355 
356 /**
357    * Get selections count.
358    * @param nSelections Variant to accept selections count.
359    * @return Result.
360 */
361 STDMETHODIMP CAccTextBase::get_nSelections(long * nSelections)
362 {
363 
364 	CHECK_ENABLE_INF
365 
366     ENTER_PROTECTED_BLOCK
367 
368     if (nSelections == NULL)
369         return E_INVALIDARG;
370     // #CHECK XInterface#
371     if(pUNOInterface == NULL)
372     {
373         *nSelections = 0;
374         return S_OK;
375     }
376 
377     Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
378 
379     Reference< XAccessibleTextSelection > pRExtension(pRContext,UNO_QUERY);
380 
381     if( pRExtension.is() )
382     {
383         *nSelections = pRExtension->getSelectedPortionCount();
384         return S_OK;
385     }
386 
387     long iLength = GetXInterface()->getSelectedText().getLength();
388     if( iLength> 0)
389     {
390         *nSelections = 1;
391         return S_OK;
392     }
393 
394     *nSelections = 0;
395     return S_OK;
396 
397     LEAVE_PROTECTED_BLOCK
398 }
399 
400 /**
401    * Get offset of some special point.
402    * @param x X position of one point.
403    * @param x Y position of one point.
404    * @param coordType Type.
405    * @param offset Variant to accept offset.
406    * @return Result.
407 */
408 STDMETHODIMP CAccTextBase::get_offsetAtPoint(long x, long y, IA2CoordinateType, long * offset)
409 {
410 	CHECK_ENABLE_INF
411     ENTER_PROTECTED_BLOCK
412 
413     if (offset == NULL)
414         return E_INVALIDARG;
415     // #CHECK XInterface#
416     if(!pRXText.is())
417         return E_FAIL;
418 
419     com::sun::star::awt::Point point;
420     point.X = x;
421     point.Y = y;
422     *offset = GetXInterface()->getIndexAtPoint(point);
423     return S_OK;
424 
425     LEAVE_PROTECTED_BLOCK
426 }
427 
428 /**
429    * Get selection range.
430    * @param selection selection count.
431    * @param startOffset Variant to accept the start offset of special selection.
432    * @param endOffset Variant to accept the end offset of special selection.
433    * @return Result.
434 */
435 
436 STDMETHODIMP CAccTextBase::get_selection(long selectionIndex, long * startOffset, long * endOffset)
437 {
438 
439 	CHECK_ENABLE_INF
440 
441     ENTER_PROTECTED_BLOCK
442 
443     if (startOffset == NULL || endOffset == NULL )
444         return E_INVALIDARG;
445     // #CHECK XInterface#
446     if(pUNOInterface == NULL )
447         return E_FAIL;
448 
449     long nSelection = 0;
450     get_nSelections(&nSelection);
451 
452     if(selectionIndex >= nSelection || selectionIndex < 0 )
453         return E_FAIL;
454 
455     Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
456 
457     Reference< XAccessibleTextSelection > pRExtension(pRContext,UNO_QUERY);
458 
459     if( pRExtension.is() )
460     {
461         *startOffset = pRExtension->getSeletedPositionStart(selectionIndex);
462         *endOffset = pRExtension->getSeletedPositionEnd(selectionIndex);
463         return S_OK;
464     }
465     else if(GetXInterface()->getSelectionEnd() > -1)
466     {
467         *startOffset = GetXInterface()->getSelectionStart();
468         *endOffset = GetXInterface()->getSelectionEnd();
469         return S_OK;
470     }
471 
472     *startOffset = 0;
473     *endOffset = 0;
474     return E_FAIL;
475 
476     LEAVE_PROTECTED_BLOCK
477 }
478 
479 /**
480    * Get special text.
481    * @param startOffset Start position of special range.
482    * @param endOffset   End position of special range.
483    * @param text        Variant to accept the text of special range.
484    * @return Result.
485 */
486 STDMETHODIMP CAccTextBase::get_text(long startOffset, long endOffset, BSTR * text)
487 {
488 
489 	CHECK_ENABLE_INF
490 
491     ENTER_PROTECTED_BLOCK
492 
493     if (text == NULL)
494         return E_INVALIDARG;
495     // #CHECK XInterface#
496     if(!pRXText.is())
497         return E_FAIL;
498 
499     if (endOffset < -1 || endOffset < startOffset )
500     {
501         return E_FAIL;
502     }
503 
504     ::rtl::OUString ouStr;
505     if (endOffset == -1 )
506     {
507         long nLen=0;
508         if(SUCCEEDED(get_characterCount(&nLen)))
509         {
510             ouStr = GetXInterface()->getTextRange( 0, nLen );
511         }
512     }
513     else
514     {
515         ouStr = GetXInterface()->getTextRange( startOffset, endOffset );
516     }
517 
518     SysFreeString(*text);
519     *text = SysAllocString((OLECHAR*)ouStr.getStr());
520     return S_OK;
521 
522     LEAVE_PROTECTED_BLOCK
523 }
524 
525 /**
526    * Get special text before some position.
527    * @param offset Special position.
528    * @param boundaryType Boundary type.
529    * @param startOffset Variant to accept the start offset.
530    * @param endOffset   Variant to accept the end offset.
531    * @param text        Variant to accept the special text.
532    * @return Result.
533 */
534 STDMETHODIMP CAccTextBase::get_textBeforeOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text)
535 {
536 
537 	CHECK_ENABLE_INF
538 
539     ENTER_PROTECTED_BLOCK
540 
541     // #CHECK#
542     if (startOffset == NULL || endOffset == NULL || text == NULL)
543         return E_INVALIDARG;
544     // #CHECK XInterface#
545     if(!pRXText.is())
546         return E_FAIL;
547 
548     // In New UNO IAccessibleText.idl these constant values are defined as follows:
549     //
550     //  const long TEXT_BOUNDARY_CHAR = -1;
551     //  const long TEXT_BOUNDARY_TO_CURSOR_POS = -2;
552     //  const long TEXT_BOUNDARY_START_OF_WORD = -3;
553     //  const long TEXT_BOUNDARY_END_OF_WORD = -4;
554     //  const long TEXT_BOUNDARY_START_OF_SENTENCE = -5;
555     //  const long TEXT_BOUNDARY_END_OF_SENTENCE = -6;
556     //  const long TEXT_BOUNDARY_START_OF_LINE = -7;
557     //  const long TEXT_BOUNDARY_END_OF_LINE = -8;
558     //
559     // In UNO, the corresponding values are as follows:
560     //
561     //  const short CHARACTER = 1;
562     //  const short WORD = 2;
563     //  const short SENTENCE = 3;
564     //  const short PARAGRAPH = 4;
565     //  const short LINE = 5;
566     //  const short GLYPH = 6;
567     //  const short ATTRIBUTE_RUN = 7;
568     //
569 
570     long			lUnoBoundaryType;
571 
572     switch(boundaryType)
573     {
574     case IA2_TEXT_BOUNDARY_CHAR:
575         lUnoBoundaryType = 1; // CHARACTER;
576         break;
577     case IA2_TEXT_BOUNDARY_WORD:
578         lUnoBoundaryType = 2; // WORD;
579         break;
580     case IA2_TEXT_BOUNDARY_SENTENCE:
581         lUnoBoundaryType = 3; // SENTENCE;
582         break;
583     case IA2_TEXT_BOUNDARY_LINE:
584         lUnoBoundaryType = 5; // LINE;
585         break;
586     case IA2_TEXT_BOUNDARY_PARAGRAPH:
587         lUnoBoundaryType = 4;
588         break;
589     case IA2_TEXT_BOUNDARY_ALL:
590         {
591             long nChar;
592             get_nCharacters( &nChar );
593             *startOffset = 0;
594             *endOffset = nChar;
595             return get_text(0, nChar, text);
596         }
597         break;
598     default:
599         return E_FAIL;
600     }
601 
602     TextSegment segment = GetXInterface()->getTextBeforeIndex( offset, sal_Int16(lUnoBoundaryType));
603     ::rtl::OUString ouStr = segment.SegmentText;
604     SysFreeString(*text);
605     *text = SysAllocString((OLECHAR*)ouStr.getStr());
606     *startOffset = segment.SegmentStart;
607     *endOffset = segment.SegmentEnd;
608 
609     return S_OK;
610 
611     LEAVE_PROTECTED_BLOCK
612 }
613 
614 /**
615    * Get special text after some position.
616    * @param offset Special position.
617    * @param boundaryType Boundary type.
618    * @param startOffset Variant to accept the start offset.
619    * @param endOffset   Variant to accept the end offset.
620    * @param text        Variant to accept the special text.
621    * @return Result.
622 */
623 STDMETHODIMP CAccTextBase::get_textAfterOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text)
624 {
625 
626 	CHECK_ENABLE_INF
627 
628     ENTER_PROTECTED_BLOCK
629 
630     if (startOffset == NULL || endOffset == NULL || text == NULL)
631         return E_INVALIDARG;
632     // #CHECK XInterface#
633     if(!pRXText.is())
634         return E_FAIL;
635 
636     // In New UNO IAccessibleText.idl these constant values are defined as follows:
637     //
638     //  const long TEXT_BOUNDARY_CHAR = -1;
639     //  const long TEXT_BOUNDARY_TO_CURSOR_POS = -2;
640     //  const long TEXT_BOUNDARY_START_OF_WORD = -3;
641     //  const long TEXT_BOUNDARY_END_OF_WORD = -4;
642     //  const long TEXT_BOUNDARY_START_OF_SENTENCE = -5;
643     //  const long TEXT_BOUNDARY_END_OF_SENTENCE = -6;
644     //  const long TEXT_BOUNDARY_START_OF_LINE = -7;
645     //  const long TEXT_BOUNDARY_END_OF_LINE = -8;
646     //
647     // In UNO, the corresponding values are as follows:
648     //
649     //  const short CHARACTER = 1;
650     //  const short WORD = 2;
651     //  const short SENTENCE = 3;
652     //  const short PARAGRAPH = 4;
653     //  const short LINE = 5;
654     //  const short GLYPH = 6;
655     //  const short ATTRIBUTE_RUN = 7;
656     //
657 
658     long			lUnoBoundaryType;
659     switch(boundaryType)
660     {
661     case IA2_TEXT_BOUNDARY_CHAR:
662         lUnoBoundaryType = 1; // CHARACTER;
663         break;
664     case IA2_TEXT_BOUNDARY_WORD:
665         lUnoBoundaryType = 2; // WORD;
666         break;
667     case IA2_TEXT_BOUNDARY_SENTENCE:
668         lUnoBoundaryType = 3; // SENTENCE;
669         break;
670     case IA2_TEXT_BOUNDARY_LINE:
671         lUnoBoundaryType = 5; // LINE;
672         break;
673     case IA2_TEXT_BOUNDARY_PARAGRAPH:
674         lUnoBoundaryType = 4;
675         break;
676     case IA2_TEXT_BOUNDARY_ALL:
677         {
678             long nChar;
679             get_nCharacters( &nChar );
680             *startOffset = 0;
681             *endOffset = nChar;
682             return get_text(0, nChar, text);
683         }
684         break;
685     default:
686         return E_FAIL;
687     }
688 
689     TextSegment segment = GetXInterface()->getTextBehindIndex( offset, sal_Int16(lUnoBoundaryType));
690     ::rtl::OUString ouStr = segment.SegmentText;
691     SysFreeString(*text);
692     *text = SysAllocString((OLECHAR*)ouStr.getStr());
693     *startOffset = segment.SegmentStart;
694     *endOffset = segment.SegmentEnd;
695 
696     return S_OK;
697 
698     LEAVE_PROTECTED_BLOCK
699 }
700 
701 /**
702    * Get special text at some position.
703    * @param offset Special position.
704    * @param boundaryType Boundary type.
705    * @param startOffset Variant to accept the start offset.
706    * @param endOffset   Variant to accept the end offset.
707    * @param text        Variant to accept the special text.
708    * @return Result.
709 */
710 STDMETHODIMP CAccTextBase::get_textAtOffset(long offset, IA2TextBoundaryType boundaryType, long * startOffset, long * endOffset, BSTR * text)
711 {
712 
713 
714 	CHECK_ENABLE_INF
715 
716     ENTER_PROTECTED_BLOCK
717 
718     if (startOffset == NULL || text == NULL ||endOffset == NULL)
719         return E_INVALIDARG;
720     // #CHECK XInterface#
721     if(!pRXText.is())
722         return E_FAIL;
723 
724     // In New UNO IAccessibleText.idl these constant values are defined as follows:
725     //
726     //  const long TEXT_BOUNDARY_CHAR = -1;
727     //  const long TEXT_BOUNDARY_TO_CURSOR_POS = -2;
728     //  const long TEXT_BOUNDARY_START_OF_WORD = -3;
729     //  const long TEXT_BOUNDARY_END_OF_WORD = -4;
730     //  const long TEXT_BOUNDARY_START_OF_SENTENCE = -5;
731     //  const long TEXT_BOUNDARY_END_OF_SENTENCE = -6;
732     //  const long TEXT_BOUNDARY_START_OF_LINE = -7;
733     //  const long TEXT_BOUNDARY_END_OF_LINE = -8;
734     //
735     // In UNO, the corresponding values are as follows:
736     //
737     //  const short CHARACTER = 1;
738     //  const short WORD = 2;
739     //  const short SENTENCE = 3;
740     //  const short PARAGRAPH = 4;
741     //  const short LINE = 5;
742     //  const short GLYPH = 6;
743     //  const short ATTRIBUTE_RUN = 7;
744     //
745 
746     long			lUnoBoundaryType;
747 
748     switch(boundaryType)
749     {
750     case IA2_TEXT_BOUNDARY_CHAR:
751         lUnoBoundaryType = 1; // CHARACTER;
752         break;
753     case IA2_TEXT_BOUNDARY_WORD:
754         lUnoBoundaryType = 2; // WORD;
755         break;
756     case IA2_TEXT_BOUNDARY_SENTENCE:
757         lUnoBoundaryType = 3; // SENTENCE;
758         break;
759     case IA2_TEXT_BOUNDARY_LINE:
760         lUnoBoundaryType = 5; // LINE;
761         break;
762     case IA2_TEXT_BOUNDARY_PARAGRAPH:
763         lUnoBoundaryType = 4;
764         break;
765     case IA2_TEXT_BOUNDARY_ALL:
766         {
767             long nChar;
768             get_nCharacters( &nChar );
769             *startOffset = 0;
770             *endOffset = nChar;
771             return get_text(0, nChar, text);
772         }
773         break;
774     default:
775         return E_FAIL;
776     }
777 
778     TextSegment segment = GetXInterface()->getTextAtIndex( offset, sal_Int16(lUnoBoundaryType));
779     ::rtl::OUString ouStr = segment.SegmentText;
780     SysFreeString(*text);
781     *text = SysAllocString((OLECHAR*)ouStr.getStr());
782     *startOffset = segment.SegmentStart;
783     *endOffset = segment.SegmentEnd;
784 
785     return S_OK;
786 
787     LEAVE_PROTECTED_BLOCK
788 }
789 
790 /**
791    * Remove selection.
792    * @param selectionIndex Special selection index
793    * @param success Variant to accept the memthod called result.
794    * @return Result.
795 */
796 STDMETHODIMP CAccTextBase::removeSelection(long selectionIndex)
797 {
798 
799 	CHECK_ENABLE_INF
800 
801     ENTER_PROTECTED_BLOCK
802 
803     // #CHECK XInterface#
804     if(pUNOInterface == NULL)
805     {
806         return E_FAIL;
807     }
808 
809     Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
810 
811     Reference< XAccessibleTextSelection > pRExtension(pRContext,UNO_QUERY);
812 
813     if( pRExtension.is() )
814     {
815         pRExtension->removeSelection(selectionIndex);
816         return S_OK;
817     }
818 	else
819     {
820         GetXInterface()->setSelection(0, 0);
821         return S_OK;
822     }
823 
824     return E_FAIL;
825 
826     LEAVE_PROTECTED_BLOCK
827 }
828 
829 /**
830    * Set caret position.
831    * @param offset Special position.
832    * @param success Variant to accept the memthod called result.
833    * @return Result.
834 */
835 STDMETHODIMP CAccTextBase::setCaretOffset(long offset)
836 {
837 
838 	CHECK_ENABLE_INF
839 
840     ENTER_PROTECTED_BLOCK
841 
842     // #CHECK XInterface#
843     if(!pRXText.is())
844         return E_FAIL;
845 
846     GetXInterface()->setCaretPosition( offset);
847 
848     return S_OK;
849 
850     LEAVE_PROTECTED_BLOCK
851 }
852 
853 /**
854    * Set special selection.
855    * @param selectionIndex Special selection index.
856    * @param startOffset start position.
857    * @param endOffset end position.
858    * @param success Variant to accept the memthod called result.
859    * @return Result.
860 */
861 STDMETHODIMP CAccTextBase::setSelection(long, long startOffset, long endOffset)
862 {
863 
864 	CHECK_ENABLE_INF
865 
866     ENTER_PROTECTED_BLOCK
867 
868     // #CHECK XInterface#
869     if(!pRXText.is())
870     {
871         return E_FAIL;
872     }
873 
874     GetXInterface()->setSelection( startOffset,	endOffset );
875 
876     return S_OK;
877 
878     LEAVE_PROTECTED_BLOCK
879 }
880 
881 /**
882    * Get characters count.
883    * @param nCharacters Variant to accept the characters count.
884    * @return Result.
885 */
886 STDMETHODIMP CAccTextBase::get_nCharacters(long * nCharacters)
887 {
888 
889 	CHECK_ENABLE_INF
890 
891     ENTER_PROTECTED_BLOCK
892 
893     if (nCharacters == NULL)
894         return E_INVALIDARG;
895     // #CHECK XInterface#
896     if(!pRXText.is())
897     {
898         *nCharacters = 0;
899         return S_OK;
900     }
901 
902     *nCharacters = GetXInterface()->getCharacterCount();
903 
904     return S_OK;
905 
906     LEAVE_PROTECTED_BLOCK
907 }
908 
909 // added by qiuhd, 2006/07/03, for direver 07/11
910 STDMETHODIMP CAccTextBase::get_newText( IA2TextSegment *)
911 {
912     return E_NOTIMPL;
913 }
914 
915 STDMETHODIMP CAccTextBase::get_oldText( IA2TextSegment *)
916 {
917     return E_NOTIMPL;
918 }
919 
920 /**
921    * Scroll to special sub-string .
922    * @param startIndex Start index of sub string.
923    * @param endIndex   End index of sub string.
924    * @return Result.
925 */
926 STDMETHODIMP CAccTextBase::scrollSubstringToPoint(long, long, IA2CoordinateType, long, long )
927 {
928 
929 
930     ENTER_PROTECTED_BLOCK
931 
932     return E_NOTIMPL;
933 
934     LEAVE_PROTECTED_BLOCK
935 }
936 
937 STDMETHODIMP CAccTextBase::scrollSubstringTo(long, long, IA2ScrollType)
938 {
939 
940 
941     ENTER_PROTECTED_BLOCK
942 
943     return E_NOTIMPL;
944 
945     LEAVE_PROTECTED_BLOCK
946 }
947 
948 /**
949    * Put UNO interface.
950    * @param pXInterface UNO interface.
951    * @return Result.
952 */
953 STDMETHODIMP CAccTextBase::put_XInterface(long pXInterface)
954 {
955 
956 	CHECK_ENABLE_INF
957 
958     ENTER_PROTECTED_BLOCK
959 
960     CUNOXWrapper::put_XInterface(pXInterface);
961     //special query.
962     if(pUNOInterface == NULL)
963         return E_FAIL;
964     Reference<XAccessibleContext> pRContext = pUNOInterface->getAccessibleContext();
965     if( !pRContext.is() )
966     {
967         return E_FAIL;
968     }
969     Reference<XAccessibleText> pRXI(pRContext,UNO_QUERY);
970     if( !pRXI.is() )
971         pRXText = NULL;
972     else
973         pRXText = pRXI;
974     return S_OK;
975 
976     LEAVE_PROTECTED_BLOCK
977 }
978 
979 OUString ReplaceOneChar(OUString oldOUString, OUString replacedChar, OUString replaceStr)
980 {
981     int iReplace = -1;
982     iReplace = oldOUString.lastIndexOf(replacedChar);
983     if (iReplace > -1)
984     {
985         for(;iReplace>-1;)
986         {
987             oldOUString = oldOUString.replaceAt(iReplace,1, replaceStr);
988             iReplace=oldOUString.lastIndexOf(replacedChar,iReplace);
989         }
990     }
991     return oldOUString;
992 
993 }
994 OUString ReplaceFourChar(OUString oldOUString)
995 {
996     oldOUString = ReplaceOneChar(oldOUString,OUString::createFromAscii("\\"),OUString::createFromAscii("\\\\"));
997     oldOUString = ReplaceOneChar(oldOUString,OUString::createFromAscii(";"),OUString::createFromAscii("\\;"));
998     oldOUString = ReplaceOneChar(oldOUString,OUString::createFromAscii("="),OUString::createFromAscii("\\="));
999     oldOUString = ReplaceOneChar(oldOUString,OUString::createFromAscii(","),OUString::createFromAscii("\\,"));
1000     oldOUString = ReplaceOneChar(oldOUString,OUString::createFromAscii(":"),OUString::createFromAscii("\\:"));
1001     return oldOUString;
1002 }
1003