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