xref: /AOO41X/main/sw/source/core/access/accpara.cxx (revision e467b8b3c91f261373da5f181866ead4a014a21c)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <txtfrm.hxx>
28cdf0e10cSrcweir #include <flyfrm.hxx>
29cdf0e10cSrcweir #include <ndtxt.hxx>
30cdf0e10cSrcweir #include <pam.hxx>
31cdf0e10cSrcweir #include <unotextrange.hxx>
32cdf0e10cSrcweir #include <unocrsrhelper.hxx>
33cdf0e10cSrcweir #include <crstate.hxx>
34cdf0e10cSrcweir #include <accmap.hxx>
35cdf0e10cSrcweir #include <fesh.hxx>
36cdf0e10cSrcweir #include <viewopt.hxx>
37cdf0e10cSrcweir #include <vos/mutex.hxx>
38cdf0e10cSrcweir #include <vcl/svapp.hxx>
39cdf0e10cSrcweir #include <vcl/window.hxx>
40cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
41cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRole.hpp>
42cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleStateType.hpp>
43cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleTextType.hpp>
44cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleEventId.hpp>
45cdf0e10cSrcweir #include <unotools/accessiblestatesethelper.hxx>
46cdf0e10cSrcweir #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
47cdf0e10cSrcweir #include <com/sun/star/i18n/WordType.hpp>
48cdf0e10cSrcweir #include <com/sun/star/i18n/XBreakIterator.hpp>
49cdf0e10cSrcweir #include <com/sun/star/beans/UnknownPropertyException.hpp>
50cdf0e10cSrcweir #include <breakit.hxx>
51cdf0e10cSrcweir #include <accpara.hxx>
52cdf0e10cSrcweir #include <access.hrc>
53cdf0e10cSrcweir #include <accportions.hxx>
54cdf0e10cSrcweir #include <sfx2/viewsh.hxx>      // for ExecuteAtViewShell(...)
55cdf0e10cSrcweir #include <sfx2/viewfrm.hxx>      // for ExecuteAtViewShell(...)
56cdf0e10cSrcweir #include <sfx2/dispatch.hxx>    // for ExecuteAtViewShell(...)
57cdf0e10cSrcweir #include <unotools/charclass.hxx>   // for GetWordBoundary
58cdf0e10cSrcweir // for get/setCharacterAttribute(...)
59ca62e2c2SSteve Yin 
60ca62e2c2SSteve Yin #include <reffld.hxx>
61ca62e2c2SSteve Yin #include <docufld.hxx>
62ca62e2c2SSteve Yin #include <expfld.hxx>
63ca62e2c2SSteve Yin #include <flddat.hxx>
64ca62e2c2SSteve Yin #include <fldui.hrc>
65ca62e2c2SSteve Yin #include "../../ui/inc/fldmgr.hxx"
66ca62e2c2SSteve Yin #include "fldbas.hxx"      // SwField
67ca62e2c2SSteve Yin #include <svl/svstdarr.hxx>
68cdf0e10cSrcweir #include <unocrsr.hxx>
69cdf0e10cSrcweir //#include <unoobj.hxx>
70cdf0e10cSrcweir #include <unoport.hxx>
71cdf0e10cSrcweir #include <doc.hxx>
72cdf0e10cSrcweir #include <crsskip.hxx>
73cdf0e10cSrcweir #include <txtatr.hxx>
74cdf0e10cSrcweir #include <acchyperlink.hxx>
75cdf0e10cSrcweir #include <acchypertextdata.hxx>
76cdf0e10cSrcweir #include <unotools/accessiblerelationsethelper.hxx>
77cdf0e10cSrcweir #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
78ca62e2c2SSteve Yin #include <section.hxx>
79ca62e2c2SSteve Yin #include <doctxm.hxx>
80cdf0e10cSrcweir #include <comphelper/accessibletexthelper.hxx>
81ca62e2c2SSteve Yin #include <algorithm>
82ca62e2c2SSteve Yin #include <docufld.hxx>
83ca62e2c2SSteve Yin #include <txtfld.hxx>
84ca62e2c2SSteve Yin #include <fmtfld.hxx>
85ca62e2c2SSteve Yin #include <modcfg.hxx>
86ca62e2c2SSteve Yin //#include "accnote.hxx"
87ca62e2c2SSteve Yin #include <com/sun/star/beans/XPropertySet.hpp>
88ca62e2c2SSteve Yin #include "swmodule.hxx"
89ca62e2c2SSteve Yin #include "redline.hxx"
90ca62e2c2SSteve Yin #include <com/sun/star/awt/FontWeight.hpp>
91ca62e2c2SSteve Yin #include <com/sun/star/awt/FontStrikeout.hpp>
92ca62e2c2SSteve Yin #include <com/sun/star/awt/FontSlant.hpp>
93ca62e2c2SSteve Yin #include <wrong.hxx>
94ca62e2c2SSteve Yin #include <editeng/brshitem.hxx>
95ca62e2c2SSteve Yin #include <swatrset.hxx>
96ca62e2c2SSteve Yin #include <frmatr.hxx>
97ca62e2c2SSteve Yin #include <unosett.hxx>
98ca62e2c2SSteve Yin #include <paratr.hxx>
99ca62e2c2SSteve Yin #include <com/sun/star/container/XIndexReplace.hpp>
100ca62e2c2SSteve Yin // --> OD 2006-07-12 #i63870#
101cdf0e10cSrcweir #include <unomap.hxx>
102cdf0e10cSrcweir #include <unoprnms.hxx>
103cdf0e10cSrcweir #include <com/sun/star/text/WritingMode2.hpp>
104cdf0e10cSrcweir #include <editeng/brshitem.hxx>
105cdf0e10cSrcweir #include <viewimp.hxx>
106cdf0e10cSrcweir #include <boost/scoped_ptr.hpp>
107cdf0e10cSrcweir #include <textmarkuphelper.hxx>
108cdf0e10cSrcweir // --> OD 2010-02-22 #i10825#
109cdf0e10cSrcweir #include <parachangetrackinginfo.hxx>
110cdf0e10cSrcweir #include <com/sun/star/text/TextMarkupType.hpp>
111cdf0e10cSrcweir // <--
112cdf0e10cSrcweir // --> OD 2010-03-08 #i92233#
113cdf0e10cSrcweir #include <comphelper/stlunosequence.hxx>
114cdf0e10cSrcweir // <--
115cdf0e10cSrcweir 
116cdf0e10cSrcweir #include <algorithm>
117cdf0e10cSrcweir 
118cdf0e10cSrcweir using namespace ::com::sun::star;
119cdf0e10cSrcweir using namespace ::com::sun::star::accessibility;
120ca62e2c2SSteve Yin using namespace ::com::sun::star::container;
121ca62e2c2SSteve Yin using ::rtl::OUString;
122cdf0e10cSrcweir 
123cdf0e10cSrcweir using beans::PropertyValue;
124cdf0e10cSrcweir using beans::XMultiPropertySet;
125cdf0e10cSrcweir using beans::UnknownPropertyException;
126cdf0e10cSrcweir using beans::PropertyState_DIRECT_VALUE;
127cdf0e10cSrcweir 
128cdf0e10cSrcweir using std::max;
129cdf0e10cSrcweir using std::min;
130cdf0e10cSrcweir using std::sort;
131cdf0e10cSrcweir 
132cdf0e10cSrcweir namespace com { namespace sun { namespace star {
133cdf0e10cSrcweir     namespace text {
134cdf0e10cSrcweir         class XText;
135cdf0e10cSrcweir     }
136cdf0e10cSrcweir } } }
137cdf0e10cSrcweir 
138cdf0e10cSrcweir 
139cdf0e10cSrcweir const sal_Char sServiceName[] = "com.sun.star.text.AccessibleParagraphView";
140cdf0e10cSrcweir const sal_Char sImplementationName[] = "com.sun.star.comp.Writer.SwAccessibleParagraphView";
141cdf0e10cSrcweir const xub_StrLen MAX_DESC_TEXT_LEN = 40;
GetTxtNode() const142cdf0e10cSrcweir const SwTxtNode* SwAccessibleParagraph::GetTxtNode() const
143cdf0e10cSrcweir {
144cdf0e10cSrcweir     const SwFrm* pFrm = GetFrm();
145cdf0e10cSrcweir     DBG_ASSERT( pFrm->IsTxtFrm(), "The text frame has mutated!" );
146cdf0e10cSrcweir 
147cdf0e10cSrcweir     const SwTxtNode* pNode = static_cast<const SwTxtFrm*>(pFrm)->GetTxtNode();
148cdf0e10cSrcweir     DBG_ASSERT( pNode != NULL, "A text frame without a text node." );
149cdf0e10cSrcweir 
150cdf0e10cSrcweir     return pNode;
151cdf0e10cSrcweir }
152cdf0e10cSrcweir 
GetString()153cdf0e10cSrcweir ::rtl::OUString SwAccessibleParagraph::GetString()
154cdf0e10cSrcweir {
155cdf0e10cSrcweir     return GetPortionData().GetAccessibleString();
156cdf0e10cSrcweir }
157cdf0e10cSrcweir 
GetDescription()158cdf0e10cSrcweir ::rtl::OUString SwAccessibleParagraph::GetDescription()
159cdf0e10cSrcweir {
160cdf0e10cSrcweir     // --> OD 2004-09-29 #117933# - provide empty description for paragraphs
161cdf0e10cSrcweir     return ::rtl::OUString();
162cdf0e10cSrcweir     // <--
163cdf0e10cSrcweir }
164cdf0e10cSrcweir 
GetCaretPos()165cdf0e10cSrcweir sal_Int32 SwAccessibleParagraph::GetCaretPos()
166cdf0e10cSrcweir {
167cdf0e10cSrcweir     sal_Int32 nRet = -1;
168cdf0e10cSrcweir 
169cdf0e10cSrcweir     // get the selection's point, and test whether it's in our node
170cdf0e10cSrcweir     // --> OD 2005-12-20 #i27301# - consider adjusted method signature
171cdf0e10cSrcweir     SwPaM* pCaret = GetCursor( false );  // caret is first PaM in PaM-ring
172cdf0e10cSrcweir     // <--
173cdf0e10cSrcweir     if( pCaret != NULL )
174cdf0e10cSrcweir     {
175cdf0e10cSrcweir         const SwTxtNode* pNode = GetTxtNode();
176cdf0e10cSrcweir 
177cdf0e10cSrcweir         // check whether the point points into 'our' node
178cdf0e10cSrcweir         SwPosition* pPoint = pCaret->GetPoint();
179cdf0e10cSrcweir         if( pNode->GetIndex() == pPoint->nNode.GetIndex() )
180cdf0e10cSrcweir         {
181cdf0e10cSrcweir             // same node? Then check whether it's also within 'our' part
182cdf0e10cSrcweir             // of the paragraph
183cdf0e10cSrcweir             sal_uInt16 nIndex = pPoint->nContent.GetIndex();
184ca62e2c2SSteve Yin 			if(!GetPortionData().IsValidCorePosition( nIndex ) ||
185ca62e2c2SSteve Yin 				( GetPortionData().IsZeroCorePositionData() && nIndex== 0) )
186ca62e2c2SSteve Yin 			{
187ca62e2c2SSteve Yin 				SwTxtFrm *pTxtFrm = PTR_CAST( SwTxtFrm, GetFrm() );
188ca62e2c2SSteve Yin 				bool bFormat = (pTxtFrm && pTxtFrm->HasPara());
189ca62e2c2SSteve Yin 				if(bFormat)
190ca62e2c2SSteve Yin 				{
191ca62e2c2SSteve Yin 					ClearPortionData();
192ca62e2c2SSteve Yin 					UpdatePortionData();
193ca62e2c2SSteve Yin 				}
194ca62e2c2SSteve Yin 			}
195cdf0e10cSrcweir             if( GetPortionData().IsValidCorePosition( nIndex ) )
196cdf0e10cSrcweir             {
197cdf0e10cSrcweir                 // Yes, it's us!
198cdf0e10cSrcweir                 // --> OD 2006-10-19 #70538#
199cdf0e10cSrcweir                 // consider that cursor/caret is in front of the list label
200cdf0e10cSrcweir                 if ( pCaret->IsInFrontOfLabel() )
201cdf0e10cSrcweir                 {
202cdf0e10cSrcweir                     nRet = 0;
203cdf0e10cSrcweir                 }
204cdf0e10cSrcweir                 else
205cdf0e10cSrcweir                 {
206cdf0e10cSrcweir                     nRet = GetPortionData().GetAccessiblePosition( nIndex );
207cdf0e10cSrcweir                 }
208cdf0e10cSrcweir                 // <--
209cdf0e10cSrcweir 
210cdf0e10cSrcweir                 DBG_ASSERT( nRet >= 0, "invalid cursor?" );
211cdf0e10cSrcweir                 DBG_ASSERT( nRet <= GetPortionData().GetAccessibleString().
212cdf0e10cSrcweir                                               getLength(), "invalid cursor?" );
213cdf0e10cSrcweir             }
214cdf0e10cSrcweir             // else: in this paragraph, but in different frame
215cdf0e10cSrcweir         }
216cdf0e10cSrcweir         // else: not in this paragraph
217cdf0e10cSrcweir     }
218cdf0e10cSrcweir     // else: no cursor -> no caret
219cdf0e10cSrcweir 
220cdf0e10cSrcweir     return nRet;
221cdf0e10cSrcweir }
222cdf0e10cSrcweir 
GetSelection(sal_Int32 & nStart,sal_Int32 & nEnd)223cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::GetSelection(
224cdf0e10cSrcweir     sal_Int32& nStart, sal_Int32& nEnd)
225cdf0e10cSrcweir {
226cdf0e10cSrcweir     sal_Bool bRet = sal_False;
227cdf0e10cSrcweir     nStart = -1;
228cdf0e10cSrcweir     nEnd = -1;
229cdf0e10cSrcweir 
230cdf0e10cSrcweir     // get the selection, and test whether it affects our text node
231cdf0e10cSrcweir     // --> OD 2005-12-20 #i27301# - consider adjusted method signature
232cdf0e10cSrcweir     SwPaM* pCrsr = GetCursor( true );
233cdf0e10cSrcweir     // <--
234cdf0e10cSrcweir     if( pCrsr != NULL )
235cdf0e10cSrcweir     {
236cdf0e10cSrcweir         // get SwPosition for my node
237cdf0e10cSrcweir         const SwTxtNode* pNode = GetTxtNode();
238cdf0e10cSrcweir         sal_uLong nHere = pNode->GetIndex();
239cdf0e10cSrcweir 
240cdf0e10cSrcweir         // iterate over ring
241cdf0e10cSrcweir         SwPaM* pRingStart = pCrsr;
242cdf0e10cSrcweir         do
243cdf0e10cSrcweir         {
244cdf0e10cSrcweir             // ignore, if no mark
245cdf0e10cSrcweir             if( pCrsr->HasMark() )
246cdf0e10cSrcweir             {
247cdf0e10cSrcweir                 // check whether nHere is 'inside' pCrsr
248cdf0e10cSrcweir                 SwPosition* pStart = pCrsr->Start();
249cdf0e10cSrcweir                 sal_uLong nStartIndex = pStart->nNode.GetIndex();
250cdf0e10cSrcweir                 SwPosition* pEnd = pCrsr->End();
251cdf0e10cSrcweir                 sal_uLong nEndIndex = pEnd->nNode.GetIndex();
252cdf0e10cSrcweir                 if( ( nHere >= nStartIndex ) &&
253cdf0e10cSrcweir                     ( nHere <= nEndIndex )      )
254cdf0e10cSrcweir                 {
255cdf0e10cSrcweir                     // translate start and end positions
256cdf0e10cSrcweir 
257cdf0e10cSrcweir                     // start position
258cdf0e10cSrcweir                     sal_Int32 nLocalStart = -1;
259cdf0e10cSrcweir                     if( nHere > nStartIndex )
260cdf0e10cSrcweir                     {
261cdf0e10cSrcweir                         // selection starts in previous node:
262cdf0e10cSrcweir                         // then our local selection starts with the paragraph
263cdf0e10cSrcweir                         nLocalStart = 0;
264cdf0e10cSrcweir                     }
265cdf0e10cSrcweir                     else
266cdf0e10cSrcweir                     {
267cdf0e10cSrcweir                         DBG_ASSERT( nHere == nStartIndex,
268cdf0e10cSrcweir                                     "miscalculated index" );
269cdf0e10cSrcweir 
270cdf0e10cSrcweir                         // selection starts in this node:
271cdf0e10cSrcweir                         // then check whether it's before or inside our part of
272cdf0e10cSrcweir                         // the paragraph, and if so, get the proper position
273cdf0e10cSrcweir                         sal_uInt16 nCoreStart = pStart->nContent.GetIndex();
274cdf0e10cSrcweir                         if( nCoreStart <
275cdf0e10cSrcweir                             GetPortionData().GetFirstValidCorePosition() )
276cdf0e10cSrcweir                         {
277cdf0e10cSrcweir                             nLocalStart = 0;
278cdf0e10cSrcweir                         }
279cdf0e10cSrcweir                         else if( nCoreStart <=
280cdf0e10cSrcweir                                  GetPortionData().GetLastValidCorePosition() )
281cdf0e10cSrcweir                         {
282cdf0e10cSrcweir                             DBG_ASSERT(
283cdf0e10cSrcweir                                 GetPortionData().IsValidCorePosition(
284cdf0e10cSrcweir                                                                   nCoreStart ),
285cdf0e10cSrcweir                                  "problem determining valid core position" );
286cdf0e10cSrcweir 
287cdf0e10cSrcweir                             nLocalStart =
288cdf0e10cSrcweir                                 GetPortionData().GetAccessiblePosition(
289cdf0e10cSrcweir                                                                   nCoreStart );
290cdf0e10cSrcweir                         }
291cdf0e10cSrcweir                     }
292cdf0e10cSrcweir 
293cdf0e10cSrcweir                     // end position
294cdf0e10cSrcweir                     sal_Int32 nLocalEnd = -1;
295cdf0e10cSrcweir                     if( nHere < nEndIndex )
296cdf0e10cSrcweir                     {
297cdf0e10cSrcweir                         // selection ends in following node:
298cdf0e10cSrcweir                         // then our local selection extends to the end
299cdf0e10cSrcweir                         nLocalEnd = GetPortionData().GetAccessibleString().
300cdf0e10cSrcweir                                                                    getLength();
301cdf0e10cSrcweir                     }
302cdf0e10cSrcweir                     else
303cdf0e10cSrcweir                     {
304cdf0e10cSrcweir                         DBG_ASSERT( nHere == nEndIndex,
305cdf0e10cSrcweir                                     "miscalculated index" );
306cdf0e10cSrcweir 
307cdf0e10cSrcweir                         // selection ends in this node: then select everything
308cdf0e10cSrcweir                         // before our part of the node
309cdf0e10cSrcweir                         sal_uInt16 nCoreEnd = pEnd->nContent.GetIndex();
310cdf0e10cSrcweir                         if( nCoreEnd >
311cdf0e10cSrcweir                                 GetPortionData().GetLastValidCorePosition() )
312cdf0e10cSrcweir                         {
313cdf0e10cSrcweir                             // selection extends beyond out part of this para
314cdf0e10cSrcweir                             nLocalEnd = GetPortionData().GetAccessibleString().
315cdf0e10cSrcweir                                                                    getLength();
316cdf0e10cSrcweir                         }
317cdf0e10cSrcweir                         else if( nCoreEnd >=
318cdf0e10cSrcweir                                  GetPortionData().GetFirstValidCorePosition() )
319cdf0e10cSrcweir                         {
320cdf0e10cSrcweir                             // selection is inside our part of this para
321cdf0e10cSrcweir                             DBG_ASSERT(
322cdf0e10cSrcweir                                 GetPortionData().IsValidCorePosition(
323cdf0e10cSrcweir                                                                   nCoreEnd ),
324cdf0e10cSrcweir                                  "problem determining valid core position" );
325cdf0e10cSrcweir 
326cdf0e10cSrcweir                             nLocalEnd = GetPortionData().GetAccessiblePosition(
327cdf0e10cSrcweir                                                                    nCoreEnd );
328cdf0e10cSrcweir                         }
329cdf0e10cSrcweir                     }
330cdf0e10cSrcweir 
331cdf0e10cSrcweir                     if( ( nLocalStart != -1 ) && ( nLocalEnd != -1 ) )
332cdf0e10cSrcweir                     {
333cdf0e10cSrcweir                         nStart = nLocalStart;
334cdf0e10cSrcweir                         nEnd = nLocalEnd;
335cdf0e10cSrcweir                         bRet = sal_True;
336cdf0e10cSrcweir                     }
337cdf0e10cSrcweir                 }
338cdf0e10cSrcweir                 // else: this PaM doesn't point to this paragraph
339cdf0e10cSrcweir             }
340cdf0e10cSrcweir             // else: this PaM is collapsed and doesn't select anything
341cdf0e10cSrcweir 
342cdf0e10cSrcweir             // next PaM in ring
343cdf0e10cSrcweir             pCrsr = static_cast<SwPaM*>( pCrsr->GetNext() );
344cdf0e10cSrcweir         }
345cdf0e10cSrcweir         while( !bRet && (pCrsr != pRingStart) );
346cdf0e10cSrcweir     }
347cdf0e10cSrcweir     // else: nocursor -> no selection
348cdf0e10cSrcweir 
349cdf0e10cSrcweir     return bRet;
350cdf0e10cSrcweir }
351cdf0e10cSrcweir 
352cdf0e10cSrcweir // --> OD 2005-12-20 #i27301# - new parameter <_bForSelection>
GetCursor(const bool _bForSelection)353cdf0e10cSrcweir SwPaM* SwAccessibleParagraph::GetCursor( const bool _bForSelection )
354cdf0e10cSrcweir {
355cdf0e10cSrcweir     // get the cursor shell; if we don't have any, we don't have a
356cdf0e10cSrcweir     // cursor/selection either
357cdf0e10cSrcweir     SwPaM* pCrsr = NULL;
358cdf0e10cSrcweir     SwCrsrShell* pCrsrShell = SwAccessibleParagraph::GetCrsrShell();
359cdf0e10cSrcweir     // --> OD 2005-12-20 #i27301#
360cdf0e10cSrcweir     // - if cursor is retrieved for selection, the cursors for a table selection
361cdf0e10cSrcweir     //   has to be returned.
362cdf0e10cSrcweir     if ( pCrsrShell != NULL &&
363cdf0e10cSrcweir          ( _bForSelection || !pCrsrShell->IsTableMode() ) )
364cdf0e10cSrcweir     // <--
365cdf0e10cSrcweir     {
366cdf0e10cSrcweir 		SwFEShell *pFESh = pCrsrShell->ISA( SwFEShell )
367cdf0e10cSrcweir 							? static_cast< SwFEShell * >( pCrsrShell ) : 0;
368cdf0e10cSrcweir 		if( !pFESh ||
369cdf0e10cSrcweir 			!(pFESh->IsFrmSelected() || pFESh->IsObjSelected() > 0) )
370cdf0e10cSrcweir 		{
371cdf0e10cSrcweir 			// get the selection, and test whether it affects our text node
372cdf0e10cSrcweir 			pCrsr = pCrsrShell->GetCrsr( sal_False /* ??? */ );
373cdf0e10cSrcweir 		}
374cdf0e10cSrcweir     }
375cdf0e10cSrcweir 
376cdf0e10cSrcweir     return pCrsr;
377cdf0e10cSrcweir }
378cdf0e10cSrcweir 
IsHeading() const379cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::IsHeading() const
380cdf0e10cSrcweir {
381cdf0e10cSrcweir 	const SwTxtNode *pTxtNd = GetTxtNode();
382cdf0e10cSrcweir 	return pTxtNd->IsOutline();
383cdf0e10cSrcweir }
384cdf0e10cSrcweir 
GetStates(::utl::AccessibleStateSetHelper & rStateSet)385cdf0e10cSrcweir void SwAccessibleParagraph::GetStates(
386cdf0e10cSrcweir 		::utl::AccessibleStateSetHelper& rStateSet )
387cdf0e10cSrcweir {
388cdf0e10cSrcweir 	SwAccessibleContext::GetStates( rStateSet );
389cdf0e10cSrcweir 
390cdf0e10cSrcweir 	// MULTILINE
391cdf0e10cSrcweir 	rStateSet.AddState( AccessibleStateType::MULTI_LINE );
392cdf0e10cSrcweir 
393cdf0e10cSrcweir 	// MULTISELECTABLE
394cdf0e10cSrcweir 	SwCrsrShell *pCrsrSh = GetCrsrShell();
395cdf0e10cSrcweir 	if( pCrsrSh )
396cdf0e10cSrcweir 		rStateSet.AddState( AccessibleStateType::MULTI_SELECTABLE );
397cdf0e10cSrcweir 
398cdf0e10cSrcweir 	// FOCUSABLE
399cdf0e10cSrcweir 	if( pCrsrSh )
400cdf0e10cSrcweir 		rStateSet.AddState( AccessibleStateType::FOCUSABLE );
401cdf0e10cSrcweir 
402cdf0e10cSrcweir 	// FOCUSED (simulates node index of cursor)
403cdf0e10cSrcweir     // --> OD 2005-12-20 #i27301# - consider adjusted method signature
404cdf0e10cSrcweir     SwPaM* pCaret = GetCursor( false );
405cdf0e10cSrcweir     // <--
406cdf0e10cSrcweir 	const SwTxtNode* pTxtNd = GetTxtNode();
407cdf0e10cSrcweir 	if( pCaret != 0 && pTxtNd != 0 &&
408cdf0e10cSrcweir 		pTxtNd->GetIndex() == pCaret->GetPoint()->nNode.GetIndex() &&
409cdf0e10cSrcweir 		nOldCaretPos != -1)
410cdf0e10cSrcweir 	{
411cdf0e10cSrcweir 		Window *pWin = GetWindow();
412cdf0e10cSrcweir 		if( pWin && pWin->HasFocus() )
413cdf0e10cSrcweir 			rStateSet.AddState( AccessibleStateType::FOCUSED );
414cdf0e10cSrcweir 		::vos::ORef < SwAccessibleContext > xThis( this );
415cdf0e10cSrcweir 		GetMap()->SetCursorContext( xThis );
416cdf0e10cSrcweir 	}
417cdf0e10cSrcweir }
418cdf0e10cSrcweir 
_InvalidateContent(sal_Bool bVisibleDataFired)419cdf0e10cSrcweir void SwAccessibleParagraph::_InvalidateContent( sal_Bool bVisibleDataFired )
420cdf0e10cSrcweir {
421cdf0e10cSrcweir     ::rtl::OUString sOldText( GetString() );
422cdf0e10cSrcweir 
423cdf0e10cSrcweir 	ClearPortionData();
424cdf0e10cSrcweir 
425cdf0e10cSrcweir     const ::rtl::OUString& rText = GetString();
426cdf0e10cSrcweir 
427cdf0e10cSrcweir 	if( rText != sOldText )
428cdf0e10cSrcweir 	{
429cdf0e10cSrcweir 		// The text is changed
430cdf0e10cSrcweir 		AccessibleEventObject aEvent;
431cdf0e10cSrcweir 		aEvent.EventId = AccessibleEventId::TEXT_CHANGED;
432cdf0e10cSrcweir 
433cdf0e10cSrcweir         // determine exact changes between sOldText and rText
434cdf0e10cSrcweir         comphelper::OCommonAccessibleText::implInitTextChangedEvent(
435cdf0e10cSrcweir             sOldText, rText,
436cdf0e10cSrcweir             aEvent.OldValue, aEvent.NewValue );
437cdf0e10cSrcweir 
438cdf0e10cSrcweir 		FireAccessibleEvent( aEvent );
439ca62e2c2SSteve Yin 		uno::Reference< XAccessible > xparent = getAccessibleParent();
440ca62e2c2SSteve Yin 		uno::Reference< XAccessibleContext > xAccContext(xparent,uno::UNO_QUERY);
441ca62e2c2SSteve Yin 		if (xAccContext.is() && xAccContext->getAccessibleRole() == AccessibleRole::TABLE_CELL)
442ca62e2c2SSteve Yin 		{
443ca62e2c2SSteve Yin 			SwAccessibleContext* pPara = static_cast< SwAccessibleContext* >(xparent.get());
444ca62e2c2SSteve Yin 			if(pPara)
445ca62e2c2SSteve Yin 			{
446ca62e2c2SSteve Yin 				AccessibleEventObject aParaEvent;
447ca62e2c2SSteve Yin 				aParaEvent.EventId = AccessibleEventId::VALUE_CHANGED;
448ca62e2c2SSteve Yin 				pPara->FireAccessibleEvent(aParaEvent);
449ca62e2c2SSteve Yin 			}
450ca62e2c2SSteve Yin 		}
451cdf0e10cSrcweir 	}
452cdf0e10cSrcweir 	else if( !bVisibleDataFired )
453cdf0e10cSrcweir 	{
454cdf0e10cSrcweir 		FireVisibleDataEvent();
455cdf0e10cSrcweir 	}
456cdf0e10cSrcweir 
457cdf0e10cSrcweir 	sal_Bool bNewIsHeading = IsHeading();
458ca62e2c2SSteve Yin 	//Get the real heading level, Heading1 ~ Heading10
459ca62e2c2SSteve Yin 	nHeadingLevel = GetRealHeadingLevel();
460cdf0e10cSrcweir 	sal_Bool bOldIsHeading;
461cdf0e10cSrcweir 	{
462cdf0e10cSrcweir 		vos::OGuard aGuard( aMutex );
463cdf0e10cSrcweir 		bOldIsHeading = bIsHeading;
464cdf0e10cSrcweir 		if( bIsHeading != bNewIsHeading )
465cdf0e10cSrcweir 			bIsHeading = bNewIsHeading;
466cdf0e10cSrcweir 	}
467cdf0e10cSrcweir 
468cdf0e10cSrcweir 
469cdf0e10cSrcweir 	if( bNewIsHeading != bOldIsHeading || rText != sOldText )
470cdf0e10cSrcweir 	{
471cdf0e10cSrcweir         ::rtl::OUString sNewDesc( GetDescription() );
472cdf0e10cSrcweir         ::rtl::OUString sOldDesc;
473cdf0e10cSrcweir 		{
474cdf0e10cSrcweir 			vos::OGuard aGuard( aMutex );
475cdf0e10cSrcweir 			sOldDesc = sDesc;
476cdf0e10cSrcweir 			if( sDesc != sNewDesc )
477cdf0e10cSrcweir 				sDesc = sNewDesc;
478cdf0e10cSrcweir 		}
479cdf0e10cSrcweir 
480cdf0e10cSrcweir 		if( sNewDesc != sOldDesc )
481cdf0e10cSrcweir 		{
482cdf0e10cSrcweir 			// The text is changed
483cdf0e10cSrcweir 			AccessibleEventObject aEvent;
484cdf0e10cSrcweir 			aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED;
485cdf0e10cSrcweir 			aEvent.OldValue <<= sOldDesc;
486cdf0e10cSrcweir 			aEvent.NewValue <<= sNewDesc;
487cdf0e10cSrcweir 
488cdf0e10cSrcweir 			FireAccessibleEvent( aEvent );
489cdf0e10cSrcweir 		}
490cdf0e10cSrcweir 	}
491cdf0e10cSrcweir }
492cdf0e10cSrcweir 
_InvalidateCursorPos()493cdf0e10cSrcweir void SwAccessibleParagraph::_InvalidateCursorPos()
494cdf0e10cSrcweir {
495cdf0e10cSrcweir 	// The text is changed
496cdf0e10cSrcweir 	sal_Int32 nNew = GetCaretPos();
497cdf0e10cSrcweir 	sal_Int32 nOld;
498cdf0e10cSrcweir 	{
499cdf0e10cSrcweir 		vos::OGuard aGuard( aMutex );
500cdf0e10cSrcweir 		nOld = nOldCaretPos;
501cdf0e10cSrcweir 		nOldCaretPos = nNew;
502cdf0e10cSrcweir 	}
503cdf0e10cSrcweir 	if( -1 != nNew )
504cdf0e10cSrcweir 	{
505cdf0e10cSrcweir 		// remember that object as the one that has the caret. This is
506cdf0e10cSrcweir 		// neccessary to notify that object if the cursor leaves it.
507cdf0e10cSrcweir 		::vos::ORef < SwAccessibleContext > xThis( this );
508cdf0e10cSrcweir 		GetMap()->SetCursorContext( xThis );
509cdf0e10cSrcweir 	}
510cdf0e10cSrcweir 
511cdf0e10cSrcweir 	Window *pWin = GetWindow();
512cdf0e10cSrcweir 	if( nOld != nNew )
513cdf0e10cSrcweir 	{
514cdf0e10cSrcweir 		// The cursor's node position is sumilated by the focus!
515cdf0e10cSrcweir 		if( pWin && pWin->HasFocus() && -1 == nOld )
516cdf0e10cSrcweir 			FireStateChangedEvent( AccessibleStateType::FOCUSED, sal_True );
517cdf0e10cSrcweir 
518cdf0e10cSrcweir 
519cdf0e10cSrcweir 		AccessibleEventObject aEvent;
520cdf0e10cSrcweir 		aEvent.EventId = AccessibleEventId::CARET_CHANGED;
521cdf0e10cSrcweir 		aEvent.OldValue <<= nOld;
522cdf0e10cSrcweir 		aEvent.NewValue <<= nNew;
523cdf0e10cSrcweir 
524cdf0e10cSrcweir 		FireAccessibleEvent( aEvent );
525cdf0e10cSrcweir 
526cdf0e10cSrcweir 		if( pWin && pWin->HasFocus() && -1 == nNew )
527cdf0e10cSrcweir 			FireStateChangedEvent( AccessibleStateType::FOCUSED, sal_False );
528ca62e2c2SSteve Yin 		//To send TEXT_SELECTION_CHANGED event
529ca62e2c2SSteve Yin 		sal_Int32 nStart=0;
530ca62e2c2SSteve Yin 		sal_Int32 nEnd  =0;
531ca62e2c2SSteve Yin 		sal_Bool bCurSelection=GetSelection(nStart,nEnd);
532ca62e2c2SSteve Yin 		if(m_bLastHasSelection || bCurSelection )
533ca62e2c2SSteve Yin 		{
534ca62e2c2SSteve Yin 			aEvent.EventId = AccessibleEventId::TEXT_SELECTION_CHANGED;
535ca62e2c2SSteve Yin 			aEvent.OldValue <<= uno::Any();
536ca62e2c2SSteve Yin 			aEvent.NewValue <<= uno::Any();
537ca62e2c2SSteve Yin 			FireAccessibleEvent(aEvent);
538ca62e2c2SSteve Yin 		}
539ca62e2c2SSteve Yin 		m_bLastHasSelection =bCurSelection;
540cdf0e10cSrcweir 	}
541cdf0e10cSrcweir }
542cdf0e10cSrcweir 
_InvalidateFocus()543cdf0e10cSrcweir void SwAccessibleParagraph::_InvalidateFocus()
544cdf0e10cSrcweir {
545cdf0e10cSrcweir 	Window *pWin = GetWindow();
546cdf0e10cSrcweir 	if( pWin )
547cdf0e10cSrcweir 	{
548cdf0e10cSrcweir 		sal_Int32 nPos;
549cdf0e10cSrcweir 		{
550cdf0e10cSrcweir 			vos::OGuard aGuard( aMutex );
551cdf0e10cSrcweir 			nPos = nOldCaretPos;
552cdf0e10cSrcweir 		}
553cdf0e10cSrcweir 		ASSERT( nPos != -1, "focus object should be selected" );
554cdf0e10cSrcweir 
555cdf0e10cSrcweir 		FireStateChangedEvent( AccessibleStateType::FOCUSED,
556cdf0e10cSrcweir 							   pWin->HasFocus() && nPos != -1 );
557cdf0e10cSrcweir 	}
558cdf0e10cSrcweir }
559cdf0e10cSrcweir 
SwAccessibleParagraph(SwAccessibleMap & rInitMap,const SwTxtFrm & rTxtFrm)560cdf0e10cSrcweir SwAccessibleParagraph::SwAccessibleParagraph(
561cdf0e10cSrcweir         SwAccessibleMap& rInitMap,
562cdf0e10cSrcweir         const SwTxtFrm& rTxtFrm )
563cdf0e10cSrcweir     // --> OD 2010-02-24 #i108125#
564cdf0e10cSrcweir     : SwClient( const_cast<SwTxtNode*>(rTxtFrm.GetTxtNode()) )
565cdf0e10cSrcweir     // <--
566cdf0e10cSrcweir     , SwAccessibleContext( &rInitMap, AccessibleRole::PARAGRAPH, &rTxtFrm )
567cdf0e10cSrcweir     , sDesc()
568cdf0e10cSrcweir     , pPortionData( NULL )
569cdf0e10cSrcweir     , pHyperTextData( NULL )
570cdf0e10cSrcweir     , nOldCaretPos( -1 )
571cdf0e10cSrcweir     , bIsHeading( sal_False )
572ca62e2c2SSteve Yin     //Get the real heading level, Heading1 ~ Heading10
573ca62e2c2SSteve Yin     , nHeadingLevel (-1)
574cdf0e10cSrcweir     , aSelectionHelper( *this )
575cdf0e10cSrcweir     // --> OD 2010-02-19 #i108125#
576cdf0e10cSrcweir     , mpParaChangeTrackInfo( new SwParaChangeTrackingInfo( rTxtFrm ) )
577cdf0e10cSrcweir     // <--
578ca62e2c2SSteve Yin     , m_bLastHasSelection(false)  //To add TEXT_SELECTION_CHANGED event
579cdf0e10cSrcweir {
580cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
581cdf0e10cSrcweir 
582cdf0e10cSrcweir 	bIsHeading = IsHeading();
583ca62e2c2SSteve Yin 	//Get the real heading level, Heading1 ~ Heading10
584ca62e2c2SSteve Yin 	nHeadingLevel = GetRealHeadingLevel();
585cdf0e10cSrcweir     // --> OD 2004-09-27 #117970# - set an empty accessibility name for paragraphs
586cdf0e10cSrcweir     SetName( ::rtl::OUString() );
587cdf0e10cSrcweir     // <--
588cdf0e10cSrcweir 
589cdf0e10cSrcweir 	// If this object has the focus, then it is remembered by the map itself.
590ca62e2c2SSteve Yin 	// not necessary to remember this pos here. Generally, the pos will be updated in invalidateXXX method, which may fire the
591ca62e2c2SSteve Yin 	//Focus event based on the difference of new & old caret pos.
592ca62e2c2SSteve Yin 	//nOldCaretPos = GetCaretPos();
593cdf0e10cSrcweir }
594cdf0e10cSrcweir 
~SwAccessibleParagraph()595cdf0e10cSrcweir SwAccessibleParagraph::~SwAccessibleParagraph()
596cdf0e10cSrcweir {
5978394d9e9SSteve Yin 	if(Application::GetUnoWrapper())
598cdf0e10cSrcweir 		vos::OGuard aGuard(Application::GetSolarMutex());
599cdf0e10cSrcweir 
600cdf0e10cSrcweir     delete pPortionData;
601cdf0e10cSrcweir     delete pHyperTextData;
602cdf0e10cSrcweir     // --> OD 2010-02-22 #i108125#
603cdf0e10cSrcweir     delete mpParaChangeTrackInfo;
604cdf0e10cSrcweir     // <--
605cdf0e10cSrcweir }
606cdf0e10cSrcweir 
HasCursor()607cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::HasCursor()
608cdf0e10cSrcweir {
609cdf0e10cSrcweir 	vos::OGuard aGuard( aMutex );
610cdf0e10cSrcweir 	return nOldCaretPos != -1;
611cdf0e10cSrcweir }
612cdf0e10cSrcweir 
UpdatePortionData()613cdf0e10cSrcweir void SwAccessibleParagraph::UpdatePortionData()
614cdf0e10cSrcweir     throw( uno::RuntimeException )
615cdf0e10cSrcweir {
616cdf0e10cSrcweir     // obtain the text frame
617cdf0e10cSrcweir     DBG_ASSERT( GetFrm() != NULL, "The text frame has vanished!" );
618cdf0e10cSrcweir     DBG_ASSERT( GetFrm()->IsTxtFrm(), "The text frame has mutated!" );
619cdf0e10cSrcweir     const SwTxtFrm* pFrm = static_cast<const SwTxtFrm*>( GetFrm() );
620cdf0e10cSrcweir 
621cdf0e10cSrcweir     // build new portion data
622cdf0e10cSrcweir     delete pPortionData;
623cdf0e10cSrcweir     pPortionData = new SwAccessiblePortionData(
624cdf0e10cSrcweir         pFrm->GetTxtNode(), GetMap()->GetShell()->GetViewOptions() );
625cdf0e10cSrcweir     pFrm->VisitPortions( *pPortionData );
626cdf0e10cSrcweir 
627cdf0e10cSrcweir     DBG_ASSERT( pPortionData != NULL, "UpdatePortionData() failed" );
628cdf0e10cSrcweir }
629cdf0e10cSrcweir 
ClearPortionData()630cdf0e10cSrcweir void SwAccessibleParagraph::ClearPortionData()
631cdf0e10cSrcweir {
632cdf0e10cSrcweir     delete pPortionData;
633cdf0e10cSrcweir     pPortionData = NULL;
634cdf0e10cSrcweir 
635cdf0e10cSrcweir 	delete pHyperTextData;
636cdf0e10cSrcweir 	pHyperTextData = 0;
637cdf0e10cSrcweir }
638cdf0e10cSrcweir 
639cdf0e10cSrcweir 
ExecuteAtViewShell(sal_uInt16 nSlot)640cdf0e10cSrcweir void SwAccessibleParagraph::ExecuteAtViewShell( sal_uInt16 nSlot )
641cdf0e10cSrcweir {
642cdf0e10cSrcweir     DBG_ASSERT( GetMap() != NULL, "no map?" );
643cdf0e10cSrcweir     ViewShell* pViewShell = GetMap()->GetShell();
644cdf0e10cSrcweir 
645cdf0e10cSrcweir     DBG_ASSERT( pViewShell != NULL, "View shell exptected!" );
646cdf0e10cSrcweir     SfxViewShell* pSfxShell = pViewShell->GetSfxViewShell();
647cdf0e10cSrcweir 
648cdf0e10cSrcweir     DBG_ASSERT( pSfxShell != NULL, "SfxViewShell shell exptected!" );
649cdf0e10cSrcweir     if( !pSfxShell )
650cdf0e10cSrcweir 		return;
651cdf0e10cSrcweir 
652cdf0e10cSrcweir 	SfxViewFrame *pFrame = pSfxShell->GetViewFrame();
653cdf0e10cSrcweir     DBG_ASSERT( pFrame != NULL, "View frame exptected!" );
654cdf0e10cSrcweir 	if( !pFrame )
655cdf0e10cSrcweir 		return;
656cdf0e10cSrcweir 
657cdf0e10cSrcweir 	SfxDispatcher *pDispatcher = pFrame->GetDispatcher();
658cdf0e10cSrcweir     DBG_ASSERT( pDispatcher != NULL, "Dispatcher exptected!" );
659cdf0e10cSrcweir 	if( !pDispatcher )
660cdf0e10cSrcweir 		return;
661cdf0e10cSrcweir 
662cdf0e10cSrcweir 	pDispatcher->Execute( nSlot );
663cdf0e10cSrcweir }
664cdf0e10cSrcweir 
CreateUnoPortion(sal_Int32 nStartIndex,sal_Int32 nEndIndex)665cdf0e10cSrcweir SwXTextPortion* SwAccessibleParagraph::CreateUnoPortion(
666cdf0e10cSrcweir     sal_Int32 nStartIndex,
667cdf0e10cSrcweir     sal_Int32 nEndIndex )
668cdf0e10cSrcweir {
669cdf0e10cSrcweir     DBG_ASSERT( (IsValidChar(nStartIndex, GetString().getLength()) &&
670cdf0e10cSrcweir                  (nEndIndex == -1)) ||
671cdf0e10cSrcweir                 IsValidRange(nStartIndex, nEndIndex, GetString().getLength()),
672cdf0e10cSrcweir                 "please check parameters before calling this method" );
673cdf0e10cSrcweir 
674cdf0e10cSrcweir     sal_uInt16 nStart = GetPortionData().GetModelPosition( nStartIndex );
675cdf0e10cSrcweir     sal_uInt16 nEnd = (nEndIndex == -1) ? (nStart + 1) :
676cdf0e10cSrcweir                         GetPortionData().GetModelPosition( nEndIndex );
677cdf0e10cSrcweir 
678cdf0e10cSrcweir     // create UNO cursor
679cdf0e10cSrcweir     SwTxtNode* pTxtNode = const_cast<SwTxtNode*>( GetTxtNode() );
680cdf0e10cSrcweir     SwIndex aIndex( pTxtNode, nStart );
681cdf0e10cSrcweir     SwPosition aStartPos( *pTxtNode, aIndex );
682cdf0e10cSrcweir     SwUnoCrsr* pUnoCursor = pTxtNode->GetDoc()->CreateUnoCrsr( aStartPos );
683cdf0e10cSrcweir     pUnoCursor->SetMark();
684cdf0e10cSrcweir     pUnoCursor->GetMark()->nContent = nEnd;
685cdf0e10cSrcweir 
686cdf0e10cSrcweir     // create a (dummy) text portion to be returned
687cdf0e10cSrcweir     uno::Reference<text::XText> aEmpty;
688cdf0e10cSrcweir     SwXTextPortion* pPortion =
689cdf0e10cSrcweir         new SwXTextPortion ( pUnoCursor, aEmpty, PORTION_TEXT);
690cdf0e10cSrcweir     delete pUnoCursor;
691cdf0e10cSrcweir 
692cdf0e10cSrcweir     return pPortion;
693cdf0e10cSrcweir }
694cdf0e10cSrcweir 
695cdf0e10cSrcweir 
696cdf0e10cSrcweir //
697cdf0e10cSrcweir // range checking for parameter
698cdf0e10cSrcweir //
699cdf0e10cSrcweir 
IsValidChar(sal_Int32 nPos,sal_Int32 nLength)700cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::IsValidChar(
701cdf0e10cSrcweir     sal_Int32 nPos, sal_Int32 nLength)
702cdf0e10cSrcweir {
703cdf0e10cSrcweir     return (nPos >= 0) && (nPos < nLength);
704cdf0e10cSrcweir }
705cdf0e10cSrcweir 
IsValidPosition(sal_Int32 nPos,sal_Int32 nLength)706cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::IsValidPosition(
707cdf0e10cSrcweir     sal_Int32 nPos, sal_Int32 nLength)
708cdf0e10cSrcweir {
709cdf0e10cSrcweir     return (nPos >= 0) && (nPos <= nLength);
710cdf0e10cSrcweir }
711cdf0e10cSrcweir 
IsValidRange(sal_Int32 nBegin,sal_Int32 nEnd,sal_Int32 nLength)712cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::IsValidRange(
713cdf0e10cSrcweir     sal_Int32 nBegin, sal_Int32 nEnd, sal_Int32 nLength)
714cdf0e10cSrcweir {
715cdf0e10cSrcweir     return IsValidPosition(nBegin, nLength) && IsValidPosition(nEnd, nLength);
716cdf0e10cSrcweir }
GetTOXSortTabBase()717ca62e2c2SSteve Yin SwTOXSortTabBase* SwAccessibleParagraph::GetTOXSortTabBase()
718ca62e2c2SSteve Yin {
719ca62e2c2SSteve Yin 	const SwTxtNode* pTxtNd = GetTxtNode();
720ca62e2c2SSteve Yin 	if( pTxtNd )
721ca62e2c2SSteve Yin 	{
722ca62e2c2SSteve Yin 		const SwSectionNode * pSectNd = pTxtNd->FindSectionNode();
723ca62e2c2SSteve Yin 		if( pSectNd )
724ca62e2c2SSteve Yin 		{
725ca62e2c2SSteve Yin 			const SwSection * pSect = &pSectNd->GetSection();
726ca62e2c2SSteve Yin 			SwTOXBaseSection *pTOXBaseSect = (SwTOXBaseSection *)pSect;
727ca62e2c2SSteve Yin 			if( pSect->GetType() == TOX_CONTENT_SECTION )
728ca62e2c2SSteve Yin 			{
729ca62e2c2SSteve Yin 				SwTOXSortTabBase* pSortBase = 0;
730ca62e2c2SSteve Yin 				int nSize = pTOXBaseSect->GetTOXSortTabBases()->Count();
731cdf0e10cSrcweir 
732ca62e2c2SSteve Yin 				for(int nIndex = 0; nIndex<nSize; nIndex++ )
733ca62e2c2SSteve Yin 				{
734ca62e2c2SSteve Yin 					pSortBase = (*(pTOXBaseSect->GetTOXSortTabBases()))[nIndex];
735ca62e2c2SSteve Yin 					if( pSortBase->pTOXNd == pTxtNd )
736ca62e2c2SSteve Yin 						break;
737ca62e2c2SSteve Yin 				}
738ca62e2c2SSteve Yin 
739ca62e2c2SSteve Yin 				if (pSortBase)
740ca62e2c2SSteve Yin 				{
741ca62e2c2SSteve Yin 					return pSortBase;
742ca62e2c2SSteve Yin 				}
743ca62e2c2SSteve Yin 			}
744ca62e2c2SSteve Yin 		}
745ca62e2c2SSteve Yin 	}
746ca62e2c2SSteve Yin 	return NULL;
747ca62e2c2SSteve Yin }
748ca62e2c2SSteve Yin 
GetTOCLevel()749ca62e2c2SSteve Yin short SwAccessibleParagraph::GetTOCLevel()
750ca62e2c2SSteve Yin {
751ca62e2c2SSteve Yin 	SwTOXSortTabBase* pToxBase = GetTOXSortTabBase();
752ca62e2c2SSteve Yin 	if( pToxBase )
753ca62e2c2SSteve Yin 	{
754ca62e2c2SSteve Yin 		const SwCntntNode*	pNd = pToxBase->aTOXSources[0].pNd;
755ca62e2c2SSteve Yin 		if( pNd )
756ca62e2c2SSteve Yin 			return pToxBase->GetLevel();
757ca62e2c2SSteve Yin 		else
758ca62e2c2SSteve Yin 			return -1;
759ca62e2c2SSteve Yin 	}
760ca62e2c2SSteve Yin 	else
761ca62e2c2SSteve Yin 		return -1;
762ca62e2c2SSteve Yin }
763ca62e2c2SSteve Yin 
764ca62e2c2SSteve Yin //the function is to check whether the position is in a redline range.
GetRedlineAtIndex(sal_Int32)765ca62e2c2SSteve Yin const SwRedline* SwAccessibleParagraph::GetRedlineAtIndex( sal_Int32 )
766ca62e2c2SSteve Yin {
767ca62e2c2SSteve Yin 	const SwRedline* pRedline = NULL;
768ca62e2c2SSteve Yin 	SwPaM* pCrSr = GetCursor( true );
769ca62e2c2SSteve Yin 	if ( pCrSr )
770ca62e2c2SSteve Yin 	{
771ca62e2c2SSteve Yin 		SwPosition* pStart = pCrSr->Start();
772ca62e2c2SSteve Yin 		const SwTxtNode* pNode = GetTxtNode();
773ca62e2c2SSteve Yin 		if ( pNode )
774ca62e2c2SSteve Yin 		{
775ca62e2c2SSteve Yin 			const SwDoc* pDoc = pNode->GetDoc();
776ca62e2c2SSteve Yin 			if ( pDoc )
777ca62e2c2SSteve Yin 			{
778ca62e2c2SSteve Yin 				pRedline = pDoc->GetRedline( *pStart, NULL );
779ca62e2c2SSteve Yin 			}
780ca62e2c2SSteve Yin 		}
781ca62e2c2SSteve Yin 	}
782ca62e2c2SSteve Yin 
783ca62e2c2SSteve Yin 	return pRedline;
784ca62e2c2SSteve Yin }
785cdf0e10cSrcweir 
786cdf0e10cSrcweir //
787cdf0e10cSrcweir // text boundaries
788cdf0e10cSrcweir //
789cdf0e10cSrcweir 
790cdf0e10cSrcweir 
GetCharBoundary(i18n::Boundary & rBound,const::rtl::OUString &,sal_Int32 nPos)791cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::GetCharBoundary(
792cdf0e10cSrcweir     i18n::Boundary& rBound,
793cdf0e10cSrcweir     const ::rtl::OUString&,
794cdf0e10cSrcweir     sal_Int32 nPos )
795cdf0e10cSrcweir {
796ca62e2c2SSteve Yin     if( GetPortionData().FillBoundaryIFDateField( rBound,  nPos) )
797ca62e2c2SSteve Yin 		return sal_True;
798ca62e2c2SSteve Yin 
799cdf0e10cSrcweir     rBound.startPos = nPos;
800cdf0e10cSrcweir     rBound.endPos = nPos+1;
801cdf0e10cSrcweir     return sal_True;
802cdf0e10cSrcweir }
803cdf0e10cSrcweir 
GetWordBoundary(i18n::Boundary & rBound,const::rtl::OUString & rText,sal_Int32 nPos)804cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::GetWordBoundary(
805cdf0e10cSrcweir     i18n::Boundary& rBound,
806cdf0e10cSrcweir     const ::rtl::OUString& rText,
807cdf0e10cSrcweir     sal_Int32 nPos )
808cdf0e10cSrcweir {
809cdf0e10cSrcweir     sal_Bool bRet = sal_False;
810cdf0e10cSrcweir 
811cdf0e10cSrcweir     // now ask the Break-Iterator for the word
812cdf0e10cSrcweir     DBG_ASSERT( pBreakIt != NULL, "We always need a break." );
813cdf0e10cSrcweir     DBG_ASSERT( pBreakIt->GetBreakIter().is(), "No break-iterator." );
814cdf0e10cSrcweir     if( pBreakIt->GetBreakIter().is() )
815cdf0e10cSrcweir     {
816cdf0e10cSrcweir         // get locale for this position
817cdf0e10cSrcweir         sal_uInt16 nModelPos = GetPortionData().GetModelPosition( nPos );
818cdf0e10cSrcweir         lang::Locale aLocale = pBreakIt->GetLocale(
819cdf0e10cSrcweir                               GetTxtNode()->GetLang( nModelPos ) );
820cdf0e10cSrcweir 
821cdf0e10cSrcweir         // which type of word are we interested in?
822cdf0e10cSrcweir         // (DICTIONARY_WORD includes punctuation, ANY_WORD doesn't.)
823cdf0e10cSrcweir         const sal_uInt16 nWordType = i18n::WordType::ANY_WORD;
824cdf0e10cSrcweir 
825ca62e2c2SSteve Yin /*
826ca62e2c2SSteve Yin 		// get word boundary, as the Break-Iterator sees fit.
827ca62e2c2SSteve Yin 		sal_Unicode SpaceChar(' ');
828ca62e2c2SSteve Yin 		if (rText.getCodePointAt(nPos) == SpaceChar)
829ca62e2c2SSteve Yin 		{
830ca62e2c2SSteve Yin 			int nStartPos = nPos;
831ca62e2c2SSteve Yin 			int nEndPos = nPos+1;
832ca62e2c2SSteve Yin 			while (nStartPos >= 0 && rText.getCodePointAt(nStartPos) == SpaceChar)
833ca62e2c2SSteve Yin 				--nStartPos;
834ca62e2c2SSteve Yin 			while (nEndPos < rText.getLength() && rText.getCodePointAt(nEndPos) == SpaceChar)
835ca62e2c2SSteve Yin 				++nEndPos;
836ca62e2c2SSteve Yin 			//Get the previous word boundary + the followed space characters
837ca62e2c2SSteve Yin 			if (nStartPos >= 0)
838ca62e2c2SSteve Yin 			{
839ca62e2c2SSteve Yin 				rBound = pBreakIt->xBreak->getWordBoundary( rText, nStartPos, aLocale, nWordType, sal_True );
840ca62e2c2SSteve Yin 				rBound.endPos += (nEndPos-nStartPos - 1);
841ca62e2c2SSteve Yin 			}
842ca62e2c2SSteve Yin 			//When the frontal characters are whitespace, return the all space characters directly.
843ca62e2c2SSteve Yin 			else
844ca62e2c2SSteve Yin 			{
845ca62e2c2SSteve Yin 				rBound.startPos = 0;
846ca62e2c2SSteve Yin 				rBound.endPos = nEndPos;
847ca62e2c2SSteve Yin 			}
848ca62e2c2SSteve Yin 		}
849ca62e2c2SSteve Yin 		// add the " " into the word boundry
850ca62e2c2SSteve Yin 		else
851ca62e2c2SSteve Yin 		{
852ca62e2c2SSteve Yin 			rBound = pBreakIt->xBreak->getWordBoundary(rText, nPos, aLocale, nWordType, sal_True );
853ca62e2c2SSteve Yin 			sal_Int32 nEndPos = rBound.endPos, nLength = rText.getLength();
854ca62e2c2SSteve Yin 			while ( nEndPos < nLength && rText.getCodePointAt(nEndPos) == SpaceChar )
855ca62e2c2SSteve Yin 				nEndPos++;
856ca62e2c2SSteve Yin 			rBound.endPos = nEndPos;
857ca62e2c2SSteve Yin 		}
858ca62e2c2SSteve Yin 		tabCharInWord( nPos, rBound);
859ca62e2c2SSteve Yin 		if( GetPortionData().FillBoundaryIFDateField( rBound,  rBound.startPos) )
860ca62e2c2SSteve Yin 			return sal_True;
861ca62e2c2SSteve Yin         return sal_True; // MT: So why do we need the return TRUE above???
862ca62e2c2SSteve Yin */
863cdf0e10cSrcweir         // get word boundary, as the Break-Iterator sees fit.
864cdf0e10cSrcweir         rBound = pBreakIt->GetBreakIter()->getWordBoundary(
865cdf0e10cSrcweir             rText, nPos, aLocale, nWordType, sal_True );
866cdf0e10cSrcweir 
867cdf0e10cSrcweir         // It's a word if the first character is an alpha-numeric character.
868cdf0e10cSrcweir         bRet = GetAppCharClass().isLetterNumeric(
869cdf0e10cSrcweir             rText.getStr()[ rBound.startPos ] );
870cdf0e10cSrcweir     }
871cdf0e10cSrcweir     else
872cdf0e10cSrcweir     {
873cdf0e10cSrcweir         // no break Iterator -> no word
874cdf0e10cSrcweir         rBound.startPos = nPos;
875cdf0e10cSrcweir         rBound.endPos = nPos;
876cdf0e10cSrcweir     }
877cdf0e10cSrcweir 
878cdf0e10cSrcweir     return bRet;
879cdf0e10cSrcweir }
880cdf0e10cSrcweir 
GetSentenceBoundary(i18n::Boundary & rBound,const::rtl::OUString & rText,sal_Int32 nPos)881cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::GetSentenceBoundary(
882cdf0e10cSrcweir     i18n::Boundary& rBound,
883ca62e2c2SSteve Yin     const ::rtl::OUString& rText,
884cdf0e10cSrcweir     sal_Int32 nPos )
885cdf0e10cSrcweir {
886ca62e2c2SSteve Yin 	const sal_Unicode* pStr = rText.getStr();
887ca62e2c2SSteve Yin 	if (pStr)
888ca62e2c2SSteve Yin 	{
889ca62e2c2SSteve Yin 		while( pStr[nPos] == sal_Unicode(' ') && nPos < rText.getLength())
890ca62e2c2SSteve Yin 			nPos++;
891ca62e2c2SSteve Yin 	}
892cdf0e10cSrcweir     GetPortionData().GetSentenceBoundary( rBound, nPos );
893cdf0e10cSrcweir     return sal_True;
894cdf0e10cSrcweir }
895cdf0e10cSrcweir 
GetLineBoundary(i18n::Boundary & rBound,const::rtl::OUString & rText,sal_Int32 nPos)896cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::GetLineBoundary(
897cdf0e10cSrcweir     i18n::Boundary& rBound,
898cdf0e10cSrcweir     const ::rtl::OUString& rText,
899cdf0e10cSrcweir     sal_Int32 nPos )
900cdf0e10cSrcweir {
901cdf0e10cSrcweir 	if( rText.getLength() == nPos )
902cdf0e10cSrcweir 		GetPortionData().GetLastLineBoundary( rBound );
903cdf0e10cSrcweir 	else
904cdf0e10cSrcweir 		GetPortionData().GetLineBoundary( rBound, nPos );
905cdf0e10cSrcweir     return sal_True;
906cdf0e10cSrcweir }
907cdf0e10cSrcweir 
GetParagraphBoundary(i18n::Boundary & rBound,const::rtl::OUString & rText,sal_Int32)908cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::GetParagraphBoundary(
909cdf0e10cSrcweir     i18n::Boundary& rBound,
910cdf0e10cSrcweir     const ::rtl::OUString& rText,
911cdf0e10cSrcweir     sal_Int32 )
912cdf0e10cSrcweir {
913cdf0e10cSrcweir     rBound.startPos = 0;
914cdf0e10cSrcweir     rBound.endPos = rText.getLength();
915cdf0e10cSrcweir     return sal_True;
916cdf0e10cSrcweir }
917cdf0e10cSrcweir 
GetAttributeBoundary(i18n::Boundary & rBound,const::rtl::OUString &,sal_Int32 nPos)918cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::GetAttributeBoundary(
919cdf0e10cSrcweir     i18n::Boundary& rBound,
920cdf0e10cSrcweir     const ::rtl::OUString&,
921cdf0e10cSrcweir     sal_Int32 nPos )
922cdf0e10cSrcweir {
923cdf0e10cSrcweir     GetPortionData().GetAttributeBoundary( rBound, nPos );
924cdf0e10cSrcweir     return sal_True;
925cdf0e10cSrcweir }
926cdf0e10cSrcweir 
GetGlyphBoundary(i18n::Boundary & rBound,const::rtl::OUString & rText,sal_Int32 nPos)927cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::GetGlyphBoundary(
928cdf0e10cSrcweir     i18n::Boundary& rBound,
929cdf0e10cSrcweir     const ::rtl::OUString& rText,
930cdf0e10cSrcweir     sal_Int32 nPos )
931cdf0e10cSrcweir {
932cdf0e10cSrcweir     sal_Bool bRet = sal_False;
933cdf0e10cSrcweir 
934cdf0e10cSrcweir     // ask the Break-Iterator for the glyph by moving one cell
935cdf0e10cSrcweir     // forward, and then one cell back
936cdf0e10cSrcweir     DBG_ASSERT( pBreakIt != NULL, "We always need a break." );
937cdf0e10cSrcweir     DBG_ASSERT( pBreakIt->GetBreakIter().is(), "No break-iterator." );
938cdf0e10cSrcweir     if( pBreakIt->GetBreakIter().is() )
939cdf0e10cSrcweir     {
940cdf0e10cSrcweir         // get locale for this position
941cdf0e10cSrcweir         sal_uInt16 nModelPos = GetPortionData().GetModelPosition( nPos );
942cdf0e10cSrcweir         lang::Locale aLocale = pBreakIt->GetLocale(
943cdf0e10cSrcweir                               GetTxtNode()->GetLang( nModelPos ) );
944cdf0e10cSrcweir 
945cdf0e10cSrcweir         // get word boundary, as the Break-Iterator sees fit.
946cdf0e10cSrcweir         const sal_uInt16 nIterMode = i18n::CharacterIteratorMode::SKIPCELL;
947cdf0e10cSrcweir         sal_Int32 nDone = 0;
948cdf0e10cSrcweir         rBound.endPos = pBreakIt->GetBreakIter()->nextCharacters(
949cdf0e10cSrcweir              rText, nPos, aLocale, nIterMode, 1, nDone );
950cdf0e10cSrcweir         rBound.startPos = pBreakIt->GetBreakIter()->previousCharacters(
951cdf0e10cSrcweir              rText, rBound.endPos, aLocale, nIterMode, 1, nDone );
952cdf0e10cSrcweir 
953187afabeSHerbert Dürr         bRet = ((rBound.startPos <= nPos) && (nPos <= rBound.endPos));
954cdf0e10cSrcweir         DBG_ASSERT( rBound.startPos <= nPos, "start pos too high" );
955cdf0e10cSrcweir         DBG_ASSERT( rBound.endPos >= nPos, "end pos too low" );
956cdf0e10cSrcweir     }
957cdf0e10cSrcweir     else
958cdf0e10cSrcweir     {
959cdf0e10cSrcweir         // no break Iterator -> no glyph
960cdf0e10cSrcweir         rBound.startPos = nPos;
961cdf0e10cSrcweir         rBound.endPos = nPos;
962cdf0e10cSrcweir     }
963cdf0e10cSrcweir 
964cdf0e10cSrcweir     return bRet;
965cdf0e10cSrcweir }
966cdf0e10cSrcweir 
967cdf0e10cSrcweir 
GetTextBoundary(i18n::Boundary & rBound,const::rtl::OUString & rText,sal_Int32 nPos,sal_Int16 nTextType)968cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::GetTextBoundary(
969cdf0e10cSrcweir     i18n::Boundary& rBound,
970cdf0e10cSrcweir     const ::rtl::OUString& rText,
971cdf0e10cSrcweir     sal_Int32 nPos,
972cdf0e10cSrcweir     sal_Int16 nTextType )
973cdf0e10cSrcweir     throw (
974cdf0e10cSrcweir         lang::IndexOutOfBoundsException,
975cdf0e10cSrcweir         lang::IllegalArgumentException,
976cdf0e10cSrcweir         uno::RuntimeException)
977cdf0e10cSrcweir {
978cdf0e10cSrcweir     // error checking
979cdf0e10cSrcweir     if( !( AccessibleTextType::LINE == nTextType
980cdf0e10cSrcweir 				? IsValidPosition( nPos, rText.getLength() )
981cdf0e10cSrcweir 				: IsValidChar( nPos, rText.getLength() ) ) )
982cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
983cdf0e10cSrcweir 
984cdf0e10cSrcweir     sal_Bool bRet;
985cdf0e10cSrcweir 
986cdf0e10cSrcweir     switch( nTextType )
987cdf0e10cSrcweir     {
988cdf0e10cSrcweir         case AccessibleTextType::WORD:
989cdf0e10cSrcweir             bRet = GetWordBoundary( rBound, rText, nPos );
990cdf0e10cSrcweir             break;
991cdf0e10cSrcweir 
992cdf0e10cSrcweir         case AccessibleTextType::SENTENCE:
993cdf0e10cSrcweir             bRet = GetSentenceBoundary( rBound, rText, nPos );
994cdf0e10cSrcweir             break;
995cdf0e10cSrcweir 
996cdf0e10cSrcweir         case AccessibleTextType::PARAGRAPH:
997cdf0e10cSrcweir             bRet = GetParagraphBoundary( rBound, rText, nPos );
998cdf0e10cSrcweir             break;
999cdf0e10cSrcweir 
1000cdf0e10cSrcweir         case AccessibleTextType::CHARACTER:
1001cdf0e10cSrcweir             bRet = GetCharBoundary( rBound, rText, nPos );
1002cdf0e10cSrcweir             break;
1003cdf0e10cSrcweir 
1004cdf0e10cSrcweir         case AccessibleTextType::LINE:
1005ca62e2c2SSteve Yin             //Solve the problem of returning wrong LINE and PARAGRAPH
1006ca62e2c2SSteve Yin             if((nPos == rText.getLength()) && nPos > 0)
1007ca62e2c2SSteve Yin             	bRet = GetLineBoundary( rBound, rText, nPos - 1);
1008ca62e2c2SSteve Yin             else
1009cdf0e10cSrcweir             	bRet = GetLineBoundary( rBound, rText, nPos );
1010cdf0e10cSrcweir             break;
1011cdf0e10cSrcweir 
1012cdf0e10cSrcweir         case AccessibleTextType::ATTRIBUTE_RUN:
1013cdf0e10cSrcweir             bRet = GetAttributeBoundary( rBound, rText, nPos );
1014ca62e2c2SSteve Yin 			if(bRet)
1015ca62e2c2SSteve Yin 			{
1016ca62e2c2SSteve Yin 				SwCrsrShell* pCrsrShell = GetCrsrShell();
1017ca62e2c2SSteve Yin 				if( pCrsrShell != NULL && pCrsrShell->GetViewOptions() && pCrsrShell->GetViewOptions()->IsOnlineSpell())
1018ca62e2c2SSteve Yin 				{
1019ca62e2c2SSteve Yin 					SwTxtNode* pTxtNode = const_cast<SwTxtNode*>( GetTxtNode() );
1020ca62e2c2SSteve Yin 					if(pTxtNode)
1021ca62e2c2SSteve Yin 					{
1022ca62e2c2SSteve Yin 						const SwWrongList* pWrongList = pTxtNode->GetWrong();
1023ca62e2c2SSteve Yin 						if( NULL != pWrongList )
1024ca62e2c2SSteve Yin 						{
1025ca62e2c2SSteve Yin 							xub_StrLen nBegin = nPos;
1026ca62e2c2SSteve Yin 							xub_StrLen nLen = 1;
1027ca62e2c2SSteve Yin 							const xub_StrLen nNext = pWrongList->NextWrong(nBegin);
1028ca62e2c2SSteve Yin 							xub_StrLen nLast;
1029ca62e2c2SSteve Yin                             xub_StrLen nWrongPos = pWrongList->GetWrongPos( nBegin );
1030ca62e2c2SSteve Yin                             if ( nWrongPos >= pWrongList->Count() ||
1031ca62e2c2SSteve Yin                                  ( nLast = pWrongList->Pos( nWrongPos ) ) >= nBegin )
1032ca62e2c2SSteve Yin                             {
1033ca62e2c2SSteve Yin                                 nLast = nWrongPos
1034ca62e2c2SSteve Yin                                         ? pWrongList->Pos( --nWrongPos )
1035ca62e2c2SSteve Yin                                         : STRING_LEN;
1036ca62e2c2SSteve Yin                             }
1037ca62e2c2SSteve Yin                             if ( nBegin > pWrongList->GetBeginInv() &&
1038ca62e2c2SSteve Yin                                  ( nLast == STRING_LEN || nLast < pWrongList->GetEndInv() ) )
1039ca62e2c2SSteve Yin                             {
1040ca62e2c2SSteve Yin                                 nLast = nBegin > pWrongList->GetEndInv()
1041ca62e2c2SSteve Yin                                         ? pWrongList->GetEndInv()
1042ca62e2c2SSteve Yin                                         : nBegin;
1043ca62e2c2SSteve Yin                             }
1044ca62e2c2SSteve Yin                             else if ( nLast < STRING_LEN )
1045ca62e2c2SSteve Yin                             {
1046ca62e2c2SSteve Yin                                 nLast += pWrongList->Len( nWrongPos );
1047ca62e2c2SSteve Yin                             }
1048ca62e2c2SSteve Yin 							//
1049ca62e2c2SSteve Yin 							sal_Bool bIn = pWrongList->InWrongWord(nBegin,nLen); // && !pTxtNode->IsSymbol(nBegin) )
1050ca62e2c2SSteve Yin 							if(bIn)
1051ca62e2c2SSteve Yin 							{
1052ca62e2c2SSteve Yin 								rBound.startPos = max(nNext,(xub_StrLen)rBound.startPos);
1053ca62e2c2SSteve Yin 								rBound.endPos = min(xub_StrLen(nNext + nLen),(xub_StrLen)rBound.endPos);
1054ca62e2c2SSteve Yin 							}
1055ca62e2c2SSteve Yin 							else
1056ca62e2c2SSteve Yin 							{
1057ca62e2c2SSteve Yin 								if (STRING_LEN == nLast)//first
1058ca62e2c2SSteve Yin 								{
1059ca62e2c2SSteve Yin 									rBound.endPos = min(nNext,(xub_StrLen)rBound.endPos);
1060ca62e2c2SSteve Yin 								}
1061ca62e2c2SSteve Yin 								else if(STRING_LEN == nNext)
1062ca62e2c2SSteve Yin 								{
1063ca62e2c2SSteve Yin 									rBound.startPos = max(nLast,(xub_StrLen)rBound.startPos);
1064ca62e2c2SSteve Yin 								}
1065ca62e2c2SSteve Yin 								else
1066ca62e2c2SSteve Yin 								{
1067ca62e2c2SSteve Yin 									rBound.startPos = max(nLast,(xub_StrLen)rBound.startPos);
1068ca62e2c2SSteve Yin 									rBound.endPos = min(nNext,(xub_StrLen)rBound.endPos);
1069ca62e2c2SSteve Yin 								}
1070ca62e2c2SSteve Yin 							}
1071ca62e2c2SSteve Yin 						}
1072ca62e2c2SSteve Yin 					}
1073ca62e2c2SSteve Yin 				}
1074ca62e2c2SSteve Yin 			}
1075cdf0e10cSrcweir             break;
1076cdf0e10cSrcweir 
1077cdf0e10cSrcweir         case AccessibleTextType::GLYPH:
1078cdf0e10cSrcweir             bRet = GetGlyphBoundary( rBound, rText, nPos );
1079cdf0e10cSrcweir             break;
1080cdf0e10cSrcweir 
1081cdf0e10cSrcweir         default:
1082cdf0e10cSrcweir             throw lang::IllegalArgumentException( );
1083cdf0e10cSrcweir     }
1084cdf0e10cSrcweir 
1085cdf0e10cSrcweir     return bRet;
1086cdf0e10cSrcweir }
1087cdf0e10cSrcweir 
getAccessibleDescription(void)1088cdf0e10cSrcweir ::rtl::OUString SAL_CALL SwAccessibleParagraph::getAccessibleDescription (void)
1089cdf0e10cSrcweir         throw (uno::RuntimeException)
1090cdf0e10cSrcweir {
1091cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
1092cdf0e10cSrcweir 
1093cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleContext );
1094cdf0e10cSrcweir 
1095cdf0e10cSrcweir 	vos::OGuard aGuard2( aMutex );
1096cdf0e10cSrcweir 	if( !sDesc.getLength() )
1097cdf0e10cSrcweir 		sDesc = GetDescription();
1098cdf0e10cSrcweir 
1099cdf0e10cSrcweir     return sDesc;
1100cdf0e10cSrcweir }
1101cdf0e10cSrcweir 
getLocale(void)1102cdf0e10cSrcweir lang::Locale SAL_CALL SwAccessibleParagraph::getLocale (void)
1103cdf0e10cSrcweir         throw (IllegalAccessibleComponentStateException, uno::RuntimeException)
1104cdf0e10cSrcweir {
1105cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
1106cdf0e10cSrcweir 
1107cdf0e10cSrcweir 	SwTxtFrm *pTxtFrm = PTR_CAST( SwTxtFrm, GetFrm() );
1108cdf0e10cSrcweir 	if( !pTxtFrm )
1109cdf0e10cSrcweir 	{
1110cdf0e10cSrcweir 		THROW_RUNTIME_EXCEPTION( XAccessibleContext, "internal error (no text frame)" );
1111cdf0e10cSrcweir 	}
1112cdf0e10cSrcweir 
1113cdf0e10cSrcweir 	const SwTxtNode *pTxtNd = pTxtFrm->GetTxtNode();
1114cdf0e10cSrcweir     lang::Locale aLoc( pBreakIt->GetLocale( pTxtNd->GetLang( 0 ) ) );
1115cdf0e10cSrcweir 
1116cdf0e10cSrcweir 	return aLoc;
1117cdf0e10cSrcweir }
1118cdf0e10cSrcweir 
1119cdf0e10cSrcweir /** paragraphs are in relation CONTENT_FLOWS_FROM and/or CONTENT_FLOWS_TO
1120cdf0e10cSrcweir 
1121cdf0e10cSrcweir     OD 2005-12-02 #i27138#
1122cdf0e10cSrcweir 
1123cdf0e10cSrcweir     @author OD
1124cdf0e10cSrcweir */
getAccessibleRelationSet()1125cdf0e10cSrcweir uno::Reference<XAccessibleRelationSet> SAL_CALL SwAccessibleParagraph::getAccessibleRelationSet()
1126cdf0e10cSrcweir     throw ( uno::RuntimeException )
1127cdf0e10cSrcweir {
1128cdf0e10cSrcweir     vos::OGuard aGuard(Application::GetSolarMutex());
1129cdf0e10cSrcweir     CHECK_FOR_DEFUNC( XAccessibleContext );
1130cdf0e10cSrcweir 
1131cdf0e10cSrcweir     utl::AccessibleRelationSetHelper* pHelper = new utl::AccessibleRelationSetHelper();
1132cdf0e10cSrcweir 
1133cdf0e10cSrcweir     const SwTxtFrm* pTxtFrm = dynamic_cast<const SwTxtFrm*>(GetFrm());
1134cdf0e10cSrcweir     ASSERT( pTxtFrm,
1135cdf0e10cSrcweir             "<SwAccessibleParagraph::getAccessibleRelationSet()> - missing text frame");
1136cdf0e10cSrcweir     if ( pTxtFrm )
1137cdf0e10cSrcweir     {
1138cdf0e10cSrcweir         const SwCntntFrm* pPrevCntFrm( pTxtFrm->FindPrevCnt( true ) );
1139cdf0e10cSrcweir         if ( pPrevCntFrm )
1140cdf0e10cSrcweir         {
1141cdf0e10cSrcweir             uno::Sequence< uno::Reference<XInterface> > aSequence(1);
1142cdf0e10cSrcweir             aSequence[0] = GetMap()->GetContext( pPrevCntFrm );
1143cdf0e10cSrcweir             AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_FROM,
1144cdf0e10cSrcweir                                         aSequence );
1145cdf0e10cSrcweir             pHelper->AddRelation( aAccRel );
1146cdf0e10cSrcweir         }
1147cdf0e10cSrcweir 
1148cdf0e10cSrcweir         const SwCntntFrm* pNextCntFrm( pTxtFrm->FindNextCnt( true ) );
1149cdf0e10cSrcweir         if ( pNextCntFrm )
1150cdf0e10cSrcweir         {
1151cdf0e10cSrcweir             uno::Sequence< uno::Reference<XInterface> > aSequence(1);
1152cdf0e10cSrcweir             aSequence[0] = GetMap()->GetContext( pNextCntFrm );
1153cdf0e10cSrcweir             AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_TO,
1154cdf0e10cSrcweir                                         aSequence );
1155cdf0e10cSrcweir             pHelper->AddRelation( aAccRel );
1156cdf0e10cSrcweir         }
1157cdf0e10cSrcweir     }
1158cdf0e10cSrcweir 
1159cdf0e10cSrcweir     return pHelper;
1160cdf0e10cSrcweir }
1161cdf0e10cSrcweir 
grabFocus()1162cdf0e10cSrcweir void SAL_CALL SwAccessibleParagraph::grabFocus()
1163cdf0e10cSrcweir         throw (uno::RuntimeException)
1164cdf0e10cSrcweir {
1165cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
1166cdf0e10cSrcweir 
1167cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleContext );
1168cdf0e10cSrcweir 
1169cdf0e10cSrcweir     // get cursor shell
1170cdf0e10cSrcweir 	SwCrsrShell *pCrsrSh = GetCrsrShell();
1171cdf0e10cSrcweir     // --> OD 2005-12-20 #i27301# - consider new method signature
1172cdf0e10cSrcweir     SwPaM *pCrsr = GetCursor( false );
1173cdf0e10cSrcweir     // <--
1174cdf0e10cSrcweir 	const SwTxtFrm *pTxtFrm = static_cast<const SwTxtFrm*>( GetFrm() );
1175cdf0e10cSrcweir 	const SwTxtNode* pTxtNd = pTxtFrm->GetTxtNode();
1176cdf0e10cSrcweir 
1177cdf0e10cSrcweir     if( pCrsrSh != 0 && pTxtNd != 0 &&
1178cdf0e10cSrcweir 		( pCrsr == 0 ||
1179cdf0e10cSrcweir 	 	  pCrsr->GetPoint()->nNode.GetIndex() != pTxtNd->GetIndex() ||
1180cdf0e10cSrcweir 		  !pTxtFrm->IsInside( pCrsr->GetPoint()->nContent.GetIndex()) ) )
1181cdf0e10cSrcweir     {
1182cdf0e10cSrcweir         // create pam for selection
1183cdf0e10cSrcweir         SwIndex aIndex( const_cast< SwTxtNode * >( pTxtNd ),
1184cdf0e10cSrcweir 						pTxtFrm->GetOfst() );
1185cdf0e10cSrcweir         SwPosition aStartPos( *pTxtNd, aIndex );
1186cdf0e10cSrcweir         SwPaM aPaM( aStartPos );
1187cdf0e10cSrcweir 
1188cdf0e10cSrcweir         // set PaM at cursor shell
1189cdf0e10cSrcweir 		Select( aPaM );
1190cdf0e10cSrcweir 
1191cdf0e10cSrcweir 
1192cdf0e10cSrcweir     }
1193cdf0e10cSrcweir 
1194cdf0e10cSrcweir     /* ->#i13955# */
1195cdf0e10cSrcweir     Window * pWindow = GetWindow();
1196cdf0e10cSrcweir 
1197cdf0e10cSrcweir     if (pWindow != NULL)
1198cdf0e10cSrcweir         pWindow->GrabFocus();
1199cdf0e10cSrcweir     /* <-#i13955# */
1200cdf0e10cSrcweir }
1201cdf0e10cSrcweir 
1202cdf0e10cSrcweir // --> OD 2007-01-17 #i71385#
lcl_GetBackgroundColor(Color & rColor,const SwFrm * pFrm,SwCrsrShell * pCrsrSh)1203cdf0e10cSrcweir bool lcl_GetBackgroundColor( Color & rColor,
1204cdf0e10cSrcweir                              const SwFrm* pFrm,
1205cdf0e10cSrcweir                              SwCrsrShell* pCrsrSh )
1206cdf0e10cSrcweir {
1207cdf0e10cSrcweir     const SvxBrushItem* pBackgrdBrush = 0;
1208cdf0e10cSrcweir     const Color* pSectionTOXColor = 0;
1209cdf0e10cSrcweir     SwRect aDummyRect;
1210cdf0e10cSrcweir     if ( pFrm &&
1211cdf0e10cSrcweir          pFrm->GetBackgroundBrush( pBackgrdBrush, pSectionTOXColor, aDummyRect, false ) )
1212cdf0e10cSrcweir     {
1213cdf0e10cSrcweir         if ( pSectionTOXColor )
1214cdf0e10cSrcweir         {
1215cdf0e10cSrcweir             rColor = *pSectionTOXColor;
1216cdf0e10cSrcweir             return true;
1217cdf0e10cSrcweir         }
1218cdf0e10cSrcweir         else
1219cdf0e10cSrcweir         {
1220cdf0e10cSrcweir             rColor =  pBackgrdBrush->GetColor();
1221cdf0e10cSrcweir             return true;
1222cdf0e10cSrcweir         }
1223cdf0e10cSrcweir     }
1224cdf0e10cSrcweir     else if ( pCrsrSh )
1225cdf0e10cSrcweir     {
1226cdf0e10cSrcweir         rColor = pCrsrSh->Imp()->GetRetoucheColor();
1227cdf0e10cSrcweir         return true;
1228cdf0e10cSrcweir     }
1229cdf0e10cSrcweir 
1230cdf0e10cSrcweir     return false;
1231cdf0e10cSrcweir }
1232cdf0e10cSrcweir 
getForeground()1233cdf0e10cSrcweir sal_Int32 SAL_CALL SwAccessibleParagraph::getForeground()
1234cdf0e10cSrcweir                                 throw (uno::RuntimeException)
1235cdf0e10cSrcweir {
1236cdf0e10cSrcweir     Color aBackgroundCol;
1237cdf0e10cSrcweir 
1238cdf0e10cSrcweir     if ( lcl_GetBackgroundColor( aBackgroundCol, GetFrm(), GetCrsrShell() ) )
1239cdf0e10cSrcweir     {
1240cdf0e10cSrcweir         if ( aBackgroundCol.IsDark() )
1241cdf0e10cSrcweir         {
1242cdf0e10cSrcweir             return COL_WHITE;
1243cdf0e10cSrcweir         }
1244cdf0e10cSrcweir         else
1245cdf0e10cSrcweir         {
1246cdf0e10cSrcweir             return COL_BLACK;
1247cdf0e10cSrcweir         }
1248cdf0e10cSrcweir     }
1249cdf0e10cSrcweir 
1250cdf0e10cSrcweir     return SwAccessibleContext::getForeground();
1251cdf0e10cSrcweir }
1252cdf0e10cSrcweir 
getBackground()1253cdf0e10cSrcweir sal_Int32 SAL_CALL SwAccessibleParagraph::getBackground()
1254cdf0e10cSrcweir                                 throw (uno::RuntimeException)
1255cdf0e10cSrcweir {
1256cdf0e10cSrcweir     Color aBackgroundCol;
1257cdf0e10cSrcweir 
1258cdf0e10cSrcweir     if ( lcl_GetBackgroundColor( aBackgroundCol, GetFrm(), GetCrsrShell() ) )
1259cdf0e10cSrcweir     {
1260cdf0e10cSrcweir         return aBackgroundCol.GetColor();
1261cdf0e10cSrcweir     }
1262cdf0e10cSrcweir 
1263cdf0e10cSrcweir     return SwAccessibleContext::getBackground();
1264cdf0e10cSrcweir }
1265cdf0e10cSrcweir // <--
1266cdf0e10cSrcweir 
getImplementationName()1267cdf0e10cSrcweir ::rtl::OUString SAL_CALL SwAccessibleParagraph::getImplementationName()
1268cdf0e10cSrcweir         throw( uno::RuntimeException )
1269cdf0e10cSrcweir {
1270cdf0e10cSrcweir     return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(sImplementationName));
1271cdf0e10cSrcweir }
1272cdf0e10cSrcweir 
supportsService(const::rtl::OUString & sTestServiceName)1273cdf0e10cSrcweir sal_Bool SAL_CALL SwAccessibleParagraph::supportsService(
1274cdf0e10cSrcweir 		const ::rtl::OUString& sTestServiceName)
1275cdf0e10cSrcweir     throw (uno::RuntimeException)
1276cdf0e10cSrcweir {
1277cdf0e10cSrcweir 	return sTestServiceName.equalsAsciiL( sServiceName,
1278cdf0e10cSrcweir 										  sizeof(sServiceName)-1 ) ||
1279cdf0e10cSrcweir 		   sTestServiceName.equalsAsciiL( sAccessibleServiceName,
1280cdf0e10cSrcweir 				   						  sizeof(sAccessibleServiceName)-1 );
1281cdf0e10cSrcweir }
1282cdf0e10cSrcweir 
getSupportedServiceNames()1283cdf0e10cSrcweir uno::Sequence< ::rtl::OUString > SAL_CALL SwAccessibleParagraph::getSupportedServiceNames()
1284cdf0e10cSrcweir         throw( uno::RuntimeException )
1285cdf0e10cSrcweir {
1286cdf0e10cSrcweir     uno::Sequence< ::rtl::OUString > aRet(2);
1287cdf0e10cSrcweir     ::rtl::OUString* pArray = aRet.getArray();
1288cdf0e10cSrcweir     pArray[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(sServiceName) );
1289cdf0e10cSrcweir     pArray[1] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(sAccessibleServiceName) );
1290cdf0e10cSrcweir 	return aRet;
1291cdf0e10cSrcweir }
1292cdf0e10cSrcweir 
getAttributeNames()1293ca62e2c2SSteve Yin uno::Sequence< ::rtl::OUString > getAttributeNames()
1294ca62e2c2SSteve Yin {
1295ca62e2c2SSteve Yin     static uno::Sequence< ::rtl::OUString >* pNames = NULL;
1296ca62e2c2SSteve Yin 
1297ca62e2c2SSteve Yin     if( pNames == NULL )
1298ca62e2c2SSteve Yin     {
1299ca62e2c2SSteve Yin         // Add the font name to attribute list
1300ca62e2c2SSteve Yin         uno::Sequence< ::rtl::OUString >* pSeq = new uno::Sequence< ::rtl::OUString >( 13 );
1301ca62e2c2SSteve Yin 
1302ca62e2c2SSteve Yin         ::rtl::OUString* pStrings = pSeq->getArray();
1303ca62e2c2SSteve Yin 
1304ca62e2c2SSteve Yin         // sorted list of strings
1305ca62e2c2SSteve Yin         sal_Int32 i = 0;
1306ca62e2c2SSteve Yin 
1307ca62e2c2SSteve Yin #define STR(x) pStrings[i++] = OUString::createFromAscii(x)
1308ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_CHAR_BACK_COLOR ).pName );
1309ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_CHAR_COLOR ).pName );
1310ca62e2c2SSteve Yin        	STR( GetPropName( UNO_NAME_CHAR_CONTOURED ).pName );
1311ca62e2c2SSteve Yin 		STR( GetPropName( UNO_NAME_CHAR_EMPHASIS ).pName );
1312ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_CHAR_ESCAPEMENT ).pName );
1313ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_CHAR_FONT_NAME ).pName );
1314ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_CHAR_HEIGHT ).pName );
1315ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_CHAR_POSTURE ).pName );
1316ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_CHAR_SHADOWED ).pName );
1317ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_CHAR_STRIKEOUT ).pName );
1318ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_CHAR_UNDERLINE ).pName );
1319ca62e2c2SSteve Yin 		STR( GetPropName( UNO_NAME_CHAR_UNDERLINE_COLOR ).pName );
1320ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_CHAR_WEIGHT ).pName );
1321ca62e2c2SSteve Yin #undef STR
1322ca62e2c2SSteve Yin         DBG_ASSERT( i == pSeq->getLength(), "Please adjust length" );
1323ca62e2c2SSteve Yin         if( i != pSeq->getLength() )
1324ca62e2c2SSteve Yin             pSeq->realloc( i );
1325ca62e2c2SSteve Yin         pNames = pSeq;
1326ca62e2c2SSteve Yin     }
1327ca62e2c2SSteve Yin     return *pNames;
1328ca62e2c2SSteve Yin }
1329ca62e2c2SSteve Yin 
getSupplementalAttributeNames()1330ca62e2c2SSteve Yin uno::Sequence< ::rtl::OUString > getSupplementalAttributeNames()
1331ca62e2c2SSteve Yin {
1332ca62e2c2SSteve Yin     static uno::Sequence< ::rtl::OUString >* pNames = NULL;
1333ca62e2c2SSteve Yin 
1334ca62e2c2SSteve Yin     if( pNames == NULL )
1335ca62e2c2SSteve Yin     {
1336ca62e2c2SSteve Yin         uno::Sequence< ::rtl::OUString >* pSeq = new uno::Sequence< ::rtl::OUString >( 9 );
1337ca62e2c2SSteve Yin 
1338ca62e2c2SSteve Yin         ::rtl::OUString* pStrings = pSeq->getArray();
1339ca62e2c2SSteve Yin 
1340ca62e2c2SSteve Yin         // sorted list of strings
1341ca62e2c2SSteve Yin         sal_Int32 i = 0;
1342ca62e2c2SSteve Yin 
1343ca62e2c2SSteve Yin #define STR(x) pStrings[i++] = OUString::createFromAscii(x)
1344ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_NUMBERING_LEVEL ).pName );
1345ca62e2c2SSteve Yin 		STR( GetPropName( UNO_NAME_NUMBERING_RULES ).pName );
1346ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_PARA_ADJUST ).pName );
1347ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_PARA_BOTTOM_MARGIN ).pName );
1348ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_PARA_FIRST_LINE_INDENT ).pName );
1349ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_PARA_LEFT_MARGIN ).pName );
1350ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_PARA_LINE_SPACING ).pName );
1351ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_PARA_RIGHT_MARGIN ).pName );
1352ca62e2c2SSteve Yin         STR( GetPropName( UNO_NAME_TABSTOPS ).pName );
1353ca62e2c2SSteve Yin #undef STR
1354ca62e2c2SSteve Yin         DBG_ASSERT( i == pSeq->getLength(), "Please adjust length" );
1355ca62e2c2SSteve Yin         if( i != pSeq->getLength() )
1356ca62e2c2SSteve Yin             pSeq->realloc( i );
1357ca62e2c2SSteve Yin         pNames = pSeq;
1358ca62e2c2SSteve Yin     }
1359ca62e2c2SSteve Yin     return *pNames;
1360ca62e2c2SSteve Yin }
1361cdf0e10cSrcweir //
1362cdf0e10cSrcweir //=====  XInterface  =======================================================
1363cdf0e10cSrcweir //
1364cdf0e10cSrcweir 
queryInterface(const uno::Type & rType)1365cdf0e10cSrcweir uno::Any SwAccessibleParagraph::queryInterface( const uno::Type& rType )
1366cdf0e10cSrcweir     throw (uno::RuntimeException)
1367cdf0e10cSrcweir {
1368cdf0e10cSrcweir     uno::Any aRet;
1369cdf0e10cSrcweir     if ( rType == ::getCppuType((uno::Reference<XAccessibleText> *)0) )
1370cdf0e10cSrcweir     {
1371cdf0e10cSrcweir         uno::Reference<XAccessibleText> aAccText = (XAccessibleText *) *this; // resolve ambiguity
1372cdf0e10cSrcweir         aRet <<= aAccText;
1373cdf0e10cSrcweir     }
1374cdf0e10cSrcweir     else if ( rType == ::getCppuType((uno::Reference<XAccessibleEditableText> *)0) )
1375cdf0e10cSrcweir     {
1376cdf0e10cSrcweir         uno::Reference<XAccessibleEditableText> aAccEditText = this;
1377cdf0e10cSrcweir         aRet <<= aAccEditText;
1378cdf0e10cSrcweir     }
1379cdf0e10cSrcweir     else if ( rType == ::getCppuType((uno::Reference<XAccessibleSelection> *)0) )
1380cdf0e10cSrcweir     {
1381cdf0e10cSrcweir         uno::Reference<XAccessibleSelection> aAccSel = this;
1382cdf0e10cSrcweir         aRet <<= aAccSel;
1383cdf0e10cSrcweir     }
1384cdf0e10cSrcweir     else if ( rType == ::getCppuType((uno::Reference<XAccessibleHypertext> *)0) )
1385cdf0e10cSrcweir     {
1386cdf0e10cSrcweir         uno::Reference<XAccessibleHypertext> aAccHyp = this;
1387cdf0e10cSrcweir         aRet <<= aAccHyp;
1388cdf0e10cSrcweir     }
1389cdf0e10cSrcweir     // --> OD 2006-07-13 #i63870#
1390cdf0e10cSrcweir     // add interface com::sun:star:accessibility::XAccessibleTextAttributes
1391cdf0e10cSrcweir     else if ( rType == ::getCppuType((uno::Reference<XAccessibleTextAttributes> *)0) )
1392cdf0e10cSrcweir     {
1393cdf0e10cSrcweir         uno::Reference<XAccessibleTextAttributes> aAccTextAttr = this;
1394cdf0e10cSrcweir         aRet <<= aAccTextAttr;
1395cdf0e10cSrcweir     }
1396cdf0e10cSrcweir     // <--
1397cdf0e10cSrcweir     // --> OD 2008-06-10 #i89175#
1398cdf0e10cSrcweir     // add interface com::sun:star:accessibility::XAccessibleTextMarkup
1399cdf0e10cSrcweir     else if ( rType == ::getCppuType((uno::Reference<XAccessibleTextMarkup> *)0) )
1400cdf0e10cSrcweir     {
1401cdf0e10cSrcweir         uno::Reference<XAccessibleTextMarkup> aAccTextMarkup = this;
1402cdf0e10cSrcweir         aRet <<= aAccTextMarkup;
1403cdf0e10cSrcweir     }
1404cdf0e10cSrcweir     // add interface com::sun:star:accessibility::XAccessibleMultiLineText
1405cdf0e10cSrcweir     else if ( rType == ::getCppuType((uno::Reference<XAccessibleMultiLineText> *)0) )
1406cdf0e10cSrcweir     {
1407cdf0e10cSrcweir         uno::Reference<XAccessibleMultiLineText> aAccMultiLineText = this;
1408cdf0e10cSrcweir         aRet <<= aAccMultiLineText;
1409cdf0e10cSrcweir     }
1410cdf0e10cSrcweir     // <--
1411ca62e2c2SSteve Yin 	//MSAA Extension Implementation in app  module
1412ca62e2c2SSteve Yin     else if ( rType == ::getCppuType((uno::Reference<XAccessibleTextSelection> *)NULL) )
1413ca62e2c2SSteve Yin     {
1414ca62e2c2SSteve Yin         uno::Reference< com::sun::star::accessibility::XAccessibleTextSelection > aTextExtension = this;
1415ca62e2c2SSteve Yin         aRet <<= aTextExtension;
1416ca62e2c2SSteve Yin     }
1417ca62e2c2SSteve Yin 	else if ( rType == ::getCppuType((uno::Reference<XAccessibleExtendedAttributes> *)NULL) )
1418ca62e2c2SSteve Yin     {
1419ca62e2c2SSteve Yin 		uno::Reference<XAccessibleExtendedAttributes> xAttr = this;
1420ca62e2c2SSteve Yin         aRet <<= xAttr;
1421ca62e2c2SSteve Yin     }
1422cdf0e10cSrcweir     else
1423cdf0e10cSrcweir     {
1424cdf0e10cSrcweir         aRet = SwAccessibleContext::queryInterface(rType);
1425cdf0e10cSrcweir     }
1426cdf0e10cSrcweir 
1427cdf0e10cSrcweir     return aRet;
1428cdf0e10cSrcweir }
1429cdf0e10cSrcweir 
1430cdf0e10cSrcweir //====== XTypeProvider ====================================================
getTypes()1431cdf0e10cSrcweir uno::Sequence< uno::Type > SAL_CALL SwAccessibleParagraph::getTypes() throw(uno::RuntimeException)
1432cdf0e10cSrcweir {
1433cdf0e10cSrcweir     uno::Sequence< uno::Type > aTypes( SwAccessibleContext::getTypes() );
1434cdf0e10cSrcweir 
1435cdf0e10cSrcweir 	sal_Int32 nIndex = aTypes.getLength();
1436cdf0e10cSrcweir     // --> OD 2006-07-13 #i63870#
1437cdf0e10cSrcweir     // add type accessibility::XAccessibleTextAttributes
1438cdf0e10cSrcweir     // --> OD 2008-06-10 #i89175#
1439cdf0e10cSrcweir     // add type accessibility::XAccessibleTextMarkup and accessibility::XAccessibleMultiLineText
1440cdf0e10cSrcweir     aTypes.realloc( nIndex + 6 );
1441cdf0e10cSrcweir 
1442cdf0e10cSrcweir     uno::Type* pTypes = aTypes.getArray();
1443cdf0e10cSrcweir 	pTypes[nIndex++] = ::getCppuType( static_cast< uno::Reference< XAccessibleEditableText > * >( 0 ) );
1444cdf0e10cSrcweir     pTypes[nIndex++] = ::getCppuType( static_cast< uno::Reference< XAccessibleTextAttributes > * >( 0 ) );
1445cdf0e10cSrcweir 	pTypes[nIndex++] = ::getCppuType( static_cast< uno::Reference< XAccessibleSelection > * >( 0 ) );
1446cdf0e10cSrcweir     pTypes[nIndex++] = ::getCppuType( static_cast< uno::Reference< XAccessibleTextMarkup > * >( 0 ) );
1447cdf0e10cSrcweir     pTypes[nIndex++] = ::getCppuType( static_cast< uno::Reference< XAccessibleMultiLineText > * >( 0 ) );
1448cdf0e10cSrcweir 	pTypes[nIndex] = ::getCppuType( static_cast< uno::Reference< XAccessibleHypertext > * >( 0 ) );
1449cdf0e10cSrcweir     // <--
1450cdf0e10cSrcweir 
1451cdf0e10cSrcweir 	return aTypes;
1452cdf0e10cSrcweir }
1453cdf0e10cSrcweir 
getImplementationId()1454cdf0e10cSrcweir uno::Sequence< sal_Int8 > SAL_CALL SwAccessibleParagraph::getImplementationId()
1455cdf0e10cSrcweir         throw(uno::RuntimeException)
1456cdf0e10cSrcweir {
1457cdf0e10cSrcweir     vos::OGuard aGuard(Application::GetSolarMutex());
1458cdf0e10cSrcweir     static uno::Sequence< sal_Int8 > aId( 16 );
1459cdf0e10cSrcweir     static sal_Bool bInit = sal_False;
1460cdf0e10cSrcweir     if(!bInit)
1461cdf0e10cSrcweir     {
1462cdf0e10cSrcweir         rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
1463cdf0e10cSrcweir         bInit = sal_True;
1464cdf0e10cSrcweir     }
1465cdf0e10cSrcweir     return aId;
1466cdf0e10cSrcweir }
1467cdf0e10cSrcweir 
1468cdf0e10cSrcweir 
1469cdf0e10cSrcweir //
1470cdf0e10cSrcweir //=====  XAccesibleText  ===================================================
1471cdf0e10cSrcweir //
1472cdf0e10cSrcweir 
getCaretPosition()1473cdf0e10cSrcweir sal_Int32 SwAccessibleParagraph::getCaretPosition()
1474cdf0e10cSrcweir     throw (uno::RuntimeException)
1475cdf0e10cSrcweir {
1476cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
1477cdf0e10cSrcweir 
1478cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
1479cdf0e10cSrcweir 
1480cdf0e10cSrcweir     sal_Int32 nRet = GetCaretPos();
1481cdf0e10cSrcweir 	{
1482cdf0e10cSrcweir         vos::OGuard aOldCaretPosGuard( aMutex );
1483cdf0e10cSrcweir 		ASSERT( nRet == nOldCaretPos, "caret pos out of sync" );
1484cdf0e10cSrcweir 		nOldCaretPos = nRet;
1485cdf0e10cSrcweir 	}
1486cdf0e10cSrcweir 	if( -1 != nRet )
1487cdf0e10cSrcweir 	{
1488cdf0e10cSrcweir 		::vos::ORef < SwAccessibleContext > xThis( this );
1489cdf0e10cSrcweir 		GetMap()->SetCursorContext( xThis );
1490cdf0e10cSrcweir 	}
1491cdf0e10cSrcweir 
1492cdf0e10cSrcweir     return nRet;
1493cdf0e10cSrcweir }
1494cdf0e10cSrcweir 
setCaretPosition(sal_Int32 nIndex)1495cdf0e10cSrcweir sal_Bool SAL_CALL SwAccessibleParagraph::setCaretPosition( sal_Int32 nIndex )
1496cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1497cdf0e10cSrcweir {
1498cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
1499cdf0e10cSrcweir 
1500cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
1501cdf0e10cSrcweir 
1502cdf0e10cSrcweir     // parameter checking
1503cdf0e10cSrcweir     sal_Int32 nLength = GetString().getLength();
1504cdf0e10cSrcweir     if ( ! IsValidPosition( nIndex, nLength ) )
1505cdf0e10cSrcweir     {
1506cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
1507cdf0e10cSrcweir     }
1508cdf0e10cSrcweir 
1509cdf0e10cSrcweir     sal_Bool bRet = sal_False;
1510cdf0e10cSrcweir 
1511cdf0e10cSrcweir     // get cursor shell
1512cdf0e10cSrcweir     SwCrsrShell* pCrsrShell = GetCrsrShell();
1513cdf0e10cSrcweir     if( pCrsrShell != NULL )
1514cdf0e10cSrcweir     {
1515cdf0e10cSrcweir         // create pam for selection
1516cdf0e10cSrcweir         SwTxtNode* pNode = const_cast<SwTxtNode*>( GetTxtNode() );
1517cdf0e10cSrcweir         SwIndex aIndex( pNode, GetPortionData().GetModelPosition(nIndex));
1518cdf0e10cSrcweir         SwPosition aStartPos( *pNode, aIndex );
1519cdf0e10cSrcweir         SwPaM aPaM( aStartPos );
1520cdf0e10cSrcweir 
1521cdf0e10cSrcweir         // set PaM at cursor shell
1522cdf0e10cSrcweir         bRet = Select( aPaM );
1523cdf0e10cSrcweir     }
1524cdf0e10cSrcweir 
1525cdf0e10cSrcweir     return bRet;
1526cdf0e10cSrcweir }
1527cdf0e10cSrcweir 
getCharacter(sal_Int32 nIndex)1528cdf0e10cSrcweir sal_Unicode SwAccessibleParagraph::getCharacter( sal_Int32 nIndex )
1529cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1530cdf0e10cSrcweir {
1531cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
1532cdf0e10cSrcweir 
1533cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
1534cdf0e10cSrcweir 
1535cdf0e10cSrcweir     ::rtl::OUString sText( GetString() );
1536cdf0e10cSrcweir 
1537cdf0e10cSrcweir     // return character (if valid)
1538cdf0e10cSrcweir     if( IsValidChar(nIndex, sText.getLength() ) )
1539cdf0e10cSrcweir     {
1540cdf0e10cSrcweir         return sText.getStr()[nIndex];
1541cdf0e10cSrcweir     }
1542cdf0e10cSrcweir     else
1543cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
1544cdf0e10cSrcweir }
1545cdf0e10cSrcweir 
GetCurrentTabStop(sal_Int32 nIndex)1546ca62e2c2SSteve Yin com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > SwAccessibleParagraph::GetCurrentTabStop( sal_Int32 nIndex  )
1547ca62e2c2SSteve Yin {
1548ca62e2c2SSteve Yin vos::OGuard aGuard(Application::GetSolarMutex());
1549ca62e2c2SSteve Yin 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
1550ca62e2c2SSteve Yin 
1551ca62e2c2SSteve Yin 
1552ca62e2c2SSteve Yin 
1553ca62e2c2SSteve Yin     /*  #i12332# The position after the string needs special treatment.
1554ca62e2c2SSteve Yin         IsValidChar -> IsValidPosition
1555ca62e2c2SSteve Yin     */
1556ca62e2c2SSteve Yin     if( ! (IsValidPosition( nIndex, GetString().getLength() ) ) )
1557ca62e2c2SSteve Yin         throw lang::IndexOutOfBoundsException();
1558ca62e2c2SSteve Yin 
1559ca62e2c2SSteve Yin     /*  #i12332#  */
1560ca62e2c2SSteve Yin     sal_Bool bBehindText = sal_False;
1561ca62e2c2SSteve Yin     if ( nIndex == GetString().getLength() )
1562ca62e2c2SSteve Yin         bBehindText = sal_True;
1563ca62e2c2SSteve Yin 
1564ca62e2c2SSteve Yin     // get model position & prepare GetCharRect() arguments
1565ca62e2c2SSteve Yin     SwCrsrMoveState aMoveState;
1566ca62e2c2SSteve Yin     aMoveState.bRealHeight = sal_True;
1567ca62e2c2SSteve Yin     aMoveState.bRealWidth = sal_True;
1568ca62e2c2SSteve Yin     SwSpecialPos aSpecialPos;
1569ca62e2c2SSteve Yin     SwTxtNode* pNode = const_cast<SwTxtNode*>( GetTxtNode() );
1570ca62e2c2SSteve Yin 
1571ca62e2c2SSteve Yin     sal_uInt16 nPos = 0;
1572ca62e2c2SSteve Yin 
1573ca62e2c2SSteve Yin     /*  #i12332# FillSpecialPos does not accept nIndex ==
1574ca62e2c2SSteve Yin          GetString().getLength(). In that case nPos is set to the
1575ca62e2c2SSteve Yin          length of the string in the core. This way GetCharRect
1576ca62e2c2SSteve Yin          returns the rectangle for a cursor at the end of the
1577ca62e2c2SSteve Yin          paragraph. */
1578ca62e2c2SSteve Yin     if (bBehindText)
1579ca62e2c2SSteve Yin     {
1580ca62e2c2SSteve Yin         nPos = pNode->GetTxt().Len();
1581ca62e2c2SSteve Yin     }
1582ca62e2c2SSteve Yin     else
1583ca62e2c2SSteve Yin         nPos = GetPortionData().FillSpecialPos
1584ca62e2c2SSteve Yin             (nIndex, aSpecialPos, aMoveState.pSpecialPos );
1585ca62e2c2SSteve Yin 
1586ca62e2c2SSteve Yin     // call GetCharRect
1587ca62e2c2SSteve Yin     SwRect aCoreRect;
1588ca62e2c2SSteve Yin     SwIndex aIndex( pNode, nPos );
1589ca62e2c2SSteve Yin     SwPosition aPosition( *pNode, aIndex );
1590ca62e2c2SSteve Yin     GetFrm()->GetCharRect( aCoreRect, aPosition, &aMoveState );
1591ca62e2c2SSteve Yin 
1592ca62e2c2SSteve Yin 	// already get the caret postion
1593ca62e2c2SSteve Yin 
1594ca62e2c2SSteve Yin 	/*SwFrm* pTFrm = const_cast<SwFrm*>(GetFrm());
1595ca62e2c2SSteve Yin 	com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > tabs =
1596ca62e2c2SSteve Yin 		pTFrm->GetTabStopInfo(aCoreRect.Left());*/
1597ca62e2c2SSteve Yin 
1598ca62e2c2SSteve Yin 	com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > tabs;
1599ca62e2c2SSteve Yin 	const xub_StrLen nStrLen = GetTxtNode()->GetTxt().Len();
1600ca62e2c2SSteve Yin 	if( nStrLen > 0 )
1601ca62e2c2SSteve Yin 	{
1602ca62e2c2SSteve Yin 		SwFrm* pTFrm = const_cast<SwFrm*>(GetFrm());
1603ca62e2c2SSteve Yin 		tabs = pTFrm->GetTabStopInfo(aCoreRect.Left());
1604ca62e2c2SSteve Yin 	}
1605ca62e2c2SSteve Yin 
1606ca62e2c2SSteve Yin 	if( tabs.hasElements() )
1607ca62e2c2SSteve Yin 	{
1608ca62e2c2SSteve Yin 		// translate core coordinates into accessibility coordinates
1609ca62e2c2SSteve Yin 		Window *pWin = GetWindow();
1610ca62e2c2SSteve Yin 		CHECK_FOR_WINDOW( XAccessibleComponent, pWin );
1611ca62e2c2SSteve Yin 
1612ca62e2c2SSteve Yin 		SwRect aTmpRect(0, 0, tabs[0].Position, 0);
1613ca62e2c2SSteve Yin 
1614ca62e2c2SSteve Yin 		Rectangle aScreenRect( GetMap()->CoreToPixel( aTmpRect.SVRect() ));
1615ca62e2c2SSteve Yin         SwRect aFrmLogBounds( GetBounds( *(GetMap()) ) ); // twip rel to doc root
1616ca62e2c2SSteve Yin 
1617ca62e2c2SSteve Yin 		Point aFrmPixPos( GetMap()->CoreToPixel( aFrmLogBounds.SVRect() ).TopLeft() );
1618ca62e2c2SSteve Yin 		aScreenRect.Move( -aFrmPixPos.X(), -aFrmPixPos.Y() );
1619ca62e2c2SSteve Yin 
1620ca62e2c2SSteve Yin 		tabs[0].Position = aScreenRect.GetWidth();
1621ca62e2c2SSteve Yin 	}
1622ca62e2c2SSteve Yin 
1623ca62e2c2SSteve Yin 	return tabs;
1624ca62e2c2SSteve Yin }
1625ca62e2c2SSteve Yin 
1626ca62e2c2SSteve Yin struct IndexCompare
1627ca62e2c2SSteve Yin {
1628ca62e2c2SSteve Yin 	const PropertyValue* pValues;
IndexCompareIndexCompare1629ca62e2c2SSteve Yin 	IndexCompare( const PropertyValue* pVals ) : pValues(pVals) {}
operator ()IndexCompare1630ca62e2c2SSteve Yin 	bool operator() ( const sal_Int32& a, const sal_Int32& b ) const
1631ca62e2c2SSteve Yin 	{
1632ca62e2c2SSteve Yin 		return (pValues[a].Name < pValues[b].Name) ? true : false;
1633ca62e2c2SSteve Yin 	}
1634ca62e2c2SSteve Yin };
1635ca62e2c2SSteve Yin 
GetFieldTypeNameAtIndex(sal_Int32 nIndex)1636ca62e2c2SSteve Yin String SwAccessibleParagraph::GetFieldTypeNameAtIndex(sal_Int32 nIndex)
1637ca62e2c2SSteve Yin {
1638ca62e2c2SSteve Yin 	String strTypeName;
1639ca62e2c2SSteve Yin 	SwFldMgr aMgr;
1640ca62e2c2SSteve Yin 	SwTxtFld* pTxtFld = NULL;
1641ca62e2c2SSteve Yin 	SwTxtNode* pTxtNd = const_cast<SwTxtNode*>( GetTxtNode() );
1642ca62e2c2SSteve Yin 	SwIndex fldIndex( pTxtNd, nIndex );
1643ca62e2c2SSteve Yin 	sal_Int32 nFldIndex = GetPortionData().GetFieldIndex(nIndex);
1644ca62e2c2SSteve Yin 	if (nFldIndex >= 0)
1645ca62e2c2SSteve Yin 	{
1646ca62e2c2SSteve Yin 		const SwpHints* pSwpHints = GetTxtNode()->GetpSwpHints();
1647ca62e2c2SSteve Yin 		if (pSwpHints)
1648ca62e2c2SSteve Yin 		{
1649ca62e2c2SSteve Yin 			const sal_uInt16  nSize = pSwpHints ? pSwpHints->Count() : 0;
1650ca62e2c2SSteve Yin 			for( sal_uInt16 i = 0; i < nSize; ++i )
1651ca62e2c2SSteve Yin 			{
1652ca62e2c2SSteve Yin 				const SwTxtAttr* pHt = (*pSwpHints)[i];
1653dec99bbdSOliver-Rainer Wittmann 				if ( ( pHt->Which() == RES_TXTATR_FIELD
1654dec99bbdSOliver-Rainer Wittmann                        || pHt->Which() == RES_TXTATR_ANNOTATION
1655dec99bbdSOliver-Rainer Wittmann                        || pHt->Which() == RES_TXTATR_INPUTFIELD )
1656dec99bbdSOliver-Rainer Wittmann                      && (nFldIndex-- == 0))
1657ca62e2c2SSteve Yin 				{
1658ca62e2c2SSteve Yin 					pTxtFld = (SwTxtFld *)pHt;
1659ca62e2c2SSteve Yin 					break;
1660ca62e2c2SSteve Yin 				}
1661dec99bbdSOliver-Rainer Wittmann 				else if ( pHt->Which() == RES_TXTATR_REFMARK
1662dec99bbdSOliver-Rainer Wittmann                           && (nFldIndex-- == 0) )
1663ca62e2c2SSteve Yin 					strTypeName = String(OUString(RTL_CONSTASCII_USTRINGPARAM("set reference")));
1664ca62e2c2SSteve Yin 			}
1665ca62e2c2SSteve Yin 		}
1666ca62e2c2SSteve Yin 	}
1667ca62e2c2SSteve Yin 	if (pTxtFld)
1668ca62e2c2SSteve Yin 	{
16698e8ee8feSSteve Yin 		const SwField* pField = (pTxtFld->GetFmtFld()).GetField();
1670ca62e2c2SSteve Yin 		if (pField)
1671ca62e2c2SSteve Yin 		{
1672ca62e2c2SSteve Yin 			strTypeName = pField->GetTyp()->GetTypeStr(pField->GetTypeId());
1673ca62e2c2SSteve Yin 			sal_uInt16 nWhich = pField->GetTyp()->Which();
1674ca62e2c2SSteve Yin 			rtl::OUString sEntry;
1675ca62e2c2SSteve Yin 			sal_Int32 subType = 0;
1676ca62e2c2SSteve Yin 			switch (nWhich)
1677ca62e2c2SSteve Yin 			{
1678ca62e2c2SSteve Yin 			case RES_DOCSTATFLD:
1679ca62e2c2SSteve Yin 				subType = ((SwDocStatField*)pField)->GetSubType();
1680ca62e2c2SSteve Yin 				break;
1681ca62e2c2SSteve Yin 			case RES_GETREFFLD:
1682ca62e2c2SSteve Yin 				{
1683ca62e2c2SSteve Yin 					sal_uInt16 nSub = pField->GetSubType();
1684ca62e2c2SSteve Yin 					switch( nSub )
1685ca62e2c2SSteve Yin 					{
1686ca62e2c2SSteve Yin 					case REF_BOOKMARK:
1687ca62e2c2SSteve Yin 						{
1688ca62e2c2SSteve Yin 							const SwGetRefField* pRefFld = dynamic_cast<const SwGetRefField*>(pField);
1689ca62e2c2SSteve Yin 							if ( pRefFld && pRefFld->IsRefToHeadingCrossRefBookmark() )
1690ca62e2c2SSteve Yin 								sEntry = OUString(RTL_CONSTASCII_USTRINGPARAM("Headings"));
1691ca62e2c2SSteve Yin 							else if ( pRefFld && pRefFld->IsRefToNumItemCrossRefBookmark() )
1692ca62e2c2SSteve Yin 								sEntry = OUString(RTL_CONSTASCII_USTRINGPARAM("Numbered Paragraphs"));
1693ca62e2c2SSteve Yin 							else
1694ca62e2c2SSteve Yin 								sEntry = OUString(RTL_CONSTASCII_USTRINGPARAM("Bookmarks"));
1695ca62e2c2SSteve Yin 						}
1696ca62e2c2SSteve Yin 						break;
1697ca62e2c2SSteve Yin 					case REF_FOOTNOTE:
1698ca62e2c2SSteve Yin 						sEntry = OUString(RTL_CONSTASCII_USTRINGPARAM("Footnotes"));
1699ca62e2c2SSteve Yin 						break;
1700ca62e2c2SSteve Yin 					case REF_ENDNOTE:
1701ca62e2c2SSteve Yin 						sEntry = OUString(RTL_CONSTASCII_USTRINGPARAM("Endnotes"));
1702ca62e2c2SSteve Yin 						break;
1703ca62e2c2SSteve Yin 					case REF_SETREFATTR:
1704ca62e2c2SSteve Yin 						sEntry = OUString(RTL_CONSTASCII_USTRINGPARAM("Insert Reference"));
1705ca62e2c2SSteve Yin 						break;
1706ca62e2c2SSteve Yin 					case REF_SEQUENCEFLD:
1707ca62e2c2SSteve Yin 						sEntry = ((SwGetRefField*)pField)->GetSetRefName();
1708ca62e2c2SSteve Yin 						break;
1709ca62e2c2SSteve Yin 					}
1710ca62e2c2SSteve Yin 					//Get format string
1711ca62e2c2SSteve Yin 					strTypeName = sEntry;
1712ca62e2c2SSteve Yin                     // <pField->GetFormat() >= 0> is always true as <pField->GetFormat()> is unsigned
1713ca62e2c2SSteve Yin //                    if (pField->GetFormat() >= 0)
1714ca62e2c2SSteve Yin 					{
1715ca62e2c2SSteve Yin 						sEntry = aMgr.GetFormatStr( pField->GetTypeId(), pField->GetFormat() );
1716ca62e2c2SSteve Yin 						if (sEntry.getLength() > 0)
1717ca62e2c2SSteve Yin 						{
1718ca62e2c2SSteve Yin 							strTypeName.AppendAscii("-");
1719ca62e2c2SSteve Yin 							strTypeName += String(sEntry);
1720ca62e2c2SSteve Yin 						}
1721ca62e2c2SSteve Yin 					}
1722ca62e2c2SSteve Yin 				}
1723ca62e2c2SSteve Yin 				break;
1724ca62e2c2SSteve Yin 			case RES_DATETIMEFLD:
1725ca62e2c2SSteve Yin 				subType = ((SwDateTimeField*)pField)->GetSubType();
1726ca62e2c2SSteve Yin 				break;
1727ca62e2c2SSteve Yin 			case RES_JUMPEDITFLD:
1728ca62e2c2SSteve Yin 				{
1729ca62e2c2SSteve Yin 					sal_uInt16 nFormat= pField->GetFormat();
1730ca62e2c2SSteve Yin 					sal_uInt16 nSize = aMgr.GetFormatCount(pField->GetTypeId(), sal_False);
1731ca62e2c2SSteve Yin 					if (nFormat < nSize)
1732ca62e2c2SSteve Yin 					{
1733ca62e2c2SSteve Yin 						sEntry = aMgr.GetFormatStr(pField->GetTypeId(), nFormat);
1734ca62e2c2SSteve Yin 						if (sEntry.getLength() > 0)
1735ca62e2c2SSteve Yin 						{
1736ca62e2c2SSteve Yin 							strTypeName.AppendAscii("-");
1737ca62e2c2SSteve Yin 							strTypeName += String(sEntry);
1738ca62e2c2SSteve Yin 						}
1739ca62e2c2SSteve Yin 					}
1740ca62e2c2SSteve Yin 				}
1741ca62e2c2SSteve Yin 				break;
1742ca62e2c2SSteve Yin 			case RES_EXTUSERFLD:
1743ca62e2c2SSteve Yin 				subType = ((SwExtUserField*)pField)->GetSubType();
1744ca62e2c2SSteve Yin 				break;
1745ca62e2c2SSteve Yin 			case RES_HIDDENTXTFLD:
1746ca62e2c2SSteve Yin 			case RES_SETEXPFLD:
1747ca62e2c2SSteve Yin 				{
1748ca62e2c2SSteve Yin 					sEntry = pField->GetTyp()->GetName();
1749ca62e2c2SSteve Yin 					if (sEntry.getLength() > 0)
1750ca62e2c2SSteve Yin 					{
1751ca62e2c2SSteve Yin 						strTypeName.AppendAscii("-");
1752ca62e2c2SSteve Yin 						strTypeName += String(sEntry);
1753ca62e2c2SSteve Yin 					}
1754ca62e2c2SSteve Yin 				}
1755ca62e2c2SSteve Yin 				break;
1756ca62e2c2SSteve Yin 			case RES_DOCINFOFLD:
1757ca62e2c2SSteve Yin 				subType = pField->GetSubType();
1758ca62e2c2SSteve Yin 				subType &= 0x00ff;
1759ca62e2c2SSteve Yin 				break;
1760ca62e2c2SSteve Yin 			case RES_REFPAGESETFLD:
1761ca62e2c2SSteve Yin 				{
1762ca62e2c2SSteve Yin 					SwRefPageSetField* pRPld = (SwRefPageSetField*)pField;
1763ca62e2c2SSteve Yin 					sal_Bool bOn = pRPld->IsOn();
1764ca62e2c2SSteve Yin 					strTypeName.AppendAscii("-");
1765ca62e2c2SSteve Yin 					if (bOn)
1766ca62e2c2SSteve Yin 						strTypeName += String(OUString(RTL_CONSTASCII_USTRINGPARAM("on")));
1767ca62e2c2SSteve Yin 					else
1768ca62e2c2SSteve Yin 						strTypeName += String(OUString(RTL_CONSTASCII_USTRINGPARAM("off")));
1769ca62e2c2SSteve Yin 				}
1770ca62e2c2SSteve Yin 				break;
1771ca62e2c2SSteve Yin 			case RES_AUTHORFLD:
1772ca62e2c2SSteve Yin 				{
1773ca62e2c2SSteve Yin 					strTypeName.AppendAscii("-");
1774ca62e2c2SSteve Yin 					strTypeName += aMgr.GetFormatStr(pField->GetTypeId(), pField->GetFormat() & 0xff);
1775ca62e2c2SSteve Yin 				}
1776ca62e2c2SSteve Yin 				break;
1777ca62e2c2SSteve Yin 			}
1778ca62e2c2SSteve Yin 			if (subType > 0 || (subType == 0 && (nWhich == RES_DOCINFOFLD || nWhich == RES_EXTUSERFLD || nWhich == RES_DOCSTATFLD)))
1779ca62e2c2SSteve Yin 			{
1780ca62e2c2SSteve Yin 				SvStringsDtor aLst;
1781ca62e2c2SSteve Yin 				aMgr.GetSubTypes(pField->GetTypeId(), aLst);
1782ca62e2c2SSteve Yin 				if (subType < aLst.Count())
1783ca62e2c2SSteve Yin 					sEntry = *aLst[subType];
1784ca62e2c2SSteve Yin 				if (sEntry.getLength() > 0)
1785ca62e2c2SSteve Yin 				{
1786ca62e2c2SSteve Yin 					if (nWhich == RES_DOCINFOFLD)
1787ca62e2c2SSteve Yin 					{
1788ca62e2c2SSteve Yin 						strTypeName = String(sEntry);
1789ca62e2c2SSteve Yin 						sal_uInt32 nSize = aMgr.GetFormatCount(pField->GetTypeId(), sal_False);
1790ca62e2c2SSteve Yin 						sal_uInt16 nExSub = pField->GetSubType() & 0xff00;
1791ca62e2c2SSteve Yin 						if (nSize > 0 && nExSub > 0)
1792ca62e2c2SSteve Yin 						{
1793ca62e2c2SSteve Yin 							//Get extra subtype string
1794ca62e2c2SSteve Yin 							strTypeName.AppendAscii("-");
1795ca62e2c2SSteve Yin 							sEntry = aMgr.GetFormatStr(pField->GetTypeId(), nExSub/0x0100-1);
1796ca62e2c2SSteve Yin 							strTypeName += String(sEntry);
1797ca62e2c2SSteve Yin 						}
1798ca62e2c2SSteve Yin 					}
1799ca62e2c2SSteve Yin 					else
1800ca62e2c2SSteve Yin 					{
1801ca62e2c2SSteve Yin 						strTypeName.AppendAscii("-");
1802ca62e2c2SSteve Yin 						strTypeName += String(sEntry);
1803ca62e2c2SSteve Yin 					}
1804ca62e2c2SSteve Yin 				}
1805ca62e2c2SSteve Yin 			}
1806ca62e2c2SSteve Yin 		}
1807ca62e2c2SSteve Yin 	}
1808ca62e2c2SSteve Yin 	return strTypeName;
1809ca62e2c2SSteve Yin }
1810cdf0e10cSrcweir // --> OD 2006-07-20 #i63870#
1811cdf0e10cSrcweir // re-implement method on behalf of methods <_getDefaultAttributesImpl(..)> and
1812cdf0e10cSrcweir // <_getRunAttributesImpl(..)>
getCharacterAttributes(sal_Int32 nIndex,const uno::Sequence<::rtl::OUString> & aRequestedAttributes)1813cdf0e10cSrcweir uno::Sequence<PropertyValue> SwAccessibleParagraph::getCharacterAttributes(
1814cdf0e10cSrcweir     sal_Int32 nIndex,
1815cdf0e10cSrcweir     const uno::Sequence< ::rtl::OUString >& aRequestedAttributes )
1816cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
1817cdf0e10cSrcweir {
1818cdf0e10cSrcweir 
1819cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
1820cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
1821cdf0e10cSrcweir 
1822cdf0e10cSrcweir     const ::rtl::OUString& rText = GetString();
1823cdf0e10cSrcweir 
182490386390SHerbert Dürr     if( ! IsValidChar( nIndex, rText.getLength()+1 ) )
182590386390SHerbert Dürr         throw lang::IndexOutOfBoundsException();
1826cdf0e10cSrcweir 
1827ca62e2c2SSteve Yin 	bool bSupplementalMode = false;
1828ca62e2c2SSteve Yin     uno::Sequence< ::rtl::OUString > aNames = aRequestedAttributes;
1829ca62e2c2SSteve Yin 	if (aNames.getLength() == 0)
1830ca62e2c2SSteve Yin 	{
1831ca62e2c2SSteve Yin 		bSupplementalMode = true;
1832ca62e2c2SSteve Yin 		aNames = getAttributeNames();
1833ca62e2c2SSteve Yin 	}
1834cdf0e10cSrcweir     // retrieve default character attributes
1835cdf0e10cSrcweir     tAccParaPropValMap aDefAttrSeq;
1836ca62e2c2SSteve Yin     _getDefaultAttributesImpl( aNames, aDefAttrSeq, true );
1837cdf0e10cSrcweir 
1838cdf0e10cSrcweir     // retrieved run character attributes
1839cdf0e10cSrcweir     tAccParaPropValMap aRunAttrSeq;
1840ca62e2c2SSteve Yin     _getRunAttributesImpl( nIndex, aNames, aRunAttrSeq );
1841cdf0e10cSrcweir 
1842cdf0e10cSrcweir     // merge default and run attributes
1843cdf0e10cSrcweir     uno::Sequence< PropertyValue > aValues( aDefAttrSeq.size() );
1844cdf0e10cSrcweir     PropertyValue* pValues = aValues.getArray();
1845cdf0e10cSrcweir     sal_Int32 i = 0;
1846cdf0e10cSrcweir     for ( tAccParaPropValMap::const_iterator aDefIter = aDefAttrSeq.begin();
1847cdf0e10cSrcweir           aDefIter != aDefAttrSeq.end();
1848cdf0e10cSrcweir           ++aDefIter )
1849cdf0e10cSrcweir     {
1850cdf0e10cSrcweir         tAccParaPropValMap::const_iterator aRunIter =
1851cdf0e10cSrcweir                                         aRunAttrSeq.find( aDefIter->first );
1852cdf0e10cSrcweir         if ( aRunIter != aRunAttrSeq.end() )
1853cdf0e10cSrcweir         {
1854cdf0e10cSrcweir             pValues[i] = aRunIter->second;
1855cdf0e10cSrcweir         }
1856cdf0e10cSrcweir         else
1857cdf0e10cSrcweir         {
1858cdf0e10cSrcweir             pValues[i] = aDefIter->second;
1859cdf0e10cSrcweir         }
1860cdf0e10cSrcweir         ++i;
1861cdf0e10cSrcweir     }
1862ca62e2c2SSteve Yin 	if( bSupplementalMode )
1863ca62e2c2SSteve Yin 	{
1864ca62e2c2SSteve Yin         uno::Sequence< ::rtl::OUString > aSupplementalNames = aRequestedAttributes;
1865ca62e2c2SSteve Yin 		if (aSupplementalNames.getLength() == 0)
1866ca62e2c2SSteve Yin 			aSupplementalNames = getSupplementalAttributeNames();
1867ca62e2c2SSteve Yin 
1868ca62e2c2SSteve Yin 		tAccParaPropValMap aSupplementalAttrSeq;
1869ca62e2c2SSteve Yin 		_getSupplementalAttributesImpl( nIndex, aSupplementalNames, aSupplementalAttrSeq );
1870ca62e2c2SSteve Yin 
1871ca62e2c2SSteve Yin 		aValues.realloc( aValues.getLength() + aSupplementalAttrSeq.size() );
1872ca62e2c2SSteve Yin 		pValues = aValues.getArray();
1873ca62e2c2SSteve Yin 
1874ca62e2c2SSteve Yin 		for ( tAccParaPropValMap::const_iterator aSupplementalIter = aSupplementalAttrSeq.begin();
1875ca62e2c2SSteve Yin 			aSupplementalIter != aSupplementalAttrSeq.end();
1876ca62e2c2SSteve Yin 			++aSupplementalIter )
1877ca62e2c2SSteve Yin 		{
1878ca62e2c2SSteve Yin 			pValues[i] = aSupplementalIter->second;
1879ca62e2c2SSteve Yin 			++i;
1880ca62e2c2SSteve Yin 		}
1881ca62e2c2SSteve Yin 
1882ca62e2c2SSteve Yin 		_correctValues( nIndex, aValues );
1883ca62e2c2SSteve Yin 
1884ca62e2c2SSteve Yin 		aValues.realloc( aValues.getLength() + 1 );
1885ca62e2c2SSteve Yin 
1886ca62e2c2SSteve Yin 		pValues = aValues.getArray();
1887ca62e2c2SSteve Yin 
1888ca62e2c2SSteve Yin 		const SwTxtNode* pTxtNode( GetTxtNode() );
1889ca62e2c2SSteve Yin 		PropertyValue& rValue = pValues[aValues.getLength() - 1 ];
1890ca62e2c2SSteve Yin 		rValue.Name = OUString::createFromAscii("NumberingPrefix");
1891ca62e2c2SSteve Yin 		OUString sNumBullet = pTxtNode->GetNumString();
1892ca62e2c2SSteve Yin 		rValue.Value <<= sNumBullet;
1893ca62e2c2SSteve Yin 		rValue.Handle = -1;
1894ca62e2c2SSteve Yin 		rValue.State = PropertyState_DIRECT_VALUE;
1895ca62e2c2SSteve Yin 
1896ca62e2c2SSteve Yin 		String strTypeName = GetFieldTypeNameAtIndex(nIndex);
1897ca62e2c2SSteve Yin 		if (strTypeName.Len() > 0)
1898ca62e2c2SSteve Yin 		{
1899ca62e2c2SSteve Yin 			aValues.realloc( aValues.getLength() + 1 );
1900ca62e2c2SSteve Yin 			pValues = aValues.getArray();
1901362c80bbSSteve Yin 			PropertyValue& rValueFT = pValues[aValues.getLength() - 1];
1902362c80bbSSteve Yin 			rValueFT.Name = OUString::createFromAscii("FieldType");
1903362c80bbSSteve Yin 			rValueFT.Value <<= rtl::OUString(strTypeName.ToLowerAscii());
1904362c80bbSSteve Yin 			rValueFT.Handle = -1;
1905362c80bbSSteve Yin 			rValueFT.State = PropertyState_DIRECT_VALUE;
1906ca62e2c2SSteve Yin 		}
1907ca62e2c2SSteve Yin 
1908ca62e2c2SSteve Yin 		//sort property values
1909ca62e2c2SSteve Yin 		// build sorted index array
1910ca62e2c2SSteve Yin 		sal_Int32 nLength = aValues.getLength();
1911ca62e2c2SSteve Yin 		const PropertyValue* pPairs = aValues.getConstArray();
1912ca62e2c2SSteve Yin 		sal_Int32* pIndices = new sal_Int32[nLength];
1913ca62e2c2SSteve Yin 		for( i = 0; i < nLength; i++ )
1914ca62e2c2SSteve Yin 			pIndices[i] = i;
1915ca62e2c2SSteve Yin 		sort( &pIndices[0], &pIndices[nLength], IndexCompare(pPairs) );
1916ca62e2c2SSteve Yin 		// create sorted sequences accoring to index array
1917ca62e2c2SSteve Yin         uno::Sequence<PropertyValue> aNewValues( nLength );
1918ca62e2c2SSteve Yin 		PropertyValue* pNewValues = aNewValues.getArray();
1919ca62e2c2SSteve Yin 		for( i = 0; i < nLength; i++ )
1920ca62e2c2SSteve Yin 		{
1921ca62e2c2SSteve Yin 			pNewValues[i] = pPairs[pIndices[i]];
1922ca62e2c2SSteve Yin 		}
1923ca62e2c2SSteve Yin 		delete[] pIndices;
1924ca62e2c2SSteve Yin 		return aNewValues;
1925ca62e2c2SSteve Yin 	}
1926cdf0e10cSrcweir 
1927cdf0e10cSrcweir //    // create a (dummy) text portion for the sole purpose of calling
1928cdf0e10cSrcweir //    // getPropertyValues on it
1929cdf0e10cSrcweir //    Reference<XMultiPropertySet> xPortion = CreateUnoPortion( nIndex, nIndex + 1 );
1930cdf0e10cSrcweir 
1931cdf0e10cSrcweir //    // get values
1932cdf0e10cSrcweir //    Sequence<OUString> aNames = getAttributeNames();
1933cdf0e10cSrcweir //    sal_Int32 nLength = aNames.getLength();
1934cdf0e10cSrcweir //    Sequence<Any> aAnys( nLength );
1935cdf0e10cSrcweir //    aAnys = xPortion->getPropertyValues( aNames );
1936cdf0e10cSrcweir 
1937cdf0e10cSrcweir //    // copy names + anys into return sequence
1938cdf0e10cSrcweir //    Sequence<PropertyValue> aValues( aNames.getLength() );
1939cdf0e10cSrcweir //    const OUString* pNames = aNames.getConstArray();
1940cdf0e10cSrcweir //    const Any* pAnys = aAnys.getConstArray();
1941cdf0e10cSrcweir //    PropertyValue* pValues = aValues.getArray();
1942cdf0e10cSrcweir //    for( sal_Int32 i = 0; i < nLength; i++ )
1943cdf0e10cSrcweir //    {
1944cdf0e10cSrcweir //        PropertyValue& rValue = pValues[i];
1945cdf0e10cSrcweir //        rValue.Name = pNames[i];
1946cdf0e10cSrcweir //        rValue.Value = pAnys[i];
1947cdf0e10cSrcweir //        rValue.Handle = -1;                         // handle not supported
1948cdf0e10cSrcweir //        rValue.State = PropertyState_DIRECT_VALUE;  // states not supported
1949cdf0e10cSrcweir //    }
1950cdf0e10cSrcweir 
1951cdf0e10cSrcweir //    // adjust background color if we're in a gray portion
1952cdf0e10cSrcweir //    DBG_ASSERT( pValues[CHAR_BACK_COLOR_POS].Name.
1953cdf0e10cSrcweir //                equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("CharBackColor")),
1954cdf0e10cSrcweir //                "Please adjust CHAR_BACK_COLOR_POS constant." );
1955cdf0e10cSrcweir //    if( GetPortionData().IsInGrayPortion( nIndex ) )
1956cdf0e10cSrcweir //        pValues[CHAR_BACK_COLOR_POS].Value <<= SwViewOption::GetFieldShadingsColor().GetColor();
1957cdf0e10cSrcweir 
1958cdf0e10cSrcweir     return aValues;
1959cdf0e10cSrcweir }
1960cdf0e10cSrcweir 
1961cdf0e10cSrcweir // --> OD 2006-07-11 #i63870#
_getDefaultAttributesImpl(const uno::Sequence<::rtl::OUString> & aRequestedAttributes,tAccParaPropValMap & rDefAttrSeq,const bool bOnlyCharAttrs)1962cdf0e10cSrcweir void SwAccessibleParagraph::_getDefaultAttributesImpl(
1963cdf0e10cSrcweir         const uno::Sequence< ::rtl::OUString >& aRequestedAttributes,
1964cdf0e10cSrcweir         tAccParaPropValMap& rDefAttrSeq,
1965cdf0e10cSrcweir         const bool bOnlyCharAttrs )
1966cdf0e10cSrcweir {
1967cdf0e10cSrcweir     // retrieve default attributes
1968cdf0e10cSrcweir     const SwTxtNode* pTxtNode( GetTxtNode() );
1969cdf0e10cSrcweir     ::boost::scoped_ptr<SfxItemSet> pSet;
1970cdf0e10cSrcweir     if ( !bOnlyCharAttrs )
1971cdf0e10cSrcweir     {
1972cdf0e10cSrcweir         pSet.reset( new SfxItemSet( const_cast<SwAttrPool&>(pTxtNode->GetDoc()->GetAttrPool()),
1973cdf0e10cSrcweir                                RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
1974cdf0e10cSrcweir                                RES_PARATR_BEGIN, RES_PARATR_END - 1,
1975cdf0e10cSrcweir                                RES_FRMATR_BEGIN, RES_FRMATR_END - 1,
1976cdf0e10cSrcweir                                0 ) );
1977cdf0e10cSrcweir     }
1978cdf0e10cSrcweir     else
1979cdf0e10cSrcweir     {
1980cdf0e10cSrcweir         pSet.reset( new SfxItemSet( const_cast<SwAttrPool&>(pTxtNode->GetDoc()->GetAttrPool()),
1981cdf0e10cSrcweir                                RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
1982cdf0e10cSrcweir                                0 ) );
1983cdf0e10cSrcweir     }
1984cdf0e10cSrcweir     // --> OD 2007-11-12 #i82637#
1985cdf0e10cSrcweir     // From the perspective of the a11y API the default character attributes
1986cdf0e10cSrcweir     // are the character attributes, which are set at the paragraph style
1987cdf0e10cSrcweir     // of the paragraph. The character attributes set at the automatic paragraph
1988cdf0e10cSrcweir     // style of the paragraph are treated as run attributes.
1989cdf0e10cSrcweir //    pTxtNode->SwCntntNode::GetAttr( *pSet );
1990cdf0e10cSrcweir     // get default paragraph attributes, if needed, and merge these into <pSet>
1991cdf0e10cSrcweir     if ( !bOnlyCharAttrs )
1992cdf0e10cSrcweir     {
1993cdf0e10cSrcweir         SfxItemSet aParaSet( const_cast<SwAttrPool&>(pTxtNode->GetDoc()->GetAttrPool()),
1994cdf0e10cSrcweir                              RES_PARATR_BEGIN, RES_PARATR_END - 1,
1995cdf0e10cSrcweir                              RES_FRMATR_BEGIN, RES_FRMATR_END - 1,
1996cdf0e10cSrcweir                              0 );
1997cdf0e10cSrcweir         pTxtNode->SwCntntNode::GetAttr( aParaSet );
1998cdf0e10cSrcweir         pSet->Put( aParaSet );
1999cdf0e10cSrcweir     }
2000cdf0e10cSrcweir     // get default character attributes and merge these into <pSet>
2001cdf0e10cSrcweir     ASSERT( pTxtNode->GetTxtColl(),
2002cdf0e10cSrcweir             "<SwAccessibleParagraph::_getDefaultAttributesImpl(..)> - missing paragraph style. Serious defect, please inform OD!" );
2003cdf0e10cSrcweir     if ( pTxtNode->GetTxtColl() )
2004cdf0e10cSrcweir     {
2005cdf0e10cSrcweir         SfxItemSet aCharSet( const_cast<SwAttrPool&>(pTxtNode->GetDoc()->GetAttrPool()),
2006cdf0e10cSrcweir                              RES_CHRATR_BEGIN, RES_CHRATR_END - 1,
2007cdf0e10cSrcweir                              0 );
2008cdf0e10cSrcweir         aCharSet.Put( pTxtNode->GetTxtColl()->GetAttrSet() );
2009cdf0e10cSrcweir         pSet->Put( aCharSet );
2010cdf0e10cSrcweir     }
2011cdf0e10cSrcweir     // <--
2012cdf0e10cSrcweir 
2013cdf0e10cSrcweir     // build-up sequence containing the run attributes <rDefAttrSeq>
2014cdf0e10cSrcweir     tAccParaPropValMap aDefAttrSeq;
2015cdf0e10cSrcweir     {
2016cdf0e10cSrcweir         const SfxItemPropertyMap* pPropMap =
2017cdf0e10cSrcweir                     aSwMapProvider.GetPropertySet( PROPERTY_MAP_TEXT_CURSOR )->getPropertyMap();
2018cdf0e10cSrcweir         PropertyEntryVector_t aPropertyEntries = pPropMap->getPropertyEntries();
2019cdf0e10cSrcweir         PropertyEntryVector_t::const_iterator aPropIt = aPropertyEntries.begin();
2020cdf0e10cSrcweir         while ( aPropIt != aPropertyEntries.end() )
2021cdf0e10cSrcweir         {
2022cdf0e10cSrcweir             const SfxPoolItem* pItem = pSet->GetItem( aPropIt->nWID );
2023cdf0e10cSrcweir             if ( pItem )
2024cdf0e10cSrcweir             {
2025cdf0e10cSrcweir                 uno::Any aVal;
2026cdf0e10cSrcweir                 pItem->QueryValue( aVal, aPropIt->nMemberId );
2027cdf0e10cSrcweir 
2028cdf0e10cSrcweir                 PropertyValue rPropVal;
2029cdf0e10cSrcweir                 rPropVal.Name = aPropIt->sName;
2030cdf0e10cSrcweir                 rPropVal.Value = aVal;
2031cdf0e10cSrcweir                 rPropVal.Handle = -1;
2032cdf0e10cSrcweir                 rPropVal.State = beans::PropertyState_DEFAULT_VALUE;
2033cdf0e10cSrcweir 
2034cdf0e10cSrcweir                 aDefAttrSeq[rPropVal.Name] = rPropVal;
2035cdf0e10cSrcweir             }
2036cdf0e10cSrcweir             ++aPropIt;
2037cdf0e10cSrcweir         }
2038cdf0e10cSrcweir 
2039cdf0e10cSrcweir         // --> OD 2007-01-15 #i72800#
2040cdf0e10cSrcweir         // add property value entry for the paragraph style
2041cdf0e10cSrcweir         if ( !bOnlyCharAttrs && pTxtNode->GetTxtColl() )
2042cdf0e10cSrcweir         {
2043cdf0e10cSrcweir             const ::rtl::OUString sParaStyleName =
2044cdf0e10cSrcweir                     ::rtl::OUString::createFromAscii(
2045cdf0e10cSrcweir                             GetPropName( UNO_NAME_PARA_STYLE_NAME ).pName );
2046cdf0e10cSrcweir             if ( aDefAttrSeq.find( sParaStyleName ) == aDefAttrSeq.end() )
2047cdf0e10cSrcweir             {
2048cdf0e10cSrcweir                 PropertyValue rPropVal;
2049cdf0e10cSrcweir                 rPropVal.Name = sParaStyleName;
2050cdf0e10cSrcweir                 uno::Any aVal( uno::makeAny( ::rtl::OUString( pTxtNode->GetTxtColl()->GetName() ) ) );
2051cdf0e10cSrcweir                 rPropVal.Value = aVal;
2052cdf0e10cSrcweir                 rPropVal.Handle = -1;
2053cdf0e10cSrcweir                 rPropVal.State = beans::PropertyState_DEFAULT_VALUE;
2054cdf0e10cSrcweir 
2055cdf0e10cSrcweir                 aDefAttrSeq[rPropVal.Name] = rPropVal;
2056cdf0e10cSrcweir             }
2057cdf0e10cSrcweir         }
2058cdf0e10cSrcweir         // <--
2059cdf0e10cSrcweir 
2060cdf0e10cSrcweir         // --> OD 2007-01-15 #i73371#
2061cdf0e10cSrcweir         // resolve value text::WritingMode2::PAGE of property value entry WritingMode
2062cdf0e10cSrcweir         if ( !bOnlyCharAttrs && GetFrm() )
2063cdf0e10cSrcweir         {
2064cdf0e10cSrcweir             const ::rtl::OUString sWritingMode =
2065cdf0e10cSrcweir                     ::rtl::OUString::createFromAscii(
2066cdf0e10cSrcweir                             GetPropName( UNO_NAME_WRITING_MODE ).pName );
2067cdf0e10cSrcweir             tAccParaPropValMap::iterator aIter = aDefAttrSeq.find( sWritingMode );
2068cdf0e10cSrcweir             if ( aIter != aDefAttrSeq.end() )
2069cdf0e10cSrcweir             {
2070cdf0e10cSrcweir                 PropertyValue rPropVal( aIter->second );
2071cdf0e10cSrcweir                 sal_Int16 nVal = rPropVal.Value.get<sal_Int16>();
2072cdf0e10cSrcweir                 if ( nVal == text::WritingMode2::PAGE )
2073cdf0e10cSrcweir                 {
2074cdf0e10cSrcweir                     const SwFrm* pUpperFrm( GetFrm()->GetUpper() );
2075cdf0e10cSrcweir                     while ( pUpperFrm )
2076cdf0e10cSrcweir                     {
2077cdf0e10cSrcweir                         if ( pUpperFrm->GetType() &
2078cdf0e10cSrcweir                                ( FRM_PAGE | FRM_FLY | FRM_SECTION | FRM_TAB | FRM_CELL ) )
2079cdf0e10cSrcweir                         {
2080cdf0e10cSrcweir                             if ( pUpperFrm->IsVertical() )
2081cdf0e10cSrcweir                             {
2082cdf0e10cSrcweir                                 nVal = text::WritingMode2::TB_RL;
2083cdf0e10cSrcweir                             }
2084cdf0e10cSrcweir                             else if ( pUpperFrm->IsRightToLeft() )
2085cdf0e10cSrcweir                             {
2086cdf0e10cSrcweir                                 nVal = text::WritingMode2::RL_TB;
2087cdf0e10cSrcweir                             }
2088cdf0e10cSrcweir                             else
2089cdf0e10cSrcweir                             {
2090cdf0e10cSrcweir                                 nVal = text::WritingMode2::LR_TB;
2091cdf0e10cSrcweir                             }
2092cdf0e10cSrcweir                             rPropVal.Value <<= nVal;
2093cdf0e10cSrcweir                             aDefAttrSeq[rPropVal.Name] = rPropVal;
2094cdf0e10cSrcweir                             break;
2095cdf0e10cSrcweir                         }
2096cdf0e10cSrcweir 
2097cdf0e10cSrcweir                         if ( dynamic_cast<const SwFlyFrm*>(pUpperFrm) )
2098cdf0e10cSrcweir                         {
2099cdf0e10cSrcweir                             pUpperFrm = dynamic_cast<const SwFlyFrm*>(pUpperFrm)->GetAnchorFrm();
2100cdf0e10cSrcweir                         }
2101cdf0e10cSrcweir                         else
2102cdf0e10cSrcweir                         {
2103cdf0e10cSrcweir                             pUpperFrm = pUpperFrm->GetUpper();
2104cdf0e10cSrcweir                         }
2105cdf0e10cSrcweir                     }
2106cdf0e10cSrcweir                 }
2107cdf0e10cSrcweir             }
2108cdf0e10cSrcweir         }
2109cdf0e10cSrcweir         // <--
2110cdf0e10cSrcweir     }
2111cdf0e10cSrcweir 
2112cdf0e10cSrcweir     if ( aRequestedAttributes.getLength() == 0 )
2113cdf0e10cSrcweir     {
2114cdf0e10cSrcweir         rDefAttrSeq = aDefAttrSeq;
2115cdf0e10cSrcweir     }
2116cdf0e10cSrcweir     else
2117cdf0e10cSrcweir     {
2118cdf0e10cSrcweir         const ::rtl::OUString* pReqAttrs = aRequestedAttributes.getConstArray();
2119cdf0e10cSrcweir         const sal_Int32 nLength = aRequestedAttributes.getLength();
2120cdf0e10cSrcweir         for( sal_Int32 i = 0; i < nLength; ++i )
2121cdf0e10cSrcweir         {
2122cdf0e10cSrcweir             tAccParaPropValMap::const_iterator const aIter = aDefAttrSeq.find( pReqAttrs[i] );
2123cdf0e10cSrcweir             if ( aIter != aDefAttrSeq.end() )
2124cdf0e10cSrcweir             {
2125cdf0e10cSrcweir                 rDefAttrSeq[ aIter->first ] = aIter->second;
2126cdf0e10cSrcweir             }
2127cdf0e10cSrcweir         }
2128cdf0e10cSrcweir     }
2129cdf0e10cSrcweir }
2130cdf0e10cSrcweir 
getDefaultAttributes(const uno::Sequence<::rtl::OUString> & aRequestedAttributes)2131cdf0e10cSrcweir uno::Sequence< PropertyValue > SwAccessibleParagraph::getDefaultAttributes(
2132cdf0e10cSrcweir         const uno::Sequence< ::rtl::OUString >& aRequestedAttributes )
2133cdf0e10cSrcweir         throw ( uno::RuntimeException )
2134cdf0e10cSrcweir {
2135cdf0e10cSrcweir     vos::OGuard aGuard(Application::GetSolarMutex());
2136cdf0e10cSrcweir     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
2137cdf0e10cSrcweir 
2138cdf0e10cSrcweir     tAccParaPropValMap aDefAttrSeq;
2139cdf0e10cSrcweir     _getDefaultAttributesImpl( aRequestedAttributes, aDefAttrSeq );
2140cdf0e10cSrcweir 
2141cdf0e10cSrcweir     // --> OD 2010-03-08 #i92233#
2142cdf0e10cSrcweir     static rtl::OUString sMMToPixelRatio( rtl::OUString::createFromAscii( "MMToPixelRatio" ) );
2143cdf0e10cSrcweir     bool bProvideMMToPixelRatio( false );
2144cdf0e10cSrcweir     {
2145cdf0e10cSrcweir         if ( aRequestedAttributes.getLength() == 0 )
2146cdf0e10cSrcweir         {
2147cdf0e10cSrcweir             bProvideMMToPixelRatio = true;
2148cdf0e10cSrcweir         }
2149cdf0e10cSrcweir         else
2150cdf0e10cSrcweir         {
2151cdf0e10cSrcweir             const rtl::OUString* aRequestedAttrIter =
2152cdf0e10cSrcweir                   ::std::find( ::comphelper::stl_begin( aRequestedAttributes ),
2153cdf0e10cSrcweir                                ::comphelper::stl_end( aRequestedAttributes ),
2154cdf0e10cSrcweir                                sMMToPixelRatio );
2155cdf0e10cSrcweir             if ( aRequestedAttrIter != ::comphelper::stl_end( aRequestedAttributes ) )
2156cdf0e10cSrcweir             {
2157cdf0e10cSrcweir                 bProvideMMToPixelRatio = true;
2158cdf0e10cSrcweir             }
2159cdf0e10cSrcweir         }
2160cdf0e10cSrcweir     }
2161cdf0e10cSrcweir     // <--
2162cdf0e10cSrcweir 
2163cdf0e10cSrcweir     uno::Sequence< PropertyValue > aValues( aDefAttrSeq.size() +
2164cdf0e10cSrcweir                                             ( bProvideMMToPixelRatio ? 1 : 0 ) );
2165cdf0e10cSrcweir     PropertyValue* pValues = aValues.getArray();
2166cdf0e10cSrcweir     sal_Int32 i = 0;
2167cdf0e10cSrcweir     for ( tAccParaPropValMap::const_iterator aIter  = aDefAttrSeq.begin();
2168cdf0e10cSrcweir           aIter != aDefAttrSeq.end();
2169cdf0e10cSrcweir           ++aIter )
2170cdf0e10cSrcweir     {
2171cdf0e10cSrcweir         pValues[i] = aIter->second;
2172cdf0e10cSrcweir         ++i;
2173cdf0e10cSrcweir     }
2174cdf0e10cSrcweir 
2175cdf0e10cSrcweir     // --> OD 2010-03-08 #i92233#
2176cdf0e10cSrcweir     if ( bProvideMMToPixelRatio )
2177cdf0e10cSrcweir     {
2178cdf0e10cSrcweir         PropertyValue rPropVal;
2179cdf0e10cSrcweir         rPropVal.Name = sMMToPixelRatio;
2180cdf0e10cSrcweir         const Size a100thMMSize( 1000, 1000 );
2181cdf0e10cSrcweir         const Size aPixelSize = GetMap()->LogicToPixel( a100thMMSize );
2182cdf0e10cSrcweir         const float fRatio = ((float)a100thMMSize.Width()/100)/aPixelSize.Width();
2183cdf0e10cSrcweir         rPropVal.Value = uno::makeAny( fRatio );
2184cdf0e10cSrcweir         rPropVal.Handle = -1;
2185cdf0e10cSrcweir         rPropVal.State = beans::PropertyState_DEFAULT_VALUE;
2186cdf0e10cSrcweir         pValues[ aValues.getLength() - 1 ] = rPropVal;
2187cdf0e10cSrcweir     }
2188cdf0e10cSrcweir     // <--
2189cdf0e10cSrcweir 
2190cdf0e10cSrcweir     return aValues;
2191cdf0e10cSrcweir }
2192cdf0e10cSrcweir 
_getRunAttributesImpl(const sal_Int32 nIndex,const uno::Sequence<::rtl::OUString> & aRequestedAttributes,tAccParaPropValMap & rRunAttrSeq)2193cdf0e10cSrcweir void SwAccessibleParagraph::_getRunAttributesImpl(
2194cdf0e10cSrcweir         const sal_Int32 nIndex,
2195cdf0e10cSrcweir         const uno::Sequence< ::rtl::OUString >& aRequestedAttributes,
2196cdf0e10cSrcweir         tAccParaPropValMap& rRunAttrSeq )
2197cdf0e10cSrcweir {
2198cdf0e10cSrcweir     // create PaM for character at position <nIndex>
2199cdf0e10cSrcweir     SwPaM* pPaM( 0 );
2200cdf0e10cSrcweir     {
2201cdf0e10cSrcweir         const SwTxtNode* pTxtNode( GetTxtNode() );
2202cdf0e10cSrcweir         SwPosition* pStartPos = new SwPosition( *pTxtNode );
2203cdf0e10cSrcweir         pStartPos->nContent.Assign( const_cast<SwTxtNode*>(pTxtNode), static_cast<sal_uInt16>(nIndex) );
2204cdf0e10cSrcweir         SwPosition* pEndPos = new SwPosition( *pTxtNode );
2205cdf0e10cSrcweir         pEndPos->nContent.Assign( const_cast<SwTxtNode*>(pTxtNode), static_cast<sal_uInt16>(nIndex+1) );
2206cdf0e10cSrcweir 
2207cdf0e10cSrcweir         pPaM = new SwPaM( *pStartPos, *pEndPos );
2208cdf0e10cSrcweir 
2209cdf0e10cSrcweir         delete pStartPos;
2210cdf0e10cSrcweir         delete pEndPos;
2211cdf0e10cSrcweir     }
2212cdf0e10cSrcweir 
2213cdf0e10cSrcweir     // retrieve character attributes for the created PaM <pPaM>
2214cdf0e10cSrcweir     SfxItemSet aSet( pPaM->GetDoc()->GetAttrPool(),
2215cdf0e10cSrcweir                      RES_CHRATR_BEGIN, RES_CHRATR_END -1,
2216cdf0e10cSrcweir                      0 );
2217cdf0e10cSrcweir     // --> OD 2007-11-12 #i82637#
2218cdf0e10cSrcweir     // From the perspective of the a11y API the character attributes, which
2219cdf0e10cSrcweir     // are set at the automatic paragraph style of the paragraph are treated
2220cdf0e10cSrcweir     // as run attributes.
2221cdf0e10cSrcweir //    SwXTextCursor::GetCrsrAttr( *pPaM, aSet, sal_True, sal_True );
2222cdf0e10cSrcweir     // get character attributes from automatic paragraph style and merge these into <aSet>
2223cdf0e10cSrcweir     {
2224cdf0e10cSrcweir         const SwTxtNode* pTxtNode( GetTxtNode() );
2225cdf0e10cSrcweir         if ( pTxtNode->HasSwAttrSet() )
2226cdf0e10cSrcweir         {
2227cdf0e10cSrcweir             SfxItemSet aAutomaticParaStyleCharAttrs( pPaM->GetDoc()->GetAttrPool(),
2228cdf0e10cSrcweir                                                      RES_CHRATR_BEGIN, RES_CHRATR_END -1,
2229cdf0e10cSrcweir                                                      0 );
2230cdf0e10cSrcweir             aAutomaticParaStyleCharAttrs.Put( *(pTxtNode->GetpSwAttrSet()), sal_False );
2231cdf0e10cSrcweir             aSet.Put( aAutomaticParaStyleCharAttrs );
2232cdf0e10cSrcweir         }
2233cdf0e10cSrcweir     }
2234cdf0e10cSrcweir     // get character attributes at <pPaM> and merge these into <aSet>
2235cdf0e10cSrcweir     {
2236cdf0e10cSrcweir         SfxItemSet aCharAttrsAtPaM( pPaM->GetDoc()->GetAttrPool(),
2237cdf0e10cSrcweir                                     RES_CHRATR_BEGIN, RES_CHRATR_END -1,
2238cdf0e10cSrcweir                                     0 );
2239cdf0e10cSrcweir         SwUnoCursorHelper::GetCrsrAttr(*pPaM, aCharAttrsAtPaM, sal_True, sal_True);
2240cdf0e10cSrcweir         aSet.Put( aCharAttrsAtPaM );
2241cdf0e10cSrcweir     }
2242cdf0e10cSrcweir     // <--
2243cdf0e10cSrcweir 
2244cdf0e10cSrcweir     // build-up sequence containing the run attributes <rRunAttrSeq>
2245cdf0e10cSrcweir     {
2246cdf0e10cSrcweir         tAccParaPropValMap aRunAttrSeq;
2247cdf0e10cSrcweir         {
2248cdf0e10cSrcweir             // --> OD 2007-11-12 #i82637#
2249cdf0e10cSrcweir             tAccParaPropValMap aDefAttrSeq;
2250cdf0e10cSrcweir             uno::Sequence< ::rtl::OUString > aDummy;
2251cdf0e10cSrcweir             _getDefaultAttributesImpl( aDummy, aDefAttrSeq, true );
2252cdf0e10cSrcweir             // <--
2253cdf0e10cSrcweir 
2254cdf0e10cSrcweir             const SfxItemPropertyMap* pPropMap =
2255cdf0e10cSrcweir                     aSwMapProvider.GetPropertySet( PROPERTY_MAP_TEXT_CURSOR )->getPropertyMap();
2256cdf0e10cSrcweir             PropertyEntryVector_t aPropertyEntries = pPropMap->getPropertyEntries();
2257cdf0e10cSrcweir             PropertyEntryVector_t::const_iterator aPropIt = aPropertyEntries.begin();
2258cdf0e10cSrcweir             while ( aPropIt != aPropertyEntries.end() )
2259cdf0e10cSrcweir             {
2260cdf0e10cSrcweir                 const SfxPoolItem* pItem( 0 );
2261cdf0e10cSrcweir                 // --> OD 2007-11-12 #i82637#
2262cdf0e10cSrcweir                 // Found character attributes, whose value equals the value of
2263cdf0e10cSrcweir                 // the corresponding default character attributes, are excluded.
2264cdf0e10cSrcweir                 if ( aSet.GetItemState( aPropIt->nWID, sal_True, &pItem ) == SFX_ITEM_SET )
2265cdf0e10cSrcweir                 {
2266cdf0e10cSrcweir                     uno::Any aVal;
2267cdf0e10cSrcweir                     pItem->QueryValue( aVal, aPropIt->nMemberId );
2268cdf0e10cSrcweir 
2269cdf0e10cSrcweir                     PropertyValue rPropVal;
2270cdf0e10cSrcweir                     rPropVal.Name = aPropIt->sName;
2271cdf0e10cSrcweir                     rPropVal.Value = aVal;
2272cdf0e10cSrcweir                     rPropVal.Handle = -1;
2273cdf0e10cSrcweir                     rPropVal.State = PropertyState_DIRECT_VALUE;
2274cdf0e10cSrcweir 
2275cdf0e10cSrcweir                     tAccParaPropValMap::const_iterator aDefIter =
2276cdf0e10cSrcweir                                             aDefAttrSeq.find( rPropVal.Name );
2277cdf0e10cSrcweir                     if ( aDefIter == aDefAttrSeq.end() ||
2278cdf0e10cSrcweir                          rPropVal.Value != aDefIter->second.Value )
2279cdf0e10cSrcweir                     {
2280cdf0e10cSrcweir                         aRunAttrSeq[rPropVal.Name] = rPropVal;
2281cdf0e10cSrcweir                     }
2282cdf0e10cSrcweir                 }
2283cdf0e10cSrcweir 
2284cdf0e10cSrcweir                 ++aPropIt;
2285cdf0e10cSrcweir             }
2286cdf0e10cSrcweir         }
2287cdf0e10cSrcweir 
2288cdf0e10cSrcweir         if ( aRequestedAttributes.getLength() == 0 )
2289cdf0e10cSrcweir         {
2290cdf0e10cSrcweir             rRunAttrSeq = aRunAttrSeq;
2291cdf0e10cSrcweir         }
2292cdf0e10cSrcweir         else
2293cdf0e10cSrcweir         {
2294cdf0e10cSrcweir             const ::rtl::OUString* pReqAttrs = aRequestedAttributes.getConstArray();
2295cdf0e10cSrcweir             const sal_Int32 nLength = aRequestedAttributes.getLength();
2296cdf0e10cSrcweir             for( sal_Int32 i = 0; i < nLength; ++i )
2297cdf0e10cSrcweir             {
2298cdf0e10cSrcweir                 tAccParaPropValMap::iterator aIter = aRunAttrSeq.find( pReqAttrs[i] );
2299cdf0e10cSrcweir                 if ( aIter != aRunAttrSeq.end() )
2300cdf0e10cSrcweir                 {
2301cdf0e10cSrcweir                     rRunAttrSeq[ (*aIter).first ] = (*aIter).second;
2302cdf0e10cSrcweir                 }
2303cdf0e10cSrcweir             }
2304cdf0e10cSrcweir         }
2305cdf0e10cSrcweir     }
2306cdf0e10cSrcweir 
2307cdf0e10cSrcweir     delete pPaM;
2308cdf0e10cSrcweir }
2309cdf0e10cSrcweir 
getRunAttributes(sal_Int32 nIndex,const uno::Sequence<::rtl::OUString> & aRequestedAttributes)2310cdf0e10cSrcweir uno::Sequence< PropertyValue > SwAccessibleParagraph::getRunAttributes(
2311cdf0e10cSrcweir         sal_Int32 nIndex,
2312cdf0e10cSrcweir         const uno::Sequence< ::rtl::OUString >& aRequestedAttributes )
2313cdf0e10cSrcweir         throw ( lang::IndexOutOfBoundsException,
2314cdf0e10cSrcweir                 uno::RuntimeException )
2315cdf0e10cSrcweir {
2316cdf0e10cSrcweir     vos::OGuard aGuard(Application::GetSolarMutex());
2317cdf0e10cSrcweir     CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
2318cdf0e10cSrcweir 
2319cdf0e10cSrcweir     {
2320cdf0e10cSrcweir         const ::rtl::OUString& rText = GetString();
2321cdf0e10cSrcweir         if ( !IsValidChar( nIndex, rText.getLength() ) )
2322cdf0e10cSrcweir         {
2323cdf0e10cSrcweir             throw lang::IndexOutOfBoundsException();
2324cdf0e10cSrcweir         }
2325cdf0e10cSrcweir     }
2326cdf0e10cSrcweir 
2327cdf0e10cSrcweir     tAccParaPropValMap aRunAttrSeq;
2328cdf0e10cSrcweir     _getRunAttributesImpl( nIndex, aRequestedAttributes, aRunAttrSeq );
2329cdf0e10cSrcweir 
2330cdf0e10cSrcweir     uno::Sequence< PropertyValue > aValues( aRunAttrSeq.size() );
2331cdf0e10cSrcweir     PropertyValue* pValues = aValues.getArray();
2332cdf0e10cSrcweir     sal_Int32 i = 0;
2333cdf0e10cSrcweir     for ( tAccParaPropValMap::const_iterator aIter  = aRunAttrSeq.begin();
2334cdf0e10cSrcweir           aIter != aRunAttrSeq.end();
2335cdf0e10cSrcweir           ++aIter )
2336cdf0e10cSrcweir     {
2337cdf0e10cSrcweir         pValues[i] = aIter->second;
2338cdf0e10cSrcweir         ++i;
2339cdf0e10cSrcweir     }
2340cdf0e10cSrcweir 
2341cdf0e10cSrcweir     return aValues;
2342cdf0e10cSrcweir }
2343cdf0e10cSrcweir // <--
_getSupplementalAttributesImpl(const sal_Int32,const uno::Sequence<::rtl::OUString> & aRequestedAttributes,tAccParaPropValMap & rSupplementalAttrSeq)2344ca62e2c2SSteve Yin void SwAccessibleParagraph::_getSupplementalAttributesImpl(
2345ca62e2c2SSteve Yin         const sal_Int32,
2346ca62e2c2SSteve Yin         const uno::Sequence< ::rtl::OUString >& aRequestedAttributes,
2347ca62e2c2SSteve Yin         tAccParaPropValMap& rSupplementalAttrSeq )
2348ca62e2c2SSteve Yin {
2349ca62e2c2SSteve Yin 	const SwTxtNode* pTxtNode( GetTxtNode() );
2350ca62e2c2SSteve Yin 	::boost::scoped_ptr<SfxItemSet> pSet;
2351ca62e2c2SSteve Yin 	pSet.reset( new SfxItemSet( const_cast<SwAttrPool&>(pTxtNode->GetDoc()->GetAttrPool()),
2352ca62e2c2SSteve Yin 		RES_PARATR_ADJUST, RES_PARATR_ADJUST,
2353ca62e2c2SSteve Yin 		RES_PARATR_TABSTOP, RES_PARATR_TABSTOP,
2354ca62e2c2SSteve Yin 		RES_PARATR_LINESPACING, RES_PARATR_LINESPACING,
2355ca62e2c2SSteve Yin 		RES_UL_SPACE, RES_UL_SPACE,
2356ca62e2c2SSteve Yin 		RES_LR_SPACE, RES_LR_SPACE,
2357ca62e2c2SSteve Yin 		RES_PARATR_NUMRULE, RES_PARATR_NUMRULE,
2358ca62e2c2SSteve Yin 		RES_PARATR_LIST_BEGIN, RES_PARATR_LIST_END-1,
2359ca62e2c2SSteve Yin 		0 ) );
2360ca62e2c2SSteve Yin 
2361ca62e2c2SSteve Yin 	if ( pTxtNode->HasBullet() || pTxtNode->HasNumber() )
2362ca62e2c2SSteve Yin 	{
2363ca62e2c2SSteve Yin 		pSet->Put( pTxtNode->GetAttr(RES_PARATR_LIST_LEVEL, RES_PARATR_LIST_LEVEL) );
2364ca62e2c2SSteve Yin 	}
2365ca62e2c2SSteve Yin 	pSet->Put( pTxtNode->SwCntntNode::GetAttr(RES_UL_SPACE) );
2366ca62e2c2SSteve Yin 	pSet->Put( pTxtNode->SwCntntNode::GetAttr(RES_LR_SPACE) );
2367ca62e2c2SSteve Yin 	pSet->Put( pTxtNode->SwCntntNode::GetAttr(RES_PARATR_ADJUST) );
2368ca62e2c2SSteve Yin 
2369ca62e2c2SSteve Yin 	tAccParaPropValMap aSupplementalAttrSeq;
2370ca62e2c2SSteve Yin     {
2371ca62e2c2SSteve Yin         const SfxItemPropertyMapEntry* pPropMap(
2372ca62e2c2SSteve Yin                 aSwMapProvider.GetPropertyMapEntries( PROPERTY_MAP_ACCESSIBILITY_TEXT_ATTRIBUTE ) );
2373ca62e2c2SSteve Yin         while ( pPropMap->pName )
2374ca62e2c2SSteve Yin         {
2375ca62e2c2SSteve Yin             const SfxPoolItem* pItem = pSet->GetItem( pPropMap->nWID );
2376ca62e2c2SSteve Yin             if ( pItem )
2377ca62e2c2SSteve Yin             {
2378ca62e2c2SSteve Yin                 uno::Any aVal;
2379ca62e2c2SSteve Yin                 pItem->QueryValue( aVal, pPropMap->nMemberId );
2380ca62e2c2SSteve Yin 
2381ca62e2c2SSteve Yin                 PropertyValue rPropVal;
2382ca62e2c2SSteve Yin                 rPropVal.Name = OUString::createFromAscii( pPropMap->pName );
2383ca62e2c2SSteve Yin                 rPropVal.Value = aVal;
2384ca62e2c2SSteve Yin                 rPropVal.Handle = -1;
2385ca62e2c2SSteve Yin                 rPropVal.State = beans::PropertyState_DEFAULT_VALUE;
2386ca62e2c2SSteve Yin 
2387ca62e2c2SSteve Yin                 aSupplementalAttrSeq[rPropVal.Name] = rPropVal;
2388ca62e2c2SSteve Yin             }
2389ca62e2c2SSteve Yin 
2390ca62e2c2SSteve Yin             ++pPropMap;
2391ca62e2c2SSteve Yin         }
2392ca62e2c2SSteve Yin 	}
2393ca62e2c2SSteve Yin 
2394ca62e2c2SSteve Yin 	const OUString* pSupplementalAttrs = aRequestedAttributes.getConstArray();
2395ca62e2c2SSteve Yin 	const sal_Int32 nSupplementalLength = aRequestedAttributes.getLength();
2396ca62e2c2SSteve Yin 
2397ca62e2c2SSteve Yin 	for( sal_Int32 index = 0; index < nSupplementalLength; ++index )
2398ca62e2c2SSteve Yin 	{
2399ca62e2c2SSteve Yin 		tAccParaPropValMap::const_iterator const aIter = aSupplementalAttrSeq.find( pSupplementalAttrs[index] );
2400ca62e2c2SSteve Yin 		if ( aIter != aSupplementalAttrSeq.end() )
2401ca62e2c2SSteve Yin 		{
2402ca62e2c2SSteve Yin 			rSupplementalAttrSeq[ aIter->first ] = aIter->second;
2403ca62e2c2SSteve Yin 		}
2404ca62e2c2SSteve Yin 	}
2405ca62e2c2SSteve Yin }
2406ca62e2c2SSteve Yin 
_correctValues(const sal_Int32 nIndex,uno::Sequence<PropertyValue> & rValues)2407ca62e2c2SSteve Yin void SwAccessibleParagraph::_correctValues( const sal_Int32 nIndex,
2408ca62e2c2SSteve Yin 										   uno::Sequence< PropertyValue >& rValues)
2409ca62e2c2SSteve Yin {
2410ca62e2c2SSteve Yin 	PropertyValue ChangeAttr, ChangeAttrColor;
2411ca62e2c2SSteve Yin 
2412ca62e2c2SSteve Yin 	const SwRedline* pRedline = GetRedlineAtIndex( nIndex );
2413ca62e2c2SSteve Yin 	if ( pRedline )
2414ca62e2c2SSteve Yin 	{
2415ca62e2c2SSteve Yin 
2416ca62e2c2SSteve Yin 		const SwModuleOptions *pOpt = SW_MOD()->GetModuleConfig();
2417ca62e2c2SSteve Yin 		AuthorCharAttr aChangeAttr;
2418ca62e2c2SSteve Yin 		if ( pOpt )
2419ca62e2c2SSteve Yin 		{
2420ca62e2c2SSteve Yin 			switch( pRedline->GetType())
2421ca62e2c2SSteve Yin 			{
2422ca62e2c2SSteve Yin 			case nsRedlineType_t::REDLINE_INSERT:
2423ca62e2c2SSteve Yin 				aChangeAttr = pOpt->GetInsertAuthorAttr();
2424ca62e2c2SSteve Yin 				break;
2425ca62e2c2SSteve Yin 			case nsRedlineType_t::REDLINE_DELETE:
2426ca62e2c2SSteve Yin 				aChangeAttr = pOpt->GetDeletedAuthorAttr();
2427ca62e2c2SSteve Yin 				break;
2428ca62e2c2SSteve Yin 			case nsRedlineType_t::REDLINE_FORMAT:
2429ca62e2c2SSteve Yin 				aChangeAttr = pOpt->GetFormatAuthorAttr();
2430ca62e2c2SSteve Yin 				break;
2431ca62e2c2SSteve Yin 			}
2432ca62e2c2SSteve Yin 		}
2433ca62e2c2SSteve Yin 		switch( aChangeAttr.nItemId )
2434ca62e2c2SSteve Yin 		{
2435ca62e2c2SSteve Yin 		case SID_ATTR_CHAR_WEIGHT:
2436ca62e2c2SSteve Yin 			ChangeAttr.Name = OUString::createFromAscii( GetPropName( UNO_NAME_CHAR_WEIGHT).pName );
2437ca62e2c2SSteve Yin 			ChangeAttr.Value <<= awt::FontWeight::BOLD;
2438ca62e2c2SSteve Yin 			break;
2439ca62e2c2SSteve Yin 		case SID_ATTR_CHAR_POSTURE:
2440ca62e2c2SSteve Yin 			ChangeAttr.Name = OUString::createFromAscii( GetPropName( UNO_NAME_CHAR_POSTURE).pName );
2441ca62e2c2SSteve Yin 			ChangeAttr.Value <<= awt::FontSlant_ITALIC; //char posture
2442ca62e2c2SSteve Yin 			break;
2443ca62e2c2SSteve Yin 		case SID_ATTR_CHAR_STRIKEOUT:
2444ca62e2c2SSteve Yin 			ChangeAttr.Name = OUString::createFromAscii( GetPropName( UNO_NAME_CHAR_STRIKEOUT).pName );
2445ca62e2c2SSteve Yin 			ChangeAttr.Value <<= awt::FontStrikeout::SINGLE; //char strikeout
2446ca62e2c2SSteve Yin 			break;
2447ca62e2c2SSteve Yin 		case SID_ATTR_CHAR_UNDERLINE:
2448ca62e2c2SSteve Yin 			ChangeAttr.Name = OUString::createFromAscii( GetPropName( UNO_NAME_CHAR_UNDERLINE).pName );
2449ca62e2c2SSteve Yin 			ChangeAttr.Value <<= aChangeAttr.nAttr; //underline line
2450ca62e2c2SSteve Yin 			break;
2451ca62e2c2SSteve Yin 		}
2452ca62e2c2SSteve Yin 		if( aChangeAttr.nColor != COL_NONE )
2453ca62e2c2SSteve Yin 		{
2454ca62e2c2SSteve Yin 			if( aChangeAttr.nItemId == SID_ATTR_BRUSH )
2455ca62e2c2SSteve Yin 			{
2456ca62e2c2SSteve Yin 				ChangeAttrColor.Name = OUString::createFromAscii( GetPropName( UNO_NAME_CHAR_BACK_COLOR).pName );
2457ca62e2c2SSteve Yin 				if( aChangeAttr.nColor == COL_TRANSPARENT )//char backcolor
2458ca62e2c2SSteve Yin 					ChangeAttrColor.Value <<= COL_BLUE;
2459ca62e2c2SSteve Yin 				else
2460ca62e2c2SSteve Yin 					ChangeAttrColor.Value <<= aChangeAttr.nColor;
2461ca62e2c2SSteve Yin 			}
2462ca62e2c2SSteve Yin 			else
2463ca62e2c2SSteve Yin 			{
2464ca62e2c2SSteve Yin 				ChangeAttrColor.Name = OUString::createFromAscii( GetPropName( UNO_NAME_CHAR_COLOR ).pName );
2465ca62e2c2SSteve Yin 				if( aChangeAttr.nColor == COL_TRANSPARENT )//char color
2466ca62e2c2SSteve Yin 					ChangeAttrColor.Value <<= COL_BLUE;
2467ca62e2c2SSteve Yin 				else
2468ca62e2c2SSteve Yin 					ChangeAttrColor.Value <<= aChangeAttr.nColor;
2469ca62e2c2SSteve Yin 			}
2470ca62e2c2SSteve Yin 		}
2471ca62e2c2SSteve Yin 	}
2472ca62e2c2SSteve Yin 
2473ca62e2c2SSteve Yin 	PropertyValue* pValues = rValues.getArray();
2474ca62e2c2SSteve Yin 
2475ca62e2c2SSteve Yin 	const SwTxtNode* pTxtNode( GetTxtNode() );
2476ca62e2c2SSteve Yin 
2477ca62e2c2SSteve Yin 	sal_Int32 nValues = rValues.getLength();
2478ca62e2c2SSteve Yin 	for (sal_Int32 i = 0;  i < nValues;  ++i)
2479ca62e2c2SSteve Yin 	{
2480ca62e2c2SSteve Yin 		PropertyValue& rValue = pValues[i];
2481ca62e2c2SSteve Yin 
2482ca62e2c2SSteve Yin 		if (rValue.Name.compareTo( ChangeAttr.Name )==0)
2483ca62e2c2SSteve Yin 		{
2484ca62e2c2SSteve Yin 			rValue.Value = ChangeAttr.Value;
2485ca62e2c2SSteve Yin 			continue;
2486ca62e2c2SSteve Yin 		}
2487ca62e2c2SSteve Yin 
2488ca62e2c2SSteve Yin 		if (rValue.Name.compareTo( ChangeAttrColor.Name )==0)
2489ca62e2c2SSteve Yin 		{
2490ca62e2c2SSteve Yin 			rValue.Value = ChangeAttr.Value;
2491ca62e2c2SSteve Yin 			continue;
2492ca62e2c2SSteve Yin 		}
2493ca62e2c2SSteve Yin 
2494ca62e2c2SSteve Yin 		//back color
2495ca62e2c2SSteve Yin 		if (rValue.Name.compareTo(::rtl::OUString::createFromAscii( GetPropName( UNO_NAME_CHAR_BACK_COLOR ).pName ) )==0)
2496ca62e2c2SSteve Yin 		{
2497ca62e2c2SSteve Yin 			uno::Any &anyChar = rValue.Value;
24985b989b89SHerbert Dürr 			sal_uInt32 crBack = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved));
2499ca62e2c2SSteve Yin 			if (COL_AUTO == crBack)
2500ca62e2c2SSteve Yin 			{
2501ca62e2c2SSteve Yin                 uno::Reference<XAccessibleComponent> xComponent(this);
2502ca62e2c2SSteve Yin 				if (xComponent.is())
2503ca62e2c2SSteve Yin 				{
2504ca62e2c2SSteve Yin 					crBack = (sal_uInt32)xComponent->getBackground();
2505ca62e2c2SSteve Yin 				}
2506ca62e2c2SSteve Yin 				rValue.Value <<= crBack;
2507ca62e2c2SSteve Yin 			}
2508ca62e2c2SSteve Yin 			continue;
2509ca62e2c2SSteve Yin 		}
2510ca62e2c2SSteve Yin 
2511ca62e2c2SSteve Yin 		//char color
2512ca62e2c2SSteve Yin 		if (rValue.Name.compareTo(::rtl::OUString::createFromAscii( GetPropName( UNO_NAME_CHAR_COLOR ).pName ) )==0)
2513ca62e2c2SSteve Yin 		{
2514ca62e2c2SSteve Yin 			if( GetPortionData().IsInGrayPortion( nIndex ) )
2515ca62e2c2SSteve Yin 				 rValue.Value <<= SwViewOption::GetFieldShadingsColor().GetColor();
2516ca62e2c2SSteve Yin 			uno::Any &anyChar = rValue.Value;
25175b989b89SHerbert Dürr 			sal_uInt32 crChar = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved));
2518ca62e2c2SSteve Yin 
2519ca62e2c2SSteve Yin 			if( COL_AUTO == crChar )
2520ca62e2c2SSteve Yin 			{
2521ca62e2c2SSteve Yin                 uno::Reference<XAccessibleComponent> xComponent(this);
2522ca62e2c2SSteve Yin 				if (xComponent.is())
2523ca62e2c2SSteve Yin 				{
2524ca62e2c2SSteve Yin 					Color cr(xComponent->getBackground());
2525ca62e2c2SSteve Yin 					crChar = cr.IsDark() ? COL_WHITE : COL_BLACK;
2526ca62e2c2SSteve Yin 					rValue.Value <<= crChar;
2527ca62e2c2SSteve Yin 				}
2528ca62e2c2SSteve Yin 			}
2529ca62e2c2SSteve Yin 			continue;
2530ca62e2c2SSteve Yin 		}
2531ca62e2c2SSteve Yin 
2532ca62e2c2SSteve Yin 		// UnderLine
2533ca62e2c2SSteve Yin 		if (rValue.Name.compareTo(::rtl::OUString::createFromAscii( GetPropName( UNO_NAME_CHAR_UNDERLINE ).pName ) )==0)
2534ca62e2c2SSteve Yin 		{
2535ca62e2c2SSteve Yin 			//misspelled word
2536ca62e2c2SSteve Yin 			SwCrsrShell* pCrsrShell = GetCrsrShell();
2537ca62e2c2SSteve Yin 			if( pCrsrShell != NULL && pCrsrShell->GetViewOptions() && pCrsrShell->GetViewOptions()->IsOnlineSpell())
2538ca62e2c2SSteve Yin 			{
2539ca62e2c2SSteve Yin 				const SwWrongList* pWrongList = pTxtNode->GetWrong();
2540ca62e2c2SSteve Yin 				if( NULL != pWrongList )
2541ca62e2c2SSteve Yin 				{
2542ca62e2c2SSteve Yin 					xub_StrLen nBegin = nIndex;
2543ca62e2c2SSteve Yin 					xub_StrLen nLen = 1;
2544ca62e2c2SSteve Yin 					if(	pWrongList->InWrongWord(nBegin,nLen) && !pTxtNode->IsSymbol(nBegin) )
2545ca62e2c2SSteve Yin 					{
2546ca62e2c2SSteve Yin 						rValue.Value <<= (sal_uInt16)UNDERLINE_WAVE;
2547ca62e2c2SSteve Yin 					}
2548ca62e2c2SSteve Yin 				}
2549ca62e2c2SSteve Yin 			}
2550ca62e2c2SSteve Yin 			continue;
2551ca62e2c2SSteve Yin 		}
2552ca62e2c2SSteve Yin 
2553ca62e2c2SSteve Yin 		// UnderLineColor
2554ca62e2c2SSteve Yin 		if (rValue.Name.compareTo(::rtl::OUString::createFromAscii( GetPropName( UNO_NAME_CHAR_UNDERLINE_COLOR ).pName ) )==0)
2555ca62e2c2SSteve Yin 		{
2556ca62e2c2SSteve Yin 			//misspelled word
2557ca62e2c2SSteve Yin 			SwCrsrShell* pCrsrShell = GetCrsrShell();
2558ca62e2c2SSteve Yin 			if( pCrsrShell != NULL && pCrsrShell->GetViewOptions() && pCrsrShell->GetViewOptions()->IsOnlineSpell())
2559ca62e2c2SSteve Yin 			{
2560ca62e2c2SSteve Yin 				const SwWrongList* pWrongList = pTxtNode->GetWrong();
2561ca62e2c2SSteve Yin 				if( NULL != pWrongList )
2562ca62e2c2SSteve Yin 				{
2563ca62e2c2SSteve Yin 					xub_StrLen nBegin = nIndex;
2564ca62e2c2SSteve Yin 					xub_StrLen nLen = 1;
2565ca62e2c2SSteve Yin 					if(	pWrongList->InWrongWord(nBegin,nLen) && !pTxtNode->IsSymbol(nBegin) )
2566ca62e2c2SSteve Yin 					{
2567ca62e2c2SSteve Yin 						rValue.Value <<= (sal_Int32)0x00ff0000;
2568ca62e2c2SSteve Yin 						continue;
2569ca62e2c2SSteve Yin 					}
2570ca62e2c2SSteve Yin 				}
2571ca62e2c2SSteve Yin 			}
2572ca62e2c2SSteve Yin 
2573ca62e2c2SSteve Yin 			uno::Any &anyChar = rValue.Value;
25745b989b89SHerbert Dürr 			sal_uInt32 crUnderline = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved));
2575ca62e2c2SSteve Yin 			if ( COL_AUTO == crUnderline )
2576ca62e2c2SSteve Yin 			{
2577ca62e2c2SSteve Yin                 uno::Reference<XAccessibleComponent> xComponent(this);
2578ca62e2c2SSteve Yin 				if (xComponent.is())
2579ca62e2c2SSteve Yin 				{
2580ca62e2c2SSteve Yin 					Color cr(xComponent->getBackground());
2581ca62e2c2SSteve Yin 					crUnderline = cr.IsDark() ? COL_WHITE : COL_BLACK;
2582ca62e2c2SSteve Yin 					rValue.Value <<= crUnderline;
2583ca62e2c2SSteve Yin 				}
2584ca62e2c2SSteve Yin 			}
2585ca62e2c2SSteve Yin 
2586ca62e2c2SSteve Yin 			continue;
2587ca62e2c2SSteve Yin 		}
2588ca62e2c2SSteve Yin 
2589ca62e2c2SSteve Yin 		//tab stop
2590ca62e2c2SSteve Yin 		if (rValue.Name.compareTo(::rtl::OUString::createFromAscii( GetPropName( UNO_NAME_TABSTOPS ).pName ) )==0)
2591ca62e2c2SSteve Yin 		{
2592ca62e2c2SSteve Yin 			com::sun::star::uno::Sequence< ::com::sun::star::style::TabStop > tabs = GetCurrentTabStop( nIndex );
2593ca62e2c2SSteve Yin 			if( !tabs.hasElements() )
2594ca62e2c2SSteve Yin 			{
2595ca62e2c2SSteve Yin 				tabs.realloc(1);
2596ca62e2c2SSteve Yin 				::com::sun::star::style::TabStop ts;
2597ca62e2c2SSteve Yin 				com::sun::star::awt::Rectangle rc0 = getCharacterBounds(0);
2598ca62e2c2SSteve Yin 				com::sun::star::awt::Rectangle rc1 = getCharacterBounds(nIndex);
2599ca62e2c2SSteve Yin 				if( rc1.X - rc0.X >= 48 )
2600ca62e2c2SSteve Yin 					ts.Position = (rc1.X - rc0.X) - (rc1.X - rc0.X - 48)% 47 + 47;
2601ca62e2c2SSteve Yin 				else
2602ca62e2c2SSteve Yin 					ts.Position = 48;
2603ca62e2c2SSteve Yin 				ts.DecimalChar = ' ';
2604ca62e2c2SSteve Yin 				ts.FillChar = ' ';
2605ca62e2c2SSteve Yin 				ts.Alignment = ::com::sun::star::style::TabAlign_LEFT;
2606ca62e2c2SSteve Yin 				tabs[0] = ts;
2607ca62e2c2SSteve Yin 			}
2608ca62e2c2SSteve Yin 			rValue.Value <<= tabs;
2609ca62e2c2SSteve Yin 			continue;
2610ca62e2c2SSteve Yin 		}
2611ca62e2c2SSteve Yin 
2612ca62e2c2SSteve Yin 		//number bullet
2613ca62e2c2SSteve Yin 		if (rValue.Name.compareTo(::rtl::OUString::createFromAscii( GetPropName( UNO_NAME_NUMBERING_RULES ).pName ) )==0)
2614ca62e2c2SSteve Yin 		{
2615ca62e2c2SSteve Yin 			if ( pTxtNode->HasBullet() || pTxtNode->HasNumber() )
2616ca62e2c2SSteve Yin 			{
2617ca62e2c2SSteve Yin                 uno::Any aVal;
2618ca62e2c2SSteve Yin 				SwNumRule* pNumRule = pTxtNode->GetNumRule();
2619ca62e2c2SSteve Yin 				if (pNumRule)
2620ca62e2c2SSteve Yin 				{
2621ca62e2c2SSteve Yin                     uno::Reference< container::XIndexReplace >  xNum = new SwXNumberingRules(*pNumRule);
2622ca62e2c2SSteve Yin                     aVal.setValue(&xNum, ::getCppuType((const uno::Reference< container::XIndexReplace >*)0));
2623ca62e2c2SSteve Yin 				}
2624ca62e2c2SSteve Yin 				rValue.Value <<= aVal;
2625ca62e2c2SSteve Yin 			}
2626ca62e2c2SSteve Yin 			continue;
2627ca62e2c2SSteve Yin 		}
2628ca62e2c2SSteve Yin 
2629ca62e2c2SSteve Yin 		//footnote & endnote
2630ca62e2c2SSteve Yin 		if (rValue.Name.compareTo(::rtl::OUString::createFromAscii( GetPropName( UNO_NAME_CHAR_ESCAPEMENT ).pName ) )==0)
2631ca62e2c2SSteve Yin 		{
2632ca62e2c2SSteve Yin 			if ( GetPortionData().IsIndexInFootnode(nIndex) )
2633ca62e2c2SSteve Yin 			{
2634ca62e2c2SSteve Yin 				const OUString sEscapmentName = OUString::createFromAscii( GetPropName( UNO_NAME_CHAR_ESCAPEMENT ).pName );
2635ca62e2c2SSteve Yin 				rValue.Value <<= (sal_Int32)101;
2636ca62e2c2SSteve Yin 			}
2637ca62e2c2SSteve Yin 			continue;
2638ca62e2c2SSteve Yin 		}
2639ca62e2c2SSteve Yin 	}
2640ca62e2c2SSteve Yin }
2641cdf0e10cSrcweir 
getCharacterBounds(sal_Int32 nIndex)2642cdf0e10cSrcweir awt::Rectangle SwAccessibleParagraph::getCharacterBounds(
2643cdf0e10cSrcweir     sal_Int32 nIndex )
2644cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2645cdf0e10cSrcweir {
2646cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
2647cdf0e10cSrcweir 
2648cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
2649cdf0e10cSrcweir 
2650cdf0e10cSrcweir 
2651cdf0e10cSrcweir     /*  #i12332# The position after the string needs special treatment.
2652cdf0e10cSrcweir         IsValidChar -> IsValidPosition
2653cdf0e10cSrcweir     */
2654cdf0e10cSrcweir     if( ! (IsValidPosition( nIndex, GetString().getLength() ) ) )
2655cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
2656cdf0e10cSrcweir 
2657cdf0e10cSrcweir     /*  #i12332#  */
2658cdf0e10cSrcweir     sal_Bool bBehindText = sal_False;
2659cdf0e10cSrcweir     if ( nIndex == GetString().getLength() )
2660cdf0e10cSrcweir         bBehindText = sal_True;
2661cdf0e10cSrcweir 
2662cdf0e10cSrcweir     // get model position & prepare GetCharRect() arguments
2663cdf0e10cSrcweir     SwCrsrMoveState aMoveState;
2664cdf0e10cSrcweir     aMoveState.bRealHeight = sal_True;
2665cdf0e10cSrcweir     aMoveState.bRealWidth = sal_True;
2666cdf0e10cSrcweir     SwSpecialPos aSpecialPos;
2667cdf0e10cSrcweir     SwTxtNode* pNode = const_cast<SwTxtNode*>( GetTxtNode() );
2668cdf0e10cSrcweir 
2669cdf0e10cSrcweir     sal_uInt16 nPos = 0;
2670cdf0e10cSrcweir 
2671cdf0e10cSrcweir     /*  #i12332# FillSpecialPos does not accept nIndex ==
2672cdf0e10cSrcweir          GetString().getLength(). In that case nPos is set to the
2673cdf0e10cSrcweir          length of the string in the core. This way GetCharRect
2674cdf0e10cSrcweir          returns the rectangle for a cursor at the end of the
2675cdf0e10cSrcweir          paragraph. */
2676cdf0e10cSrcweir     if (bBehindText)
2677cdf0e10cSrcweir     {
2678cdf0e10cSrcweir         nPos = pNode->GetTxt().Len();
2679cdf0e10cSrcweir     }
2680cdf0e10cSrcweir     else
2681cdf0e10cSrcweir         nPos = GetPortionData().FillSpecialPos
2682cdf0e10cSrcweir             (nIndex, aSpecialPos, aMoveState.pSpecialPos );
2683cdf0e10cSrcweir 
2684cdf0e10cSrcweir     // call GetCharRect
2685cdf0e10cSrcweir     SwRect aCoreRect;
2686cdf0e10cSrcweir     SwIndex aIndex( pNode, nPos );
2687cdf0e10cSrcweir     SwPosition aPosition( *pNode, aIndex );
2688cdf0e10cSrcweir     GetFrm()->GetCharRect( aCoreRect, aPosition, &aMoveState );
2689cdf0e10cSrcweir 
2690cdf0e10cSrcweir     // translate core coordinates into accessibility coordinates
2691cdf0e10cSrcweir 	Window *pWin = GetWindow();
2692cdf0e10cSrcweir 	CHECK_FOR_WINDOW( XAccessibleComponent, pWin );
2693cdf0e10cSrcweir 
2694cdf0e10cSrcweir 	Rectangle aScreenRect( GetMap()->CoreToPixel( aCoreRect.SVRect() ));
2695cdf0e10cSrcweir     SwRect aFrmLogBounds( GetBounds( *(GetMap()) ) ); // twip rel to doc root
2696cdf0e10cSrcweir 
2697cdf0e10cSrcweir 	Point aFrmPixPos( GetMap()->CoreToPixel( aFrmLogBounds.SVRect() ).TopLeft() );
2698cdf0e10cSrcweir 	aScreenRect.Move( -aFrmPixPos.X(), -aFrmPixPos.Y() );
2699cdf0e10cSrcweir 
2700cdf0e10cSrcweir     // convert into AWT Rectangle
2701cdf0e10cSrcweir     return awt::Rectangle(
2702cdf0e10cSrcweir         aScreenRect.Left(), aScreenRect.Top(),
2703cdf0e10cSrcweir         aScreenRect.GetWidth(), aScreenRect.GetHeight() );
2704cdf0e10cSrcweir }
2705cdf0e10cSrcweir 
getCharacterCount()2706cdf0e10cSrcweir sal_Int32 SwAccessibleParagraph::getCharacterCount()
2707cdf0e10cSrcweir     throw (uno::RuntimeException)
2708cdf0e10cSrcweir {
2709cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
2710cdf0e10cSrcweir 
2711cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
2712cdf0e10cSrcweir 
2713cdf0e10cSrcweir     return GetString().getLength();
2714cdf0e10cSrcweir }
2715cdf0e10cSrcweir 
getIndexAtPoint(const awt::Point & rPoint)2716cdf0e10cSrcweir sal_Int32 SwAccessibleParagraph::getIndexAtPoint( const awt::Point& rPoint )
2717cdf0e10cSrcweir     throw (uno::RuntimeException)
2718cdf0e10cSrcweir {
2719cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
2720cdf0e10cSrcweir 
2721cdf0e10cSrcweir 
2722cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
2723cdf0e10cSrcweir 
2724cdf0e10cSrcweir     // construct SwPosition (where GetCrsrOfst() will put the result into)
2725cdf0e10cSrcweir     SwTxtNode* pNode = const_cast<SwTxtNode*>( GetTxtNode() );
2726cdf0e10cSrcweir     SwIndex aIndex( pNode, 0);
2727cdf0e10cSrcweir     SwPosition aPos( *pNode, aIndex );
2728cdf0e10cSrcweir 
2729cdf0e10cSrcweir     // construct Point (translate into layout coordinates)
2730cdf0e10cSrcweir 	Window *pWin = GetWindow();
2731cdf0e10cSrcweir 	CHECK_FOR_WINDOW( XAccessibleComponent, pWin );
2732cdf0e10cSrcweir     Point aPoint( rPoint.X, rPoint.Y );
2733cdf0e10cSrcweir     SwRect aLogBounds( GetBounds( *(GetMap()), GetFrm() ) ); // twip rel to doc root
2734cdf0e10cSrcweir 	Point aPixPos( GetMap()->CoreToPixel( aLogBounds.SVRect() ).TopLeft() );
2735cdf0e10cSrcweir 	aPoint.X() += aPixPos.X();
2736cdf0e10cSrcweir 	aPoint.Y() += aPixPos.Y();
2737cdf0e10cSrcweir     MapMode aMapMode = pWin->GetMapMode();
2738cdf0e10cSrcweir 	Point aCorePoint( GetMap()->PixelToCore( aPoint ) );
2739cdf0e10cSrcweir 	if( !aLogBounds.IsInside( aCorePoint ) )
2740cdf0e10cSrcweir     {
2741cdf0e10cSrcweir         /* #i12332# rPoint is may also be in rectangle returned by
2742cdf0e10cSrcweir             getCharacterBounds(getCharacterCount() */
2743cdf0e10cSrcweir 
2744cdf0e10cSrcweir         awt::Rectangle aRectEndPos =
2745cdf0e10cSrcweir             getCharacterBounds(getCharacterCount());
2746cdf0e10cSrcweir 
2747cdf0e10cSrcweir         if (rPoint.X - aRectEndPos.X >= 0 &&
2748cdf0e10cSrcweir             rPoint.X - aRectEndPos.X < aRectEndPos.Width &&
2749cdf0e10cSrcweir             rPoint.Y - aRectEndPos.Y >= 0 &&
2750cdf0e10cSrcweir             rPoint.Y - aRectEndPos.Y < aRectEndPos.Height)
2751cdf0e10cSrcweir             return getCharacterCount();
2752cdf0e10cSrcweir 
2753cdf0e10cSrcweir 		return -1;
2754cdf0e10cSrcweir     }
2755cdf0e10cSrcweir 
2756cdf0e10cSrcweir     // ask core for position
2757cdf0e10cSrcweir     DBG_ASSERT( GetFrm() != NULL, "The text frame has vanished!" );
2758cdf0e10cSrcweir     DBG_ASSERT( GetFrm()->IsTxtFrm(), "The text frame has mutated!" );
2759cdf0e10cSrcweir     const SwTxtFrm* pFrm = static_cast<const SwTxtFrm*>( GetFrm() );
2760cdf0e10cSrcweir     SwCrsrMoveState aMoveState;
2761cdf0e10cSrcweir     aMoveState.bPosMatchesBounds = sal_True;
2762cdf0e10cSrcweir     sal_Bool bSuccess = pFrm->GetCrsrOfst( &aPos, aCorePoint, &aMoveState );
2763cdf0e10cSrcweir 
2764cdf0e10cSrcweir     SwIndex aCntntIdx = aPos.nContent;
2765cdf0e10cSrcweir     const xub_StrLen nIndex = aCntntIdx.GetIndex();
2766cdf0e10cSrcweir     if ( nIndex > 0 )
2767cdf0e10cSrcweir     {
2768cdf0e10cSrcweir         SwRect aResultRect;
2769cdf0e10cSrcweir         pFrm->GetCharRect( aResultRect, aPos );
2770cdf0e10cSrcweir         bool bVert = pFrm->IsVertical();
2771cdf0e10cSrcweir         bool bR2L = pFrm->IsRightToLeft();
2772cdf0e10cSrcweir 
2773cdf0e10cSrcweir         if ( (!bVert && aResultRect.Pos().X() > aCorePoint.X()) ||
2774cdf0e10cSrcweir              ( bVert && aResultRect.Pos().Y() > aCorePoint.Y()) ||
2775cdf0e10cSrcweir              ( bR2L  && aResultRect.Right()   < aCorePoint.X()) )
2776cdf0e10cSrcweir         {
2777cdf0e10cSrcweir             SwIndex aIdxPrev( pNode, nIndex - 1);
2778cdf0e10cSrcweir             SwPosition aPosPrev( *pNode, aIdxPrev );
2779cdf0e10cSrcweir             SwRect aResultRectPrev;
2780cdf0e10cSrcweir             pFrm->GetCharRect( aResultRectPrev, aPosPrev );
2781cdf0e10cSrcweir             if ( (!bVert && aResultRectPrev.Pos().X() < aCorePoint.X() && aResultRect.Pos().Y() == aResultRectPrev.Pos().Y()) ||
2782cdf0e10cSrcweir                  ( bVert && aResultRectPrev.Pos().Y() < aCorePoint.Y() && aResultRect.Pos().X() == aResultRectPrev.Pos().X()) ||
2783cdf0e10cSrcweir                  (  bR2L && aResultRectPrev.Right()   > aCorePoint.X() && aResultRect.Pos().Y() == aResultRectPrev.Pos().Y()) )
2784cdf0e10cSrcweir                 aPos = aPosPrev;
2785cdf0e10cSrcweir         }
2786cdf0e10cSrcweir     }
2787cdf0e10cSrcweir 
2788cdf0e10cSrcweir     return bSuccess ?
2789cdf0e10cSrcweir         GetPortionData().GetAccessiblePosition( aPos.nContent.GetIndex() )
2790cdf0e10cSrcweir         : -1L;
2791cdf0e10cSrcweir }
2792cdf0e10cSrcweir 
getSelectedText()2793cdf0e10cSrcweir ::rtl::OUString SwAccessibleParagraph::getSelectedText()
2794cdf0e10cSrcweir     throw (uno::RuntimeException)
2795cdf0e10cSrcweir {
2796cdf0e10cSrcweir     vos::OGuard aGuard(Application::GetSolarMutex());
2797cdf0e10cSrcweir 
2798cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
2799cdf0e10cSrcweir 
2800cdf0e10cSrcweir     sal_Int32 nStart, nEnd;
2801cdf0e10cSrcweir     sal_Bool bSelected = GetSelection( nStart, nEnd );
2802cdf0e10cSrcweir     return bSelected
2803cdf0e10cSrcweir            ? GetString().copy( nStart, nEnd - nStart )
2804cdf0e10cSrcweir            : ::rtl::OUString();
2805cdf0e10cSrcweir }
2806cdf0e10cSrcweir 
getSelectionStart()2807cdf0e10cSrcweir sal_Int32 SwAccessibleParagraph::getSelectionStart()
2808cdf0e10cSrcweir     throw (uno::RuntimeException)
2809cdf0e10cSrcweir {
2810cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
2811cdf0e10cSrcweir 
2812cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
2813cdf0e10cSrcweir 
2814cdf0e10cSrcweir     sal_Int32 nStart, nEnd;
2815cdf0e10cSrcweir     GetSelection( nStart, nEnd );
2816cdf0e10cSrcweir     return nStart;
2817cdf0e10cSrcweir }
2818cdf0e10cSrcweir 
getSelectionEnd()2819cdf0e10cSrcweir sal_Int32 SwAccessibleParagraph::getSelectionEnd()
2820cdf0e10cSrcweir     throw (uno::RuntimeException)
2821cdf0e10cSrcweir {
2822cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
2823cdf0e10cSrcweir 
2824cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
2825cdf0e10cSrcweir 
2826cdf0e10cSrcweir     sal_Int32 nStart, nEnd;
2827cdf0e10cSrcweir     GetSelection( nStart, nEnd );
2828cdf0e10cSrcweir     return nEnd;
2829cdf0e10cSrcweir }
2830cdf0e10cSrcweir 
setSelection(sal_Int32 nStartIndex,sal_Int32 nEndIndex)2831cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2832cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2833cdf0e10cSrcweir {
2834cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
2835cdf0e10cSrcweir 
2836cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
2837cdf0e10cSrcweir 
2838cdf0e10cSrcweir     // parameter checking
2839cdf0e10cSrcweir     sal_Int32 nLength = GetString().getLength();
2840cdf0e10cSrcweir     if ( ! IsValidRange( nStartIndex, nEndIndex, nLength ) )
2841cdf0e10cSrcweir     {
2842cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
2843cdf0e10cSrcweir     }
2844cdf0e10cSrcweir 
2845cdf0e10cSrcweir     sal_Bool bRet = sal_False;
2846cdf0e10cSrcweir 
2847cdf0e10cSrcweir     // get cursor shell
2848cdf0e10cSrcweir     SwCrsrShell* pCrsrShell = GetCrsrShell();
2849cdf0e10cSrcweir     if( pCrsrShell != NULL )
2850cdf0e10cSrcweir     {
2851cdf0e10cSrcweir         // create pam for selection
2852cdf0e10cSrcweir         SwTxtNode* pNode = const_cast<SwTxtNode*>( GetTxtNode() );
2853cdf0e10cSrcweir         SwIndex aIndex( pNode, GetPortionData().GetModelPosition(nStartIndex));
2854cdf0e10cSrcweir         SwPosition aStartPos( *pNode, aIndex );
2855cdf0e10cSrcweir         SwPaM aPaM( aStartPos );
2856cdf0e10cSrcweir         aPaM.SetMark();
2857cdf0e10cSrcweir         aPaM.GetPoint()->nContent =
2858cdf0e10cSrcweir             GetPortionData().GetModelPosition(nEndIndex);
2859cdf0e10cSrcweir 
2860cdf0e10cSrcweir         // set PaM at cursor shell
2861cdf0e10cSrcweir         bRet = Select( aPaM );
2862cdf0e10cSrcweir     }
2863cdf0e10cSrcweir 
2864cdf0e10cSrcweir     return bRet;
2865cdf0e10cSrcweir }
2866cdf0e10cSrcweir 
getText()2867cdf0e10cSrcweir ::rtl::OUString SwAccessibleParagraph::getText()
2868cdf0e10cSrcweir     throw (uno::RuntimeException)
2869cdf0e10cSrcweir {
2870cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
2871cdf0e10cSrcweir 
2872cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
2873cdf0e10cSrcweir 
2874cdf0e10cSrcweir     return GetString();
2875cdf0e10cSrcweir }
2876cdf0e10cSrcweir 
getTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)2877cdf0e10cSrcweir ::rtl::OUString SwAccessibleParagraph::getTextRange(
2878cdf0e10cSrcweir     sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2879cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
2880cdf0e10cSrcweir {
2881cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
2882cdf0e10cSrcweir 
2883cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
2884cdf0e10cSrcweir 
2885cdf0e10cSrcweir     ::rtl::OUString sText( GetString() );
2886cdf0e10cSrcweir 
2887cdf0e10cSrcweir     if ( IsValidRange( nStartIndex, nEndIndex, sText.getLength() ) )
2888cdf0e10cSrcweir     {
2889cdf0e10cSrcweir         OrderRange( nStartIndex, nEndIndex );
2890cdf0e10cSrcweir         return sText.copy(nStartIndex, nEndIndex-nStartIndex );
2891cdf0e10cSrcweir     }
2892cdf0e10cSrcweir     else
2893cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
2894cdf0e10cSrcweir }
2895cdf0e10cSrcweir 
getTextAtIndex(sal_Int32 nIndex,sal_Int16 nTextType)2896cdf0e10cSrcweir /*accessibility::*/TextSegment SwAccessibleParagraph::getTextAtIndex( sal_Int32 nIndex, sal_Int16 nTextType ) throw (lang::IndexOutOfBoundsException, lang::IllegalArgumentException, uno::RuntimeException)
2897cdf0e10cSrcweir {
2898cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
2899cdf0e10cSrcweir 
2900cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
2901cdf0e10cSrcweir 
2902cdf0e10cSrcweir     /*accessibility::*/TextSegment aResult;
2903cdf0e10cSrcweir     aResult.SegmentStart = -1;
2904cdf0e10cSrcweir     aResult.SegmentEnd = -1;
2905cdf0e10cSrcweir 
2906cdf0e10cSrcweir     const ::rtl::OUString rText = GetString();
2907cdf0e10cSrcweir     // implement the silly specification that first position after
2908cdf0e10cSrcweir     // text must return an empty string, rather than throwing an
2909cdf0e10cSrcweir     // IndexOutOfBoundsException, except for LINE, where the last
2910cdf0e10cSrcweir 	// line is returned
2911cdf0e10cSrcweir     if( nIndex == rText.getLength() && AccessibleTextType::LINE != nTextType )
2912cdf0e10cSrcweir 		return aResult;
2913cdf0e10cSrcweir 
2914cdf0e10cSrcweir     // with error checking
2915cdf0e10cSrcweir     i18n::Boundary aBound;
2916cdf0e10cSrcweir     sal_Bool bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
2917cdf0e10cSrcweir 
2918cdf0e10cSrcweir     DBG_ASSERT( aBound.startPos >= 0,               "illegal boundary" );
2919cdf0e10cSrcweir     DBG_ASSERT( aBound.startPos <= aBound.endPos,   "illegal boundary" );
2920cdf0e10cSrcweir 
2921cdf0e10cSrcweir     // return word (if present)
2922cdf0e10cSrcweir     if ( bWord )
2923cdf0e10cSrcweir     {
2924cdf0e10cSrcweir     	aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
2925cdf0e10cSrcweir     	aResult.SegmentStart = aBound.startPos;
2926cdf0e10cSrcweir     	aResult.SegmentEnd = aBound.endPos;
2927cdf0e10cSrcweir     }
2928cdf0e10cSrcweir 
2929cdf0e10cSrcweir     return aResult;
2930cdf0e10cSrcweir }
2931cdf0e10cSrcweir 
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 nTextType)2932cdf0e10cSrcweir /*accessibility::*/TextSegment SwAccessibleParagraph::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 nTextType ) throw (lang::IndexOutOfBoundsException, lang::IllegalArgumentException, uno::RuntimeException)
2933cdf0e10cSrcweir {
2934cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
2935cdf0e10cSrcweir 
2936cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
2937cdf0e10cSrcweir 
2938cdf0e10cSrcweir     const ::rtl::OUString rText = GetString();
2939cdf0e10cSrcweir 
2940cdf0e10cSrcweir     /*accessibility::*/TextSegment aResult;
2941cdf0e10cSrcweir     aResult.SegmentStart = -1;
2942cdf0e10cSrcweir     aResult.SegmentEnd = -1;
2943ca62e2c2SSteve Yin 	//If nIndex = 0, then nobefore text so return -1 directly.
2944ca62e2c2SSteve Yin     if( nIndex == 0 )
2945ca62e2c2SSteve Yin         	return aResult;
2946ca62e2c2SSteve Yin 	//Tab will be return when call WORDTYPE
2947cdf0e10cSrcweir 
2948cdf0e10cSrcweir     // get starting pos
2949cdf0e10cSrcweir     i18n::Boundary aBound;
2950cdf0e10cSrcweir     if (nIndex ==  rText.getLength())
2951cdf0e10cSrcweir         aBound.startPos = aBound.endPos = nIndex;
2952cdf0e10cSrcweir     else
2953cdf0e10cSrcweir     {
2954cdf0e10cSrcweir         sal_Bool bTmp = GetTextBoundary( aBound, rText, nIndex, nTextType );
2955cdf0e10cSrcweir 
2956cdf0e10cSrcweir         if ( ! bTmp )
2957cdf0e10cSrcweir             aBound.startPos = aBound.endPos = nIndex;
2958cdf0e10cSrcweir     }
2959cdf0e10cSrcweir 
2960cdf0e10cSrcweir     // now skip to previous word
2961ca62e2c2SSteve Yin 	if (nTextType==2 || nTextType == 3)
2962ca62e2c2SSteve Yin 	{
2963ca62e2c2SSteve Yin         i18n::Boundary preBound = aBound;
2964ca62e2c2SSteve Yin 		while(preBound.startPos==aBound.startPos && nIndex > 0)
2965ca62e2c2SSteve Yin 		{
2966ca62e2c2SSteve Yin 			nIndex = min( nIndex, preBound.startPos ) - 1;
2967ca62e2c2SSteve Yin 			if( nIndex < 0 ) break;
2968ca62e2c2SSteve Yin 			GetTextBoundary( preBound, rText, nIndex, nTextType );
2969ca62e2c2SSteve Yin 		}
2970ca62e2c2SSteve Yin 		//if (nIndex>0)
2971ca62e2c2SSteve Yin 		if (nIndex>=0)
2972ca62e2c2SSteve Yin 		//Tab will be return when call WORDTYPE
2973ca62e2c2SSteve Yin 		{
2974ca62e2c2SSteve Yin 			aResult.SegmentText = rText.copy( preBound.startPos, preBound.endPos - preBound.startPos );
2975ca62e2c2SSteve Yin 			aResult.SegmentStart = preBound.startPos;
2976ca62e2c2SSteve Yin 			aResult.SegmentEnd = preBound.endPos;
2977ca62e2c2SSteve Yin 		}
2978ca62e2c2SSteve Yin 	}
2979ca62e2c2SSteve Yin 	else
2980ca62e2c2SSteve Yin 	{
2981cdf0e10cSrcweir 		sal_Bool bWord = sal_False;
2982cdf0e10cSrcweir 		while( !bWord )
2983cdf0e10cSrcweir 		{
2984cdf0e10cSrcweir 			nIndex = min( nIndex, aBound.startPos ) - 1;
2985cdf0e10cSrcweir 			if( nIndex >= 0 )
2986ca62e2c2SSteve Yin 			{
2987cdf0e10cSrcweir 				bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
2988ca62e2c2SSteve Yin 			}
2989cdf0e10cSrcweir 			else
2990cdf0e10cSrcweir 				break;  // exit if beginning of string is reached
2991cdf0e10cSrcweir 		}
2992cdf0e10cSrcweir 
2993ca62e2c2SSteve Yin 		if (bWord && nIndex<rText.getLength())
2994cdf0e10cSrcweir 		{
2995cdf0e10cSrcweir 			aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
2996cdf0e10cSrcweir 			aResult.SegmentStart = aBound.startPos;
2997cdf0e10cSrcweir 			aResult.SegmentEnd = aBound.endPos;
2998ca62e2c2SSteve Yin 		}
2999ca62e2c2SSteve Yin 	}
3000cdf0e10cSrcweir     return aResult;
3001cdf0e10cSrcweir }
3002cdf0e10cSrcweir 
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 nTextType)3003cdf0e10cSrcweir /*accessibility::*/TextSegment SwAccessibleParagraph::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 nTextType ) throw (lang::IndexOutOfBoundsException, lang::IllegalArgumentException, uno::RuntimeException)
3004cdf0e10cSrcweir {
3005cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
3006cdf0e10cSrcweir 
3007cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
3008cdf0e10cSrcweir 
3009cdf0e10cSrcweir     /*accessibility::*/TextSegment aResult;
3010cdf0e10cSrcweir     aResult.SegmentStart = -1;
3011cdf0e10cSrcweir     aResult.SegmentEnd = -1;
3012cdf0e10cSrcweir     const ::rtl::OUString rText = GetString();
3013cdf0e10cSrcweir 
3014cdf0e10cSrcweir     // implement the silly specification that first position after
3015cdf0e10cSrcweir     // text must return an empty string, rather than throwing an
3016cdf0e10cSrcweir     // IndexOutOfBoundsException
3017cdf0e10cSrcweir     if( nIndex == rText.getLength() )
3018cdf0e10cSrcweir         return aResult;
3019cdf0e10cSrcweir 
3020cdf0e10cSrcweir 
3021cdf0e10cSrcweir     // get first word, then skip to next word
3022cdf0e10cSrcweir     i18n::Boundary aBound;
3023cdf0e10cSrcweir     GetTextBoundary( aBound, rText, nIndex, nTextType );
3024cdf0e10cSrcweir     sal_Bool bWord = sal_False;
3025cdf0e10cSrcweir     while( !bWord )
3026cdf0e10cSrcweir     {
3027cdf0e10cSrcweir         nIndex = max( sal_Int32(nIndex+1), aBound.endPos );
3028cdf0e10cSrcweir         if( nIndex < rText.getLength() )
3029cdf0e10cSrcweir             bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
3030cdf0e10cSrcweir         else
3031cdf0e10cSrcweir             break;  // exit if end of string is reached
3032cdf0e10cSrcweir     }
3033cdf0e10cSrcweir 
3034cdf0e10cSrcweir     if ( bWord )
3035cdf0e10cSrcweir     {
3036cdf0e10cSrcweir     	aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
3037cdf0e10cSrcweir     	aResult.SegmentStart = aBound.startPos;
3038cdf0e10cSrcweir     	aResult.SegmentEnd = aBound.endPos;
3039cdf0e10cSrcweir     }
3040ca62e2c2SSteve Yin 
3041ca62e2c2SSteve Yin /*
3042ca62e2c2SSteve Yin         sal_Bool bWord = sal_False;
3043ca62e2c2SSteve Yin     bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
3044ca62e2c2SSteve Yin 
3045ca62e2c2SSteve Yin         if (nTextType==2)
3046ca62e2c2SSteve Yin         {
3047ca62e2c2SSteve Yin                 Boundary nexBound=aBound;
3048ca62e2c2SSteve Yin 
3049ca62e2c2SSteve Yin 		// real current word
3050ca62e2c2SSteve Yin 		if( nIndex <= aBound.endPos && nIndex >= aBound.startPos )
3051ca62e2c2SSteve Yin 		{
3052ca62e2c2SSteve Yin 			while(nexBound.endPos==aBound.endPos&&nIndex<rText.getLength())
3053ca62e2c2SSteve Yin 			{
3054ca62e2c2SSteve Yin 				// nIndex = max( (sal_Int32)(nIndex), nexBound.endPos) + 1;
3055ca62e2c2SSteve Yin 				nIndex = max( (sal_Int32)(nIndex), nexBound.endPos) ;
3056ca62e2c2SSteve Yin 				const sal_Unicode* pStr = rText.getStr();
3057ca62e2c2SSteve Yin 				if (pStr)
3058ca62e2c2SSteve Yin 				{
3059ca62e2c2SSteve Yin 					if( pStr[nIndex] == sal_Unicode(' ') )
3060ca62e2c2SSteve Yin 						nIndex++;
3061ca62e2c2SSteve Yin 				}
3062ca62e2c2SSteve Yin 				if( nIndex < rText.getLength() )
3063ca62e2c2SSteve Yin 				{
3064ca62e2c2SSteve Yin 					bWord = GetTextBoundary( nexBound, rText, nIndex, nTextType );
3065ca62e2c2SSteve Yin 				}
3066ca62e2c2SSteve Yin 			}
3067ca62e2c2SSteve Yin 		}
3068ca62e2c2SSteve Yin 
3069ca62e2c2SSteve Yin 		if (bWord && nIndex<rText.getLength())
3070ca62e2c2SSteve Yin 		{
3071ca62e2c2SSteve Yin 			aResult.SegmentText = rText.copy( nexBound.startPos, nexBound.endPos - nexBound.startPos );
3072ca62e2c2SSteve Yin 			aResult.SegmentStart = nexBound.startPos;
3073ca62e2c2SSteve Yin 			aResult.SegmentEnd = nexBound.endPos;
3074ca62e2c2SSteve Yin 		}
3075ca62e2c2SSteve Yin 
3076ca62e2c2SSteve Yin 	}
3077ca62e2c2SSteve Yin 	else
3078ca62e2c2SSteve Yin 	{
3079ca62e2c2SSteve Yin 		bWord = sal_False;
3080ca62e2c2SSteve Yin 		while( !bWord )
3081ca62e2c2SSteve Yin 		{
3082ca62e2c2SSteve Yin 			nIndex = max( (sal_Int32)(nIndex+1), aBound.endPos );
3083ca62e2c2SSteve Yin 			if( nIndex < rText.getLength() )
3084ca62e2c2SSteve Yin 			{
3085ca62e2c2SSteve Yin 				bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
3086ca62e2c2SSteve Yin 			}
3087ca62e2c2SSteve Yin 			else
3088ca62e2c2SSteve Yin 				break;  // exit if end of string is reached
3089ca62e2c2SSteve Yin 		}
3090ca62e2c2SSteve Yin 		if (bWord && nIndex<rText.getLength())
3091ca62e2c2SSteve Yin 		{
3092ca62e2c2SSteve Yin 			aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
3093ca62e2c2SSteve Yin 			aResult.SegmentStart = aBound.startPos;
3094ca62e2c2SSteve Yin 			aResult.SegmentEnd = aBound.endPos;
3095ca62e2c2SSteve Yin 		}
3096ca62e2c2SSteve Yin 	}
3097ca62e2c2SSteve Yin */
3098cdf0e10cSrcweir     return aResult;
3099cdf0e10cSrcweir }
3100cdf0e10cSrcweir 
copyText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)3101cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
3102cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
3103cdf0e10cSrcweir {
3104cdf0e10cSrcweir 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
3105cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
3106cdf0e10cSrcweir 
3107cdf0e10cSrcweir     // select and copy (through dispatch mechanism)
3108cdf0e10cSrcweir     setSelection( nStartIndex, nEndIndex );
3109cdf0e10cSrcweir     ExecuteAtViewShell( SID_COPY );
3110cdf0e10cSrcweir     return sal_True;
3111cdf0e10cSrcweir }
3112cdf0e10cSrcweir 
3113cdf0e10cSrcweir 
3114cdf0e10cSrcweir //
3115cdf0e10cSrcweir //=====  XAccesibleEditableText  ==========================================
3116cdf0e10cSrcweir //
3117cdf0e10cSrcweir 
cutText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)3118cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
3119cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
3120cdf0e10cSrcweir {
3121cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleEditableText );
3122cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
3123cdf0e10cSrcweir 
3124cdf0e10cSrcweir 	if( !IsEditableState() )
3125cdf0e10cSrcweir 		return sal_False;
3126cdf0e10cSrcweir 
3127cdf0e10cSrcweir     // select and cut (through dispatch mechanism)
3128cdf0e10cSrcweir     setSelection( nStartIndex, nEndIndex );
3129cdf0e10cSrcweir     ExecuteAtViewShell( SID_CUT );
3130cdf0e10cSrcweir     return sal_True;
3131cdf0e10cSrcweir }
3132cdf0e10cSrcweir 
pasteText(sal_Int32 nIndex)3133cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::pasteText( sal_Int32 nIndex )
3134cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
3135cdf0e10cSrcweir {
3136cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleEditableText );
3137cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
3138cdf0e10cSrcweir 
3139cdf0e10cSrcweir 	if( !IsEditableState() )
3140cdf0e10cSrcweir 		return sal_False;
3141cdf0e10cSrcweir 
3142cdf0e10cSrcweir     // select and paste (through dispatch mechanism)
3143cdf0e10cSrcweir     setSelection( nIndex, nIndex );
3144cdf0e10cSrcweir     ExecuteAtViewShell( SID_PASTE );
3145cdf0e10cSrcweir     return sal_True;
3146cdf0e10cSrcweir }
3147cdf0e10cSrcweir 
deleteText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)3148cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
3149cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
3150cdf0e10cSrcweir {
3151cdf0e10cSrcweir     return replaceText( nStartIndex, nEndIndex, ::rtl::OUString() );
3152cdf0e10cSrcweir }
3153cdf0e10cSrcweir 
insertText(const::rtl::OUString & sText,sal_Int32 nIndex)3154cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::insertText( const ::rtl::OUString& sText, sal_Int32 nIndex )
3155cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
3156cdf0e10cSrcweir {
3157cdf0e10cSrcweir     return replaceText( nIndex, nIndex, sText );
3158cdf0e10cSrcweir }
3159cdf0e10cSrcweir 
replaceText(sal_Int32 nStartIndex,sal_Int32 nEndIndex,const::rtl::OUString & sReplacement)3160cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::replaceText(
3161cdf0e10cSrcweir     sal_Int32 nStartIndex, sal_Int32 nEndIndex,
3162cdf0e10cSrcweir     const ::rtl::OUString& sReplacement )
3163cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
3164cdf0e10cSrcweir {
3165cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
3166cdf0e10cSrcweir 
3167cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleEditableText );
3168cdf0e10cSrcweir 
3169cdf0e10cSrcweir     const ::rtl::OUString& rText = GetString();
3170cdf0e10cSrcweir 
3171cdf0e10cSrcweir     if( IsValidRange( nStartIndex, nEndIndex, rText.getLength() ) )
3172cdf0e10cSrcweir     {
3173cdf0e10cSrcweir 		if( !IsEditableState() )
3174cdf0e10cSrcweir 			return sal_False;
3175cdf0e10cSrcweir 
3176cdf0e10cSrcweir         SwTxtNode* pNode = const_cast<SwTxtNode*>( GetTxtNode() );
3177cdf0e10cSrcweir 
3178cdf0e10cSrcweir         // translate positions
3179cdf0e10cSrcweir         sal_uInt16 nStart, nEnd;
3180cdf0e10cSrcweir         sal_Bool bSuccess = GetPortionData().GetEditableRange(
3181cdf0e10cSrcweir                                         nStartIndex, nEndIndex, nStart, nEnd );
3182cdf0e10cSrcweir 
3183cdf0e10cSrcweir         // edit only if the range is editable
3184cdf0e10cSrcweir         if( bSuccess )
3185cdf0e10cSrcweir         {
3186cdf0e10cSrcweir             // create SwPosition for nStartIndex
3187cdf0e10cSrcweir             SwIndex aIndex( pNode, nStart );
3188cdf0e10cSrcweir             SwPosition aStartPos( *pNode, aIndex );
3189cdf0e10cSrcweir 
3190cdf0e10cSrcweir             // create SwPosition for nEndIndex
3191cdf0e10cSrcweir             SwPosition aEndPos( aStartPos );
3192cdf0e10cSrcweir             aEndPos.nContent = nEnd;
3193cdf0e10cSrcweir 
3194cdf0e10cSrcweir             // now create XTextRange as helper and set string
3195cdf0e10cSrcweir             const uno::Reference<text::XTextRange> xRange(
3196cdf0e10cSrcweir                 SwXTextRange::CreateXTextRange(
3197cdf0e10cSrcweir                     *pNode->GetDoc(), aStartPos, &aEndPos));
3198cdf0e10cSrcweir             xRange->setString(sReplacement);
3199cdf0e10cSrcweir 
3200cdf0e10cSrcweir             // delete portion data
3201cdf0e10cSrcweir             ClearPortionData();
3202cdf0e10cSrcweir         }
3203cdf0e10cSrcweir 
3204cdf0e10cSrcweir         return bSuccess;
3205cdf0e10cSrcweir     }
3206cdf0e10cSrcweir     else
3207cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
3208cdf0e10cSrcweir }
3209cdf0e10cSrcweir 
3210cdf0e10cSrcweir 
setAttributes(sal_Int32 nStartIndex,sal_Int32 nEndIndex,const uno::Sequence<PropertyValue> & rAttributeSet)3211cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::setAttributes(
3212cdf0e10cSrcweir     sal_Int32 nStartIndex,
3213cdf0e10cSrcweir     sal_Int32 nEndIndex,
3214cdf0e10cSrcweir     const uno::Sequence<PropertyValue>& rAttributeSet )
3215cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
3216cdf0e10cSrcweir {
3217cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
3218cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleEditableText );
3219cdf0e10cSrcweir 
3220cdf0e10cSrcweir     const ::rtl::OUString& rText = GetString();
3221cdf0e10cSrcweir 
3222cdf0e10cSrcweir     if( ! IsValidRange( nStartIndex, nEndIndex, rText.getLength() ) )
3223cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
3224cdf0e10cSrcweir 
3225cdf0e10cSrcweir 	if( !IsEditableState() )
3226cdf0e10cSrcweir 		return sal_False;
3227cdf0e10cSrcweir 
3228cdf0e10cSrcweir 
3229cdf0e10cSrcweir     // create a (dummy) text portion for the sole purpose of calling
3230cdf0e10cSrcweir     // setPropertyValue on it
3231cdf0e10cSrcweir     uno::Reference<XMultiPropertySet> xPortion = CreateUnoPortion( nStartIndex,
3232cdf0e10cSrcweir                                                               nEndIndex );
3233cdf0e10cSrcweir 
3234cdf0e10cSrcweir     // build sorted index array
3235cdf0e10cSrcweir     sal_Int32 nLength = rAttributeSet.getLength();
3236cdf0e10cSrcweir     const PropertyValue* pPairs = rAttributeSet.getConstArray();
3237cdf0e10cSrcweir     sal_Int32* pIndices = new sal_Int32[nLength];
3238cdf0e10cSrcweir     sal_Int32 i;
3239cdf0e10cSrcweir     for( i = 0; i < nLength; i++ )
3240cdf0e10cSrcweir         pIndices[i] = i;
3241cdf0e10cSrcweir     sort( &pIndices[0], &pIndices[nLength], IndexCompare(pPairs) );
3242cdf0e10cSrcweir 
3243cdf0e10cSrcweir     // create sorted sequences accoring to index array
3244cdf0e10cSrcweir     uno::Sequence< ::rtl::OUString > aNames( nLength );
3245cdf0e10cSrcweir     ::rtl::OUString* pNames = aNames.getArray();
3246cdf0e10cSrcweir     uno::Sequence< uno::Any > aValues( nLength );
3247cdf0e10cSrcweir     uno::Any* pValues = aValues.getArray();
3248cdf0e10cSrcweir     for( i = 0; i < nLength; i++ )
3249cdf0e10cSrcweir     {
3250cdf0e10cSrcweir         const PropertyValue& rVal = pPairs[pIndices[i]];
3251cdf0e10cSrcweir         pNames[i]  = rVal.Name;
3252cdf0e10cSrcweir         pValues[i] = rVal.Value;
3253cdf0e10cSrcweir     }
3254cdf0e10cSrcweir     delete[] pIndices;
3255cdf0e10cSrcweir 
3256cdf0e10cSrcweir     // now set the values
3257cdf0e10cSrcweir     sal_Bool bRet = sal_True;
3258cdf0e10cSrcweir     try
3259cdf0e10cSrcweir     {
3260cdf0e10cSrcweir         xPortion->setPropertyValues( aNames, aValues );
3261cdf0e10cSrcweir     }
3262cdf0e10cSrcweir     catch( UnknownPropertyException e )
3263cdf0e10cSrcweir     {
3264cdf0e10cSrcweir         // error handling through return code!
3265cdf0e10cSrcweir         bRet = sal_False;
3266cdf0e10cSrcweir     }
3267cdf0e10cSrcweir 
3268cdf0e10cSrcweir     return bRet;
3269cdf0e10cSrcweir }
3270cdf0e10cSrcweir 
setText(const::rtl::OUString & sText)3271cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::setText( const ::rtl::OUString& sText )
3272cdf0e10cSrcweir     throw (uno::RuntimeException)
3273cdf0e10cSrcweir {
3274cdf0e10cSrcweir     return replaceText(0, GetString().getLength(), sText);
3275cdf0e10cSrcweir }
3276cdf0e10cSrcweir 
3277cdf0e10cSrcweir //=====  XAccessibleSelection  ============================================
3278cdf0e10cSrcweir 
selectAccessibleChild(sal_Int32 nChildIndex)3279cdf0e10cSrcweir void SwAccessibleParagraph::selectAccessibleChild(
3280cdf0e10cSrcweir     sal_Int32 nChildIndex )
3281cdf0e10cSrcweir     throw ( lang::IndexOutOfBoundsException,
3282cdf0e10cSrcweir             uno::RuntimeException )
3283cdf0e10cSrcweir {
3284cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleSelection );
3285cdf0e10cSrcweir 
3286cdf0e10cSrcweir     aSelectionHelper.selectAccessibleChild(nChildIndex);
3287cdf0e10cSrcweir }
3288cdf0e10cSrcweir 
isAccessibleChildSelected(sal_Int32 nChildIndex)3289cdf0e10cSrcweir sal_Bool SwAccessibleParagraph::isAccessibleChildSelected(
3290cdf0e10cSrcweir     sal_Int32 nChildIndex )
3291cdf0e10cSrcweir     throw ( lang::IndexOutOfBoundsException,
3292cdf0e10cSrcweir             uno::RuntimeException )
3293cdf0e10cSrcweir {
3294cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleSelection );
3295cdf0e10cSrcweir 
3296cdf0e10cSrcweir     return aSelectionHelper.isAccessibleChildSelected(nChildIndex);
3297cdf0e10cSrcweir }
3298cdf0e10cSrcweir 
clearAccessibleSelection()3299cdf0e10cSrcweir void SwAccessibleParagraph::clearAccessibleSelection(  )
3300cdf0e10cSrcweir     throw ( uno::RuntimeException )
3301cdf0e10cSrcweir {
3302cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleSelection );
3303cdf0e10cSrcweir 
3304cdf0e10cSrcweir     aSelectionHelper.clearAccessibleSelection();
3305cdf0e10cSrcweir }
3306cdf0e10cSrcweir 
selectAllAccessibleChildren()3307cdf0e10cSrcweir void SwAccessibleParagraph::selectAllAccessibleChildren(  )
3308cdf0e10cSrcweir     throw ( uno::RuntimeException )
3309cdf0e10cSrcweir {
3310cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleSelection );
3311cdf0e10cSrcweir 
3312cdf0e10cSrcweir     aSelectionHelper.selectAllAccessibleChildren();
3313cdf0e10cSrcweir }
3314cdf0e10cSrcweir 
getSelectedAccessibleChildCount()3315cdf0e10cSrcweir sal_Int32 SwAccessibleParagraph::getSelectedAccessibleChildCount(  )
3316cdf0e10cSrcweir     throw ( uno::RuntimeException )
3317cdf0e10cSrcweir {
3318cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleSelection );
3319cdf0e10cSrcweir 
3320cdf0e10cSrcweir     return aSelectionHelper.getSelectedAccessibleChildCount();
3321cdf0e10cSrcweir }
3322cdf0e10cSrcweir 
getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)3323cdf0e10cSrcweir uno::Reference<XAccessible> SwAccessibleParagraph::getSelectedAccessibleChild(
3324cdf0e10cSrcweir     sal_Int32 nSelectedChildIndex )
3325cdf0e10cSrcweir     throw ( lang::IndexOutOfBoundsException,
3326cdf0e10cSrcweir             uno::RuntimeException)
3327cdf0e10cSrcweir {
3328cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleSelection );
3329cdf0e10cSrcweir 
3330cdf0e10cSrcweir     return aSelectionHelper.getSelectedAccessibleChild(nSelectedChildIndex);
3331cdf0e10cSrcweir }
3332cdf0e10cSrcweir 
3333cdf0e10cSrcweir // --> OD 2004-11-16 #111714# - index has to be treated as global child index.
deselectAccessibleChild(sal_Int32 nChildIndex)3334cdf0e10cSrcweir void SwAccessibleParagraph::deselectAccessibleChild(
3335cdf0e10cSrcweir     sal_Int32 nChildIndex )
3336cdf0e10cSrcweir     throw ( lang::IndexOutOfBoundsException,
3337cdf0e10cSrcweir             uno::RuntimeException )
3338cdf0e10cSrcweir {
3339cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleSelection );
3340cdf0e10cSrcweir 
3341cdf0e10cSrcweir     aSelectionHelper.deselectAccessibleChild( nChildIndex );
3342cdf0e10cSrcweir }
3343cdf0e10cSrcweir 
3344cdf0e10cSrcweir //=====  XAccessibleHypertext  ============================================
3345cdf0e10cSrcweir 
3346cdf0e10cSrcweir class SwHyperlinkIter_Impl
3347cdf0e10cSrcweir {
3348cdf0e10cSrcweir 	const SwpHints *pHints;
3349cdf0e10cSrcweir 	xub_StrLen nStt;
3350cdf0e10cSrcweir 	xub_StrLen nEnd;
3351cdf0e10cSrcweir 	sal_uInt16 nPos;
3352cdf0e10cSrcweir 
3353cdf0e10cSrcweir public:
3354cdf0e10cSrcweir 	SwHyperlinkIter_Impl( const SwTxtFrm *pTxtFrm );
3355cdf0e10cSrcweir 	const SwTxtAttr *next();
getCurrHintPos() const3356cdf0e10cSrcweir 	sal_uInt16 getCurrHintPos() const { return nPos-1; }
3357cdf0e10cSrcweir 
startIdx() const3358cdf0e10cSrcweir 	xub_StrLen startIdx() const { return nStt; }
endIdx() const3359cdf0e10cSrcweir 	xub_StrLen endIdx() const { return nEnd; }
3360cdf0e10cSrcweir };
3361cdf0e10cSrcweir 
SwHyperlinkIter_Impl(const SwTxtFrm * pTxtFrm)3362cdf0e10cSrcweir SwHyperlinkIter_Impl::SwHyperlinkIter_Impl( const SwTxtFrm *pTxtFrm ) :
3363cdf0e10cSrcweir 	pHints( pTxtFrm->GetTxtNode()->GetpSwpHints() ),
3364cdf0e10cSrcweir 	nStt( pTxtFrm->GetOfst() ),
3365cdf0e10cSrcweir 	nPos( 0 )
3366cdf0e10cSrcweir {
3367cdf0e10cSrcweir 	const SwTxtFrm *pFollFrm = pTxtFrm->GetFollow();
3368cdf0e10cSrcweir 	nEnd = pFollFrm ? pFollFrm->GetOfst() : pTxtFrm->GetTxtNode()->Len();
3369cdf0e10cSrcweir }
3370cdf0e10cSrcweir 
next()3371cdf0e10cSrcweir const SwTxtAttr *SwHyperlinkIter_Impl::next()
3372cdf0e10cSrcweir {
3373cdf0e10cSrcweir 	const SwTxtAttr *pAttr = 0;
3374cdf0e10cSrcweir 	if( pHints )
3375cdf0e10cSrcweir 	{
3376cdf0e10cSrcweir 		while( !pAttr && nPos < pHints->Count() )
3377cdf0e10cSrcweir 		{
3378cdf0e10cSrcweir 			const SwTxtAttr *pHt = (*pHints)[nPos];
3379cdf0e10cSrcweir 			if( RES_TXTATR_INETFMT == pHt->Which() )
3380cdf0e10cSrcweir 			{
3381cdf0e10cSrcweir 				xub_StrLen nHtStt = *pHt->GetStart();
3382cdf0e10cSrcweir 				xub_StrLen nHtEnd = *pHt->GetAnyEnd();
3383cdf0e10cSrcweir 				if( nHtEnd > nHtStt &&
3384cdf0e10cSrcweir 					( (nHtStt >= nStt && nHtStt < nEnd) ||
3385cdf0e10cSrcweir 					  (nHtEnd > nStt && nHtEnd <= nEnd) ) )
3386cdf0e10cSrcweir 				{
3387cdf0e10cSrcweir 					pAttr = pHt;
3388cdf0e10cSrcweir 				}
3389cdf0e10cSrcweir 			}
3390cdf0e10cSrcweir 			++nPos;
3391cdf0e10cSrcweir 		}
3392cdf0e10cSrcweir 	}
3393cdf0e10cSrcweir 
3394cdf0e10cSrcweir 	return pAttr;
3395cdf0e10cSrcweir };
3396cdf0e10cSrcweir 
getHyperLinkCount()3397cdf0e10cSrcweir sal_Int32 SAL_CALL SwAccessibleParagraph::getHyperLinkCount()
3398cdf0e10cSrcweir     throw (uno::RuntimeException)
3399cdf0e10cSrcweir {
3400cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
3401cdf0e10cSrcweir 
3402cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleHypertext );
3403cdf0e10cSrcweir 
3404cdf0e10cSrcweir 	sal_Int32 nCount = 0;
3405cdf0e10cSrcweir     // --> OD 2007-06-27 #i77108# - provide hyperlinks also in editable documents.
3406cdf0e10cSrcweir //    if( !IsEditableState() )
3407cdf0e10cSrcweir     // <--
3408cdf0e10cSrcweir 	{
3409cdf0e10cSrcweir 		const SwTxtFrm *pTxtFrm = static_cast<const SwTxtFrm*>( GetFrm() );
3410cdf0e10cSrcweir 		SwHyperlinkIter_Impl aIter( pTxtFrm );
3411cdf0e10cSrcweir 		while( aIter.next() )
3412cdf0e10cSrcweir 			nCount++;
3413cdf0e10cSrcweir 	}
3414cdf0e10cSrcweir 
3415cdf0e10cSrcweir 	return nCount;
3416cdf0e10cSrcweir }
3417cdf0e10cSrcweir 
3418cdf0e10cSrcweir uno::Reference< XAccessibleHyperlink > SAL_CALL
getHyperLink(sal_Int32 nLinkIndex)3419cdf0e10cSrcweir 	SwAccessibleParagraph::getHyperLink( sal_Int32 nLinkIndex )
3420cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
3421cdf0e10cSrcweir {
3422cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
3423cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleHypertext );
3424cdf0e10cSrcweir 
3425cdf0e10cSrcweir     uno::Reference< XAccessibleHyperlink > xRet;
3426cdf0e10cSrcweir 
3427cdf0e10cSrcweir     // --> OD 2007-06-27 #i77108# - provide hyperlinks also in editable documents.
3428cdf0e10cSrcweir //    if( !IsEditableState() )
3429ca62e2c2SSteve Yin 	const SwTxtFrm *pTxtFrm = static_cast<const SwTxtFrm*>( GetFrm() );
3430ca62e2c2SSteve Yin 	SwHyperlinkIter_Impl aHIter( pTxtFrm );
3431ca62e2c2SSteve Yin 	//SwAccessibleAutoRecognizerHelper_Impl aARHelper( pTxtFrm );
3432ca62e2c2SSteve Yin 	sal_Int32 nARCount = 0;
3433ca62e2c2SSteve Yin 	sal_Int32 nARIndex = 0;
3434ca62e2c2SSteve Yin 	sal_Int32 nTIndex = -1;
3435ca62e2c2SSteve Yin 	sal_Int32 nTOCEndIndex = -1;
3436ca62e2c2SSteve Yin 	SwTxtNode* pNode = NULL;
3437ca62e2c2SSteve Yin 	SwTOXSortTabBase* pTBase = GetTOXSortTabBase();
3438ca62e2c2SSteve Yin 	if( pTBase )
3439cdf0e10cSrcweir 	{
3440ca62e2c2SSteve Yin 		pNode = const_cast<SwTxtNode*>(GetTxtNode());
3441ca62e2c2SSteve Yin 	}
3442ca62e2c2SSteve Yin 	nTOCEndIndex = -1;
3443ca62e2c2SSteve Yin 	SwTxtAttr* pHt = (SwTxtAttr*)(aHIter.next());
3444ca62e2c2SSteve Yin 	while( (nLinkIndex < getHyperLinkCount()) && nTIndex < nLinkIndex)
3445ca62e2c2SSteve Yin 	{
3446ca62e2c2SSteve Yin 		// no candidates, exit
3447ca62e2c2SSteve Yin 		//if( (!pHt) && (nARIndex >= nARCount) && nTOCEndIndex <= 0)
3448ca62e2c2SSteve Yin 		//	break;
3449ca62e2c2SSteve Yin 
3450ca62e2c2SSteve Yin 		sal_Int32 nHStt = -1;
3451ca62e2c2SSteve Yin 		sal_Int32 nAStt = -1;
3452ca62e2c2SSteve Yin 		sal_Bool bH = sal_False;
3453ca62e2c2SSteve Yin 		sal_Bool bA = sal_False;
3454ca62e2c2SSteve Yin 
3455ca62e2c2SSteve Yin 
3456ca62e2c2SSteve Yin 		if( pHt )
3457ca62e2c2SSteve Yin 			nHStt = *pHt->GetStart();
3458ca62e2c2SSteve Yin 		if( nARIndex < nARCount )
3459ca62e2c2SSteve Yin 		{
3460ca62e2c2SSteve Yin 			/*
3461ca62e2c2SSteve Yin 			sal_Int32 nAEnd;
3462ca62e2c2SSteve Yin 			aARHelper.getPosition( nARIndex, nAStt, nAEnd );
3463ca62e2c2SSteve Yin 			*/
3464ca62e2c2SSteve Yin 		}
3465ca62e2c2SSteve Yin 		sal_Bool bTOC = sal_False;
3466ca62e2c2SSteve Yin 		// Inside TOC & get the first link
3467ca62e2c2SSteve Yin 		if( pTBase && nTIndex == -1 )
3468ca62e2c2SSteve Yin 		{
3469ca62e2c2SSteve Yin 			nTIndex++;
3470ca62e2c2SSteve Yin 			bTOC = sal_True;
3471ca62e2c2SSteve Yin 		}
3472ca62e2c2SSteve Yin 		else
3473ca62e2c2SSteve Yin 		{
3474ca62e2c2SSteve Yin 			if( nHStt >=0 && nAStt >=0 )
3475ca62e2c2SSteve Yin 			{	// both hyperlink and smart tag available
3476ca62e2c2SSteve Yin 				nTIndex++;
3477ca62e2c2SSteve Yin 				if( nHStt <= nAStt )
3478ca62e2c2SSteve Yin 					bH = sal_True;
3479ca62e2c2SSteve Yin 				else
3480ca62e2c2SSteve Yin 					bA = sal_True;
3481ca62e2c2SSteve Yin 			}
3482ca62e2c2SSteve Yin 			else if( nHStt >= 0 )
3483ca62e2c2SSteve Yin 			{	// only hyperlink available
3484ca62e2c2SSteve Yin 				nTIndex++;
3485ca62e2c2SSteve Yin 				bH = sal_True;
3486ca62e2c2SSteve Yin 			}
3487ca62e2c2SSteve Yin 			else if( nAStt >= 0 )
3488ca62e2c2SSteve Yin 			{	// only smart tag available
3489ca62e2c2SSteve Yin 				nTIndex++;
3490ca62e2c2SSteve Yin 				bA = sal_True;
3491ca62e2c2SSteve Yin 			}
3492ca62e2c2SSteve Yin 		}
3493ca62e2c2SSteve Yin 
3494ca62e2c2SSteve Yin 		if( nTIndex == nLinkIndex )
3495ca62e2c2SSteve Yin 		{	// found
3496ca62e2c2SSteve Yin 			if( bH )
3497ca62e2c2SSteve Yin 			{	// it's a hyperlink
3498ca62e2c2SSteve Yin 				if( pHt )
3499ca62e2c2SSteve Yin 				{
3500ca62e2c2SSteve Yin //                    const SwField* pFFld = pHt->GetFld().GetFld();
3501ca62e2c2SSteve Yin                     {
3502ca62e2c2SSteve Yin 						if( !pHyperTextData )
3503ca62e2c2SSteve Yin 							pHyperTextData = new SwAccessibleHyperTextData;
3504ca62e2c2SSteve Yin 						SwAccessibleHyperTextData::iterator aIter =
3505ca62e2c2SSteve Yin 							pHyperTextData ->find( pHt );
3506ca62e2c2SSteve Yin 						if( aIter != pHyperTextData->end() )
3507ca62e2c2SSteve Yin 						{
3508ca62e2c2SSteve Yin 							xRet = (*aIter).second;
3509ca62e2c2SSteve Yin 						}
3510ca62e2c2SSteve Yin 						if( !xRet.is() )
3511ca62e2c2SSteve Yin 						{
3512ca62e2c2SSteve Yin                             {
3513ca62e2c2SSteve Yin                                 const sal_Int32 nTmpHStt= GetPortionData().GetAccessiblePosition(
3514ca62e2c2SSteve Yin                                     max( aHIter.startIdx(), *pHt->GetStart() ) );
3515ca62e2c2SSteve Yin                                 const sal_Int32 nTmpHEnd= GetPortionData().GetAccessiblePosition(
3516ca62e2c2SSteve Yin                                     min( aHIter.endIdx(), *pHt->GetAnyEnd() ) );
3517ca62e2c2SSteve Yin                                 xRet = new SwAccessibleHyperlink( aHIter.getCurrHintPos(),
3518ca62e2c2SSteve Yin                                     this, nTmpHStt, nTmpHEnd );
3519ca62e2c2SSteve Yin                             }
3520ca62e2c2SSteve Yin 							if( aIter != pHyperTextData->end() )
3521ca62e2c2SSteve Yin 							{
3522ca62e2c2SSteve Yin 								(*aIter).second = xRet;
3523ca62e2c2SSteve Yin 							}
3524ca62e2c2SSteve Yin 							else
3525ca62e2c2SSteve Yin 							{
3526ca62e2c2SSteve Yin 								SwAccessibleHyperTextData::value_type aEntry( pHt, xRet );
3527ca62e2c2SSteve Yin 								pHyperTextData->insert( aEntry );
3528ca62e2c2SSteve Yin 							}
3529ca62e2c2SSteve Yin 						}
3530ca62e2c2SSteve Yin 					}
3531ca62e2c2SSteve Yin 				}
3532ca62e2c2SSteve Yin 			}
3533ca62e2c2SSteve Yin 			else if( bTOC )
3534ca62e2c2SSteve Yin 			{
3535ca62e2c2SSteve Yin 				//xRet = new SwAccessibleTOCLink( this );
3536ca62e2c2SSteve Yin 			}
3537ca62e2c2SSteve Yin 			else if( bA )
3538ca62e2c2SSteve Yin 			{
3539ca62e2c2SSteve Yin 				/*
3540ca62e2c2SSteve Yin 				// it's a smart tag
3541ca62e2c2SSteve Yin 				if( !pAutoRecognizerData )
3542ca62e2c2SSteve Yin 					pAutoRecognizerData = new SwAccessibleAutoRecognizerData;
3543ca62e2c2SSteve Yin 				SwAccessibleAutoRecognizerData::iterator aIter =
3544ca62e2c2SSteve Yin 					pAutoRecognizerData ->find( nARIndex );
3545ca62e2c2SSteve Yin 				if( aIter != pAutoRecognizerData->end() )
3546ca62e2c2SSteve Yin 				{
3547ca62e2c2SSteve Yin 					xRet = (*aIter).second;
3548ca62e2c2SSteve Yin 				}
3549ca62e2c2SSteve Yin 				if( !xRet.is() )
3550ca62e2c2SSteve Yin 				{
3551ca62e2c2SSteve Yin 					sal_Int32 nAStt = 0;
3552ca62e2c2SSteve Yin 					sal_Int32 nAEnd = 0;
3553ca62e2c2SSteve Yin 					//aARHelper.getPosition( nARIndex, nAStt, nAEnd );
3554ca62e2c2SSteve Yin 					xRet = new SwAccessibleAutoRecognizer( this, nAStt, nAEnd );
3555ca62e2c2SSteve Yin 					if( aIter != pAutoRecognizerData->end() )
3556ca62e2c2SSteve Yin 					{
3557ca62e2c2SSteve Yin 						(*aIter).second = xRet;
3558ca62e2c2SSteve Yin 					}
3559ca62e2c2SSteve Yin 					else
3560ca62e2c2SSteve Yin 					{
3561ca62e2c2SSteve Yin 						SwAccessibleAutoRecognizerData::value_type aEntry( nARIndex, xRet );
3562ca62e2c2SSteve Yin 						pAutoRecognizerData->insert( aEntry );
3563ca62e2c2SSteve Yin 					}
3564ca62e2c2SSteve Yin 				}
3565ca62e2c2SSteve Yin 				*/
3566ca62e2c2SSteve Yin 			}
3567ca62e2c2SSteve Yin 			break;
3568ca62e2c2SSteve Yin 		}
3569ca62e2c2SSteve Yin 
3570ca62e2c2SSteve Yin 		// iterate next
3571ca62e2c2SSteve Yin 		if( bH )
3572ca62e2c2SSteve Yin 			// iterate next hyperlink
3573ca62e2c2SSteve Yin 			pHt = (SwTxtAttr*)(aHIter.next());
3574ca62e2c2SSteve Yin 		else if( bA )
3575ca62e2c2SSteve Yin 			// iterate next smart tag
3576ca62e2c2SSteve Yin 			nARIndex++;
3577ca62e2c2SSteve Yin 		else if(bTOC)
3578ca62e2c2SSteve Yin 			continue;
3579ca62e2c2SSteve Yin 		else
3580ca62e2c2SSteve Yin 			// no candidate, exit
3581ca62e2c2SSteve Yin 			break;
3582ca62e2c2SSteve Yin 	}
3583ca62e2c2SSteve Yin 	/*
3584cdf0e10cSrcweir 		const SwTxtFrm *pTxtFrm = static_cast<const SwTxtFrm*>( GetFrm() );
3585cdf0e10cSrcweir 		SwHyperlinkIter_Impl aHIter( pTxtFrm );
3586cdf0e10cSrcweir 		while( nLinkIndex-- )
3587cdf0e10cSrcweir 			aHIter.next();
3588cdf0e10cSrcweir 
3589cdf0e10cSrcweir 		const SwTxtAttr *pHt = aHIter.next();
3590cdf0e10cSrcweir 		if( pHt )
3591cdf0e10cSrcweir 		{
3592cdf0e10cSrcweir 			if( !pHyperTextData )
3593cdf0e10cSrcweir 				pHyperTextData = new SwAccessibleHyperTextData;
3594cdf0e10cSrcweir 			SwAccessibleHyperTextData::iterator aIter =
3595cdf0e10cSrcweir 				pHyperTextData ->find( pHt );
3596cdf0e10cSrcweir 			if( aIter != pHyperTextData->end() )
3597cdf0e10cSrcweir 			{
3598cdf0e10cSrcweir 				xRet = (*aIter).second;
3599cdf0e10cSrcweir 			}
3600cdf0e10cSrcweir 			if( !xRet.is() )
3601cdf0e10cSrcweir 			{
3602cdf0e10cSrcweir 				sal_Int32 nHStt= GetPortionData().GetAccessiblePosition(
3603cdf0e10cSrcweir 								max( aHIter.startIdx(), *pHt->GetStart() ) );
3604cdf0e10cSrcweir 				sal_Int32 nHEnd= GetPortionData().GetAccessiblePosition(
3605cdf0e10cSrcweir 								min( aHIter.endIdx(), *pHt->GetAnyEnd() ) );
3606cdf0e10cSrcweir 				xRet = new SwAccessibleHyperlink( aHIter.getCurrHintPos(),
3607cdf0e10cSrcweir 												  this, nHStt, nHEnd );
3608cdf0e10cSrcweir 				if( aIter != pHyperTextData->end() )
3609cdf0e10cSrcweir 				{
3610cdf0e10cSrcweir 					(*aIter).second = xRet;
3611cdf0e10cSrcweir 				}
3612cdf0e10cSrcweir 				else
3613cdf0e10cSrcweir 				{
3614cdf0e10cSrcweir 					SwAccessibleHyperTextData::value_type aEntry( pHt, xRet );
3615cdf0e10cSrcweir 					pHyperTextData->insert( aEntry );
3616cdf0e10cSrcweir 				}
3617cdf0e10cSrcweir 			}
3618cdf0e10cSrcweir 		}
3619cdf0e10cSrcweir 	}
3620ca62e2c2SSteve Yin 	*/
3621cdf0e10cSrcweir 	if( !xRet.is() )
3622cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
3623cdf0e10cSrcweir 
3624cdf0e10cSrcweir 	return xRet;
3625cdf0e10cSrcweir }
3626cdf0e10cSrcweir 
getHyperLinkIndex(sal_Int32 nCharIndex)3627cdf0e10cSrcweir sal_Int32 SAL_CALL SwAccessibleParagraph::getHyperLinkIndex( sal_Int32 nCharIndex )
3628cdf0e10cSrcweir     throw (lang::IndexOutOfBoundsException, uno::RuntimeException)
3629cdf0e10cSrcweir {
3630cdf0e10cSrcweir 	vos::OGuard aGuard(Application::GetSolarMutex());
3631cdf0e10cSrcweir 	CHECK_FOR_DEFUNC( XAccessibleHypertext );
3632cdf0e10cSrcweir 
3633cdf0e10cSrcweir     // parameter checking
3634cdf0e10cSrcweir     sal_Int32 nLength = GetString().getLength();
3635cdf0e10cSrcweir     if ( ! IsValidPosition( nCharIndex, nLength ) )
3636cdf0e10cSrcweir     {
3637cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
3638cdf0e10cSrcweir     }
3639cdf0e10cSrcweir 
3640cdf0e10cSrcweir 	sal_Int32 nRet = -1;
3641cdf0e10cSrcweir     // --> OD 2007-06-27 #i77108# - provide hyperlinks also in editable documents.
3642cdf0e10cSrcweir //    if( !IsEditableState() )
3643cdf0e10cSrcweir     // <--
3644cdf0e10cSrcweir 	{
3645cdf0e10cSrcweir 		const SwTxtFrm *pTxtFrm = static_cast<const SwTxtFrm*>( GetFrm() );
3646cdf0e10cSrcweir 		SwHyperlinkIter_Impl aHIter( pTxtFrm );
3647cdf0e10cSrcweir 
3648cdf0e10cSrcweir 		xub_StrLen nIdx = GetPortionData().GetModelPosition( nCharIndex );
3649cdf0e10cSrcweir 		sal_Int32 nPos = 0;
3650cdf0e10cSrcweir 		const SwTxtAttr *pHt = aHIter.next();
3651cdf0e10cSrcweir 		while( pHt && !(nIdx >= *pHt->GetStart() && nIdx < *pHt->GetAnyEnd()) )
3652cdf0e10cSrcweir 		{
3653cdf0e10cSrcweir 			pHt = aHIter.next();
3654cdf0e10cSrcweir 			nPos++;
3655cdf0e10cSrcweir 		}
3656cdf0e10cSrcweir 
3657cdf0e10cSrcweir 		if( pHt )
3658cdf0e10cSrcweir 			nRet = nPos;
3659cdf0e10cSrcweir 	}
3660cdf0e10cSrcweir 
3661ca62e2c2SSteve Yin 	if (nRet == -1)
3662ca62e2c2SSteve Yin 		throw lang::IndexOutOfBoundsException();
3663ca62e2c2SSteve Yin 	else
3664cdf0e10cSrcweir 		return nRet;
3665ca62e2c2SSteve Yin 	//return nRet;
3666cdf0e10cSrcweir }
3667cdf0e10cSrcweir 
3668cdf0e10cSrcweir // --> OD 2008-05-26 #i71360#
3669cdf0e10cSrcweir // --> OD 2010-02-22 #i108125# - adjustments for change tracking text markup
getTextMarkupCount(sal_Int32 nTextMarkupType)3670cdf0e10cSrcweir sal_Int32 SAL_CALL SwAccessibleParagraph::getTextMarkupCount( sal_Int32 nTextMarkupType )
3671cdf0e10cSrcweir                                         throw (lang::IllegalArgumentException,
3672cdf0e10cSrcweir                                                uno::RuntimeException)
3673cdf0e10cSrcweir {
3674cdf0e10cSrcweir     std::auto_ptr<SwTextMarkupHelper> pTextMarkupHelper;
3675cdf0e10cSrcweir     switch ( nTextMarkupType )
3676cdf0e10cSrcweir     {
3677cdf0e10cSrcweir         case text::TextMarkupType::TRACK_CHANGE_INSERTION:
3678cdf0e10cSrcweir         case text::TextMarkupType::TRACK_CHANGE_DELETION:
3679cdf0e10cSrcweir         case text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE:
3680cdf0e10cSrcweir         {
3681cdf0e10cSrcweir             pTextMarkupHelper.reset( new SwTextMarkupHelper(
3682cdf0e10cSrcweir                 GetPortionData(),
3683cdf0e10cSrcweir                 *(mpParaChangeTrackInfo->getChangeTrackingTextMarkupList( nTextMarkupType ) )) );
3684cdf0e10cSrcweir         }
3685cdf0e10cSrcweir         break;
3686cdf0e10cSrcweir         default:
3687cdf0e10cSrcweir         {
3688cdf0e10cSrcweir             pTextMarkupHelper.reset( new SwTextMarkupHelper( GetPortionData(), *GetTxtNode() ) );
3689cdf0e10cSrcweir         }
3690cdf0e10cSrcweir     }
3691cdf0e10cSrcweir 
3692cdf0e10cSrcweir     return pTextMarkupHelper->getTextMarkupCount( nTextMarkupType );
3693cdf0e10cSrcweir }
3694ca62e2c2SSteve Yin //MSAA Extension Implementation in app  module
scrollToPosition(const::com::sun::star::awt::Point &,sal_Bool)3695ca62e2c2SSteve Yin sal_Bool SAL_CALL SwAccessibleParagraph::scrollToPosition( const ::com::sun::star::awt::Point&, sal_Bool )
3696ca62e2c2SSteve Yin 	throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
3697ca62e2c2SSteve Yin {
3698ca62e2c2SSteve Yin 	return sal_False;
3699ca62e2c2SSteve Yin }
3700ca62e2c2SSteve Yin 
getSelectedPortionCount()3701ca62e2c2SSteve Yin sal_Int32 SAL_CALL SwAccessibleParagraph::getSelectedPortionCount(  )
3702ca62e2c2SSteve Yin 	throw (::com::sun::star::uno::RuntimeException)
3703ca62e2c2SSteve Yin {
3704ca62e2c2SSteve Yin 	sal_Int32 nSeleted = 0;
3705ca62e2c2SSteve Yin 	SwPaM* pCrsr = GetCursor( true );
3706ca62e2c2SSteve Yin     if( pCrsr != NULL )
3707ca62e2c2SSteve Yin     {
3708ca62e2c2SSteve Yin         // get SwPosition for my node
3709ca62e2c2SSteve Yin         const SwTxtNode* pNode = GetTxtNode();
3710ca62e2c2SSteve Yin         sal_uLong nHere = pNode->GetIndex();
3711ca62e2c2SSteve Yin 
3712ca62e2c2SSteve Yin         // iterate over ring
3713ca62e2c2SSteve Yin         SwPaM* pRingStart = pCrsr;
3714ca62e2c2SSteve Yin         do
3715ca62e2c2SSteve Yin         {
3716ca62e2c2SSteve Yin             // ignore, if no mark
3717ca62e2c2SSteve Yin             if( pCrsr->HasMark() )
3718ca62e2c2SSteve Yin             {
3719ca62e2c2SSteve Yin                 // check whether nHere is 'inside' pCrsr
3720ca62e2c2SSteve Yin                 SwPosition* pStart = pCrsr->Start();
3721ca62e2c2SSteve Yin                 sal_uLong nStartIndex = pStart->nNode.GetIndex();
3722ca62e2c2SSteve Yin                 SwPosition* pEnd = pCrsr->End();
3723ca62e2c2SSteve Yin                 sal_uLong nEndIndex = pEnd->nNode.GetIndex();
3724ca62e2c2SSteve Yin                 if( ( nHere >= nStartIndex ) &&
3725ca62e2c2SSteve Yin                     ( nHere <= nEndIndex )      )
3726ca62e2c2SSteve Yin                 {
3727ca62e2c2SSteve Yin 					nSeleted++;
3728ca62e2c2SSteve Yin                 }
3729ca62e2c2SSteve Yin                 // else: this PaM doesn't point to this paragraph
3730ca62e2c2SSteve Yin             }
3731ca62e2c2SSteve Yin             // else: this PaM is collapsed and doesn't select anything
3732ca62e2c2SSteve Yin 
3733ca62e2c2SSteve Yin             // next PaM in ring
3734ca62e2c2SSteve Yin             pCrsr = static_cast<SwPaM*>( pCrsr->GetNext() );
3735ca62e2c2SSteve Yin         }
3736ca62e2c2SSteve Yin         while( pCrsr != pRingStart );
3737ca62e2c2SSteve Yin     }
3738ca62e2c2SSteve Yin 	return nSeleted;
3739ca62e2c2SSteve Yin 
3740ca62e2c2SSteve Yin }
3741ca62e2c2SSteve Yin 
getSeletedPositionStart(sal_Int32 nSelectedPortionIndex)3742ca62e2c2SSteve Yin sal_Int32 SAL_CALL SwAccessibleParagraph::getSeletedPositionStart( sal_Int32 nSelectedPortionIndex )
3743ca62e2c2SSteve Yin 	throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
3744ca62e2c2SSteve Yin {
3745ca62e2c2SSteve Yin 	vos::OGuard aGuard(Application::GetSolarMutex());
3746ca62e2c2SSteve Yin 
3747ca62e2c2SSteve Yin 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
3748ca62e2c2SSteve Yin 
3749ca62e2c2SSteve Yin 	sal_Int32 nStart, nEnd;
3750ca62e2c2SSteve Yin     /*sal_Bool bSelected = */GetSelectionAtIndex(nSelectedPortionIndex, nStart, nEnd );
3751ca62e2c2SSteve Yin 	return nStart;
3752ca62e2c2SSteve Yin }
3753ca62e2c2SSteve Yin 
getSeletedPositionEnd(sal_Int32 nSelectedPortionIndex)3754ca62e2c2SSteve Yin sal_Int32 SAL_CALL SwAccessibleParagraph::getSeletedPositionEnd( sal_Int32 nSelectedPortionIndex )
3755ca62e2c2SSteve Yin 	throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
3756ca62e2c2SSteve Yin {
3757ca62e2c2SSteve Yin 	vos::OGuard aGuard(Application::GetSolarMutex());
3758ca62e2c2SSteve Yin 
3759ca62e2c2SSteve Yin 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
3760ca62e2c2SSteve Yin 
3761ca62e2c2SSteve Yin 	sal_Int32 nStart, nEnd;
3762ca62e2c2SSteve Yin     /*sal_Bool bSelected = */GetSelectionAtIndex(nSelectedPortionIndex, nStart, nEnd );
3763ca62e2c2SSteve Yin 	return nEnd;
3764ca62e2c2SSteve Yin }
3765ca62e2c2SSteve Yin 
removeSelection(sal_Int32 selectionIndex)3766ca62e2c2SSteve Yin sal_Bool SAL_CALL SwAccessibleParagraph::removeSelection( sal_Int32 selectionIndex )
3767ca62e2c2SSteve Yin 	throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
3768ca62e2c2SSteve Yin {
3769ca62e2c2SSteve Yin 	if(selectionIndex < 0) return sal_False;
3770ca62e2c2SSteve Yin 
3771ca62e2c2SSteve Yin     sal_Bool bRet = sal_False;
3772ca62e2c2SSteve Yin 	sal_Int32 nSelected = selectionIndex;
3773ca62e2c2SSteve Yin 
3774ca62e2c2SSteve Yin     // get the selection, and test whether it affects our text node
3775ca62e2c2SSteve Yin 	SwPaM* pCrsr = GetCursor( true );
3776ca62e2c2SSteve Yin //  SwPaM* pFirst = pCrsr;
3777ca62e2c2SSteve Yin 	SwPaM* pPrev = pCrsr;
3778ca62e2c2SSteve Yin 
3779ca62e2c2SSteve Yin     if( pCrsr != NULL )
3780ca62e2c2SSteve Yin     {
3781ca62e2c2SSteve Yin         // get SwPosition for my node
3782ca62e2c2SSteve Yin         const SwTxtNode* pNode = GetTxtNode();
3783ca62e2c2SSteve Yin         sal_uLong nHere = pNode->GetIndex();
3784ca62e2c2SSteve Yin 
3785ca62e2c2SSteve Yin         // iterate over ring
3786ca62e2c2SSteve Yin         SwPaM* pRingStart = pCrsr;
3787ca62e2c2SSteve Yin         do
3788ca62e2c2SSteve Yin         {
3789ca62e2c2SSteve Yin             // ignore, if no mark
3790ca62e2c2SSteve Yin             if( pCrsr->HasMark() )
3791ca62e2c2SSteve Yin             {
3792ca62e2c2SSteve Yin                 // check whether nHere is 'inside' pCrsr
3793ca62e2c2SSteve Yin                 SwPosition* pStart = pCrsr->Start();
3794ca62e2c2SSteve Yin                 sal_uLong nStartIndex = pStart->nNode.GetIndex();
3795ca62e2c2SSteve Yin                 SwPosition* pEnd = pCrsr->End();
3796ca62e2c2SSteve Yin                 sal_uLong nEndIndex = pEnd->nNode.GetIndex();
3797ca62e2c2SSteve Yin                 if( ( nHere >= nStartIndex ) &&
3798ca62e2c2SSteve Yin                     ( nHere <= nEndIndex )      )
3799ca62e2c2SSteve Yin                 {
3800ca62e2c2SSteve Yin 					if( nSelected == 0 )
3801ca62e2c2SSteve Yin 					{
3802ca62e2c2SSteve Yin 						pCrsr->MoveTo((Ring*)0);
3803ca62e2c2SSteve Yin 						delete pCrsr;
3804ca62e2c2SSteve Yin 						bRet = sal_True;
3805ca62e2c2SSteve Yin 					}
3806ca62e2c2SSteve Yin 					else
3807ca62e2c2SSteve Yin 					{
3808ca62e2c2SSteve Yin 						nSelected--;
3809ca62e2c2SSteve Yin 					}
3810ca62e2c2SSteve Yin 				}
3811ca62e2c2SSteve Yin 			}
3812ca62e2c2SSteve Yin             // else: this PaM is collapsed and doesn't select anything
3813ca62e2c2SSteve Yin 		   pPrev = pCrsr;
3814*e467b8b3SPedro Giffuni            if(!bRet)
3815ca62e2c2SSteve Yin                pCrsr = static_cast<SwPaM*>( pCrsr->GetNext() );
3816ca62e2c2SSteve Yin         }
3817ca62e2c2SSteve Yin         while( !bRet && (pCrsr != pRingStart) );
3818ca62e2c2SSteve Yin 	}
3819ca62e2c2SSteve Yin 	return sal_True;
3820ca62e2c2SSteve Yin }
3821ca62e2c2SSteve Yin 
addSelection(sal_Int32,sal_Int32 startOffset,sal_Int32 endOffset)3822ca62e2c2SSteve Yin sal_Int32 SAL_CALL SwAccessibleParagraph::addSelection( sal_Int32, sal_Int32 startOffset, sal_Int32 endOffset)
3823ca62e2c2SSteve Yin 	throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
3824ca62e2c2SSteve Yin {
3825ca62e2c2SSteve Yin 	vos::OGuard aGuard(Application::GetSolarMutex());
3826ca62e2c2SSteve Yin 
3827ca62e2c2SSteve Yin 	CHECK_FOR_DEFUNC_THIS( XAccessibleText, *this );
3828ca62e2c2SSteve Yin 
3829ca62e2c2SSteve Yin     // parameter checking
3830ca62e2c2SSteve Yin     sal_Int32 nLength = GetString().getLength();
3831ca62e2c2SSteve Yin     if ( ! IsValidRange( startOffset, endOffset, nLength ) )
3832ca62e2c2SSteve Yin     {
3833ca62e2c2SSteve Yin         throw lang::IndexOutOfBoundsException();
3834ca62e2c2SSteve Yin     }
3835ca62e2c2SSteve Yin 
3836ca62e2c2SSteve Yin 	sal_Int32 nSelectedCount = getSelectedPortionCount();
3837ca62e2c2SSteve Yin 	for ( sal_Int32 i = nSelectedCount ; i >= 0 ; i--)
3838ca62e2c2SSteve Yin 	{
3839ca62e2c2SSteve Yin 		sal_Int32 nStart, nEnd;
3840ca62e2c2SSteve Yin 		sal_Bool bSelected = GetSelectionAtIndex(i, nStart, nEnd );
3841ca62e2c2SSteve Yin 		if(bSelected)
3842ca62e2c2SSteve Yin 		{
3843ca62e2c2SSteve Yin 			if(nStart <= nEnd )
3844ca62e2c2SSteve Yin 			{
3845ca62e2c2SSteve Yin 				if (( startOffset>=nStart && startOffset <=nEnd ) ||     //startOffset in a selection
3846ca62e2c2SSteve Yin 			   		( endOffset>=nStart && endOffset <=nEnd )     ||  //endOffset in a selection
3847ca62e2c2SSteve Yin 					( startOffset <= nStart && endOffset >=nEnd)  ||       //start and  end include the old selection
3848ca62e2c2SSteve Yin 					( startOffset >= nStart && endOffset <=nEnd) )
3849ca62e2c2SSteve Yin 				{
3850ca62e2c2SSteve Yin 					removeSelection(i);
3851ca62e2c2SSteve Yin 				}
3852ca62e2c2SSteve Yin 
3853ca62e2c2SSteve Yin 			}
3854ca62e2c2SSteve Yin 			else
3855ca62e2c2SSteve Yin 			{
3856ca62e2c2SSteve Yin 				if (( startOffset>=nEnd && startOffset <=nStart ) ||     //startOffset in a selection
3857ca62e2c2SSteve Yin 			   		( endOffset>=nEnd && endOffset <=nStart )     || //endOffset in a selection
3858ca62e2c2SSteve Yin 					( startOffset <= nStart && endOffset >=nEnd)  ||       //start and  end include the old selection
3859ca62e2c2SSteve Yin 					( startOffset >= nStart && endOffset <=nEnd) )
3860ca62e2c2SSteve Yin 
3861ca62e2c2SSteve Yin 				{
3862ca62e2c2SSteve Yin 					removeSelection(i);
3863ca62e2c2SSteve Yin 				}
3864ca62e2c2SSteve Yin 			}
3865ca62e2c2SSteve Yin 		}
3866ca62e2c2SSteve Yin 
3867ca62e2c2SSteve Yin 	}
3868ca62e2c2SSteve Yin 
3869ca62e2c2SSteve Yin     sal_Bool bRet = sal_False;
3870ca62e2c2SSteve Yin 
3871ca62e2c2SSteve Yin     // get cursor shell
3872ca62e2c2SSteve Yin     SwCrsrShell* pCrsrShell = GetCrsrShell();
3873ca62e2c2SSteve Yin     if( pCrsrShell != NULL )
3874ca62e2c2SSteve Yin     {
3875ca62e2c2SSteve Yin         // create pam for selection
3876ca62e2c2SSteve Yin 		pCrsrShell->StartAction();
3877ca62e2c2SSteve Yin //        SwTxtNode* pNode = const_cast<SwTxtNode*>( GetTxtNode() );
3878ca62e2c2SSteve Yin         SwPaM* aPaM = pCrsrShell->CreateCrsr();
3879ca62e2c2SSteve Yin         aPaM->SetMark();
3880ca62e2c2SSteve Yin 		aPaM->GetPoint()->nContent = GetPortionData().GetModelPosition(startOffset);
3881ca62e2c2SSteve Yin         aPaM->GetMark()->nContent =  GetPortionData().GetModelPosition(endOffset);
3882ca62e2c2SSteve Yin 		//pCrsrShell->ShowCrsr();
3883ca62e2c2SSteve Yin 		pCrsrShell->EndAction();
3884ca62e2c2SSteve Yin         // set PaM at cursor shell
3885ca62e2c2SSteve Yin         //bRet = Select( aPaM );
3886ca62e2c2SSteve Yin     }
3887ca62e2c2SSteve Yin 
3888ca62e2c2SSteve Yin     return bRet;
3889ca62e2c2SSteve Yin }
3890cdf0e10cSrcweir 
3891cdf0e10cSrcweir /*accessibility::*/TextSegment SAL_CALL
getTextMarkup(sal_Int32 nTextMarkupIndex,sal_Int32 nTextMarkupType)3892cdf0e10cSrcweir         SwAccessibleParagraph::getTextMarkup( sal_Int32 nTextMarkupIndex,
3893cdf0e10cSrcweir                                               sal_Int32 nTextMarkupType )
3894cdf0e10cSrcweir                                         throw (lang::IndexOutOfBoundsException,
3895cdf0e10cSrcweir                                                lang::IllegalArgumentException,
3896cdf0e10cSrcweir                                                uno::RuntimeException)
3897cdf0e10cSrcweir {
3898cdf0e10cSrcweir     std::auto_ptr<SwTextMarkupHelper> pTextMarkupHelper;
3899cdf0e10cSrcweir     switch ( nTextMarkupType )
3900cdf0e10cSrcweir     {
3901cdf0e10cSrcweir         case text::TextMarkupType::TRACK_CHANGE_INSERTION:
3902cdf0e10cSrcweir         case text::TextMarkupType::TRACK_CHANGE_DELETION:
3903cdf0e10cSrcweir         case text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE:
3904cdf0e10cSrcweir         {
3905cdf0e10cSrcweir             pTextMarkupHelper.reset( new SwTextMarkupHelper(
3906cdf0e10cSrcweir                 GetPortionData(),
3907cdf0e10cSrcweir                 *(mpParaChangeTrackInfo->getChangeTrackingTextMarkupList( nTextMarkupType ) )) );
3908cdf0e10cSrcweir         }
3909cdf0e10cSrcweir         break;
3910cdf0e10cSrcweir         default:
3911cdf0e10cSrcweir         {
3912cdf0e10cSrcweir             pTextMarkupHelper.reset( new SwTextMarkupHelper( GetPortionData(), *GetTxtNode() ) );
3913cdf0e10cSrcweir         }
3914cdf0e10cSrcweir     }
3915cdf0e10cSrcweir 
3916cdf0e10cSrcweir     return pTextMarkupHelper->getTextMarkup( nTextMarkupIndex, nTextMarkupType );
3917cdf0e10cSrcweir }
3918cdf0e10cSrcweir 
3919cdf0e10cSrcweir uno::Sequence< /*accessibility::*/TextSegment > SAL_CALL
getTextMarkupAtIndex(sal_Int32 nCharIndex,sal_Int32 nTextMarkupType)3920cdf0e10cSrcweir         SwAccessibleParagraph::getTextMarkupAtIndex( sal_Int32 nCharIndex,
3921cdf0e10cSrcweir                                                      sal_Int32 nTextMarkupType )
3922cdf0e10cSrcweir                                         throw (lang::IndexOutOfBoundsException,
3923cdf0e10cSrcweir                                                lang::IllegalArgumentException,
3924cdf0e10cSrcweir                                                uno::RuntimeException)
3925cdf0e10cSrcweir {
3926cdf0e10cSrcweir     // parameter checking
3927cdf0e10cSrcweir     const sal_Int32 nLength = GetString().getLength();
3928cdf0e10cSrcweir     if ( ! IsValidPosition( nCharIndex, nLength ) )
3929cdf0e10cSrcweir     {
3930cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
3931cdf0e10cSrcweir     }
3932cdf0e10cSrcweir 
3933cdf0e10cSrcweir     std::auto_ptr<SwTextMarkupHelper> pTextMarkupHelper;
3934cdf0e10cSrcweir     switch ( nTextMarkupType )
3935cdf0e10cSrcweir     {
3936cdf0e10cSrcweir         case text::TextMarkupType::TRACK_CHANGE_INSERTION:
3937cdf0e10cSrcweir         case text::TextMarkupType::TRACK_CHANGE_DELETION:
3938cdf0e10cSrcweir         case text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE:
3939cdf0e10cSrcweir         {
3940cdf0e10cSrcweir             pTextMarkupHelper.reset( new SwTextMarkupHelper(
3941cdf0e10cSrcweir                 GetPortionData(),
3942cdf0e10cSrcweir                 *(mpParaChangeTrackInfo->getChangeTrackingTextMarkupList( nTextMarkupType ) )) );
3943cdf0e10cSrcweir         }
3944cdf0e10cSrcweir         break;
3945cdf0e10cSrcweir         default:
3946cdf0e10cSrcweir         {
3947cdf0e10cSrcweir             pTextMarkupHelper.reset( new SwTextMarkupHelper( GetPortionData(), *GetTxtNode() ) );
3948cdf0e10cSrcweir         }
3949cdf0e10cSrcweir     }
3950cdf0e10cSrcweir 
3951cdf0e10cSrcweir     return pTextMarkupHelper->getTextMarkupAtIndex( nCharIndex, nTextMarkupType );
3952cdf0e10cSrcweir }
3953cdf0e10cSrcweir // <--
3954cdf0e10cSrcweir 
3955cdf0e10cSrcweir // --> OD 2008-05-29 #i89175#
getLineNumberAtIndex(sal_Int32 nIndex)3956cdf0e10cSrcweir sal_Int32 SAL_CALL SwAccessibleParagraph::getLineNumberAtIndex( sal_Int32 nIndex )
3957cdf0e10cSrcweir                                         throw (lang::IndexOutOfBoundsException,
3958cdf0e10cSrcweir                                                uno::RuntimeException)
3959cdf0e10cSrcweir {
3960cdf0e10cSrcweir     // parameter checking
3961cdf0e10cSrcweir     const sal_Int32 nLength = GetString().getLength();
3962cdf0e10cSrcweir     if ( ! IsValidPosition( nIndex, nLength ) )
3963cdf0e10cSrcweir     {
3964cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
3965cdf0e10cSrcweir     }
3966cdf0e10cSrcweir 
3967cdf0e10cSrcweir     const sal_Int32 nLineNo = GetPortionData().GetLineNo( nIndex );
3968cdf0e10cSrcweir     return nLineNo;
3969cdf0e10cSrcweir }
3970cdf0e10cSrcweir 
3971cdf0e10cSrcweir /*accessibility::*/TextSegment SAL_CALL
getTextAtLineNumber(sal_Int32 nLineNo)3972cdf0e10cSrcweir         SwAccessibleParagraph::getTextAtLineNumber( sal_Int32 nLineNo )
3973cdf0e10cSrcweir                                         throw (lang::IndexOutOfBoundsException,
3974cdf0e10cSrcweir                                                uno::RuntimeException)
3975cdf0e10cSrcweir {
3976cdf0e10cSrcweir     // parameter checking
3977cdf0e10cSrcweir     if ( nLineNo < 0 ||
3978cdf0e10cSrcweir          nLineNo >= GetPortionData().GetLineCount() )
3979cdf0e10cSrcweir     {
3980cdf0e10cSrcweir         throw lang::IndexOutOfBoundsException();
3981cdf0e10cSrcweir     }
3982cdf0e10cSrcweir 
3983cdf0e10cSrcweir     i18n::Boundary aLineBound;
3984cdf0e10cSrcweir     GetPortionData().GetBoundaryOfLine( nLineNo, aLineBound );
3985cdf0e10cSrcweir 
3986cdf0e10cSrcweir     /*accessibility::*/TextSegment aTextAtLine;
3987cdf0e10cSrcweir     const ::rtl::OUString rText = GetString();
3988cdf0e10cSrcweir     aTextAtLine.SegmentText = rText.copy( aLineBound.startPos,
3989cdf0e10cSrcweir                                           aLineBound.endPos - aLineBound.startPos );
3990cdf0e10cSrcweir     aTextAtLine.SegmentStart = aLineBound.startPos;
3991cdf0e10cSrcweir     aTextAtLine.SegmentEnd = aLineBound.endPos;
3992cdf0e10cSrcweir 
3993cdf0e10cSrcweir     return aTextAtLine;
3994cdf0e10cSrcweir }
3995cdf0e10cSrcweir 
getTextAtLineWithCaret()3996cdf0e10cSrcweir /*accessibility::*/TextSegment SAL_CALL SwAccessibleParagraph::getTextAtLineWithCaret()
3997cdf0e10cSrcweir                                         throw (uno::RuntimeException)
3998cdf0e10cSrcweir {
3999cdf0e10cSrcweir     const sal_Int32 nLineNoOfCaret = getNumberOfLineWithCaret();
4000cdf0e10cSrcweir 
4001cdf0e10cSrcweir     if ( nLineNoOfCaret >= 0 &&
4002cdf0e10cSrcweir          nLineNoOfCaret < GetPortionData().GetLineCount() )
4003cdf0e10cSrcweir     {
4004cdf0e10cSrcweir         return getTextAtLineNumber( nLineNoOfCaret );
4005cdf0e10cSrcweir     }
4006cdf0e10cSrcweir 
4007cdf0e10cSrcweir     return /*accessibility::*/TextSegment();
4008cdf0e10cSrcweir }
4009cdf0e10cSrcweir 
getNumberOfLineWithCaret()4010cdf0e10cSrcweir sal_Int32 SAL_CALL SwAccessibleParagraph::getNumberOfLineWithCaret()
4011cdf0e10cSrcweir                                         throw (uno::RuntimeException)
4012cdf0e10cSrcweir {
4013cdf0e10cSrcweir     const sal_Int32 nCaretPos = getCaretPosition();
4014cdf0e10cSrcweir     const sal_Int32 nLength = GetString().getLength();
4015cdf0e10cSrcweir     if ( !IsValidPosition( nCaretPos, nLength ) )
4016cdf0e10cSrcweir     {
4017cdf0e10cSrcweir         return -1;
4018cdf0e10cSrcweir     }
4019cdf0e10cSrcweir 
4020cdf0e10cSrcweir     sal_Int32 nLineNo = GetPortionData().GetLineNo( nCaretPos );
4021cdf0e10cSrcweir 
4022cdf0e10cSrcweir     // special handling for cursor positioned at end of text line via End key
4023cdf0e10cSrcweir     if ( nCaretPos != 0 )
4024cdf0e10cSrcweir     {
4025cdf0e10cSrcweir         i18n::Boundary aLineBound;
4026cdf0e10cSrcweir         GetPortionData().GetBoundaryOfLine( nLineNo, aLineBound );
4027cdf0e10cSrcweir         if ( nCaretPos == aLineBound.startPos )
4028cdf0e10cSrcweir         {
4029cdf0e10cSrcweir             SwCrsrShell* pCrsrShell = SwAccessibleParagraph::GetCrsrShell();
4030cdf0e10cSrcweir             if ( pCrsrShell != 0 )
4031cdf0e10cSrcweir             {
4032cdf0e10cSrcweir                 const awt::Rectangle aCharRect = getCharacterBounds( nCaretPos );
4033cdf0e10cSrcweir 
4034cdf0e10cSrcweir                 const SwRect& aCursorCoreRect = pCrsrShell->GetCharRect();
4035cdf0e10cSrcweir                 // translate core coordinates into accessibility coordinates
4036cdf0e10cSrcweir                 Window *pWin = GetWindow();
4037cdf0e10cSrcweir                 CHECK_FOR_WINDOW( XAccessibleComponent, pWin );
4038cdf0e10cSrcweir 
4039cdf0e10cSrcweir                 Rectangle aScreenRect( GetMap()->CoreToPixel( aCursorCoreRect.SVRect() ));
4040cdf0e10cSrcweir 
4041cdf0e10cSrcweir                 SwRect aFrmLogBounds( GetBounds( *(GetMap()) ) ); // twip rel to doc root
4042cdf0e10cSrcweir                 Point aFrmPixPos( GetMap()->CoreToPixel( aFrmLogBounds.SVRect() ).TopLeft() );
4043cdf0e10cSrcweir                 aScreenRect.Move( -aFrmPixPos.X(), -aFrmPixPos.Y() );
4044cdf0e10cSrcweir 
4045cdf0e10cSrcweir                 // convert into AWT Rectangle
4046cdf0e10cSrcweir                 const awt::Rectangle aCursorRect( aScreenRect.Left(),
4047cdf0e10cSrcweir                                                   aScreenRect.Top(),
4048cdf0e10cSrcweir                                                   aScreenRect.GetWidth(),
4049cdf0e10cSrcweir                                                   aScreenRect.GetHeight() );
4050cdf0e10cSrcweir 
4051cdf0e10cSrcweir                 if ( aCharRect.X != aCursorRect.X ||
4052cdf0e10cSrcweir                      aCharRect.Y != aCursorRect.Y )
4053cdf0e10cSrcweir                 {
4054cdf0e10cSrcweir                     --nLineNo;
4055cdf0e10cSrcweir                 }
4056cdf0e10cSrcweir             }
4057cdf0e10cSrcweir         }
4058cdf0e10cSrcweir     }
4059cdf0e10cSrcweir 
4060cdf0e10cSrcweir     return nLineNo;
4061cdf0e10cSrcweir }
4062cdf0e10cSrcweir 
4063cdf0e10cSrcweir // --> OD 2010-02-19 #i108125#
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)4064cdf0e10cSrcweir void SwAccessibleParagraph::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
4065cdf0e10cSrcweir {
4066cdf0e10cSrcweir     mpParaChangeTrackInfo->reset();
4067cdf0e10cSrcweir 
4068cdf0e10cSrcweir     CheckRegistration( pOld, pNew );
4069cdf0e10cSrcweir }
4070cdf0e10cSrcweir // <--
4071ca62e2c2SSteve Yin 
GetSelectionAtIndex(sal_Int32 & nIndex,sal_Int32 & nStart,sal_Int32 & nEnd)4072ca62e2c2SSteve Yin sal_Bool SwAccessibleParagraph::GetSelectionAtIndex(
4073ca62e2c2SSteve Yin     sal_Int32& nIndex, sal_Int32& nStart, sal_Int32& nEnd)
4074ca62e2c2SSteve Yin {
4075ca62e2c2SSteve Yin         if(nIndex < 0) return sal_False;
4076ca62e2c2SSteve Yin 
4077ca62e2c2SSteve Yin 
4078ca62e2c2SSteve Yin     sal_Bool bRet = sal_False;
4079ca62e2c2SSteve Yin     nStart = -1;
4080ca62e2c2SSteve Yin     nEnd = -1;
4081ca62e2c2SSteve Yin 	sal_Int32 nSelected = nIndex;
4082ca62e2c2SSteve Yin 
4083ca62e2c2SSteve Yin     // get the selection, and test whether it affects our text node
4084ca62e2c2SSteve Yin 	SwPaM* pCrsr = GetCursor( true );
4085ca62e2c2SSteve Yin     if( pCrsr != NULL )
4086ca62e2c2SSteve Yin     {
4087ca62e2c2SSteve Yin         // get SwPosition for my node
4088ca62e2c2SSteve Yin         const SwTxtNode* pNode = GetTxtNode();
4089ca62e2c2SSteve Yin         sal_uLong nHere = pNode->GetIndex();
4090ca62e2c2SSteve Yin 
4091ca62e2c2SSteve Yin         // iterate over ring
4092ca62e2c2SSteve Yin         SwPaM* pRingStart = pCrsr;
4093ca62e2c2SSteve Yin         do
4094ca62e2c2SSteve Yin         {
4095ca62e2c2SSteve Yin             // ignore, if no mark
4096ca62e2c2SSteve Yin             if( pCrsr->HasMark() )
4097ca62e2c2SSteve Yin             {
4098ca62e2c2SSteve Yin                 // check whether nHere is 'inside' pCrsr
4099ca62e2c2SSteve Yin                 SwPosition* pStart = pCrsr->Start();
4100ca62e2c2SSteve Yin                 sal_uLong nStartIndex = pStart->nNode.GetIndex();
4101ca62e2c2SSteve Yin                 SwPosition* pEnd = pCrsr->End();
4102ca62e2c2SSteve Yin                 sal_uLong nEndIndex = pEnd->nNode.GetIndex();
4103ca62e2c2SSteve Yin                 if( ( nHere >= nStartIndex ) &&
4104ca62e2c2SSteve Yin                     ( nHere <= nEndIndex )      )
4105ca62e2c2SSteve Yin                 {
4106ca62e2c2SSteve Yin 					if( nSelected == 0 )
4107ca62e2c2SSteve Yin 					{
4108ca62e2c2SSteve Yin 						// translate start and end positions
4109ca62e2c2SSteve Yin 
4110ca62e2c2SSteve Yin 						// start position
4111ca62e2c2SSteve Yin 						sal_Int32 nLocalStart = -1;
4112ca62e2c2SSteve Yin 						if( nHere > nStartIndex )
4113ca62e2c2SSteve Yin 						{
4114ca62e2c2SSteve Yin 							// selection starts in previous node:
4115ca62e2c2SSteve Yin 							// then our local selection starts with the paragraph
4116ca62e2c2SSteve Yin 							nLocalStart = 0;
4117ca62e2c2SSteve Yin 						}
4118ca62e2c2SSteve Yin 						else
4119ca62e2c2SSteve Yin 						{
4120ca62e2c2SSteve Yin 							DBG_ASSERT( nHere == nStartIndex,
4121ca62e2c2SSteve Yin 										"miscalculated index" );
4122ca62e2c2SSteve Yin 
4123ca62e2c2SSteve Yin 							// selection starts in this node:
4124ca62e2c2SSteve Yin 							// then check whether it's before or inside our part of
4125ca62e2c2SSteve Yin 							// the paragraph, and if so, get the proper position
4126ca62e2c2SSteve Yin 							sal_uInt16 nCoreStart = pStart->nContent.GetIndex();
4127ca62e2c2SSteve Yin 							if( nCoreStart <
4128ca62e2c2SSteve Yin 								GetPortionData().GetFirstValidCorePosition() )
4129ca62e2c2SSteve Yin 							{
4130ca62e2c2SSteve Yin 								nLocalStart = 0;
4131ca62e2c2SSteve Yin 							}
4132ca62e2c2SSteve Yin 							else if( nCoreStart <=
4133ca62e2c2SSteve Yin 									 GetPortionData().GetLastValidCorePosition() )
4134ca62e2c2SSteve Yin 							{
4135ca62e2c2SSteve Yin 								DBG_ASSERT(
4136ca62e2c2SSteve Yin 									GetPortionData().IsValidCorePosition(
4137ca62e2c2SSteve Yin 																	  nCoreStart ),
4138ca62e2c2SSteve Yin 									 "problem determining valid core position" );
4139ca62e2c2SSteve Yin 
4140ca62e2c2SSteve Yin 								nLocalStart =
4141ca62e2c2SSteve Yin 									GetPortionData().GetAccessiblePosition(
4142ca62e2c2SSteve Yin 																	  nCoreStart );
4143ca62e2c2SSteve Yin 							}
4144ca62e2c2SSteve Yin 						}
4145ca62e2c2SSteve Yin 
4146ca62e2c2SSteve Yin 						// end position
4147ca62e2c2SSteve Yin 						sal_Int32 nLocalEnd = -1;
4148ca62e2c2SSteve Yin 						if( nHere < nEndIndex )
4149ca62e2c2SSteve Yin 						{
4150ca62e2c2SSteve Yin 							// selection ends in following node:
4151ca62e2c2SSteve Yin 							// then our local selection extends to the end
4152ca62e2c2SSteve Yin 							nLocalEnd = GetPortionData().GetAccessibleString().
4153ca62e2c2SSteve Yin 																	   getLength();
4154ca62e2c2SSteve Yin 						}
4155ca62e2c2SSteve Yin 						else
4156ca62e2c2SSteve Yin 						{
4157ca62e2c2SSteve Yin 							DBG_ASSERT( nHere == nStartIndex,
4158ca62e2c2SSteve Yin 										"miscalculated index" );
4159ca62e2c2SSteve Yin 
4160ca62e2c2SSteve Yin 							// selection ends in this node: then select everything
4161ca62e2c2SSteve Yin 							// before our part of the node
4162ca62e2c2SSteve Yin 							sal_uInt16 nCoreEnd = pEnd->nContent.GetIndex();
4163ca62e2c2SSteve Yin 							if( nCoreEnd >
4164ca62e2c2SSteve Yin 									GetPortionData().GetLastValidCorePosition() )
4165ca62e2c2SSteve Yin 							{
4166ca62e2c2SSteve Yin 								// selection extends beyond out part of this para
4167ca62e2c2SSteve Yin 								nLocalEnd = GetPortionData().GetAccessibleString().
4168ca62e2c2SSteve Yin 																	   getLength();
4169ca62e2c2SSteve Yin 							}
4170ca62e2c2SSteve Yin 							else if( nCoreEnd >=
4171ca62e2c2SSteve Yin 									 GetPortionData().GetFirstValidCorePosition() )
4172ca62e2c2SSteve Yin 							{
4173ca62e2c2SSteve Yin 								// selection is inside our part of this para
4174ca62e2c2SSteve Yin 								DBG_ASSERT(
4175ca62e2c2SSteve Yin 									GetPortionData().IsValidCorePosition(
4176ca62e2c2SSteve Yin 																	  nCoreEnd ),
4177ca62e2c2SSteve Yin 									 "problem determining valid core position" );
4178ca62e2c2SSteve Yin 
4179ca62e2c2SSteve Yin 								nLocalEnd = GetPortionData().GetAccessiblePosition(
4180ca62e2c2SSteve Yin 																	   nCoreEnd );
4181ca62e2c2SSteve Yin 							}
4182ca62e2c2SSteve Yin 						}
4183ca62e2c2SSteve Yin 
4184ca62e2c2SSteve Yin 						if( ( nLocalStart != -1 ) && ( nLocalEnd != -1 ) )
4185ca62e2c2SSteve Yin 						{
4186ca62e2c2SSteve Yin 							nStart = nLocalStart;
4187ca62e2c2SSteve Yin 							nEnd = nLocalEnd;
4188ca62e2c2SSteve Yin 							bRet = sal_True;
4189ca62e2c2SSteve Yin 						}
4190ca62e2c2SSteve Yin 					} // if hit the index
4191ca62e2c2SSteve Yin 					else
4192ca62e2c2SSteve Yin 					{
4193ca62e2c2SSteve Yin 						nSelected--;
4194ca62e2c2SSteve Yin 					}
4195ca62e2c2SSteve Yin                 }
4196ca62e2c2SSteve Yin                 // else: this PaM doesn't point to this paragraph
4197ca62e2c2SSteve Yin             }
4198ca62e2c2SSteve Yin             // else: this PaM is collapsed and doesn't select anything
4199ca62e2c2SSteve Yin 
4200ca62e2c2SSteve Yin             // next PaM in ring
4201ca62e2c2SSteve Yin             pCrsr = static_cast<SwPaM*>( pCrsr->GetNext() );
4202ca62e2c2SSteve Yin         }
4203ca62e2c2SSteve Yin         while( !bRet && (pCrsr != pRingStart) );
4204ca62e2c2SSteve Yin     }
4205ca62e2c2SSteve Yin     // else: nocursor -> no selection
4206ca62e2c2SSteve Yin 
4207ca62e2c2SSteve Yin     if( bRet )
4208ca62e2c2SSteve Yin     {
4209ca62e2c2SSteve Yin 		sal_Int32 nCaretPos = GetCaretPos();
4210ca62e2c2SSteve Yin 		if( nStart == nCaretPos )
4211ca62e2c2SSteve Yin 		{
4212ca62e2c2SSteve Yin 			sal_Int32 tmp = nStart;
4213ca62e2c2SSteve Yin 			nStart = nEnd;
4214ca62e2c2SSteve Yin 			nEnd = tmp;
4215ca62e2c2SSteve Yin 		}
4216ca62e2c2SSteve Yin     }
4217ca62e2c2SSteve Yin     return bRet;
4218ca62e2c2SSteve Yin }
4219ca62e2c2SSteve Yin 
getAccessibleRole(void)4220ca62e2c2SSteve Yin sal_Int16 SAL_CALL SwAccessibleParagraph::getAccessibleRole (void) throw (::com::sun::star::uno::RuntimeException)
4221ca62e2c2SSteve Yin {
4222ca62e2c2SSteve Yin 	//Get the real heading level, Heading1 ~ Heading10
4223ca62e2c2SSteve Yin 	if (nHeadingLevel > 0)
4224ca62e2c2SSteve Yin 	{
4225ca62e2c2SSteve Yin 		return AccessibleRole::HEADING;
4226ca62e2c2SSteve Yin 	}
4227ca62e2c2SSteve Yin 	else
4228ca62e2c2SSteve Yin 	{
4229ca62e2c2SSteve Yin 		return AccessibleRole::PARAGRAPH;
4230ca62e2c2SSteve Yin 	}
4231ca62e2c2SSteve Yin }
4232ca62e2c2SSteve Yin 
4233ca62e2c2SSteve Yin 
4234ca62e2c2SSteve Yin //Get the real heading level, Heading1 ~ Heading10
GetRealHeadingLevel()4235ca62e2c2SSteve Yin sal_Int32 SwAccessibleParagraph::GetRealHeadingLevel()
4236ca62e2c2SSteve Yin {
4237ca62e2c2SSteve Yin     uno::Reference< ::com::sun::star::beans::XPropertySet > xPortion = CreateUnoPortion( 0, 0 );
4238ca62e2c2SSteve Yin     ::rtl::OUString pString = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ParaStyleName"));
4239ca62e2c2SSteve Yin     uno::Any styleAny = xPortion->getPropertyValue( pString );
4240ca62e2c2SSteve Yin     ::rtl::OUString sValue;
4241ca62e2c2SSteve Yin 	if (styleAny >>= sValue)
4242ca62e2c2SSteve Yin 	{
4243362c80bbSSteve Yin 		sal_Int32 length = sValue.getLength();
4244ca62e2c2SSteve Yin 		if (length == 9 || length == 10)
4245ca62e2c2SSteve Yin 		{
4246ca62e2c2SSteve Yin             ::rtl::OUString headStr = sValue.copy(0, 7);
4247ca62e2c2SSteve Yin             if (headStr.equals(::rtl::OUString::createFromAscii("Heading")))
4248ca62e2c2SSteve Yin 			{
4249ca62e2c2SSteve Yin                 ::rtl::OUString intStr = sValue.copy(8);
4250ca62e2c2SSteve Yin 				sal_Int32 headingLevel = intStr.toInt32(10);
4251ca62e2c2SSteve Yin 				return headingLevel;
4252ca62e2c2SSteve Yin 			}
4253ca62e2c2SSteve Yin 		}
4254ca62e2c2SSteve Yin 	}
4255ca62e2c2SSteve Yin 	return -1;
4256ca62e2c2SSteve Yin }
4257ca62e2c2SSteve Yin 
getExtendedAttributes()4258ca62e2c2SSteve Yin uno::Any SAL_CALL SwAccessibleParagraph::getExtendedAttributes()
4259ca62e2c2SSteve Yin 		throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
4260ca62e2c2SSteve Yin {
4261ca62e2c2SSteve Yin     uno::Any Ret;
4262ca62e2c2SSteve Yin     ::rtl::OUString strHeading(::rtl::OUString::createFromAscii("heading-level:"));
4263ca62e2c2SSteve Yin 	if( nHeadingLevel >= 0 )
4264ca62e2c2SSteve Yin 		strHeading += OUString::valueOf(nHeadingLevel, 10);
4265ca62e2c2SSteve Yin 	strHeading += OUString::createFromAscii(";");
4266ca62e2c2SSteve Yin 
4267ca62e2c2SSteve Yin 	Ret <<= strHeading;
4268ca62e2c2SSteve Yin 
4269ca62e2c2SSteve Yin 	return Ret;
4270ca62e2c2SSteve Yin }
4271ca62e2c2SSteve Yin 
4272ca62e2c2SSteve Yin //Tab will be return when call WORDTYPE
tabCharInWord(sal_Int32 nIndex,i18n::Boundary & aBound)4273ca62e2c2SSteve Yin sal_Bool SwAccessibleParagraph::tabCharInWord( sal_Int32 nIndex, i18n::Boundary& aBound)
4274ca62e2c2SSteve Yin {
4275ca62e2c2SSteve Yin 	sal_Bool bFind =  sal_False;
4276ca62e2c2SSteve Yin 	if( aBound.startPos != nIndex)
4277ca62e2c2SSteve Yin 	{
4278ca62e2c2SSteve Yin 		OUString tabStr;
4279ca62e2c2SSteve Yin 		if(aBound.startPos>nIndex)
4280ca62e2c2SSteve Yin 			tabStr = GetString().copy(nIndex,(aBound.startPos - nIndex) );
4281ca62e2c2SSteve Yin 
4282ca62e2c2SSteve Yin 		sal_Unicode tabChar('\t');
4283ca62e2c2SSteve Yin 		sal_Int32 tabIndex = tabStr.indexOf(tabChar);
4284ca62e2c2SSteve Yin 		if( tabIndex > -1 )
4285ca62e2c2SSteve Yin 		{
4286ca62e2c2SSteve Yin 			aBound.startPos = nIndex + tabIndex ;
4287ca62e2c2SSteve Yin 			aBound.endPos = aBound.startPos + 1;
4288ca62e2c2SSteve Yin 			bFind = sal_True;
4289ca62e2c2SSteve Yin 		}
4290ca62e2c2SSteve Yin 	}
4291ca62e2c2SSteve Yin 	return bFind;
4292ca62e2c2SSteve Yin }
4293