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