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