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( static_cast< sal_uInt16 >( 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( static_cast< sal_uInt16 >( nParaIndex ) );
241 
242         CheckPosition(nIndex);
243 
244         rBoundary.startPos = rBoundary.endPos = -1;
245 
246         const sal_uInt16 nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( 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( static_cast< sal_uInt16 >( 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( static_cast< sal_uInt16 >( nParaIndex ), nLine);
267 
268                 if( nCurIndex > nIndex )
269                 {
270                     rBoundary.startPos = nCurIndex - rCacheTF.GetLineLen(static_cast< sal_uInt16 >( 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_uInt16 nParaIndex = static_cast< sal_uInt16 >( 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_uInt16 nPara = static_cast< sal_uInt16 > ( 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( static_cast< sal_uInt16 >( 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( static_cast< sal_uInt16 >(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 wether 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() <= USHRT_MAX,
801                    "AccessibleEditableTextPara::getLocale: paragraph index value overflow");
802 
803         return GetTextForwarder().GetAttributeRun( nStartIndex,
804                                                    nEndIndex,
805                                                    static_cast< sal_uInt16 >(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( static_cast< sal_uInt16 > (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( static_cast< sal_uInt16 >( 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( static_cast< sal_uInt16 >(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(sal_uInt16(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(sal_uInt16(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( static_cast< sal_uInt16 >(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 accoring 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( static_cast< sal_uInt16 >( 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_uInt16 nPara, nIndex;
1626 
1627         // offset from surrounding cell/shape
1628         Point aOffset( GetEEOffset() );
1629         Point aPoint( rPoint.X - aOffset.X(), rPoint.Y - aOffset.Y() );
1630 
1631         // convert to logical coordinates
1632         SvxTextForwarder& rCacheTF = GetTextForwarder();
1633         Point aLogPoint( GetViewForwarder().PixelToLogic( aPoint, rCacheTF.GetMapMode() ) );
1634 
1635         // re-offset to parent (paragraph)
1636         Rectangle aParaRect = rCacheTF.GetParaBounds( static_cast< sal_uInt16 >( GetParagraphIndex() ) );
1637         aLogPoint.Move( aParaRect.Left(), aParaRect.Top() );
1638 
1639         if( rCacheTF.GetIndexAtPoint( aLogPoint, nPara, nIndex ) &&
1640             GetParagraphIndex() == nPara )
1641         {
1642             // #102259# Double-check if we're _really_ on the given character
1643             try
1644             {
1645                 awt::Rectangle aRect1( getCharacterBounds(nIndex) );
1646                 Rectangle aRect2( aRect1.X, aRect1.Y,
1647                                   aRect1.Width + aRect1.X, aRect1.Height + aRect1.Y );
1648                 if( aRect2.IsInside( Point( rPoint.X, rPoint.Y ) ) )
1649                     return nIndex;
1650                 else
1651                     return -1;
1652             }
1653             catch( const lang::IndexOutOfBoundsException& )
1654             {
1655                 // #103927# Don't throw for invalid nIndex values
1656                 return -1;
1657             }
1658         }
1659         else
1660         {
1661             // not within our paragraph
1662             return -1;
1663         }
1664     }
1665 
getSelectedText()1666     ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getSelectedText() throw (uno::RuntimeException)
1667     {
1668         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1669 
1670         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1671 
1672         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1673                    "AccessibleEditableTextPara::getSelectedText: index value overflow");
1674 
1675         if( !HaveEditView() )
1676             return ::rtl::OUString();
1677 
1678         return OCommonAccessibleText::getSelectedText();
1679     }
1680 
getSelectionStart()1681     sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionStart() throw (uno::RuntimeException)
1682     {
1683         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1684 
1685         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1686 
1687         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1688                    "AccessibleEditableTextPara::getSelectionStart: index value overflow");
1689 
1690         if( !HaveEditView() )
1691             return -1;
1692 
1693         return OCommonAccessibleText::getSelectionStart();
1694     }
1695 
getSelectionEnd()1696     sal_Int32 SAL_CALL AccessibleEditableTextPara::getSelectionEnd() throw (uno::RuntimeException)
1697     {
1698         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1699 
1700         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1701 
1702         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1703                    "AccessibleEditableTextPara::getSelectionEnd: index value overflow");
1704 
1705         if( !HaveEditView() )
1706             return -1;
1707 
1708         return OCommonAccessibleText::getSelectionEnd();
1709     }
1710 
setSelection(sal_Int32 nStartIndex,sal_Int32 nEndIndex)1711     sal_Bool SAL_CALL AccessibleEditableTextPara::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1712     {
1713         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1714 
1715         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1716 
1717         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1718                    "AccessibleEditableTextPara::setSelection: paragraph index value overflow");
1719 
1720         CheckRange(nStartIndex, nEndIndex);
1721 
1722         try
1723         {
1724             SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
1725             return rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
1726         }
1727         catch( const uno::RuntimeException& )
1728         {
1729             return sal_False;
1730         }
1731     }
1732 
getText()1733     ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getText() throw (uno::RuntimeException)
1734     {
1735         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1736 
1737         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1738 
1739         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1740                    "AccessibleEditableTextPara::getText: paragraph index value overflow");
1741 
1742         return OCommonAccessibleText::getText();
1743     }
1744 
getTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)1745     ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1746     {
1747         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
1748 
1749         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1750 
1751         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
1752                    "AccessibleEditableTextPara::getTextRange: paragraph index value overflow");
1753 
1754         return OCommonAccessibleText::getTextRange(nStartIndex, nEndIndex);
1755     }
_correctValues(const sal_Int32,uno::Sequence<PropertyValue> & rValues)1756 	void AccessibleEditableTextPara::_correctValues( const sal_Int32 /* nIndex */,
1757 										   uno::Sequence< PropertyValue >& rValues)
1758 	{
1759 		SvxTextForwarder& rCacheTF = GetTextForwarder();
1760 		sal_Int32 nRes = rValues.getLength();
1761 		beans::PropertyValue *pRes = rValues.getArray();
1762 		for (sal_Int32 i = 0;  i < nRes;  ++i)
1763 		{
1764 			beans::PropertyValue &rRes = pRes[i];
1765 			// Char color
1766 			if (rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharColor"))==0)
1767 			{
1768 				uno::Any &anyChar = rRes.Value;
1769 				sal_uInt32 crChar = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved));
1770 				if (COL_AUTO == crChar )
1771 				{
1772 					uno::Reference< ::com::sun::star::accessibility::XAccessibleComponent > xComponent;
1773 					if (mxParent.is())
1774 					{
1775 						xComponent.set(mxParent,uno::UNO_QUERY);
1776 					}
1777 					else
1778 					{
1779 						xComponent.set(m_xAccInfo,uno::UNO_QUERY);
1780 					}
1781 					if (xComponent.is())
1782 					{
1783 						uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY);
1784 						if (xContext->getAccessibleRole() == AccessibleRole::SHAPE
1785 							|| xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL)
1786 						{
1787 							anyChar <<= COL_BLACK;
1788 						}
1789 						else
1790 						{
1791 							Color cr(xComponent->getBackground());
1792 							crChar = cr.IsDark() ? COL_WHITE : COL_BLACK;
1793 							anyChar <<= crChar;
1794 						}
1795 					}
1796 				}
1797 				continue;
1798 			}
1799 			// Underline
1800 			if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharUnderline"))==0)
1801 			{
1802 				/*
1803 				// MT: Implement XAccessibleTextMarkup, mark with TextMarkupType::SPELLCHECK. This way done in SW.
1804 				if (IsCurrentEditorEnableAutoSpell( mxParent ))
1805 				{
1806 					try
1807 					{
1808 						SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_False );
1809 						sal_Bool bWrong = rCacheVF.IsWrongSpelledWordAtPos( GetParagraphIndex(), nIndex );
1810 						if ( bWrong )
1811 						{
1812 							uno::Any &anyUnderLine = pRes[9].Value;
1813 							// MT IA2: Not needed? sal_uInt16 crUnderLine = (sal_uInt16)(anyUnderLine.pReserved);
1814 							anyUnderLine <<= (sal_uInt16)UNDERLINE_WAVE;
1815 						}
1816 					}
1817 					catch( const uno::RuntimeException& )
1818 					{
1819 					}
1820 				}
1821 				*/
1822 				continue;
1823 			}
1824 			// Underline color && Mis-spell
1825 			if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("CharUnderlineColor"))==0)
1826 			{
1827 				uno::Any &anyCharUnderLine = rRes.Value;
1828 				sal_uInt32 crCharUnderLine = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>( anyCharUnderLine.pReserved));
1829 				if (COL_AUTO == crCharUnderLine )
1830 				{
1831 					uno::Reference< ::com::sun::star::accessibility::XAccessibleComponent > xComponent;
1832 					if (mxParent.is())
1833 					{
1834 						xComponent.set(mxParent,uno::UNO_QUERY);
1835 					}
1836 					else
1837 					{
1838 						xComponent.set(m_xAccInfo,uno::UNO_QUERY);
1839 					}
1840 					if (xComponent.is())
1841 					{
1842 						uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > xContext(xComponent,uno::UNO_QUERY);
1843 						if (xContext->getAccessibleRole() == AccessibleRole::SHAPE
1844 							|| xContext->getAccessibleRole() == AccessibleRole::TABLE_CELL)
1845 						{
1846 							anyCharUnderLine <<= COL_BLACK;
1847 						}
1848 						else
1849 						{
1850 							Color cr(xComponent->getBackground());
1851 							crCharUnderLine = cr.IsDark() ? COL_WHITE : COL_BLACK;
1852 							anyCharUnderLine <<= crCharUnderLine;
1853 						}
1854 					}
1855 				}
1856 				// MT: Implement XAccessibleTextMarkup, mark with TextMarkupType::SPELLCHECK. This way done in SW.
1857 				/*
1858 				if (IsCurrentEditorEnableAutoSpell( mxParent ))
1859 				{
1860 					try
1861 					{
1862 						SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_False );
1863 						sal_Bool bWrong = rCacheVF.IsWrongSpelledWordAtPos( GetParagraphIndex(), nIndex );
1864 						if ( bWrong )
1865 						{
1866 							uno::Any &anyUnderLineColor = rRes.Value;
1867 							// MT IA2: Not needed? sal_uInt16 crUnderLineColor = (sal_uInt16)(anyUnderLineColor.pReserved);
1868 							anyUnderLineColor <<= COL_LIGHTRED;
1869 						}
1870 					}
1871 					catch( const uno::RuntimeException& )
1872 					{
1873 					}
1874 				}
1875 				*/
1876 				continue;
1877 			}
1878 			// NumberingLevel
1879 			if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("NumberingLevel"))==0)
1880 			{
1881 				const SvxNumBulletItem& rNumBullet = ( SvxNumBulletItem& )rCacheTF.GetParaAttribs(static_cast< sal_uInt16 >(GetParagraphIndex())).Get(EE_PARA_NUMBULLET);
1882 				if(rNumBullet.GetNumRule()->GetLevelCount()==0)
1883 				{
1884 					rRes.Value <<= (sal_Int16)-1;
1885 					rRes.Handle = -1;
1886 					rRes.State = PropertyState_DIRECT_VALUE;
1887 				}
1888 				else
1889 				{
1890 //					SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
1891 //						ImplGetSvxCharAndParaPropertiesMap() );
1892 					// MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap
1893             		SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() );
1894 
1895 					aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) );
1896 					rRes.Value = aPropSet._getPropertyValue( rRes.Name, mnParagraphIndex );
1897 					rRes.State = aPropSet._getPropertyState( rRes.Name, mnParagraphIndex );
1898 					rRes.Handle = -1;
1899 				}
1900 				continue;
1901 			}
1902 			// NumberingRules
1903 			if(rRes.Name.compareTo(::rtl::OUString::createFromAscii("NumberingRules"))==0)
1904 			{
1905 				SfxItemSet aAttribs = rCacheTF.GetParaAttribs( static_cast< sal_uInt16 >(GetParagraphIndex()) );
1906 				sal_Bool bVis = ((const SfxUInt16Item&)aAttribs.Get( EE_PARA_BULLETSTATE )).GetValue() ? sal_True : sal_False;
1907 				if(bVis)
1908 				{
1909 					rRes.Value <<= (sal_Int16)-1;
1910 					rRes.Handle = -1;
1911 					rRes.State = PropertyState_DIRECT_VALUE;
1912 				}
1913 				else
1914 				{
1915 					// MT IA2 TODO: Check if this is the correct replacement for ImplGetSvxCharAndParaPropertiesMap
1916             		SvxAccessibleTextPropertySet aPropSet( &GetEditSource(), ImplGetSvxTextPortionSvxPropertySet() );
1917 					aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) );
1918 					rRes.Value = aPropSet._getPropertyValue( rRes.Name, mnParagraphIndex );
1919 					rRes.State = aPropSet._getPropertyState( rRes.Name, mnParagraphIndex );
1920 					rRes.Handle = -1;
1921 				}
1922 				continue;
1923 			}
1924 		}
1925 	}
SkipField(sal_Int32 nIndex,sal_Bool bForward)1926     sal_Int32 AccessibleEditableTextPara::SkipField(sal_Int32 nIndex, sal_Bool bForward)
1927     {
1928 		sal_Int32 nParaIndex = GetParagraphIndex();
1929 		SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();
1930 		sal_Int32 nAllFieldLen = 0;
1931 		sal_Int32 nField = rCacheTF.GetFieldCount(sal_uInt16(nParaIndex)), nFoundFieldIndex = -1;
1932 		EFieldInfo ree;
1933 		sal_Int32  reeBegin=0, reeEnd=0;
1934 		for(sal_uInt16 j = 0; j < nField; j++)
1935 		{
1936 			ree = rCacheTF.GetFieldInfo(sal_uInt16(nParaIndex), j);
1937 			reeBegin  = ree.aPosition.nIndex + nAllFieldLen;
1938 			reeEnd = reeBegin + ree.aCurrentText.Len();
1939 			nAllFieldLen += (ree.aCurrentText.Len() - 1);
1940 			if( reeBegin > nIndex )
1941 			{
1942 				break;
1943 			}
1944 			if(  nIndex >= reeBegin && nIndex < reeEnd )
1945 			{
1946 				if(ree.pFieldItem->GetField()->GetClassId() != SVX_URLFIELD)
1947 				{
1948 					nFoundFieldIndex = j;
1949 					break;
1950 				}
1951 			}
1952 		}
1953 		if( nFoundFieldIndex >= 0  )
1954 		{
1955 			if( bForward )
1956 				return reeEnd - 1;
1957 			else
1958 				return reeBegin;
1959 		}
1960 		return nIndex;
1961     }
ExtendByField(::com::sun::star::accessibility::TextSegment & Segment)1962     sal_Bool AccessibleEditableTextPara::ExtendByField( ::com::sun::star::accessibility::TextSegment& Segment )
1963     {
1964 		sal_Int32 nParaIndex = GetParagraphIndex();
1965 		SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();
1966 		sal_Int32 nAllFieldLen = 0;
1967 		sal_Int32 nField = rCacheTF.GetFieldCount(sal_uInt16(nParaIndex)), nFoundFieldIndex = -1;
1968 		EFieldInfo ree;
1969 		sal_Int32  reeBegin=0, reeEnd=0;
1970 		for(sal_uInt16 j = 0; j < nField; j++)
1971 		{
1972 			ree = rCacheTF.GetFieldInfo(sal_uInt16(nParaIndex), j);
1973 			reeBegin  = ree.aPosition.nIndex + nAllFieldLen;
1974 			reeEnd = reeBegin + ree.aCurrentText.Len();
1975 			nAllFieldLen += (ree.aCurrentText.Len() - 1);
1976 			if( reeBegin > Segment.SegmentEnd )
1977 			{
1978 				break;
1979 			}
1980 			if(  (Segment.SegmentEnd > reeBegin && Segment.SegmentEnd <= reeEnd) ||
1981 			      (Segment.SegmentStart >= reeBegin && Segment.SegmentStart < reeEnd)  )
1982 			{
1983 				if(ree.pFieldItem->GetField()->GetClassId() != SVX_URLFIELD)
1984 				{
1985 					nFoundFieldIndex = j;
1986 					break;
1987 				}
1988 			}
1989 		}
1990 		sal_Bool bExtend = sal_False;
1991 		if( nFoundFieldIndex >= 0 )
1992 		{
1993 			if( Segment.SegmentEnd < reeEnd )
1994 			{
1995 				Segment.SegmentEnd  = reeEnd;
1996 				bExtend = sal_True;
1997 			}
1998 			if( Segment.SegmentStart > reeBegin )
1999 			{
2000 				Segment.SegmentStart = reeBegin;
2001 				bExtend = sal_True;
2002 			}
2003 			if( bExtend )
2004 			{
2005 				//If there is a bullet before the field, should add the bullet length into the segment.
2006 				EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo(sal_uInt16(nParaIndex));
2007 				int nBulletLen = aBulletInfo.aText.Len();
2008 				if (nBulletLen > 0)
2009 				{
2010 					Segment.SegmentEnd += nBulletLen;
2011 					if (nFoundFieldIndex > 0)
2012 						Segment.SegmentStart += nBulletLen;
2013 					Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd);
2014 					//After get the correct field name, should restore the offset value which don't contain the bullet.
2015 					Segment.SegmentEnd -= nBulletLen;
2016 					if (nFoundFieldIndex > 0)
2017 						Segment.SegmentStart -= nBulletLen;
2018 				}
2019 				else
2020 					Segment.SegmentText = GetTextRange(Segment.SegmentStart, Segment.SegmentEnd);
2021 			}
2022 		}
2023 		return bExtend;
2024     }
getTextAtIndex(sal_Int32 nIndex,sal_Int16 aTextType)2025     ::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)
2026     {
2027         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2028 
2029         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2030 
2031         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2032                    "AccessibleEditableTextPara::getTextAtIndex: paragraph index value overflow");
2033 
2034         ::com::sun::star::accessibility::TextSegment aResult;
2035         aResult.SegmentStart = -1;
2036         aResult.SegmentEnd = -1;
2037 
2038         switch( aTextType )
2039         {
2040 		case AccessibleTextType::CHARACTER:
2041 		case AccessibleTextType::WORD:
2042 		{
2043 			aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
2044 			ExtendByField( aResult );
2045 			break;
2046             	}
2047             // Not yet handled by OCommonAccessibleText. Missing
2048             // implGetAttributeRunBoundary() method there
2049             case AccessibleTextType::ATTRIBUTE_RUN:
2050             {
2051                 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( static_cast< sal_uInt16 >( GetParagraphIndex() ) );
2052 
2053                 if( nIndex == nTextLen )
2054                 {
2055                     // #i17014# Special-casing one-behind-the-end character
2056                     aResult.SegmentStart = aResult.SegmentEnd = nTextLen;
2057                 }
2058                 else
2059                 {
2060                     sal_uInt16 nStartIndex, nEndIndex;
2061 					//For the bullet paragraph, the bullet string is ingnored for IAText::attributes() function.
2062 					SvxTextForwarder&	rCacheTF = GetTextForwarder();
2063 					// MT IA2: Not used? sal_Int32 nBulletLen = 0;
2064 					EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) );
2065 					if (aBulletInfo.bVisible)
2066 						nIndex += aBulletInfo.aText.Len();
2067 					if (nIndex != 0  && nIndex >= getCharacterCount())
2068 						nIndex = getCharacterCount()-1;
2069 					CheckPosition(nIndex);
2070                     if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
2071                     {
2072                         aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
2073 						if (aBulletInfo.bVisible)
2074 						{
2075 							nStartIndex -= aBulletInfo.aText.Len();
2076 							nEndIndex -= aBulletInfo.aText.Len();
2077 						}
2078                         aResult.SegmentStart = nStartIndex;
2079                         aResult.SegmentEnd = nEndIndex;
2080                     }
2081 		}
2082                 break;
2083             }
2084             case AccessibleTextType::LINE:
2085             {
2086                 SvxTextForwarder&	rCacheTF = GetTextForwarder();
2087                 sal_Int32			nParaIndex = GetParagraphIndex();
2088                 // MT IA2: Not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( static_cast< sal_uInt16 >( nParaIndex ) );
2089                 CheckPosition(nIndex);
2090 		if (nIndex != 0  && nIndex == getCharacterCount())
2091 			--nIndex;
2092                 sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) );
2093                 sal_Int32 nCurIndex;
2094                 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
2095                 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
2096                 //by the IAText::attributes(). So here must do special support for bullet line.
2097                 sal_Int32 nBulletLen = 0;
2098                 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
2099                 {
2100                     if (nLine == 0)
2101                     {
2102                         EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(nParaIndex) );
2103                         if (aBulletInfo.bVisible)
2104                         {
2105                             //in bullet or numbering;
2106                             nBulletLen = aBulletInfo.aText.Len();
2107                         }
2108                     }
2109                     //nCurIndex += rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine);
2110                     sal_Int32 nLineLen = rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine);
2111                     if (nLine == 0)
2112                         nCurIndex += nLineLen - nBulletLen;
2113                     else
2114                         nCurIndex += nLineLen;
2115                     if( nCurIndex > nIndex )
2116                     {
2117                         if (nLine ==0)
2118                         {
2119                             //aResult.SegmentStart = nCurIndex - rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine);
2120                             aResult.SegmentStart = 0;
2121                             aResult.SegmentEnd = nCurIndex;
2122                             //aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd );
2123                             aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen);
2124                             break;
2125                         }
2126                         else
2127                         {
2128                             //aResult.SegmentStart = nCurIndex - rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine);
2129                             aResult.SegmentStart = nCurIndex - nLineLen;
2130                             aResult.SegmentEnd = nCurIndex;
2131                             //aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd );
2132                             aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen);
2133                             break;
2134                         }
2135                     }
2136                 }
2137                 break;
2138             }
2139             default:
2140                 aResult = OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
2141                 break;
2142         } /* end of switch( aTextType ) */
2143 
2144         return aResult;
2145     }
2146 
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 aTextType)2147     ::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)
2148     {
2149         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2150 
2151         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2152 
2153         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2154                    "AccessibleEditableTextPara::getTextBeforeIndex: paragraph index value overflow");
2155 
2156         ::com::sun::star::accessibility::TextSegment aResult;
2157         aResult.SegmentStart = -1;
2158         aResult.SegmentEnd = -1;
2159 		i18n::Boundary aBoundary;
2160         switch( aTextType )
2161         {
2162             // Not yet handled by OCommonAccessibleText. Missing
2163             // implGetAttributeRunBoundary() method there
2164             case AccessibleTextType::ATTRIBUTE_RUN:
2165             {
2166                 const sal_Int32 nTextLen = GetTextForwarder().GetTextLen( static_cast< sal_uInt16 >( GetParagraphIndex() ) );
2167                 sal_uInt16 nStartIndex, nEndIndex;
2168 
2169                 if( nIndex == nTextLen )
2170                 {
2171                     // #i17014# Special-casing one-behind-the-end character
2172                     if( nIndex > 0 &&
2173                         GetAttributeRun(nStartIndex, nEndIndex, nIndex-1) )
2174                     {
2175                         aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
2176                         aResult.SegmentStart = nStartIndex;
2177                         aResult.SegmentEnd = nEndIndex;
2178                     }
2179                 }
2180                 else
2181                 {
2182                     if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
2183                     {
2184                         // already at the left border? If not, query
2185                         // one index further left
2186                         if( nStartIndex > 0 &&
2187                             GetAttributeRun(nStartIndex, nEndIndex, nStartIndex-1) )
2188                         {
2189                             aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
2190                             aResult.SegmentStart = nStartIndex;
2191                             aResult.SegmentEnd = nEndIndex;
2192                         }
2193                     }
2194                 }
2195                 break;
2196             }
2197             case AccessibleTextType::LINE:
2198             {
2199                 SvxTextForwarder&	rCacheTF = GetTextForwarder();
2200                 sal_Int32			nParaIndex = GetParagraphIndex();
2201                 // MT IA2 not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( static_cast< sal_uInt16 >( nParaIndex ) );
2202 
2203                 CheckPosition(nIndex);
2204 
2205                 sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) );
2206                 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
2207                 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
2208                 //by the IAText::attributes(). So here must do special support for bullet line.
2209                 sal_Int32 nCurIndex=0, nLastIndex=0, nCurLineLen=0;
2210                 sal_Int32 nLastLineLen = 0, nBulletLen = 0;;
2211                 // get the line before the line the index points into
2212                 for( nLine=0, nCurIndex=0, nLastIndex=0; nLine<nLineCount; ++nLine )
2213                 {
2214                     nLastIndex = nCurIndex;
2215                     if (nLine == 0)
2216                     {
2217                         EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(nParaIndex) );
2218                         if (aBulletInfo.bVisible)
2219                         {
2220                             //in bullet or numbering;
2221                             nBulletLen = aBulletInfo.aText.Len();
2222                         }
2223                     }
2224                     if (nLine == 1)
2225                         nLastLineLen = nCurLineLen - nBulletLen;
2226                     else
2227                         nLastLineLen = nCurLineLen;
2228                     nCurLineLen = rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine);
2229                     //nCurIndex += nCurLineLen;
2230                     if (nLine == 0)
2231                         nCurIndex += nCurLineLen - nBulletLen;
2232                     else
2233                         nCurIndex += nCurLineLen;
2234 
2235                     //if( nCurIndex > nIndex &&
2236                     //nLastIndex > nCurLineLen )
2237                     if (nCurIndex > nIndex)
2238                     {
2239                         if (nLine == 0)
2240                         {
2241                             break;
2242                         }
2243                         else if (nLine == 1)
2244                         {
2245                             aResult.SegmentStart = 0;
2246                             aResult.SegmentEnd = static_cast< sal_uInt16 >( nLastIndex );
2247                             aResult.SegmentText = GetTextRange( aResult.SegmentStart, aResult.SegmentEnd + nBulletLen);
2248                             break;
2249                         }
2250                         else
2251                         {
2252                             //aResult.SegmentStart = nLastIndex - nCurLineLen;
2253                             aResult.SegmentStart = nLastIndex - nLastLineLen;
2254                             aResult.SegmentEnd = static_cast< sal_uInt16 >( nLastIndex );
2255                             aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen);
2256                             break;
2257                         }
2258                     }
2259                 }
2260 
2261                 break;
2262             }
2263 			case AccessibleTextType::WORD:
2264 			{
2265 				nIndex = SkipField( nIndex, sal_False);
2266 				::rtl::OUString sText( implGetText() );
2267 				sal_Int32 nLength = sText.getLength();
2268 
2269 				// get word at index
2270 				implGetWordBoundary( aBoundary, nIndex );
2271 
2272 
2273 				//sal_Int32 curWordStart = aBoundary.startPos;
2274 				//sal_Int32 preWordStart = curWordStart;
2275 				sal_Int32 curWordStart , preWordStart;
2276 				if( aBoundary.startPos == -1 || aBoundary.startPos > nIndex)
2277 					curWordStart = preWordStart = nIndex;
2278 				else
2279 					curWordStart = preWordStart = aBoundary.startPos;
2280 
2281 				// get previous word
2282 
2283 				sal_Bool bWord = sal_False;
2284 
2285 				//while ( preWordStart > 0 && aBoundary.startPos == curWordStart)
2286 				while ( (preWordStart >= 0 && !bWord ) || ( aBoundary.endPos > curWordStart ) )
2287 					{
2288 					preWordStart--;
2289 					bWord = implGetWordBoundary( aBoundary, preWordStart );
2290 				}
2291 				if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
2292 				{
2293 					aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
2294 					aResult.SegmentStart = aBoundary.startPos;
2295 					aResult.SegmentEnd = aBoundary.endPos;
2296 					ExtendByField( aResult );
2297 				}
2298 			}
2299 			break;
2300 			case AccessibleTextType::CHARACTER:
2301 			{
2302 				nIndex = SkipField( nIndex, sal_False);
2303 				aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
2304 				ExtendByField( aResult );
2305 				break;
2306 			}
2307             default:
2308                 aResult = OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
2309                 break;
2310         } /* end of switch( aTextType ) */
2311 
2312         return aResult;
2313     }
2314 
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 aTextType)2315     ::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)
2316     {
2317         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2318 
2319         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2320 
2321         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2322                    "AccessibleEditableTextPara::getTextBehindIndex: paragraph index value overflow");
2323 
2324         ::com::sun::star::accessibility::TextSegment aResult;
2325         aResult.SegmentStart = -1;
2326         aResult.SegmentEnd = -1;
2327 		i18n::Boundary aBoundary;
2328         switch( aTextType )
2329         {
2330             case AccessibleTextType::ATTRIBUTE_RUN:
2331             {
2332                 sal_uInt16 nStartIndex, nEndIndex;
2333 
2334                 if( GetAttributeRun(nStartIndex, nEndIndex, nIndex) )
2335                 {
2336                     // already at the right border?
2337                     if( nEndIndex < GetTextLen() )
2338                     {
2339                         if( GetAttributeRun(nStartIndex, nEndIndex, nEndIndex) )
2340                         {
2341                             aResult.SegmentText = GetTextRange(nStartIndex, nEndIndex);
2342                             aResult.SegmentStart = nStartIndex;
2343                             aResult.SegmentEnd = nEndIndex;
2344                         }
2345                     }
2346                 }
2347                 break;
2348             }
2349 
2350             case AccessibleTextType::LINE:
2351             {
2352                 SvxTextForwarder&	rCacheTF = GetTextForwarder();
2353                 sal_Int32			nParaIndex = GetParagraphIndex();
2354                 // MT IA2 not needed? sal_Int32 nTextLen = rCacheTF.GetTextLen( static_cast< sal_uInt16 >( nParaIndex ) );
2355 
2356                 CheckPosition(nIndex);
2357 
2358                 sal_uInt16 nLine, nLineCount=rCacheTF.GetLineCount( static_cast< sal_uInt16 >( nParaIndex ) );
2359                 sal_Int32 nCurIndex;
2360                 //the problem is that rCacheTF.GetLineLen() will include the bullet length. But for the bullet line,
2361                 //the text value doesn't contain the bullet characters. all of the bullet and numbering info are exposed
2362                 //by the IAText::attributes(). So here must do special support for bullet line.
2363                 sal_Int32 nBulletLen = 0;
2364                 // get the line after the line the index points into
2365                 for( nLine=0, nCurIndex=0; nLine<nLineCount; ++nLine )
2366                 {
2367                     if (nLine == 0)
2368                     {
2369                         EBulletInfo aBulletInfo = rCacheTF.GetBulletInfo( static_cast< sal_uInt16 >(nParaIndex) );
2370                         if (aBulletInfo.bVisible)
2371                         {
2372                             //in bullet or numbering;
2373                             nBulletLen = aBulletInfo.aText.Len();
2374                         }
2375                     }
2376                     //nCurIndex += rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine);
2377                     sal_Int32 nLineLen = rCacheTF.GetLineLen( static_cast< sal_uInt16 >( nParaIndex ), nLine);
2378 
2379                     if (nLine == 0)
2380                         nCurIndex += nLineLen - nBulletLen;
2381                     else
2382                         nCurIndex += nLineLen;
2383 
2384                     if( nCurIndex > nIndex &&
2385                         nLine < nLineCount-1 )
2386                     {
2387                         aResult.SegmentStart = nCurIndex;
2388                         aResult.SegmentEnd = nCurIndex + rCacheTF.GetLineLen(static_cast< sal_uInt16 >( nParaIndex ), nLine+1);
2389                         aResult.SegmentText = GetTextRange( aResult.SegmentStart + nBulletLen, aResult.SegmentEnd + nBulletLen);
2390                         break;
2391                     }
2392                 }
2393 
2394                 break;
2395             }
2396 			case AccessibleTextType::WORD:
2397 			{
2398 				nIndex = SkipField( nIndex, sal_True);
2399 				::rtl::OUString sText( implGetText() );
2400 				sal_Int32 nLength = sText.getLength();
2401 
2402 				// get word at index
2403 				sal_Bool bWord = implGetWordBoundary( aBoundary, nIndex );
2404 
2405 				// real current world
2406 				sal_Int32 nextWord = nIndex;
2407 				//if( nIndex >= aBoundary.startPos && nIndex <= aBoundary.endPos )
2408 				if( nIndex <= aBoundary.endPos )
2409 				{
2410 					nextWord = 	aBoundary.endPos;
2411 					if( sText.getStr()[nextWord] == sal_Unicode(' ') ) nextWord++;
2412 					bWord = implGetWordBoundary( aBoundary, nextWord );
2413 				}
2414 
2415 				if ( bWord && implIsValidBoundary( aBoundary, nLength ) )
2416 				{
2417 					aResult.SegmentText = sText.copy( aBoundary.startPos, aBoundary.endPos - aBoundary.startPos );
2418 					aResult.SegmentStart = aBoundary.startPos;
2419 					aResult.SegmentEnd = aBoundary.endPos;
2420 
2421 					// If the end position of aBoundary is inside a field, extend the result to the end of the field
2422 
2423 					ExtendByField( aResult );
2424 				}
2425 			}
2426 			break;
2427 
2428 			case AccessibleTextType::CHARACTER:
2429 			{
2430 				nIndex = SkipField( nIndex, sal_True);
2431 				aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
2432 				ExtendByField( aResult );
2433 				break;
2434 			}
2435             default:
2436                 aResult = OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
2437                 break;
2438         } /* end of switch( aTextType ) */
2439 
2440         return aResult;
2441     }
2442 
copyText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)2443     sal_Bool SAL_CALL AccessibleEditableTextPara::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2444     {
2445         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2446 
2447         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2448 
2449         try
2450         {
2451             SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
2452             #if OSL_DEBUG_LEVEL > 0
2453             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();    // MUST be after GetEditViewForwarder(), see method docs
2454             (void)rCacheTF;
2455             #else
2456             GetTextForwarder();                                         // MUST be after GetEditViewForwarder(), see method docs
2457             #endif
2458 
2459             sal_Bool aRetVal;
2460 
2461             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2462                        "AccessibleEditableTextPara::copyText: index value overflow");
2463 
2464             CheckRange(nStartIndex, nEndIndex);
2465 
2466             //Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2467             sal_Int32 nBulletLen = 0;
2468             EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) );
2469             if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2470                         nBulletLen = aBulletInfo.aText.Len();
2471             // save current selection
2472             ESelection aOldSelection;
2473 
2474             rCacheVF.GetSelection( aOldSelection );
2475             //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2476             rCacheVF.SetSelection( MakeSelection(nStartIndex + nBulletLen, nEndIndex + nBulletLen) );
2477             aRetVal = rCacheVF.Copy();
2478             rCacheVF.SetSelection( aOldSelection ); // restore
2479 
2480             return aRetVal;
2481         }
2482         catch( const uno::RuntimeException& )
2483         {
2484             return sal_False;
2485         }
2486     }
2487 
2488 	// XAccessibleEditableText
cutText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)2489     sal_Bool SAL_CALL AccessibleEditableTextPara::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2490     {
2491         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2492 
2493         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2494 
2495         try
2496         {
2497             SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
2498             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
2499 
2500             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2501                        "AccessibleEditableTextPara::cutText: index value overflow");
2502 
2503             CheckRange(nStartIndex, nEndIndex);
2504 
2505             // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2506             sal_Int32 nBulletLen = 0;
2507             EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) );
2508             if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2509                         nBulletLen = aBulletInfo.aText.Len();
2510             ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen);
2511             if( !rCacheTF.IsEditable( aSelection ) )
2512                 return sal_False; // non-editable area selected
2513 
2514             // don't save selection, might become invalid after cut!
2515             //rCacheVF.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2516             rCacheVF.SetSelection( aSelection );
2517 
2518             return rCacheVF.Cut();
2519         }
2520         catch( const uno::RuntimeException& )
2521         {
2522             return sal_False;
2523         }
2524     }
2525 
pasteText(sal_Int32 nIndex)2526     sal_Bool SAL_CALL AccessibleEditableTextPara::pasteText( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2527     {
2528         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2529 
2530         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2531 
2532         try
2533         {
2534             SvxEditViewForwarder& rCacheVF = GetEditViewForwarder( sal_True );
2535             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
2536 
2537             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2538                        "AccessibleEditableTextPara::pasteText: index value overflow");
2539 
2540             CheckPosition(nIndex);
2541 
2542             // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2543             sal_Int32 nBulletLen = 0;
2544             EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) );
2545             if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2546                         nBulletLen = aBulletInfo.aText.Len();
2547             //if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) )
2548             if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) )
2549                 return sal_False; // non-editable area selected
2550 
2551             // #104400# set empty selection (=> cursor) to given index
2552             //rCacheVF.SetSelection( MakeCursor(nIndex) );
2553             rCacheVF.SetSelection( MakeCursor(nIndex + nBulletLen) );
2554 
2555             return rCacheVF.Paste();
2556         }
2557         catch( const uno::RuntimeException& )
2558         {
2559             return sal_False;
2560         }
2561     }
2562 
deleteText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)2563     sal_Bool SAL_CALL AccessibleEditableTextPara::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2564     {
2565         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2566 
2567         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2568 
2569         try
2570         {
2571             // #102710# Request edit view when doing changes
2572             // AccessibleEmptyEditSource relies on this behaviour
2573             GetEditViewForwarder( sal_True );
2574             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
2575 
2576             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2577                        "AccessibleEditableTextPara::deleteText: index value overflow");
2578 
2579             CheckRange(nStartIndex, nEndIndex);
2580 
2581             // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2582             sal_Int32 nBulletLen = 0;
2583             EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) );
2584             if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2585                         nBulletLen = aBulletInfo.aText.Len();
2586             ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen);
2587 
2588             //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2589             if( !rCacheTF.IsEditable( aSelection ) )
2590                 return sal_False; // non-editable area selected
2591 
2592             //sal_Bool bRet = rCacheTF.Delete( MakeSelection(nStartIndex, nEndIndex) );
2593             sal_Bool bRet = rCacheTF.Delete( aSelection );
2594 
2595             GetEditSource().UpdateData();
2596 
2597             return bRet;
2598         }
2599         catch( const uno::RuntimeException& )
2600         {
2601             return sal_False;
2602         }
2603     }
2604 
insertText(const::rtl::OUString & sText,sal_Int32 nIndex)2605     sal_Bool SAL_CALL AccessibleEditableTextPara::insertText( const ::rtl::OUString& sText, sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2606     {
2607         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2608 
2609         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2610 
2611         try
2612         {
2613             // #102710# Request edit view when doing changes
2614             // AccessibleEmptyEditSource relies on this behaviour
2615             GetEditViewForwarder( sal_True );
2616             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
2617 
2618             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2619                        "AccessibleEditableTextPara::insertText: index value overflow");
2620 
2621             CheckPosition(nIndex);
2622 
2623             // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2624             sal_Int32 nBulletLen = 0;
2625             EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) );
2626             if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2627                         nBulletLen = aBulletInfo.aText.Len();
2628 
2629             //if( !rCacheTF.IsEditable( MakeSelection(nIndex) ) )
2630             if( !rCacheTF.IsEditable( MakeSelection(nIndex + nBulletLen) ) )
2631                 return sal_False; // non-editable area selected
2632 
2633             // #104400# insert given text at empty selection (=> cursor)
2634             //sal_Bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex) );
2635             sal_Bool bRet = rCacheTF.InsertText( sText, MakeCursor(nIndex + nBulletLen) );
2636 
2637             rCacheTF.QuickFormatDoc();
2638             GetEditSource().UpdateData();
2639 
2640             return bRet;
2641         }
2642         catch( const uno::RuntimeException& )
2643         {
2644             return sal_False;
2645         }
2646     }
2647 
replaceText(sal_Int32 nStartIndex,sal_Int32 nEndIndex,const::rtl::OUString & sReplacement)2648     sal_Bool SAL_CALL AccessibleEditableTextPara::replaceText( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const ::rtl::OUString& sReplacement ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2649     {
2650         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2651 
2652         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2653 
2654         try
2655         {
2656             // #102710# Request edit view when doing changes
2657             // AccessibleEmptyEditSource relies on this behaviour
2658             GetEditViewForwarder( sal_True );
2659             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
2660 
2661             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2662                        "AccessibleEditableTextPara::replaceText: index value overflow");
2663 
2664             CheckRange(nStartIndex, nEndIndex);
2665 
2666             // Because bullet may occupy one or more characters, the TextAdapter will include bullet to calculate the selection. Add offset to handle bullet
2667             sal_Int32 nBulletLen = 0;
2668             EBulletInfo aBulletInfo = GetTextForwarder().GetBulletInfo( static_cast< sal_uInt16 >(GetParagraphIndex()) );
2669             if( aBulletInfo.nParagraph != EE_PARA_NOT_FOUND && aBulletInfo.bVisible )
2670                         nBulletLen = aBulletInfo.aText.Len();
2671             ESelection aSelection = MakeSelection (nStartIndex + nBulletLen, nEndIndex + nBulletLen);
2672 
2673             //if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2674             if( !rCacheTF.IsEditable( aSelection ) )
2675                 return sal_False; // non-editable area selected
2676 
2677             // insert given text into given range => replace
2678             //sal_Bool bRet = rCacheTF.InsertText( sReplacement, MakeSelection(nStartIndex, nEndIndex) );
2679             sal_Bool bRet = rCacheTF.InsertText( sReplacement, aSelection );
2680 
2681             rCacheTF.QuickFormatDoc();
2682             GetEditSource().UpdateData();
2683 
2684             return bRet;
2685         }
2686         catch( const uno::RuntimeException& )
2687         {
2688             return sal_False;
2689         }
2690     }
2691 
setAttributes(sal_Int32 nStartIndex,sal_Int32 nEndIndex,const uno::Sequence<beans::PropertyValue> & aAttributeSet)2692     sal_Bool SAL_CALL AccessibleEditableTextPara::setAttributes( sal_Int32 nStartIndex, sal_Int32 nEndIndex, const uno::Sequence< beans::PropertyValue >& aAttributeSet ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2693     {
2694         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2695 
2696         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2697 
2698         try
2699         {
2700             // #102710# Request edit view when doing changes
2701             // AccessibleEmptyEditSource relies on this behaviour
2702             GetEditViewForwarder( sal_True );
2703             SvxAccessibleTextAdapter& rCacheTF = GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
2704             sal_uInt16 nPara = static_cast< sal_uInt16 >( GetParagraphIndex() );
2705 
2706             DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2707                        "AccessibleEditableTextPara::setAttributes: index value overflow");
2708 
2709             CheckRange(nStartIndex, nEndIndex);
2710 
2711             if( !rCacheTF.IsEditable( MakeSelection(nStartIndex, nEndIndex) ) )
2712                 return sal_False; // non-editable area selected
2713 
2714             // do the indices span the whole paragraph? Then use the outliner map
2715             // TODO: hold it as a member?
2716             SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
2717                                                    0 == nStartIndex &&
2718                                                    rCacheTF.GetTextLen(nPara) == nEndIndex ?
2719                                                    ImplGetSvxUnoOutlinerTextCursorSvxPropertySet() :
2720                                                    ImplGetSvxTextPortionSvxPropertySet() );
2721 
2722             aPropSet.SetSelection( MakeSelection(nStartIndex, nEndIndex) );
2723 
2724             // convert from PropertyValue to Any
2725             sal_Int32 i, nLength( aAttributeSet.getLength() );
2726             const beans::PropertyValue*	pPropArray = aAttributeSet.getConstArray();
2727             for(i=0; i<nLength; ++i)
2728             {
2729                 try
2730                 {
2731                     aPropSet.setPropertyValue(pPropArray->Name, pPropArray->Value);
2732                 }
2733                 catch( const uno::Exception& )
2734                 {
2735                     DBG_ERROR("AccessibleEditableTextPara::setAttributes exception in setPropertyValue");
2736                 }
2737 
2738                 ++pPropArray;
2739             }
2740 
2741             rCacheTF.QuickFormatDoc();
2742             GetEditSource().UpdateData();
2743 
2744             return sal_True;
2745         }
2746         catch( const uno::RuntimeException& )
2747         {
2748             return sal_False;
2749         }
2750     }
2751 
setText(const::rtl::OUString & sText)2752     sal_Bool SAL_CALL AccessibleEditableTextPara::setText( const ::rtl::OUString& sText ) throw (uno::RuntimeException)
2753     {
2754         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2755 
2756         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2757 
2758         return replaceText(0, getCharacterCount(), sText);
2759     }
2760 
2761     // XAccessibleTextAttributes
getDefaultAttributes(const uno::Sequence<::rtl::OUString> & rRequestedAttributes)2762     uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getDefaultAttributes(
2763             const uno::Sequence< ::rtl::OUString >& rRequestedAttributes )
2764         throw (uno::RuntimeException)
2765     {
2766         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2767         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2768 
2769         #if OSL_DEBUG_LEVEL > 0
2770         SvxAccessibleTextAdapter& rCacheTF =
2771         #endif
2772             GetTextForwarder();
2773 
2774         #if OSL_DEBUG_LEVEL > 0
2775         (void)rCacheTF;
2776         #endif
2777 
2778         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2779                    "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
2780 
2781         // get XPropertySetInfo for paragraph attributes and
2782         // character attributes that span all the paragraphs text.
2783         SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
2784                 ImplGetSvxCharAndParaPropertiesSet() );
2785         aPropSet.SetSelection( MakeSelection( 0, GetTextLen() ) );
2786         uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo();
2787         if (!xPropSetInfo.is())
2788             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot query XPropertySetInfo")),
2789                         uno::Reference< uno::XInterface >
2790                         ( static_cast< XAccessible* > (this) ) );   // disambiguate hierarchy
2791 
2792         // build sequence of available properties to check
2793         sal_Int32 nLenReqAttr = rRequestedAttributes.getLength();
2794         uno::Sequence< beans::Property > aProperties;
2795         if (nLenReqAttr)
2796         {
2797             const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray();
2798 
2799             aProperties.realloc( nLenReqAttr );
2800             beans::Property *pProperties = aProperties.getArray();
2801             sal_Int32 nCurLen = 0;
2802             for (sal_Int32 i = 0;  i < nLenReqAttr;  ++i)
2803             {
2804                 beans::Property aProp;
2805                 try
2806                 {
2807                     aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] );
2808                 }
2809                 catch (beans::UnknownPropertyException &)
2810                 {
2811                     continue;
2812                 }
2813                 pProperties[ nCurLen++ ] = aProp;
2814             }
2815             aProperties.realloc( nCurLen );
2816         }
2817         else
2818             aProperties = xPropSetInfo->getProperties();
2819 
2820         sal_Int32 nLength = aProperties.getLength();
2821         const beans::Property *pProperties = aProperties.getConstArray();
2822 
2823         // build resulting sequence
2824         uno::Sequence< beans::PropertyValue > aOutSequence( nLength );
2825         beans::PropertyValue* pOutSequence = aOutSequence.getArray();
2826         sal_Int32 nOutLen = 0;
2827         for (sal_Int32 i = 0;  i < nLength;  ++i)
2828         {
2829             // calling implementation functions:
2830             // _getPropertyState and _getPropertyValue (see below) to provide
2831             // the proper paragraph number when retrieving paragraph attributes
2832             PropertyState eState = aPropSet._getPropertyState( pProperties->Name, mnParagraphIndex );
2833             if ( eState == PropertyState_AMBIGUOUS_VALUE )
2834             {
2835                 OSL_ENSURE( false, "ambiguous property value encountered" );
2836             }
2837 
2838             //if (eState == PropertyState_DIRECT_VALUE)
2839             // per definition all paragraph properties and all character
2840             // properties spanning the whole paragraph should be returned
2841             // and declared as default value
2842             {
2843                 pOutSequence->Name      = pProperties->Name;
2844                 pOutSequence->Handle    = pProperties->Handle;
2845                 pOutSequence->Value     = aPropSet._getPropertyValue( pProperties->Name, mnParagraphIndex );
2846                 pOutSequence->State     = PropertyState_DEFAULT_VALUE;
2847 
2848                 ++pOutSequence;
2849                 ++nOutLen;
2850             }
2851             ++pProperties;
2852         }
2853         aOutSequence.realloc( nOutLen );
2854 
2855         return aOutSequence;
2856     }
2857 
2858 
getRunAttributes(sal_Int32 nIndex,const uno::Sequence<::rtl::OUString> & rRequestedAttributes)2859     uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleEditableTextPara::getRunAttributes(
2860             sal_Int32 nIndex,
2861             const uno::Sequence< ::rtl::OUString >& rRequestedAttributes )
2862         throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2863     {
2864         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
2865 
2866         ::vos::OGuard aGuard( Application::GetSolarMutex() );
2867 
2868         #if OSL_DEBUG_LEVEL > 0
2869         SvxAccessibleTextAdapter& rCacheTF =
2870         #endif
2871             GetTextForwarder();
2872 
2873         #if OSL_DEBUG_LEVEL > 0
2874         (void)rCacheTF;
2875         #endif
2876 
2877         DBG_ASSERT(GetParagraphIndex() >= 0 && GetParagraphIndex() <= USHRT_MAX,
2878                    "AccessibleEditableTextPara::getCharacterAttributes: index value overflow");
2879 
2880 		if( getCharacterCount() > 0 )
2881 			CheckIndex(nIndex);
2882 		else
2883 			CheckPosition(nIndex);
2884 
2885         SvxAccessibleTextPropertySet aPropSet( &GetEditSource(),
2886                                                ImplGetSvxCharAndParaPropertiesSet() );
2887         aPropSet.SetSelection( MakeSelection( nIndex ) );
2888         uno::Reference< beans::XPropertySetInfo > xPropSetInfo = aPropSet.getPropertySetInfo();
2889         if (!xPropSetInfo.is())
2890             throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Cannot query XPropertySetInfo")),
2891                                         uno::Reference< uno::XInterface >
2892                                         ( static_cast< XAccessible* > (this) ) );   // disambiguate hierarchy
2893 
2894         // build sequence of available properties to check
2895         sal_Int32 nLenReqAttr = rRequestedAttributes.getLength();
2896         uno::Sequence< beans::Property > aProperties;
2897         if (nLenReqAttr)
2898         {
2899             const rtl::OUString *pRequestedAttributes = rRequestedAttributes.getConstArray();
2900 
2901             aProperties.realloc( nLenReqAttr );
2902             beans::Property *pProperties = aProperties.getArray();
2903             sal_Int32 nCurLen = 0;
2904             for (sal_Int32 i = 0;  i < nLenReqAttr;  ++i)
2905             {
2906                 beans::Property aProp;
2907                 try
2908                 {
2909                     aProp = xPropSetInfo->getPropertyByName( pRequestedAttributes[i] );
2910                 }
2911                 catch (beans::UnknownPropertyException &)
2912                 {
2913                     continue;
2914                 }
2915                 pProperties[ nCurLen++ ] = aProp;
2916             }
2917             aProperties.realloc( nCurLen );
2918         }
2919         else
2920             aProperties = xPropSetInfo->getProperties();
2921 
2922         sal_Int32 nLength = aProperties.getLength();
2923         const beans::Property *pProperties = aProperties.getConstArray();
2924 
2925         // build resulting sequence
2926         uno::Sequence< beans::PropertyValue > aOutSequence( nLength );
2927         beans::PropertyValue* pOutSequence = aOutSequence.getArray();
2928         sal_Int32 nOutLen = 0;
2929         for (sal_Int32 i = 0;  i < nLength;  ++i)
2930         {
2931             // calling 'regular' functions that will operate on the selection
2932             PropertyState eState = aPropSet.getPropertyState( pProperties->Name );
2933             if (eState == PropertyState_DIRECT_VALUE)
2934             {
2935                 pOutSequence->Name      = pProperties->Name;
2936                 pOutSequence->Handle    = pProperties->Handle;
2937                 pOutSequence->Value     = aPropSet.getPropertyValue( pProperties->Name );
2938                 pOutSequence->State     = eState;
2939 
2940                 ++pOutSequence;
2941                 ++nOutLen;
2942             }
2943             ++pProperties;
2944         }
2945         aOutSequence.realloc( nOutLen );
2946 
2947         return aOutSequence;
2948     }
2949 
2950     // XAccessibleHypertext
getHyperLinkCount()2951     ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkCount(  ) throw (::com::sun::star::uno::RuntimeException)
2952     {
2953         SvxAccessibleTextAdapter& rT = GetTextForwarder();
2954         const sal_Int32 nPara = GetParagraphIndex();
2955 
2956         sal_uInt16 nHyperLinks = 0;
2957         sal_uInt16 nFields = rT.GetFieldCount( nPara );
2958         for ( sal_uInt16 n = 0; n < nFields; n++ )
2959         {
2960             EFieldInfo aField = rT.GetFieldInfo( nPara, n );
2961             if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
2962                 nHyperLinks++;
2963         }
2964         return nHyperLinks;
2965     }
2966 
getHyperLink(::sal_Int32 nLinkIndex)2967     ::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)
2968     {
2969         ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleHyperlink > xRef;
2970 
2971         SvxAccessibleTextAdapter& rT = GetTextForwarder();
2972         const sal_Int32 nPara = GetParagraphIndex();
2973 
2974         sal_uInt16 nHyperLink = 0;
2975         sal_uInt16 nFields = rT.GetFieldCount( nPara );
2976         for ( sal_uInt16 n = 0; n < nFields; n++ )
2977         {
2978             EFieldInfo aField = rT.GetFieldInfo( nPara, n );
2979             if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
2980             {
2981                 if ( nHyperLink == nLinkIndex )
2982                 {
2983                     sal_uInt16 nEEStart = aField.aPosition.nIndex;
2984 
2985                     // Translate EE Index to accessible index
2986                     sal_uInt16 nStart = rT.CalcEditEngineIndex( nPara, nEEStart );
2987                     sal_uInt16 nEnd = nStart + aField.aCurrentText.Len();
2988                     xRef = new AccessibleHyperlink( rT, new SvxFieldItem( *aField.pFieldItem ), nPara, nEEStart, nStart, nEnd, aField.aCurrentText );
2989                     break;
2990                 }
2991                 nHyperLink++;
2992             }
2993         }
2994 
2995         return xRef;
2996     }
2997 
getHyperLinkIndex(::sal_Int32 nCharIndex)2998     ::sal_Int32 SAL_CALL AccessibleEditableTextPara::getHyperLinkIndex( ::sal_Int32 nCharIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
2999     {
3000         const sal_Int32 nPara = GetParagraphIndex();
3001         SvxAccessibleTextAdapter& rT = GetTextForwarder();
3002 
3003 //        SvxAccessibleTextIndex aIndex;
3004 //        aIndex.SetIndex(nPara, nCharIndex, rT);
3005 //        const sal_uInt16 nEEIndex = aIndex.GetEEIndex();
3006 
3007         const sal_uInt16 nEEIndex = rT.CalcEditEngineIndex( nPara, nCharIndex );
3008         sal_Int32 nHLIndex = -1; //i123620
3009         sal_uInt16 nHyperLink = 0;
3010         sal_uInt16 nFields = rT.GetFieldCount( nPara );
3011         for ( sal_uInt16 n = 0; n < nFields; n++ )
3012         {
3013             EFieldInfo aField = rT.GetFieldInfo( nPara, n );
3014             if ( aField.pFieldItem->GetField()->ISA( SvxURLField ) )
3015             {
3016                 if ( aField.aPosition.nIndex == nEEIndex )
3017                 {
3018                     nHLIndex = nHyperLink;
3019                     break;
3020                 }
3021                 nHyperLink++;
3022             }
3023         }
3024 
3025         return nHLIndex;
3026     }
3027 
3028     // XAccessibleMultiLineText
getLineNumberAtIndex(sal_Int32 nIndex)3029     sal_Int32 SAL_CALL AccessibleEditableTextPara::getLineNumberAtIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
3030     {
3031         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3032 
3033         sal_Int32 nRes = -1;
3034         sal_Int32 nPara = GetParagraphIndex();
3035 
3036         SvxTextForwarder &rCacheTF = GetTextForwarder();
3037         const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
3038         DBG_ASSERT( bValidPara, "getLineNumberAtIndex: current paragraph index out of range" );
3039         if (bValidPara)
3040         {
3041             // we explicitly allow for the index to point at the character right behind the text
3042             if (0 <= nIndex && nIndex <= rCacheTF.GetTextLen( static_cast< sal_uInt16 >(nPara) ))
3043                 nRes = rCacheTF.GetLineNumberAtIndex( static_cast< sal_uInt16 >(nPara), static_cast< sal_uInt16 >(nIndex) );
3044             else
3045                 throw lang::IndexOutOfBoundsException();
3046         }
3047         return nRes;
3048     }
3049 
3050     // XAccessibleMultiLineText
getTextAtLineNumber(sal_Int32 nLineNo)3051     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineNumber( sal_Int32 nLineNo ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
3052     {
3053         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3054 
3055         ::com::sun::star::accessibility::TextSegment aResult;
3056         sal_Int32 nPara = GetParagraphIndex();
3057         SvxTextForwarder &rCacheTF = GetTextForwarder();
3058         const bool bValidPara = 0 <= nPara && nPara < rCacheTF.GetParagraphCount();
3059         DBG_ASSERT( bValidPara, "getTextAtLineNumber: current paragraph index out of range" );
3060         if (bValidPara)
3061         {
3062             if (0 <= nLineNo && nLineNo < rCacheTF.GetLineCount( static_cast< sal_uInt16 >(nPara) ))
3063             {
3064                 sal_uInt16 nStart = 0, nEnd = 0;
3065                 rCacheTF.GetLineBoundaries( nStart, nEnd, static_cast< sal_uInt16 >(nPara), static_cast< sal_uInt16 >(nLineNo) );
3066                 if (nStart != 0xFFFF && nEnd != 0xFFFF)
3067                 {
3068                     try
3069                     {
3070                         aResult.SegmentText     = getTextRange( nStart, nEnd );
3071                         aResult.SegmentStart    = nStart;
3072                         aResult.SegmentEnd      = nEnd;
3073                     }
3074                     catch (lang::IndexOutOfBoundsException)
3075                     {
3076                         // this is not the exception that should be raised in this function ...
3077                         DBG_ASSERT( 0, "unexpected exception" );
3078                     }
3079                 }
3080             }
3081             else
3082                 throw lang::IndexOutOfBoundsException();
3083         }
3084         return aResult;
3085     }
3086 
3087     // XAccessibleMultiLineText
getTextAtLineWithCaret()3088     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleEditableTextPara::getTextAtLineWithCaret(  ) throw (uno::RuntimeException)
3089     {
3090         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3091 
3092         ::com::sun::star::accessibility::TextSegment aResult;
3093         try
3094         {
3095             aResult = getTextAtLineNumber( getNumberOfLineWithCaret() );
3096         }
3097         catch (lang::IndexOutOfBoundsException &)
3098         {
3099             // this one needs to be catched since this interface does not allow for it.
3100         }
3101         return aResult;
3102     }
3103 
3104     // XAccessibleMultiLineText
getNumberOfLineWithCaret()3105     sal_Int32 SAL_CALL AccessibleEditableTextPara::getNumberOfLineWithCaret(  ) throw (uno::RuntimeException)
3106     {
3107         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3108 
3109         sal_Int32 nRes = -1;
3110         try
3111         {
3112             nRes = getLineNumberAtIndex( getCaretPosition() );
3113         }
3114         catch (lang::IndexOutOfBoundsException &)
3115         {
3116             // this one needs to be catched since this interface does not allow for it.
3117         }
3118         return nRes;
3119     }
3120 
3121 
3122 	// XServiceInfo
getImplementationName(void)3123     ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getImplementationName (void) throw (uno::RuntimeException)
3124     {
3125         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3126 
3127         return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("AccessibleEditableTextPara"));
3128     }
3129 
supportsService(const::rtl::OUString & sServiceName)3130     sal_Bool SAL_CALL AccessibleEditableTextPara::supportsService (const ::rtl::OUString& sServiceName) throw (uno::RuntimeException)
3131     {
3132         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3133 
3134         //  Iterate over all supported service names and return true if on of them
3135         //  matches the given name.
3136         uno::Sequence< ::rtl::OUString> aSupportedServices (
3137             getSupportedServiceNames ());
3138         for (int i=0; i<aSupportedServices.getLength(); i++)
3139             if (sServiceName == aSupportedServices[i])
3140                 return sal_True;
3141         return sal_False;
3142     }
3143 
getSupportedServiceNames(void)3144     uno::Sequence< ::rtl::OUString> SAL_CALL AccessibleEditableTextPara::getSupportedServiceNames (void) throw (uno::RuntimeException)
3145     {
3146         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3147 
3148         const ::rtl::OUString sServiceName( getServiceName() );
3149         return uno::Sequence< ::rtl::OUString > (&sServiceName, 1);
3150     }
3151 
3152 	// XServiceName
getServiceName(void)3153     ::rtl::OUString SAL_CALL AccessibleEditableTextPara::getServiceName (void) throw (uno::RuntimeException)
3154     {
3155         DBG_CHKTHIS( AccessibleEditableTextPara, NULL );
3156 
3157         // #105185# Using correct service now
3158         return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.AccessibleParagraphView"));
3159     }
3160 
3161 }  // end of namespace accessibility
3162 
3163 //------------------------------------------------------------------------
3164