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 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_editeng.hxx"
26 
27 //------------------------------------------------------------------------
28 //
29 // Global header
30 //
31 //------------------------------------------------------------------------
32 
33 #include <limits.h>
34 #include <vector>
35 #include <algorithm>
36 #include <vos/mutex.hxx>
37 #include <vcl/window.hxx>
38 #include <vcl/svapp.hxx>
39 #include <editeng/flditem.hxx>
40 #include <com/sun/star/uno/Any.hxx>
41 #include <com/sun/star/uno/Reference.hxx>
42 #include <com/sun/star/awt/Point.hpp>
43 #include <com/sun/star/awt/Rectangle.hpp>
44 #include <com/sun/star/lang/DisposedException.hpp>
45 #include <com/sun/star/accessibility/AccessibleRole.hpp>
46 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
47 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
48 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
49 #include <comphelper/accessibleeventnotifier.hxx>
50 #include <comphelper/sequenceashashmap.hxx>
51 #include <unotools/accessiblestatesethelper.hxx>
52 #include <unotools/accessiblerelationsethelper.hxx>
53 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
54 #include <vcl/unohelp.hxx>
55 #include <editeng/editeng.hxx>
56 #include <editeng/unoprnms.hxx>
57 #include <editeng/unoipset.hxx>
58 #include <editeng/outliner.hxx>
59 #include <svl/intitem.hxx>
60 
61 //------------------------------------------------------------------------
62 //
63 // Project-local header
64 //
65 //------------------------------------------------------------------------
66 
67 #include <com/sun/star/beans/PropertyState.hpp>
68 
69 //!!!#include <svx/unoshape.hxx>
70 //!!!#include <svx/dialmgr.hxx>
71 //!!!#include "accessibility.hrc"
72 
73 #include <editeng/unolingu.hxx>
74 #include <editeng/unopracc.hxx>
75 #include "editeng/AccessibleEditableTextPara.hxx"
76 #include "AccessibleHyperlink.hxx"
77 
78 #include <svtools/colorcfg.hxx>
79 #include <algorithm>
80 using namespace std;
81 #include "editeng.hrc"
82 #include <editeng/eerdll.hxx>
83 #include <editeng/numitem.hxx>
84 
85 using namespace ::com::sun::star;
86 using namespace ::com::sun::star::beans;
87 using namespace ::com::sun::star::accessibility;
88 
89 
90 //------------------------------------------------------------------------
91 //
92 // AccessibleEditableTextPara implementation
93 //
94 //------------------------------------------------------------------------
95 
96 namespace accessibility
97 {
98 
ImplGetSvxCharAndParaPropertiesSet()99     const SvxItemPropertySet* ImplGetSvxCharAndParaPropertiesSet()
100     {
101         // PropertyMap for character and paragraph properties
102         static const SfxItemPropertyMapEntry aPropMap[] =
103         {
104 			SVX_UNOEDIT_OUTLINER_PROPERTIES,
105             SVX_UNOEDIT_CHAR_PROPERTIES,
106             SVX_UNOEDIT_PARA_PROPERTIES,
107             SVX_UNOEDIT_NUMBERING_PROPERTIE,
108             {MAP_CHAR_LEN("TextUserDefinedAttributes"),     EE_CHAR_XMLATTRIBS,     &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0)  ,        0,     0},
109             {MAP_CHAR_LEN("ParaUserDefinedAttributes"),     EE_PARA_XMLATTRIBS,     &::getCppuType((const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameContainer >*)0)  ,        0,     0},
110             {0,0,0,0,0,0}
111         };
112         static SvxItemPropertySet aPropSet( aPropMap, EditEngine::GetGlobalItemPool() );
113         return &aPropSet;
114     }
115 
116 
DBG_NAME(AccessibleEditableTextPara)117     DBG_NAME( AccessibleEditableTextPara )
118 
119     // --> OD 2006-01-11 #i27138# - add parameter <_pParaManager>
120     AccessibleEditableTextPara::AccessibleEditableTextPara(
121                                 const uno::Reference< XAccessible >& rParent,
122                                 const AccessibleParaManager* _pParaManager )
123         : AccessibleTextParaInterfaceBase( m_aMutex ),
124           mnParagraphIndex( 0 ),
125           mnIndexInParent( 0 ),
126           mpEditSource( NULL ),
127           maEEOffset( 0, 0 ),
128           mxParent( rParent ),
129           // well, that's strictly (UNO) exception safe, though not
130           // really robust. We rely on the fact that this member is
131           // constructed last, and that the constructor body catches
132           // exceptions, thus no chance for exceptions once the Id is
133           // fetched. Nevertheless, normally should employ RAII here...
134           mnNotifierClientId(::comphelper::AccessibleEventNotifier::registerClient()),
135           // --> OD 2006-01-11 #i27138#
136           mpParaManager( _pParaManager )
137           // <--
138     {
139 #ifdef DBG_UTIL
140         DBG_CTOR( AccessibleEditableTextPara, NULL );
141         OSL_TRACE( "AccessibleEditableTextPara received ID: %d\n", mnNotifierClientId );
142 #endif
143 
144 		try
145         {
146             // Create the state set.
147             ::utl::AccessibleStateSetHelper* pStateSet  = new ::utl::AccessibleStateSetHelper ();
148             mxStateSet = pStateSet;
149 
150             // these are always on
151             pStateSet->AddState( AccessibleStateType::MULTI_LINE );
152             pStateSet->AddState( AccessibleStateType::FOCUSABLE );
153             pStateSet->AddState( AccessibleStateType::VISIBLE );
154             pStateSet->AddState( AccessibleStateType::SHOWING );
155             pStateSet->AddState( AccessibleStateType::ENABLED );
156             pStateSet->AddState( AccessibleStateType::SENSITIVE );
157         }
158         catch( const uno::Exception& ) {}
159     }
160 
~AccessibleEditableTextPara()161     AccessibleEditableTextPara::~AccessibleEditableTextPara()
162     {
163         DBG_DTOR( AccessibleEditableTextPara, NULL );
164 
165         // sign off from event notifier
166         if( getNotifierClientId() != -1 )
167         {
168             try
169             {
170                 ::comphelper::AccessibleEventNotifier::revokeClient( getNotifierClientId() );
171 #ifdef DBG_UTIL
172                 OSL_TRACE( "AccessibleEditableTextPara revoked ID: %d\n", mnNotifierClientId );
173 #endif
174             }
175             catch( const uno::Exception& ) {}
176         }
177     }
178 
implGetText()179     ::rtl::OUString AccessibleEditableTextPara::implGetText()
180     {
181         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
182 
183         return GetTextRange( 0, GetTextLen() );
184     }
185 
implGetLocale()186     ::com::sun::star::lang::Locale AccessibleEditableTextPara::implGetLocale()
187     {
188         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
189 
190         lang::Locale		aLocale;
191 
192         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
193                    "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
194 
195         // return locale of first character in the paragraph
196         return SvxLanguageToLocale(aLocale, GetTextForwarder().GetLanguage( GetParagraphIndex(), 0 ));
197     }
198 
implGetSelection(sal_Int32 & nStartIndex,sal_Int32 & nEndIndex)199     void AccessibleEditableTextPara::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
200     {
201         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
202 
203         sal_uInt16 nStart, nEnd;
204 
205         if( GetSelection( nStart, nEnd ) )
206         {
207             nStartIndex = nStart;
208             nEndIndex = nEnd;
209         }
210         else
211         {
212             // #102234# No exception, just set to 'invalid'
213             nStartIndex = -1;
214             nEndIndex = -1;
215         }
216     }
217 
implGetParagraphBoundary(::com::sun::star::i18n::Boundary & rBoundary,sal_Int32)218     void AccessibleEditableTextPara::implGetParagraphBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 /*nIndex*/ )
219     {
220         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
221         DBG_WARNING( "AccessibleEditableTextPara::implGetParagraphBoundary: only a base implementation, ignoring the index" );
222 
223         rBoundary.startPos = 0;
224         //rBoundary.endPos = GetTextLen();
225         ::rtl::OUString sText( implGetText() );
226         sal_Int32 nLength = sText.getLength();
227         rBoundary.endPos = nLength;
228     }
229 
implGetLineBoundary(::com::sun::star::i18n::Boundary & rBoundary,sal_Int32 nIndex)230     void AccessibleEditableTextPara::implGetLineBoundary( ::com::sun::star::i18n::Boundary& rBoundary, sal_Int32 nIndex )
231     {
232         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
233 
234         SvxTextForwarder&	rCacheTF = GetTextForwarder();
235         const sal_Int32		nParaIndex = GetParagraphIndex();
236 
237         DBG_ASSERT(nParaIndex >= 0 && nParaIndex <= USHRT_MAX,
238                    "AccessibleEditableTextPara::implGetLineBoundary: paragraph index value overflow");
239 
240         const sal_Int32 nTextLen = rCacheTF.GetTextLen( nParaIndex );
241 
242         CheckPosition(nIndex);
243 
244         rBoundary.startPos = rBoundary.endPos = -1;
245 
246         const sal_uInt16 nLineCount=rCacheTF.GetLineCount( nParaIndex );
247 
248         if( nIndex == nTextLen )
249         {
250             // #i17014# Special-casing one-behind-the-end character
251             if( nLineCount <= 1 )
252                 rBoundary.startPos = 0;
253             else
254                 rBoundary.startPos = nTextLen - rCacheTF.GetLineLen( nParaIndex,
255                                                                      nLineCount-1 );
256 
257             rBoundary.endPos = nTextLen;
258         }
259         else
260         {
261             // normal line search
262             sal_uInt16 nLine;
263             sal_Int32 nCurIndex;
264             for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
265             {
266                 nCurIndex += rCacheTF.GetLineLen(nParaIndex, nLine);
267 
268                 if( nCurIndex > nIndex )
269                 {
270                     rBoundary.startPos = nCurIndex - rCacheTF.GetLineLen(nParaIndex, nLine);
271                     rBoundary.endPos = nCurIndex;
272                     break;
273                 }
274             }
275         }
276     }
277 
getNotifierClientId() const278     int AccessibleEditableTextPara::getNotifierClientId() const
279     {
280         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
281 
282         return mnNotifierClientId;
283     }
284 
SetIndexInParent(sal_Int32 nIndex)285     void AccessibleEditableTextPara::SetIndexInParent( sal_Int32 nIndex )
286     {
287         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
288 
289         mnIndexInParent = nIndex;
290     }
291 
GetIndexInParent() const292     sal_Int32 AccessibleEditableTextPara::GetIndexInParent() const
293     {
294         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
295 
296         return mnIndexInParent;
297     }
298 
SetParagraphIndex(sal_Int32 nIndex)299     void AccessibleEditableTextPara::SetParagraphIndex( sal_Int32 nIndex )
300     {
301         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
302 
303         sal_Int32 nOldIndex = mnParagraphIndex;
304 
305         mnParagraphIndex = nIndex;
306 
307         WeakBullet::HardRefType aChild( maImageBullet.get() );
308         if( aChild.is() )
309             aChild->SetParagraphIndex(mnParagraphIndex);
310 
311         try
312         {
313             if( nOldIndex != nIndex )
314             {
315 				uno::Any aOldDesc;
316 				uno::Any aOldName;
317 
318 				try
319 				{
320 					aOldDesc <<= getAccessibleDescription();
321 					aOldName <<= getAccessibleName();
322 				}
323 				catch( const uno::Exception& ) {} // optional behaviour
324                 // index and therefore description changed
325                 FireEvent( AccessibleEventId::DESCRIPTION_CHANGED, uno::makeAny( getAccessibleDescription() ), aOldDesc );
326                 FireEvent( AccessibleEventId::NAME_CHANGED, uno::makeAny( getAccessibleName() ), aOldName );
327             }
328         }
329         catch( const uno::Exception& ) {} // optional behaviour
330     }
331 
GetParagraphIndex() const332     sal_Int32 AccessibleEditableTextPara::GetParagraphIndex() const SAL_THROW((uno::RuntimeException))
333     {
334         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
335 
336         return mnParagraphIndex;
337     }
338 
Dispose()339     void AccessibleEditableTextPara::Dispose()
340     {
341         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
342 
343         int nClientId( getNotifierClientId() );
344 
345         // #108212# drop all references before notifying dispose
346         mxParent = NULL;
347         mnNotifierClientId = -1;
348         mpEditSource = NULL;
349 
350         // notify listeners
351         if( nClientId != -1 )
352         {
353             try
354             {
355                 uno::Reference < XAccessibleContext > xThis = getAccessibleContext();
356 
357                 // #106234# Delegate to EventNotifier
358                 ::comphelper::AccessibleEventNotifier::revokeClientNotifyDisposing( nClientId, xThis );
359 #ifdef DBG_UTIL
360                 OSL_TRACE( "Disposed ID: %d\n", nClientId );
361 #endif
362             }
363             catch( const uno::Exception& ) {}
364         }
365     }
366 
SetEditSource(SvxEditSourceAdapter * pEditSource)367     void AccessibleEditableTextPara::SetEditSource( SvxEditSourceAdapter* pEditSource )
368     {
369         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
370 
371         WeakBullet::HardRefType aChild( maImageBullet.get() );
372         if( aChild.is() )
373             aChild->SetEditSource(pEditSource);
374 
375         if( !pEditSource )
376         {
377             // going defunc
378             UnSetState( AccessibleStateType::SHOWING );
379             UnSetState( AccessibleStateType::VISIBLE );
380             SetState( AccessibleStateType::INVALID );
381             SetState( AccessibleStateType::DEFUNC );
382 
383             Dispose();
384         }
385 		mpEditSource = pEditSource;
386         // #108900# Init last text content
387         try
388         {
389             TextChanged();
390         }
391         catch( const uno::RuntimeException& ) {}
392     }
393 
MakeSelection(sal_Int32 nStartEEIndex,sal_Int32 nEndEEIndex)394     ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nStartEEIndex, sal_Int32 nEndEEIndex )
395     {
396         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
397 
398         // check overflow
399         DBG_ASSERT(nStartEEIndex >= 0 && nStartEEIndex <= USHRT_MAX &&
400                    nEndEEIndex >= 0 && nEndEEIndex <= USHRT_MAX &&
401                    GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
402                    "AccessibleEditableTextPara::MakeSelection: index value overflow");
403 
404 		sal_uInt32 nParaIndex = GetParagraphIndex();
405         return ESelection( nParaIndex, static_cast< sal_uInt16 >( nStartEEIndex ),
406                            nParaIndex, static_cast< sal_uInt16 >( nEndEEIndex ) );
407     }
408 
MakeSelection(sal_Int32 nEEIndex)409     ESelection AccessibleEditableTextPara::MakeSelection( sal_Int32 nEEIndex )
410     {
411         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
412 
413         return MakeSelection( nEEIndex, nEEIndex+1 );
414     }
415 
MakeCursor(sal_Int32 nEEIndex)416     ESelection AccessibleEditableTextPara::MakeCursor( sal_Int32 nEEIndex )
417     {
418         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
419 
420         return MakeSelection( nEEIndex, nEEIndex );
421     }
422 
CheckIndex(sal_Int32 nIndex)423     void AccessibleEditableTextPara::CheckIndex( sal_Int32 nIndex ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
424     {
425         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
426 
427         if( nIndex < 0 || nIndex >= getCharacterCount() )
428             throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleEditableTextPara: character index out of bounds")),
429                                                   uno::Reference< uno::XInterface >
430                                                   ( static_cast< ::cppu::OWeakObject* > (this) ) );	// disambiguate hierarchy
431     }
432 
CheckPosition(sal_Int32 nIndex)433     void AccessibleEditableTextPara::CheckPosition( sal_Int32 nIndex ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
434     {
435         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
436 
437         if( nIndex < 0 || nIndex > getCharacterCount() )
438             throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleEditableTextPara: character position out of bounds")),
439                                                   uno::Reference< uno::XInterface >
440                                                   ( static_cast< ::cppu::OWeakObject* > (this) ) );	// disambiguate hierarchy
441     }
442 
CheckRange(sal_Int32 nStart,sal_Int32 nEnd)443     void AccessibleEditableTextPara::CheckRange( sal_Int32 nStart, sal_Int32 nEnd ) SAL_THROW((lang::IndexOutOfBoundsException, uno::RuntimeException))
444     {
445         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
446 
447         CheckPosition( nStart );
448         CheckPosition( nEnd );
449     }
450 
GetSelection(sal_uInt16 & nStartPos,sal_uInt16 & nEndPos)451     sal_Bool AccessibleEditableTextPara::GetSelection( sal_uInt16& nStartPos, sal_uInt16& nEndPos ) SAL_THROW((uno::RuntimeException))
452     {
453         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
454 
455         ESelection aSelection;
456         sal_uInt32 nPara = GetParagraphIndex();
457         if( !GetEditViewForwarder().GetSelection( aSelection ) )
458             return sal_False;
459 
460         if( aSelection.nStartPara < aSelection.nEndPara )
461         {
462             if( aSelection.nStartPara > nPara ||
463                 aSelection.nEndPara < nPara )
464                 return sal_False;
465 
466             if( nPara == aSelection.nStartPara )
467                 nStartPos = aSelection.nStartPos;
468             else
469                 nStartPos = 0;
470 
471             if( nPara == aSelection.nEndPara )
472                 nEndPos = aSelection.nEndPos;
473             else
474                 nEndPos = GetTextLen();
475         }
476         else
477         {
478             if( aSelection.nStartPara < nPara ||
479                 aSelection.nEndPara > nPara )
480                 return sal_False;
481 
482             if( nPara == aSelection.nStartPara )
483                 nStartPos = aSelection.nStartPos;
484             else
485                 nStartPos = GetTextLen();
486 
487             if( nPara == aSelection.nEndPara )
488                 nEndPos = aSelection.nEndPos;
489             else
490                 nEndPos = 0;
491         }
492 
493         return sal_True;
494     }
495 
GetText(sal_Int32 nIndex)496     String AccessibleEditableTextPara::GetText( sal_Int32 nIndex ) SAL_THROW((uno::RuntimeException))
497     {
498         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
499 
500         return GetTextForwarder().GetText( MakeSelection(nIndex) );
501     }
502 
GetTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)503     String AccessibleEditableTextPara::GetTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) SAL_THROW((uno::RuntimeException))
504     {
505         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
506 
507         return GetTextForwarder().GetText( MakeSelection(nStartIndex, nEndIndex) );
508     }
509 
GetTextLen() const510     sal_uInt16 AccessibleEditableTextPara::GetTextLen() const SAL_THROW((uno::RuntimeException))
511     {
512         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
513 
514         return GetTextForwarder().GetTextLen( GetParagraphIndex() );
515     }
516 
IsVisible() const517     sal_Bool AccessibleEditableTextPara::IsVisible() const
518     {
519         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
520 
521         return mpEditSource ? sal_True : sal_False ;
522     }
523 
GetParaInterface(sal_Int32 nIndex)524     uno::Reference< XAccessibleText > AccessibleEditableTextPara::GetParaInterface( sal_Int32 nIndex )
525     {
526         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
527 
528         uno::Reference< XAccessible > xParent = getAccessibleParent();
529         if( xParent.is() )
530         {
531             uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext();
532             if( xParentContext.is() )
533             {
534                 uno::Reference< XAccessible > xPara = xParentContext->getAccessibleChild( nIndex );
535                 if( xPara.is() )
536                 {
537                     return uno::Reference< XAccessibleText > ( xPara, uno::UNO_QUERY );
538                 }
539             }
540         }
541 
542         return uno::Reference< XAccessibleText >();
543     }
544 
GetEditSource() const545     SvxEditSourceAdapter& AccessibleEditableTextPara::GetEditSource() const SAL_THROW((uno::RuntimeException))
546     {
547         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
548 
549         if( mpEditSource )
550             return *mpEditSource;
551         else
552             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No edit source, object is defunct")),
553                                         uno::Reference< uno::XInterface >
554                                         ( static_cast< ::cppu::OWeakObject* >
555                                           ( const_cast< AccessibleEditableTextPara* > (this) ) ) );	// disambiguate hierarchy
556     }
557 
GetTextForwarder() const558     SvxAccessibleTextAdapter& AccessibleEditableTextPara::GetTextForwarder() const SAL_THROW((uno::RuntimeException))
559     {
560         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
561 
562         SvxEditSourceAdapter& rEditSource = GetEditSource();
563         SvxAccessibleTextAdapter* pTextForwarder = rEditSource.GetTextForwarderAdapter();
564 
565         if( !pTextForwarder )
566             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch text forwarder, object is defunct")),
567                                         uno::Reference< uno::XInterface >
568                                         ( static_cast< ::cppu::OWeakObject* >
569                                           ( const_cast< AccessibleEditableTextPara* > (this) ) ) );	// disambiguate hierarchy
570 
571         if( pTextForwarder->IsValid() )
572             return *pTextForwarder;
573         else
574             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Text forwarder is invalid, object is defunct")),
575                                         uno::Reference< uno::XInterface >
576                                         ( static_cast< ::cppu::OWeakObject* >
577                                           ( const_cast< AccessibleEditableTextPara* > (this) ) ) );	// disambiguate hierarchy
578     }
579 
GetViewForwarder() const580     SvxViewForwarder& AccessibleEditableTextPara::GetViewForwarder() const SAL_THROW((uno::RuntimeException))
581     {
582         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
583 
584         SvxEditSource& rEditSource = GetEditSource();
585         SvxViewForwarder* pViewForwarder = rEditSource.GetViewForwarder();
586 
587         if( !pViewForwarder )
588         {
589             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, object is defunct")),
590                                         uno::Reference< uno::XInterface >
591                                         ( static_cast< ::cppu::OWeakObject* >
592                                           ( const_cast< AccessibleEditableTextPara* > (this) ) ) );	// disambiguate hierarchy
593         }
594 
595         if( pViewForwarder->IsValid() )
596             return *pViewForwarder;
597         else
598             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object is defunct")),
599                                         uno::Reference< uno::XInterface >
600                                         ( static_cast< ::cppu::OWeakObject* >
601                                           ( const_cast< AccessibleEditableTextPara* > (this) )  ) );	// disambiguate hierarchy
602     }
603 
GetEditViewForwarder(sal_Bool bCreate) const604     SvxAccessibleTextEditViewAdapter& AccessibleEditableTextPara::GetEditViewForwarder( sal_Bool bCreate ) const SAL_THROW((uno::RuntimeException))
605     {
606         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
607 
608         SvxEditSourceAdapter& rEditSource = GetEditSource();
609         SvxAccessibleTextEditViewAdapter* pTextEditViewForwarder = rEditSource.GetEditViewForwarderAdapter( bCreate );
610 
611         if( !pTextEditViewForwarder )
612         {
613             if( bCreate )
614                 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Unable to fetch view forwarder, object is defunct")),
615                                             uno::Reference< uno::XInterface >
616                                             ( static_cast< ::cppu::OWeakObject* >
617                                               ( const_cast< AccessibleEditableTextPara* > (this) ) ) );	// disambiguate hierarchy
618             else
619                 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No view forwarder, object not in edit mode")),
620                                             uno::Reference< uno::XInterface >
621                                             ( static_cast< ::cppu::OWeakObject* >
622                                               ( const_cast< AccessibleEditableTextPara* > (this) ) ) );	// disambiguate hierarchy
623         }
624 
625         if( pTextEditViewForwarder->IsValid() )
626             return *pTextEditViewForwarder;
627         else
628         {
629             if( bCreate )
630                 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object is defunct")),
631                                             uno::Reference< uno::XInterface >
632                                             ( static_cast< ::cppu::OWeakObject* >
633                                               ( const_cast< AccessibleEditableTextPara* > (this) )  ) );	// disambiguate hierarchy
634             else
635                 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("View forwarder is invalid, object not in edit mode")),
636                                             uno::Reference< uno::XInterface >
637                                             ( static_cast< ::cppu::OWeakObject* >
638                                               ( const_cast< AccessibleEditableTextPara* > (this) )  ) );	// disambiguate hierarchy
639         }
640     }
641 
HaveEditView() const642     sal_Bool AccessibleEditableTextPara::HaveEditView() const
643     {
644         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
645 
646         SvxEditSource& rEditSource = GetEditSource();
647         SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder();
648 
649         if( !pViewForwarder )
650             return sal_False;
651 
652         if( !pViewForwarder->IsValid() )
653             return sal_False;
654 
655         return sal_True;
656     }
657 
HaveChildren()658     sal_Bool AccessibleEditableTextPara::HaveChildren()
659     {
660         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
661 
662         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
663                    "AccessibleEditableTextPara::HaveChildren: paragraph index value overflow");
664 
665         return GetTextForwarder().HaveImageBullet( GetParagraphIndex() );
666     }
667 
IsActive() const668     sal_Bool AccessibleEditableTextPara::IsActive() const SAL_THROW((uno::RuntimeException))
669     {
670         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
671 
672         SvxEditSource& rEditSource = GetEditSource();
673         SvxEditViewForwarder* pViewForwarder = rEditSource.GetEditViewForwarder();
674 
675         if( !pViewForwarder )
676             return sal_False;
677 
678         if( pViewForwarder->IsValid() )
679             return sal_False;
680         else
681             return sal_True;
682     }
683 
LogicToPixel(const Rectangle & rRect,const MapMode & rMapMode,SvxViewForwarder & rForwarder)684     Rectangle AccessibleEditableTextPara::LogicToPixel( const Rectangle& rRect, const MapMode& rMapMode, SvxViewForwarder& rForwarder )
685     {
686         // convert to screen coordinates
687         return Rectangle( rForwarder.LogicToPixel( rRect.TopLeft(), rMapMode ),
688                           rForwarder.LogicToPixel( rRect.BottomRight(), rMapMode ) );
689     }
690 
GetEEOffset() const691     const Point& AccessibleEditableTextPara::GetEEOffset() const
692     {
693         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
694 
695         return maEEOffset;
696     }
697 
SetEEOffset(const Point & rOffset)698     void AccessibleEditableTextPara::SetEEOffset( const Point& rOffset )
699     {
700         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
701 
702         WeakBullet::HardRefType aChild( maImageBullet.get() );
703         if( aChild.is() )
704             aChild->SetEEOffset(rOffset);
705 
706         maEEOffset = rOffset;
707     }
708 
FireEvent(const sal_Int16 nEventId,const uno::Any & rNewValue,const uno::Any & rOldValue) const709     void AccessibleEditableTextPara::FireEvent(const sal_Int16 nEventId, const uno::Any& rNewValue, const uno::Any& rOldValue) const
710     {
711         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
712 
713         uno::Reference < XAccessibleContext > xThis( const_cast< AccessibleEditableTextPara* > (this)->getAccessibleContext() );
714 
715         AccessibleEventObject aEvent(xThis, nEventId, rNewValue, rOldValue);
716 
717         // #102261# Call global queue for focus events
718         if( nEventId == AccessibleEventId::STATE_CHANGED )
719             vcl::unohelper::NotifyAccessibleStateEventGlobally( aEvent );
720 
721         // #106234# Delegate to EventNotifier
722         if( getNotifierClientId() != -1 )
723             ::comphelper::AccessibleEventNotifier::addEvent( getNotifierClientId(),
724                                                              aEvent );
725     }
726 
GotPropertyEvent(const uno::Any & rNewValue,const sal_Int16 nEventId) const727     void AccessibleEditableTextPara::GotPropertyEvent( const uno::Any& rNewValue, const sal_Int16 nEventId ) const
728     {
729         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
730 
731         FireEvent( nEventId, rNewValue );
732     }
733 
LostPropertyEvent(const uno::Any & rOldValue,const sal_Int16 nEventId) const734     void AccessibleEditableTextPara::LostPropertyEvent( const uno::Any& rOldValue, const sal_Int16 nEventId ) const
735     {
736         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
737 
738         FireEvent( nEventId, uno::Any(), rOldValue );
739     }
740 
HasState(const sal_Int16 nStateId)741     bool AccessibleEditableTextPara::HasState( const sal_Int16 nStateId )
742     {
743         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
744 
745         ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
746         if( pStateSet != NULL )
747             return pStateSet->contains(nStateId) ? true : false;
748 
749         return false;
750     }
751 
SetState(const sal_Int16 nStateId)752     void AccessibleEditableTextPara::SetState( const sal_Int16 nStateId )
753     {
754         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
755 
756         ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
757         if( pStateSet != NULL &&
758             !pStateSet->contains(nStateId) )
759         {
760             pStateSet->AddState( nStateId );
761 		// MT: Removed method IsShapeParaFocusable which was introduced with IA2 - basically it was only about figuring out whether or not the window has the focus, should be solved differently
762 		// if(IsShapeParaFocusable())
763             GotPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED );
764         }
765     }
766 
UnSetState(const sal_Int16 nStateId)767     void AccessibleEditableTextPara::UnSetState( const sal_Int16 nStateId )
768     {
769         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
770 
771         ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
772         if( pStateSet != NULL &&
773             pStateSet->contains(nStateId) )
774         {
775             pStateSet->RemoveState( nStateId );
776             LostPropertyEvent( uno::makeAny( nStateId ), AccessibleEventId::STATE_CHANGED );
777         }
778     }
779 
TextChanged()780     void AccessibleEditableTextPara::TextChanged()
781     {
782         ::rtl::OUString aCurrentString( OCommonAccessibleText::getText() );
783         uno::Any aDeleted;
784         uno::Any aInserted;
785         if( OCommonAccessibleText::implInitTextChangedEvent( maLastTextString, aCurrentString,
786                                                              aDeleted, aInserted) )
787         {
788             FireEvent( AccessibleEventId::TEXT_CHANGED, aInserted, aDeleted );
789             maLastTextString = aCurrentString;
790         }
791     }
792 
GetAttributeRun(sal_uInt16 & nStartIndex,sal_uInt16 & nEndIndex,sal_Int32 nIndex)793     sal_Bool AccessibleEditableTextPara::GetAttributeRun( sal_uInt16& nStartIndex, sal_uInt16& nEndIndex, sal_Int32 nIndex )
794     {
795         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
796 
797         DBG_ASSERT(nIndex >= 0 && nIndex <= USHRT_MAX,
798                    "AccessibleEditableTextPara::GetAttributeRun: index value overflow");
799 
800         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= EE_PARA_MAX,
801                    "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
802 
803         return GetTextForwarder().GetAttributeRun( nStartIndex,
804                                                    nEndIndex,
805                                                    GetParagraphIndex(),
806                                                    static_cast< sal_uInt16 >(nIndex) );
807     }
808 
queryInterface(const uno::Type & rType)809     uno::Any SAL_CALL AccessibleEditableTextPara::queryInterface (const uno::Type & rType) throw (uno::RuntimeException)
810     {
811         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
812 
813         uno::Any aRet;
814 
815         // must provide XAccesibleText by hand, since it comes publicly inherited by XAccessibleEditableText
816         if ( rType == ::getCppuType((uno::Reference< XAccessibleText > *)0) )
817         {
818             uno::Reference< XAccessibleText > aAccText = static_cast< XAccessibleEditableText * >(this);
819             aRet <<= aAccText;
820         }
821         else if ( rType == ::getCppuType((uno::Reference< XAccessibleEditableText > *)0) )
822         {
823             uno::Reference< XAccessibleEditableText > aAccEditText = this;
824             aRet <<= aAccEditText;
825         }
826 	else if ( rType == ::getCppuType((uno::Reference< XAccessibleHypertext > *)0) )
827         {
828             uno::Reference< XAccessibleHypertext > aAccHyperText = this;
829             aRet <<= aAccHyperText;
830         }
831         else
832         {
833             aRet = AccessibleTextParaInterfaceBase::queryInterface(rType);
834         }
835 
836         return aRet;
837     }
838 
839 	// XAccessible
getAccessibleContext()840     uno::Reference< XAccessibleContext > SAL_CALL AccessibleEditableTextPara::getAccessibleContext() throw (uno::RuntimeException)
841     {
842         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
843 
844         // We implement the XAccessibleContext interface in the same object
845         return uno::Reference< XAccessibleContext > ( this );
846     }
847 
848 	// XAccessibleContext
getAccessibleChildCount()849     sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleChildCount() throw (uno::RuntimeException)
850     {
851         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
852 
853         ::vos::OGuard aGuard( Application::GetSolarMutex() );
854 
855         return HaveChildren() ? 1 : 0;
856     }
857 
getAccessibleChild(sal_Int32 i)858     uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleChild( sal_Int32 i ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
859     {
860         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
861 
862         ::vos::OGuard aGuard( Application::GetSolarMutex() );
863 
864         if( !HaveChildren() )
865             throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("No childs available")),
866                                                   uno::Reference< uno::XInterface >
867                                                   ( static_cast< ::cppu::OWeakObject* > (this) ) );	// static_cast: disambiguate hierarchy
868 
869         if( i != 0 )
870             throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Invalid child index")),
871                                                   uno::Reference< uno::XInterface >
872                                                   ( static_cast< ::cppu::OWeakObject* > (this) ) );	// static_cast: disambiguate hierarchy
873 
874         WeakBullet::HardRefType aChild( maImageBullet.get() );
875 
876         if( !aChild.is() )
877         {
878             // there is no hard reference available, create object then
879             AccessibleImageBullet* pChild = new AccessibleImageBullet( uno::Reference< XAccessible >( this ) );
880             uno::Reference< XAccessible > xChild( static_cast< ::cppu::OWeakObject* > (pChild), uno::UNO_QUERY );
881 
882             if( !xChild.is() )
883                 throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Child creation failed")),
884                                             uno::Reference< uno::XInterface >
885                                             ( static_cast< ::cppu::OWeakObject* > (this) ) );
886 
887             aChild = WeakBullet::HardRefType( xChild, pChild );
888 
889             aChild->SetEditSource( &GetEditSource() );
890             aChild->SetParagraphIndex( GetParagraphIndex() );
891             aChild->SetIndexInParent( i );
892 
893             maImageBullet = aChild;
894         }
895 
896         return aChild.getRef();
897     }
898 
getAccessibleParent()899     uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleParent() throw (uno::RuntimeException)
900     {
901         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
902 
903 #ifdef DBG_UTIL
904         if( !mxParent.is() )
905             DBG_TRACE( "AccessibleEditableTextPara::getAccessibleParent: no frontend set, did somebody forgot to call AccessibleTextHelper::SetEventSource()?");
906 #endif
907 
908         return mxParent;
909     }
910 
getAccessibleIndexInParent()911     sal_Int32 SAL_CALL AccessibleEditableTextPara::getAccessibleIndexInParent() throw (uno::RuntimeException)
912     {
913         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
914 
915         return mnIndexInParent;
916     }
917 
getAccessibleRole()918     sal_Int16 SAL_CALL AccessibleEditableTextPara::getAccessibleRole() throw (uno::RuntimeException)
919     {
920         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
921 
922         return AccessibleRole::PARAGRAPH;
923     }
924 
getAccessibleDescription()925     ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleDescription() throw (uno::RuntimeException)
926     {
927         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
928         ::vos::OGuard aGuard( Application::GetSolarMutex() );
929 
930         // append first 40 characters from text, or first line, if shorter
931         // (writer takes first sentence here, but that's not supported
932         // from EditEngine)
933         // throws if defunc
934         ::rtl::OUString aLine;
935 
936         if( getCharacterCount() )
937             aLine = getTextAtIndex(0, AccessibleTextType::LINE).SegmentText;
938 
939         // Get the string from the resource for the specified id.
940         String sStr = ::rtl::OUString( String( EditResId (RID_SVXSTR_A11Y_PARAGRAPH_DESCRIPTION ) ) );
941         String sParaIndex = ::rtl::OUString::valueOf( GetParagraphIndex() );
942 		sStr.SearchAndReplace( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "$(ARG)" )),
943                                sParaIndex );
944 
945         if( aLine.getLength() > MaxDescriptionLen )
946         {
947             ::rtl::OUString aCurrWord;
948             sal_Int32 i;
949 
950             // search backward from MaxDescriptionLen for previous word start
951             for( aCurrWord=getTextAtIndex(MaxDescriptionLen, AccessibleTextType::WORD).SegmentText,
952                      i=MaxDescriptionLen,
953                      aLine=::rtl::OUString();
954                  i>=0;
955                  --i )
956             {
957                 if( getTextAtIndex(i, AccessibleTextType::WORD).SegmentText != aCurrWord )
958                 {
959                     if( i == 0 )
960                         // prevent completely empty string
961                         aLine = getTextAtIndex(0, AccessibleTextType::WORD).SegmentText;
962                     else
963                         aLine = getTextRange(0, i);
964                 }
965             }
966         }
967 
968         return ::rtl::OUString( sStr ) + aLine;
969     }
970 
getAccessibleName()971     ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getAccessibleName() throw (uno::RuntimeException)
972     {
973         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
974 
975         ::vos::OGuard aGuard( Application::GetSolarMutex() );
976 
977         // throws if defunc
978         sal_Int32 nPara( GetParagraphIndex() );
979 
980         // Get the string from the resource for the specified id.
981         String sStr = ::rtl::OUString( String( EditResId (RID_SVXSTR_A11Y_PARAGRAPH_NAME) ) );
982         String sParaIndex = ::rtl::OUString::valueOf( nPara );
983 		sStr.SearchAndReplace( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "$(ARG)" )),
984                                sParaIndex );
985 
986         return ::rtl::OUString( sStr );
987     }
988 
getAccessibleRelationSet()989     uno::Reference< XAccessibleRelationSet > SAL_CALL AccessibleEditableTextPara::getAccessibleRelationSet() throw (uno::RuntimeException)
990     {
991         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
992 
993         // --> OD 2006-01-11 #i27138# - provide relations CONTENT_FLOWS_FROM
994         // and CONTENT_FLOWS_TO
995         if ( mpParaManager )
996         {
997             utl::AccessibleRelationSetHelper* pAccRelSetHelper =
998                                         new utl::AccessibleRelationSetHelper();
999             sal_Int32 nMyParaIndex( GetParagraphIndex() );
1000             // relation CONTENT_FLOWS_FROM
1001             if ( nMyParaIndex > 0 &&
1002                  mpParaManager->IsReferencable( nMyParaIndex - 1 ) )
1003             {
1004                 uno::Sequence<uno::Reference<XInterface> > aSequence(1);
1005                 aSequence[0] =
1006                     mpParaManager->GetChild( nMyParaIndex - 1 ).first.get().getRef();
1007                 AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_FROM,
1008                                             aSequence );
1009                 pAccRelSetHelper->AddRelation( aAccRel );
1010             }
1011 
1012             // relation CONTENT_FLOWS_TO
1013             if ( (nMyParaIndex + 1) < (sal_Int32)mpParaManager->GetNum() &&
1014                  mpParaManager->IsReferencable( nMyParaIndex + 1 ) )
1015             {
1016                 uno::Sequence<uno::Reference<XInterface> > aSequence(1);
1017                 aSequence[0] =
1018                     mpParaManager->GetChild( nMyParaIndex + 1 ).first.get().getRef();
1019                 AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_TO,
1020                                             aSequence );
1021                 pAccRelSetHelper->AddRelation( aAccRel );
1022             }
1023 
1024             return pAccRelSetHelper;
1025         }
1026         else
1027         {
1028             // no relations, therefore empty
1029             return uno::Reference< XAccessibleRelationSet >();
1030         }
1031         // <--
1032     }
1033 
getAccessibleStateSet()1034     uno::Reference< XAccessibleStateSet > SAL_CALL AccessibleEditableTextPara::getAccessibleStateSet() throw (uno::RuntimeException)
1035     {
1036         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1037 
1038         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1039 
1040         // Create a copy of the state set and return it.
1041         ::utl::AccessibleStateSetHelper* pStateSet = static_cast< ::utl::AccessibleStateSetHelper*>(mxStateSet.get());
1042 
1043         if( !pStateSet )
1044             return uno::Reference<XAccessibleStateSet>();
1045 		uno::Reference<XAccessibleStateSet> xParentStates;
1046 		if (getAccessibleParent().is())
1047 		{
1048 			uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
1049 			xParentStates = xParentContext->getAccessibleStateSet();
1050 		}
1051 		if (xParentStates.is() && xParentStates->contains(AccessibleStateType::EDITABLE) )
1052 		{
1053 			pStateSet->AddState(AccessibleStateType::EDITABLE);
1054 		}
1055         return uno::Reference<XAccessibleStateSet>( new ::utl::AccessibleStateSetHelper (*pStateSet) );
1056     }
1057 
getLocale()1058     lang::Locale SAL_CALL AccessibleEditableTextPara::getLocale() throw (IllegalAccessibleComponentStateException, uno::RuntimeException)
1059     {
1060         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1061 
1062         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1063 
1064         return implGetLocale();
1065     }
1066 
addEventListener(const uno::Reference<XAccessibleEventListener> & xListener)1067     void SAL_CALL AccessibleEditableTextPara::addEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException)
1068     {
1069         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1070 
1071         if( getNotifierClientId() != -1 )
1072             ::comphelper::AccessibleEventNotifier::addEventListener( getNotifierClientId(), xListener );
1073     }
1074 
removeEventListener(const uno::Reference<XAccessibleEventListener> & xListener)1075     void SAL_CALL AccessibleEditableTextPara::removeEventListener( const uno::Reference< XAccessibleEventListener >& xListener ) throw (uno::RuntimeException)
1076     {
1077         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1078 
1079         if( getNotifierClientId() != -1 )
1080             ::comphelper::AccessibleEventNotifier::removeEventListener( getNotifierClientId(), xListener );
1081     }
1082 
1083 	// XAccessibleComponent
containsPoint(const awt::Point & aTmpPoint)1084     sal_Bool SAL_CALL AccessibleEditableTextPara::containsPoint( const awt::Point& aTmpPoint ) throw (uno::RuntimeException)
1085     {
1086         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1087 
1088         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1089 
1090         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1091                    "AccessibleEditableTextPara::contains: index value overflow");
1092 
1093         awt::Rectangle aTmpRect = getBounds();
1094         Rectangle aRect( Point(aTmpRect.X, aTmpRect.Y), Size(aTmpRect.Width, aTmpRect.Height) );
1095         Point aPoint( aTmpPoint.X, aTmpPoint.Y );
1096 
1097         return aRect.IsInside( aPoint );
1098     }
1099 
getAccessibleAtPoint(const awt::Point & _aPoint)1100     uno::Reference< XAccessible > SAL_CALL AccessibleEditableTextPara::getAccessibleAtPoint( const awt::Point& _aPoint ) throw (uno::RuntimeException)
1101     {
1102         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1103 
1104         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1105 
1106         if( HaveChildren() )
1107         {
1108             // #103862# No longer need to make given position relative
1109             Point aPoint( _aPoint.X, _aPoint.Y );
1110 
1111             // respect EditEngine offset to surrounding shape/cell
1112             aPoint -= GetEEOffset();
1113 
1114             // convert to EditEngine coordinate system
1115             SvxTextForwarder& rCacheTF = GetTextForwarder();
1116             Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
1117 
1118             EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( GetParagraphIndex() );
1119 
1120             if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
1121                 aBulletInfo.bVisible &&
1122                 aBulletInfo.nType == SVX_NUM_BITMAP )
1123             {
1124                 Rectangle aRect = aBulletInfo.aBounds;
1125 
1126                 if( aRect.IsInside( aLogPoint ) )
1127                     return getAccessibleChild(0);
1128             }
1129         }
1130 
1131         // no children at all, or none at given position
1132         return uno::Reference< XAccessible >();
1133     }
1134 
getBounds()1135     awt::Rectangle SAL_CALL AccessibleEditableTextPara::getBounds() throw (uno::RuntimeException)
1136     {
1137         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1138 
1139         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1140 
1141         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1142                    "AccessibleEditableTextPara::getBounds: index value overflow");
1143 
1144         SvxTextForwarder& rCacheTF = GetTextForwarder();
1145         Rectangle aRect = rCacheTF.GetParaBounds( GetParagraphIndex() );
1146 
1147         // convert to screen coordinates
1148         Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect,
1149                                                                           rCacheTF.GetMapMode(),
1150                                                                           GetViewForwarder() );
1151 
1152         // offset from shape/cell
1153         Point aOffset = GetEEOffset();
1154 
1155         return awt::Rectangle( aScreenRect.Left() + aOffset.X(),
1156                                aScreenRect.Top() + aOffset.Y(),
1157                                aScreenRect.GetSize().Width(),
1158                                aScreenRect.GetSize().Height() );
1159     }
1160 
getLocation()1161     awt::Point SAL_CALL AccessibleEditableTextPara::getLocation(  ) throw (uno::RuntimeException)
1162     {
1163         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1164 
1165         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1166 
1167         awt::Rectangle aRect = getBounds();
1168 
1169         return awt::Point( aRect.X, aRect.Y );
1170     }
1171 
getLocationOnScreen()1172     awt::Point SAL_CALL AccessibleEditableTextPara::getLocationOnScreen(  ) throw (uno::RuntimeException)
1173     {
1174         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1175 
1176         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1177 
1178         // relate us to parent
1179         uno::Reference< XAccessible > xParent = getAccessibleParent();
1180         if( xParent.is() )
1181         {
1182             uno::Reference< XAccessibleComponent > xParentComponent( xParent, uno::UNO_QUERY );
1183             if( xParentComponent.is() )
1184             {
1185                 awt::Point aRefPoint = xParentComponent->getLocationOnScreen();
1186                 awt::Point aPoint = getLocation();
1187                 aPoint.X += aRefPoint.X;
1188                 aPoint.Y += aRefPoint.Y;
1189 
1190                 return aPoint;
1191             }
1192             // --> OD 2009-12-16 #i88070#
1193             // fallback to parent's <XAccessibleContext> instance
1194             else
1195             {
1196                 uno::Reference< XAccessibleContext > xParentContext = xParent->getAccessibleContext();
1197                 if ( xParentContext.is() )
1198                 {
1199                     uno::Reference< XAccessibleComponent > xParentContextComponent( xParentContext, uno::UNO_QUERY );
1200                     if( xParentContextComponent.is() )
1201                     {
1202                         awt::Point aRefPoint = xParentContextComponent->getLocationOnScreen();
1203                         awt::Point aPoint = getLocation();
1204                         aPoint.X += aRefPoint.X;
1205                         aPoint.Y += aRefPoint.Y;
1206 
1207                         return aPoint;
1208                     }
1209                 }
1210             }
1211             // <--
1212         }
1213 
1214         throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot access parent")),
1215                                     uno::Reference< uno::XInterface >
1216                                     ( static_cast< XAccessible* > (this) ) );	// disambiguate hierarchy
1217     }
1218 
getSize()1219     awt::Size SAL_CALL AccessibleEditableTextPara::getSize(  ) throw (uno::RuntimeException)
1220     {
1221         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1222 
1223         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1224 
1225         awt::Rectangle aRect = getBounds();
1226 
1227         return awt::Size( aRect.Width, aRect.Height );
1228     }
1229 
grabFocus()1230     void SAL_CALL AccessibleEditableTextPara::grabFocus(  ) throw (uno::RuntimeException)
1231     {
1232         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1233 
1234         // set cursor to this paragraph
1235         setSelection(0,0);
1236     }
1237 
getForeground()1238     sal_Int32 SAL_CALL AccessibleEditableTextPara::getForeground(  ) throw (::com::sun::star::uno::RuntimeException)
1239     {
1240         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1241 
1242         // #104444# Added to XAccessibleComponent interface
1243 		svtools::ColorConfig aColorConfig;
1244 	    sal_uInt32 nColor = aColorConfig.GetColorValue( svtools::FONTCOLOR ).nColor;
1245         return static_cast<sal_Int32>(nColor);
1246     }
1247 
getBackground()1248     sal_Int32 SAL_CALL AccessibleEditableTextPara::getBackground(  ) throw (::com::sun::star::uno::RuntimeException)
1249     {
1250         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1251 
1252         // #104444# Added to XAccessibleComponent interface
1253         Color aColor( Application::GetSettings().GetStyleSettings().GetWindowColor().GetColor() );
1254 
1255         // the background is transparent
1256         aColor.SetTransparency( 0xFF);
1257 
1258         return static_cast<sal_Int32>( aColor.GetColor() );
1259     }
1260 
1261 	// XAccessibleText
getCaretPosition()1262     sal_Int32 SAL_CALL AccessibleEditableTextPara::getCaretPosition() throw (uno::RuntimeException)
1263     {
1264         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1265 
1266         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1267 
1268         if( !HaveEditView() )
1269             return -1;
1270 
1271         ESelection aSelection;
1272         if( GetEditViewForwarder().GetSelection( aSelection ) &&
1273             GetParagraphIndex() == aSelection.nEndPara )
1274         {
1275             // caret is always nEndPara,nEndPos
1276 			EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() );
1277 			if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND &&
1278 				aBulletInfo.bVisible &&
1279 				aBulletInfo.nType != SVX_NUM_BITMAP )
1280 			{
1281 				sal_Int32 nBulletLen = aBulletInfo.aText.Len();
1282 				if( aSelection.nEndPos - nBulletLen >= 0 )
1283 					return aSelection.nEndPos - nBulletLen;
1284 			}
1285             return aSelection.nEndPos;
1286         }
1287 
1288         // not within this paragraph
1289         return -1;
1290     }
1291 
setCaretPosition(sal_Int32 nIndex)1292     sal_Bool SAL_CALL AccessibleEditableTextPara::setCaretPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1293     {
1294         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1295 
1296         return setSelection(nIndex, nIndex);
1297     }
1298 
getCharacter(sal_Int32 nIndex)1299     sal_Unicode SAL_CALL AccessibleEditableTextPara::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1300     {
1301         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1302 
1303         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1304 
1305         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1306                    "AccessibleEditableTextPara::getCharacter: index value overflow");
1307 
1308         return OCommonAccessibleText::getCharacter( nIndex );
1309     }
getAttributeNames()1310 	static uno::Sequence< ::rtl::OUString > getAttributeNames()
1311 	{
1312 		static uno::Sequence< ::rtl::OUString >* pNames = NULL;
1313 
1314 		if( pNames == NULL )
1315 		{
1316 			uno::Sequence< ::rtl::OUString >* pSeq = new uno::Sequence< ::rtl::OUString >( 21 );
1317 			::rtl::OUString* pStrings = pSeq->getArray();
1318 			sal_Int32 i = 0;
1319 	#define STR(x) pStrings[i++] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(x))
1320 			//STR("CharBackColor");
1321 			STR("CharColor");
1322 	  STR("CharContoured");
1323 	  STR("CharEmphasis");
1324 			STR("CharEscapement");
1325 			STR("CharFontName");
1326 			STR("CharHeight");
1327 			STR("CharPosture");
1328 	  STR("CharShadowed");
1329 			STR("CharStrikeout");
1330 			STR("CharUnderline");
1331 			STR("CharUnderlineColor");
1332 			STR("CharWeight");
1333 		        STR("NumberingLevel");
1334 			STR("NumberingRules");
1335 			STR("ParaAdjust");
1336 			STR("ParaBottomMargin");
1337 			STR("ParaFirstLineIndent");
1338 			STR("ParaLeftMargin");
1339 			STR("ParaLineSpacing");
1340 			STR("ParaRightMargin");
1341 			STR("ParaTabStops");
1342 	#undef STR
1343 			DBG_ASSERT( i == pSeq->getLength(), "Please adjust length" );
1344 			if( i != pSeq->getLength() )
1345 				pSeq->realloc( i );
1346 			pNames = pSeq;
1347 		}
1348 		return *pNames;
1349 	}
1350 	struct IndexCompare
1351 	{
1352 		const PropertyValue* pValues;
IndexCompareaccessibility::IndexCompare1353 		IndexCompare( const PropertyValue* pVals ) : pValues(pVals) {}
operator ()accessibility::IndexCompare1354 		bool operator() ( const sal_Int32& a, const sal_Int32& b ) const
1355 		{
1356 			return (pValues[a].Name < pValues[b].Name) ? true : false;
1357 		}
1358 	};
1359 
GetFieldTypeNameAtIndex(sal_Int32 nIndex)1360 	String AccessibleEditableTextPara::GetFieldTypeNameAtIndex(sal_Int32 nIndex)
1361 	{
1362 		String strFldType;
1363         SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();
1364 		//For field object info
1365 		sal_Int32 nParaIndex = GetParagraphIndex();
1366 		sal_Int32 nAllFieldLen = 0;
1367 		sal_Int32 nField = rCacheTF.GetFieldCount(nParaIndex), nFoundFieldIndex = -1;
1368 		EFieldInfo ree;
1369 		sal_Int32  reeBegin, reeEnd;
1370 		sal_Int32 nFieldType = -1;
1371 		for(sal_uInt16 j = 0; j < nField; j++)
1372 		{
1373 			ree = rCacheTF.GetFieldInfo(nParaIndex, j);
1374 			reeBegin  = ree.aPosition.nIndex + nAllFieldLen;
1375 			reeEnd = reeBegin + ree.aCurrentText.Len();
1376 			nAllFieldLen += (ree.aCurrentText.Len() - 1);
1377 			if( reeBegin > nIndex )
1378 			{
1379 				break;
1380 			}
1381 			if(  nIndex >= reeBegin && nIndex < reeEnd )
1382 			{
1383 				nFoundFieldIndex = j;
1384 				break;
1385 			}
1386 		}
1387 		if( nFoundFieldIndex >= 0  )
1388 		{
1389 			// So we get a field, check its type now.
1390 			nFieldType = ree.pFieldItem->GetField()->GetClassId() ;
1391 		}
1392 		switch(nFieldType)
1393 		{
1394 		case SVX_DATEFIELD:
1395 			{
1396 				const SvxDateField* pDateField = static_cast< const SvxDateField* >(ree.pFieldItem->GetField());
1397 				if (pDateField)
1398 				{
1399 					if (pDateField->GetType() == SVXDATETYPE_FIX)
1400 						strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("date (fixed)"));
1401 					else if (pDateField->GetType() == SVXDATETYPE_VAR)
1402 						strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("date (variable)"));
1403 				}
1404 			}
1405 			break;
1406 		case SVX_PAGEFIELD:
1407 			strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("page-number"));
1408 			break;
1409 		//support the sheet name & pages fields
1410 		case SVX_PAGESFIELD:
1411 				strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("page-count"));
1412 			break;
1413 		case SVX_TABLEFIELD:
1414 				strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("sheet-name"));
1415 			break;
1416 		//End
1417 		case SVX_TIMEFIELD:
1418 			strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time"));
1419 			break;
1420 		case SVX_EXT_TIMEFIELD:
1421 			{
1422 				const SvxExtTimeField* pTimeField = static_cast< const SvxExtTimeField* >(ree.pFieldItem->GetField());
1423 				if (pTimeField)
1424 				{
1425 					if (pTimeField->GetType() == SVXTIMETYPE_FIX)
1426 						strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time (fixed)"));
1427 					else if (pTimeField->GetType() == SVXTIMETYPE_VAR)
1428 						strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("time (variable)"));
1429 				}
1430 			}
1431 			break;
1432 		case SVX_AUTHORFIELD:
1433 			strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("author"));
1434 			break;
1435 		case SVX_EXT_FILEFIELD:
1436 		case SVX_FILEFIELD:
1437 			strFldType = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("file name"));
1438 		default:
1439 			break;
1440 		}
1441 		return strFldType;
1442 	}
1443 
getCharacterAttributes(sal_Int32 nIndex,const::com::sun::star::uno::Sequence<::rtl::OUString> & rRequestedAttributes)1444     uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& rRequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1445     {
1446         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1447         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1448 
1449 		//Skip the bullet range to ingnore the bullet text
1450 		SvxTextForwarder& rCacheTF = GetTextForwarder();
1451 		EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( GetParagraphIndex() );
1452 		if (aBulletInfo.bVisible)
1453 			nIndex += aBulletInfo.aText.Len();
1454 		if (nIndex != 0 && nIndex >= getCharacterCount())
1455 			nIndex = getCharacterCount()-1;
1456 		//
1457 		if (nIndex != 0)
1458 			CheckIndex(nIndex);	// may throw IndexOutOfBoundsException
1459 
1460 		bool bSupplementalMode = false;
1461 		uno::Sequence< ::rtl::OUString > aPropertyNames = rRequestedAttributes;
1462 		if (aPropertyNames.getLength() == 0)
1463 		{
1464 			bSupplementalMode = true;
1465 			aPropertyNames = getAttributeNames();
1466 		}
1467         // get default attribues...
1468         ::comphelper::SequenceAsHashMap aPropHashMap( getDefaultAttributes( aPropertyNames ) );
1469 
1470         // ... and override them with the direct attributes from the specific position
1471         uno::Sequence< beans::PropertyValue > aRunAttribs( getRunAttributes( nIndex, aPropertyNames ) );
1472         sal_Int32 nRunAttribs = aRunAttribs.getLength();
1473         const beans::PropertyValue *pRunAttrib = aRunAttribs.getConstArray();
1474         for (sal_Int32 k = 0;  k < nRunAttribs;  ++k)
1475         {
1476             const beans::PropertyValue &rRunAttrib = pRunAttrib[k];
1477             aPropHashMap[ rRunAttrib.Name ] = rRunAttrib.Value; //!! should not only be the value !!
1478         }
1479 #ifdef TL_DEBUG
1480         {
1481             uno::Sequence< rtl::OUString > aNames(1);
1482             aNames.getArray()[0] = rtl::OUString::createFromAscii("CharHeight");
1483             const rtl::OUString *pNames = aNames.getConstArray();
1484             const uno::Sequence< beans::PropertyValue > aAttribs( getRunAttributes( nIndex, aNames ) );
1485             const beans::PropertyValue *pAttribs = aAttribs.getConstArray();
1486             double d1 = -1.0;
1487             float  f1 = -1.0;
1488             if (aAttribs.getLength())
1489             {
1490                 uno::Any aAny( pAttribs[0].Value );
1491                 aAny >>= d1;
1492                 aAny >>= f1;
1493             }
1494             int i = 3;
1495         }
1496 #endif
1497 
1498         // get resulting sequence
1499         uno::Sequence< beans::PropertyValue > aRes;
1500         aPropHashMap >> aRes;
1501 
1502         // since SequenceAsHashMap ignores property handles and property state
1503         // we have to restore the property state here (property handles are
1504         // of no use to the accessibility API).
1505         sal_Int32 nRes = aRes.getLength();
1506         beans::PropertyValue *pRes = aRes.getArray();
1507         for (sal_Int32 i = 0;  i < nRes;  ++i)
1508         {
1509 			beans::PropertyValue &rRes = pRes[i];
1510             sal_Bool bIsDirectVal = sal_False;
1511             for (sal_Int32 k = 0;  k < nRunAttribs && !bIsDirectVal;  ++k)
1512             {
1513                 if (rRes.Name == pRunAttrib[k].Name)
1514                     bIsDirectVal = sal_True;
1515             }
1516             rRes.Handle = -1;
1517             rRes.State  = bIsDirectVal ? PropertyState_DIRECT_VALUE : PropertyState_DEFAULT_VALUE;
1518         }
1519 		if( bSupplementalMode )
1520 		{
1521 			_correctValues( nIndex, aRes );
1522 			// NumberingPrefix
1523 			nRes = aRes.getLength();
1524 			aRes.realloc( nRes + 1 );
1525 			pRes = aRes.getArray();
1526 			beans::PropertyValue &rRes = pRes[nRes];
1527 			rRes.Name = rtl::OUString::createFromAscii("NumberingPrefix");
1528 			::rtl::OUString numStr;
1529 			if (aBulletInfo.nType != SVX_NUM_CHAR_SPECIAL && aBulletInfo.nType != SVX_NUM_BITMAP)
1530 				numStr = (::rtl::OUString)aBulletInfo.aText;
1531 			rRes.Value <<= numStr;
1532 			rRes.Handle = -1;
1533 			rRes.State = PropertyState_DIRECT_VALUE;
1534 			//For field object.
1535 			String strFieldType = GetFieldTypeNameAtIndex(nIndex);
1536 			if (strFieldType.Len() > 0)
1537 			{
1538 				nRes = aRes.getLength();
1539 				aRes.realloc( nRes + 1 );
1540 				pRes = aRes.getArray();
1541 				beans::PropertyValue &rResField = pRes[nRes];
1542 				beans::PropertyValue aFieldType;
1543 				rResField.Name = rtl::OUString::createFromAscii("FieldType");
1544 				rResField.Value <<= rtl::OUString(strFieldType.ToLowerAscii());
1545 				rResField.Handle = -1;
1546 				rResField.State = PropertyState_DIRECT_VALUE;
1547         }
1548 		//sort property values
1549 		// build sorted index array
1550 		sal_Int32 nLength = aRes.getLength();
1551 		const beans::PropertyValue* pPairs = aRes.getConstArray();
1552 		sal_Int32* pIndices = new sal_Int32[nLength];
1553 		sal_Int32 i = 0;
1554 		for( i = 0; i < nLength; i++ )
1555 			pIndices[i] = i;
1556 		sort( &pIndices[0], &pIndices[nLength], IndexCompare(pPairs) );
1557 		// create sorted sequences according to index array
1558 		uno::Sequence<beans::PropertyValue> aNewValues( nLength );
1559 		beans::PropertyValue* pNewValues = aNewValues.getArray();
1560 		for( i = 0; i < nLength; i++ )
1561 		{
1562 			pNewValues[i] = pPairs[pIndices[i]];
1563 		}
1564 		delete[] pIndices;
1565 		//
1566         return aNewValues;
1567 		}
1568 		return aRes;
1569     }
1570 
getCharacterBounds(sal_Int32 nIndex)1571     awt::Rectangle SAL_CALL AccessibleEditableTextPara::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1572     {
1573         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1574 
1575         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1576 
1577         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1578                    "AccessibleEditableTextPara::getCharacterBounds: index value overflow");
1579 
1580         // #108900# Have position semantics now for nIndex, as
1581         // one-past-the-end values are legal, too.
1582         CheckPosition( nIndex );
1583 
1584         SvxTextForwarder& rCacheTF = GetTextForwarder();
1585         Rectangle aRect = rCacheTF.GetCharBounds( GetParagraphIndex(), static_cast< sal_uInt16 >( nIndex ) );
1586 
1587         // convert to screen
1588         Rectangle aScreenRect = AccessibleEditableTextPara::LogicToPixel( aRect,
1589                                                                           rCacheTF.GetMapMode(),
1590                                                                           GetViewForwarder() );
1591         // #109864# offset from parent (paragraph), but in screen
1592         // coordinates. This makes sure the internal text offset in
1593         // the outline view forwarder gets cancelled out here
1594         awt::Rectangle aParaRect( getBounds() );
1595         aScreenRect.Move( -aParaRect.X, -aParaRect.Y );
1596 
1597         // offset from shape/cell
1598         Point aOffset = GetEEOffset();
1599 
1600         return awt::Rectangle( aScreenRect.Left() + aOffset.X(),
1601                                aScreenRect.Top() + aOffset.Y(),
1602                                aScreenRect.GetSize().Width(),
1603                                aScreenRect.GetSize().Height() );
1604     }
1605 
getCharacterCount()1606     sal_Int32 SAL_CALL AccessibleEditableTextPara::getCharacterCount() throw (uno::RuntimeException)
1607     {
1608         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1609 
1610         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1611 
1612         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1613                    "AccessibleEditableTextPara::getCharacterCount: index value overflow");
1614 
1615         return OCommonAccessibleText::getCharacterCount();
1616     }
1617 
getIndexAtPoint(const awt::Point & rPoint)1618     sal_Int32 SAL_CALL AccessibleEditableTextPara::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException)
1619     {
1620         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1621 
1622         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1623 	if ((rPoint.X <= 0) && (rPoint.Y <= 0))
1624 		return 0;
1625         sal_uInt32 nPara;
1626         sal_uInt16 nIndex;
1627 
1628         // offset from surrounding cell/shape
1629         Point aOffset( GetEEOffset() );
1630         Point aPoint( rPoint.X - aOffset.X(), rPoint.Y - aOffset.Y() );
1631 
1632         // convert to logical coordinates
1633         SvxTextForwarder& rCacheTF = GetTextForwarder();
1634         Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
1635 
1636         // re-offset to parent (paragraph)
1637         Rectangle aParaRect = rCacheTF.GetParaBounds( GetParagraphIndex() );
1638         aLogPoint.Move( aParaRect.Left(), aParaRect.Top() );
1639 
1640         if( rCacheTF.GetIndexAtPoint( aLogPoint, nPara, nIndex ) &&
1641             GetParagraphIndex() == nPara )
1642         {
1643             // #102259# Double-check if we're _really_ on the given character
1644             try
1645             {
1646                 awt::Rectangle aRect1( getCharacterBounds(nIndex) );
1647                 Rectangle aRect2( aRect1.X, aRect1.Y,
1648                                   aRect1.Width + aRect1.X, aRect1.Height + aRect1.Y );
1649                 if( aRect2.IsInside( Point( rPoint.X, rPoint.Y ) ) )
1650                     return nIndex;
1651                 else
1652                     return -1;
1653             }
1654             catch( const lang::IndexOutOfBoundsException& )
1655             {
1656                 // #103927# Don't throw for invalid nIndex values
1657                 return -1;
1658             }
1659         }
1660         else
1661         {
1662             // not within our paragraph
1663             return -1;
1664         }
1665     }
1666 
getSelectedText()1667     ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getSelectedText() throw (uno::RuntimeException)
1668     {
1669         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1670 
1671         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1672 
1673         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1674                    "AccessibleEditableTextPara::getSelectedText: index value overflow");
1675 
1676         if( !HaveEditView() )
1677             return ::rtl::OUString();
1678 
1679         return OCommonAccessibleText::getSelectedText();
1680     }
1681 
getSelectionStart()1682     sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionStart() throw (uno::RuntimeException)
1683     {
1684         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1685 
1686         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1687 
1688         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1689                    "AccessibleEditableTextPara::getSelectionStart: index value overflow");
1690 
1691         if( !HaveEditView() )
1692             return -1;
1693 
1694         return OCommonAccessibleText::getSelectionStart();
1695     }
1696 
getSelectionEnd()1697     sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionEnd() throw (uno::RuntimeException)
1698     {
1699         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1700 
1701         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1702 
1703         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1704                    "AccessibleEditableTextPara::getSelectionEnd: index value overflow");
1705 
1706         if( !HaveEditView() )
1707             return -1;
1708 
1709         return OCommonAccessibleText::getSelectionEnd();
1710     }
1711 
setSelection(sal_Int32 nStartIndex,sal_Int32 nEndIndex)1712     sal_Bool SAL_CALL AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1713     {
1714         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1715 
1716         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1717 
1718         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1719                    "AccessibleEditableTextPara::setSelection: paragraph index value overflow");
1720 
1721         CheckRange(nStartIndex, nEndIndex);
1722 
1723         try
1724         {
1725             SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
1726             return rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
1727         }
1728         catch( const uno::RuntimeException& )
1729         {
1730             return sal_False;
1731         }
1732     }
1733 
getText()1734     ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getText() throw (uno::RuntimeException)
1735     {
1736         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1737 
1738         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1739 
1740         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1741                    "AccessibleEditableTextPara::getText: paragraph index value overflow");
1742 
1743         return OCommonAccessibleText::getText();
1744     }
1745 
getTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)1746     ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1747     {
1748         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1749 
1750         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1751 
1752         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1753                    "AccessibleEditableTextPara::getTextRange: paragraph index value overflow");
1754 
1755         return OCommonAccessibleText::getTextRange(nStartIndex, nEndIndex);
1756     }
_correctValues(const sal_Int32,uno::Sequence<PropertyValue> & rValues)1757 	void AccessibleEditableTextPara::_correctValues( const sal_Int32 /* nIndex */,
1758 										   uno::Sequence< PropertyValue >& rValues)
1759 	{
1760 		SvxTextForwarder& rCacheTF = GetTextForwarder();
1761 		sal_Int32 nRes = rValues.getLength();
1762 		beans::PropertyValue *pRes = rValues.getArray();
1763 		for (sal_Int32 i = 0;  i < nRes;  ++i)
1764 		{
1765 			beans::PropertyValue &rRes = pRes[i];
1766 			// Char color
1767 			if (rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharColor"))==0)
1768 			{
1769 				uno::Any &anyChar = rRes.Value;
1770 				sal_uInt32 crChar = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved));
1771 				if (COL_AUTO == crChar )
1772 				{
1773 					uno::Reference< ::com::sun::star::accessibility::XAccessibleComponent > xComponent;
1774 					if (mxParent.is())
1775 					{
1776 						xComponent.set(mxParent,uno::UNO_QUERY);
1777 					}
1778 					else
1779 					{
1780 						xComponent.set(m_xAccInfo,uno::UNO_QUERY);
1781 					}
1782 					if (xComponent.is())
1783 					{
1784 						uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY);
1785 						if (xContext->getAccessibleRole() == AccessibleRole::SHAPE
1786 							|| xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL)
1787 						{
1788 							anyChar <<= COL_BLACK;
1789 						}
1790 						else
1791 						{
1792 							Color cr(xComponent->getBackground());
1793 							crChar = cr.IsDark() ? COL_WHITE : COL_BLACK;
1794 							anyChar <<= crChar;
1795 						}
1796 					}
1797 				}
1798 				continue;
1799 			}
1800 			// Underline
1801 			if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharUnderline"))==0)
1802 			{
1803 				/*
1804 				// MT: Implement XAccessibleTextMarkup, mark with TextMarkupType::SPELLCHECK. This way done in SW.
1805 				if (IsCurrentEditorEnableAutoSpell( mxParent ))
1806 				{
1807 					try
1808 					{
1809 						SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_False );
1810 						sal_Bool bWrong = rCacheVF.IsWrongSpelledWordAtPos( GetParagraphIndex(), nIndex );
1811 						if ( bWrong )
1812 						{
1813 							uno::Any &anyUnderLine = pRes[9].Value;
1814 							// MT IA2: Not needed? sal_uInt16 crUnderLine = (sal_uInt16)(anyUnderLine.pReserved);
1815 							anyUnderLine <<= (sal_uInt16)UNDERLINE_WAVE;
1816 						}
1817 					}
1818 					catch( const uno::RuntimeException& )
1819 					{
1820 					}
1821 				}
1822 				*/
1823 				continue;
1824 			}
1825 			// Underline color && Mis-spell
1826 			if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharUnderlineColor"))==0)
1827 			{
1828 				uno::Any &anyCharUnderLine = rRes.Value;
1829 				sal_uInt32 crCharUnderLine = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>( anyCharUnderLine.pReserved));
1830 				if (COL_AUTO == crCharUnderLine )
1831 				{
1832 					uno::Reference< ::com::sun::star::accessibility::XAccessibleComponent > xComponent;
1833 					if (mxParent.is())
1834 					{
1835 						xComponent.set(mxParent,uno::UNO_QUERY);
1836 					}
1837 					else
1838 					{
1839 						xComponent.set(m_xAccInfo,uno::UNO_QUERY);
1840 					}
1841 					if (xComponent.is())
1842 					{
1843 						uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY);
1844 						if (xContext->getAccessibleRole() == AccessibleRole::SHAPE
1845 							|| xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL)
1846 						{
1847 							anyCharUnderLine <<= COL_BLACK;
1848 						}
1849 						else
1850 						{
1851 							Color cr(xComponent->getBackground());
1852 							crCharUnderLine = cr.IsDark() ? COL_WHITE : COL_BLACK;
1853 							anyCharUnderLine <<= crCharUnderLine;
1854 						}
1855 					}
1856 				}
1857 				// MT: Implement XAccessibleTextMarkup, mark with TextMarkupType::SPELLCHECK. This way done in SW.
1858 				/*
1859 				if (IsCurrentEditorEnableAutoSpell( mxParent ))
1860 				{
1861 					try
1862 					{
1863 						SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_False );
1864 						sal_Bool bWrong = rCacheVF.IsWrongSpelledWordAtPos( GetParagraphIndex(), nIndex );
1865 						if ( bWrong )
1866 						{
1867 							uno::Any &anyUnderLineColor = rRes.Value;
1868 							// MT IA2: Not needed? sal_uInt16 crUnderLineColor = (sal_uInt16)(anyUnderLineColor.pReserved);
1869 							anyUnderLineColor <<= COL_LIGHTRED;
1870 						}
1871 					}
1872 					catch( const uno::RuntimeException& )
1873 					{
1874 					}
1875 				}
1876 				*/
1877 				continue;
1878 			}
1879 			// NumberingLevel
1880 			if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("NumberingLevel"))==0)
1881 			{
1882 				const SvxNumBulletItem& rNumBullet = ( SvxNumBulletItem& )rCacheTF.GetParaAttribs(GetParagraphIndex()).Get(EE_PARA_NUMBULLET);
1883 				if(rNumBullet.GetNumRule()->GetLevelCount()==0)
1884 				{
1885 					rRes.Value <<= (sal_Int16)-1;
1886 					rRes.Handle = -1;
1887 					rRes.State = PropertyState_DIRECT_VALUE;
1888 				}
1889 				else
1890 				{
1891 //					SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
1892 //						ImplGetSvxCharAndParaPropertiesMap() );
1893 					// MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap
1894             		SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() );
1895 
1896 					aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) );
1897 					rRes.Value = aPropSet._getPropertyValue( rRes.Name, mnParagraphIndex );
1898 					rRes.State = aPropSet._getPropertyState( rRes.Name, mnParagraphIndex );
1899 					rRes.Handle = -1;
1900 				}
1901 				continue;
1902 			}
1903 			// NumberingRules
1904 			if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("NumberingRules"))==0)
1905 			{
1906 				SfxItemSet aAttribs = rCacheTF.GetParaAttribs( GetParagraphIndex() );
1907 				sal_Bool bVis = ((const SfxUInt16Item&)aAttribs.Get( EE_PARA_BULLETSTATE )).GetValue() ? sal_True : sal_False;
1908 				if(bVis)
1909 				{
1910 					rRes.Value <<= (sal_Int16)-1;
1911 					rRes.Handle = -1;
1912 					rRes.State = PropertyState_DIRECT_VALUE;
1913 				}
1914 				else
1915 				{
1916 					// MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap
1917             		SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() );
1918 					aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) );
1919 					rRes.Value = aPropSet._getPropertyValue( rRes.Name, mnParagraphIndex );
1920 					rRes.State = aPropSet._getPropertyState( rRes.Name, mnParagraphIndex );
1921 					rRes.Handle = -1;
1922 				}
1923 				continue;
1924 			}
1925 		}
1926 	}
SkipField(sal_Int32 nIndex,sal_Bool bForward)1927     sal_Int32 AccessibleEditableTextPara::SkipField(sal_Int32 nIndex, sal_Bool bForward)
1928     {
1929 		sal_Int32 nParaIndex = GetParagraphIndex();
1930 		SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();
1931 		sal_Int32 nAllFieldLen = 0;
1932 		sal_Int32 nField = rCacheTF.GetFieldCount(nParaIndex), nFoundFieldIndex = -1;
1933 		EFieldInfo ree;
1934 		sal_Int32  reeBegin=0, reeEnd=0;
1935 		for(sal_uInt16 j = 0; j < nField; j++)
1936 		{
1937 			ree = rCacheTF.GetFieldInfo(nParaIndex, j);
1938 			reeBegin  = ree.aPosition.nIndex + nAllFieldLen;
1939 			reeEnd = reeBegin + ree.aCurrentText.Len();
1940 			nAllFieldLen += (ree.aCurrentText.Len() - 1);
1941 			if( reeBegin > nIndex )
1942 			{
1943 				break;
1944 			}
1945 			if(  nIndex >= reeBegin && nIndex < reeEnd )
1946 			{
1947 				if(ree.pFieldItem->GetField()->GetClassId() != SVX_URLFIELD)
1948 				{
1949 					nFoundFieldIndex = j;
1950 					break;
1951 				}
1952 			}
1953 		}
1954 		if( nFoundFieldIndex >= 0  )
1955 		{
1956 			if( bForward )
1957 				return reeEnd - 1;
1958 			else
1959 				return reeBegin;
1960 		}
1961 		return nIndex;
1962     }
ExtendByField(::com::sun::star::accessibility::TextSegment & Segment)1963     sal_Bool AccessibleEditableTextPara::ExtendByField( ::com::sun::star::accessibility::TextSegment& Segment )
1964     {
1965 		sal_Int32 nParaIndex = GetParagraphIndex();
1966 		SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();
1967 		sal_Int32 nAllFieldLen = 0;
1968 		sal_Int32 nField = rCacheTF.GetFieldCount(nParaIndex), nFoundFieldIndex = -1;
1969 		EFieldInfo ree;
1970 		sal_Int32  reeBegin=0, reeEnd=0;
1971 		for(sal_uInt16 j = 0; j < nField; j++)
1972 		{
1973 			ree = rCacheTF.GetFieldInfo(nParaIndex, j);
1974 			reeBegin  = ree.aPosition.nIndex + nAllFieldLen;
1975 			reeEnd = reeBegin + ree.aCurrentText.Len();
1976 			nAllFieldLen += (ree.aCurrentText.Len() - 1);
1977 			if( reeBegin > Segment.SegmentEnd )
1978 			{
1979 				break;
1980 			}
1981 			if(  (Segment.SegmentEnd > reeBegin && Segment.SegmentEnd <= reeEnd) ||
1982 			      (Segment.SegmentStart >= reeBegin && Segment.SegmentStart < reeEnd)  )
1983 			{
1984 				if(ree.pFieldItem->GetField()->GetClassId() != SVX_URLFIELD)
1985 				{
1986 					nFoundFieldIndex = j;
1987 					break;
1988 				}
1989 			}
1990 		}
1991 		sal_Bool bExtend = sal_False;
1992 		if( nFoundFieldIndex >= 0 )
1993 		{
1994 			if( Segment.SegmentEnd < reeEnd )
1995 			{
1996 				Segment.SegmentEnd  = reeEnd;
1997 				bExtend = sal_True;
1998 			}
1999 			if( Segment.SegmentStart > reeBegin )
2000 			{
2001 				Segment.SegmentStart = reeBegin;
2002 				bExtend = sal_True;
2003 			}
2004 			if( bExtend )
2005 			{
2006 				//If there is a bullet before the field, should add the bullet length into the segment.
2007 				EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(nParaIndex);
2008 				int nBulletLen = aBulletInfo.aText.Len();
2009 				if (nBulletLen > 0)
2010 				{
2011 					Segment.SegmentEnd += nBulletLen;
2012 					if (nFoundFieldIndex > 0)
2013 						Segment.SegmentStart += nBulletLen;
2014 					Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd);
2015 					//After get the correct field name, should restore the offset value which don't contain the bullet.
2016 					Segment.SegmentEnd -= nBulletLen;
2017 					if (nFoundFieldIndex > 0)
2018 						Segment.SegmentStart -= nBulletLen;
2019 				}
2020 				else
2021 					Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd);
2022 			}
2023 		}
2024 		return bExtend;
2025     }
getTextAtIndex(sal_Int32 nIndex,sal_Int16 aTextType)2026     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
2027     {
2028         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2029 
2030         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2031 
2032         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2033                    "AccessibleEditableTextPara::getTextAtIndex: paragraph index value overflow");
2034 
2035         ::com::sun::star::accessibility::TextSegment aResult;
2036         aResult.SegmentStart = -1;
2037         aResult.SegmentEnd = -1;
2038 
2039         switch( aTextType )
2040         {
2041 		case AccessibleTextType::CHARACTER:
2042 		case AccessibleTextType::WORD:
2043 		{
2044 			aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
2045 			ExtendByField( aResult );
2046 			break;
2047             	}
2048             // Not yet handled by OCommonAccessibleText. Missing
2049             // implGetAttributeRunBoundary() method there
2050             case AccessibleTextType::ATTRIBUTE_RUN:
2051             {
2052                 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( GetParagraphIndex() );
2053 
2054                 if( nIndex == nTextLen )
2055                 {
2056                     // #i17014# Special-casing one-behind-the-end character
2057                     aResult.SegmentStart = aResult.SegmentEnd = nTextLen;
2058                 }
2059                 else
2060                 {
2061                     sal_uInt16 nStartIndex, nEndIndex;
2062 					//For the bullet paragraph, the bullet string is ingnored for IAText::attributes() function.
2063 					SvxTextForwarder&	rCacheTF = GetTextForwarder();
2064 					// MT IA2: Not used? sal_Int32 nBulletLen = 0;
2065 					EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( GetParagraphIndex() );
2066 					if (aBulletInfo.bVisible)
2067 						nIndex += aBulletInfo.aText.Len();
2068 					if (nIndex != 0  && nIndex >= getCharacterCount())
2069 						nIndex = getCharacterCount()-1;
2070 					CheckPosition(nIndex);
2071                     if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
2072                     {
2073                         aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
2074 						if (aBulletInfo.bVisible)
2075 						{
2076 							nStartIndex -= aBulletInfo.aText.Len();
2077 							nEndIndex -= aBulletInfo.aText.Len();
2078 						}
2079                         aResult.SegmentStart = nStartIndex;
2080                         aResult.SegmentEnd = nEndIndex;
2081                     }
2082 		}
2083                 break;
2084             }
2085             case AccessibleTextType::LINE:
2086             {
2087                 SvxTextForwarder&	rCacheTF = GetTextForwarder();
2088                 sal_Int32			nParaIndex = GetParagraphIndex();
2089                 // MT IA2: Not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( nParaIndex );
2090                 CheckPosition(nIndex);
2091 		if (nIndex != 0  && nIndex == getCharacterCount())
2092 			--nIndex;
2093                 sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( nParaIndex );
2094                 sal_Int32 nCurIndex;
2095                 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
2096                 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
2097                 //by the IAText::attributes(). So here must do special support for bullet line.
2098                 sal_Int32 nBulletLen = 0;
2099                 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
2100                 {
2101                     if (nLine == 0)
2102                     {
2103                         EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( nParaIndex );
2104                         if (aBulletInfo.bVisible)
2105                         {
2106                             //in bullet or numbering;
2107                             nBulletLen = aBulletInfo.aText.Len();
2108                         }
2109                     }
2110                     //nCurIndex += rCacheTF.GetLineLen(nParaIndex, nLine);
2111                     sal_Int32 nLineLen = rCacheTF.GetLineLen(nParaIndex, nLine);
2112                     if (nLine == 0)
2113                         nCurIndex += nLineLen - nBulletLen;
2114                     else
2115                         nCurIndex += nLineLen;
2116                     if( nCurIndex > nIndex )
2117                     {
2118                         if (nLine ==0)
2119                         {
2120                             //aResult.SegmentStart = nCurIndex - rCacheTF.GetLineLen(nParaIndex, nLine);
2121                             aResult.SegmentStart = 0;
2122                             aResult.SegmentEnd = nCurIndex;
2123                             //aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd );
2124                             aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen);
2125                             break;
2126                         }
2127                         else
2128                         {
2129                             //aResult.SegmentStart = nCurIndex - rCacheTF.GetLineLen(nParaIndex, nLine);
2130                             aResult.SegmentStart = nCurIndex - nLineLen;
2131                             aResult.SegmentEnd = nCurIndex;
2132                             //aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd );
2133                             aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen);
2134                             break;
2135                         }
2136                     }
2137                 }
2138                 break;
2139             }
2140             default:
2141                 aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
2142                 break;
2143         } /* end of switch( aTextType ) */
2144 
2145         return aResult;
2146     }
2147 
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 aTextType)2148     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
2149     {
2150         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2151 
2152         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2153 
2154         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2155                    "AccessibleEditableTextPara::getTextBeforeIndex: paragraph index value overflow");
2156 
2157         ::com::sun::star::accessibility::TextSegment aResult;
2158         aResult.SegmentStart = -1;
2159         aResult.SegmentEnd = -1;
2160 		i18n::Boundary aBoundary;
2161         switch( aTextType )
2162         {
2163             // Not yet handled by OCommonAccessibleText. Missing
2164             // implGetAttributeRunBoundary() method there
2165             case AccessibleTextType::ATTRIBUTE_RUN:
2166             {
2167                 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( GetParagraphIndex() );
2168                 sal_uInt16 nStartIndex, nEndIndex;
2169 
2170                 if( nIndex == nTextLen )
2171                 {
2172                     // #i17014# Special-casing one-behind-the-end character
2173                     if( nIndex > 0 &&
2174                         GetAttributeRun(nStartIndex, nEndIndex, nIndex-1) )
2175                     {
2176                         aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
2177                         aResult.SegmentStart = nStartIndex;
2178                         aResult.SegmentEnd = nEndIndex;
2179                     }
2180                 }
2181                 else
2182                 {
2183                     if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
2184                     {
2185                         // already at the left border? If not, query
2186                         // one index further left
2187                         if( nStartIndex > 0 &&
2188                             GetAttributeRun(nStartIndex, nEndIndex, nStartIndex-1) )
2189                         {
2190                             aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
2191                             aResult.SegmentStart = nStartIndex;
2192                             aResult.SegmentEnd = nEndIndex;
2193                         }
2194                     }
2195                 }
2196                 break;
2197             }
2198             case AccessibleTextType::LINE:
2199             {
2200                 SvxTextForwarder&	rCacheTF = GetTextForwarder();
2201                 sal_Int32			nParaIndex = GetParagraphIndex();
2202                 // MT IA2 not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( nParaIndex );
2203 
2204                 CheckPosition(nIndex);
2205 
2206                 sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( nParaIndex );
2207                 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
2208                 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
2209                 //by the IAText::attributes(). So here must do special support for bullet line.
2210                 sal_Int32 nCurIndex=0, nLastIndex=0, nCurLineLen=0;
2211                 sal_Int32 nLastLineLen = 0, nBulletLen = 0;;
2212                 // get the line before the line the index points into
2213                 for( nLine=0, nCurIndex=0, nLastIndex=0; nLine<nLineCount; ++nLine )
2214                 {
2215                     nLastIndex = nCurIndex;
2216                     if (nLine == 0)
2217                     {
2218                         EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( nParaIndex );
2219                         if (aBulletInfo.bVisible)
2220                         {
2221                             //in bullet or numbering;
2222                             nBulletLen = aBulletInfo.aText.Len();
2223                         }
2224                     }
2225                     if (nLine == 1)
2226                         nLastLineLen = nCurLineLen - nBulletLen;
2227                     else
2228                         nLastLineLen = nCurLineLen;
2229                     nCurLineLen = rCacheTF.GetLineLen(nParaIndex, nLine);
2230                     //nCurIndex += nCurLineLen;
2231                     if (nLine == 0)
2232                         nCurIndex += nCurLineLen - nBulletLen;
2233                     else
2234                         nCurIndex += nCurLineLen;
2235 
2236                     //if( nCurIndex > nIndex &&
2237                     //nLastIndex > nCurLineLen )
2238                     if (nCurIndex > nIndex)
2239                     {
2240                         if (nLine == 0)
2241                         {
2242                             break;
2243                         }
2244                         else if (nLine == 1)
2245                         {
2246                             aResult.SegmentStart = 0;
2247                             aResult.SegmentEnd = static_cast< sal_uInt16 >( nLastIndex );
2248                             aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen);
2249                             break;
2250                         }
2251                         else
2252                         {
2253                             //aResult.SegmentStart = nLastIndex - nCurLineLen;
2254                             aResult.SegmentStart = nLastIndex - nLastLineLen;
2255                             aResult.SegmentEnd = static_cast< sal_uInt16 >( nLastIndex );
2256                             aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen);
2257                             break;
2258                         }
2259                     }
2260                 }
2261 
2262                 break;
2263             }
2264 			case AccessibleTextType::WORD:
2265 			{
2266 				nIndex = SkipField( nIndex, sal_False);
2267 				::rtl::OUString sText( implGetText() );
2268 				sal_Int32 nLength = sText.getLength();
2269 
2270 				// get word at index
2271 				implGetWordBoundary( aBoundary, nIndex );
2272 
2273 
2274 				//sal_Int32 curWordStart = aBoundary.startPos;
2275 				//sal_Int32 preWordStart = curWordStart;
2276 				sal_Int32 curWordStart , preWordStart;
2277 				if( aBoundary.startPos == -1 || aBoundary.startPos > nIndex)
2278 					curWordStart = preWordStart = nIndex;
2279 				else
2280 					curWordStart = preWordStart = aBoundary.startPos;
2281 
2282 				// get previous word
2283 
2284 				sal_Bool bWord = sal_False;
2285 
2286 				//while ( preWordStart > 0 && aBoundary.startPos == curWordStart)
2287 				while ( (preWordStart >= 0 && !bWord ) || ( aBoundary.endPos > curWordStart ) )
2288 					{
2289 					preWordStart--;
2290 					bWord = implGetWordBoundary( aBoundary, preWordStart );
2291 				}
2292 				if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
2293 				{
2294 					aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
2295 					aResult.SegmentStart = aBoundary.startPos;
2296 					aResult.SegmentEnd = aBoundary.endPos;
2297 					ExtendByField( aResult );
2298 				}
2299 			}
2300 			break;
2301 			case AccessibleTextType::CHARACTER:
2302 			{
2303 				nIndex = SkipField( nIndex, sal_False);
2304 				aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
2305 				ExtendByField( aResult );
2306 				break;
2307 			}
2308             default:
2309                 aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
2310                 break;
2311         } /* end of switch( aTextType ) */
2312 
2313         return aResult;
2314     }
2315 
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 aTextType)2316     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
2317     {
2318         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2319 
2320         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2321 
2322         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2323                    "AccessibleEditableTextPara::getTextBehindIndex: paragraph index value overflow");
2324 
2325         ::com::sun::star::accessibility::TextSegment aResult;
2326         aResult.SegmentStart = -1;
2327         aResult.SegmentEnd = -1;
2328 		i18n::Boundary aBoundary;
2329         switch( aTextType )
2330         {
2331             case AccessibleTextType::ATTRIBUTE_RUN:
2332             {
2333                 sal_uInt16 nStartIndex, nEndIndex;
2334 
2335                 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
2336                 {
2337                     // already at the right border?
2338                     if( nEndIndex < GetTextLen() )
2339                     {
2340                         if( GetAttributeRun(nStartIndex, nEndIndex, nEndIndex) )
2341                         {
2342                             aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
2343                             aResult.SegmentStart = nStartIndex;
2344                             aResult.SegmentEnd = nEndIndex;
2345                         }
2346                     }
2347                 }
2348                 break;
2349             }
2350 
2351             case AccessibleTextType::LINE:
2352             {
2353                 SvxTextForwarder&	rCacheTF = GetTextForwarder();
2354                 sal_Int32			nParaIndex = GetParagraphIndex();
2355                 // MT IA2 not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( nParaIndex );
2356 
2357                 CheckPosition(nIndex);
2358 
2359                 sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( nParaIndex );
2360                 sal_Int32 nCurIndex;
2361                 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
2362                 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
2363                 //by the IAText::attributes(). So here must do special support for bullet line.
2364                 sal_Int32 nBulletLen = 0;
2365                 // get the line after the line the index points into
2366                 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
2367                 {
2368                     if (nLine == 0)
2369                     {
2370                         EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( nParaIndex );
2371                         if (aBulletInfo.bVisible)
2372                         {
2373                             //in bullet or numbering;
2374                             nBulletLen = aBulletInfo.aText.Len();
2375                         }
2376                     }
2377                     //nCurIndex += rCacheTF.GetLineLen(nParaIndex, nLine);
2378                     sal_Int32 nLineLen = rCacheTF.GetLineLen(nParaIndex, nLine);
2379 
2380                     if (nLine == 0)
2381                         nCurIndex += nLineLen - nBulletLen;
2382                     else
2383                         nCurIndex += nLineLen;
2384 
2385                     if( nCurIndex > nIndex &&
2386                         nLine < nLineCount-1 )
2387                     {
2388                         aResult.SegmentStart = nCurIndex;
2389                         aResult.SegmentEnd = nCurIndex + rCacheTF.GetLineLen(nParaIndex, nLine+1);
2390                         aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen);
2391                         break;
2392                     }
2393                 }
2394 
2395                 break;
2396             }
2397 			case AccessibleTextType::WORD:
2398 			{
2399 				nIndex = SkipField( nIndex, sal_True);
2400 				::rtl::OUString sText( implGetText() );
2401 				sal_Int32 nLength = sText.getLength();
2402 
2403 				// get word at index
2404 				sal_Bool bWord = implGetWordBoundary( aBoundary, nIndex );
2405 
2406 				// real current world
2407 				sal_Int32 nextWord = nIndex;
2408 				//if( nIndex >= aBoundary.startPos && nIndex <= aBoundary.endPos )
2409 				if( nIndex <= aBoundary.endPos )
2410 				{
2411 					nextWord = 	aBoundary.endPos;
2412 					if( sText.getStr()[nextWord] == sal_Unicode(' ') ) nextWord++;
2413 					bWord = implGetWordBoundary( aBoundary, nextWord );
2414 				}
2415 
2416 				if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
2417 				{
2418 					aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
2419 					aResult.SegmentStart = aBoundary.startPos;
2420 					aResult.SegmentEnd = aBoundary.endPos;
2421 
2422 					// If the end position of aBoundary is inside a field, extend the result to the end of the field
2423 
2424 					ExtendByField( aResult );
2425 				}
2426 			}
2427 			break;
2428 
2429 			case AccessibleTextType::CHARACTER:
2430 			{
2431 				nIndex = SkipField( nIndex, sal_True);
2432 				aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
2433 				ExtendByField( aResult );
2434 				break;
2435 			}
2436             default:
2437                 aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
2438                 break;
2439         } /* end of switch( aTextType ) */
2440 
2441         return aResult;
2442     }
2443 
copyText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)2444     sal_Bool SAL_CALL AccessibleEditableTextPara::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2445     {
2446         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2447 
2448         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2449 
2450         try
2451         {
2452             SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
2453             #if OSL_DEBUG_LEVEL > 0
2454             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();    // MUST be after GetEditViewForwarder(), see method docs
2455             (void)rCacheTF;
2456             #else
2457             GetTextForwarder();                                         // MUST be after GetEditViewForwarder(), see method docs
2458             #endif
2459 
2460             sal_Bool aRetVal;
2461 
2462             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2463                        "AccessibleEditableTextPara::copyText: index value overflow");
2464 
2465             CheckRange(nStartIndex, nEndIndex);
2466 
2467             //Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2468             sal_Int32 nBulletLen = 0;
2469             EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() );
2470             if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2471                         nBulletLen = aBulletInfo.aText.Len();
2472             // save current selection
2473             ESelection aOldSelection;
2474 
2475             rCacheVF.GetSelection( aOldSelection );
2476             //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2477             rCacheVF.SetSelection( MakeSelection(nStartIndex + nBulletLen, nEndIndex + nBulletLen) );
2478             aRetVal = rCacheVF.Copy();
2479             rCacheVF.SetSelection( aOldSelection ); // restore
2480 
2481             return aRetVal;
2482         }
2483         catch( const uno::RuntimeException& )
2484         {
2485             return sal_False;
2486         }
2487     }
2488 
2489 	// XAccessibleEditableText
cutText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)2490     sal_Bool SAL_CALL AccessibleEditableTextPara::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2491     {
2492         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2493 
2494         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2495 
2496         try
2497         {
2498             SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
2499             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
2500 
2501             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2502                        "AccessibleEditableTextPara::cutText: index value overflow");
2503 
2504             CheckRange(nStartIndex, nEndIndex);
2505 
2506             // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2507             sal_Int32 nBulletLen = 0;
2508             EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() );
2509             if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2510                         nBulletLen = aBulletInfo.aText.Len();
2511             ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen);
2512             if( !rCacheTF.IsEditable( aSelection ) )
2513                 return sal_False; // non-editable area selected
2514 
2515             // don't save selection, might become invalid after cut!
2516             //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2517             rCacheVF.SetSelection( aSelection );
2518 
2519             return rCacheVF.Cut();
2520         }
2521         catch( const uno::RuntimeException& )
2522         {
2523             return sal_False;
2524         }
2525     }
2526 
pasteText(sal_Int32 nIndex)2527     sal_Bool SAL_CALL AccessibleEditableTextPara::pasteText( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2528     {
2529         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2530 
2531         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2532 
2533         try
2534         {
2535             SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
2536             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
2537 
2538             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2539                        "AccessibleEditableTextPara::pasteText: index value overflow");
2540 
2541             CheckPosition(nIndex);
2542 
2543             // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2544             sal_Int32 nBulletLen = 0;
2545             EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() );
2546             if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2547                         nBulletLen = aBulletInfo.aText.Len();
2548             //if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) )
2549             if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) )
2550                 return sal_False; // non-editable area selected
2551 
2552             // #104400# set empty selection (=> cursor) to given index
2553             //rCacheVF.SetSelection( MakeCursor(nIndex) );
2554             rCacheVF.SetSelection( MakeCursor(nIndex + nBulletLen) );
2555 
2556             return rCacheVF.Paste();
2557         }
2558         catch( const uno::RuntimeException& )
2559         {
2560             return sal_False;
2561         }
2562     }
2563 
deleteText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)2564     sal_Bool SAL_CALL AccessibleEditableTextPara::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2565     {
2566         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2567 
2568         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2569 
2570         try
2571         {
2572             // #102710# Request edit view when doing changes
2573             // AccessibleEmptyEditSource relies on this behaviour
2574             GetEditViewForwarder( sal_True );
2575             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
2576 
2577             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2578                        "AccessibleEditableTextPara::deleteText: index value overflow");
2579 
2580             CheckRange(nStartIndex, nEndIndex);
2581 
2582             // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2583             sal_Int32 nBulletLen = 0;
2584             EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() );
2585             if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2586                         nBulletLen = aBulletInfo.aText.Len();
2587             ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen);
2588 
2589             //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2590             if( !rCacheTF.IsEditable( aSelection ) )
2591                 return sal_False; // non-editable area selected
2592 
2593             //sal_Bool bRet = rCacheTF.Delete( MakeSelection(nStartIndex, nEndIndex) );
2594             sal_Bool bRet = rCacheTF.Delete( aSelection );
2595 
2596             GetEditSource().UpdateData();
2597 
2598             return bRet;
2599         }
2600         catch( const uno::RuntimeException& )
2601         {
2602             return sal_False;
2603         }
2604     }
2605 
insertText(const::rtl::OUString & sText,sal_Int32 nIndex)2606     sal_Bool SAL_CALL AccessibleEditableTextPara::insertText( const ::rtl::OUString& sText, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2607     {
2608         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2609 
2610         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2611 
2612         try
2613         {
2614             // #102710# Request edit view when doing changes
2615             // AccessibleEmptyEditSource relies on this behaviour
2616             GetEditViewForwarder( sal_True );
2617             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
2618 
2619             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2620                        "AccessibleEditableTextPara::insertText: index value overflow");
2621 
2622             CheckPosition(nIndex);
2623 
2624             // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2625             sal_Int32 nBulletLen = 0;
2626             EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() );
2627             if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2628                         nBulletLen = aBulletInfo.aText.Len();
2629 
2630             //if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) )
2631             if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) )
2632                 return sal_False; // non-editable area selected
2633 
2634             // #104400# insert given text at empty selection (=> cursor)
2635             //sal_Bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex) );
2636             sal_Bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex + nBulletLen) );
2637 
2638             rCacheTF.QuickFormatDoc();
2639             GetEditSource().UpdateData();
2640 
2641             return bRet;
2642         }
2643         catch( const uno::RuntimeException& )
2644         {
2645             return sal_False;
2646         }
2647     }
2648 
replaceText(sal_Int32 nStartIndex,sal_Int32 nEndIndex,const::rtl::OUString & sReplacement)2649     sal_Bool SAL_CALL AccessibleEditableTextPara::replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const ::rtl::OUString& sReplacement ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2650     {
2651         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2652 
2653         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2654 
2655         try
2656         {
2657             // #102710# Request edit view when doing changes
2658             // AccessibleEmptyEditSource relies on this behaviour
2659             GetEditViewForwarder( sal_True );
2660             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
2661 
2662             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2663                        "AccessibleEditableTextPara::replaceText: index value overflow");
2664 
2665             CheckRange(nStartIndex, nEndIndex);
2666 
2667             // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2668             sal_Int32 nBulletLen = 0;
2669             EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( GetParagraphIndex() );
2670             if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2671                         nBulletLen = aBulletInfo.aText.Len();
2672             ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen);
2673 
2674             //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2675             if( !rCacheTF.IsEditable( aSelection ) )
2676                 return sal_False; // non-editable area selected
2677 
2678             // insert given text into given range => replace
2679             //sal_Bool bRet = rCacheTF.InsertText( sReplacement, MakeSelection(nStartIndex, nEndIndex) );
2680             sal_Bool bRet = rCacheTF.InsertText( sReplacement, aSelection );
2681 
2682             rCacheTF.QuickFormatDoc();
2683             GetEditSource().UpdateData();
2684 
2685             return bRet;
2686         }
2687         catch( const uno::RuntimeException& )
2688         {
2689             return sal_False;
2690         }
2691     }
2692 
setAttributes(sal_Int32 nStartIndex,sal_Int32 nEndIndex,const uno::Sequence<beans::PropertyValue> & aAttributeSet)2693     sal_Bool SAL_CALL AccessibleEditableTextPara::setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const uno::Sequence< beans::PropertyValue >& aAttributeSet ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2694     {
2695         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2696 
2697         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2698 
2699         try
2700         {
2701             // #102710# Request edit view when doing changes
2702             // AccessibleEmptyEditSource relies on this behaviour
2703             GetEditViewForwarder( sal_True );
2704             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
2705             sal_uInt32 nPara = GetParagraphIndex();
2706 
2707             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2708                        "AccessibleEditableTextPara::setAttributes: index value overflow");
2709 
2710             CheckRange(nStartIndex, nEndIndex);
2711 
2712             if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2713                 return sal_False; // non-editable area selected
2714 
2715             // do the indices span the whole paragraph? Then use the outliner map
2716             // TODO: hold it as a member?
2717             SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
2718                                                    0 == nStartIndex &&
2719                                                    rCacheTF.GetTextLen(nPara) == nEndIndex ?
2720                                                    ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() :
2721                                                    ImplGetSvxTextPortionSvxPropertySet() );
2722 
2723             aPropSet.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2724 
2725             // convert from PropertyValue to Any
2726             sal_Int32 i, nLength( aAttributeSet.getLength() );
2727             const beans::PropertyValue*	pPropArray = aAttributeSet.getConstArray();
2728             for(i=0; i<nLength; ++i)
2729             {
2730                 try
2731                 {
2732                     aPropSet.setPropertyValue(pPropArray->Name, pPropArray->Value);
2733                 }
2734                 catch( const uno::Exception& )
2735                 {
2736                     DBG_ERROR("AccessibleEditableTextPara::setAttributes exception in setPropertyValue");
2737                 }
2738 
2739                 ++pPropArray;
2740             }
2741 
2742             rCacheTF.QuickFormatDoc();
2743             GetEditSource().UpdateData();
2744 
2745             return sal_True;
2746         }
2747         catch( const uno::RuntimeException& )
2748         {
2749             return sal_False;
2750         }
2751     }
2752 
setText(const::rtl::OUString & sText)2753     sal_Bool SAL_CALL AccessibleEditableTextPara::setText( const ::rtl::OUString& sText ) throw (uno::RuntimeException)
2754     {
2755         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2756 
2757         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2758 
2759         return replaceText(0, getCharacterCount(), sText);
2760     }
2761 
2762     // XAccessibleTextAttributes
getDefaultAttributes(const uno::Sequence<::rtl::OUString> & rRequestedAttributes)2763     uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getDefaultAttributes(
2764             const uno::Sequence< ::rtl::OUString >& rRequestedAttributes )
2765         throw (uno::RuntimeException)
2766     {
2767         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2768         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2769 
2770         #if OSL_DEBUG_LEVEL > 0
2771         SvxAccessibleTextAdapter& rCacheTF =
2772         #endif
2773             GetTextForwarder();
2774 
2775         #if OSL_DEBUG_LEVEL > 0
2776         (void)rCacheTF;
2777         #endif
2778 
2779         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2780                    "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
2781 
2782         // get XPropertySetInfo for paragraph attributes and
2783         // character attributes that span all the paragraphs text.
2784         SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
2785                 ImplGetSvxCharAndParaPropertiesSet() );
2786         aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) );
2787         uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo();
2788         if (!xPropSetInfo.is())
2789             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot query XPropertySetInfo")),
2790                         uno::Reference< uno::XInterface >
2791                         ( static_cast< XAccessible* > (this) ) );   // disambiguate hierarchy
2792 
2793         // build sequence of available properties to check
2794         sal_Int32 nLenReqAttr = rRequestedAttributes.getLength();
2795         uno::Sequence< beans::Property > aProperties;
2796         if (nLenReqAttr)
2797         {
2798             const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray();
2799 
2800             aProperties.realloc( nLenReqAttr );
2801             beans::Property *pProperties = aProperties.getArray();
2802             sal_Int32 nCurLen = 0;
2803             for (sal_Int32 i = 0;  i < nLenReqAttr;  ++i)
2804             {
2805                 beans::Property aProp;
2806                 try
2807                 {
2808                     aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] );
2809                 }
2810                 catch (beans::UnknownPropertyException &)
2811                 {
2812                     continue;
2813                 }
2814                 pProperties[ nCurLen++ ] = aProp;
2815             }
2816             aProperties.realloc( nCurLen );
2817         }
2818         else
2819             aProperties = xPropSetInfo->getProperties();
2820 
2821         sal_Int32 nLength = aProperties.getLength();
2822         const beans::Property *pProperties = aProperties.getConstArray();
2823 
2824         // build resulting sequence
2825         uno::Sequence< beans::PropertyValue > aOutSequence( nLength );
2826         beans::PropertyValue* pOutSequence = aOutSequence.getArray();
2827         sal_Int32 nOutLen = 0;
2828         for (sal_Int32 i = 0;  i < nLength;  ++i)
2829         {
2830             // calling implementation functions:
2831             // _getPropertyState and _getPropertyValue (see below) to provide
2832             // the proper paragraph number when retrieving paragraph attributes
2833             PropertyState eState = aPropSet._getPropertyState( pProperties->Name, mnParagraphIndex );
2834             if ( eState == PropertyState_AMBIGUOUS_VALUE )
2835             {
2836                 OSL_ENSURE( false, "ambiguous property value encountered" );
2837             }
2838 
2839             //if (eState == PropertyState_DIRECT_VALUE)
2840             // per definition all paragraph properties and all character
2841             // properties spanning the whole paragraph should be returned
2842             // and declared as default value
2843             {
2844                 pOutSequence->Name      = pProperties->Name;
2845                 pOutSequence->Handle    = pProperties->Handle;
2846                 pOutSequence->Value     = aPropSet._getPropertyValue( pProperties->Name, mnParagraphIndex );
2847                 pOutSequence->State     = PropertyState_DEFAULT_VALUE;
2848 
2849                 ++pOutSequence;
2850                 ++nOutLen;
2851             }
2852             ++pProperties;
2853         }
2854         aOutSequence.realloc( nOutLen );
2855 
2856         return aOutSequence;
2857     }
2858 
2859 
getRunAttributes(sal_Int32 nIndex,const uno::Sequence<::rtl::OUString> & rRequestedAttributes)2860     uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getRunAttributes(
2861             sal_Int32 nIndex,
2862             const uno::Sequence< ::rtl::OUString >& rRequestedAttributes )
2863         throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2864     {
2865         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2866 
2867         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2868 
2869         #if OSL_DEBUG_LEVEL > 0
2870         SvxAccessibleTextAdapter& rCacheTF =
2871         #endif
2872             GetTextForwarder();
2873 
2874         #if OSL_DEBUG_LEVEL > 0
2875         (void)rCacheTF;
2876         #endif
2877 
2878         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2879                    "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
2880 
2881 		if( getCharacterCount() > 0 )
2882 			CheckIndex(nIndex);
2883 		else
2884 			CheckPosition(nIndex);
2885 
2886         SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
2887                                                ImplGetSvxCharAndParaPropertiesSet() );
2888         aPropSet.SetSelection( MakeSelection( nIndex ) );
2889         uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo();
2890         if (!xPropSetInfo.is())
2891             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot query XPropertySetInfo")),
2892                                         uno::Reference< uno::XInterface >
2893                                         ( static_cast< XAccessible* > (this) ) );   // disambiguate hierarchy
2894 
2895         // build sequence of available properties to check
2896         sal_Int32 nLenReqAttr = rRequestedAttributes.getLength();
2897         uno::Sequence< beans::Property > aProperties;
2898         if (nLenReqAttr)
2899         {
2900             const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray();
2901 
2902             aProperties.realloc( nLenReqAttr );
2903             beans::Property *pProperties = aProperties.getArray();
2904             sal_Int32 nCurLen = 0;
2905             for (sal_Int32 i = 0;  i < nLenReqAttr;  ++i)
2906             {
2907                 beans::Property aProp;
2908                 try
2909                 {
2910                     aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] );
2911                 }
2912                 catch (beans::UnknownPropertyException &)
2913                 {
2914                     continue;
2915                 }
2916                 pProperties[ nCurLen++ ] = aProp;
2917             }
2918             aProperties.realloc( nCurLen );
2919         }
2920         else
2921             aProperties = xPropSetInfo->getProperties();
2922 
2923         sal_Int32 nLength = aProperties.getLength();
2924         const beans::Property *pProperties = aProperties.getConstArray();
2925 
2926         // build resulting sequence
2927         uno::Sequence< beans::PropertyValue > aOutSequence( nLength );
2928         beans::PropertyValue* pOutSequence = aOutSequence.getArray();
2929         sal_Int32 nOutLen = 0;
2930         for (sal_Int32 i = 0;  i < nLength;  ++i)
2931         {
2932             // calling 'regular' functions that will operate on the selection
2933             PropertyState eState = aPropSet.getPropertyState( pProperties->Name );
2934             if (eState == PropertyState_DIRECT_VALUE)
2935             {
2936                 pOutSequence->Name      = pProperties->Name;
2937                 pOutSequence->Handle    = pProperties->Handle;
2938                 pOutSequence->Value     = aPropSet.getPropertyValue( pProperties->Name );
2939                 pOutSequence->State     = eState;
2940 
2941                 ++pOutSequence;
2942                 ++nOutLen;
2943             }
2944             ++pProperties;
2945         }
2946         aOutSequence.realloc( nOutLen );
2947 
2948         return aOutSequence;
2949     }
2950 
2951     // XAccessibleHypertext
getHyperLinkCount()2952     ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkCount(  ) throw (::com::sun::star::uno::RuntimeException)
2953     {
2954         SvxAccessibleTextAdapter& rT = GetTextForwarder();
2955         const sal_Int32 nPara = GetParagraphIndex();
2956 
2957         sal_uInt16 nHyperLinks = 0;
2958         sal_uInt16 nFields = rT.GetFieldCount( nPara );
2959         for ( sal_uInt16 n = 0; n < nFields; n++ )
2960         {
2961             EFieldInfo aField = rT.GetFieldInfo( nPara, n );
2962             if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
2963                 nHyperLinks++;
2964         }
2965         return nHyperLinks;
2966     }
2967 
getHyperLink(::sal_Int32 nLinkIndex)2968     ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleHyperlink > SAL_CALL AccessibleEditableTextPara::getHyperLink( ::sal_Int32 nLinkIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
2969     {
2970         ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleHyperlink > xRef;
2971 
2972         SvxAccessibleTextAdapter& rT = GetTextForwarder();
2973         const sal_Int32 nPara = GetParagraphIndex();
2974 
2975         sal_uInt16 nHyperLink = 0;
2976         sal_uInt16 nFields = rT.GetFieldCount( nPara );
2977         for ( sal_uInt16 n = 0; n < nFields; n++ )
2978         {
2979             EFieldInfo aField = rT.GetFieldInfo( nPara, n );
2980             if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
2981             {
2982                 if ( nHyperLink == nLinkIndex )
2983                 {
2984                     sal_uInt16 nEEStart = aField.aPosition.nIndex;
2985 
2986                     // Translate EE Index to accessible index
2987                     sal_uInt16 nStart = rT.CalcEditEngineIndex( nPara, nEEStart );
2988                     sal_uInt16 nEnd = nStart + aField.aCurrentText.Len();
2989                     xRef = new AccessibleHyperlink( rT, new SvxFieldItem( *aField.pFieldItem ), nPara, nEEStart, nStart, nEnd, aField.aCurrentText );
2990                     break;
2991                 }
2992                 nHyperLink++;
2993             }
2994         }
2995 
2996         return xRef;
2997     }
2998 
getHyperLinkIndex(::sal_Int32 nCharIndex)2999     ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkIndex( ::sal_Int32 nCharIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
3000     {
3001         const sal_Int32 nPara = GetParagraphIndex();
3002         SvxAccessibleTextAdapter& rT = GetTextForwarder();
3003 
3004 //        SvxAccessibleTextIndex aIndex;
3005 //        aIndex.SetIndex(nPara, nCharIndex, rT);
3006 //        const sal_uInt16 nEEIndex = aIndex.GetEEIndex();
3007 
3008         const sal_uInt16 nEEIndex = rT.CalcEditEngineIndex( nPara, nCharIndex );
3009         sal_Int32 nHLIndex = -1; //i123620
3010         sal_uInt16 nHyperLink = 0;
3011         sal_uInt16 nFields = rT.GetFieldCount( nPara );
3012         for ( sal_uInt16 n = 0; n < nFields; n++ )
3013         {
3014             EFieldInfo aField = rT.GetFieldInfo( nPara, n );
3015             if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
3016             {
3017                 if ( aField.aPosition.nIndex == nEEIndex )
3018                 {
3019                     nHLIndex = nHyperLink;
3020                     break;
3021                 }
3022                 nHyperLink++;
3023             }
3024         }
3025 
3026         return nHLIndex;
3027     }
3028 
3029     // XAccessibleMultiLineText
getLineNumberAtIndex(sal_Int32 nIndex)3030     sal_Int32 SAL_CALL AccessibleEditableTextPara::getLineNumberAtIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
3031     {
3032         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3033 
3034         sal_Int32 nRes = -1;
3035         sal_Int32 nPara = GetParagraphIndex();
3036 
3037         SvxTextForwarder &rCacheTF = GetTextForwarder();
3038         const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
3039         DBG_ASSERT( bValidPara, "getLineNumberAtIndex: current paragraph index out of range" );
3040         if (bValidPara)
3041         {
3042             // we explicitly allow for the index to point at the character right behind the text
3043             if (0 <= nIndex && nIndex <= rCacheTF.GetTextLen( nPara ))
3044                 nRes = rCacheTF.GetLineNumberAtIndex( nPara, static_cast< sal_uInt16 >(nIndex) );
3045             else
3046                 throw lang::IndexOutOfBoundsException();
3047         }
3048         return nRes;
3049     }
3050 
3051     // XAccessibleMultiLineText
getTextAtLineNumber(sal_Int32 nLineNo)3052     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineNumber( sal_Int32 nLineNo ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
3053     {
3054         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3055 
3056         ::com::sun::star::accessibility::TextSegment aResult;
3057         sal_Int32 nPara = GetParagraphIndex();
3058         SvxTextForwarder &rCacheTF = GetTextForwarder();
3059         const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
3060         DBG_ASSERT( bValidPara, "getTextAtLineNumber: current paragraph index out of range" );
3061         if (bValidPara)
3062         {
3063             if (0 <= nLineNo && nLineNo < rCacheTF.GetLineCount( nPara ))
3064             {
3065                 sal_uInt16 nStart = 0, nEnd = 0;
3066                 rCacheTF.GetLineBoundaries( nStart, nEnd, nPara, static_cast< sal_uInt16 >(nLineNo) );
3067                 if (nStart != 0xFFFF && nEnd != 0xFFFF)
3068                 {
3069                     try
3070                     {
3071                         aResult.SegmentText     = getTextRange( nStart, nEnd );
3072                         aResult.SegmentStart    = nStart;
3073                         aResult.SegmentEnd      = nEnd;
3074                     }
3075                     catch (lang::IndexOutOfBoundsException)
3076                     {
3077                         // this is not the exception that should be raised in this function ...
3078                         DBG_ASSERT( 0, "unexpected exception" );
3079                     }
3080                 }
3081             }
3082             else
3083                 throw lang::IndexOutOfBoundsException();
3084         }
3085         return aResult;
3086     }
3087 
3088     // XAccessibleMultiLineText
getTextAtLineWithCaret()3089     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineWithCaret(  ) throw (uno::RuntimeException)
3090     {
3091         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3092 
3093         ::com::sun::star::accessibility::TextSegment aResult;
3094         try
3095         {
3096             aResult = getTextAtLineNumber( getNumberOfLineWithCaret() );
3097         }
3098         catch (lang::IndexOutOfBoundsException &)
3099         {
3100             // this one needs to be catched since this interface does not allow for it.
3101         }
3102         return aResult;
3103     }
3104 
3105     // XAccessibleMultiLineText
getNumberOfLineWithCaret()3106     sal_Int32 SAL_CALL AccessibleEditableTextPara::getNumberOfLineWithCaret(  ) throw (uno::RuntimeException)
3107     {
3108         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3109 
3110         sal_Int32 nRes = -1;
3111         try
3112         {
3113             nRes = getLineNumberAtIndex( getCaretPosition() );
3114         }
3115         catch (lang::IndexOutOfBoundsException &)
3116         {
3117             // this one needs to be catched since this interface does not allow for it.
3118         }
3119         return nRes;
3120     }
3121 
3122 
3123 	// XServiceInfo
getImplementationName(void)3124     ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getImplementationName (void) throw (uno::RuntimeException)
3125     {
3126         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3127 
3128         return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("AccessibleEditableTextPara"));
3129     }
3130 
supportsService(const::rtl::OUString & sServiceName)3131     sal_Bool SAL_CALL AccessibleEditableTextPara::supportsService (const ::rtl::OUString& sServiceName) throw (uno::RuntimeException)
3132     {
3133         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3134 
3135         //  Iterate over all supported service names and return true if on of them
3136         //  matches the given name.
3137         uno::Sequence< ::rtl::OUString> aSupportedServices (
3138             getSupportedServiceNames ());
3139         for (int i=0; i<aSupportedServices.getLength(); i++)
3140             if (sServiceName == aSupportedServices[i])
3141                 return sal_True;
3142         return sal_False;
3143     }
3144 
getSupportedServiceNames(void)3145     uno::Sequence< ::rtl::OUString> SAL_CALL AccessibleEditableTextPara::getSupportedServiceNames (void) throw (uno::RuntimeException)
3146     {
3147         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3148 
3149         const ::rtl::OUString sServiceName( getServiceName() );
3150         return uno::Sequence< ::rtl::OUString > (&sServiceName, 1);
3151     }
3152 
3153 	// XServiceName
getServiceName(void)3154     ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getServiceName (void) throw (uno::RuntimeException)
3155     {
3156         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3157 
3158         // #105185# Using correct service now
3159         return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.AccessibleParagraphView"));
3160     }
3161 
3162 }  // end of namespace accessibility
3163 
3164 //------------------------------------------------------------------------
3165