xref: /AOO41X/main/editeng/source/accessibility/AccessibleStaticTextBase.cxx (revision 9b8096d048072d5e312699b7e51b3b8a9f64fe9a)
1190118d0SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3190118d0SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4190118d0SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5190118d0SAndrew Rist  * distributed with this work for additional information
6190118d0SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7190118d0SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8190118d0SAndrew Rist  * "License"); you may not use this file except in compliance
9190118d0SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11190118d0SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13190118d0SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14190118d0SAndrew Rist  * software distributed under the License is distributed on an
15190118d0SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16190118d0SAndrew Rist  * KIND, either express or implied.  See the License for the
17190118d0SAndrew Rist  * specific language governing permissions and limitations
18190118d0SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20190118d0SAndrew Rist  *************************************************************/
21190118d0SAndrew Rist 
22190118d0SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_editeng.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir //------------------------------------------------------------------------
28cdf0e10cSrcweir //
29cdf0e10cSrcweir // Global header
30cdf0e10cSrcweir //
31cdf0e10cSrcweir //------------------------------------------------------------------------
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #include <limits.h>
34cdf0e10cSrcweir #include <vector>
35cdf0e10cSrcweir #include <algorithm>
36cdf0e10cSrcweir #include <boost/bind.hpp>
37cdf0e10cSrcweir #include <vos/mutex.hxx>
38cdf0e10cSrcweir #include <vcl/window.hxx>
39cdf0e10cSrcweir #include <vcl/svapp.hxx>
40cdf0e10cSrcweir #include <comphelper/sequenceasvector.hxx>
41cdf0e10cSrcweir #include <com/sun/star/uno/Any.hxx>
42cdf0e10cSrcweir #include <com/sun/star/uno/Reference.hxx>
43cdf0e10cSrcweir #include <com/sun/star/awt/Point.hpp>
44cdf0e10cSrcweir #include <com/sun/star/awt/Rectangle.hpp>
45cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleTextType.hpp>
46cdf0e10cSrcweir 
47cdf0e10cSrcweir //------------------------------------------------------------------------
48cdf0e10cSrcweir //
49cdf0e10cSrcweir // Project-local header
50cdf0e10cSrcweir //
51cdf0e10cSrcweir //------------------------------------------------------------------------
52cdf0e10cSrcweir 
53cdf0e10cSrcweir #include <editeng/editdata.hxx>
54cdf0e10cSrcweir #include <editeng/unopracc.hxx>
55cdf0e10cSrcweir #include "editeng/unoedprx.hxx"
56cdf0e10cSrcweir #include <editeng/AccessibleStaticTextBase.hxx>
57cdf0e10cSrcweir #include "editeng/AccessibleEditableTextPara.hxx"
58cdf0e10cSrcweir 
59cdf0e10cSrcweir 
60cdf0e10cSrcweir using namespace ::com::sun::star;
61cdf0e10cSrcweir using namespace ::com::sun::star::accessibility;
62cdf0e10cSrcweir 
63cdf0e10cSrcweir /* TODO:
64cdf0e10cSrcweir    =====
65cdf0e10cSrcweir 
66cdf0e10cSrcweir    - separate adapter functionality from AccessibleStaticText class
67cdf0e10cSrcweir 
68cdf0e10cSrcweir    - refactor common loops into templates, using mem_fun
69cdf0e10cSrcweir 
70cdf0e10cSrcweir  */
71cdf0e10cSrcweir 
72cdf0e10cSrcweir namespace accessibility
73cdf0e10cSrcweir {
74cdf0e10cSrcweir     typedef ::comphelper::SequenceAsVector< beans::PropertyValue > PropertyValueVector;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir     class PropertyValueEqualFunctor : public ::std::binary_function< beans::PropertyValue, beans::PropertyValue, bool >
77cdf0e10cSrcweir     {
78cdf0e10cSrcweir     public:
79cdf0e10cSrcweir         PropertyValueEqualFunctor()
80cdf0e10cSrcweir         {}
81cdf0e10cSrcweir         bool operator() ( const beans::PropertyValue& lhs, const beans::PropertyValue& rhs ) const
82cdf0e10cSrcweir         {
83cdf0e10cSrcweir             return ( lhs.Name == rhs.Name && lhs.Value == rhs.Value );
84cdf0e10cSrcweir         }
85cdf0e10cSrcweir     };
86*9b8096d0SSteve Yin //IAccessibility2 Implementation 2009-----
87*9b8096d0SSteve Yin sal_Unicode cNewLine(0x0a);
88*9b8096d0SSteve Yin //-----IAccessibility2 Implementation 2009
89cdf0e10cSrcweir 	//------------------------------------------------------------------------
90cdf0e10cSrcweir 	//
91cdf0e10cSrcweir 	// Static Helper
92cdf0e10cSrcweir 	//
93cdf0e10cSrcweir 	//------------------------------------------------------------------------
94cdf0e10cSrcweir     ESelection MakeSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
95cdf0e10cSrcweir                               sal_Int32 nEndPara, sal_Int32 nEndIndex )
96cdf0e10cSrcweir     {
97cdf0e10cSrcweir         DBG_ASSERT(nStartPara >= 0 && nStartPara <= USHRT_MAX &&
98cdf0e10cSrcweir                    nStartIndex >= 0 && nStartIndex <= USHRT_MAX &&
99cdf0e10cSrcweir                    nEndPara >= 0 && nEndPara <= USHRT_MAX &&
100cdf0e10cSrcweir                    nEndIndex >= 0 && nEndIndex <= USHRT_MAX ,
101cdf0e10cSrcweir                    "AccessibleStaticTextBase_Impl::MakeSelection: index value overflow");
102cdf0e10cSrcweir 
103cdf0e10cSrcweir         return ESelection( static_cast< sal_uInt16 >(nStartPara), static_cast< sal_uInt16 >(nStartIndex),
104cdf0e10cSrcweir                            static_cast< sal_uInt16 >(nEndPara), static_cast< sal_uInt16 >(nEndIndex) );
105cdf0e10cSrcweir     }
106cdf0e10cSrcweir 
107cdf0e10cSrcweir 	//------------------------------------------------------------------------
108cdf0e10cSrcweir 	//
109cdf0e10cSrcweir 	// AccessibleStaticTextBase_Impl declaration
110cdf0e10cSrcweir 	//
111cdf0e10cSrcweir 	//------------------------------------------------------------------------
112cdf0e10cSrcweir 
113cdf0e10cSrcweir     DBG_NAME( AccessibleStaticTextBase_Impl );
114cdf0e10cSrcweir 
115cdf0e10cSrcweir     /** AccessibleStaticTextBase_Impl
116cdf0e10cSrcweir 
117cdf0e10cSrcweir     	This class implements the AccessibleStaticTextBase
118cdf0e10cSrcweir     	functionality, mainly by forwarding the calls to an aggregated
119cdf0e10cSrcweir     	AccessibleEditableTextPara. As this is a therefore non-trivial
120cdf0e10cSrcweir     	adapter, factoring out the common functionality from
121cdf0e10cSrcweir     	AccessibleEditableTextPara might be a profitable future task.
122cdf0e10cSrcweir      */
123cdf0e10cSrcweir     class AccessibleStaticTextBase_Impl
124cdf0e10cSrcweir     {
125*9b8096d0SSteve Yin 	//IAccessibility2 Implementation 2009-----
126*9b8096d0SSteve Yin 		friend class AccessibleStaticTextBase;
127*9b8096d0SSteve Yin 	//-----IAccessibility2 Implementation 2009
128cdf0e10cSrcweir     public:
129cdf0e10cSrcweir 
130cdf0e10cSrcweir         // receive pointer to our frontend class and view window
131cdf0e10cSrcweir         AccessibleStaticTextBase_Impl();
132cdf0e10cSrcweir         ~AccessibleStaticTextBase_Impl();
133cdf0e10cSrcweir 
134cdf0e10cSrcweir         SvxEditSourceAdapter& GetEditSource() const SAL_THROW((uno::RuntimeException))
135cdf0e10cSrcweir         {
136cdf0e10cSrcweir             DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
137cdf0e10cSrcweir 
138cdf0e10cSrcweir             return maEditSource;
139cdf0e10cSrcweir         }
140cdf0e10cSrcweir         void SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException));
141cdf0e10cSrcweir 
142cdf0e10cSrcweir         void SetEventSource( const uno::Reference< XAccessible >& rInterface )
143cdf0e10cSrcweir         {
144cdf0e10cSrcweir             DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
145cdf0e10cSrcweir 
146cdf0e10cSrcweir             mxThis = rInterface;
147cdf0e10cSrcweir         }
148cdf0e10cSrcweir         uno::Reference< XAccessible > GetEventSource() const
149cdf0e10cSrcweir         {
150cdf0e10cSrcweir             DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
151cdf0e10cSrcweir 
152cdf0e10cSrcweir             return mxThis;
153cdf0e10cSrcweir         }
154cdf0e10cSrcweir 
155cdf0e10cSrcweir         void SetOffset( const Point& );
156cdf0e10cSrcweir         Point GetOffset() const
157cdf0e10cSrcweir         {
158cdf0e10cSrcweir             DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
159cdf0e10cSrcweir 
160cdf0e10cSrcweir             ::osl::MutexGuard aGuard( maMutex ); Point aPoint( maOffset );
161cdf0e10cSrcweir             return aPoint;
162cdf0e10cSrcweir         }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir         void UpdateChildren();
165cdf0e10cSrcweir         void Dispose();
166cdf0e10cSrcweir 
167cdf0e10cSrcweir #ifdef DBG_UTIL
168cdf0e10cSrcweir         void CheckInvariants() const;
169cdf0e10cSrcweir #endif
170cdf0e10cSrcweir 
171cdf0e10cSrcweir         AccessibleEditableTextPara& GetParagraph( sal_Int32 nPara ) const;
172cdf0e10cSrcweir         sal_Int32 					GetParagraphCount() const;
173cdf0e10cSrcweir         sal_Int32                   GetParagraphIndex() const;
174cdf0e10cSrcweir         sal_Int32                   GetLineCount( sal_Int32 nParagraph ) const;
175cdf0e10cSrcweir 
176cdf0e10cSrcweir         EPosition                   Index2Internal( sal_Int32 nFlatIndex ) const
177cdf0e10cSrcweir         {
178cdf0e10cSrcweir             DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
179cdf0e10cSrcweir 
180cdf0e10cSrcweir             return ImpCalcInternal( nFlatIndex, false );
181cdf0e10cSrcweir         }
182cdf0e10cSrcweir 
183cdf0e10cSrcweir         EPosition                   Range2Internal( sal_Int32 nFlatIndex ) const
184cdf0e10cSrcweir         {
185cdf0e10cSrcweir             DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
186cdf0e10cSrcweir 
187cdf0e10cSrcweir             return ImpCalcInternal( nFlatIndex, true );
188cdf0e10cSrcweir         }
189cdf0e10cSrcweir 
190cdf0e10cSrcweir         sal_Int32					Internal2Index( EPosition nEEIndex ) const;
191cdf0e10cSrcweir 
192cdf0e10cSrcweir         void						CorrectTextSegment( TextSegment&	aTextSegment,
193cdf0e10cSrcweir                                                         int				nPara	) const;
194cdf0e10cSrcweir 
195cdf0e10cSrcweir         sal_Bool					SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
196cdf0e10cSrcweir                                                   sal_Int32 nEndPara, sal_Int32 nEndIndex );
197cdf0e10cSrcweir         sal_Bool					CopyText( sal_Int32 nStartPara, sal_Int32 nStartIndex,
198cdf0e10cSrcweir                                               sal_Int32 nEndPara, sal_Int32 nEndIndex );
199cdf0e10cSrcweir 
200cdf0e10cSrcweir         Rectangle                   GetParagraphBoundingBox() const;
201*9b8096d0SSteve Yin 	//IAccessibility2 Implementation 2009-----
202*9b8096d0SSteve Yin 		sal_Bool					RemoveLineBreakCount( sal_Int32& rIndex );
203*9b8096d0SSteve Yin 	//-----IAccessibility2 Implementation 2009
204cdf0e10cSrcweir 
205cdf0e10cSrcweir     private:
206cdf0e10cSrcweir 
207cdf0e10cSrcweir         EPosition 					ImpCalcInternal( sal_Int32 nFlatIndex, bool bExclusive ) const;
208cdf0e10cSrcweir 
209cdf0e10cSrcweir         // our frontend class (the one implementing the actual
210cdf0e10cSrcweir         // interface). That's not necessarily the one containing the impl
211cdf0e10cSrcweir         // pointer
212cdf0e10cSrcweir         uno::Reference< XAccessible > mxThis;
213cdf0e10cSrcweir 
214cdf0e10cSrcweir         // implements our functionality, we're just an adapter (guarded by solar mutex)
215cdf0e10cSrcweir         mutable AccessibleEditableTextPara* mpTextParagraph;
216cdf0e10cSrcweir 
217cdf0e10cSrcweir         uno::Reference< XAccessible > mxParagraph;
218cdf0e10cSrcweir 
219cdf0e10cSrcweir         // a wrapper for the text forwarders (guarded by solar mutex)
220cdf0e10cSrcweir         mutable SvxEditSourceAdapter maEditSource;
221cdf0e10cSrcweir 
222cdf0e10cSrcweir         // guard for maOffset
223cdf0e10cSrcweir         mutable ::osl::Mutex maMutex;
224cdf0e10cSrcweir 
225cdf0e10cSrcweir         /// our current offset to the containing shape/cell (guarded by maMutex)
226cdf0e10cSrcweir         Point maOffset;
227cdf0e10cSrcweir 
228cdf0e10cSrcweir     };
229cdf0e10cSrcweir 
230cdf0e10cSrcweir 	//------------------------------------------------------------------------
231cdf0e10cSrcweir 	//
232cdf0e10cSrcweir 	// AccessibleStaticTextBase_Impl implementation
233cdf0e10cSrcweir 	//
234cdf0e10cSrcweir 	//------------------------------------------------------------------------
235cdf0e10cSrcweir 
236cdf0e10cSrcweir     AccessibleStaticTextBase_Impl::AccessibleStaticTextBase_Impl() :
237cdf0e10cSrcweir         mxThis( NULL ),
238cdf0e10cSrcweir         mpTextParagraph( new AccessibleEditableTextPara(NULL) ),
239cdf0e10cSrcweir         mxParagraph( mpTextParagraph ),
240cdf0e10cSrcweir         maEditSource(),
241cdf0e10cSrcweir         maMutex(),
242cdf0e10cSrcweir         maOffset(0,0)
243cdf0e10cSrcweir     {
244cdf0e10cSrcweir         DBG_CTOR( AccessibleStaticTextBase_Impl, NULL );
245cdf0e10cSrcweir 
246cdf0e10cSrcweir         // TODO: this is still somewhat of a hack, all the more since
247cdf0e10cSrcweir         // now the maTextParagraph has an empty parent reference set
248cdf0e10cSrcweir     }
249cdf0e10cSrcweir 
250cdf0e10cSrcweir     AccessibleStaticTextBase_Impl::~AccessibleStaticTextBase_Impl()
251cdf0e10cSrcweir     {
252cdf0e10cSrcweir         DBG_DTOR( AccessibleStaticTextBase_Impl, NULL );
253cdf0e10cSrcweir     }
254cdf0e10cSrcweir 
255cdf0e10cSrcweir     void AccessibleStaticTextBase_Impl::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException))
256cdf0e10cSrcweir     {
257cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
258cdf0e10cSrcweir 
259cdf0e10cSrcweir         maEditSource.SetEditSource( pEditSource );
260cdf0e10cSrcweir         if( mpTextParagraph )
261cdf0e10cSrcweir             mpTextParagraph->SetEditSource( &maEditSource );
262cdf0e10cSrcweir     }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir     void AccessibleStaticTextBase_Impl::SetOffset( const Point& rPoint )
265cdf0e10cSrcweir     {
266cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
267cdf0e10cSrcweir 
268cdf0e10cSrcweir         // guard against non-atomic access to maOffset data structure
269cdf0e10cSrcweir         {
270cdf0e10cSrcweir             ::osl::MutexGuard aGuard( maMutex );
271cdf0e10cSrcweir             maOffset = rPoint;
272cdf0e10cSrcweir         }
273cdf0e10cSrcweir 
274cdf0e10cSrcweir         if( mpTextParagraph )
275cdf0e10cSrcweir             mpTextParagraph->SetEEOffset( rPoint );
276cdf0e10cSrcweir 
277cdf0e10cSrcweir         // in all cases, check visibility afterwards.
278cdf0e10cSrcweir         UpdateChildren();
279cdf0e10cSrcweir     }
280cdf0e10cSrcweir 
281cdf0e10cSrcweir     void AccessibleStaticTextBase_Impl::UpdateChildren()
282cdf0e10cSrcweir     {
283cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
284cdf0e10cSrcweir 
285cdf0e10cSrcweir         // currently no children
286cdf0e10cSrcweir     }
287cdf0e10cSrcweir 
288cdf0e10cSrcweir     void AccessibleStaticTextBase_Impl::Dispose()
289cdf0e10cSrcweir     {
290cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
291cdf0e10cSrcweir 
292cdf0e10cSrcweir         // we're the owner of the paragraph, so destroy it, too
293cdf0e10cSrcweir         if( mpTextParagraph )
294cdf0e10cSrcweir             mpTextParagraph->Dispose();
295cdf0e10cSrcweir 
296cdf0e10cSrcweir         // drop references
297cdf0e10cSrcweir         mxParagraph = NULL;
298cdf0e10cSrcweir         mxThis = NULL;
299cdf0e10cSrcweir         mpTextParagraph = NULL;
300cdf0e10cSrcweir     }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir #ifdef DBG_UTIL
303cdf0e10cSrcweir     void AccessibleStaticTextBase_Impl::CheckInvariants() const
304cdf0e10cSrcweir     {
305cdf0e10cSrcweir         // TODO
306cdf0e10cSrcweir     }
307cdf0e10cSrcweir #endif
308cdf0e10cSrcweir 
309cdf0e10cSrcweir     AccessibleEditableTextPara& AccessibleStaticTextBase_Impl::GetParagraph( sal_Int32 nPara ) const
310cdf0e10cSrcweir     {
311cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
312cdf0e10cSrcweir 
313cdf0e10cSrcweir         if( !mpTextParagraph )
314cdf0e10cSrcweir             throw lang::DisposedException (
315cdf0e10cSrcweir                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")), mxThis );
316cdf0e10cSrcweir 
317cdf0e10cSrcweir         // TODO: Have a differnt method on AccessibleEditableTextPara
318cdf0e10cSrcweir         // that does not care about state changes
319cdf0e10cSrcweir         mpTextParagraph->SetParagraphIndex( nPara );
320cdf0e10cSrcweir 
321cdf0e10cSrcweir         return *mpTextParagraph;
322cdf0e10cSrcweir     }
323cdf0e10cSrcweir 
324cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase_Impl::GetParagraphCount() const
325cdf0e10cSrcweir     {
326cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
327cdf0e10cSrcweir 
328cdf0e10cSrcweir         if( !mpTextParagraph )
329cdf0e10cSrcweir             return 0;
330cdf0e10cSrcweir         else
331cdf0e10cSrcweir             return mpTextParagraph->GetTextForwarder().GetParagraphCount();
332cdf0e10cSrcweir     }
333cdf0e10cSrcweir 
334cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase_Impl::GetParagraphIndex() const
335cdf0e10cSrcweir     {
336cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
337cdf0e10cSrcweir 
338cdf0e10cSrcweir         sal_Int32 nIndex = -1;
339cdf0e10cSrcweir         if( mpTextParagraph )
340cdf0e10cSrcweir             nIndex = mpTextParagraph->GetParagraphIndex();
341cdf0e10cSrcweir         return nIndex;
342cdf0e10cSrcweir     }
343cdf0e10cSrcweir 
344cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase_Impl::GetLineCount( sal_Int32 nParagraph ) const
345cdf0e10cSrcweir     {
346cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
347cdf0e10cSrcweir 
348cdf0e10cSrcweir         sal_Int32 nIndex = 0;
349cdf0e10cSrcweir         if( mpTextParagraph )
350cdf0e10cSrcweir             nIndex = mpTextParagraph->GetTextForwarder().GetLineCount( static_cast< sal_uInt16 >(nParagraph) );
351cdf0e10cSrcweir         return nIndex;
352cdf0e10cSrcweir     }
353cdf0e10cSrcweir 
354cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase_Impl::Internal2Index( EPosition nEEIndex ) const
355cdf0e10cSrcweir     {
356cdf0e10cSrcweir         sal_Int32 aRes(0);
357cdf0e10cSrcweir         int i;
358cdf0e10cSrcweir         for(i=0; i<nEEIndex.nPara; ++i)
359cdf0e10cSrcweir             aRes += GetParagraph(i).getCharacterCount();
360cdf0e10cSrcweir 
361cdf0e10cSrcweir         return aRes + nEEIndex.nIndex;
362cdf0e10cSrcweir     }
363cdf0e10cSrcweir 
364cdf0e10cSrcweir     void AccessibleStaticTextBase_Impl::CorrectTextSegment( TextSegment&	aTextSegment,
365cdf0e10cSrcweir                                                             int				nPara	) const
366cdf0e10cSrcweir     {
367cdf0e10cSrcweir         // Keep 'invalid' values at the TextSegment
368cdf0e10cSrcweir         if( aTextSegment.SegmentStart != -1 &&
369cdf0e10cSrcweir             aTextSegment.SegmentStart != -1 )
370cdf0e10cSrcweir         {
371cdf0e10cSrcweir             // #112814# Correct TextSegment by paragraph offset
372cdf0e10cSrcweir             sal_Int32 nOffset(0);
373cdf0e10cSrcweir             int i;
374cdf0e10cSrcweir             for(i=0; i<nPara; ++i)
375cdf0e10cSrcweir                 nOffset += GetParagraph(i).getCharacterCount();
376cdf0e10cSrcweir 
377cdf0e10cSrcweir             aTextSegment.SegmentStart += nOffset;
378cdf0e10cSrcweir             aTextSegment.SegmentEnd += nOffset;
379cdf0e10cSrcweir         }
380cdf0e10cSrcweir     }
381cdf0e10cSrcweir 
382cdf0e10cSrcweir     EPosition AccessibleStaticTextBase_Impl::ImpCalcInternal( sal_Int32 nFlatIndex, bool bExclusive ) const
383cdf0e10cSrcweir     {
384cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
385cdf0e10cSrcweir 
386cdf0e10cSrcweir         if( nFlatIndex < 0 )
387cdf0e10cSrcweir             throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleStaticTextBase_Impl::Index2Internal: character index out of bounds")),
388cdf0e10cSrcweir                                                   mxThis);
389cdf0e10cSrcweir         // gratuitously accepting larger indices here, AccessibleEditableTextPara will throw eventually
390cdf0e10cSrcweir 
391cdf0e10cSrcweir         sal_Int32 nCurrPara, nCurrIndex, nParas, nCurrCount;
392cdf0e10cSrcweir         for( nCurrPara=0, nParas=GetParagraphCount(), nCurrCount=0, nCurrIndex=0; nCurrPara<nParas; ++nCurrPara )
393cdf0e10cSrcweir         {
394cdf0e10cSrcweir             nCurrCount = GetParagraph( nCurrPara ).getCharacterCount();
395cdf0e10cSrcweir             nCurrIndex += nCurrCount;
396*9b8096d0SSteve Yin 	//IAccessibility2 Implementation 2009-----
397*9b8096d0SSteve Yin             if( nCurrIndex >= nFlatIndex )
398*9b8096d0SSteve Yin 	//-----IAccessibility2 Implementation 2009
399cdf0e10cSrcweir             {
400cdf0e10cSrcweir                 // check overflow
401cdf0e10cSrcweir                 DBG_ASSERT(nCurrPara >= 0 && nCurrPara <= USHRT_MAX &&
402cdf0e10cSrcweir                            nFlatIndex - nCurrIndex + nCurrCount >= 0 && nFlatIndex - nCurrIndex + nCurrCount <= USHRT_MAX ,
403cdf0e10cSrcweir                            "AccessibleStaticTextBase_Impl::Index2Internal: index value overflow");
404cdf0e10cSrcweir 
405cdf0e10cSrcweir                 return EPosition( static_cast< sal_uInt16 >(nCurrPara), static_cast< sal_uInt16 >(nFlatIndex - nCurrIndex + nCurrCount) );
406cdf0e10cSrcweir             }
407cdf0e10cSrcweir         }
408cdf0e10cSrcweir 
409cdf0e10cSrcweir         // #102170# Allow one-past the end for ranges
410cdf0e10cSrcweir         if( bExclusive && nCurrIndex == nFlatIndex )
411cdf0e10cSrcweir         {
412cdf0e10cSrcweir             // check overflow
413cdf0e10cSrcweir             DBG_ASSERT(nCurrPara >= 0 && nCurrPara <= USHRT_MAX &&
414cdf0e10cSrcweir                        nFlatIndex - nCurrIndex + nCurrCount >= 0 && nFlatIndex - nCurrIndex + nCurrCount <= USHRT_MAX ,
415cdf0e10cSrcweir                        "AccessibleStaticTextBase_Impl::Index2Internal: index value overflow");
416cdf0e10cSrcweir 
417cdf0e10cSrcweir             return EPosition( static_cast< sal_uInt16 >(nCurrPara-1), static_cast< sal_uInt16 >(nFlatIndex - nCurrIndex + nCurrCount) );
418cdf0e10cSrcweir         }
419cdf0e10cSrcweir 
420cdf0e10cSrcweir         // not found? Out of bounds
421cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleStaticTextBase_Impl::Index2Internal: character index out of bounds")),
422cdf0e10cSrcweir                                               mxThis);
423cdf0e10cSrcweir     }
424cdf0e10cSrcweir 
425cdf0e10cSrcweir     sal_Bool AccessibleStaticTextBase_Impl::SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
426cdf0e10cSrcweir                                                           sal_Int32 nEndPara, sal_Int32 nEndIndex )
427cdf0e10cSrcweir     {
428cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
429cdf0e10cSrcweir 
430cdf0e10cSrcweir         if( !mpTextParagraph )
431cdf0e10cSrcweir             return sal_False;
432cdf0e10cSrcweir 
433cdf0e10cSrcweir         try
434cdf0e10cSrcweir         {
435cdf0e10cSrcweir             SvxEditViewForwarder& rCacheVF = mpTextParagraph->GetEditViewForwarder( sal_True );
436cdf0e10cSrcweir             return rCacheVF.SetSelection( MakeSelection(nStartPara, nStartIndex, nEndPara, nEndIndex) );
437cdf0e10cSrcweir         }
438cdf0e10cSrcweir         catch( const uno::RuntimeException& )
439cdf0e10cSrcweir         {
440cdf0e10cSrcweir             return sal_False;
441cdf0e10cSrcweir         }
442cdf0e10cSrcweir     }
443cdf0e10cSrcweir 
444cdf0e10cSrcweir     sal_Bool AccessibleStaticTextBase_Impl::CopyText( sal_Int32 nStartPara, sal_Int32 nStartIndex,
445cdf0e10cSrcweir                                                       sal_Int32 nEndPara, sal_Int32 nEndIndex )
446cdf0e10cSrcweir     {
447cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
448cdf0e10cSrcweir 
449cdf0e10cSrcweir         if( !mpTextParagraph )
450cdf0e10cSrcweir             return sal_False;
451cdf0e10cSrcweir 
452cdf0e10cSrcweir         try
453cdf0e10cSrcweir         {
454cdf0e10cSrcweir             SvxEditViewForwarder& rCacheVF = mpTextParagraph->GetEditViewForwarder( sal_True );
455cdf0e10cSrcweir             mpTextParagraph->GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
456cdf0e10cSrcweir             sal_Bool aRetVal;
457cdf0e10cSrcweir 
458cdf0e10cSrcweir             // save current selection
459cdf0e10cSrcweir             ESelection aOldSelection;
460cdf0e10cSrcweir 
461cdf0e10cSrcweir             rCacheVF.GetSelection( aOldSelection );
462cdf0e10cSrcweir             rCacheVF.SetSelection( MakeSelection(nStartPara, nStartIndex, nEndPara, nEndIndex) );
463cdf0e10cSrcweir             aRetVal = rCacheVF.Copy();
464cdf0e10cSrcweir             rCacheVF.SetSelection( aOldSelection ); // restore
465cdf0e10cSrcweir 
466cdf0e10cSrcweir             return aRetVal;
467cdf0e10cSrcweir         }
468cdf0e10cSrcweir         catch( const uno::RuntimeException& )
469cdf0e10cSrcweir         {
470cdf0e10cSrcweir             return sal_False;
471cdf0e10cSrcweir         }
472cdf0e10cSrcweir     }
473cdf0e10cSrcweir 
474cdf0e10cSrcweir     Rectangle AccessibleStaticTextBase_Impl::GetParagraphBoundingBox() const
475cdf0e10cSrcweir     {
476cdf0e10cSrcweir         Rectangle aRect;
477cdf0e10cSrcweir         if( mpTextParagraph )
478cdf0e10cSrcweir         {
479cdf0e10cSrcweir             awt::Rectangle aAwtRect = mpTextParagraph->getBounds();
480cdf0e10cSrcweir             aRect = Rectangle( Point( aAwtRect.X, aAwtRect.Y ), Size( aAwtRect.Width, aAwtRect.Height ) );
481cdf0e10cSrcweir         }
482cdf0e10cSrcweir         else
483cdf0e10cSrcweir         {
484cdf0e10cSrcweir             aRect.SetEmpty();
485cdf0e10cSrcweir         }
486cdf0e10cSrcweir         return aRect;
487cdf0e10cSrcweir     }
488*9b8096d0SSteve Yin     	//IAccessibility2 Implementation 2009-----
489*9b8096d0SSteve Yin 	//the input argument is the index(including "\n" ) in the string.
490*9b8096d0SSteve Yin 	//the function will calculate the actual index(not including "\n") in the string.
491*9b8096d0SSteve Yin 	//and return true if the index is just at a "\n"
492*9b8096d0SSteve Yin 	sal_Bool AccessibleStaticTextBase_Impl::RemoveLineBreakCount( sal_Int32& rIndex )
493*9b8096d0SSteve Yin 	{
494*9b8096d0SSteve Yin 		// get the total char number inside the cell.
495*9b8096d0SSteve Yin 		sal_Int32 i, nCount, nParas;
496*9b8096d0SSteve Yin         for( i=0, nCount=0, nParas=GetParagraphCount(); i<nParas; ++i )
497*9b8096d0SSteve Yin             nCount += GetParagraph(i).getCharacterCount();
498*9b8096d0SSteve Yin 		nCount = nCount + (nParas-1);
499*9b8096d0SSteve Yin 		if( nCount == 0 &&  rIndex == 0) return sal_False;
500cdf0e10cSrcweir 
501*9b8096d0SSteve Yin 
502*9b8096d0SSteve Yin 		sal_Int32 nCurrPara, nCurrCount;
503*9b8096d0SSteve Yin 		sal_Int32 nLineBreakPos = 0, nLineBreakCount = 0;
504*9b8096d0SSteve Yin 		sal_Int32 nParaCount = GetParagraphCount();
505*9b8096d0SSteve Yin 		for ( nCurrCount = 0, nCurrPara = 0; nCurrPara < nParaCount; nCurrPara++ )
506*9b8096d0SSteve Yin 		{
507*9b8096d0SSteve Yin 			nCurrCount += GetParagraph( nCurrPara ).getCharacterCount();
508*9b8096d0SSteve Yin 			nLineBreakPos = nCurrCount++;
509*9b8096d0SSteve Yin 			if ( rIndex == nLineBreakPos )
510*9b8096d0SSteve Yin 			{
511*9b8096d0SSteve Yin 				rIndex -= (++nLineBreakCount);//(++nLineBreakCount);
512*9b8096d0SSteve Yin 				if ( rIndex < 0)
513*9b8096d0SSteve Yin 				{
514*9b8096d0SSteve Yin 					rIndex = 0;
515*9b8096d0SSteve Yin 				}
516*9b8096d0SSteve Yin 				//if the index is at the last position of the last paragraph
517*9b8096d0SSteve Yin 				//there is no "\n" , so we should increase rIndex by 1 and return false.
518*9b8096d0SSteve Yin 				if ( (nCurrPara+1) == nParaCount )
519*9b8096d0SSteve Yin 				{
520*9b8096d0SSteve Yin 					rIndex++;
521*9b8096d0SSteve Yin 					return sal_False;
522*9b8096d0SSteve Yin 				}
523*9b8096d0SSteve Yin 				else
524*9b8096d0SSteve Yin 				{
525*9b8096d0SSteve Yin 					return sal_True;
526*9b8096d0SSteve Yin 				}
527*9b8096d0SSteve Yin 			}
528*9b8096d0SSteve Yin 			else if ( rIndex < nLineBreakPos )
529*9b8096d0SSteve Yin 			{
530*9b8096d0SSteve Yin 				rIndex -= nLineBreakCount;
531*9b8096d0SSteve Yin 				return sal_False;
532*9b8096d0SSteve Yin 			}
533*9b8096d0SSteve Yin 			else
534*9b8096d0SSteve Yin 			{
535*9b8096d0SSteve Yin 				nLineBreakCount++;
536*9b8096d0SSteve Yin 			}
537*9b8096d0SSteve Yin 		}
538*9b8096d0SSteve Yin 		return sal_False;
539*9b8096d0SSteve Yin 	}
540*9b8096d0SSteve Yin 	//-----IAccessibility2 Implementation 2009
541cdf0e10cSrcweir 	//------------------------------------------------------------------------
542cdf0e10cSrcweir 	//
543cdf0e10cSrcweir 	// AccessibleStaticTextBase implementation
544cdf0e10cSrcweir 	//
545cdf0e10cSrcweir 	//------------------------------------------------------------------------
546cdf0e10cSrcweir 
547cdf0e10cSrcweir     AccessibleStaticTextBase::AccessibleStaticTextBase( ::std::auto_ptr< SvxEditSource > 		pEditSource ) :
548cdf0e10cSrcweir         mpImpl( new AccessibleStaticTextBase_Impl() )
549cdf0e10cSrcweir     {
550cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
551cdf0e10cSrcweir 
552cdf0e10cSrcweir         SetEditSource( pEditSource );
553cdf0e10cSrcweir     }
554cdf0e10cSrcweir 
555cdf0e10cSrcweir     AccessibleStaticTextBase::~AccessibleStaticTextBase()
556cdf0e10cSrcweir     {
557cdf0e10cSrcweir     }
558cdf0e10cSrcweir 
559cdf0e10cSrcweir     const SvxEditSource& AccessibleStaticTextBase::GetEditSource() const SAL_THROW((::com::sun::star::uno::RuntimeException))
560cdf0e10cSrcweir     {
561cdf0e10cSrcweir #ifdef DBG_UTIL
562cdf0e10cSrcweir         mpImpl->CheckInvariants();
563cdf0e10cSrcweir 
564cdf0e10cSrcweir         const SvxEditSource& aEditSource = mpImpl->GetEditSource();
565cdf0e10cSrcweir 
566cdf0e10cSrcweir         mpImpl->CheckInvariants();
567cdf0e10cSrcweir 
568cdf0e10cSrcweir         return aEditSource;
569cdf0e10cSrcweir #else
570cdf0e10cSrcweir         return mpImpl->GetEditSource();
571cdf0e10cSrcweir #endif
572cdf0e10cSrcweir     }
573cdf0e10cSrcweir 
574cdf0e10cSrcweir     void AccessibleStaticTextBase::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((::com::sun::star::uno::RuntimeException))
575cdf0e10cSrcweir     {
576cdf0e10cSrcweir #ifdef DBG_UTIL
577cdf0e10cSrcweir         // precondition: solar mutex locked
578cdf0e10cSrcweir         DBG_TESTSOLARMUTEX();
579cdf0e10cSrcweir 
580cdf0e10cSrcweir         mpImpl->CheckInvariants();
581cdf0e10cSrcweir 
582cdf0e10cSrcweir         mpImpl->SetEditSource( pEditSource );
583cdf0e10cSrcweir 
584cdf0e10cSrcweir         mpImpl->CheckInvariants();
585cdf0e10cSrcweir #else
586cdf0e10cSrcweir         mpImpl->SetEditSource( pEditSource );
587cdf0e10cSrcweir #endif
588cdf0e10cSrcweir     }
589cdf0e10cSrcweir 
590cdf0e10cSrcweir     void AccessibleStaticTextBase::SetEventSource( const uno::Reference< XAccessible >& rInterface )
591cdf0e10cSrcweir     {
592cdf0e10cSrcweir #ifdef DBG_UTIL
593cdf0e10cSrcweir         mpImpl->CheckInvariants();
594cdf0e10cSrcweir #endif
595cdf0e10cSrcweir 
596cdf0e10cSrcweir         mpImpl->SetEventSource( rInterface );
597cdf0e10cSrcweir 
598cdf0e10cSrcweir #ifdef DBG_UTIL
599cdf0e10cSrcweir         mpImpl->CheckInvariants();
600cdf0e10cSrcweir #endif
601cdf0e10cSrcweir     }
602cdf0e10cSrcweir 
603cdf0e10cSrcweir     uno::Reference< XAccessible > AccessibleStaticTextBase::GetEventSource() const
604cdf0e10cSrcweir     {
605cdf0e10cSrcweir #ifdef DBG_UTIL
606cdf0e10cSrcweir         mpImpl->CheckInvariants();
607cdf0e10cSrcweir 
608cdf0e10cSrcweir         uno::Reference< XAccessible > xRet( mpImpl->GetEventSource() );
609cdf0e10cSrcweir 
610cdf0e10cSrcweir         mpImpl->CheckInvariants();
611cdf0e10cSrcweir 
612cdf0e10cSrcweir         return xRet;
613cdf0e10cSrcweir #else
614cdf0e10cSrcweir         return mpImpl->GetEventSource();
615cdf0e10cSrcweir #endif
616cdf0e10cSrcweir     }
617cdf0e10cSrcweir 
618cdf0e10cSrcweir     void AccessibleStaticTextBase::SetOffset( const Point& rPoint )
619cdf0e10cSrcweir     {
620cdf0e10cSrcweir #ifdef DBG_UTIL
621cdf0e10cSrcweir         // precondition: solar mutex locked
622cdf0e10cSrcweir         DBG_TESTSOLARMUTEX();
623cdf0e10cSrcweir 
624cdf0e10cSrcweir         mpImpl->CheckInvariants();
625cdf0e10cSrcweir 
626cdf0e10cSrcweir         mpImpl->SetOffset( rPoint );
627cdf0e10cSrcweir 
628cdf0e10cSrcweir         mpImpl->CheckInvariants();
629cdf0e10cSrcweir #else
630cdf0e10cSrcweir         mpImpl->SetOffset( rPoint );
631cdf0e10cSrcweir #endif
632cdf0e10cSrcweir     }
633cdf0e10cSrcweir 
634cdf0e10cSrcweir     Point AccessibleStaticTextBase::GetOffset() const
635cdf0e10cSrcweir     {
636cdf0e10cSrcweir #ifdef DBG_UTIL
637cdf0e10cSrcweir         mpImpl->CheckInvariants();
638cdf0e10cSrcweir 
639cdf0e10cSrcweir         Point aPoint( mpImpl->GetOffset() );
640cdf0e10cSrcweir 
641cdf0e10cSrcweir         mpImpl->CheckInvariants();
642cdf0e10cSrcweir 
643cdf0e10cSrcweir         return aPoint;
644cdf0e10cSrcweir #else
645cdf0e10cSrcweir         return mpImpl->GetOffset();
646cdf0e10cSrcweir #endif
647cdf0e10cSrcweir     }
648cdf0e10cSrcweir 
649cdf0e10cSrcweir     void AccessibleStaticTextBase::UpdateChildren() SAL_THROW((::com::sun::star::uno::RuntimeException))
650cdf0e10cSrcweir     {
651cdf0e10cSrcweir #ifdef DBG_UTIL
652cdf0e10cSrcweir         // precondition: solar mutex locked
653cdf0e10cSrcweir         DBG_TESTSOLARMUTEX();
654cdf0e10cSrcweir 
655cdf0e10cSrcweir         mpImpl->CheckInvariants();
656cdf0e10cSrcweir 
657cdf0e10cSrcweir         mpImpl->UpdateChildren();
658cdf0e10cSrcweir 
659cdf0e10cSrcweir         mpImpl->CheckInvariants();
660cdf0e10cSrcweir #else
661cdf0e10cSrcweir         mpImpl->UpdateChildren();
662cdf0e10cSrcweir #endif
663cdf0e10cSrcweir     }
664cdf0e10cSrcweir 
665cdf0e10cSrcweir     void AccessibleStaticTextBase::Dispose()
666cdf0e10cSrcweir     {
667cdf0e10cSrcweir #ifdef DBG_UTIL
668cdf0e10cSrcweir         mpImpl->CheckInvariants();
669cdf0e10cSrcweir #endif
670cdf0e10cSrcweir 
671cdf0e10cSrcweir         mpImpl->Dispose();
672cdf0e10cSrcweir 
673cdf0e10cSrcweir #ifdef DBG_UTIL
674cdf0e10cSrcweir         mpImpl->CheckInvariants();
675cdf0e10cSrcweir #endif
676cdf0e10cSrcweir     }
677cdf0e10cSrcweir 
678cdf0e10cSrcweir 	// XAccessibleContext
679cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleStaticTextBase::getAccessibleChildCount() throw (uno::RuntimeException)
680cdf0e10cSrcweir     {
681cdf0e10cSrcweir         // no children at all
682cdf0e10cSrcweir         return 0;
683cdf0e10cSrcweir     }
684cdf0e10cSrcweir 
685cdf0e10cSrcweir     uno::Reference< XAccessible > SAL_CALL AccessibleStaticTextBase::getAccessibleChild( sal_Int32 /*i*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
686cdf0e10cSrcweir     {
687cdf0e10cSrcweir         // no children at all
688cdf0e10cSrcweir         return uno::Reference< XAccessible >();
689cdf0e10cSrcweir     }
690cdf0e10cSrcweir 
691cdf0e10cSrcweir     uno::Reference< XAccessible > SAL_CALL AccessibleStaticTextBase::getAccessibleAtPoint( const awt::Point& /*_aPoint*/ ) throw (uno::RuntimeException)
692cdf0e10cSrcweir     {
693cdf0e10cSrcweir         // no children at all
694cdf0e10cSrcweir         return uno::Reference< XAccessible >();
695cdf0e10cSrcweir     }
696cdf0e10cSrcweir 
697cdf0e10cSrcweir 	// XAccessibleText
698cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleStaticTextBase::getCaretPosition() throw (uno::RuntimeException)
699cdf0e10cSrcweir     {
700cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
701cdf0e10cSrcweir 
702cdf0e10cSrcweir         sal_Int32 i, nPos, nParas;
703cdf0e10cSrcweir         for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
704cdf0e10cSrcweir         {
705cdf0e10cSrcweir             if( (nPos=mpImpl->GetParagraph(i).getCaretPosition()) != -1 )
706cdf0e10cSrcweir                 return nPos;
707cdf0e10cSrcweir         }
708cdf0e10cSrcweir 
709cdf0e10cSrcweir         return nPos;
710cdf0e10cSrcweir     }
711cdf0e10cSrcweir 
712cdf0e10cSrcweir     sal_Bool SAL_CALL AccessibleStaticTextBase::setCaretPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
713cdf0e10cSrcweir     {
714cdf0e10cSrcweir         return setSelection(nIndex, nIndex);
715cdf0e10cSrcweir     }
716cdf0e10cSrcweir 
717cdf0e10cSrcweir     sal_Unicode SAL_CALL AccessibleStaticTextBase::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
718cdf0e10cSrcweir     {
719cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
720cdf0e10cSrcweir 
721cdf0e10cSrcweir         EPosition aPos( mpImpl->Index2Internal(nIndex) );
722cdf0e10cSrcweir 
723cdf0e10cSrcweir         return mpImpl->GetParagraph( aPos.nPara ).getCharacter( aPos.nIndex );
724cdf0e10cSrcweir     }
725cdf0e10cSrcweir 
726cdf0e10cSrcweir     uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleStaticTextBase::getCharacterAttributes( sal_Int32 nIndex, const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aRequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
727cdf0e10cSrcweir     {
728cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
729*9b8096d0SSteve Yin 	//IAccessibility2 Implementation 2009-----
730*9b8096d0SSteve Yin 		//get the actual index without "\n"
731*9b8096d0SSteve Yin 		mpImpl->RemoveLineBreakCount( nIndex );
732*9b8096d0SSteve Yin 	//IAccessibility2 Implementation 2009-----
733cdf0e10cSrcweir 
734cdf0e10cSrcweir         EPosition aPos( mpImpl->Index2Internal(nIndex) );
735cdf0e10cSrcweir 
736cdf0e10cSrcweir         return mpImpl->GetParagraph( aPos.nPara ).getCharacterAttributes( aPos.nIndex, aRequestedAttributes );
737cdf0e10cSrcweir     }
738cdf0e10cSrcweir 
739cdf0e10cSrcweir     awt::Rectangle SAL_CALL AccessibleStaticTextBase::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
740cdf0e10cSrcweir     {
741cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
742cdf0e10cSrcweir 
743cdf0e10cSrcweir         // #108900# Allow ranges for nIndex, as one-past-the-end
744cdf0e10cSrcweir         // values are now legal, too.
745cdf0e10cSrcweir         EPosition aPos( mpImpl->Range2Internal(nIndex) );
746cdf0e10cSrcweir 
747cdf0e10cSrcweir         // #i70916# Text in spread sheet cells return the wrong extents
748cdf0e10cSrcweir         AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( aPos.nPara );
749cdf0e10cSrcweir         awt::Rectangle aParaBounds( rPara.getBounds() );
750cdf0e10cSrcweir         awt::Rectangle aBounds( rPara.getCharacterBounds( aPos.nIndex ) );
751cdf0e10cSrcweir         aBounds.X += aParaBounds.X;
752cdf0e10cSrcweir         aBounds.Y += aParaBounds.Y;
753cdf0e10cSrcweir 
754cdf0e10cSrcweir         return aBounds;
755cdf0e10cSrcweir     }
756cdf0e10cSrcweir 
757cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleStaticTextBase::getCharacterCount() throw (uno::RuntimeException)
758cdf0e10cSrcweir     {
759cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
760cdf0e10cSrcweir 
761cdf0e10cSrcweir         sal_Int32 i, nCount, nParas;
762cdf0e10cSrcweir         for( i=0, nCount=0, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
763cdf0e10cSrcweir             nCount += mpImpl->GetParagraph(i).getCharacterCount();
764*9b8096d0SSteve Yin 	//IAccessibility2 Implementation 2009-----
765*9b8096d0SSteve Yin 		//count on the number of "\n" which equals number of paragraphs decrease 1.
766*9b8096d0SSteve Yin 		nCount = nCount + (nParas-1);
767*9b8096d0SSteve Yin 	//IAccessibility2 Implementation 2009-----
768cdf0e10cSrcweir         return nCount;
769cdf0e10cSrcweir     }
770cdf0e10cSrcweir 
771cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleStaticTextBase::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException)
772cdf0e10cSrcweir     {
773cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
774cdf0e10cSrcweir 
775cdf0e10cSrcweir         const sal_Int32 nParas( mpImpl->GetParagraphCount() );
776cdf0e10cSrcweir         sal_Int32 nIndex;
777cdf0e10cSrcweir         int i;
778cdf0e10cSrcweir         for( i=0; i<nParas; ++i )
779cdf0e10cSrcweir         {
780cdf0e10cSrcweir             // TODO: maybe exploit the fact that paragraphs are
781cdf0e10cSrcweir             // ordered vertically for early exit
782cdf0e10cSrcweir 
783cdf0e10cSrcweir             // #i70916# Text in spread sheet cells return the wrong extents
784cdf0e10cSrcweir             AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( i );
785cdf0e10cSrcweir             awt::Rectangle aParaBounds( rPara.getBounds() );
786cdf0e10cSrcweir             awt::Point aPoint( rPoint );
787cdf0e10cSrcweir             aPoint.X -= aParaBounds.X;
788cdf0e10cSrcweir             aPoint.Y -= aParaBounds.Y;
789cdf0e10cSrcweir 
790cdf0e10cSrcweir             // #112814# Use correct index offset
791cdf0e10cSrcweir             if ( ( nIndex = rPara.getIndexAtPoint( aPoint ) ) != -1 )
792cdf0e10cSrcweir                 return mpImpl->Internal2Index( EPosition(sal::static_int_cast<sal_uInt16>(i),
793cdf0e10cSrcweir                                                          sal::static_int_cast<sal_uInt16>(nIndex)) );
794cdf0e10cSrcweir         }
795cdf0e10cSrcweir 
796cdf0e10cSrcweir         return -1;
797cdf0e10cSrcweir     }
798cdf0e10cSrcweir 
799cdf0e10cSrcweir     ::rtl::OUString SAL_CALL AccessibleStaticTextBase::getSelectedText() throw (uno::RuntimeException)
800cdf0e10cSrcweir     {
801cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
802cdf0e10cSrcweir 
803cdf0e10cSrcweir         sal_Int32 nStart( getSelectionStart() );
804cdf0e10cSrcweir         sal_Int32 nEnd( getSelectionEnd() );
805cdf0e10cSrcweir 
806cdf0e10cSrcweir         // #104481# Return the empty string for 'no selection'
807cdf0e10cSrcweir         if( nStart < 0 || nEnd < 0 )
808cdf0e10cSrcweir             return ::rtl::OUString();
809cdf0e10cSrcweir 
810cdf0e10cSrcweir         return getTextRange( nStart, nEnd );
811cdf0e10cSrcweir     }
812cdf0e10cSrcweir 
813cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleStaticTextBase::getSelectionStart() throw (uno::RuntimeException)
814cdf0e10cSrcweir     {
815cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
816cdf0e10cSrcweir 
817cdf0e10cSrcweir         sal_Int32 i, nPos, nParas;
818cdf0e10cSrcweir         for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
819cdf0e10cSrcweir         {
820cdf0e10cSrcweir             if( (nPos=mpImpl->GetParagraph(i).getSelectionStart()) != -1 )
821cdf0e10cSrcweir                 return nPos;
822cdf0e10cSrcweir         }
823cdf0e10cSrcweir 
824cdf0e10cSrcweir         return nPos;
825cdf0e10cSrcweir     }
826cdf0e10cSrcweir 
827cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleStaticTextBase::getSelectionEnd() throw (uno::RuntimeException)
828cdf0e10cSrcweir     {
829cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
830cdf0e10cSrcweir 
831cdf0e10cSrcweir         sal_Int32 i, nPos, nParas;
832cdf0e10cSrcweir         for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
833cdf0e10cSrcweir         {
834cdf0e10cSrcweir             if( (nPos=mpImpl->GetParagraph(i).getSelectionEnd()) != -1 )
835cdf0e10cSrcweir                 return nPos;
836cdf0e10cSrcweir         }
837cdf0e10cSrcweir 
838cdf0e10cSrcweir         return nPos;
839cdf0e10cSrcweir     }
840cdf0e10cSrcweir 
841cdf0e10cSrcweir     sal_Bool SAL_CALL AccessibleStaticTextBase::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
842cdf0e10cSrcweir     {
843cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
844cdf0e10cSrcweir 
845cdf0e10cSrcweir         EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
846cdf0e10cSrcweir         EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
847cdf0e10cSrcweir 
848cdf0e10cSrcweir         return mpImpl->SetSelection( aStartIndex.nPara, aStartIndex.nIndex,
849cdf0e10cSrcweir                                      aEndIndex.nPara, aEndIndex.nIndex );
850cdf0e10cSrcweir     }
851cdf0e10cSrcweir 
852cdf0e10cSrcweir     ::rtl::OUString SAL_CALL AccessibleStaticTextBase::getText() throw (uno::RuntimeException)
853cdf0e10cSrcweir     {
854cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
855cdf0e10cSrcweir 
856cdf0e10cSrcweir         sal_Int32 i, nParas;
857cdf0e10cSrcweir         ::rtl::OUString aRes;
858cdf0e10cSrcweir         for( i=0, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
859cdf0e10cSrcweir             aRes += mpImpl->GetParagraph(i).getText();
860cdf0e10cSrcweir 
861cdf0e10cSrcweir         return aRes;
862cdf0e10cSrcweir     }
863cdf0e10cSrcweir 
864cdf0e10cSrcweir     ::rtl::OUString SAL_CALL AccessibleStaticTextBase::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
865cdf0e10cSrcweir     {
866cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
867cdf0e10cSrcweir 
868cdf0e10cSrcweir         if( nStartIndex > nEndIndex )
869cdf0e10cSrcweir             ::std::swap(nStartIndex, nEndIndex);
870*9b8096d0SSteve Yin 		//IAccessibility2 Implementation 2009-----
871*9b8096d0SSteve Yin 		//if startindex equals endindex we will get nothing. So return an empty string directly.
872*9b8096d0SSteve Yin 		if ( nStartIndex == nEndIndex )
873*9b8096d0SSteve Yin 		{
874*9b8096d0SSteve Yin 			::rtl::OUString sEmptyStr;
875*9b8096d0SSteve Yin 			return sEmptyStr;
876*9b8096d0SSteve Yin 		}
877*9b8096d0SSteve Yin 		sal_Bool bStart = mpImpl->RemoveLineBreakCount( nStartIndex );
878*9b8096d0SSteve Yin 		//if the start index is just at a "\n", we need to begin from the next char
879*9b8096d0SSteve Yin 		if ( bStart )
880*9b8096d0SSteve Yin 		{
881*9b8096d0SSteve Yin 			nStartIndex++;
882*9b8096d0SSteve Yin 		}
883*9b8096d0SSteve Yin 		//we need to find out whether the previous position of the current endindex is at "\n" or not
884*9b8096d0SSteve Yin 		//if yes we need to mark it and add "\n" at the end of the result
885*9b8096d0SSteve Yin 		sal_Int32 nTemp = nEndIndex - 1;
886*9b8096d0SSteve Yin 		sal_Bool bEnd = mpImpl->RemoveLineBreakCount( nTemp );
887*9b8096d0SSteve Yin 		sal_Bool bTemp = mpImpl->RemoveLineBreakCount( nEndIndex );
888*9b8096d0SSteve Yin 		//if the below condition is true it indicates an empty paragraph with just a "\n"
889*9b8096d0SSteve Yin 		//so we need to set one "\n" flag to avoid duplication.
890*9b8096d0SSteve Yin 		if ( bStart && bEnd && ( nStartIndex == nEndIndex) )
891*9b8096d0SSteve Yin 		{
892*9b8096d0SSteve Yin 			bEnd = sal_False;
893*9b8096d0SSteve Yin 		}
894*9b8096d0SSteve Yin 		//if the current endindex is at a "\n", we need to increase endindex by 1 to make sure
895*9b8096d0SSteve Yin 		//the char before "\n" is included. Because string returned by this function will not include
896*9b8096d0SSteve Yin 		//the char at the endindex.
897*9b8096d0SSteve Yin 		if ( bTemp )
898*9b8096d0SSteve Yin 		{
899*9b8096d0SSteve Yin 			nEndIndex++;
900*9b8096d0SSteve Yin 		}
901*9b8096d0SSteve Yin 		::rtl::OUString aRes;
902cdf0e10cSrcweir         EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
903cdf0e10cSrcweir         EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
904cdf0e10cSrcweir 
905cdf0e10cSrcweir         // #102170# Special case: start and end paragraph are identical
906cdf0e10cSrcweir         if( aStartIndex.nPara == aEndIndex.nPara )
907cdf0e10cSrcweir         {
908*9b8096d0SSteve Yin 			//we don't return the string directly now for that we have to do some further process for "\n"
909*9b8096d0SSteve Yin 			aRes = mpImpl->GetParagraph( aStartIndex.nPara ).getTextRange( aStartIndex.nIndex, aEndIndex.nIndex );
910*9b8096d0SSteve Yin             //return mpImpl->GetParagraph( aStartIndex.nPara ).getTextRange( aStartIndex.nIndex, aEndIndex.nIndex );
911*9b8096d0SSteve Yin 			//-----IAccessibility2 Implementation 2009
912cdf0e10cSrcweir         }
913cdf0e10cSrcweir         else
914cdf0e10cSrcweir         {
915cdf0e10cSrcweir             sal_Int32 i( aStartIndex.nPara );
916*9b8096d0SSteve Yin 	    		//IAccessibility2 Implementation 2009-----
917*9b8096d0SSteve Yin 	            aRes = mpImpl->GetParagraph(i).getTextRange( aStartIndex.nIndex,
918*9b8096d0SSteve Yin                                                                         mpImpl->GetParagraph(i).getCharacterCount()/*-1*/);
919*9b8096d0SSteve Yin 			//-----IAccessibility2 Implementation 2009
920cdf0e10cSrcweir             ++i;
921cdf0e10cSrcweir 
922cdf0e10cSrcweir             // paragraphs inbetween are fully included
923cdf0e10cSrcweir             for( ; i<aEndIndex.nPara; ++i )
924*9b8096d0SSteve Yin 	    //IAccessibility2 Implementation 2009-----
925*9b8096d0SSteve Yin 			{
926*9b8096d0SSteve Yin 				aRes += rtl::OUString(cNewLine);
927cdf0e10cSrcweir                 aRes += mpImpl->GetParagraph(i).getText();
928*9b8096d0SSteve Yin 			}
929cdf0e10cSrcweir 
930cdf0e10cSrcweir             if( i<=aEndIndex.nPara )
931*9b8096d0SSteve Yin 			{
932*9b8096d0SSteve Yin 				//if the below condition is mathed it means the endindex is at mid of the last paragraph
933*9b8096d0SSteve Yin 				//we need to add a "\n" before we add the last part of the string.
934*9b8096d0SSteve Yin 				if ( !bEnd && aEndIndex.nIndex )
935*9b8096d0SSteve Yin 				{
936*9b8096d0SSteve Yin 					aRes += rtl::OUString(cNewLine);
937cdf0e10cSrcweir 				}
938*9b8096d0SSteve Yin                 aRes += mpImpl->GetParagraph(i).getTextRange( 0, aEndIndex.nIndex );
939*9b8096d0SSteve Yin 			}
940*9b8096d0SSteve Yin             //return aRes;
941*9b8096d0SSteve Yin         }
942*9b8096d0SSteve Yin 		//According the the flag we marked before, we have to add "\n" at the beginning
943*9b8096d0SSteve Yin 		//or at the end of the result string.
944*9b8096d0SSteve Yin 		if ( bStart )
945*9b8096d0SSteve Yin 		{
946*9b8096d0SSteve Yin 			aRes = rtl::OUString(cNewLine) + aRes;
947*9b8096d0SSteve Yin 		}
948*9b8096d0SSteve Yin 		if ( bEnd )
949*9b8096d0SSteve Yin 		{
950*9b8096d0SSteve Yin 			aRes += rtl::OUString(cNewLine);
951*9b8096d0SSteve Yin 		}
952*9b8096d0SSteve Yin 		return aRes;
953*9b8096d0SSteve Yin 		//-----IAccessibility2 Implementation 2009
954cdf0e10cSrcweir     }
955cdf0e10cSrcweir 
956cdf0e10cSrcweir     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
957cdf0e10cSrcweir     {
958*9b8096d0SSteve Yin     	//IAccessibility2 Implementation 2009-----
959cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
960cdf0e10cSrcweir 
961*9b8096d0SSteve Yin 		sal_Bool bLineBreak = mpImpl->RemoveLineBreakCount( nIndex );
962*9b8096d0SSteve Yin 	//-----IAccessibility2 Implementation 2009
963cdf0e10cSrcweir         EPosition aPos( mpImpl->Range2Internal(nIndex) );
964cdf0e10cSrcweir 
965cdf0e10cSrcweir         ::com::sun::star::accessibility::TextSegment aResult;
966cdf0e10cSrcweir 
967cdf0e10cSrcweir         if( AccessibleTextType::PARAGRAPH == aTextType )
968cdf0e10cSrcweir         {
969cdf0e10cSrcweir             // #106393# Special casing one behind last paragraph is
970cdf0e10cSrcweir             // not necessary, since then, we return the content and
971cdf0e10cSrcweir             // boundary of that last paragraph. Range2Internal is
972cdf0e10cSrcweir             // tolerant against that, and returns the last paragraph
973cdf0e10cSrcweir             // in aPos.nPara.
974cdf0e10cSrcweir 
975cdf0e10cSrcweir             // retrieve full text of the paragraph
976cdf0e10cSrcweir             aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara ).getText();
977cdf0e10cSrcweir 
978cdf0e10cSrcweir             // #112814# Adapt the start index with the paragraph offset
979cdf0e10cSrcweir             aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara, 0 ) );
980cdf0e10cSrcweir             aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
981cdf0e10cSrcweir         }
982*9b8096d0SSteve Yin 	//IAccessibility2 Implementation 2009-----
983*9b8096d0SSteve Yin         else if ( AccessibleTextType::ATTRIBUTE_RUN == aTextType )
984*9b8096d0SSteve Yin         {
985*9b8096d0SSteve Yin               SvxAccessibleTextAdapter& rTextForwarder = mpImpl->GetParagraph( aPos.nIndex ).GetTextForwarder();
986*9b8096d0SSteve Yin               sal_uInt16 nStartIndex, nEndIndex;
987*9b8096d0SSteve Yin               if ( rTextForwarder.GetAttributeRun( nStartIndex, nEndIndex, aPos.nPara, aPos.nIndex, sal_True ) )
988*9b8096d0SSteve Yin               {
989*9b8096d0SSteve Yin                      aResult.SegmentText = getTextRange( nStartIndex, nEndIndex );
990*9b8096d0SSteve Yin                      aResult.SegmentStart = nStartIndex;
991*9b8096d0SSteve Yin                      aResult.SegmentEnd = nEndIndex;
992*9b8096d0SSteve Yin               }
993*9b8096d0SSteve Yin         }
994*9b8096d0SSteve Yin 	//-----IAccessibility2 Implementation 2009
995cdf0e10cSrcweir         else
996cdf0e10cSrcweir         {
997cdf0e10cSrcweir             // No special handling required, forward to wrapped class
998cdf0e10cSrcweir             aResult = mpImpl->GetParagraph( aPos.nPara ).getTextAtIndex( aPos.nIndex, aTextType );
999cdf0e10cSrcweir 
1000cdf0e10cSrcweir             // #112814# Adapt the start index with the paragraph offset
1001cdf0e10cSrcweir             mpImpl->CorrectTextSegment( aResult, aPos.nPara );
1002*9b8096d0SSteve Yin 	    //IAccessibility2 Implementation 2009-----
1003*9b8096d0SSteve Yin 			if ( bLineBreak )
1004*9b8096d0SSteve Yin 			{
1005*9b8096d0SSteve Yin 				aResult.SegmentText = rtl::OUString(cNewLine);
1006*9b8096d0SSteve Yin 			}
1007*9b8096d0SSteve Yin 	    //-----IAccessibility2 Implementation 2009
1008cdf0e10cSrcweir         }
1009cdf0e10cSrcweir 
1010cdf0e10cSrcweir         return aResult;
1011cdf0e10cSrcweir     }
1012cdf0e10cSrcweir 
1013cdf0e10cSrcweir     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1014cdf0e10cSrcweir     {
1015cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1016*9b8096d0SSteve Yin 		//IAccessibility2 Implementation 2009-----
1017*9b8096d0SSteve Yin 		sal_Int32 nOldIdx = nIndex;
1018*9b8096d0SSteve Yin 		sal_Bool bLineBreak =  mpImpl->RemoveLineBreakCount( nIndex );
1019*9b8096d0SSteve Yin 		//-----IAccessibility2 Implementation 2009
1020cdf0e10cSrcweir         EPosition aPos( mpImpl->Range2Internal(nIndex) );
1021cdf0e10cSrcweir 
1022cdf0e10cSrcweir         ::com::sun::star::accessibility::TextSegment aResult;
1023cdf0e10cSrcweir 
1024cdf0e10cSrcweir         if( AccessibleTextType::PARAGRAPH == aTextType )
1025cdf0e10cSrcweir         {
1026cdf0e10cSrcweir             if( aPos.nIndex == mpImpl->GetParagraph( aPos.nPara ).getCharacterCount() )
1027cdf0e10cSrcweir             {
1028cdf0e10cSrcweir                 // #103589# Special casing one behind the last paragraph
1029cdf0e10cSrcweir                 aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara ).getText();
1030cdf0e10cSrcweir 
1031cdf0e10cSrcweir                 // #112814# Adapt the start index with the paragraph offset
1032cdf0e10cSrcweir                 aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara, 0 ) );
1033cdf0e10cSrcweir             }
1034cdf0e10cSrcweir             else if( aPos.nPara > 0 )
1035cdf0e10cSrcweir             {
1036cdf0e10cSrcweir                 aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara - 1 ).getText();
1037cdf0e10cSrcweir 
1038cdf0e10cSrcweir                 // #112814# Adapt the start index with the paragraph offset
1039cdf0e10cSrcweir                 aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara - 1, 0 ) );
1040cdf0e10cSrcweir             }
1041cdf0e10cSrcweir 
1042cdf0e10cSrcweir             aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
1043cdf0e10cSrcweir         }
1044cdf0e10cSrcweir         else
1045cdf0e10cSrcweir         {
1046cdf0e10cSrcweir             // No special handling required, forward to wrapped class
1047cdf0e10cSrcweir             aResult = mpImpl->GetParagraph( aPos.nPara ).getTextBeforeIndex( aPos.nIndex, aTextType );
1048cdf0e10cSrcweir 
1049cdf0e10cSrcweir             // #112814# Adapt the start index with the paragraph offset
1050cdf0e10cSrcweir             mpImpl->CorrectTextSegment( aResult, aPos.nPara );
1051*9b8096d0SSteve Yin 			//IAccessibility2 Implementation 2009-----
1052*9b8096d0SSteve Yin 			if ( bLineBreak && (nOldIdx-1) >= 0)
1053*9b8096d0SSteve Yin 			{
1054*9b8096d0SSteve Yin 				aResult = getTextAtIndex( nOldIdx-1, aTextType );
1055*9b8096d0SSteve Yin 			}
1056*9b8096d0SSteve Yin 			//-----IAccessibility2 Implementation 2009
1057cdf0e10cSrcweir         }
1058cdf0e10cSrcweir 
1059cdf0e10cSrcweir         return aResult;
1060cdf0e10cSrcweir     }
1061cdf0e10cSrcweir 
1062cdf0e10cSrcweir     ::com::sun::star::accessibility::TextSegment SAL_CALL AccessibleStaticTextBase::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
1063cdf0e10cSrcweir     {
1064cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1065*9b8096d0SSteve Yin 	//IAccessibility2 Implementation 2009-----
1066*9b8096d0SSteve Yin 		sal_Int32 nTemp = nIndex+1;
1067*9b8096d0SSteve Yin 		sal_Bool bLineBreak = mpImpl->RemoveLineBreakCount( nTemp );
1068*9b8096d0SSteve Yin 		mpImpl->RemoveLineBreakCount( nIndex );
1069*9b8096d0SSteve Yin 	//-----IAccessibility2 Implementation 2009
1070cdf0e10cSrcweir         EPosition aPos( mpImpl->Range2Internal(nIndex) );
1071cdf0e10cSrcweir 
1072cdf0e10cSrcweir         ::com::sun::star::accessibility::TextSegment aResult;
1073cdf0e10cSrcweir 
1074cdf0e10cSrcweir         if( AccessibleTextType::PARAGRAPH == aTextType )
1075cdf0e10cSrcweir         {
1076cdf0e10cSrcweir             // Special casing one behind the last paragraph is not
1077cdf0e10cSrcweir             // necessary, this case is invalid here for
1078cdf0e10cSrcweir             // getTextBehindIndex
1079cdf0e10cSrcweir             if( aPos.nPara + 1 < mpImpl->GetParagraphCount() )
1080cdf0e10cSrcweir             {
1081cdf0e10cSrcweir                 aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara + 1 ).getText();
1082cdf0e10cSrcweir 
1083cdf0e10cSrcweir                 // #112814# Adapt the start index with the paragraph offset
1084cdf0e10cSrcweir                 aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara + 1, 0 ) );
1085cdf0e10cSrcweir                 aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
1086cdf0e10cSrcweir             }
1087cdf0e10cSrcweir         }
1088cdf0e10cSrcweir         else
1089cdf0e10cSrcweir         {
1090cdf0e10cSrcweir             // No special handling required, forward to wrapped class
1091cdf0e10cSrcweir             aResult = mpImpl->GetParagraph( aPos.nPara ).getTextBehindIndex( aPos.nIndex, aTextType );
1092cdf0e10cSrcweir 
1093cdf0e10cSrcweir             // #112814# Adapt the start index with the paragraph offset
1094cdf0e10cSrcweir             mpImpl->CorrectTextSegment( aResult, aPos.nPara );
1095*9b8096d0SSteve Yin 			//IAccessibility2 Implementation 2009-----
1096*9b8096d0SSteve Yin 			if ( bLineBreak )
1097*9b8096d0SSteve Yin 			{
1098*9b8096d0SSteve Yin 				aResult.SegmentText = rtl::OUString(cNewLine) + aResult.SegmentText;
1099*9b8096d0SSteve Yin 			}
1100*9b8096d0SSteve Yin 			//-----IAccessibility2 Implementation 2009
1101cdf0e10cSrcweir        }
1102cdf0e10cSrcweir 
1103cdf0e10cSrcweir         return aResult;
1104cdf0e10cSrcweir     }
1105cdf0e10cSrcweir 
1106cdf0e10cSrcweir     sal_Bool SAL_CALL AccessibleStaticTextBase::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1107cdf0e10cSrcweir     {
1108cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1109cdf0e10cSrcweir 
1110cdf0e10cSrcweir         if( nStartIndex > nEndIndex )
1111cdf0e10cSrcweir             ::std::swap(nStartIndex, nEndIndex);
1112cdf0e10cSrcweir 
1113cdf0e10cSrcweir         EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
1114cdf0e10cSrcweir         EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
1115cdf0e10cSrcweir 
1116cdf0e10cSrcweir         return mpImpl->CopyText( aStartIndex.nPara, aStartIndex.nIndex,
1117cdf0e10cSrcweir                                  aEndIndex.nPara, aEndIndex.nIndex );
1118cdf0e10cSrcweir     }
1119cdf0e10cSrcweir 
1120cdf0e10cSrcweir     // XAccessibleTextAttributes
1121cdf0e10cSrcweir     uno::Sequence< beans::PropertyValue > AccessibleStaticTextBase::getDefaultAttributes( const uno::Sequence< ::rtl::OUString >& RequestedAttributes ) throw (uno::RuntimeException)
1122cdf0e10cSrcweir     {
1123cdf0e10cSrcweir         // get the intersection of the default attributes of all paragraphs
1124cdf0e10cSrcweir 
1125cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1126cdf0e10cSrcweir 
1127cdf0e10cSrcweir         PropertyValueVector aDefAttrVec( mpImpl->GetParagraph( 0 ).getDefaultAttributes( RequestedAttributes ) );
1128cdf0e10cSrcweir 
1129cdf0e10cSrcweir         const sal_Int32 nParaCount = mpImpl->GetParagraphCount();
1130cdf0e10cSrcweir         for ( sal_Int32 nPara = 1; nPara < nParaCount; ++nPara )
1131cdf0e10cSrcweir         {
1132cdf0e10cSrcweir             uno::Sequence< beans::PropertyValue > aSeq = mpImpl->GetParagraph( nPara ).getDefaultAttributes( RequestedAttributes );
1133cdf0e10cSrcweir             PropertyValueVector aIntersectionVec;
1134cdf0e10cSrcweir 
1135cdf0e10cSrcweir             PropertyValueVector::const_iterator aEnd = aDefAttrVec.end();
1136cdf0e10cSrcweir             for ( PropertyValueVector::const_iterator aItr = aDefAttrVec.begin(); aItr != aEnd; ++aItr )
1137cdf0e10cSrcweir             {
1138cdf0e10cSrcweir                 const beans::PropertyValue* pItr = aSeq.getConstArray();
1139cdf0e10cSrcweir                 const beans::PropertyValue* pEnd  = pItr + aSeq.getLength();
1140cdf0e10cSrcweir                 const beans::PropertyValue* pFind = ::std::find_if( pItr, pEnd, ::std::bind2nd( PropertyValueEqualFunctor(), boost::cref( *aItr ) ) );
1141cdf0e10cSrcweir                 if ( pFind != pEnd )
1142cdf0e10cSrcweir                 {
1143cdf0e10cSrcweir                     aIntersectionVec.push_back( *pFind );
1144cdf0e10cSrcweir                 }
1145cdf0e10cSrcweir             }
1146cdf0e10cSrcweir 
1147cdf0e10cSrcweir             aDefAttrVec.swap( aIntersectionVec );
1148cdf0e10cSrcweir 
1149cdf0e10cSrcweir             if ( aDefAttrVec.empty() )
1150cdf0e10cSrcweir             {
1151cdf0e10cSrcweir                 break;
1152cdf0e10cSrcweir             }
1153cdf0e10cSrcweir         }
1154cdf0e10cSrcweir 
1155cdf0e10cSrcweir         return aDefAttrVec.getAsConstList();
1156cdf0e10cSrcweir     }
1157cdf0e10cSrcweir 
1158cdf0e10cSrcweir     uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleStaticTextBase::getRunAttributes( sal_Int32 nIndex, const uno::Sequence< ::rtl::OUString >& RequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1159cdf0e10cSrcweir     {
1160cdf0e10cSrcweir         // get those default attributes of the paragraph, which are not part
1161cdf0e10cSrcweir         // of the intersection of all paragraphs and add them to the run attributes
1162cdf0e10cSrcweir 
1163cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1164cdf0e10cSrcweir 
1165cdf0e10cSrcweir         EPosition aPos( mpImpl->Index2Internal( nIndex ) );
1166cdf0e10cSrcweir         AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( aPos.nPara );
1167cdf0e10cSrcweir         uno::Sequence< beans::PropertyValue > aDefAttrSeq = rPara.getDefaultAttributes( RequestedAttributes );
1168cdf0e10cSrcweir         uno::Sequence< beans::PropertyValue > aRunAttrSeq = rPara.getRunAttributes( aPos.nIndex, RequestedAttributes );
1169cdf0e10cSrcweir         uno::Sequence< beans::PropertyValue > aIntersectionSeq = getDefaultAttributes( RequestedAttributes );
1170cdf0e10cSrcweir         PropertyValueVector aDiffVec;
1171cdf0e10cSrcweir 
1172cdf0e10cSrcweir         const beans::PropertyValue* pDefAttr = aDefAttrSeq.getConstArray();
1173cdf0e10cSrcweir         const sal_Int32 nLength = aDefAttrSeq.getLength();
1174cdf0e10cSrcweir         for ( sal_Int32 i = 0; i < nLength; ++i )
1175cdf0e10cSrcweir         {
1176cdf0e10cSrcweir             const beans::PropertyValue* pItr = aIntersectionSeq.getConstArray();
1177cdf0e10cSrcweir             const beans::PropertyValue* pEnd  = pItr + aIntersectionSeq.getLength();
1178cdf0e10cSrcweir             const beans::PropertyValue* pFind = ::std::find_if( pItr, pEnd, ::std::bind2nd( PropertyValueEqualFunctor(), boost::cref( pDefAttr[i] ) ) );
1179cdf0e10cSrcweir             if ( pFind == pEnd && pDefAttr[i].Handle != 0)
1180cdf0e10cSrcweir             {
1181cdf0e10cSrcweir                 aDiffVec.push_back( pDefAttr[i] );
1182cdf0e10cSrcweir             }
1183cdf0e10cSrcweir         }
1184cdf0e10cSrcweir 
1185cdf0e10cSrcweir         return ::comphelper::concatSequences( aRunAttrSeq, aDiffVec.getAsConstList() );
1186cdf0e10cSrcweir     }
1187cdf0e10cSrcweir 
1188cdf0e10cSrcweir     Rectangle AccessibleStaticTextBase::GetParagraphBoundingBox() const
1189cdf0e10cSrcweir     {
1190cdf0e10cSrcweir         return mpImpl->GetParagraphBoundingBox();
1191cdf0e10cSrcweir     }
1192cdf0e10cSrcweir 
1193cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase::GetParagraphIndex() const
1194cdf0e10cSrcweir     {
1195cdf0e10cSrcweir         return mpImpl->GetParagraphIndex();
1196cdf0e10cSrcweir     }
1197cdf0e10cSrcweir 
1198cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase::GetParagraphCount() const
1199cdf0e10cSrcweir     {
1200cdf0e10cSrcweir         return mpImpl->GetParagraphCount();
1201cdf0e10cSrcweir     }
1202cdf0e10cSrcweir 
1203cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase::GetLineCount( sal_Int32 nParagraph ) const
1204cdf0e10cSrcweir     {
1205cdf0e10cSrcweir         return mpImpl->GetLineCount( nParagraph );
1206cdf0e10cSrcweir     }
1207cdf0e10cSrcweir 
1208cdf0e10cSrcweir }  // end of namespace accessibility
1209cdf0e10cSrcweir 
1210cdf0e10cSrcweir //------------------------------------------------------------------------
1211