xref: /AOO41X/main/editeng/source/accessibility/AccessibleStaticTextBase.cxx (revision 441693ebd5224cbcf861f80a400de51a591b769d)
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:
PropertyValueEqualFunctor()79cdf0e10cSrcweir         PropertyValueEqualFunctor()
80cdf0e10cSrcweir         {}
operator ()(const beans::PropertyValue & lhs,const beans::PropertyValue & rhs) const81cdf0e10cSrcweir         bool operator() ( const beans::PropertyValue& lhs, const beans::PropertyValue& rhs ) const
82cdf0e10cSrcweir         {
83cdf0e10cSrcweir             return ( lhs.Name == rhs.Name && lhs.Value == rhs.Value );
84cdf0e10cSrcweir         }
85cdf0e10cSrcweir     };
869b8096d0SSteve Yin sal_Unicode cNewLine(0x0a);
87cdf0e10cSrcweir 	//------------------------------------------------------------------------
88cdf0e10cSrcweir 	//
89cdf0e10cSrcweir 	// Static Helper
90cdf0e10cSrcweir 	//
91cdf0e10cSrcweir 	//------------------------------------------------------------------------
MakeSelection(sal_Int32 nStartPara,sal_Int32 nStartIndex,sal_Int32 nEndPara,sal_Int32 nEndIndex)92cdf0e10cSrcweir     ESelection MakeSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
93cdf0e10cSrcweir                               sal_Int32 nEndPara, sal_Int32 nEndIndex )
94cdf0e10cSrcweir     {
95cdf0e10cSrcweir         DBG_ASSERT(nStartPara >= 0 && nStartPara <= USHRT_MAX &&
96cdf0e10cSrcweir                    nStartIndex >= 0 && nStartIndex <= USHRT_MAX &&
97cdf0e10cSrcweir                    nEndPara >= 0 && nEndPara <= USHRT_MAX &&
98cdf0e10cSrcweir                    nEndIndex >= 0 && nEndIndex <= USHRT_MAX ,
99cdf0e10cSrcweir                    "AccessibleStaticTextBase_Impl::MakeSelection: index value overflow");
100cdf0e10cSrcweir 
101cdf0e10cSrcweir         return ESelection( static_cast< sal_uInt16 >(nStartPara), static_cast< sal_uInt16 >(nStartIndex),
102cdf0e10cSrcweir                            static_cast< sal_uInt16 >(nEndPara), static_cast< sal_uInt16 >(nEndIndex) );
103cdf0e10cSrcweir     }
104cdf0e10cSrcweir 
105cdf0e10cSrcweir 	//------------------------------------------------------------------------
106cdf0e10cSrcweir 	//
107cdf0e10cSrcweir 	// AccessibleStaticTextBase_Impl declaration
108cdf0e10cSrcweir 	//
109cdf0e10cSrcweir 	//------------------------------------------------------------------------
110cdf0e10cSrcweir 
111cdf0e10cSrcweir     DBG_NAME( AccessibleStaticTextBase_Impl );
112cdf0e10cSrcweir 
113cdf0e10cSrcweir     /** AccessibleStaticTextBase_Impl
114cdf0e10cSrcweir 
115cdf0e10cSrcweir     	This class implements the AccessibleStaticTextBase
116cdf0e10cSrcweir     	functionality, mainly by forwarding the calls to an aggregated
117cdf0e10cSrcweir     	AccessibleEditableTextPara. As this is a therefore non-trivial
118cdf0e10cSrcweir     	adapter, factoring out the common functionality from
119cdf0e10cSrcweir     	AccessibleEditableTextPara might be a profitable future task.
120cdf0e10cSrcweir      */
121cdf0e10cSrcweir     class AccessibleStaticTextBase_Impl
122cdf0e10cSrcweir     {
1239b8096d0SSteve Yin 		friend class AccessibleStaticTextBase;
124cdf0e10cSrcweir     public:
125cdf0e10cSrcweir 
126cdf0e10cSrcweir         // receive pointer to our frontend class and view window
127cdf0e10cSrcweir         AccessibleStaticTextBase_Impl();
128cdf0e10cSrcweir         ~AccessibleStaticTextBase_Impl();
129cdf0e10cSrcweir 
GetEditSource() const130cdf0e10cSrcweir         SvxEditSourceAdapter& GetEditSource() const SAL_THROW((uno::RuntimeException))
131cdf0e10cSrcweir         {
132cdf0e10cSrcweir             DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
133cdf0e10cSrcweir 
134cdf0e10cSrcweir             return maEditSource;
135cdf0e10cSrcweir         }
136cdf0e10cSrcweir         void SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException));
137cdf0e10cSrcweir 
SetEventSource(const uno::Reference<XAccessible> & rInterface)138cdf0e10cSrcweir         void SetEventSource( const uno::Reference< XAccessible >& rInterface )
139cdf0e10cSrcweir         {
140cdf0e10cSrcweir             DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
141cdf0e10cSrcweir 
142cdf0e10cSrcweir             mxThis = rInterface;
143cdf0e10cSrcweir         }
GetEventSource() const144cdf0e10cSrcweir         uno::Reference< XAccessible > GetEventSource() const
145cdf0e10cSrcweir         {
146cdf0e10cSrcweir             DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
147cdf0e10cSrcweir 
148cdf0e10cSrcweir             return mxThis;
149cdf0e10cSrcweir         }
150cdf0e10cSrcweir 
151cdf0e10cSrcweir         void SetOffset( const Point& );
GetOffset() const152cdf0e10cSrcweir         Point GetOffset() const
153cdf0e10cSrcweir         {
154cdf0e10cSrcweir             DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
155cdf0e10cSrcweir 
156cdf0e10cSrcweir             ::osl::MutexGuard aGuard( maMutex ); Point aPoint( maOffset );
157cdf0e10cSrcweir             return aPoint;
158cdf0e10cSrcweir         }
159cdf0e10cSrcweir 
160cdf0e10cSrcweir         void UpdateChildren();
161cdf0e10cSrcweir         void Dispose();
162cdf0e10cSrcweir 
163cdf0e10cSrcweir #ifdef DBG_UTIL
164cdf0e10cSrcweir         void CheckInvariants() const;
165cdf0e10cSrcweir #endif
166cdf0e10cSrcweir 
167cdf0e10cSrcweir         AccessibleEditableTextPara& GetParagraph( sal_Int32 nPara ) const;
168cdf0e10cSrcweir         sal_Int32 					GetParagraphCount() const;
169cdf0e10cSrcweir         sal_Int32                   GetParagraphIndex() const;
170cdf0e10cSrcweir         sal_Int32                   GetLineCount( sal_Int32 nParagraph ) const;
171cdf0e10cSrcweir 
Index2Internal(sal_Int32 nFlatIndex) const172cdf0e10cSrcweir         EPosition                   Index2Internal( sal_Int32 nFlatIndex ) const
173cdf0e10cSrcweir         {
174cdf0e10cSrcweir             DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
175cdf0e10cSrcweir 
176cdf0e10cSrcweir             return ImpCalcInternal( nFlatIndex, false );
177cdf0e10cSrcweir         }
178cdf0e10cSrcweir 
Range2Internal(sal_Int32 nFlatIndex) const179cdf0e10cSrcweir         EPosition                   Range2Internal( sal_Int32 nFlatIndex ) const
180cdf0e10cSrcweir         {
181cdf0e10cSrcweir             DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
182cdf0e10cSrcweir 
183cdf0e10cSrcweir             return ImpCalcInternal( nFlatIndex, true );
184cdf0e10cSrcweir         }
185cdf0e10cSrcweir 
186cdf0e10cSrcweir         sal_Int32					Internal2Index( EPosition nEEIndex ) const;
187cdf0e10cSrcweir 
188cdf0e10cSrcweir         void						CorrectTextSegment( TextSegment&	aTextSegment,
189cdf0e10cSrcweir                                                         int				nPara	) const;
190cdf0e10cSrcweir 
191cdf0e10cSrcweir         sal_Bool					SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
192cdf0e10cSrcweir                                                   sal_Int32 nEndPara, sal_Int32 nEndIndex );
193cdf0e10cSrcweir         sal_Bool					CopyText( sal_Int32 nStartPara, sal_Int32 nStartIndex,
194cdf0e10cSrcweir                                               sal_Int32 nEndPara, sal_Int32 nEndIndex );
195cdf0e10cSrcweir 
196cdf0e10cSrcweir         Rectangle                   GetParagraphBoundingBox() const;
1979b8096d0SSteve Yin 		sal_Bool					RemoveLineBreakCount( sal_Int32& rIndex );
198cdf0e10cSrcweir 
199cdf0e10cSrcweir     private:
200cdf0e10cSrcweir 
201cdf0e10cSrcweir         EPosition 					ImpCalcInternal( sal_Int32 nFlatIndex, bool bExclusive ) const;
202cdf0e10cSrcweir 
203cdf0e10cSrcweir         // our frontend class (the one implementing the actual
204cdf0e10cSrcweir         // interface). That's not necessarily the one containing the impl
205cdf0e10cSrcweir         // pointer
206cdf0e10cSrcweir         uno::Reference< XAccessible > mxThis;
207cdf0e10cSrcweir 
208cdf0e10cSrcweir         // implements our functionality, we're just an adapter (guarded by solar mutex)
209cdf0e10cSrcweir         mutable AccessibleEditableTextPara* mpTextParagraph;
210cdf0e10cSrcweir 
211cdf0e10cSrcweir         uno::Reference< XAccessible > mxParagraph;
212cdf0e10cSrcweir 
213cdf0e10cSrcweir         // a wrapper for the text forwarders (guarded by solar mutex)
214cdf0e10cSrcweir         mutable SvxEditSourceAdapter maEditSource;
215cdf0e10cSrcweir 
216cdf0e10cSrcweir         // guard for maOffset
217cdf0e10cSrcweir         mutable ::osl::Mutex maMutex;
218cdf0e10cSrcweir 
219cdf0e10cSrcweir         /// our current offset to the containing shape/cell (guarded by maMutex)
220cdf0e10cSrcweir         Point maOffset;
221cdf0e10cSrcweir 
222cdf0e10cSrcweir     };
223cdf0e10cSrcweir 
224cdf0e10cSrcweir 	//------------------------------------------------------------------------
225cdf0e10cSrcweir 	//
226cdf0e10cSrcweir 	// AccessibleStaticTextBase_Impl implementation
227cdf0e10cSrcweir 	//
228cdf0e10cSrcweir 	//------------------------------------------------------------------------
229cdf0e10cSrcweir 
AccessibleStaticTextBase_Impl()230cdf0e10cSrcweir     AccessibleStaticTextBase_Impl::AccessibleStaticTextBase_Impl() :
231cdf0e10cSrcweir         mxThis( NULL ),
232cdf0e10cSrcweir         mpTextParagraph( new AccessibleEditableTextPara(NULL) ),
233cdf0e10cSrcweir         mxParagraph( mpTextParagraph ),
234cdf0e10cSrcweir         maEditSource(),
235cdf0e10cSrcweir         maMutex(),
236cdf0e10cSrcweir         maOffset(0,0)
237cdf0e10cSrcweir     {
238cdf0e10cSrcweir         DBG_CTOR( AccessibleStaticTextBase_Impl, NULL );
239cdf0e10cSrcweir 
240cdf0e10cSrcweir         // TODO: this is still somewhat of a hack, all the more since
241cdf0e10cSrcweir         // now the maTextParagraph has an empty parent reference set
242cdf0e10cSrcweir     }
243cdf0e10cSrcweir 
~AccessibleStaticTextBase_Impl()244cdf0e10cSrcweir     AccessibleStaticTextBase_Impl::~AccessibleStaticTextBase_Impl()
245cdf0e10cSrcweir     {
246cdf0e10cSrcweir         DBG_DTOR( AccessibleStaticTextBase_Impl, NULL );
247cdf0e10cSrcweir     }
248cdf0e10cSrcweir 
SetEditSource(::std::auto_ptr<SvxEditSource> pEditSource)249cdf0e10cSrcweir     void AccessibleStaticTextBase_Impl::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((uno::RuntimeException))
250cdf0e10cSrcweir     {
251cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
252cdf0e10cSrcweir 
253cdf0e10cSrcweir         maEditSource.SetEditSource( pEditSource );
254cdf0e10cSrcweir         if( mpTextParagraph )
255cdf0e10cSrcweir             mpTextParagraph->SetEditSource( &maEditSource );
256cdf0e10cSrcweir     }
257cdf0e10cSrcweir 
SetOffset(const Point & rPoint)258cdf0e10cSrcweir     void AccessibleStaticTextBase_Impl::SetOffset( const Point& rPoint )
259cdf0e10cSrcweir     {
260cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
261cdf0e10cSrcweir 
262cdf0e10cSrcweir         // guard against non-atomic access to maOffset data structure
263cdf0e10cSrcweir         {
264cdf0e10cSrcweir             ::osl::MutexGuard aGuard( maMutex );
265cdf0e10cSrcweir             maOffset = rPoint;
266cdf0e10cSrcweir         }
267cdf0e10cSrcweir 
268cdf0e10cSrcweir         if( mpTextParagraph )
269cdf0e10cSrcweir             mpTextParagraph->SetEEOffset( rPoint );
270cdf0e10cSrcweir 
271cdf0e10cSrcweir         // in all cases, check visibility afterwards.
272cdf0e10cSrcweir         UpdateChildren();
273cdf0e10cSrcweir     }
274cdf0e10cSrcweir 
UpdateChildren()275cdf0e10cSrcweir     void AccessibleStaticTextBase_Impl::UpdateChildren()
276cdf0e10cSrcweir     {
277cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
278cdf0e10cSrcweir 
279cdf0e10cSrcweir         // currently no children
280cdf0e10cSrcweir     }
281cdf0e10cSrcweir 
Dispose()282cdf0e10cSrcweir     void AccessibleStaticTextBase_Impl::Dispose()
283cdf0e10cSrcweir     {
284cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
285cdf0e10cSrcweir 
286cdf0e10cSrcweir         // we're the owner of the paragraph, so destroy it, too
287cdf0e10cSrcweir         if( mpTextParagraph )
288cdf0e10cSrcweir             mpTextParagraph->Dispose();
289cdf0e10cSrcweir 
290cdf0e10cSrcweir         // drop references
291cdf0e10cSrcweir         mxParagraph = NULL;
292cdf0e10cSrcweir         mxThis = NULL;
293cdf0e10cSrcweir         mpTextParagraph = NULL;
294cdf0e10cSrcweir     }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir #ifdef DBG_UTIL
CheckInvariants() const297cdf0e10cSrcweir     void AccessibleStaticTextBase_Impl::CheckInvariants() const
298cdf0e10cSrcweir     {
299cdf0e10cSrcweir         // TODO
300cdf0e10cSrcweir     }
301cdf0e10cSrcweir #endif
302cdf0e10cSrcweir 
GetParagraph(sal_Int32 nPara) const303cdf0e10cSrcweir     AccessibleEditableTextPara& AccessibleStaticTextBase_Impl::GetParagraph( sal_Int32 nPara ) const
304cdf0e10cSrcweir     {
305cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
306cdf0e10cSrcweir 
307cdf0e10cSrcweir         if( !mpTextParagraph )
308cdf0e10cSrcweir             throw lang::DisposedException (
309cdf0e10cSrcweir                 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("object has been already disposed")), mxThis );
310cdf0e10cSrcweir 
311cdf0e10cSrcweir         // TODO: Have a differnt method on AccessibleEditableTextPara
312cdf0e10cSrcweir         // that does not care about state changes
313cdf0e10cSrcweir         mpTextParagraph->SetParagraphIndex( nPara );
314cdf0e10cSrcweir 
315cdf0e10cSrcweir         return *mpTextParagraph;
316cdf0e10cSrcweir     }
317cdf0e10cSrcweir 
GetParagraphCount() const318cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase_Impl::GetParagraphCount() const
319cdf0e10cSrcweir     {
320cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
321cdf0e10cSrcweir 
322cdf0e10cSrcweir         if( !mpTextParagraph )
323cdf0e10cSrcweir             return 0;
324cdf0e10cSrcweir         else
325cdf0e10cSrcweir             return mpTextParagraph->GetTextForwarder().GetParagraphCount();
326cdf0e10cSrcweir     }
327cdf0e10cSrcweir 
GetParagraphIndex() const328cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase_Impl::GetParagraphIndex() const
329cdf0e10cSrcweir     {
330cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
331cdf0e10cSrcweir 
332cdf0e10cSrcweir         sal_Int32 nIndex = -1;
333cdf0e10cSrcweir         if( mpTextParagraph )
334cdf0e10cSrcweir             nIndex = mpTextParagraph->GetParagraphIndex();
335cdf0e10cSrcweir         return nIndex;
336cdf0e10cSrcweir     }
337cdf0e10cSrcweir 
GetLineCount(sal_Int32 nParagraph) const338cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase_Impl::GetLineCount( sal_Int32 nParagraph ) const
339cdf0e10cSrcweir     {
340cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
341cdf0e10cSrcweir 
342cdf0e10cSrcweir         sal_Int32 nIndex = 0;
343cdf0e10cSrcweir         if( mpTextParagraph )
344cdf0e10cSrcweir             nIndex = mpTextParagraph->GetTextForwarder().GetLineCount( static_cast< sal_uInt16 >(nParagraph) );
345cdf0e10cSrcweir         return nIndex;
346cdf0e10cSrcweir     }
347cdf0e10cSrcweir 
Internal2Index(EPosition nEEIndex) const348cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase_Impl::Internal2Index( EPosition nEEIndex ) const
349cdf0e10cSrcweir     {
350cdf0e10cSrcweir         sal_Int32 aRes(0);
351cdf0e10cSrcweir         int i;
352cdf0e10cSrcweir         for(i=0; i<nEEIndex.nPara; ++i)
353cdf0e10cSrcweir             aRes += GetParagraph(i).getCharacterCount();
354cdf0e10cSrcweir 
355cdf0e10cSrcweir         return aRes + nEEIndex.nIndex;
356cdf0e10cSrcweir     }
357cdf0e10cSrcweir 
CorrectTextSegment(TextSegment & aTextSegment,int nPara) const358cdf0e10cSrcweir     void AccessibleStaticTextBase_Impl::CorrectTextSegment( TextSegment&	aTextSegment,
359cdf0e10cSrcweir                                                             int				nPara	) const
360cdf0e10cSrcweir     {
361cdf0e10cSrcweir         // Keep 'invalid' values at the TextSegment
362cdf0e10cSrcweir         if( aTextSegment.SegmentStart != -1 &&
363*441693ebSDamjan Jovanovic             aTextSegment.SegmentEnd != -1 )
364cdf0e10cSrcweir         {
365cdf0e10cSrcweir             // #112814# Correct TextSegment by paragraph offset
366cdf0e10cSrcweir             sal_Int32 nOffset(0);
367cdf0e10cSrcweir             int i;
368cdf0e10cSrcweir             for(i=0; i<nPara; ++i)
369cdf0e10cSrcweir                 nOffset += GetParagraph(i).getCharacterCount();
370cdf0e10cSrcweir 
371cdf0e10cSrcweir             aTextSegment.SegmentStart += nOffset;
372cdf0e10cSrcweir             aTextSegment.SegmentEnd += nOffset;
373cdf0e10cSrcweir         }
374cdf0e10cSrcweir     }
375cdf0e10cSrcweir 
ImpCalcInternal(sal_Int32 nFlatIndex,bool bExclusive) const376cdf0e10cSrcweir     EPosition AccessibleStaticTextBase_Impl::ImpCalcInternal( sal_Int32 nFlatIndex, bool bExclusive ) const
377cdf0e10cSrcweir     {
378cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
379cdf0e10cSrcweir 
380cdf0e10cSrcweir         if( nFlatIndex < 0 )
381cdf0e10cSrcweir             throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleStaticTextBase_Impl::Index2Internal: character index out of bounds")),
382cdf0e10cSrcweir                                                   mxThis);
383cdf0e10cSrcweir         // gratuitously accepting larger indices here, AccessibleEditableTextPara will throw eventually
384cdf0e10cSrcweir 
385cdf0e10cSrcweir         sal_Int32 nCurrPara, nCurrIndex, nParas, nCurrCount;
386cdf0e10cSrcweir         for( nCurrPara=0, nParas=GetParagraphCount(), nCurrCount=0, nCurrIndex=0; nCurrPara<nParas; ++nCurrPara )
387cdf0e10cSrcweir         {
388cdf0e10cSrcweir             nCurrCount = GetParagraph( nCurrPara ).getCharacterCount();
389cdf0e10cSrcweir             nCurrIndex += nCurrCount;
3909b8096d0SSteve Yin             if( nCurrIndex >= nFlatIndex )
391cdf0e10cSrcweir             {
392cdf0e10cSrcweir                 // check overflow
393cdf0e10cSrcweir                 DBG_ASSERT(nCurrPara >= 0 && nCurrPara <= USHRT_MAX &&
394cdf0e10cSrcweir                            nFlatIndex - nCurrIndex + nCurrCount >= 0 && nFlatIndex - nCurrIndex + nCurrCount <= USHRT_MAX ,
395cdf0e10cSrcweir                            "AccessibleStaticTextBase_Impl::Index2Internal: index value overflow");
396cdf0e10cSrcweir 
397cdf0e10cSrcweir                 return EPosition( static_cast< sal_uInt16 >(nCurrPara), static_cast< sal_uInt16 >(nFlatIndex - nCurrIndex + nCurrCount) );
398cdf0e10cSrcweir             }
399cdf0e10cSrcweir         }
400cdf0e10cSrcweir 
401cdf0e10cSrcweir         // #102170# Allow one-past the end for ranges
402cdf0e10cSrcweir         if( bExclusive && nCurrIndex == nFlatIndex )
403cdf0e10cSrcweir         {
404cdf0e10cSrcweir             // check overflow
405cdf0e10cSrcweir             DBG_ASSERT(nCurrPara >= 0 && nCurrPara <= USHRT_MAX &&
406cdf0e10cSrcweir                        nFlatIndex - nCurrIndex + nCurrCount >= 0 && nFlatIndex - nCurrIndex + nCurrCount <= USHRT_MAX ,
407cdf0e10cSrcweir                        "AccessibleStaticTextBase_Impl::Index2Internal: index value overflow");
408cdf0e10cSrcweir 
409cdf0e10cSrcweir             return EPosition( static_cast< sal_uInt16 >(nCurrPara-1), static_cast< sal_uInt16 >(nFlatIndex - nCurrIndex + nCurrCount) );
410cdf0e10cSrcweir         }
411cdf0e10cSrcweir 
412cdf0e10cSrcweir         // not found? Out of bounds
413cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("AccessibleStaticTextBase_Impl::Index2Internal: character index out of bounds")),
414cdf0e10cSrcweir                                               mxThis);
415cdf0e10cSrcweir     }
416cdf0e10cSrcweir 
SetSelection(sal_Int32 nStartPara,sal_Int32 nStartIndex,sal_Int32 nEndPara,sal_Int32 nEndIndex)417cdf0e10cSrcweir     sal_Bool AccessibleStaticTextBase_Impl::SetSelection( sal_Int32 nStartPara, sal_Int32 nStartIndex,
418cdf0e10cSrcweir                                                           sal_Int32 nEndPara, sal_Int32 nEndIndex )
419cdf0e10cSrcweir     {
420cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
421cdf0e10cSrcweir 
422cdf0e10cSrcweir         if( !mpTextParagraph )
423cdf0e10cSrcweir             return sal_False;
424cdf0e10cSrcweir 
425cdf0e10cSrcweir         try
426cdf0e10cSrcweir         {
427cdf0e10cSrcweir             SvxEditViewForwarder& rCacheVF = mpTextParagraph->GetEditViewForwarder( sal_True );
428cdf0e10cSrcweir             return rCacheVF.SetSelection( MakeSelection(nStartPara, nStartIndex, nEndPara, nEndIndex) );
429cdf0e10cSrcweir         }
430cdf0e10cSrcweir         catch( const uno::RuntimeException& )
431cdf0e10cSrcweir         {
432cdf0e10cSrcweir             return sal_False;
433cdf0e10cSrcweir         }
434cdf0e10cSrcweir     }
435cdf0e10cSrcweir 
CopyText(sal_Int32 nStartPara,sal_Int32 nStartIndex,sal_Int32 nEndPara,sal_Int32 nEndIndex)436cdf0e10cSrcweir     sal_Bool AccessibleStaticTextBase_Impl::CopyText( sal_Int32 nStartPara, sal_Int32 nStartIndex,
437cdf0e10cSrcweir                                                       sal_Int32 nEndPara, sal_Int32 nEndIndex )
438cdf0e10cSrcweir     {
439cdf0e10cSrcweir         DBG_CHKTHIS( AccessibleStaticTextBase_Impl, NULL );
440cdf0e10cSrcweir 
441cdf0e10cSrcweir         if( !mpTextParagraph )
442cdf0e10cSrcweir             return sal_False;
443cdf0e10cSrcweir 
444cdf0e10cSrcweir         try
445cdf0e10cSrcweir         {
446cdf0e10cSrcweir             SvxEditViewForwarder& rCacheVF = mpTextParagraph->GetEditViewForwarder( sal_True );
447cdf0e10cSrcweir             mpTextParagraph->GetTextForwarder();	// MUST be after GetEditViewForwarder(), see method docs
448cdf0e10cSrcweir             sal_Bool aRetVal;
449cdf0e10cSrcweir 
450cdf0e10cSrcweir             // save current selection
451cdf0e10cSrcweir             ESelection aOldSelection;
452cdf0e10cSrcweir 
453cdf0e10cSrcweir             rCacheVF.GetSelection( aOldSelection );
454cdf0e10cSrcweir             rCacheVF.SetSelection( MakeSelection(nStartPara, nStartIndex, nEndPara, nEndIndex) );
455cdf0e10cSrcweir             aRetVal = rCacheVF.Copy();
456cdf0e10cSrcweir             rCacheVF.SetSelection( aOldSelection ); // restore
457cdf0e10cSrcweir 
458cdf0e10cSrcweir             return aRetVal;
459cdf0e10cSrcweir         }
460cdf0e10cSrcweir         catch( const uno::RuntimeException& )
461cdf0e10cSrcweir         {
462cdf0e10cSrcweir             return sal_False;
463cdf0e10cSrcweir         }
464cdf0e10cSrcweir     }
465cdf0e10cSrcweir 
GetParagraphBoundingBox() const466cdf0e10cSrcweir     Rectangle AccessibleStaticTextBase_Impl::GetParagraphBoundingBox() const
467cdf0e10cSrcweir     {
468cdf0e10cSrcweir         Rectangle aRect;
469cdf0e10cSrcweir         if( mpTextParagraph )
470cdf0e10cSrcweir         {
471cdf0e10cSrcweir             awt::Rectangle aAwtRect = mpTextParagraph->getBounds();
472cdf0e10cSrcweir             aRect = Rectangle( Point( aAwtRect.X, aAwtRect.Y ), Size( aAwtRect.Width, aAwtRect.Height ) );
473cdf0e10cSrcweir         }
474cdf0e10cSrcweir         else
475cdf0e10cSrcweir         {
476cdf0e10cSrcweir             aRect.SetEmpty();
477cdf0e10cSrcweir         }
478cdf0e10cSrcweir         return aRect;
479cdf0e10cSrcweir     }
4809b8096d0SSteve Yin 	//the input argument is the index(including "\n" ) in the string.
4819b8096d0SSteve Yin 	//the function will calculate the actual index(not including "\n") in the string.
4829b8096d0SSteve Yin 	//and return true if the index is just at a "\n"
RemoveLineBreakCount(sal_Int32 & rIndex)4839b8096d0SSteve Yin 	sal_Bool AccessibleStaticTextBase_Impl::RemoveLineBreakCount( sal_Int32& rIndex )
4849b8096d0SSteve Yin 	{
4859b8096d0SSteve Yin 		// get the total char number inside the cell.
4869b8096d0SSteve Yin 		sal_Int32 i, nCount, nParas;
4879b8096d0SSteve Yin         for( i=0, nCount=0, nParas=GetParagraphCount(); i<nParas; ++i )
4889b8096d0SSteve Yin             nCount += GetParagraph(i).getCharacterCount();
4899b8096d0SSteve Yin 		nCount = nCount + (nParas-1);
4909b8096d0SSteve Yin 		if( nCount == 0 &&  rIndex == 0) return sal_False;
491cdf0e10cSrcweir 
4929b8096d0SSteve Yin 
4939b8096d0SSteve Yin 		sal_Int32 nCurrPara, nCurrCount;
4949b8096d0SSteve Yin 		sal_Int32 nLineBreakPos = 0, nLineBreakCount = 0;
4959b8096d0SSteve Yin 		sal_Int32 nParaCount = GetParagraphCount();
4969b8096d0SSteve Yin 		for ( nCurrCount = 0, nCurrPara = 0; nCurrPara < nParaCount; nCurrPara++ )
4979b8096d0SSteve Yin 		{
4989b8096d0SSteve Yin 			nCurrCount += GetParagraph( nCurrPara ).getCharacterCount();
4999b8096d0SSteve Yin 			nLineBreakPos = nCurrCount++;
5009b8096d0SSteve Yin 			if ( rIndex == nLineBreakPos )
5019b8096d0SSteve Yin 			{
5029b8096d0SSteve Yin 				rIndex -= (++nLineBreakCount);//(++nLineBreakCount);
5039b8096d0SSteve Yin 				if ( rIndex < 0)
5049b8096d0SSteve Yin 				{
5059b8096d0SSteve Yin 					rIndex = 0;
5069b8096d0SSteve Yin 				}
5079b8096d0SSteve Yin 				//if the index is at the last position of the last paragraph
5089b8096d0SSteve Yin 				//there is no "\n" , so we should increase rIndex by 1 and return false.
5099b8096d0SSteve Yin 				if ( (nCurrPara+1) == nParaCount )
5109b8096d0SSteve Yin 				{
5119b8096d0SSteve Yin 					rIndex++;
5129b8096d0SSteve Yin 					return sal_False;
5139b8096d0SSteve Yin 				}
5149b8096d0SSteve Yin 				else
5159b8096d0SSteve Yin 				{
5169b8096d0SSteve Yin 					return sal_True;
5179b8096d0SSteve Yin 				}
5189b8096d0SSteve Yin 			}
5199b8096d0SSteve Yin 			else if ( rIndex < nLineBreakPos )
5209b8096d0SSteve Yin 			{
5219b8096d0SSteve Yin 				rIndex -= nLineBreakCount;
5229b8096d0SSteve Yin 				return sal_False;
5239b8096d0SSteve Yin 			}
5249b8096d0SSteve Yin 			else
5259b8096d0SSteve Yin 			{
5269b8096d0SSteve Yin 				nLineBreakCount++;
5279b8096d0SSteve Yin 			}
5289b8096d0SSteve Yin 		}
5299b8096d0SSteve Yin 		return sal_False;
5309b8096d0SSteve Yin 	}
531cdf0e10cSrcweir 	//------------------------------------------------------------------------
532cdf0e10cSrcweir 	//
533cdf0e10cSrcweir 	// AccessibleStaticTextBase implementation
534cdf0e10cSrcweir 	//
535cdf0e10cSrcweir 	//------------------------------------------------------------------------
536cdf0e10cSrcweir 
AccessibleStaticTextBase(::std::auto_ptr<SvxEditSource> pEditSource)537cdf0e10cSrcweir     AccessibleStaticTextBase::AccessibleStaticTextBase( ::std::auto_ptr< SvxEditSource > 		pEditSource ) :
538cdf0e10cSrcweir         mpImpl( new AccessibleStaticTextBase_Impl() )
539cdf0e10cSrcweir     {
540cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
541cdf0e10cSrcweir 
542cdf0e10cSrcweir         SetEditSource( pEditSource );
543cdf0e10cSrcweir     }
544cdf0e10cSrcweir 
~AccessibleStaticTextBase()545cdf0e10cSrcweir     AccessibleStaticTextBase::~AccessibleStaticTextBase()
546cdf0e10cSrcweir     {
547cdf0e10cSrcweir     }
548cdf0e10cSrcweir 
GetEditSource() const549cdf0e10cSrcweir     const SvxEditSource& AccessibleStaticTextBase::GetEditSource() const SAL_THROW((::com::sun::star::uno::RuntimeException))
550cdf0e10cSrcweir     {
551cdf0e10cSrcweir #ifdef DBG_UTIL
552cdf0e10cSrcweir         mpImpl->CheckInvariants();
553cdf0e10cSrcweir 
554cdf0e10cSrcweir         const SvxEditSource& aEditSource = mpImpl->GetEditSource();
555cdf0e10cSrcweir 
556cdf0e10cSrcweir         mpImpl->CheckInvariants();
557cdf0e10cSrcweir 
558cdf0e10cSrcweir         return aEditSource;
559cdf0e10cSrcweir #else
560cdf0e10cSrcweir         return mpImpl->GetEditSource();
561cdf0e10cSrcweir #endif
562cdf0e10cSrcweir     }
563cdf0e10cSrcweir 
SetEditSource(::std::auto_ptr<SvxEditSource> pEditSource)564cdf0e10cSrcweir     void AccessibleStaticTextBase::SetEditSource( ::std::auto_ptr< SvxEditSource > pEditSource ) SAL_THROW((::com::sun::star::uno::RuntimeException))
565cdf0e10cSrcweir     {
566cdf0e10cSrcweir #ifdef DBG_UTIL
567cdf0e10cSrcweir         // precondition: solar mutex locked
568cdf0e10cSrcweir         DBG_TESTSOLARMUTEX();
569cdf0e10cSrcweir 
570cdf0e10cSrcweir         mpImpl->CheckInvariants();
571cdf0e10cSrcweir 
572cdf0e10cSrcweir         mpImpl->SetEditSource( pEditSource );
573cdf0e10cSrcweir 
574cdf0e10cSrcweir         mpImpl->CheckInvariants();
575cdf0e10cSrcweir #else
576cdf0e10cSrcweir         mpImpl->SetEditSource( pEditSource );
577cdf0e10cSrcweir #endif
578cdf0e10cSrcweir     }
579cdf0e10cSrcweir 
SetEventSource(const uno::Reference<XAccessible> & rInterface)580cdf0e10cSrcweir     void AccessibleStaticTextBase::SetEventSource( const uno::Reference< XAccessible >& rInterface )
581cdf0e10cSrcweir     {
582cdf0e10cSrcweir #ifdef DBG_UTIL
583cdf0e10cSrcweir         mpImpl->CheckInvariants();
584cdf0e10cSrcweir #endif
585cdf0e10cSrcweir 
586cdf0e10cSrcweir         mpImpl->SetEventSource( rInterface );
587cdf0e10cSrcweir 
588cdf0e10cSrcweir #ifdef DBG_UTIL
589cdf0e10cSrcweir         mpImpl->CheckInvariants();
590cdf0e10cSrcweir #endif
591cdf0e10cSrcweir     }
592cdf0e10cSrcweir 
GetEventSource() const593cdf0e10cSrcweir     uno::Reference< XAccessible > AccessibleStaticTextBase::GetEventSource() const
594cdf0e10cSrcweir     {
595cdf0e10cSrcweir #ifdef DBG_UTIL
596cdf0e10cSrcweir         mpImpl->CheckInvariants();
597cdf0e10cSrcweir 
598cdf0e10cSrcweir         uno::Reference< XAccessible > xRet( mpImpl->GetEventSource() );
599cdf0e10cSrcweir 
600cdf0e10cSrcweir         mpImpl->CheckInvariants();
601cdf0e10cSrcweir 
602cdf0e10cSrcweir         return xRet;
603cdf0e10cSrcweir #else
604cdf0e10cSrcweir         return mpImpl->GetEventSource();
605cdf0e10cSrcweir #endif
606cdf0e10cSrcweir     }
607cdf0e10cSrcweir 
SetOffset(const Point & rPoint)608cdf0e10cSrcweir     void AccessibleStaticTextBase::SetOffset( const Point& rPoint )
609cdf0e10cSrcweir     {
610cdf0e10cSrcweir #ifdef DBG_UTIL
611cdf0e10cSrcweir         // precondition: solar mutex locked
612cdf0e10cSrcweir         DBG_TESTSOLARMUTEX();
613cdf0e10cSrcweir 
614cdf0e10cSrcweir         mpImpl->CheckInvariants();
615cdf0e10cSrcweir 
616cdf0e10cSrcweir         mpImpl->SetOffset( rPoint );
617cdf0e10cSrcweir 
618cdf0e10cSrcweir         mpImpl->CheckInvariants();
619cdf0e10cSrcweir #else
620cdf0e10cSrcweir         mpImpl->SetOffset( rPoint );
621cdf0e10cSrcweir #endif
622cdf0e10cSrcweir     }
623cdf0e10cSrcweir 
GetOffset() const624cdf0e10cSrcweir     Point AccessibleStaticTextBase::GetOffset() const
625cdf0e10cSrcweir     {
626cdf0e10cSrcweir #ifdef DBG_UTIL
627cdf0e10cSrcweir         mpImpl->CheckInvariants();
628cdf0e10cSrcweir 
629cdf0e10cSrcweir         Point aPoint( mpImpl->GetOffset() );
630cdf0e10cSrcweir 
631cdf0e10cSrcweir         mpImpl->CheckInvariants();
632cdf0e10cSrcweir 
633cdf0e10cSrcweir         return aPoint;
634cdf0e10cSrcweir #else
635cdf0e10cSrcweir         return mpImpl->GetOffset();
636cdf0e10cSrcweir #endif
637cdf0e10cSrcweir     }
638cdf0e10cSrcweir 
UpdateChildren()639cdf0e10cSrcweir     void AccessibleStaticTextBase::UpdateChildren() SAL_THROW((::com::sun::star::uno::RuntimeException))
640cdf0e10cSrcweir     {
641cdf0e10cSrcweir #ifdef DBG_UTIL
642cdf0e10cSrcweir         // precondition: solar mutex locked
643cdf0e10cSrcweir         DBG_TESTSOLARMUTEX();
644cdf0e10cSrcweir 
645cdf0e10cSrcweir         mpImpl->CheckInvariants();
646cdf0e10cSrcweir 
647cdf0e10cSrcweir         mpImpl->UpdateChildren();
648cdf0e10cSrcweir 
649cdf0e10cSrcweir         mpImpl->CheckInvariants();
650cdf0e10cSrcweir #else
651cdf0e10cSrcweir         mpImpl->UpdateChildren();
652cdf0e10cSrcweir #endif
653cdf0e10cSrcweir     }
654cdf0e10cSrcweir 
Dispose()655cdf0e10cSrcweir     void AccessibleStaticTextBase::Dispose()
656cdf0e10cSrcweir     {
657cdf0e10cSrcweir #ifdef DBG_UTIL
658cdf0e10cSrcweir         mpImpl->CheckInvariants();
659cdf0e10cSrcweir #endif
660cdf0e10cSrcweir 
661cdf0e10cSrcweir         mpImpl->Dispose();
662cdf0e10cSrcweir 
663cdf0e10cSrcweir #ifdef DBG_UTIL
664cdf0e10cSrcweir         mpImpl->CheckInvariants();
665cdf0e10cSrcweir #endif
666cdf0e10cSrcweir     }
667cdf0e10cSrcweir 
668cdf0e10cSrcweir 	// XAccessibleContext
getAccessibleChildCount()669cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleStaticTextBase::getAccessibleChildCount() throw (uno::RuntimeException)
670cdf0e10cSrcweir     {
671cdf0e10cSrcweir         // no children at all
672cdf0e10cSrcweir         return 0;
673cdf0e10cSrcweir     }
674cdf0e10cSrcweir 
getAccessibleChild(sal_Int32)675cdf0e10cSrcweir     uno::Reference< XAccessible > SAL_CALL AccessibleStaticTextBase::getAccessibleChild( sal_Int32 /*i*/ ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
676cdf0e10cSrcweir     {
677cdf0e10cSrcweir         // no children at all
678cdf0e10cSrcweir         return uno::Reference< XAccessible >();
679cdf0e10cSrcweir     }
680cdf0e10cSrcweir 
getAccessibleAtPoint(const awt::Point &)681cdf0e10cSrcweir     uno::Reference< XAccessible > SAL_CALL AccessibleStaticTextBase::getAccessibleAtPoint( const awt::Point& /*_aPoint*/ ) throw (uno::RuntimeException)
682cdf0e10cSrcweir     {
683cdf0e10cSrcweir         // no children at all
684cdf0e10cSrcweir         return uno::Reference< XAccessible >();
685cdf0e10cSrcweir     }
686cdf0e10cSrcweir 
687cdf0e10cSrcweir 	// XAccessibleText
getCaretPosition()688cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleStaticTextBase::getCaretPosition() throw (uno::RuntimeException)
689cdf0e10cSrcweir     {
690cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
691cdf0e10cSrcweir 
692cdf0e10cSrcweir         sal_Int32 i, nPos, nParas;
693cdf0e10cSrcweir         for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
694cdf0e10cSrcweir         {
695cdf0e10cSrcweir             if( (nPos=mpImpl->GetParagraph(i).getCaretPosition()) != -1 )
696cdf0e10cSrcweir                 return nPos;
697cdf0e10cSrcweir         }
698cdf0e10cSrcweir 
699cdf0e10cSrcweir         return nPos;
700cdf0e10cSrcweir     }
701cdf0e10cSrcweir 
setCaretPosition(sal_Int32 nIndex)702cdf0e10cSrcweir     sal_Bool SAL_CALL AccessibleStaticTextBase::setCaretPosition( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
703cdf0e10cSrcweir     {
704cdf0e10cSrcweir         return setSelection(nIndex, nIndex);
705cdf0e10cSrcweir     }
706cdf0e10cSrcweir 
getCharacter(sal_Int32 nIndex)707cdf0e10cSrcweir     sal_Unicode SAL_CALL AccessibleStaticTextBase::getCharacter( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
708cdf0e10cSrcweir     {
709cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
710cdf0e10cSrcweir 
711cdf0e10cSrcweir         EPosition aPos( mpImpl->Index2Internal(nIndex) );
712cdf0e10cSrcweir 
713cdf0e10cSrcweir         return mpImpl->GetParagraph( aPos.nPara ).getCharacter( aPos.nIndex );
714cdf0e10cSrcweir     }
715cdf0e10cSrcweir 
getCharacterAttributes(sal_Int32 nIndex,const::com::sun::star::uno::Sequence<::rtl::OUString> & aRequestedAttributes)716cdf0e10cSrcweir     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)
717cdf0e10cSrcweir     {
718cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
7199b8096d0SSteve Yin 		//get the actual index without "\n"
7209b8096d0SSteve Yin 		mpImpl->RemoveLineBreakCount( nIndex );
721cdf0e10cSrcweir 
722cdf0e10cSrcweir         EPosition aPos( mpImpl->Index2Internal(nIndex) );
723cdf0e10cSrcweir 
724cdf0e10cSrcweir         return mpImpl->GetParagraph( aPos.nPara ).getCharacterAttributes( aPos.nIndex, aRequestedAttributes );
725cdf0e10cSrcweir     }
726cdf0e10cSrcweir 
getCharacterBounds(sal_Int32 nIndex)727cdf0e10cSrcweir     awt::Rectangle SAL_CALL AccessibleStaticTextBase::getCharacterBounds( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
728cdf0e10cSrcweir     {
729cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
730cdf0e10cSrcweir 
731cdf0e10cSrcweir         // #108900# Allow ranges for nIndex, as one-past-the-end
732cdf0e10cSrcweir         // values are now legal, too.
733cdf0e10cSrcweir         EPosition aPos( mpImpl->Range2Internal(nIndex) );
734cdf0e10cSrcweir 
735cdf0e10cSrcweir         // #i70916# Text in spread sheet cells return the wrong extents
736cdf0e10cSrcweir         AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( aPos.nPara );
737cdf0e10cSrcweir         awt::Rectangle aParaBounds( rPara.getBounds() );
738cdf0e10cSrcweir         awt::Rectangle aBounds( rPara.getCharacterBounds( aPos.nIndex ) );
739cdf0e10cSrcweir         aBounds.X += aParaBounds.X;
740cdf0e10cSrcweir         aBounds.Y += aParaBounds.Y;
741cdf0e10cSrcweir 
742cdf0e10cSrcweir         return aBounds;
743cdf0e10cSrcweir     }
744cdf0e10cSrcweir 
getCharacterCount()745cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleStaticTextBase::getCharacterCount() throw (uno::RuntimeException)
746cdf0e10cSrcweir     {
747cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
748cdf0e10cSrcweir 
749cdf0e10cSrcweir         sal_Int32 i, nCount, nParas;
750cdf0e10cSrcweir         for( i=0, nCount=0, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
751cdf0e10cSrcweir             nCount += mpImpl->GetParagraph(i).getCharacterCount();
7529b8096d0SSteve Yin 		//count on the number of "\n" which equals number of paragraphs decrease 1.
7539b8096d0SSteve Yin 		nCount = nCount + (nParas-1);
754cdf0e10cSrcweir         return nCount;
755cdf0e10cSrcweir     }
756cdf0e10cSrcweir 
getIndexAtPoint(const awt::Point & rPoint)757cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleStaticTextBase::getIndexAtPoint( const awt::Point& rPoint ) throw (uno::RuntimeException)
758cdf0e10cSrcweir     {
759cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
760cdf0e10cSrcweir 
761cdf0e10cSrcweir         const sal_Int32 nParas( mpImpl->GetParagraphCount() );
762cdf0e10cSrcweir         sal_Int32 nIndex;
763cdf0e10cSrcweir         int i;
764cdf0e10cSrcweir         for( i=0; i<nParas; ++i )
765cdf0e10cSrcweir         {
766cdf0e10cSrcweir             // TODO: maybe exploit the fact that paragraphs are
767cdf0e10cSrcweir             // ordered vertically for early exit
768cdf0e10cSrcweir 
769cdf0e10cSrcweir             // #i70916# Text in spread sheet cells return the wrong extents
770cdf0e10cSrcweir             AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( i );
771cdf0e10cSrcweir             awt::Rectangle aParaBounds( rPara.getBounds() );
772cdf0e10cSrcweir             awt::Point aPoint( rPoint );
773cdf0e10cSrcweir             aPoint.X -= aParaBounds.X;
774cdf0e10cSrcweir             aPoint.Y -= aParaBounds.Y;
775cdf0e10cSrcweir 
776cdf0e10cSrcweir             // #112814# Use correct index offset
777cdf0e10cSrcweir             if ( ( nIndex = rPara.getIndexAtPoint( aPoint ) ) != -1 )
778cdf0e10cSrcweir                 return mpImpl->Internal2Index( EPosition(sal::static_int_cast<sal_uInt16>(i),
779cdf0e10cSrcweir                                                          sal::static_int_cast<sal_uInt16>(nIndex)) );
780cdf0e10cSrcweir         }
781cdf0e10cSrcweir 
782cdf0e10cSrcweir         return -1;
783cdf0e10cSrcweir     }
784cdf0e10cSrcweir 
getSelectedText()785cdf0e10cSrcweir     ::rtl::OUString SAL_CALL AccessibleStaticTextBase::getSelectedText() throw (uno::RuntimeException)
786cdf0e10cSrcweir     {
787cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
788cdf0e10cSrcweir 
789cdf0e10cSrcweir         sal_Int32 nStart( getSelectionStart() );
790cdf0e10cSrcweir         sal_Int32 nEnd( getSelectionEnd() );
791cdf0e10cSrcweir 
792cdf0e10cSrcweir         // #104481# Return the empty string for 'no selection'
793cdf0e10cSrcweir         if( nStart < 0 || nEnd < 0 )
794cdf0e10cSrcweir             return ::rtl::OUString();
795cdf0e10cSrcweir 
796cdf0e10cSrcweir         return getTextRange( nStart, nEnd );
797cdf0e10cSrcweir     }
798cdf0e10cSrcweir 
getSelectionStart()799cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleStaticTextBase::getSelectionStart() throw (uno::RuntimeException)
800cdf0e10cSrcweir     {
801cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
802cdf0e10cSrcweir 
803cdf0e10cSrcweir         sal_Int32 i, nPos, nParas;
804cdf0e10cSrcweir         for( i=0, nPos=-1, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
805cdf0e10cSrcweir         {
806cdf0e10cSrcweir             if( (nPos=mpImpl->GetParagraph(i).getSelectionStart()) != -1 )
807cdf0e10cSrcweir                 return nPos;
808cdf0e10cSrcweir         }
809cdf0e10cSrcweir 
810cdf0e10cSrcweir         return nPos;
811cdf0e10cSrcweir     }
812cdf0e10cSrcweir 
getSelectionEnd()813cdf0e10cSrcweir     sal_Int32 SAL_CALL AccessibleStaticTextBase::getSelectionEnd() 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).getSelectionEnd()) != -1 )
821cdf0e10cSrcweir                 return nPos;
822cdf0e10cSrcweir         }
823cdf0e10cSrcweir 
824cdf0e10cSrcweir         return nPos;
825cdf0e10cSrcweir     }
826cdf0e10cSrcweir 
setSelection(sal_Int32 nStartIndex,sal_Int32 nEndIndex)827cdf0e10cSrcweir     sal_Bool SAL_CALL AccessibleStaticTextBase::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
828cdf0e10cSrcweir     {
829cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
830cdf0e10cSrcweir 
831cdf0e10cSrcweir         EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
832cdf0e10cSrcweir         EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
833cdf0e10cSrcweir 
834cdf0e10cSrcweir         return mpImpl->SetSelection( aStartIndex.nPara, aStartIndex.nIndex,
835cdf0e10cSrcweir                                      aEndIndex.nPara, aEndIndex.nIndex );
836cdf0e10cSrcweir     }
837cdf0e10cSrcweir 
getText()838cdf0e10cSrcweir     ::rtl::OUString SAL_CALL AccessibleStaticTextBase::getText() throw (uno::RuntimeException)
839cdf0e10cSrcweir     {
840cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
841cdf0e10cSrcweir 
842cdf0e10cSrcweir         sal_Int32 i, nParas;
843cdf0e10cSrcweir         ::rtl::OUString aRes;
844cdf0e10cSrcweir         for( i=0, nParas=mpImpl->GetParagraphCount(); i<nParas; ++i )
845cdf0e10cSrcweir             aRes += mpImpl->GetParagraph(i).getText();
846cdf0e10cSrcweir 
847cdf0e10cSrcweir         return aRes;
848cdf0e10cSrcweir     }
849cdf0e10cSrcweir 
getTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)850cdf0e10cSrcweir     ::rtl::OUString SAL_CALL AccessibleStaticTextBase::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
851cdf0e10cSrcweir     {
852cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
853cdf0e10cSrcweir 
854cdf0e10cSrcweir         if( nStartIndex > nEndIndex )
855cdf0e10cSrcweir             ::std::swap(nStartIndex, nEndIndex);
8569b8096d0SSteve Yin 		//if startindex equals endindex we will get nothing. So return an empty string directly.
8579b8096d0SSteve Yin 		if ( nStartIndex == nEndIndex )
8589b8096d0SSteve Yin 		{
8599b8096d0SSteve Yin 			::rtl::OUString sEmptyStr;
8609b8096d0SSteve Yin 			return sEmptyStr;
8619b8096d0SSteve Yin 		}
8629b8096d0SSteve Yin 		sal_Bool bStart = mpImpl->RemoveLineBreakCount( nStartIndex );
8639b8096d0SSteve Yin 		//if the start index is just at a "\n", we need to begin from the next char
8649b8096d0SSteve Yin 		if ( bStart )
8659b8096d0SSteve Yin 		{
8669b8096d0SSteve Yin 			nStartIndex++;
8679b8096d0SSteve Yin 		}
8689b8096d0SSteve Yin 		//we need to find out whether the previous position of the current endindex is at "\n" or not
8699b8096d0SSteve Yin 		//if yes we need to mark it and add "\n" at the end of the result
8709b8096d0SSteve Yin 		sal_Int32 nTemp = nEndIndex - 1;
8719b8096d0SSteve Yin 		sal_Bool bEnd = mpImpl->RemoveLineBreakCount( nTemp );
8729b8096d0SSteve Yin 		sal_Bool bTemp = mpImpl->RemoveLineBreakCount( nEndIndex );
8739b8096d0SSteve Yin 		//if the below condition is true it indicates an empty paragraph with just a "\n"
8749b8096d0SSteve Yin 		//so we need to set one "\n" flag to avoid duplication.
8759b8096d0SSteve Yin 		if ( bStart && bEnd && ( nStartIndex == nEndIndex) )
8769b8096d0SSteve Yin 		{
8779b8096d0SSteve Yin 			bEnd = sal_False;
8789b8096d0SSteve Yin 		}
8799b8096d0SSteve Yin 		//if the current endindex is at a "\n", we need to increase endindex by 1 to make sure
8809b8096d0SSteve Yin 		//the char before "\n" is included. Because string returned by this function will not include
8819b8096d0SSteve Yin 		//the char at the endindex.
8829b8096d0SSteve Yin 		if ( bTemp )
8839b8096d0SSteve Yin 		{
8849b8096d0SSteve Yin 			nEndIndex++;
8859b8096d0SSteve Yin 		}
8869b8096d0SSteve Yin 		::rtl::OUString aRes;
887cdf0e10cSrcweir         EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
888cdf0e10cSrcweir         EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
889cdf0e10cSrcweir 
890cdf0e10cSrcweir         // #102170# Special case: start and end paragraph are identical
891cdf0e10cSrcweir         if( aStartIndex.nPara == aEndIndex.nPara )
892cdf0e10cSrcweir         {
8939b8096d0SSteve Yin 			//we don't return the string directly now for that we have to do some further process for "\n"
8949b8096d0SSteve Yin 			aRes = mpImpl->GetParagraph( aStartIndex.nPara ).getTextRange( aStartIndex.nIndex, aEndIndex.nIndex );
895cdf0e10cSrcweir         }
896cdf0e10cSrcweir         else
897cdf0e10cSrcweir         {
898cdf0e10cSrcweir             sal_Int32 i( aStartIndex.nPara );
8999b8096d0SSteve Yin 	            aRes = mpImpl->GetParagraph(i).getTextRange( aStartIndex.nIndex,
9009b8096d0SSteve Yin                                                                         mpImpl->GetParagraph(i).getCharacterCount()/*-1*/);
901cdf0e10cSrcweir             ++i;
902cdf0e10cSrcweir 
903cdf0e10cSrcweir             // paragraphs inbetween are fully included
904cdf0e10cSrcweir             for( ; i<aEndIndex.nPara; ++i )
9059b8096d0SSteve Yin 			{
9069b8096d0SSteve Yin 				aRes += rtl::OUString(cNewLine);
907cdf0e10cSrcweir                 aRes += mpImpl->GetParagraph(i).getText();
9089b8096d0SSteve Yin 			}
909cdf0e10cSrcweir 
910cdf0e10cSrcweir             if( i<=aEndIndex.nPara )
9119b8096d0SSteve Yin 			{
9129b8096d0SSteve Yin 				//if the below condition is mathed it means the endindex is at mid of the last paragraph
9139b8096d0SSteve Yin 				//we need to add a "\n" before we add the last part of the string.
9149b8096d0SSteve Yin 				if ( !bEnd && aEndIndex.nIndex )
9159b8096d0SSteve Yin 				{
9169b8096d0SSteve Yin 					aRes += rtl::OUString(cNewLine);
917cdf0e10cSrcweir 				}
9189b8096d0SSteve Yin                 aRes += mpImpl->GetParagraph(i).getTextRange( 0, aEndIndex.nIndex );
9199b8096d0SSteve Yin 			}
9209b8096d0SSteve Yin             //return aRes;
9219b8096d0SSteve Yin         }
9229b8096d0SSteve Yin 		//According the the flag we marked before, we have to add "\n" at the beginning
9239b8096d0SSteve Yin 		//or at the end of the result string.
9249b8096d0SSteve Yin 		if ( bStart )
9259b8096d0SSteve Yin 		{
9269b8096d0SSteve Yin 			aRes = rtl::OUString(cNewLine) + aRes;
9279b8096d0SSteve Yin 		}
9289b8096d0SSteve Yin 		if ( bEnd )
9299b8096d0SSteve Yin 		{
9309b8096d0SSteve Yin 			aRes += rtl::OUString(cNewLine);
9319b8096d0SSteve Yin 		}
9329b8096d0SSteve Yin 		return aRes;
933cdf0e10cSrcweir     }
934cdf0e10cSrcweir 
getTextAtIndex(sal_Int32 nIndex,sal_Int16 aTextType)935cdf0e10cSrcweir     ::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)
936cdf0e10cSrcweir     {
937cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
938cdf0e10cSrcweir 
9399b8096d0SSteve Yin 		sal_Bool bLineBreak = mpImpl->RemoveLineBreakCount( nIndex );
940cdf0e10cSrcweir         EPosition aPos( mpImpl->Range2Internal(nIndex) );
941cdf0e10cSrcweir 
942cdf0e10cSrcweir         ::com::sun::star::accessibility::TextSegment aResult;
943cdf0e10cSrcweir 
944cdf0e10cSrcweir         if( AccessibleTextType::PARAGRAPH == aTextType )
945cdf0e10cSrcweir         {
946cdf0e10cSrcweir             // #106393# Special casing one behind last paragraph is
947cdf0e10cSrcweir             // not necessary, since then, we return the content and
948cdf0e10cSrcweir             // boundary of that last paragraph. Range2Internal is
949cdf0e10cSrcweir             // tolerant against that, and returns the last paragraph
950cdf0e10cSrcweir             // in aPos.nPara.
951cdf0e10cSrcweir 
952cdf0e10cSrcweir             // retrieve full text of the paragraph
953cdf0e10cSrcweir             aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara ).getText();
954cdf0e10cSrcweir 
955cdf0e10cSrcweir             // #112814# Adapt the start index with the paragraph offset
956cdf0e10cSrcweir             aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara, 0 ) );
957cdf0e10cSrcweir             aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
958cdf0e10cSrcweir         }
9599b8096d0SSteve Yin         else if ( AccessibleTextType::ATTRIBUTE_RUN == aTextType )
9609b8096d0SSteve Yin         {
9619b8096d0SSteve Yin               SvxAccessibleTextAdapter& rTextForwarder = mpImpl->GetParagraph( aPos.nIndex ).GetTextForwarder();
9629b8096d0SSteve Yin               sal_uInt16 nStartIndex, nEndIndex;
9639b8096d0SSteve Yin               if ( rTextForwarder.GetAttributeRun( nStartIndex, nEndIndex, aPos.nPara, aPos.nIndex, sal_True ) )
9649b8096d0SSteve Yin               {
9659b8096d0SSteve Yin                      aResult.SegmentText = getTextRange( nStartIndex, nEndIndex );
9669b8096d0SSteve Yin                      aResult.SegmentStart = nStartIndex;
9679b8096d0SSteve Yin                      aResult.SegmentEnd = nEndIndex;
9689b8096d0SSteve Yin               }
9699b8096d0SSteve Yin         }
970cdf0e10cSrcweir         else
971cdf0e10cSrcweir         {
972cdf0e10cSrcweir             // No special handling required, forward to wrapped class
973cdf0e10cSrcweir             aResult = mpImpl->GetParagraph( aPos.nPara ).getTextAtIndex( aPos.nIndex, aTextType );
974cdf0e10cSrcweir 
975cdf0e10cSrcweir             // #112814# Adapt the start index with the paragraph offset
976cdf0e10cSrcweir             mpImpl->CorrectTextSegment( aResult, aPos.nPara );
9779b8096d0SSteve Yin 			if ( bLineBreak )
9789b8096d0SSteve Yin 			{
9799b8096d0SSteve Yin 				aResult.SegmentText = rtl::OUString(cNewLine);
9809b8096d0SSteve Yin 			}
981cdf0e10cSrcweir         }
982cdf0e10cSrcweir 
983cdf0e10cSrcweir         return aResult;
984cdf0e10cSrcweir     }
985cdf0e10cSrcweir 
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 aTextType)986cdf0e10cSrcweir     ::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)
987cdf0e10cSrcweir     {
988cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
9899b8096d0SSteve Yin 		sal_Int32 nOldIdx = nIndex;
9909b8096d0SSteve Yin 		sal_Bool bLineBreak =  mpImpl->RemoveLineBreakCount( nIndex );
991cdf0e10cSrcweir         EPosition aPos( mpImpl->Range2Internal(nIndex) );
992cdf0e10cSrcweir 
993cdf0e10cSrcweir         ::com::sun::star::accessibility::TextSegment aResult;
994cdf0e10cSrcweir 
995cdf0e10cSrcweir         if( AccessibleTextType::PARAGRAPH == aTextType )
996cdf0e10cSrcweir         {
997cdf0e10cSrcweir             if( aPos.nIndex == mpImpl->GetParagraph( aPos.nPara ).getCharacterCount() )
998cdf0e10cSrcweir             {
999cdf0e10cSrcweir                 // #103589# Special casing one behind the last paragraph
1000cdf0e10cSrcweir                 aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara ).getText();
1001cdf0e10cSrcweir 
1002cdf0e10cSrcweir                 // #112814# Adapt the start index with the paragraph offset
1003cdf0e10cSrcweir                 aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara, 0 ) );
1004cdf0e10cSrcweir             }
1005cdf0e10cSrcweir             else if( aPos.nPara > 0 )
1006cdf0e10cSrcweir             {
1007cdf0e10cSrcweir                 aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara - 1 ).getText();
1008cdf0e10cSrcweir 
1009cdf0e10cSrcweir                 // #112814# Adapt the start index with the paragraph offset
1010cdf0e10cSrcweir                 aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara - 1, 0 ) );
1011cdf0e10cSrcweir             }
1012cdf0e10cSrcweir 
1013cdf0e10cSrcweir             aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
1014cdf0e10cSrcweir         }
1015cdf0e10cSrcweir         else
1016cdf0e10cSrcweir         {
1017cdf0e10cSrcweir             // No special handling required, forward to wrapped class
1018cdf0e10cSrcweir             aResult = mpImpl->GetParagraph( aPos.nPara ).getTextBeforeIndex( aPos.nIndex, aTextType );
1019cdf0e10cSrcweir 
1020cdf0e10cSrcweir             // #112814# Adapt the start index with the paragraph offset
1021cdf0e10cSrcweir             mpImpl->CorrectTextSegment( aResult, aPos.nPara );
10229b8096d0SSteve Yin 			if ( bLineBreak && (nOldIdx-1) >= 0)
10239b8096d0SSteve Yin 			{
10249b8096d0SSteve Yin 				aResult = getTextAtIndex( nOldIdx-1, aTextType );
10259b8096d0SSteve Yin 			}
1026cdf0e10cSrcweir         }
1027cdf0e10cSrcweir 
1028cdf0e10cSrcweir         return aResult;
1029cdf0e10cSrcweir     }
1030cdf0e10cSrcweir 
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 aTextType)1031cdf0e10cSrcweir     ::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)
1032cdf0e10cSrcweir     {
1033cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
10349b8096d0SSteve Yin 		sal_Int32 nTemp = nIndex+1;
10359b8096d0SSteve Yin 		sal_Bool bLineBreak = mpImpl->RemoveLineBreakCount( nTemp );
10369b8096d0SSteve Yin 		mpImpl->RemoveLineBreakCount( nIndex );
1037cdf0e10cSrcweir         EPosition aPos( mpImpl->Range2Internal(nIndex) );
1038cdf0e10cSrcweir 
1039cdf0e10cSrcweir         ::com::sun::star::accessibility::TextSegment aResult;
1040cdf0e10cSrcweir 
1041cdf0e10cSrcweir         if( AccessibleTextType::PARAGRAPH == aTextType )
1042cdf0e10cSrcweir         {
1043cdf0e10cSrcweir             // Special casing one behind the last paragraph is not
1044cdf0e10cSrcweir             // necessary, this case is invalid here for
1045cdf0e10cSrcweir             // getTextBehindIndex
1046cdf0e10cSrcweir             if( aPos.nPara + 1 < mpImpl->GetParagraphCount() )
1047cdf0e10cSrcweir             {
1048cdf0e10cSrcweir                 aResult.SegmentText = mpImpl->GetParagraph( aPos.nPara + 1 ).getText();
1049cdf0e10cSrcweir 
1050cdf0e10cSrcweir                 // #112814# Adapt the start index with the paragraph offset
1051cdf0e10cSrcweir                 aResult.SegmentStart = mpImpl->Internal2Index( EPosition( aPos.nPara + 1, 0 ) );
1052cdf0e10cSrcweir                 aResult.SegmentEnd = aResult.SegmentStart + aResult.SegmentText.getLength();
1053cdf0e10cSrcweir             }
1054cdf0e10cSrcweir         }
1055cdf0e10cSrcweir         else
1056cdf0e10cSrcweir         {
1057cdf0e10cSrcweir             // No special handling required, forward to wrapped class
1058cdf0e10cSrcweir             aResult = mpImpl->GetParagraph( aPos.nPara ).getTextBehindIndex( aPos.nIndex, aTextType );
1059cdf0e10cSrcweir 
1060cdf0e10cSrcweir             // #112814# Adapt the start index with the paragraph offset
1061cdf0e10cSrcweir             mpImpl->CorrectTextSegment( aResult, aPos.nPara );
10629b8096d0SSteve Yin 			if ( bLineBreak )
10639b8096d0SSteve Yin 			{
10649b8096d0SSteve Yin 				aResult.SegmentText = rtl::OUString(cNewLine) + aResult.SegmentText;
10659b8096d0SSteve Yin 			}
1066cdf0e10cSrcweir        }
1067cdf0e10cSrcweir 
1068cdf0e10cSrcweir         return aResult;
1069cdf0e10cSrcweir     }
1070cdf0e10cSrcweir 
copyText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)1071cdf0e10cSrcweir     sal_Bool SAL_CALL AccessibleStaticTextBase::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1072cdf0e10cSrcweir     {
1073cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1074cdf0e10cSrcweir 
1075cdf0e10cSrcweir         if( nStartIndex > nEndIndex )
1076cdf0e10cSrcweir             ::std::swap(nStartIndex, nEndIndex);
1077cdf0e10cSrcweir 
1078cdf0e10cSrcweir         EPosition aStartIndex( mpImpl->Range2Internal(nStartIndex) );
1079cdf0e10cSrcweir         EPosition aEndIndex( mpImpl->Range2Internal(nEndIndex) );
1080cdf0e10cSrcweir 
1081cdf0e10cSrcweir         return mpImpl->CopyText( aStartIndex.nPara, aStartIndex.nIndex,
1082cdf0e10cSrcweir                                  aEndIndex.nPara, aEndIndex.nIndex );
1083cdf0e10cSrcweir     }
1084cdf0e10cSrcweir 
1085cdf0e10cSrcweir     // XAccessibleTextAttributes
getDefaultAttributes(const uno::Sequence<::rtl::OUString> & RequestedAttributes)1086cdf0e10cSrcweir     uno::Sequence< beans::PropertyValue > AccessibleStaticTextBase::getDefaultAttributes( const uno::Sequence< ::rtl::OUString >& RequestedAttributes ) throw (uno::RuntimeException)
1087cdf0e10cSrcweir     {
1088cdf0e10cSrcweir         // get the intersection of the default attributes of all paragraphs
1089cdf0e10cSrcweir 
1090cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1091cdf0e10cSrcweir 
1092cdf0e10cSrcweir         PropertyValueVector aDefAttrVec( mpImpl->GetParagraph( 0 ).getDefaultAttributes( RequestedAttributes ) );
1093cdf0e10cSrcweir 
1094cdf0e10cSrcweir         const sal_Int32 nParaCount = mpImpl->GetParagraphCount();
1095cdf0e10cSrcweir         for ( sal_Int32 nPara = 1; nPara < nParaCount; ++nPara )
1096cdf0e10cSrcweir         {
1097cdf0e10cSrcweir             uno::Sequence< beans::PropertyValue > aSeq = mpImpl->GetParagraph( nPara ).getDefaultAttributes( RequestedAttributes );
1098cdf0e10cSrcweir             PropertyValueVector aIntersectionVec;
1099cdf0e10cSrcweir 
1100cdf0e10cSrcweir             PropertyValueVector::const_iterator aEnd = aDefAttrVec.end();
1101cdf0e10cSrcweir             for ( PropertyValueVector::const_iterator aItr = aDefAttrVec.begin(); aItr != aEnd; ++aItr )
1102cdf0e10cSrcweir             {
1103cdf0e10cSrcweir                 const beans::PropertyValue* pItr = aSeq.getConstArray();
1104cdf0e10cSrcweir                 const beans::PropertyValue* pEnd  = pItr + aSeq.getLength();
1105cdf0e10cSrcweir                 const beans::PropertyValue* pFind = ::std::find_if( pItr, pEnd, ::std::bind2nd( PropertyValueEqualFunctor(), boost::cref( *aItr ) ) );
1106cdf0e10cSrcweir                 if ( pFind != pEnd )
1107cdf0e10cSrcweir                 {
1108cdf0e10cSrcweir                     aIntersectionVec.push_back( *pFind );
1109cdf0e10cSrcweir                 }
1110cdf0e10cSrcweir             }
1111cdf0e10cSrcweir 
1112cdf0e10cSrcweir             aDefAttrVec.swap( aIntersectionVec );
1113cdf0e10cSrcweir 
1114cdf0e10cSrcweir             if ( aDefAttrVec.empty() )
1115cdf0e10cSrcweir             {
1116cdf0e10cSrcweir                 break;
1117cdf0e10cSrcweir             }
1118cdf0e10cSrcweir         }
1119cdf0e10cSrcweir 
1120cdf0e10cSrcweir         return aDefAttrVec.getAsConstList();
1121cdf0e10cSrcweir     }
1122cdf0e10cSrcweir 
getRunAttributes(sal_Int32 nIndex,const uno::Sequence<::rtl::OUString> & RequestedAttributes)1123cdf0e10cSrcweir     uno::Sequence< beans::PropertyValue > SAL_CALL AccessibleStaticTextBase::getRunAttributes( sal_Int32 nIndex, const uno::Sequence< ::rtl::OUString >& RequestedAttributes ) throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1124cdf0e10cSrcweir     {
1125cdf0e10cSrcweir         // get those default attributes of the paragraph, which are not part
1126cdf0e10cSrcweir         // of the intersection of all paragraphs and add them to the run attributes
1127cdf0e10cSrcweir 
1128cdf0e10cSrcweir         ::vos::OGuard aGuard( Application::GetSolarMutex() );
1129cdf0e10cSrcweir 
1130cdf0e10cSrcweir         EPosition aPos( mpImpl->Index2Internal( nIndex ) );
1131cdf0e10cSrcweir         AccessibleEditableTextPara& rPara = mpImpl->GetParagraph( aPos.nPara );
1132cdf0e10cSrcweir         uno::Sequence< beans::PropertyValue > aDefAttrSeq = rPara.getDefaultAttributes( RequestedAttributes );
1133cdf0e10cSrcweir         uno::Sequence< beans::PropertyValue > aRunAttrSeq = rPara.getRunAttributes( aPos.nIndex, RequestedAttributes );
1134cdf0e10cSrcweir         uno::Sequence< beans::PropertyValue > aIntersectionSeq = getDefaultAttributes( RequestedAttributes );
1135cdf0e10cSrcweir         PropertyValueVector aDiffVec;
1136cdf0e10cSrcweir 
1137cdf0e10cSrcweir         const beans::PropertyValue* pDefAttr = aDefAttrSeq.getConstArray();
1138cdf0e10cSrcweir         const sal_Int32 nLength = aDefAttrSeq.getLength();
1139cdf0e10cSrcweir         for ( sal_Int32 i = 0; i < nLength; ++i )
1140cdf0e10cSrcweir         {
1141cdf0e10cSrcweir             const beans::PropertyValue* pItr = aIntersectionSeq.getConstArray();
1142cdf0e10cSrcweir             const beans::PropertyValue* pEnd  = pItr + aIntersectionSeq.getLength();
1143cdf0e10cSrcweir             const beans::PropertyValue* pFind = ::std::find_if( pItr, pEnd, ::std::bind2nd( PropertyValueEqualFunctor(), boost::cref( pDefAttr[i] ) ) );
1144cdf0e10cSrcweir             if ( pFind == pEnd && pDefAttr[i].Handle != 0)
1145cdf0e10cSrcweir             {
1146cdf0e10cSrcweir                 aDiffVec.push_back( pDefAttr[i] );
1147cdf0e10cSrcweir             }
1148cdf0e10cSrcweir         }
1149cdf0e10cSrcweir 
1150cdf0e10cSrcweir         return ::comphelper::concatSequences( aRunAttrSeq, aDiffVec.getAsConstList() );
1151cdf0e10cSrcweir     }
1152cdf0e10cSrcweir 
GetParagraphBoundingBox() const1153cdf0e10cSrcweir     Rectangle AccessibleStaticTextBase::GetParagraphBoundingBox() const
1154cdf0e10cSrcweir     {
1155cdf0e10cSrcweir         return mpImpl->GetParagraphBoundingBox();
1156cdf0e10cSrcweir     }
1157cdf0e10cSrcweir 
GetParagraphIndex() const1158cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase::GetParagraphIndex() const
1159cdf0e10cSrcweir     {
1160cdf0e10cSrcweir         return mpImpl->GetParagraphIndex();
1161cdf0e10cSrcweir     }
1162cdf0e10cSrcweir 
GetParagraphCount() const1163cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase::GetParagraphCount() const
1164cdf0e10cSrcweir     {
1165cdf0e10cSrcweir         return mpImpl->GetParagraphCount();
1166cdf0e10cSrcweir     }
1167cdf0e10cSrcweir 
GetLineCount(sal_Int32 nParagraph) const1168cdf0e10cSrcweir     sal_Int32 AccessibleStaticTextBase::GetLineCount( sal_Int32 nParagraph ) const
1169cdf0e10cSrcweir     {
1170cdf0e10cSrcweir         return mpImpl->GetLineCount( nParagraph );
1171cdf0e10cSrcweir     }
1172cdf0e10cSrcweir 
1173cdf0e10cSrcweir }  // end of namespace accessibility
1174cdf0e10cSrcweir 
1175cdf0e10cSrcweir //------------------------------------------------------------------------
1176