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