LibreOffice Module sw (master)  1
accpara.cxx
Go to the documentation of this file.
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 <memory>
21 #include <numeric>
22 #include <txtfrm.hxx>
23 #include <flyfrm.hxx>
24 #include <mdiexp.hxx>
25 #include <ndtxt.hxx>
26 #include <pam.hxx>
27 #include <unotextrange.hxx>
28 #include <unocrsrhelper.hxx>
29 #include <crstate.hxx>
30 #include <accmap.hxx>
31 #include <fesh.hxx>
32 #include <viewopt.hxx>
33 #include <osl/mutex.hxx>
34 #include <vcl/svapp.hxx>
35 #include <vcl/window.hxx>
36 #include <sal/log.hxx>
37 #include <com/sun/star/accessibility/AccessibleRole.hpp>
38 #include <com/sun/star/accessibility/AccessibleScrollType.hpp>
39 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
40 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
41 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
43 #include <com/sun/star/i18n/Boundary.hpp>
44 #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
45 #include <com/sun/star/i18n/WordType.hpp>
46 #include <com/sun/star/i18n/XBreakIterator.hpp>
47 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
48 #include <com/sun/star/beans/UnknownPropertyException.hpp>
49 #include <breakit.hxx>
50 #include "accpara.hxx"
51 #include "accportions.hxx"
52 #include <sfx2/viewsh.hxx>
53 #include <sfx2/viewfrm.hxx>
54 #include <sfx2/dispatch.hxx>
55 #include <unocrsr.hxx>
56 #include <unoport.hxx>
57 #include <doc.hxx>
59 #include "acchyperlink.hxx"
60 #include "acchypertextdata.hxx"
62 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
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 <editeng/unoprnms.hxx>
78 #include <swatrset.hxx>
79 #include <unosett.hxx>
80 #include <unomap.hxx>
81 #include <unoprnms.hxx>
82 #include <com/sun/star/text/WritingMode2.hpp>
83 #include <viewimp.hxx>
84 #include "textmarkuphelper.hxx"
86 #include <com/sun/star/text/TextMarkupType.hpp>
89 #include <svx/colorwindow.hxx>
90 #include <editeng/editids.hrc>
91 
92 #include <reffld.hxx>
93 #include <flddat.hxx>
94 #include "../../uibase/inc/fldmgr.hxx"
95 #include <fldbas.hxx> // SwField
96 
97 using namespace ::com::sun::star;
98 using namespace ::com::sun::star::accessibility;
99 using namespace ::com::sun::star::container;
100 
101 using beans::PropertyValue;
102 using beans::XMultiPropertySet;
103 using beans::UnknownPropertyException;
104 using beans::PropertyState_DIRECT_VALUE;
105 
106 using std::max;
107 using std::min;
108 using std::sort;
109 
110 namespace com::sun::star::text {
111  class XText;
112 }
113 
114 constexpr OUStringLiteral sServiceName = u"com.sun.star.text.AccessibleParagraphView";
115 constexpr OUStringLiteral sImplementationName = u"com.sun.star.comp.Writer.SwAccessibleParagraphView";
116 
118 {
120 }
121 
123 {
124  return OUString(); // provide empty description for paragraphs
125 }
126 
128 {
129  sal_Int32 nRet = -1;
130 
131  // get the selection's point, and test whether it's in our node
132  // #i27301# - consider adjusted method signature
133  SwPaM* pCaret = GetCursor( false ); // caret is first PaM in PaM-ring
134 
135  if( pCaret != nullptr )
136  {
137  SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(GetFrame()));
138  assert(pTextFrame);
139 
140  // check whether the point points into 'our' node
141  SwPosition* pPoint = pCaret->GetPoint();
142  if (sw::FrameContainsNode(*pTextFrame, pPoint->nNode.GetIndex()))
143  {
144  // same node? Then check whether it's also within 'our' part
145  // of the paragraph
146  const TextFrameIndex nIndex = pTextFrame->MapModelToViewPos(*pPoint);
147  if(!GetPortionData().IsValidCorePosition( nIndex ) ||
148  (GetPortionData().IsZeroCorePositionData()
149  && nIndex == TextFrameIndex(0)))
150  {
151  bool bFormat = pTextFrame->HasPara();
152  if(bFormat)
153  {
156  }
157  }
158  if( GetPortionData().IsValidCorePosition( nIndex ) )
159  {
160  // Yes, it's us!
161  // consider that cursor/caret is in front of the list label
162  if ( pCaret->IsInFrontOfLabel() )
163  {
164  nRet = 0;
165  }
166  else
167  {
168  nRet = GetPortionData().GetAccessiblePosition( nIndex );
169  }
170 
171  OSL_ENSURE( nRet >= 0, "invalid cursor?" );
172  OSL_ENSURE( nRet <= GetPortionData().GetAccessibleString().
173  getLength(), "invalid cursor?" );
174  }
175  // else: in this paragraph, but in different frame
176  }
177  // else: not in this paragraph
178  }
179  // else: no cursor -> no caret
180 
181  return nRet;
182 }
183 
184 // #i27301# - new parameter <_bForSelection>
185 SwPaM* SwAccessibleParagraph::GetCursor( const bool _bForSelection )
186 {
187  // get the cursor shell; if we don't have any, we don't have a
188  // cursor/selection either
189  SwPaM* pCursor = nullptr;
191  // #i27301# - if cursor is retrieved for selection, the cursors for
192  // a table selection has to be returned.
193  if ( pCursorShell != nullptr &&
194  ( _bForSelection || !pCursorShell->IsTableMode() ) )
195  {
196  SwFEShell *pFESh = dynamic_cast<SwFEShell*>(pCursorShell);
197  if( !pFESh ||
198  !(pFESh->IsFrameSelected() || pFESh->IsObjSelected() > 0) )
199  {
200  // get the selection, and test whether it affects our text node
201  pCursor = pCursorShell->GetCursor( false /* ??? */ );
202  }
203  }
204 
205  return pCursor;
206 }
207 
209 {
210  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
211  const SwTextNode *pTextNd = pFrame->GetTextNodeForParaProps();
212  return pTextNd->IsOutline();
213 }
214 
216  ::utl::AccessibleStateSetHelper& rStateSet )
217 {
218  SwAccessibleContext::GetStates( rStateSet );
219 
220  // MULTILINE
221  rStateSet.AddState( AccessibleStateType::MULTI_LINE );
222 
223  if (GetCursorShell())
224  {
225  // MULTISELECTABLE
226  rStateSet.AddState(AccessibleStateType::MULTI_SELECTABLE);
227  // FOCUSABLE
228  rStateSet.AddState(AccessibleStateType::FOCUSABLE);
229  }
230 
231  // FOCUSED (simulates node index of cursor)
232  SwPaM* pCaret = GetCursor( false ); // #i27301# - consider adjusted method signature
233  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
234  assert(pFrame);
235  if (pCaret != nullptr &&
236  sw::FrameContainsNode(*pFrame, pCaret->GetPoint()->nNode.GetIndex()) &&
237  m_nOldCaretPos != -1)
238  {
239  vcl::Window *pWin = GetWindow();
240  if( pWin && pWin->HasFocus() )
241  rStateSet.AddState( AccessibleStateType::FOCUSED );
243  GetMap()->SetCursorContext( xThis );
244  }
245 }
246 
247 void SwAccessibleParagraph::InvalidateContent_( bool bVisibleDataFired )
248 {
249  OUString sOldText( GetString() );
250 
252 
253  const OUString& rText = GetString();
254 
255  if( rText != sOldText )
256  {
257  // The text is changed
258  AccessibleEventObject aEvent;
259  aEvent.EventId = AccessibleEventId::TEXT_CHANGED;
260 
261  // determine exact changes between sOldText and rText
263  aEvent.OldValue,
264  aEvent.NewValue);
265 
266  FireAccessibleEvent( aEvent );
267  uno::Reference< XAccessible > xparent = getAccessibleParent();
268  uno::Reference< XAccessibleContext > xAccContext(xparent,uno::UNO_QUERY);
269  if (xAccContext.is() && xAccContext->getAccessibleRole() == AccessibleRole::TABLE_CELL)
270  {
271  SwAccessibleContext* pPara = static_cast< SwAccessibleContext* >(xparent.get());
272  if(pPara)
273  {
274  AccessibleEventObject aParaEvent;
275  aParaEvent.EventId = AccessibleEventId::VALUE_CHANGED;
276  pPara->FireAccessibleEvent(aParaEvent);
277  }
278  }
279  }
280  else if( !bVisibleDataFired )
281  {
283  }
284 
285  bool bNewIsHeading = IsHeading();
286  //Get the real heading level, Heading1 ~ Heading10
288  bool bOldIsHeading;
289  {
290  std::scoped_lock aGuard( m_Mutex );
291  bOldIsHeading = m_bIsHeading;
292  if( m_bIsHeading != bNewIsHeading )
293  m_bIsHeading = bNewIsHeading;
294  }
295 
296  if( bNewIsHeading != bOldIsHeading )
297  {
298  // The role has changed
299  AccessibleEventObject aEvent;
300  aEvent.EventId = AccessibleEventId::ROLE_CHANGED;
301 
302  FireAccessibleEvent( aEvent );
303  }
304 
305  if( rText == sOldText )
306  return;
307 
308  OUString sNewDesc( GetDescription() );
309  OUString sOldDesc;
310  {
311  std::scoped_lock aGuard( m_Mutex );
312  sOldDesc = m_sDesc;
313  if( m_sDesc != sNewDesc )
314  m_sDesc = sNewDesc;
315  }
316 
317  if( sNewDesc != sOldDesc )
318  {
319  // The text is changed
320  AccessibleEventObject aEvent;
321  aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED;
322  aEvent.OldValue <<= sOldDesc;
323  aEvent.NewValue <<= sNewDesc;
324 
325  FireAccessibleEvent( aEvent );
326  }
327 }
328 
330 {
331  // The text is changed
332  sal_Int32 nNew = GetCaretPos();
333  sal_Int32 nOld;
334  {
335  std::scoped_lock aGuard( m_Mutex );
336  nOld = m_nOldCaretPos;
337  m_nOldCaretPos = nNew;
338  }
339  if( -1 != nNew )
340  {
341  // remember that object as the one that has the caret. This is
342  // necessary to notify that object if the cursor leaves it.
344  GetMap()->SetCursorContext( xThis );
345  }
346 
347  vcl::Window *pWin = GetWindow();
348  if( nOld == nNew )
349  return;
350 
351  // The cursor's node position is simulated by the focus!
352  if( pWin && pWin->HasFocus() && -1 == nOld )
353  FireStateChangedEvent( AccessibleStateType::FOCUSED, true );
354 
355  AccessibleEventObject aEvent;
356  aEvent.EventId = AccessibleEventId::CARET_CHANGED;
357  aEvent.OldValue <<= nOld;
358  aEvent.NewValue <<= nNew;
359 
360  FireAccessibleEvent( aEvent );
361 
362  if( pWin && pWin->HasFocus() && -1 == nNew )
363  FireStateChangedEvent( AccessibleStateType::FOCUSED, false );
364  //To send TEXT_SELECTION_CHANGED event
365  sal_Int32 nStart=0;
366  sal_Int32 nEnd =0;
367  bool bCurSelection = GetSelection(nStart,nEnd);
368  if(m_bLastHasSelection || bCurSelection )
369  {
370  aEvent.EventId = AccessibleEventId::TEXT_SELECTION_CHANGED;
371  aEvent.OldValue.clear();
372  aEvent.NewValue.clear();
373  FireAccessibleEvent(aEvent);
374  }
375  m_bLastHasSelection =bCurSelection;
376 
377 }
378 
380 {
381  vcl::Window *pWin = GetWindow();
382  if( pWin )
383  {
384  sal_Int32 nPos;
385  {
386  std::scoped_lock aGuard( m_Mutex );
387  nPos = m_nOldCaretPos;
388  }
389  OSL_ENSURE( nPos != -1, "focus object should be selected" );
390 
391  FireStateChangedEvent( AccessibleStateType::FOCUSED,
392  pWin->HasFocus() && nPos != -1 );
393  }
394 }
395 
397  std::shared_ptr<SwAccessibleMap> const& pInitMap,
398  const SwTextFrame& rTextFrame )
399  : SwAccessibleContext( pInitMap, AccessibleRole::PARAGRAPH, &rTextFrame )
400  , m_nOldCaretPos( -1 )
401  , m_bIsHeading( false )
402  //Get the real heading level, Heading1 ~ Heading10
403  , m_nHeadingLevel (-1)
404  , m_aSelectionHelper( *this )
405  , mpParaChangeTrackInfo( new SwParaChangeTrackingInfo( rTextFrame ) ) // #i108125#
406  , m_bLastHasSelection(false) //To add TEXT_SELECTION_CHANGED event
407 {
408  StartListening(const_cast<SwTextFrame&>(rTextFrame));
410  //Get the real heading level, Heading1 ~ Heading10
412  SetName( OUString() ); // set an empty accessibility name for paragraphs
413 
414  // If this object has the focus, then it is remembered by the map itself.
416 }
417 
419 {
420  SolarMutexGuard aGuard;
421 
422  m_pPortionData.reset();
423  m_pHyperTextData.reset();
424  mpParaChangeTrackInfo.reset(); // #i108125#
425  EndListeningAll();
426 }
427 
429 {
430  std::scoped_lock aGuard( m_Mutex );
431  return m_nOldCaretPos != -1;
432 }
433 
435 {
436  // obtain the text frame
437  OSL_ENSURE( GetFrame() != nullptr, "The text frame has vanished!" );
438  OSL_ENSURE( GetFrame()->IsTextFrame(), "The text frame has mutated!" );
439  const SwTextFrame* pFrame = static_cast<const SwTextFrame*>( GetFrame() );
440 
441  // build new portion data
443  pFrame, GetMap()->GetShell()->GetViewOptions()) );
444  pFrame->VisitPortions( *m_pPortionData );
445 
446  OSL_ENSURE( m_pPortionData != nullptr, "UpdatePortionData() failed" );
447 }
448 
450 {
451  m_pPortionData.reset();
452  m_pHyperTextData.reset();
453 }
454 
456 {
457  OSL_ENSURE( GetMap() != nullptr, "no map?" );
458  SwViewShell* pViewShell = GetMap()->GetShell();
459 
460  OSL_ENSURE( pViewShell != nullptr, "View shell expected!" );
461  SfxViewShell* pSfxShell = pViewShell->GetSfxViewShell();
462 
463  OSL_ENSURE( pSfxShell != nullptr, "SfxViewShell shell expected!" );
464  if( !pSfxShell )
465  return;
466 
467  SfxViewFrame *pFrame = pSfxShell->GetViewFrame();
468  OSL_ENSURE( pFrame != nullptr, "View frame expected!" );
469  if( !pFrame )
470  return;
471 
472  SfxDispatcher *pDispatcher = pFrame->GetDispatcher();
473  OSL_ENSURE( pDispatcher != nullptr, "Dispatcher expected!" );
474  if( !pDispatcher )
475  return;
476 
477  pDispatcher->Execute( nSlot );
478 }
479 
481  sal_Int32 nStartIndex,
482  sal_Int32 nEndIndex )
483 {
484  OSL_ENSURE( (IsValidChar(nStartIndex, GetString().getLength()) &&
485  (nEndIndex == -1)) ||
486  IsValidRange(nStartIndex, nEndIndex, GetString().getLength()),
487  "please check parameters before calling this method" );
488 
489  const TextFrameIndex nStart = GetPortionData().GetCoreViewPosition(nStartIndex);
490  const TextFrameIndex nEnd = (nEndIndex == -1)
491  ? (nStart + TextFrameIndex(1))
492  : GetPortionData().GetCoreViewPosition(nEndIndex);
493 
494  // create UNO cursor
495  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
496  SwPosition aStartPos(pFrame->MapViewToModelPos(nStart));
497  auto pUnoCursor(const_cast<SwDoc&>(pFrame->GetDoc()).CreateUnoCursor(aStartPos));
498  pUnoCursor->SetMark();
499  *pUnoCursor->GetMark() = pFrame->MapViewToModelPos(nEnd);
500 
501  // create a (dummy) text portion to be returned
502  uno::Reference<text::XText> aEmpty;
503  return new SwXTextPortion ( pUnoCursor.get(), aEmpty, PORTION_TEXT);
504 }
505 
506 // range checking for parameter
507 
509  sal_Int32 nPos, sal_Int32 nLength)
510 {
511  return (nPos >= 0) && (nPos < nLength);
512 }
513 
515  sal_Int32 nPos, sal_Int32 nLength)
516 {
517  return (nPos >= 0) && (nPos <= nLength);
518 }
519 
521  sal_Int32 nBegin, sal_Int32 nEnd, sal_Int32 nLength)
522 {
523  return IsValidPosition(nBegin, nLength) && IsValidPosition(nEnd, nLength);
524 }
525 
526 //the function is to check whether the position is in a redline range.
528 {
529  const SwRangeRedline* pRedline = nullptr;
530  SwPaM* pCrSr = GetCursor( true );
531  if ( pCrSr )
532  {
533  SwPosition* pStart = pCrSr->Start();
534  pRedline = pStart->GetDoc().getIDocumentRedlineAccess().GetRedline(*pStart, nullptr);
535  }
536 
537  return pRedline;
538 }
539 
540 // text boundaries
541 
543  i18n::Boundary& rBound,
544  sal_Int32 nPos )
545 {
546  if( GetPortionData().FillBoundaryIFDateField( rBound, nPos) )
547  return true;
548 
549  rBound.startPos = nPos;
550  rBound.endPos = nPos+1;
551  return true;
552 }
553 
555  i18n::Boundary& rBound,
556  const OUString& rText,
557  sal_Int32 nPos )
558 {
559  // now ask the Break-Iterator for the word
560  assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
561 
562  // get locale for this position
563  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
564  const TextFrameIndex nCorePos = GetPortionData().GetCoreViewPosition(nPos);
565  lang::Locale aLocale = g_pBreakIt->GetLocale(pFrame->GetLangOfChar(nCorePos, 0, true));
566 
567  // which type of word are we interested in?
568  // (DICTIONARY_WORD includes punctuation, ANY_WORD doesn't.)
569  const sal_Int16 nWordType = i18n::WordType::ANY_WORD;
570 
571  // get word boundary, as the Break-Iterator sees fit.
572  rBound = g_pBreakIt->GetBreakIter()->getWordBoundary(
573  rText, nPos, aLocale, nWordType, true );
574 
575  return true;
576 }
577 
579  i18n::Boundary& rBound,
580  const OUString& rText,
581  sal_Int32 nPos )
582 {
583  const sal_Unicode* pStr = rText.getStr();
584  while( nPos < rText.getLength() && pStr[nPos] == u' ' )
585  nPos++;
586 
587  GetPortionData().GetSentenceBoundary( rBound, nPos );
588  return true;
589 }
590 
592  i18n::Boundary& rBound,
593  const OUString& rText,
594  sal_Int32 nPos )
595 {
596  if( rText.getLength() == nPos )
598  else
599  GetPortionData().GetLineBoundary( rBound, nPos );
600  return true;
601 }
602 
604  i18n::Boundary& rBound,
605  const OUString& rText )
606 {
607  rBound.startPos = 0;
608  rBound.endPos = rText.getLength();
609  return true;
610 }
611 
613  i18n::Boundary& rBound,
614  sal_Int32 nPos )
615 {
616  GetPortionData().GetAttributeBoundary( rBound, nPos );
617  return true;
618 }
619 
621  i18n::Boundary& rBound,
622  const OUString& rText,
623  sal_Int32 nPos )
624 {
625  // ask the Break-Iterator for the glyph by moving one cell
626  // forward, and then one cell back
627  assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
628 
629  // get locale for this position
630  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
631  const TextFrameIndex nCorePos = GetPortionData().GetCoreViewPosition(nPos);
632  lang::Locale aLocale = g_pBreakIt->GetLocale(pFrame->GetLangOfChar(nCorePos, 0, true));
633 
634  // get word boundary, as the Break-Iterator sees fit.
635  const sal_Int16 nIterMode = i18n::CharacterIteratorMode::SKIPCELL;
636  sal_Int32 nDone = 0;
637  rBound.endPos = g_pBreakIt->GetBreakIter()->nextCharacters(
638  rText, nPos, aLocale, nIterMode, 1, nDone );
639  rBound.startPos = g_pBreakIt->GetBreakIter()->previousCharacters(
640  rText, rBound.endPos, aLocale, nIterMode, 1, nDone );
641  bool bRet = ((rBound.startPos <= nPos) && (nPos <= rBound.endPos));
642  OSL_ENSURE( rBound.startPos <= nPos, "start pos too high" );
643  OSL_ENSURE( rBound.endPos >= nPos, "end pos too low" );
644 
645  return bRet;
646 }
647 
649  i18n::Boundary& rBound,
650  const OUString& rText,
651  sal_Int32 nPos,
652  sal_Int16 nTextType )
653 {
654  // error checking
655  if( !( AccessibleTextType::LINE == nTextType
656  ? IsValidPosition( nPos, rText.getLength() )
657  : IsValidChar( nPos, rText.getLength() ) ) )
658  throw lang::IndexOutOfBoundsException();
659 
660  bool bRet;
661 
662  switch( nTextType )
663  {
664  case AccessibleTextType::WORD:
665  bRet = GetWordBoundary(rBound, rText, nPos);
666  break;
667 
668  case AccessibleTextType::SENTENCE:
669  bRet = GetSentenceBoundary( rBound, rText, nPos );
670  break;
671 
672  case AccessibleTextType::PARAGRAPH:
673  bRet = GetParagraphBoundary( rBound, rText );
674  break;
675 
676  case AccessibleTextType::CHARACTER:
677  bRet = GetCharBoundary( rBound, nPos );
678  break;
679 
680  case AccessibleTextType::LINE:
681  //Solve the problem of returning wrong LINE and PARAGRAPH
682  if((nPos == rText.getLength()) && nPos > 0)
683  bRet = GetLineBoundary( rBound, rText, nPos - 1);
684  else
685  bRet = GetLineBoundary( rBound, rText, nPos );
686  break;
687 
688  case AccessibleTextType::ATTRIBUTE_RUN:
689  bRet = GetAttributeBoundary( rBound, nPos );
690  break;
691 
692  case AccessibleTextType::GLYPH:
693  bRet = GetGlyphBoundary( rBound, rText, nPos );
694  break;
695 
696  default:
697  throw lang::IllegalArgumentException( );
698  }
699 
700  return bRet;
701 }
702 
704 {
705  SolarMutexGuard aGuard;
706 
707  ThrowIfDisposed();
708 
709  std::scoped_lock aGuard2( m_Mutex );
710  if( m_sDesc.isEmpty() )
712 
713  return m_sDesc;
714 }
715 
716 lang::Locale SAL_CALL SwAccessibleParagraph::getLocale()
717 {
718  SolarMutexGuard aGuard;
719 
720  const SwTextFrame *pTextFrame = GetFrame()->DynCastTextFrame();
721  if( !pTextFrame )
722  {
723  throw uno::RuntimeException("no SwTextFrame", static_cast<cppu::OWeakObject*>(this));
724  }
725 
726  lang::Locale aLoc(g_pBreakIt->GetLocale(pTextFrame->GetLangOfChar(TextFrameIndex(0), 0, true)));
727 
728  return aLoc;
729 }
730 
731 // #i27138# - paragraphs are in relation CONTENT_FLOWS_FROM and/or CONTENT_FLOWS_TO
732 uno::Reference<XAccessibleRelationSet> SAL_CALL SwAccessibleParagraph::getAccessibleRelationSet()
733 {
734  SolarMutexGuard aGuard;
735 
736  ThrowIfDisposed();
737 
739 
740  const SwTextFrame* pTextFrame = GetFrame()->DynCastTextFrame();
741  OSL_ENSURE( pTextFrame,
742  "<SwAccessibleParagraph::getAccessibleRelationSet()> - missing text frame");
743  if ( pTextFrame )
744  {
745  const SwContentFrame* pPrevContentFrame( pTextFrame->FindPrevCnt() );
746  if ( pPrevContentFrame )
747  {
748  uno::Sequence< uno::Reference<XInterface> > aSequence { GetMap()->GetContext( pPrevContentFrame ) };
749  AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_FROM,
750  aSequence );
751  pHelper->AddRelation( aAccRel );
752  }
753 
754  const SwContentFrame* pNextContentFrame( pTextFrame->FindNextCnt( true ) );
755  if ( pNextContentFrame )
756  {
757  uno::Sequence< uno::Reference<XInterface> > aSequence { GetMap()->GetContext( pNextContentFrame ) };
758  AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_TO,
759  aSequence );
760  pHelper->AddRelation( aAccRel );
761  }
762  }
763 
764  return pHelper;
765 }
766 
768 {
769  SolarMutexGuard aGuard;
770 
771  ThrowIfDisposed();
772 
773  // get cursor shell
774  SwCursorShell *pCursorSh = GetCursorShell();
775  SwPaM *pCursor = GetCursor( false ); // #i27301# - consider new method signature
776  const SwTextFrame *pTextFrame = static_cast<const SwTextFrame*>( GetFrame() );
777 
778  if (pCursorSh != nullptr &&
779  ( pCursor == nullptr ||
780  !sw::FrameContainsNode(*pTextFrame, pCursor->GetPoint()->nNode.GetIndex()) ||
781  !pTextFrame->IsInside(pTextFrame->MapModelToViewPos(*pCursor->GetPoint()))))
782  {
783  // create pam for selection
784  SwPosition const aStartPos(pTextFrame->MapViewToModelPos(pTextFrame->GetOffset()));
785  SwPaM aPaM( aStartPos );
786 
787  // set PaM at cursor shell
788  Select( aPaM );
789 
790  }
791 
792  // ->#i13955#
793  vcl::Window * pWindow = GetWindow();
794 
795  if (pWindow != nullptr)
796  pWindow->GrabFocus();
797  // <-#i13955#
798 }
799 
800 // #i71385#
801 static bool lcl_GetBackgroundColor( Color & rColor,
802  const SwFrame* pFrame,
803  SwCursorShell* pCursorSh )
804 {
805  const SvxBrushItem* pBackgroundBrush = nullptr;
806  std::optional<Color> xSectionTOXColor;
807  SwRect aDummyRect;
809 
810  if ( pFrame &&
811  pFrame->GetBackgroundBrush( aFillAttributes, pBackgroundBrush, xSectionTOXColor, aDummyRect, false, /*bConsiderTextBox=*/false ) )
812  {
813  if ( xSectionTOXColor )
814  {
815  rColor = *xSectionTOXColor;
816  return true;
817  }
818  else
819  {
820  rColor = pBackgroundBrush->GetColor();
821  return true;
822  }
823  }
824  else if ( pCursorSh )
825  {
826  rColor = pCursorSh->Imp()->GetRetoucheColor();
827  return true;
828  }
829 
830  return false;
831 }
832 
834 {
835  SolarMutexGuard g;
836 
837  Color aBackgroundCol;
838 
839  if ( lcl_GetBackgroundColor( aBackgroundCol, GetFrame(), GetCursorShell() ) )
840  {
841  if ( aBackgroundCol.IsDark() )
842  {
843  return sal_Int32(COL_WHITE);
844  }
845  else
846  {
847  return sal_Int32(COL_BLACK);
848  }
849  }
850 
852 }
853 
855 {
856  SolarMutexGuard g;
857 
858  Color aBackgroundCol;
859 
860  if ( lcl_GetBackgroundColor( aBackgroundCol, GetFrame(), GetCursorShell() ) )
861  {
862  return sal_Int32(aBackgroundCol);
863  }
864 
866 }
867 
869 {
870  return sImplementationName;
871 }
872 
874  const OUString& sTestServiceName)
875 {
876  return cppu::supportsService(this, sTestServiceName);
877 }
878 
879 uno::Sequence< OUString > SAL_CALL SwAccessibleParagraph::getSupportedServiceNames()
880 {
882 }
883 
884 static uno::Sequence< OUString > const & getAttributeNames()
885 {
886  static uno::Sequence< OUString > const aNames
887  {
888  // Add the font name to attribute list
889  // sorted list of strings
903  };
904  return aNames;
905 }
906 
907 static uno::Sequence< OUString > const & getSupplementalAttributeNames()
908 {
909  static uno::Sequence< OUString > const aNames
910  {
911  // sorted list of strings
921  };
922  return aNames;
923 }
924 
925 // XInterface
926 
928 {
929  uno::Any aRet;
930  if ( rType == cppu::UnoType<XAccessibleText>::get())
931  {
932  uno::Reference<XAccessibleText> aAccText = static_cast<XAccessibleText *>(*this); // resolve ambiguity
933  aRet <<= aAccText;
934  }
935  else if ( rType == cppu::UnoType<XAccessibleEditableText>::get())
936  {
937  uno::Reference<XAccessibleEditableText> aAccEditText = this;
938  aRet <<= aAccEditText;
939  }
940  else if ( rType == cppu::UnoType<XAccessibleSelection>::get())
941  {
942  uno::Reference<XAccessibleSelection> aAccSel = this;
943  aRet <<= aAccSel;
944  }
945  else if ( rType == cppu::UnoType<XAccessibleHypertext>::get())
946  {
947  uno::Reference<XAccessibleHypertext> aAccHyp = this;
948  aRet <<= aAccHyp;
949  }
950  // #i63870#
951  // add interface com::sun:star:accessibility::XAccessibleTextAttributes
953  {
954  uno::Reference<XAccessibleTextAttributes> aAccTextAttr = this;
955  aRet <<= aAccTextAttr;
956  }
957  // #i89175#
958  // add interface com::sun:star:accessibility::XAccessibleTextMarkup
959  else if ( rType == cppu::UnoType<XAccessibleTextMarkup>::get())
960  {
961  uno::Reference<XAccessibleTextMarkup> aAccTextMarkup = this;
962  aRet <<= aAccTextMarkup;
963  }
964  // add interface com::sun:star:accessibility::XAccessibleMultiLineText
966  {
967  uno::Reference<XAccessibleMultiLineText> aAccMultiLineText = this;
968  aRet <<= aAccMultiLineText;
969  }
971  {
972  uno::Reference< css::accessibility::XAccessibleTextSelection > aTextExtension = this;
973  aRet <<= aTextExtension;
974  }
976  {
977  uno::Reference<XAccessibleExtendedAttributes> xAttr = this;
978  aRet <<= xAttr;
979  }
980  else
981  {
982  aRet = SwAccessibleContext::queryInterface(rType);
983  }
984 
985  return aRet;
986 }
987 
988 // XTypeProvider
989 uno::Sequence< uno::Type > SAL_CALL SwAccessibleParagraph::getTypes()
990 {
991  // #i63870# - add type accessibility::XAccessibleTextAttributes
992  // #i89175# - add type accessibility::XAccessibleTextMarkup and
993  return cppu::OTypeCollection(
1000  SwAccessibleContext::getTypes() ).getTypes();
1001 }
1002 
1003 uno::Sequence< sal_Int8 > SAL_CALL SwAccessibleParagraph::getImplementationId()
1004 {
1005  return css::uno::Sequence<sal_Int8>();
1006 }
1007 
1008 // XAccessibleText
1009 
1011 {
1012  SolarMutexGuard aGuard;
1013 
1014  ThrowIfDisposed();
1015 
1016  sal_Int32 nRet = GetCaretPos();
1017  {
1018  std::scoped_lock aOldCaretPosGuard( m_Mutex );
1019  OSL_ENSURE( nRet == m_nOldCaretPos, "caret pos out of sync" );
1020  m_nOldCaretPos = nRet;
1021  }
1022  if( -1 != nRet )
1023  {
1025  GetMap()->SetCursorContext( xThis );
1026  }
1027 
1028  return nRet;
1029 }
1030 
1032 {
1033  SolarMutexGuard aGuard;
1034 
1035  ThrowIfDisposed();
1036 
1037  // parameter checking
1038  sal_Int32 nLength = GetString().getLength();
1039  if ( ! IsValidPosition( nIndex, nLength ) )
1040  {
1041  throw lang::IndexOutOfBoundsException();
1042  }
1043 
1044  bool bRet = false;
1045 
1046  // get cursor shell
1047  SwCursorShell* pCursorShell = GetCursorShell();
1048  if( pCursorShell != nullptr )
1049  {
1050  // create pam for selection
1051  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
1052  TextFrameIndex const nFrameIndex(GetPortionData().GetCoreViewPosition(nIndex));
1053  SwPosition aStartPos(pFrame->MapViewToModelPos(nFrameIndex));
1054  SwPaM aPaM( aStartPos );
1055 
1056  // set PaM at cursor shell
1057  bRet = Select( aPaM );
1058  }
1059 
1060  return bRet;
1061 }
1062 
1064 {
1065  SolarMutexGuard aGuard;
1066 
1067  ThrowIfDisposed();
1068 
1069  OUString sText( GetString() );
1070 
1071  // return character (if valid)
1072  if( !IsValidChar(nIndex, sText.getLength() ) )
1073  throw lang::IndexOutOfBoundsException();
1074 
1075  return sText[nIndex];
1076 }
1077 
1078 css::uno::Sequence< css::style::TabStop > SwAccessibleParagraph::GetCurrentTabStop( sal_Int32 nIndex )
1079 {
1080  SolarMutexGuard aGuard;
1081 
1082  ThrowIfDisposed();
1083 
1084  /* #i12332# The position after the string needs special treatment.
1085  IsValidChar -> IsValidPosition
1086  */
1087  if( ! (IsValidPosition( nIndex, GetString().getLength() ) ) )
1088  throw lang::IndexOutOfBoundsException();
1089 
1090  /* #i12332# */
1091  bool bBehindText = false;
1092  if ( nIndex == GetString().getLength() )
1093  bBehindText = true;
1094 
1095  // get model position & prepare GetCharRect() arguments
1096  SwCursorMoveState aMoveState;
1097  aMoveState.m_bRealHeight = true;
1098  aMoveState.m_bRealWidth = true;
1099  SwSpecialPos aSpecialPos;
1100  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
1101 
1102  /* #i12332# FillSpecialPos does not accept nIndex ==
1103  GetString().getLength(). In that case nPos is set to the
1104  length of the string in the core. This way GetCharRect
1105  returns the rectangle for a cursor at the end of the
1106  paragraph. */
1107  const TextFrameIndex nPos = bBehindText
1108  ? TextFrameIndex(pFrame->GetText().getLength())
1109  : GetPortionData().FillSpecialPos(nIndex, aSpecialPos, aMoveState.m_pSpecialPos );
1110 
1111  // call GetCharRect
1112  SwRect aCoreRect;
1113  SwPosition aPosition(pFrame->MapViewToModelPos(nPos));
1114  GetFrame()->GetCharRect( aCoreRect, aPosition, &aMoveState );
1115 
1116  // already get the caret position
1117  css::uno::Sequence< css::style::TabStop > tabs;
1118  const sal_Int32 nStrLen = pFrame->GetText().getLength();
1119  if( nStrLen > 0 )
1120  {
1121  SwFrame* pTFrame = const_cast<SwFrame*>(GetFrame());
1122  tabs = pTFrame->GetTabStopInfo(aCoreRect.Left());
1123  }
1124 
1125  if( tabs.hasElements() )
1126  {
1127  // translate core coordinates into accessibility coordinates
1128  vcl::Window *pWin = GetWindow();
1129  if (!pWin)
1130  {
1131  throw uno::RuntimeException("no Window", static_cast<cppu::OWeakObject*>(this));
1132  }
1133 
1134  SwRect aTmpRect(0, 0, tabs[0].Position, 0);
1135 
1136  tools::Rectangle aScreenRect( GetMap()->CoreToPixel( aTmpRect ));
1137  SwRect aFrameLogBounds( GetBounds( *(GetMap()) ) ); // twip rel to doc root
1138 
1139  Point aFramePixPos( GetMap()->CoreToPixel( aFrameLogBounds ).TopLeft() );
1140  aScreenRect.Move( -aFramePixPos.X(), -aFramePixPos.Y() );
1141 
1142  tabs[0].Position = aScreenRect.GetWidth();
1143  }
1144 
1145  return tabs;
1146 }
1147 
1148 namespace {
1149 
1150 struct IndexCompare
1151 {
1152  const PropertyValue* pValues;
1153  explicit IndexCompare( const PropertyValue* pVals ) : pValues(pVals) {}
1154  bool operator() ( sal_Int32 a, sal_Int32 b ) const
1155  {
1156  return (pValues[a].Name < pValues[b].Name);
1157  }
1158 };
1159 
1160 }
1161 
1163 {
1164  OUString strTypeName;
1165  SwFieldMgr aMgr;
1166  SwTextField* pTextField = nullptr;
1167  sal_Int32 nFieldIndex = GetPortionData().GetFieldIndex(nIndex);
1168  if (nFieldIndex >= 0)
1169  {
1170  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
1171  sw::MergedAttrIter iter(*pFrame);
1172  while (SwTextAttr const*const pHt = iter.NextAttr())
1173  {
1174  if ((pHt->Which() == RES_TXTATR_FIELD
1175  || pHt->Which() == RES_TXTATR_ANNOTATION
1176  || pHt->Which() == RES_TXTATR_INPUTFIELD)
1177  && (nFieldIndex-- == 0))
1178  {
1179  pTextField = const_cast<SwTextField*>(
1180  static_txtattr_cast<SwTextField const*>(pHt));
1181  break;
1182  }
1183  else if (pHt->Which() == RES_TXTATR_REFMARK
1184  && (nFieldIndex-- == 0))
1185  {
1186  strTypeName = "set reference";
1187  }
1188  }
1189  }
1190  if (pTextField)
1191  {
1192  const SwField* pField = pTextField->GetFormatField().GetField();
1193  if (pField)
1194  {
1195  strTypeName = SwFieldType::GetTypeStr(pField->GetTypeId());
1196  const SwFieldIds nWhich = pField->GetTyp()->Which();
1197  OUString sEntry;
1198  sal_uInt32 subType = 0;
1199  switch (nWhich)
1200  {
1201  case SwFieldIds::DocStat:
1202  subType = static_cast<const SwDocStatField*>(pField)->GetSubType();
1203  break;
1204  case SwFieldIds::GetRef:
1205  {
1206  switch( pField->GetSubType() )
1207  {
1208  case REF_BOOKMARK:
1209  {
1210  const SwGetRefField* pRefField = dynamic_cast<const SwGetRefField*>(pField);
1211  if ( pRefField && pRefField->IsRefToHeadingCrossRefBookmark() )
1212  sEntry = "Headings";
1213  else if ( pRefField && pRefField->IsRefToNumItemCrossRefBookmark() )
1214  sEntry = "Numbered Paragraphs";
1215  else
1216  sEntry = "Bookmarks";
1217  }
1218  break;
1219  case REF_FOOTNOTE:
1220  sEntry = "Footnotes";
1221  break;
1222  case REF_ENDNOTE:
1223  sEntry = "Endnotes";
1224  break;
1225  case REF_SETREFATTR:
1226  sEntry = "Insert Reference";
1227  break;
1228  case REF_SEQUENCEFLD:
1229  sEntry = static_cast<const SwGetRefField*>(pField)->GetSetRefName();
1230  break;
1231  }
1232  //Get format string
1233  strTypeName = sEntry;
1234  // <pField->GetFormat() >= 0> is always true as <pField->GetFormat()> is unsigned
1235 // if (pField->GetFormat() >= 0)
1236  {
1237  sEntry = aMgr.GetFormatStr( pField->GetTypeId(), pField->GetFormat() );
1238  if (sEntry.getLength() > 0)
1239  {
1240  strTypeName += "-" + sEntry;
1241  }
1242  }
1243  }
1244  break;
1245  case SwFieldIds::DateTime:
1246  subType = static_cast<const SwDateTimeField*>(pField)->GetSubType();
1247  break;
1248  case SwFieldIds::JumpEdit:
1249  {
1250  const sal_uInt32 nFormat= pField->GetFormat();
1251  const sal_uInt16 nSize = aMgr.GetFormatCount(pField->GetTypeId(), false);
1252  if (nFormat < nSize)
1253  {
1254  sEntry = aMgr.GetFormatStr(pField->GetTypeId(), nFormat);
1255  if (sEntry.getLength() > 0)
1256  {
1257  strTypeName += "-" + sEntry;
1258  }
1259  }
1260  }
1261  break;
1262  case SwFieldIds::ExtUser:
1263  subType = static_cast<const SwExtUserField*>(pField)->GetSubType();
1264  break;
1266  case SwFieldIds::SetExp:
1267  {
1268  sEntry = pField->GetTyp()->GetName();
1269  if (sEntry.getLength() > 0)
1270  {
1271  strTypeName += "-" + sEntry;
1272  }
1273  }
1274  break;
1275  case SwFieldIds::DocInfo:
1276  subType = pField->GetSubType();
1277  subType &= 0x00ff;
1278  break;
1280  {
1281  const SwRefPageSetField* pRPld = static_cast<const SwRefPageSetField*>(pField);
1282  bool bOn = pRPld->IsOn();
1283  strTypeName += "-";
1284  if (bOn)
1285  strTypeName += "on";
1286  else
1287  strTypeName += "off";
1288  }
1289  break;
1290  case SwFieldIds::Author:
1291  {
1292  strTypeName += "-" + aMgr.GetFormatStr(pField->GetTypeId(), pField->GetFormat() & 0xff);
1293  }
1294  break;
1295  default: break;
1296  }
1297  if (subType > 0 || nWhich == SwFieldIds::DocInfo || nWhich == SwFieldIds::ExtUser || nWhich == SwFieldIds::DocStat)
1298  {
1299  std::vector<OUString> aLst;
1300  aMgr.GetSubTypes(pField->GetTypeId(), aLst);
1301  if (subType < aLst.size())
1302  sEntry = aLst[subType];
1303  if (sEntry.getLength() > 0)
1304  {
1305  if (nWhich == SwFieldIds::DocInfo)
1306  {
1307  strTypeName = sEntry;
1308  sal_uInt16 nSize = aMgr.GetFormatCount(pField->GetTypeId(), false);
1309  const sal_uInt16 nExSub = pField->GetSubType() & 0xff00;
1310  if (nSize > 0 && nExSub > 0)
1311  {
1312  //Get extra subtype string
1313  strTypeName += "-";
1314  sEntry = aMgr.GetFormatStr(pField->GetTypeId(), nExSub/0x0100-1);
1315  strTypeName += sEntry;
1316  }
1317  }
1318  else
1319  {
1320  strTypeName += "-" + sEntry;
1321  }
1322  }
1323  }
1324  }
1325  }
1326  return strTypeName;
1327 }
1328 
1329 // #i63870# - re-implement method on behalf of methods
1330 // <_getDefaultAttributesImpl(..)> and <_getRunAttributesImpl(..)>
1332  sal_Int32 nIndex,
1333  const uno::Sequence< OUString >& aRequestedAttributes )
1334 {
1335 
1336  SolarMutexGuard aGuard;
1337 
1338  ThrowIfDisposed();
1339 
1340  const OUString& rText = GetString();
1341 
1342  if (!IsValidPosition(nIndex, rText.getLength()))
1343  throw lang::IndexOutOfBoundsException();
1344 
1345  bool bSupplementalMode = false;
1346  uno::Sequence< OUString > aNames = aRequestedAttributes;
1347  if (!aNames.hasElements())
1348  {
1349  bSupplementalMode = true;
1350  aNames = getAttributeNames();
1351  }
1352  // retrieve default character attributes
1353  tAccParaPropValMap aDefAttrSeq;
1354  _getDefaultAttributesImpl( aNames, aDefAttrSeq, true );
1355 
1356  // retrieved run character attributes
1357  tAccParaPropValMap aRunAttrSeq;
1358  _getRunAttributesImpl( nIndex, aNames, aRunAttrSeq );
1359 
1360  // merge default and run attributes
1361  std::vector< PropertyValue > aValues( aDefAttrSeq.size() );
1362  sal_Int32 i = 0;
1363  for ( const auto& rDefEntry : aDefAttrSeq )
1364  {
1365  tAccParaPropValMap::const_iterator aRunIter =
1366  aRunAttrSeq.find( rDefEntry.first );
1367  if ( aRunIter != aRunAttrSeq.end() )
1368  {
1369  aValues[i] = aRunIter->second;
1370  }
1371  else
1372  {
1373  aValues[i] = rDefEntry.second;
1374  }
1375  ++i;
1376  }
1377  if( bSupplementalMode )
1378  {
1379  uno::Sequence< OUString > aSupplementalNames = aRequestedAttributes;
1380  if (!aSupplementalNames.hasElements())
1381  aSupplementalNames = getSupplementalAttributeNames();
1382 
1383  tAccParaPropValMap aSupplementalAttrSeq;
1384  _getSupplementalAttributesImpl( aSupplementalNames, aSupplementalAttrSeq );
1385 
1386  aValues.resize( aValues.size() + aSupplementalAttrSeq.size() );
1387 
1388  for ( const auto& rSupplementalEntry : aSupplementalAttrSeq )
1389  {
1390  aValues[i] = rSupplementalEntry.second;
1391  ++i;
1392  }
1393 
1394  _correctValues( nIndex, aValues );
1395 
1396  aValues.emplace_back();
1397 
1398  OUString strTypeName = GetFieldTypeNameAtIndex(nIndex);
1399  if (!strTypeName.isEmpty())
1400  {
1401  aValues.emplace_back();
1402  PropertyValue& rValueFT = aValues.back();
1403  rValueFT.Name = "FieldType";
1404  rValueFT.Value <<= strTypeName.toAsciiLowerCase();
1405  rValueFT.Handle = -1;
1406  rValueFT.State = PropertyState_DIRECT_VALUE;
1407  }
1408 
1409  //sort property values
1410  // build sorted index array
1411  sal_Int32 nLength = aValues.size();
1412  std::vector<sal_Int32> aIndices;
1413  aIndices.reserve(nLength);
1414  for (i = 0; i < nLength; ++i)
1415  aIndices.push_back(i);
1416  std::sort(aIndices.begin(), aIndices.end(), IndexCompare(aValues.data()));
1417  // create sorted sequences according to index array
1418  uno::Sequence<PropertyValue> aNewValues( nLength );
1419  PropertyValue* pNewValues = aNewValues.getArray();
1420  for (i = 0; i < nLength; ++i)
1421  {
1422  pNewValues[i] = aValues[aIndices[i]];
1423  }
1424  return aNewValues;
1425  }
1426 
1427  return comphelper::containerToSequence(aValues);
1428 }
1429 
1430 static void SetPutRecursive(SfxItemSet &targetSet, const SfxItemSet &sourceSet)
1431 {
1432  const SfxItemSet *const pParentSet = sourceSet.GetParent();
1433  if (pParentSet)
1434  SetPutRecursive(targetSet, *pParentSet);
1435  targetSet.Put(sourceSet);
1436 }
1437 
1438 // #i63870#
1440  const uno::Sequence< OUString >& aRequestedAttributes,
1441  tAccParaPropValMap& rDefAttrSeq,
1442  const bool bOnlyCharAttrs )
1443 {
1444  // retrieve default attributes
1445  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
1446  const SwTextNode *const pTextNode(pFrame->GetTextNodeForParaProps());
1447  std::optional<SfxItemSet> pSet;
1448  if ( !bOnlyCharAttrs )
1449  {
1450  pSet.emplace( const_cast<SwAttrPool&>(pTextNode->GetDoc().GetAttrPool()),
1454  }
1455  else
1456  {
1457  pSet.emplace( const_cast<SwAttrPool&>(pTextNode->GetDoc().GetAttrPool()),
1458  svl::Items<RES_CHRATR_BEGIN, RES_CHRATR_END - 1> );
1459  }
1460  // #i82637# - From the perspective of the a11y API the default character
1461  // attributes are the character attributes, which are set at the paragraph style
1462  // of the paragraph. The character attributes set at the automatic paragraph
1463  // style of the paragraph are treated as run attributes.
1464  // pTextNode->SwContentNode::GetAttr( *pSet );
1465  // get default paragraph attributes, if needed, and merge these into <pSet>
1466  if ( !bOnlyCharAttrs )
1467  {
1470  aParaSet( const_cast<SwAttrPool&>(pTextNode->GetDoc().GetAttrPool()) );
1471  pTextNode->SwContentNode::GetAttr( aParaSet );
1472  pSet->Put( aParaSet );
1473  }
1474  // get default character attributes and merge these into <pSet>
1475  OSL_ENSURE( pTextNode->GetTextColl(),
1476  "<SwAccessibleParagraph::_getDefaultAttributesImpl(..)> - missing paragraph style. Serious defect!" );
1477  if ( pTextNode->GetTextColl() )
1478  {
1480  aCharSet( const_cast<SwAttrPool&>(pTextNode->GetDoc().GetAttrPool()) );
1481  SetPutRecursive( aCharSet, pTextNode->GetTextColl()->GetAttrSet() );
1482  pSet->Put( aCharSet );
1483  }
1484 
1485  // build-up sequence containing the run attributes <rDefAttrSeq>
1486  tAccParaPropValMap aDefAttrSeq;
1487  {
1488  const SfxItemPropertyMap& rPropMap =
1490  for ( const auto pEntry : rPropMap.getPropertyEntries() )
1491  {
1492  const SfxPoolItem* pItem = pSet->GetItem( pEntry->nWID );
1493  if ( pItem )
1494  {
1495  uno::Any aVal;
1496  pItem->QueryValue( aVal, pEntry->nMemberId );
1497 
1498  PropertyValue rPropVal;
1499  rPropVal.Name = pEntry->aName;
1500  rPropVal.Value = aVal;
1501  rPropVal.Handle = -1;
1502  rPropVal.State = beans::PropertyState_DEFAULT_VALUE;
1503 
1504  aDefAttrSeq[rPropVal.Name] = rPropVal;
1505  }
1506  }
1507 
1508  // #i72800#
1509  // add property value entry for the paragraph style
1510  if ( !bOnlyCharAttrs && pTextNode->GetTextColl() )
1511  {
1512  if ( aDefAttrSeq.find( UNO_NAME_PARA_STYLE_NAME ) == aDefAttrSeq.end() )
1513  {
1514  PropertyValue rPropVal;
1515  rPropVal.Name = UNO_NAME_PARA_STYLE_NAME;
1516  uno::Any aVal( uno::makeAny( pTextNode->GetTextColl()->GetName() ) );
1517  rPropVal.Value = aVal;
1518  rPropVal.Handle = -1;
1519  rPropVal.State = beans::PropertyState_DEFAULT_VALUE;
1520 
1521  aDefAttrSeq[rPropVal.Name] = rPropVal;
1522  }
1523  }
1524 
1525  // #i73371#
1526  // resolve value text::WritingMode2::PAGE of property value entry WritingMode
1527  if ( !bOnlyCharAttrs && GetFrame() )
1528  {
1529  tAccParaPropValMap::iterator aIter = aDefAttrSeq.find( UNO_NAME_WRITING_MODE );
1530  if ( aIter != aDefAttrSeq.end() )
1531  {
1532  PropertyValue rPropVal( aIter->second );
1533  sal_Int16 nVal = rPropVal.Value.get<sal_Int16>();
1534  if ( nVal == text::WritingMode2::PAGE )
1535  {
1536  const SwFrame* pUpperFrame( GetFrame()->GetUpper() );
1537  while ( pUpperFrame )
1538  {
1539  if ( pUpperFrame->GetType() &
1541  {
1542  if ( pUpperFrame->IsVertical() )
1543  {
1544  nVal = text::WritingMode2::TB_RL;
1545  }
1546  else if ( pUpperFrame->IsRightToLeft() )
1547  {
1548  nVal = text::WritingMode2::RL_TB;
1549  }
1550  else
1551  {
1552  nVal = text::WritingMode2::LR_TB;
1553  }
1554  rPropVal.Value <<= nVal;
1555  aDefAttrSeq[rPropVal.Name] = rPropVal;
1556  break;
1557  }
1558 
1559  if ( pUpperFrame->IsFlyFrame() )
1560  {
1561  pUpperFrame = static_cast<const SwFlyFrame*>(pUpperFrame)->GetAnchorFrame();
1562  }
1563  else
1564  {
1565  pUpperFrame = pUpperFrame->GetUpper();
1566  }
1567  }
1568  }
1569  }
1570  }
1571  }
1572 
1573  if ( !aRequestedAttributes.hasElements() )
1574  {
1575  rDefAttrSeq = aDefAttrSeq;
1576  }
1577  else
1578  {
1579  for( const OUString& rReqAttr : aRequestedAttributes )
1580  {
1581  tAccParaPropValMap::const_iterator const aIter = aDefAttrSeq.find( rReqAttr );
1582  if ( aIter != aDefAttrSeq.end() )
1583  {
1584  rDefAttrSeq[ aIter->first ] = aIter->second;
1585  }
1586  }
1587  }
1588 }
1589 
1590 uno::Sequence< PropertyValue > SwAccessibleParagraph::getDefaultAttributes(
1591  const uno::Sequence< OUString >& aRequestedAttributes )
1592 {
1593  SolarMutexGuard aGuard;
1594 
1595  ThrowIfDisposed();
1596 
1597  tAccParaPropValMap aDefAttrSeq;
1598  _getDefaultAttributesImpl( aRequestedAttributes, aDefAttrSeq );
1599 
1600  // #i92233#
1601  constexpr OUStringLiteral sMMToPixelRatio = u"MMToPixelRatio";
1602  bool bProvideMMToPixelRatio( !aRequestedAttributes.hasElements() ||
1603  (comphelper::findValue(aRequestedAttributes, sMMToPixelRatio) != -1) );
1604 
1605  uno::Sequence< PropertyValue > aValues( aDefAttrSeq.size() +
1606  ( bProvideMMToPixelRatio ? 1 : 0 ) );
1607  auto pValues = aValues.getArray();
1608  std::transform(aDefAttrSeq.begin(), aDefAttrSeq.end(), pValues,
1609  [](const auto& rEntry) -> PropertyValue { return rEntry.second; });
1610 
1611  // #i92233#
1612  if ( bProvideMMToPixelRatio )
1613  {
1614  PropertyValue rPropVal;
1615  rPropVal.Name = sMMToPixelRatio;
1616  const Size a100thMMSize( 1000, 1000 );
1617  const Size aPixelSize = GetMap()->LogicToPixel( a100thMMSize );
1618  const float fRatio = (static_cast<float>(a100thMMSize.Width())/100)/aPixelSize.Width();
1619  rPropVal.Value <<= fRatio;
1620  rPropVal.Handle = -1;
1621  rPropVal.State = beans::PropertyState_DEFAULT_VALUE;
1622  pValues[ aValues.getLength() - 1 ] = rPropVal;
1623  }
1624 
1625  return aValues;
1626 }
1627 
1629  const sal_Int32 nIndex,
1630  const uno::Sequence< OUString >& aRequestedAttributes,
1631  tAccParaPropValMap& rRunAttrSeq )
1632 {
1633  // create PaM for character at position <nIndex>
1634  std::optional<SwPaM> pPaM;
1635  const TextFrameIndex nCorePos(GetPortionData().GetCoreViewPosition(nIndex));
1636  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
1637  SwPosition const aModelPos(pFrame->MapViewToModelPos(nCorePos));
1638  SwTextNode *const pTextNode(aModelPos.nNode.GetNode().GetTextNode());
1639  {
1640  SwPosition const aEndPos(*pTextNode,
1641  aModelPos.nContent.GetIndex() == pTextNode->Len()
1642  ? pTextNode->Len() // ???
1643  : aModelPos.nContent.GetIndex() + 1);
1644  pPaM.emplace(aModelPos, aEndPos);
1645  }
1646 
1647  // retrieve character attributes for the created PaM <pPaM>
1648  SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END -1> aSet( pPaM->GetDoc().GetAttrPool() );
1649  // #i82637#
1650  // From the perspective of the a11y API the character attributes, which
1651  // are set at the automatic paragraph style of the paragraph, are treated
1652  // as run attributes.
1653  // SwXTextCursor::GetCursorAttr( *pPaM, aSet, sal_True, sal_True );
1654  // get character attributes from automatic paragraph style and merge these into <aSet>
1655  {
1656  if ( pTextNode->HasSwAttrSet() )
1657  {
1658  SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END -1> aAutomaticParaStyleCharAttrs( pPaM->GetDoc().GetAttrPool());
1659  aAutomaticParaStyleCharAttrs.Put( *(pTextNode->GetpSwAttrSet()), false );
1660  aSet.Put( aAutomaticParaStyleCharAttrs );
1661  }
1662  }
1663  // get character attributes at <pPaM> and merge these into <aSet>
1664  {
1665  SfxItemSetFixed<RES_CHRATR_BEGIN, RES_CHRATR_END -1> aCharAttrsAtPaM( pPaM->GetDoc().GetAttrPool() );
1666  SwUnoCursorHelper::GetCursorAttr(*pPaM, aCharAttrsAtPaM, true);
1667  aSet.Put( aCharAttrsAtPaM );
1668  }
1669 
1670  // build-up sequence containing the run attributes <rRunAttrSeq>
1671  {
1672  tAccParaPropValMap aRunAttrSeq;
1673  {
1674  tAccParaPropValMap aDefAttrSeq;
1675  uno::Sequence< OUString > aDummy;
1676  _getDefaultAttributesImpl( aDummy, aDefAttrSeq, true ); // #i82637#
1677 
1678  const SfxItemPropertyMap& rPropMap =
1680  for ( const auto pEntry : rPropMap.getPropertyEntries() )
1681  {
1682  const SfxPoolItem* pItem( nullptr );
1683  // #i82637# - Found character attributes, whose value equals the value of
1684  // the corresponding default character attributes, are excluded.
1685  if ( aSet.GetItemState( pEntry->nWID, true, &pItem ) == SfxItemState::SET )
1686  {
1687  uno::Any aVal;
1688  pItem->QueryValue( aVal, pEntry->nMemberId );
1689 
1690  PropertyValue rPropVal;
1691  rPropVal.Name = pEntry->aName;
1692  rPropVal.Value = aVal;
1693  rPropVal.Handle = -1;
1694  rPropVal.State = PropertyState_DIRECT_VALUE;
1695 
1696  tAccParaPropValMap::const_iterator aDefIter =
1697  aDefAttrSeq.find( rPropVal.Name );
1698  if ( aDefIter == aDefAttrSeq.end() ||
1699  rPropVal.Value != aDefIter->second.Value )
1700  {
1701  aRunAttrSeq[rPropVal.Name] = rPropVal;
1702  }
1703  }
1704  }
1705  }
1706 
1707  if ( !aRequestedAttributes.hasElements() )
1708  {
1709  rRunAttrSeq = aRunAttrSeq;
1710  }
1711  else
1712  {
1713  for( const OUString& rReqAttr : aRequestedAttributes )
1714  {
1715  tAccParaPropValMap::iterator aIter = aRunAttrSeq.find( rReqAttr );
1716  if ( aIter != aRunAttrSeq.end() )
1717  {
1718  rRunAttrSeq[ (*aIter).first ] = (*aIter).second;
1719  }
1720  }
1721  }
1722  }
1723 }
1724 
1725 uno::Sequence< PropertyValue > SwAccessibleParagraph::getRunAttributes(
1726  sal_Int32 nIndex,
1727  const uno::Sequence< OUString >& aRequestedAttributes )
1728 {
1729  SolarMutexGuard aGuard;
1730 
1731  ThrowIfDisposed();
1732 
1733  {
1734  const OUString& rText = GetString();
1735  if (!IsValidPosition(nIndex, rText.getLength()))
1736  {
1737  throw lang::IndexOutOfBoundsException();
1738  }
1739  }
1740 
1741  tAccParaPropValMap aRunAttrSeq;
1742  _getRunAttributesImpl( nIndex, aRequestedAttributes, aRunAttrSeq );
1743 
1744  return comphelper::mapValuesToSequence( aRunAttrSeq );
1745 }
1746 
1748  const uno::Sequence< OUString >& aRequestedAttributes,
1749  tAccParaPropValMap& rSupplementalAttrSeq )
1750 {
1751  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
1752  const SwTextNode *const pTextNode(pFrame->GetTextNodeForParaProps());
1759  aSet( const_cast<SwAttrPool&>(pTextNode->GetDoc().GetAttrPool()) );
1760 
1761  if ( pTextNode->HasBullet() || pTextNode->HasNumber() )
1762  {
1763  aSet.Put( pTextNode->GetAttr(RES_PARATR_LIST_LEVEL) );
1764  }
1765  aSet.Put( pTextNode->SwContentNode::GetAttr(RES_UL_SPACE) );
1766  aSet.Put( pTextNode->SwContentNode::GetAttr(RES_LR_SPACE) );
1767  aSet.Put( pTextNode->SwContentNode::GetAttr(RES_PARATR_ADJUST) );
1768 
1769  tAccParaPropValMap aSupplementalAttrSeq;
1770  {
1771  const SfxItemPropertyMapEntry* pPropMap(
1773  while ( !pPropMap->aName.isEmpty() )
1774  {
1775  const SfxPoolItem* pItem = aSet.GetItem( pPropMap->nWID );
1776  if ( pItem )
1777  {
1778  uno::Any aVal;
1779  pItem->QueryValue( aVal, pPropMap->nMemberId );
1780 
1781  PropertyValue rPropVal;
1782  rPropVal.Name = pPropMap->aName;
1783  rPropVal.Value = aVal;
1784  rPropVal.Handle = -1;
1785  rPropVal.State = beans::PropertyState_DEFAULT_VALUE;
1786 
1787  aSupplementalAttrSeq[rPropVal.Name] = rPropVal;
1788  }
1789 
1790  ++pPropMap;
1791  }
1792  }
1793 
1794  for( const OUString& rSupplementalAttr : aRequestedAttributes )
1795  {
1796  tAccParaPropValMap::const_iterator const aIter = aSupplementalAttrSeq.find( rSupplementalAttr );
1797  if ( aIter != aSupplementalAttrSeq.end() )
1798  {
1799  rSupplementalAttrSeq[ aIter->first ] = aIter->second;
1800  }
1801  }
1802 }
1803 
1804 void SwAccessibleParagraph::_correctValues( const sal_Int32 nIndex,
1805  std::vector< PropertyValue >& rValues)
1806 {
1807  PropertyValue ChangeAttr, ChangeAttrColor;
1808 
1809  const SwRangeRedline* pRedline = GetRedlineAtIndex();
1810  if ( pRedline )
1811  {
1812 
1813  const SwModuleOptions *pOpt = SW_MOD()->GetModuleConfig();
1814  AuthorCharAttr aChangeAttr;
1815  if ( pOpt )
1816  {
1817  switch( pRedline->GetType())
1818  {
1819  case RedlineType::Insert:
1820  aChangeAttr = pOpt->GetInsertAuthorAttr();
1821  break;
1822  case RedlineType::Delete:
1823  aChangeAttr = pOpt->GetDeletedAuthorAttr();
1824  break;
1825  case RedlineType::Format:
1826  aChangeAttr = pOpt->GetFormatAuthorAttr();
1827  break;
1828  default: break;
1829  }
1830  }
1831  switch( aChangeAttr.m_nItemId )
1832  {
1833  case SID_ATTR_CHAR_WEIGHT:
1834  ChangeAttr.Name = UNO_NAME_CHAR_WEIGHT;
1835  ChangeAttr.Value <<= awt::FontWeight::BOLD;
1836  break;
1837  case SID_ATTR_CHAR_POSTURE:
1838  ChangeAttr.Name = UNO_NAME_CHAR_POSTURE;
1839  ChangeAttr.Value <<= awt::FontSlant_ITALIC; //char posture
1840  break;
1841  case SID_ATTR_CHAR_STRIKEOUT:
1842  ChangeAttr.Name = UNO_NAME_CHAR_STRIKEOUT;
1843  ChangeAttr.Value <<= awt::FontStrikeout::SINGLE; //char strikeout
1844  break;
1845  case SID_ATTR_CHAR_UNDERLINE:
1846  ChangeAttr.Name = UNO_NAME_CHAR_UNDERLINE;
1847  ChangeAttr.Value <<= aChangeAttr.m_nAttr; //underline line
1848  break;
1849  }
1850  if( aChangeAttr.m_nColor != COL_NONE_COLOR )
1851  {
1852  if( aChangeAttr.m_nItemId == SID_ATTR_BRUSH )
1853  {
1854  ChangeAttrColor.Name = UNO_NAME_CHAR_BACK_COLOR;
1855  if( aChangeAttr.m_nColor == COL_TRANSPARENT )//char backcolor
1856  ChangeAttrColor.Value <<= COL_BLUE;
1857  else
1858  ChangeAttrColor.Value <<= aChangeAttr.m_nColor;
1859  }
1860  else
1861  {
1862  ChangeAttrColor.Name = UNO_NAME_CHAR_COLOR;
1863  if( aChangeAttr.m_nColor == COL_TRANSPARENT )//char color
1864  ChangeAttrColor.Value <<= COL_BLUE;
1865  else
1866  ChangeAttrColor.Value <<= aChangeAttr.m_nColor;
1867  }
1868  }
1869  }
1870 
1871  // sw_redlinehide: this function only needs SwWrongList for 1 character,
1872  // and the end is excluded by InWrongWord(),
1873  // so it ought to work to just pick the wrong-list/node that contains
1874  // the character following the given nIndex
1875  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
1876  TextFrameIndex const nCorePos(GetPortionData().GetCoreViewPosition(nIndex));
1877  std::pair<SwTextNode*, sal_Int32> pos(pFrame->MapViewToModel(nCorePos));
1878  if (pos.first->Len() == pos.second
1879  && nCorePos != TextFrameIndex(pFrame->GetText().getLength()))
1880  {
1881  pos = pFrame->MapViewToModel(nCorePos + TextFrameIndex(1)); // try this one instead
1882  assert(pos.first->Len() != pos.second);
1883  }
1884  const SwTextNode *const pTextNode(pos.first);
1885 
1886  sal_Int32 nValues = rValues.size();
1887  for (sal_Int32 i = 0; i < nValues; ++i)
1888  {
1889  PropertyValue& rValue = rValues[i];
1890 
1891  if (rValue.Name == ChangeAttr.Name )
1892  {
1893  rValue.Value = ChangeAttr.Value;
1894  continue;
1895  }
1896 
1897  if (rValue.Name == ChangeAttrColor.Name )
1898  {
1899  rValue.Value = ChangeAttrColor.Value;
1900  continue;
1901  }
1902 
1903  //back color
1904  if (rValue.Name == UNO_NAME_CHAR_BACK_COLOR)
1905  {
1906  uno::Any &anyChar = rValue.Value;
1907  sal_uInt32 crBack = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved));
1908  if (COL_AUTO == Color(ColorTransparency, crBack))
1909  {
1910  uno::Reference<XAccessibleComponent> xComponent(this);
1911  if (xComponent.is())
1912  {
1913  crBack = static_cast<sal_uInt32>(xComponent->getBackground());
1914  }
1915  rValue.Value <<= crBack;
1916  }
1917  continue;
1918  }
1919 
1920  //char color
1921  if (rValue.Name == UNO_NAME_CHAR_COLOR)
1922  {
1923  if( GetPortionData().IsInGrayPortion( nIndex ) )
1924  rValue.Value <<= SwViewOption::GetFieldShadingsColor();
1925  uno::Any &anyChar = rValue.Value;
1926  sal_uInt32 crChar = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved));
1927 
1928  if( COL_AUTO == Color(ColorTransparency, crChar) )
1929  {
1930  uno::Reference<XAccessibleComponent> xComponent(this);
1931  if (xComponent.is())
1932  {
1933  Color cr(ColorTransparency, xComponent->getBackground());
1934  crChar = sal_uInt32(cr.IsDark() ? COL_WHITE : COL_BLACK);
1935  rValue.Value <<= crChar;
1936  }
1937  }
1938  continue;
1939  }
1940 
1941  // UnderLine
1942  if (rValue.Name == UNO_NAME_CHAR_UNDERLINE)
1943  {
1944  //misspelled word
1945  SwCursorShell* pCursorShell = GetCursorShell();
1946  if( pCursorShell != nullptr && pCursorShell->GetViewOptions() && pCursorShell->GetViewOptions()->IsOnlineSpell())
1947  {
1948  const SwWrongList* pWrongList = pTextNode->GetWrong();
1949  if( nullptr != pWrongList )
1950  {
1951  sal_Int32 nBegin = pos.second;
1952  sal_Int32 nLen = 1;
1953  if (pWrongList->InWrongWord(nBegin, nLen) && !pTextNode->IsSymbolAt(nBegin))
1954  {
1955  rValue.Value <<= sal_uInt16(LINESTYLE_WAVE);
1956  }
1957  }
1958  }
1959  continue;
1960  }
1961 
1962  // UnderLineColor
1963  if (rValue.Name == UNO_NAME_CHAR_UNDERLINE_COLOR)
1964  {
1965  //misspelled word
1966  SwCursorShell* pCursorShell = GetCursorShell();
1967  if( pCursorShell != nullptr && pCursorShell->GetViewOptions() && pCursorShell->GetViewOptions()->IsOnlineSpell())
1968  {
1969  const SwWrongList* pWrongList = pTextNode->GetWrong();
1970  if( nullptr != pWrongList )
1971  {
1972  sal_Int32 nBegin = pos.second;
1973  sal_Int32 nLen = 1;
1974  if (pWrongList->InWrongWord(nBegin, nLen) && !pTextNode->IsSymbolAt(nBegin))
1975  {
1976  rValue.Value <<= sal_Int32(0x00ff0000);
1977  continue;
1978  }
1979  }
1980  }
1981 
1982  uno::Any &anyChar = rValue.Value;
1983  sal_uInt32 crUnderline = static_cast<sal_uInt32>( reinterpret_cast<sal_uIntPtr>(anyChar.pReserved));
1984  if ( COL_AUTO == Color(ColorTransparency, crUnderline) )
1985  {
1986  uno::Reference<XAccessibleComponent> xComponent(this);
1987  if (xComponent.is())
1988  {
1989  Color cr(ColorTransparency, xComponent->getBackground());
1990  crUnderline = sal_uInt32(cr.IsDark() ? COL_WHITE : COL_BLACK);
1991  rValue.Value <<= crUnderline;
1992  }
1993  }
1994 
1995  continue;
1996  }
1997 
1998  //tab stop
1999  if (rValue.Name == UNO_NAME_TABSTOPS)
2000  {
2001  css::uno::Sequence< css::style::TabStop > tabs = GetCurrentTabStop( nIndex );
2002  if( !tabs.hasElements() )
2003  {
2004  tabs.realloc(1);
2005  css::style::TabStop ts;
2006  css::awt::Rectangle rc0 = getCharacterBounds(0);
2007  css::awt::Rectangle rc1 = getCharacterBounds(nIndex);
2008  if( rc1.X - rc0.X >= 48 )
2009  ts.Position = (rc1.X - rc0.X) - (rc1.X - rc0.X - 48)% 47 + 47;
2010  else
2011  ts.Position = 48;
2012  ts.DecimalChar = ' ';
2013  ts.FillChar = ' ';
2014  ts.Alignment = css::style::TabAlign_LEFT;
2015  tabs[0] = ts;
2016  }
2017  rValue.Value <<= tabs;
2018  continue;
2019  }
2020 
2021  //footnote & endnote
2022  if (rValue.Name == UNO_NAME_CHAR_ESCAPEMENT)
2023  {
2024  if ( GetPortionData().IsIndexInFootnode(nIndex) )
2025  {
2026  rValue.Value <<= sal_Int32(101);
2027  }
2028  continue;
2029  }
2030  }
2031 }
2032 
2034  sal_Int32 nIndex )
2035 {
2036  SolarMutexGuard aGuard;
2037 
2038  ThrowIfDisposed();
2039 
2040  // #i12332# The position after the string needs special treatment.
2041  // IsValidChar -> IsValidPosition
2042  if( ! (IsValidPosition( nIndex, GetString().getLength() ) ) )
2043  throw lang::IndexOutOfBoundsException();
2044 
2045  // #i12332#
2046  bool bBehindText = false;
2047  if ( nIndex == GetString().getLength() )
2048  bBehindText = true;
2049 
2050  // get model position & prepare GetCharRect() arguments
2051  SwCursorMoveState aMoveState;
2052  aMoveState.m_bRealHeight = true;
2053  aMoveState.m_bRealWidth = true;
2054  SwSpecialPos aSpecialPos;
2055  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
2056 
2062  const TextFrameIndex nPos = bBehindText
2063  ? TextFrameIndex(pFrame->GetText().getLength())
2064  : GetPortionData().FillSpecialPos(nIndex, aSpecialPos, aMoveState.m_pSpecialPos );
2065 
2066  // call GetCharRect
2067  SwRect aCoreRect;
2068  SwPosition aPosition(pFrame->MapViewToModelPos(nPos));
2069  GetFrame()->GetCharRect( aCoreRect, aPosition, &aMoveState );
2070 
2071  // translate core coordinates into accessibility coordinates
2072  vcl::Window *pWin = GetWindow();
2073  if (!pWin)
2074  {
2075  throw uno::RuntimeException("no Window", static_cast<cppu::OWeakObject*>(this));
2076  }
2077 
2078  tools::Rectangle aScreenRect( GetMap()->CoreToPixel( aCoreRect ));
2079  SwRect aFrameLogBounds( GetBounds( *(GetMap()) ) ); // twip rel to doc root
2080 
2081  Point aFramePixPos( GetMap()->CoreToPixel( aFrameLogBounds ).TopLeft() );
2082  aScreenRect.Move( -aFramePixPos.getX(), -aFramePixPos.getY() );
2083 
2084  // convert into AWT Rectangle
2085  return awt::Rectangle(
2086  aScreenRect.Left(), aScreenRect.Top(),
2087  aScreenRect.GetWidth(), aScreenRect.GetHeight() );
2088 }
2089 
2091 {
2092  SolarMutexGuard aGuard;
2093 
2094  ThrowIfDisposed();
2095 
2096  return GetString().getLength();
2097 }
2098 
2099 sal_Int32 SwAccessibleParagraph::getIndexAtPoint( const awt::Point& rPoint )
2100 {
2101  SolarMutexGuard aGuard;
2102 
2103  ThrowIfDisposed();
2104 
2105  // construct Point (translate into layout coordinates)
2106  vcl::Window *pWin = GetWindow();
2107  if (!pWin)
2108  {
2109  throw uno::RuntimeException("no Window", static_cast<cppu::OWeakObject*>(this));
2110  }
2111  Point aPoint( rPoint.X, rPoint.Y );
2112  SwRect aLogBounds( GetBounds( *(GetMap()), GetFrame() ) ); // twip rel to doc root
2113  Point aPixPos( GetMap()->CoreToPixel( aLogBounds ).TopLeft() );
2114  aPoint.setX(aPoint.getX() + aPixPos.getX());
2115  aPoint.setY(aPoint.getY() + aPixPos.getY());
2116  Point aCorePoint( GetMap()->PixelToCore( aPoint ) );
2117  if( !aLogBounds.Contains( aCorePoint ) )
2118  {
2119  // #i12332# rPoint is may also be in rectangle returned by
2120  // getCharacterBounds(getCharacterCount()
2121 
2122  awt::Rectangle aRectEndPos =
2124 
2125  if (rPoint.X - aRectEndPos.X >= 0 &&
2126  rPoint.X - aRectEndPos.X < aRectEndPos.Width &&
2127  rPoint.Y - aRectEndPos.Y >= 0 &&
2128  rPoint.Y - aRectEndPos.Y < aRectEndPos.Height)
2129  return getCharacterCount();
2130 
2131  return -1;
2132  }
2133 
2134  // ask core for position
2135  OSL_ENSURE( GetFrame() != nullptr, "The text frame has vanished!" );
2136  OSL_ENSURE( GetFrame()->IsTextFrame(), "The text frame has mutated!" );
2137  const SwTextFrame* pFrame = static_cast<const SwTextFrame*>( GetFrame() );
2138  // construct SwPosition (where GetModelPositionForViewPoint() will put the result into)
2139  SwTextNode* pNode = const_cast<SwTextNode*>(pFrame->GetTextNodeFirst());
2140  SwPosition aPos(*pNode, 0);
2141  SwCursorMoveState aMoveState;
2142  aMoveState.m_bPosMatchesBounds = true;
2143  const bool bSuccess = pFrame->GetModelPositionForViewPoint( &aPos, aCorePoint, &aMoveState );
2144 
2145  TextFrameIndex nIndex = pFrame->MapModelToViewPos(aPos);
2146  if (TextFrameIndex(0) < nIndex)
2147  {
2148  assert(bSuccess);
2149  SwRect aResultRect;
2150  pFrame->GetCharRect( aResultRect, aPos );
2151  bool bVert = pFrame->IsVertical();
2152  bool bR2L = pFrame->IsRightToLeft();
2153 
2154  if ( (!bVert && aResultRect.Pos().getX() > aCorePoint.getX()) ||
2155  ( bVert && aResultRect.Pos().getY() > aCorePoint.getY()) ||
2156  ( bR2L && aResultRect.Right() < aCorePoint.getX()) )
2157  {
2158  SwPosition aPosPrev(pFrame->MapViewToModelPos(nIndex - TextFrameIndex(1)));
2159  SwRect aResultRectPrev;
2160  pFrame->GetCharRect( aResultRectPrev, aPosPrev );
2161  if ( (!bVert && aResultRectPrev.Pos().getX() < aCorePoint.getX() && aResultRect.Pos().getY() == aResultRectPrev.Pos().getY()) ||
2162  ( bVert && aResultRectPrev.Pos().getY() < aCorePoint.getY() && aResultRect.Pos().getX() == aResultRectPrev.Pos().getX()) ||
2163  ( bR2L && aResultRectPrev.Right() > aCorePoint.getX() && aResultRect.Pos().getY() == aResultRectPrev.Pos().getY()) )
2164  {
2165  --nIndex;
2166  }
2167  }
2168  }
2169 
2170  return bSuccess
2172  : -1;
2173 }
2174 
2176 {
2177  SolarMutexGuard aGuard;
2178 
2179  ThrowIfDisposed();
2180 
2181  sal_Int32 nStart, nEnd;
2182  bool bSelected = GetSelection( nStart, nEnd );
2183  return bSelected
2184  ? GetString().copy( nStart, nEnd - nStart )
2185  : OUString();
2186 }
2187 
2189 {
2190  SolarMutexGuard aGuard;
2191 
2192  ThrowIfDisposed();
2193 
2194  sal_Int32 nStart, nEnd;
2195  GetSelection( nStart, nEnd );
2196  return nStart;
2197 }
2198 
2200 {
2201  SolarMutexGuard aGuard;
2202 
2203  ThrowIfDisposed();
2204 
2205  sal_Int32 nStart, nEnd;
2206  GetSelection( nStart, nEnd );
2207  return nEnd;
2208 }
2209 
2210 sal_Bool SwAccessibleParagraph::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2211 {
2212  SolarMutexGuard aGuard;
2213 
2214  ThrowIfDisposed();
2215 
2216  // parameter checking
2217  sal_Int32 nLength = GetString().getLength();
2218  if ( ! IsValidRange( nStartIndex, nEndIndex, nLength ) )
2219  {
2220  throw lang::IndexOutOfBoundsException();
2221  }
2222 
2223  bool bRet = false;
2224 
2225  // get cursor shell
2226  SwCursorShell* pCursorShell = GetCursorShell();
2227  if( pCursorShell != nullptr )
2228  {
2229  // create pam for selection
2230  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
2231  TextFrameIndex const nStart(GetPortionData().GetCoreViewPosition(nStartIndex));
2232  TextFrameIndex const nEnd(GetPortionData().GetCoreViewPosition(nEndIndex));
2233  SwPaM aPaM(pFrame->MapViewToModelPos(nStart));
2234  aPaM.SetMark();
2235  *aPaM.GetPoint() = pFrame->MapViewToModelPos(nEnd);
2236 
2237  // set PaM at cursor shell
2238  bRet = Select( aPaM );
2239  }
2240 
2241  return bRet;
2242 }
2243 
2245 {
2246  SolarMutexGuard aGuard;
2247 
2248  ThrowIfDisposed();
2249 
2250  return GetString();
2251 }
2252 
2254  sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2255 {
2256  SolarMutexGuard aGuard;
2257 
2258  ThrowIfDisposed();
2259 
2260  OUString sText( GetString() );
2261 
2262  if ( !IsValidRange( nStartIndex, nEndIndex, sText.getLength() ) )
2263  throw lang::IndexOutOfBoundsException();
2264 
2265  OrderRange( nStartIndex, nEndIndex );
2266  return sText.copy(nStartIndex, nEndIndex-nStartIndex );
2267 }
2268 
2269 /*accessibility::*/TextSegment SwAccessibleParagraph::getTextAtIndex( sal_Int32 nIndex, sal_Int16 nTextType )
2270 {
2271  SolarMutexGuard aGuard;
2272 
2273  ThrowIfDisposed();
2274 
2275  /*accessibility::*/TextSegment aResult;
2276  aResult.SegmentStart = -1;
2277  aResult.SegmentEnd = -1;
2278 
2279  const OUString rText = GetString();
2280  // implement the silly specification that first position after
2281  // text must return an empty string, rather than throwing an
2282  // IndexOutOfBoundsException, except for LINE, where the last
2283  // line is returned
2284  if( nIndex == rText.getLength() && AccessibleTextType::LINE != nTextType )
2285  return aResult;
2286 
2287  // with error checking
2288  i18n::Boundary aBound;
2289  bool bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
2290 
2291  OSL_ENSURE( aBound.startPos >= 0, "illegal boundary" );
2292  OSL_ENSURE( aBound.startPos <= aBound.endPos, "illegal boundary" );
2293 
2294  // return word (if present)
2295  if ( bWord )
2296  {
2297  aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
2298  aResult.SegmentStart = aBound.startPos;
2299  aResult.SegmentEnd = aBound.endPos;
2300  }
2301 
2302  return aResult;
2303 }
2304 
2305 /*accessibility::*/TextSegment SwAccessibleParagraph::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 nTextType )
2306 {
2307  SolarMutexGuard aGuard;
2308 
2309  ThrowIfDisposed();
2310 
2311  const OUString rText = GetString();
2312 
2313  /*accessibility::*/TextSegment aResult;
2314  aResult.SegmentStart = -1;
2315  aResult.SegmentEnd = -1;
2316  //If nIndex = 0, then nobefore text so return -1 directly.
2317  if( nIndex == 0 )
2318  return aResult;
2319  //Tab will be return when call WORDTYPE
2320 
2321  // get starting pos
2322  i18n::Boundary aBound;
2323  if (nIndex == rText.getLength())
2324  aBound.startPos = aBound.endPos = nIndex;
2325  else
2326  {
2327  bool bTmp = GetTextBoundary( aBound, rText, nIndex, nTextType );
2328 
2329  if ( ! bTmp )
2330  aBound.startPos = aBound.endPos = nIndex;
2331  }
2332 
2333  // now skip to previous word
2334  if (nTextType==2 || nTextType == 3)
2335  {
2336  i18n::Boundary preBound = aBound;
2337  while(preBound.startPos==aBound.startPos && nIndex > 0)
2338  {
2339  nIndex = min( nIndex, preBound.startPos ) - 1;
2340  if( nIndex < 0 ) break;
2341  GetTextBoundary( preBound, rText, nIndex, nTextType );
2342  }
2343  //if (nIndex>0)
2344  if (nIndex>=0)
2345  //Tab will be return when call WORDTYPE
2346  {
2347  aResult.SegmentText = rText.copy( preBound.startPos, preBound.endPos - preBound.startPos );
2348  aResult.SegmentStart = preBound.startPos;
2349  aResult.SegmentEnd = preBound.endPos;
2350  }
2351  }
2352  else
2353  {
2354  bool bWord = false;
2355  while( !bWord )
2356  {
2357  nIndex = min( nIndex, aBound.startPos ) - 1;
2358  if( nIndex >= 0 )
2359  {
2360  bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
2361  }
2362  else
2363  break; // exit if beginning of string is reached
2364  }
2365 
2366  if (bWord && nIndex<rText.getLength())
2367  {
2368  aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
2369  aResult.SegmentStart = aBound.startPos;
2370  aResult.SegmentEnd = aBound.endPos;
2371  }
2372  }
2373  return aResult;
2374 }
2375 
2376 /*accessibility::*/TextSegment SwAccessibleParagraph::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 nTextType )
2377 {
2378  SolarMutexGuard aGuard;
2379 
2380  ThrowIfDisposed();
2381 
2382  /*accessibility::*/TextSegment aResult;
2383  aResult.SegmentStart = -1;
2384  aResult.SegmentEnd = -1;
2385  const OUString rText = GetString();
2386 
2387  // implement the silly specification that first position after
2388  // text must return an empty string, rather than throwing an
2389  // IndexOutOfBoundsException
2390  if( nIndex == rText.getLength() )
2391  return aResult;
2392 
2393  // get first word, then skip to next word
2394  i18n::Boundary aBound;
2395  GetTextBoundary( aBound, rText, nIndex, nTextType );
2396  bool bWord = false;
2397  while( !bWord )
2398  {
2399  nIndex = max( sal_Int32(nIndex+1), aBound.endPos );
2400  if( nIndex < rText.getLength() )
2401  bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
2402  else
2403  break; // exit if end of string is reached
2404  }
2405 
2406  if ( bWord )
2407  {
2408  aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
2409  aResult.SegmentStart = aBound.startPos;
2410  aResult.SegmentEnd = aBound.endPos;
2411  }
2412 
2413 /*
2414  sal_Bool bWord = sal_False;
2415  bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
2416 
2417  if (nTextType==2)
2418  {
2419  Boundary nexBound=aBound;
2420 
2421  // real current word
2422  if( nIndex <= aBound.endPos && nIndex >= aBound.startPos )
2423  {
2424  while(nexBound.endPos==aBound.endPos&&nIndex<rText.getLength())
2425  {
2426  // nIndex = max( (sal_Int32)(nIndex), nexBound.endPos) + 1;
2427  nIndex = max( (sal_Int32)(nIndex), nexBound.endPos) ;
2428  const sal_Unicode* pStr = rText.getStr();
2429  if (pStr)
2430  {
2431  if( pStr[nIndex] == sal_Unicode(' ') )
2432  nIndex++;
2433  }
2434  if( nIndex < rText.getLength() )
2435  {
2436  bWord = GetTextBoundary( nexBound, rText, nIndex, nTextType );
2437  }
2438  }
2439  }
2440 
2441  if (bWord && nIndex<rText.getLength())
2442  {
2443  aResult.SegmentText = rText.copy( nexBound.startPos, nexBound.endPos - nexBound.startPos );
2444  aResult.SegmentStart = nexBound.startPos;
2445  aResult.SegmentEnd = nexBound.endPos;
2446  }
2447 
2448  }
2449  else
2450  {
2451  bWord = sal_False;
2452  while( !bWord )
2453  {
2454  nIndex = max( (sal_Int32)(nIndex+1), aBound.endPos );
2455  if( nIndex < rText.getLength() )
2456  {
2457  bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
2458  }
2459  else
2460  break; // exit if end of string is reached
2461  }
2462  if (bWord && nIndex<rText.getLength())
2463  {
2464  aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
2465  aResult.SegmentStart = aBound.startPos;
2466  aResult.SegmentEnd = aBound.endPos;
2467  }
2468  }
2469 */
2470  return aResult;
2471 }
2472 
2473 sal_Bool SwAccessibleParagraph::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2474 {
2475  SolarMutexGuard aGuard;
2476 
2477  ThrowIfDisposed();
2478 
2479  // select and copy (through dispatch mechanism)
2480  setSelection( nStartIndex, nEndIndex );
2481  ExecuteAtViewShell( SID_COPY );
2482  return true;
2483 }
2484 
2486  sal_Int32 nEndIndex, AccessibleScrollType aScrollType )
2487 {
2488  SolarMutexGuard aGuard;
2489 
2490  ThrowIfDisposed();
2491 
2492  // parameter checking
2493  sal_Int32 nLength = GetString().getLength();
2494  if ( ! IsValidRange( nStartIndex, nEndIndex, nLength ) )
2495  throw lang::IndexOutOfBoundsException();
2496 
2497  vcl::Window *pWin = GetWindow();
2498  if ( ! pWin )
2499  throw uno::RuntimeException("no Window", static_cast<cppu::OWeakObject*>(this));
2500 
2501  /* Start and end character bounds, in pixels, relative to the paragraph */
2502  awt::Rectangle startR, endR;
2503  startR = getCharacterBounds(nStartIndex);
2504  endR = getCharacterBounds(nEndIndex);
2505 
2506  /* Adjust points to fit the bounding box of both bounds. */
2507  Point sP(std::min(startR.X, endR.X), startR.Y);
2508  Point eP(std::max(startR.X + startR.Width, endR.X + endR.Width), endR.Y + endR.Height);
2509 
2510  /* Offset the values relative to the view shell frame */
2511  SwRect aFrameLogBounds( GetBounds( *(GetMap()) ) ); // twip rel to doc root
2512  Point aFramePixPos( GetMap()->CoreToPixel( aFrameLogBounds ).TopLeft() );
2513  sP += aFramePixPos;
2514  eP += aFramePixPos;
2515 
2516  Point startPoint(GetMap()->PixelToCore(sP));
2517  Point endPoint(GetMap()->PixelToCore(eP));
2518 
2519  switch (aScrollType)
2520  {
2521 #ifdef notyet
2522  case AccessibleScrollType_SCROLL_TOP_LEFT:
2523  break;
2524  case AccessibleScrollType_SCROLL_BOTTOM_RIGHT:
2525  break;
2526  case AccessibleScrollType_SCROLL_TOP_EDGE:
2527  break;
2528  case AccessibleScrollType_SCROLL_BOTTOM_EDGE:
2529  break;
2530  case AccessibleScrollType_SCROLL_LEFT_EDGE:
2531  break;
2532  case AccessibleScrollType_SCROLL_RIGHT_EDGE:
2533  break;
2534 #endif
2535  case AccessibleScrollType_SCROLL_ANYWHERE:
2536  break;
2537  default:
2538  return false;
2539  }
2540 
2541  const SwRect aRect(startPoint, endPoint);
2542  SwViewShell* pViewShell = GetMap()->GetShell();
2543  OSL_ENSURE( pViewShell != nullptr, "View shell expected!" );
2544 
2545  ScrollMDI(pViewShell, aRect, USHRT_MAX, USHRT_MAX);
2546 
2547  return true;
2548 }
2549 
2550 // XAccessibleEditableText
2551 
2552 sal_Bool SwAccessibleParagraph::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2553 {
2554  SolarMutexGuard aGuard;
2555 
2556  ThrowIfDisposed();
2557 
2558  if( !IsEditableState() )
2559  return false;
2560 
2561  // select and cut (through dispatch mechanism)
2562  setSelection( nStartIndex, nEndIndex );
2563  ExecuteAtViewShell( SID_CUT );
2564  return true;
2565 }
2566 
2568 {
2569  SolarMutexGuard aGuard;
2570 
2571  ThrowIfDisposed();
2572 
2573  if( !IsEditableState() )
2574  return false;
2575 
2576  // select and paste (through dispatch mechanism)
2577  setSelection( nIndex, nIndex );
2578  ExecuteAtViewShell( SID_PASTE );
2579  return true;
2580 }
2581 
2582 sal_Bool SwAccessibleParagraph::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2583 {
2584  return replaceText( nStartIndex, nEndIndex, OUString() );
2585 }
2586 
2587 sal_Bool SwAccessibleParagraph::insertText( const OUString& sText, sal_Int32 nIndex )
2588 {
2589  return replaceText( nIndex, nIndex, sText );
2590 }
2591 
2593  sal_Int32 nStartIndex, sal_Int32 nEndIndex,
2594  const OUString& sReplacement )
2595 {
2596  SolarMutexGuard aGuard;
2597 
2598  ThrowIfDisposed();
2599 
2600  const OUString& rText = GetString();
2601 
2602  if( !IsValidRange( nStartIndex, nEndIndex, rText.getLength() ) )
2603  throw lang::IndexOutOfBoundsException();
2604 
2605  if( !IsEditableState() )
2606  return false;
2607 
2608  // translate positions
2609  TextFrameIndex nStart;
2610  TextFrameIndex nEnd;
2611  bool bSuccess = GetPortionData().GetEditableRange(
2612  nStartIndex, nEndIndex, nStart, nEnd );
2613 
2614  // edit only if the range is editable
2615  if( bSuccess )
2616  {
2617  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
2618  // create SwPosition for nStartIndex
2619  SwPosition aStartPos(pFrame->MapViewToModelPos(nStart));
2620 
2621  // create SwPosition for nEndIndex
2622  SwPosition aEndPos(pFrame->MapViewToModelPos(nEnd));
2623 
2624  // now create XTextRange as helper and set string
2625  const uno::Reference<text::XTextRange> xRange(
2627  const_cast<SwDoc&>(pFrame->GetDoc()), aStartPos, &aEndPos));
2628  xRange->setString(sReplacement);
2629 
2630  // delete portion data
2631  ClearPortionData();
2632  }
2633 
2634  return bSuccess;
2635 
2636 }
2637 
2639  sal_Int32 nStartIndex,
2640  sal_Int32 nEndIndex,
2641  const uno::Sequence<PropertyValue>& rAttributeSet )
2642 {
2643  SolarMutexGuard aGuard;
2644 
2645  ThrowIfDisposed();
2646 
2647  const OUString& rText = GetString();
2648 
2649  if( ! IsValidRange( nStartIndex, nEndIndex, rText.getLength() ) )
2650  throw lang::IndexOutOfBoundsException();
2651 
2652  if( !IsEditableState() )
2653  return false;
2654 
2655  // create a (dummy) text portion for the sole purpose of calling
2656  // setPropertyValue on it
2657  rtl::Reference<SwXTextPortion> xPortion = CreateUnoPortion( nStartIndex,
2658  nEndIndex );
2659 
2660  // build sorted index array
2661  sal_Int32 nLength = rAttributeSet.getLength();
2662  const PropertyValue* pPairs = rAttributeSet.getConstArray();
2663  std::vector<sal_Int32> aIndices(nLength);
2664  std::iota(aIndices.begin(), aIndices.end(), 0);
2665  std::sort(aIndices.begin(), aIndices.end(), IndexCompare(pPairs));
2666 
2667  // create sorted sequences according to index array
2668  uno::Sequence< OUString > aNames( nLength );
2669  OUString* pNames = aNames.getArray();
2670  uno::Sequence< uno::Any > aValues( nLength );
2671  uno::Any* pValues = aValues.getArray();
2672  for (sal_Int32 i = 0; i < nLength; ++i)
2673  {
2674  const PropertyValue& rVal = pPairs[aIndices[i]];
2675  pNames[i] = rVal.Name;
2676  pValues[i] = rVal.Value;
2677  }
2678  aIndices.clear();
2679 
2680  // now set the values
2681  bool bRet = true;
2682  try
2683  {
2684  xPortion->setPropertyValues( aNames, aValues );
2685  }
2686  catch (const UnknownPropertyException&)
2687  {
2688  // error handling through return code!
2689  bRet = false;
2690  }
2691 
2692  return bRet;
2693 }
2694 
2696 {
2697  return replaceText(0, GetString().getLength(), sText);
2698 }
2699 
2700 // XAccessibleSelection
2701 
2703  sal_Int32 nChildIndex )
2704 {
2705  ThrowIfDisposed();
2706 
2708 }
2709 
2711  sal_Int32 nChildIndex )
2712 {
2713  ThrowIfDisposed();
2714 
2715  return m_aSelectionHelper.isAccessibleChildSelected(nChildIndex);
2716 }
2717 
2719 {
2720  ThrowIfDisposed();
2721 }
2722 
2724 {
2725  ThrowIfDisposed();
2726 
2728 }
2729 
2731 {
2732  ThrowIfDisposed();
2733 
2735 }
2736 
2738  sal_Int32 nSelectedChildIndex )
2739 {
2740  ThrowIfDisposed();
2741 
2742  return m_aSelectionHelper.getSelectedAccessibleChild(nSelectedChildIndex);
2743 }
2744 
2745 // index has to be treated as global child index.
2747  sal_Int32 nChildIndex )
2748 {
2749  ThrowIfDisposed();
2750 
2752 }
2753 
2754 // XAccessibleHypertext
2755 
2756 namespace {
2757 
2758 class SwHyperlinkIter_Impl
2759 {
2760  SwTextFrame const& m_rFrame;
2761  sw::MergedAttrIter m_Iter;
2762  TextFrameIndex m_nStt;
2763  TextFrameIndex m_nEnd;
2764 
2765 public:
2766  explicit SwHyperlinkIter_Impl(const SwTextFrame & rTextFrame);
2767  const SwTextAttr *next(SwTextNode const** ppNode = nullptr);
2768 
2769  TextFrameIndex startIdx() const { return m_nStt; }
2770  TextFrameIndex endIdx() const { return m_nEnd; }
2771 };
2772 
2773 }
2774 
2775 SwHyperlinkIter_Impl::SwHyperlinkIter_Impl(const SwTextFrame & rTextFrame)
2776  : m_rFrame(rTextFrame)
2777  , m_Iter(rTextFrame)
2778  , m_nStt(rTextFrame.GetOffset())
2779 {
2780  const SwTextFrame *const pFollFrame = rTextFrame.GetFollow();
2781  m_nEnd = pFollFrame ? pFollFrame->GetOffset() : TextFrameIndex(rTextFrame.GetText().getLength());
2782 }
2783 
2784 const SwTextAttr *SwHyperlinkIter_Impl::next(SwTextNode const** ppNode)
2785 {
2786  const SwTextAttr *pAttr = nullptr;
2787  if (ppNode)
2788  {
2789  *ppNode = nullptr;
2790  }
2791 
2792  SwTextNode const* pNode(nullptr);
2793  while (SwTextAttr const*const pHt = m_Iter.NextAttr(&pNode))
2794  {
2795  if (RES_TXTATR_INETFMT == pHt->Which())
2796  {
2797  const TextFrameIndex nHtStt(m_rFrame.MapModelToView(pNode, pHt->GetStart()));
2798  const TextFrameIndex nHtEnd(m_rFrame.MapModelToView(pNode, pHt->GetAnyEnd()));
2799  if (nHtEnd > nHtStt &&
2800  ((nHtStt >= m_nStt && nHtStt < m_nEnd) ||
2801  (nHtEnd > m_nStt && nHtEnd <= m_nEnd)))
2802  {
2803  pAttr = pHt;
2804  if (ppNode)
2805  {
2806  *ppNode = pNode;
2807  }
2808  break;
2809  }
2810  }
2811  }
2812 
2813  return pAttr;
2814 };
2815 
2817 {
2818  SolarMutexGuard aGuard;
2819 
2820  ThrowIfDisposed();
2821 
2822  sal_Int32 nCount = 0;
2823  // #i77108# - provide hyperlinks also in editable documents.
2824 
2825  const SwTextFrame *pTextFrame = static_cast<const SwTextFrame*>( GetFrame() );
2826  SwHyperlinkIter_Impl aIter(*pTextFrame);
2827  while( aIter.next() )
2828  nCount++;
2829 
2830  return nCount;
2831 }
2832 
2833 uno::Reference< XAccessibleHyperlink > SAL_CALL
2834  SwAccessibleParagraph::getHyperLink( sal_Int32 nLinkIndex )
2835 {
2836  SolarMutexGuard aGuard;
2837 
2838  ThrowIfDisposed();
2839 
2840  uno::Reference< XAccessibleHyperlink > xRet;
2841 
2842  const SwTextFrame *pTextFrame = static_cast<const SwTextFrame*>( GetFrame() );
2843  SwHyperlinkIter_Impl aHIter(*pTextFrame);
2844  SwTextNode const* pNode(nullptr);
2845  SwTextAttr* pHt = const_cast<SwTextAttr*>(aHIter.next(&pNode));
2846  for (sal_Int32 nTIndex = 0; pHt && nTIndex <= nLinkIndex; ++nTIndex)
2847  {
2848  if( nTIndex == nLinkIndex )
2849  { // found
2850  if (!m_pHyperTextData)
2853  m_pHyperTextData ->find( pHt );
2854  if (aIter != m_pHyperTextData->end())
2855  {
2856  xRet = (*aIter).second;
2857  }
2858  if (!xRet.is())
2859  {
2860  TextFrameIndex const nHintStart(pTextFrame->MapModelToView(pNode, pHt->GetStart()));
2861  TextFrameIndex const nHintEnd(pTextFrame->MapModelToView(pNode, pHt->GetAnyEnd()));
2862  const sal_Int32 nTmpHStt = GetPortionData().GetAccessiblePosition(
2863  max(aHIter.startIdx(), nHintStart));
2864  const sal_Int32 nTmpHEnd = GetPortionData().GetAccessiblePosition(
2865  min(aHIter.endIdx(), nHintEnd));
2866  xRet = new SwAccessibleHyperlink(*pHt,
2867  *this, nTmpHStt, nTmpHEnd );
2868  if (aIter != m_pHyperTextData->end())
2869  {
2870  (*aIter).second = xRet;
2871  }
2872  else
2873  {
2874  m_pHyperTextData->emplace( pHt, xRet );
2875  }
2876  }
2877  break;
2878  }
2879 
2880  // iterate next hyperlink
2881  pHt = const_cast<SwTextAttr*>(aHIter.next(&pNode));
2882  }
2883  if( !xRet.is() )
2884  throw lang::IndexOutOfBoundsException();
2885 
2886  return xRet;
2887 }
2888 
2889 sal_Int32 SAL_CALL SwAccessibleParagraph::getHyperLinkIndex( sal_Int32 nCharIndex )
2890 {
2891  SolarMutexGuard aGuard;
2892 
2893  ThrowIfDisposed();
2894 
2895  // parameter checking
2896  sal_Int32 nLength = GetString().getLength();
2897  if ( ! IsValidPosition( nCharIndex, nLength ) )
2898  {
2899  throw lang::IndexOutOfBoundsException();
2900  }
2901 
2902  sal_Int32 nRet = -1;
2903  // #i77108#
2904  {
2905  const SwTextFrame *pTextFrame = static_cast<const SwTextFrame*>( GetFrame() );
2906  SwHyperlinkIter_Impl aHIter(*pTextFrame);
2907 
2908  const TextFrameIndex nIdx = GetPortionData().GetCoreViewPosition(nCharIndex);
2909  sal_Int32 nPos = 0;
2910  SwTextNode const* pNode(nullptr);
2911  const SwTextAttr *pHt = aHIter.next(&pNode);
2912  while (pHt && (nIdx < pTextFrame->MapModelToView(pNode, pHt->GetStart())
2913  || nIdx >= pTextFrame->MapModelToView(pNode, pHt->GetAnyEnd())))
2914  {
2915  pHt = aHIter.next(&pNode);
2916  nPos++;
2917  }
2918 
2919  if( pHt )
2920  nRet = nPos;
2921  }
2922 
2923  if (nRet == -1)
2924  throw lang::IndexOutOfBoundsException();
2925  return nRet;
2926 }
2927 
2928 // #i71360#, #i108125# - adjustments for change tracking text markup
2929 sal_Int32 SAL_CALL SwAccessibleParagraph::getTextMarkupCount( sal_Int32 nTextMarkupType )
2930 {
2931  SolarMutexGuard g;
2932 
2933  std::unique_ptr<SwTextMarkupHelper> pTextMarkupHelper;
2934  switch ( nTextMarkupType )
2935  {
2936  case text::TextMarkupType::TRACK_CHANGE_INSERTION:
2937  case text::TextMarkupType::TRACK_CHANGE_DELETION:
2938  case text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE:
2939  {
2940  pTextMarkupHelper.reset( new SwTextMarkupHelper(
2941  GetPortionData(),
2942  *(mpParaChangeTrackInfo->getChangeTrackingTextMarkupList( nTextMarkupType ) )) );
2943  }
2944  break;
2945  default:
2946  {
2947  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
2948  pTextMarkupHelper.reset(new SwTextMarkupHelper(GetPortionData(), *pFrame));
2949  }
2950  }
2951 
2952  return pTextMarkupHelper->getTextMarkupCount( nTextMarkupType );
2953 }
2954 
2955 //MSAA Extension Implementation in app module
2956 sal_Bool SAL_CALL SwAccessibleParagraph::scrollToPosition( const css::awt::Point&, sal_Bool )
2957 {
2958  return false;
2959 }
2960 
2962 {
2963  SolarMutexGuard g;
2964 
2965  sal_Int32 nSelected = 0;
2966  SwPaM* pCursor = GetCursor( true );
2967  if( pCursor != nullptr )
2968  {
2969  // get SwPosition for my node
2970  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
2971  sal_uLong nFirstNode(pFrame->GetTextNodeFirst()->GetIndex());
2972  sal_uLong nLastNode;
2973  if (sw::MergedPara const*const pMerged = pFrame->GetMergedPara())
2974  {
2975  nLastNode = pMerged->pLastNode->GetIndex();
2976  }
2977  else
2978  {
2979  nLastNode = nFirstNode;
2980  }
2981 
2982  // iterate over ring
2983  for(SwPaM& rTmpCursor : pCursor->GetRingContainer())
2984  {
2985  // ignore, if no mark
2986  if( rTmpCursor.HasMark() )
2987  {
2988  // check whether frame's node(s) are 'inside' pCursor
2989  SwPosition* pStart = rTmpCursor.Start();
2990  sal_uLong nStartIndex = pStart->nNode.GetIndex();
2991  SwPosition* pEnd = rTmpCursor.End();
2992  sal_uLong nEndIndex = pEnd->nNode.GetIndex();
2993  if ((nStartIndex <= nLastNode) && (nFirstNode <= nEndIndex))
2994  {
2995  nSelected++;
2996  }
2997  // else: this PaM doesn't point to this paragraph
2998  }
2999  // else: this PaM is collapsed and doesn't select anything
3000  }
3001  }
3002  return nSelected;
3003 
3004 }
3005 
3006 sal_Int32 SAL_CALL SwAccessibleParagraph::getSeletedPositionStart( sal_Int32 nSelectedPortionIndex )
3007 {
3008  SolarMutexGuard aGuard;
3009 
3010  ThrowIfDisposed();
3011 
3012  sal_Int32 nStart=-1, nEnd=-1;
3013  /*sal_Bool bSelected = */GetSelectionAtIndex(&nSelectedPortionIndex, nStart, nEnd );
3014  return nStart;
3015 }
3016 
3017 sal_Int32 SAL_CALL SwAccessibleParagraph::getSeletedPositionEnd( sal_Int32 nSelectedPortionIndex )
3018 {
3019  SolarMutexGuard aGuard;
3020 
3021  ThrowIfDisposed();
3022 
3023  sal_Int32 nStart=-1, nEnd=-1;
3024  /*sal_Bool bSelected = */GetSelectionAtIndex(&nSelectedPortionIndex, nStart, nEnd );
3025  return nEnd;
3026 }
3027 
3028 sal_Bool SAL_CALL SwAccessibleParagraph::removeSelection( sal_Int32 selectionIndex )
3029 {
3030  SolarMutexGuard g;
3031 
3032  if(selectionIndex < 0) return false;
3033 
3034  sal_Int32 nSelected = selectionIndex;
3035 
3036  // get the selection, and test whether it affects our text node
3037  SwPaM* pCursor = GetCursor( true );
3038 
3039  if( pCursor != nullptr )
3040  {
3041  bool bRet = false;
3042 
3043  // get SwPosition for my node
3044  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
3045  sal_uLong nFirstNode(pFrame->GetTextNodeFirst()->GetIndex());
3046  sal_uLong nLastNode;
3047  if (sw::MergedPara const*const pMerged = pFrame->GetMergedPara())
3048  {
3049  nLastNode = pMerged->pLastNode->GetIndex();
3050  }
3051  else
3052  {
3053  nLastNode = nFirstNode;
3054  }
3055 
3056  // iterate over ring
3057  SwPaM* pRingStart = pCursor;
3058  do
3059  {
3060  // ignore, if no mark
3061  if( pCursor->HasMark() )
3062  {
3063  // check whether frame's node(s) are 'inside' pCursor
3064  SwPosition* pStart = pCursor->Start();
3065  sal_uLong nStartIndex = pStart->nNode.GetIndex();
3066  SwPosition* pEnd = pCursor->End();
3067  sal_uLong nEndIndex = pEnd->nNode.GetIndex();
3068  if ((nStartIndex <= nLastNode) && (nFirstNode <= nEndIndex))
3069  {
3070  if( nSelected == 0 )
3071  {
3072  pCursor->MoveTo(nullptr);
3073  delete pCursor;
3074  bRet = true;
3075  }
3076  else
3077  {
3078  nSelected--;
3079  }
3080  }
3081  }
3082  // else: this PaM is collapsed and doesn't select anything
3083  if(!bRet)
3084  pCursor = pCursor->GetNext();
3085  }
3086  while( !bRet && (pCursor != pRingStart) );
3087  }
3088  return true;
3089 }
3090 
3091 sal_Int32 SAL_CALL SwAccessibleParagraph::addSelection( sal_Int32, sal_Int32 startOffset, sal_Int32 endOffset)
3092 {
3093  SolarMutexGuard aGuard;
3094 
3095  ThrowIfDisposed();
3096 
3097  // parameter checking
3098  sal_Int32 nLength = GetString().getLength();
3099  if ( ! IsValidRange( startOffset, endOffset, nLength ) )
3100  {
3101  throw lang::IndexOutOfBoundsException();
3102  }
3103 
3104  sal_Int32 nSelectedCount = getSelectedPortionCount();
3105  for ( sal_Int32 i = nSelectedCount ; i >= 0 ; i--)
3106  {
3107  sal_Int32 nStart, nEnd;
3108  bool bSelected = GetSelectionAtIndex(&i, nStart, nEnd );
3109  if(bSelected)
3110  {
3111  if(nStart <= nEnd )
3112  {
3113  if (( startOffset>=nStart && startOffset <=nEnd ) || //startOffset in a selection
3114  ( endOffset>=nStart && endOffset <=nEnd ) || //endOffset in a selection
3115  ( startOffset <= nStart && endOffset >=nEnd) || //start and end include the old selection
3116  ( startOffset >= nStart && endOffset <=nEnd) )
3117  {
3118  removeSelection(i);
3119  }
3120 
3121  }
3122  else
3123  {
3124  if (( startOffset>=nEnd && startOffset <=nStart ) || //startOffset in a selection
3125  ( endOffset>=nEnd && endOffset <=nStart ) || //endOffset in a selection
3126  ( startOffset <= nStart && endOffset >=nEnd) || //start and end include the old selection
3127  ( startOffset >= nStart && endOffset <=nEnd) )
3128 
3129  {
3130  removeSelection(i);
3131  }
3132  }
3133  }
3134 
3135  }
3136 
3137  // get cursor shell
3138  SwCursorShell* pCursorShell = GetCursorShell();
3139  if( pCursorShell != nullptr )
3140  {
3141  // create pam for selection
3142  pCursorShell->StartAction();
3143  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
3144  SwPaM* aPaM = pCursorShell->CreateCursor();
3145  aPaM->SetMark();
3146  *aPaM->GetPoint() = pFrame->MapViewToModelPos(GetPortionData().GetCoreViewPosition(startOffset));
3147  *aPaM->GetMark() = pFrame->MapViewToModelPos(GetPortionData().GetCoreViewPosition(endOffset));
3148  pCursorShell->EndAction();
3149  }
3150 
3151  return 0;
3152 }
3153 
3154 /*accessibility::*/TextSegment SAL_CALL
3155  SwAccessibleParagraph::getTextMarkup( sal_Int32 nTextMarkupIndex,
3156  sal_Int32 nTextMarkupType )
3157 {
3158  SolarMutexGuard g;
3159 
3160  std::unique_ptr<SwTextMarkupHelper> pTextMarkupHelper;
3161  switch ( nTextMarkupType )
3162  {
3163  case text::TextMarkupType::TRACK_CHANGE_INSERTION:
3164  case text::TextMarkupType::TRACK_CHANGE_DELETION:
3165  case text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE:
3166  {
3167  pTextMarkupHelper.reset( new SwTextMarkupHelper(
3168  GetPortionData(),
3169  *(mpParaChangeTrackInfo->getChangeTrackingTextMarkupList( nTextMarkupType ) )) );
3170  }
3171  break;
3172  default:
3173  {
3174  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
3175  pTextMarkupHelper.reset(new SwTextMarkupHelper(GetPortionData(), *pFrame));
3176  }
3177  }
3178 
3179  return pTextMarkupHelper->getTextMarkup( nTextMarkupIndex, nTextMarkupType );
3180 }
3181 
3182 uno::Sequence< /*accessibility::*/TextSegment > SAL_CALL
3184  sal_Int32 nTextMarkupType )
3185 {
3186  SolarMutexGuard g;
3187 
3188  // parameter checking
3189  const sal_Int32 nLength = GetString().getLength();
3190  if ( ! IsValidPosition( nCharIndex, nLength ) )
3191  {
3192  throw lang::IndexOutOfBoundsException();
3193  }
3194 
3195  std::unique_ptr<SwTextMarkupHelper> pTextMarkupHelper;
3196  switch ( nTextMarkupType )
3197  {
3198  case text::TextMarkupType::TRACK_CHANGE_INSERTION:
3199  case text::TextMarkupType::TRACK_CHANGE_DELETION:
3200  case text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE:
3201  {
3202  pTextMarkupHelper.reset( new SwTextMarkupHelper(
3203  GetPortionData(),
3204  *(mpParaChangeTrackInfo->getChangeTrackingTextMarkupList( nTextMarkupType ) )) );
3205  }
3206  break;
3207  default:
3208  {
3209  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
3210  pTextMarkupHelper.reset(new SwTextMarkupHelper(GetPortionData(), *pFrame));
3211  }
3212  }
3213 
3214  return pTextMarkupHelper->getTextMarkupAtIndex( nCharIndex, nTextMarkupType );
3215 }
3216 
3217 // #i89175#
3218 sal_Int32 SAL_CALL SwAccessibleParagraph::getLineNumberAtIndex( sal_Int32 nIndex )
3219 {
3220  SolarMutexGuard g;
3221 
3222  // parameter checking
3223  const sal_Int32 nLength = GetString().getLength();
3224  if ( ! IsValidPosition( nIndex, nLength ) )
3225  {
3226  throw lang::IndexOutOfBoundsException();
3227  }
3228 
3229  const sal_Int32 nLineNo = GetPortionData().GetLineNo( nIndex );
3230  return nLineNo;
3231 }
3232 
3233 /*accessibility::*/TextSegment SAL_CALL
3235 {
3236  SolarMutexGuard g;
3237 
3238  // parameter checking
3239  if ( nLineNo < 0 ||
3240  nLineNo >= GetPortionData().GetLineCount() )
3241  {
3242  throw lang::IndexOutOfBoundsException();
3243  }
3244 
3245  i18n::Boundary aLineBound;
3246  GetPortionData().GetBoundaryOfLine( nLineNo, aLineBound );
3247 
3248  /*accessibility::*/TextSegment aTextAtLine;
3249  const OUString rText = GetString();
3250  aTextAtLine.SegmentText = rText.copy( aLineBound.startPos,
3251  aLineBound.endPos - aLineBound.startPos );
3252  aTextAtLine.SegmentStart = aLineBound.startPos;
3253  aTextAtLine.SegmentEnd = aLineBound.endPos;
3254 
3255  return aTextAtLine;
3256 }
3257 
3258 /*accessibility::*/TextSegment SAL_CALL SwAccessibleParagraph::getTextAtLineWithCaret()
3259 {
3260  SolarMutexGuard g;
3261 
3262  const sal_Int32 nLineNoOfCaret = getNumberOfLineWithCaret();
3263 
3264  if ( nLineNoOfCaret >= 0 &&
3265  nLineNoOfCaret < GetPortionData().GetLineCount() )
3266  {
3267  return getTextAtLineNumber( nLineNoOfCaret );
3268  }
3269 
3270  return /*accessibility::*/TextSegment();
3271 }
3272 
3274 {
3275  SolarMutexGuard g;
3276 
3277  const sal_Int32 nCaretPos = getCaretPosition();
3278  const sal_Int32 nLength = GetString().getLength();
3279  if ( !IsValidPosition( nCaretPos, nLength ) )
3280  {
3281  return -1;
3282  }
3283 
3284  sal_Int32 nLineNo = GetPortionData().GetLineNo( nCaretPos );
3285 
3286  // special handling for cursor positioned at end of text line via End key
3287  if ( nCaretPos != 0 )
3288  {
3289  i18n::Boundary aLineBound;
3290  GetPortionData().GetBoundaryOfLine( nLineNo, aLineBound );
3291  if ( nCaretPos == aLineBound.startPos )
3292  {
3294  if ( pCursorShell != nullptr )
3295  {
3296  const awt::Rectangle aCharRect = getCharacterBounds( nCaretPos );
3297 
3298  const SwRect& aCursorCoreRect = pCursorShell->GetCharRect();
3299  // translate core coordinates into accessibility coordinates
3300  vcl::Window *pWin = GetWindow();
3301  if (!pWin)
3302  {
3303  throw uno::RuntimeException("no Window", static_cast<cppu::OWeakObject*>(this));
3304  }
3305 
3306  tools::Rectangle aScreenRect( GetMap()->CoreToPixel( aCursorCoreRect ));
3307 
3308  SwRect aFrameLogBounds( GetBounds( *(GetMap()) ) ); // twip rel to doc root
3309  Point aFramePixPos( GetMap()->CoreToPixel( aFrameLogBounds ).TopLeft() );
3310  aScreenRect.Move( -aFramePixPos.getX(), -aFramePixPos.getY() );
3311 
3312  // convert into AWT Rectangle
3313  const awt::Rectangle aCursorRect( aScreenRect.Left(),
3314  aScreenRect.Top(),
3315  aScreenRect.GetWidth(),
3316  aScreenRect.GetHeight() );
3317 
3318  if ( aCharRect.X != aCursorRect.X ||
3319  aCharRect.Y != aCursorRect.Y )
3320  {
3321  --nLineNo;
3322  }
3323  }
3324  }
3325  }
3326 
3327  return nLineNo;
3328 }
3329 
3330 // #i108125#
3332 {
3333  mpParaChangeTrackInfo->reset();
3334 }
3335 
3337  sal_Int32 * pSelection, sal_Int32& nStart, sal_Int32& nEnd)
3338 {
3339  if (pSelection && *pSelection < 0) return false;
3340 
3341  bool bRet = false;
3342  nStart = -1;
3343  nEnd = -1;
3344 
3345  // get the selection, and test whether it affects our text node
3346  SwPaM* pCursor = GetCursor( true );
3347  if( pCursor != nullptr )
3348  {
3349  // get SwPosition for my node
3350  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
3351  sal_uLong nFirstNode(pFrame->GetTextNodeFirst()->GetIndex());
3352  sal_uLong nLastNode;
3353  if (sw::MergedPara const*const pMerged = pFrame->GetMergedPara())
3354  {
3355  nLastNode = pMerged->pLastNode->GetIndex();
3356  }
3357  else
3358  {
3359  nLastNode = nFirstNode;
3360  }
3361 
3362  // iterate over ring
3363  for(SwPaM& rTmpCursor : pCursor->GetRingContainer())
3364  {
3365  // ignore, if no mark
3366  if( rTmpCursor.HasMark() )
3367  {
3368  // check whether frame's node(s) are 'inside' pCursor
3369  SwPosition* pStart = rTmpCursor.Start();
3370  sal_uLong nStartIndex = pStart->nNode.GetIndex();
3371  SwPosition* pEnd = rTmpCursor.End();
3372  sal_uLong nEndIndex = pEnd->nNode.GetIndex();
3373  if ((nStartIndex <= nLastNode) && (nFirstNode <= nEndIndex))
3374  {
3375  if (!pSelection || *pSelection == 0)
3376  {
3377  // translate start and end positions
3378 
3379  // start position
3380  sal_Int32 nLocalStart = -1;
3381  if (nStartIndex < nFirstNode)
3382  {
3383  // selection starts in previous node:
3384  // then our local selection starts with the paragraph
3385  nLocalStart = 0;
3386  }
3387  else
3388  {
3389  assert(FrameContainsNode(*pFrame, nStartIndex));
3390 
3391  // selection starts in this node:
3392  // then check whether it's before or inside our part of
3393  // the paragraph, and if so, get the proper position
3394  const TextFrameIndex nCoreStart =
3395  pFrame->MapModelToViewPos(*pStart);
3396  if( nCoreStart <
3397  GetPortionData().GetFirstValidCorePosition() )
3398  {
3399  nLocalStart = 0;
3400  }
3401  else if( nCoreStart <=
3402  GetPortionData().GetLastValidCorePosition() )
3403  {
3404  SAL_WARN_IF(
3405  !GetPortionData().IsValidCorePosition(
3406  nCoreStart),
3407  "sw.a11y",
3408  "problem determining valid core position");
3409 
3410  nLocalStart =
3412  nCoreStart );
3413  }
3414  }
3415 
3416  // end position
3417  sal_Int32 nLocalEnd = -1;
3418  if (nLastNode < nEndIndex)
3419  {
3420  // selection ends in following node:
3421  // then our local selection extends to the end
3422  nLocalEnd = GetPortionData().GetAccessibleString().
3423  getLength();
3424  }
3425  else
3426  {
3427  assert(FrameContainsNode(*pFrame, nEndIndex));
3428 
3429  // selection ends in this node: then select everything
3430  // before our part of the node
3431  const TextFrameIndex nCoreEnd =
3432  pFrame->MapModelToViewPos(*pEnd);
3433  if( nCoreEnd >
3434  GetPortionData().GetLastValidCorePosition() )
3435  {
3436  // selection extends beyond out part of this para
3437  nLocalEnd = GetPortionData().GetAccessibleString().
3438  getLength();
3439  }
3440  else if( nCoreEnd >=
3441  GetPortionData().GetFirstValidCorePosition() )
3442  {
3443  // selection is inside our part of this para
3444  SAL_WARN_IF(
3445  !GetPortionData().IsValidCorePosition(
3446  nCoreEnd),
3447  "sw.a11y",
3448  "problem determining valid core position");
3449 
3450  nLocalEnd = GetPortionData().GetAccessiblePosition(
3451  nCoreEnd );
3452  }
3453  }
3454 
3455  if( ( nLocalStart != -1 ) && ( nLocalEnd != -1 ) )
3456  {
3457  nStart = nLocalStart;
3458  nEnd = nLocalEnd;
3459  bRet = true;
3460  }
3461  } // if hit the index
3462  else
3463  {
3464  --*pSelection;
3465  }
3466  }
3467  // else: this PaM doesn't point to this paragraph
3468  }
3469  // else: this PaM is collapsed and doesn't select anything
3470  if(bRet)
3471  break;
3472  }
3473  }
3474  // else: nocursor -> no selection
3475 
3476  if (pSelection && bRet)
3477  {
3478  sal_Int32 nCaretPos = GetCaretPos();
3479  if( nStart == nCaretPos )
3480  {
3481  sal_Int32 tmp = nStart;
3482  nStart = nEnd;
3483  nEnd = tmp;
3484  }
3485  }
3486  return bRet;
3487 }
3488 
3490 {
3491  SolarMutexGuard g;
3492 
3493  //Get the real heading level, Heading1 ~ Heading10
3494  if (m_nHeadingLevel > 0)
3495  {
3496  return AccessibleRole::HEADING;
3497  }
3498  else
3499  {
3500  return AccessibleRole::PARAGRAPH;
3501  }
3502 }
3503 
3504 //Get the real heading level, Heading1 ~ Heading10
3506 {
3507  uno::Reference< css::beans::XPropertySet > xPortion = CreateUnoPortion( 0, 0 );
3508  uno::Any styleAny = xPortion->getPropertyValue( "ParaStyleName" );
3509  OUString sValue;
3510  if (styleAny >>= sValue)
3511  {
3512  sal_Int32 length = sValue.getLength();
3513  if (length == 9 || length == 10)
3514  {
3515  OUString headStr = sValue.copy(0, 7);
3516  if (headStr == "Heading")
3517  {
3518  OUString intStr = sValue.copy(8);
3519  sal_Int32 headingLevel = intStr.toInt32();
3520  return headingLevel;
3521  }
3522  }
3523  }
3524  return -1;
3525 }
3526 
3528 {
3529  SolarMutexGuard g;
3530 
3531  uno::Any Ret;
3532  OUString strHeading("heading-level:");
3533  if( m_nHeadingLevel >= 0 )
3534  strHeading += OUString::number(m_nHeadingLevel);
3535  // tdf#84102: expose the same attribute with the name "level"
3536  strHeading += ";level:";
3537  if( m_nHeadingLevel >= 0 )
3538  strHeading += OUString::number(m_nHeadingLevel);
3539  strHeading += ";";
3540 
3541  Ret <<= strHeading;
3542 
3543  return Ret;
3544 }
3545 
3546 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual sal_Int32 SAL_CALL getSeletedPositionStart(sal_Int32 nSelectedPortionIndex) override
Definition: accpara.cxx:3006
const OUString & GetAccessibleString() const
get the text string, as presented by the layout
void _getDefaultAttributesImpl(const css::uno::Sequence< OUString > &aRequestedAttributes, tAccParaPropValMap &rDefAttrSeq, const bool bOnlyCharAttrs=false)
Definition: accpara.cxx:1439
SfxViewFrame * GetViewFrame() const
static uno::Sequence< OUString > const & getAttributeNames()
Definition: accpara.cxx:884
bool GetWordBoundary(css::i18n::Boundary &rBound, const OUString &rText, sal_Int32 nPos)
Definition: accpara.cxx:554
Base class of the Writer layout elements.
Definition: frame.hxx:315
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:158
static Color & GetFieldShadingsColor()
Definition: viewopt.cxx:461
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: accpara.cxx:879
sal_uLong GetIndex() const
Definition: node.hxx:291
void Right(const tools::Long nRight)
Definition: swrect.hxx:202
void FireAccessibleEvent(css::accessibility::AccessibleEventObject &rEvent)
Definition: acccontext.cxx:443
css::uno::Sequence< css::style::TabStop > GetCurrentTabStop(sal_Int32 nIndex)
Definition: accpara.cxx:1078
friend class SwAccessibleHyperlink
Definition: accpara.hxx:65
sal_Int32 nIndex
virtual sal_Bool SAL_CALL setSelection(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
Definition: accpara.cxx:2210
bool GetAttributeBoundary(css::i18n::Boundary &rBound, sal_Int32 nPos)
Definition: accpara.cxx:612
static bool GetParagraphBoundary(css::i18n::Boundary &rBound, const OUString &rText)
Definition: accpara.cxx:603
Marks a position in the document model.
Definition: pam.hxx:35
constexpr TypedWhichId< SvxTabStopItem > RES_PARATR_TABSTOP(68)
static bool lcl_GetBackgroundColor(Color &rColor, const SwFrame *pFrame, SwCursorShell *pCursorSh)
Definition: accpara.cxx:801
const SwField * GetField() const
Definition: fmtfld.hxx:110
SwTextFrame * DynCastTextFrame()
Definition: findfrm.cxx:1841
#define UNO_NAME_CHAR_UNDERLINE_COLOR
Definition: unoprnms.hxx:109
LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript, bool bNoChar=false) const
Definition: txtfrm.cxx:1344
static OUString GetDescription()
Definition: accpara.cxx:122
#define PROPERTY_MAP_TEXT_CURSOR
Definition: unomap.hxx:27
void ExecuteAtViewShell(sal_uInt16 nSlot)
Definition: accpara.cxx:455
bool m_bRealHeight
should the real height be calculated?
Definition: crstate.hxx:141
SwViewShellImp * Imp()
Definition: viewsh.hxx:182
static constexpr auto Items
bool IsOutline() const
Returns if this text node is an outline.
Definition: ndtxt.cxx:3953
virtual sal_Int32 SAL_CALL getSeletedPositionEnd(sal_Int32 nSelectedPortionIndex) override
Definition: accpara.cxx:3017
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex) override
Definition: accpara.cxx:2737
#define UNO_NAME_CHAR_FONT_NAME
Definition: unoprnms.hxx:84
virtual void SAL_CALL selectAccessibleChild(sal_Int32 nChildIndex) override
Definition: accpara.cxx:2702
sal_uInt32 GetFormat() const
Query parameters for dialog and for BASIC.
Definition: fldbas.hxx:397
virtual void GetStates(::utl::AccessibleStateSetHelper &rStateSet) override
Definition: accpara.cxx:215
bool HasPara() const
Definition: txtfrm.hxx:819
OUString const & GetString()
get the (accessible) text string (requires frame; check before)
Definition: accpara.cxx:117
constexpr tools::Long Left() const
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
virtual sal_Int32 SAL_CALL getHyperLinkCount() override
Definition: accpara.cxx:2816
SwNodeIndex nNode
Definition: pam.hxx:37
bool IsTableMode() const
Definition: crsrsh.hxx:643
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
bool IsHeading() const
Definition: accpara.cxx:208
virtual sal_Int32 SAL_CALL getBackground() override
Definition: accpara.cxx:854
TextFrameIndex FillSpecialPos(sal_Int32 nPos, SwSpecialPos &rPos, SwSpecialPos *&rpPos) const
fill a SwSpecialPos structure, suitable for calling SwTextFrame->GetCharRect Returns the core positio...
virtual sal_Bool SAL_CALL setAttributes(sal_Int32 nStartIndex, sal_Int32 nEndIndex, const css::uno::Sequence< css::beans::PropertyValue > &aAttributeSet) override
Definition: accpara.cxx:2638
SwFrameType GetType() const
Definition: frame.hxx:520
#define UNO_NAME_PARA_LEFT_MARGIN
Definition: unoprnms.hxx:56
SfxDispatcher * GetDispatcher()
void _getSupplementalAttributesImpl(const css::uno::Sequence< OUString > &aRequestedAttributes, tAccParaPropValMap &rSupplementalAttrSeq)
Definition: accpara.cxx:1747
virtual sal_Int32 SAL_CALL getForeground() override
virtual css::awt::Rectangle SAL_CALL getCharacterBounds(sal_Int32 nIndex) override
Definition: accpara.cxx:2033
sal_uIntPtr sal_uLong
constexpr::Color COL_TRANSPARENT(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
virtual sal_Int32 SAL_CALL getSelectionEnd() override
Definition: accpara.cxx:2199
constexpr TypedWhichId< SwNumRuleItem > RES_PARATR_NUMRULE(72)
vcl::Window * GetWindow()
Definition: acccontext.cxx:83
virtual sal_Unicode SAL_CALL getCharacter(sal_Int32 nIndex) override
Definition: accpara.cxx:1063
const SwPosition * GetMark() const
Definition: pam.hxx:209
virtual sal_Bool SAL_CALL scrollToPosition(const css::awt::Point &aPoint, sal_Bool isLeftTop) override
Definition: accpara.cxx:2956
Base class of all fields.
Definition: fldbas.hxx:289
virtual sal_Bool SAL_CALL setText(const OUString &sText) override
Definition: accpara.cxx:2695
constexpr::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
#define UNO_NAME_PARA_STYLE_NAME
Definition: unoprnms.hxx:173
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:450
virtual sal_Bool SAL_CALL isAccessibleChildSelected(sal_Int32 nChildIndex) override
Definition: accpara.cxx:2710
#define PROPERTY_MAP_ACCESSIBILITY_TEXT_ATTRIBUTE
Definition: unomap.hxx:124
virtual css::lang::Locale SAL_CALL getLocale() override
Return the parents locale or throw exception if this object has no parent yet/anymore.
Definition: accpara.cxx:716
bool m_bRealWidth
Calculation of the width required.
Definition: crstate.hxx:149
const SfxItemPropertySet * GetPropertySet(sal_uInt16 PropertyId)
Definition: unomap1.cxx:1062
bool GetSelectionAtIndex(sal_Int32 *pSelection, sal_Int32 &nStart, sal_Int32 &nEnd)
Definition: accpara.cxx:3336
constexpr sal_uInt16 RES_FRMATR_END(133)
#define max(a, b)
SwViewShell * GetShell()
convenience method to get the SwViewShell through accessibility map
Definition: acccontext.hxx:119
constexpr OUStringLiteral sServiceName
Definition: accpara.cxx:114
virtual bool GetCharRect(SwRect &rRect, const SwPosition &rPos, SwCursorMoveState *pCMS=nullptr, bool bAllowFarAway=true) const override
Returns the screen position of rPos.
Definition: frmcrsr.cxx:178
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getRunAttributes(sal_Int32 nIndex, const css::uno::Sequence< OUString > &aRequestedAttributes) override
Definition: accpara.cxx:1725
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
In nOffset returns the offset of the char within the set text buffer, which is closest to the positio...
Definition: frmcrsr.cxx:661
virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
Definition: accpara.cxx:2376
virtual sal_Bool SAL_CALL insertText(const OUString &sText, sal_Int32 nIndex) override
Definition: accpara.cxx:2587
virtual sal_Int32 SAL_CALL getHyperLinkIndex(sal_Int32 nCharIndex) override
Definition: accpara.cxx:2889
void Pos(const Point &rNew)
Definition: swrect.hxx:171
virtual sal_Int32 SAL_CALL getSelectedPortionCount() override
Definition: accpara.cxx:2961
#define UNO_NAME_WRITING_MODE
Definition: unoprnms.hxx:691
virtual sal_Bool SAL_CALL pasteText(sal_Int32 nIndex) override
Definition: accpara.cxx:2567
virtual void InvalidateFocus_() override
Definition: accpara.cxx:379
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
SfxViewShell * GetSfxViewShell() const
Definition: viewsh.hxx:442
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1294
bool IsInside(TextFrameIndex nPos) const
Respect the Follows.
Definition: txtfrm.hxx:829
sal_Int32 GetAnyEnd() const
end (if available), else start
Definition: txatbase.hxx:157
const AuthorCharAttr & GetInsertAuthorAttr() const
Definition: modcfg.hxx:245
static const OUString & GetTypeStr(SwFieldTypesEnum nTypeId)
Definition: fldbas.cxx:122
SwAccessiblePortionData & GetPortionData()
Definition: accpara.hxx:190
constexpr TypedWhichId< SwFormatField > RES_TXTATR_ANNOTATION(59)
static bool IsValidRange(sal_Int32 nBegin, sal_Int32 nEnd, sal_Int32 nLength)
Definition: accpara.cxx:520
sal_uInt16 m_nAttr
Definition: authratr.hxx:30
void MoveTo(value_type *pDestRing)
Removes this item from its current ring container and adds it to another ring container.
Definition: ring.hxx:135
SwTextAttr const * NextAttr(SwTextNode const **ppNode=nullptr)
Definition: txtfrm.cxx:89
bool IsSymbolAt(sal_Int32 nBegin) const
in ndcopy.cxx
Definition: itratr.cxx:853
virtual sal_Int32 SAL_CALL getNumberOfLineWithCaret() override
Definition: accpara.cxx:3273
rtl::Reference< SwXTextPortion > CreateUnoPortion(sal_Int32 nStart, sal_Int32 nEnd)
Definition: accpara.cxx:480
constexpr tools::Long Width() const
std::map< key_type, mapped_type, key_compare >::iterator iterator
SwCursorShell * GetCursorShell()
convenience method to get SwCursorShell through accessibility map
Definition: acccontext.cxx:101
sal_uInt16 sal_Unicode
bool IsFlyFrame() const
Definition: frame.hxx:1211
SwViewShell * GetShell() const
Definition: accmap.hxx:169
virtual sal_Bool SAL_CALL scrollSubstringTo(sal_Int32 nStartIndex, sal_Int32 nEndIndex, css::accessibility::AccessibleScrollType aScrollType) override
Definition: accpara.cxx:2485
static bool implInitTextChangedEvent(const OUString &rOldString, const OUString &rNewString, css::uno::Any &rDeleted, css::uno::Any &rInserted)
SwAccessibleSelectionHelper m_aSelectionHelper
Definition: accpara.hxx:85
#define min(a, b)
constexpr sal_uInt16 RES_PARATR_BEGIN(RES_TXTATR_END)
void GetCursorAttr(SwPaM &rPam, SfxItemSet &rSet, const bool bOnlyTextAttr=false, const bool bGetFromChrFormat=true)
Definition: unoobj2.cxx:296
const SwFrame * GetFrame() const
Definition: accframe.hxx:103
constexpr TypedWhichId< SfxInt16Item > RES_PARATR_LIST_LEVEL(83)
#define UNO_NAME_PARA_LINE_SPACING
Definition: unoprnms.hxx:139
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const
#define UNO_NAME_PARA_RIGHT_MARGIN
Definition: unoprnms.hxx:57
bool isAccessibleChildSelected(sal_Int32 nChildIndex)
size_t pos
A wrapper around SfxPoolItem to store the start position of (usually) a text portion, with an optional end.
Definition: txatbase.hxx:41
std::unique_ptr< SwAccessiblePortionData > m_pPortionData
Definition: accpara.hxx:74
static bool IsValidChar(sal_Int32 nPos, sal_Int32 nLength)
Definition: accpara.cxx:508
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:33
#define UNO_NAME_NUMBERING_RULES
int nCount
virtual OUString SAL_CALL getText() override
Definition: accpara.cxx:2244
sal_uLong GetIndex() const
Definition: ndindex.hxx:152
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
sal_Int32 GetStart() const
Definition: txatbase.hxx:86
virtual sal_Int32 SAL_CALL getForeground() override
Definition: accpara.cxx:833
std::shared_ptr< SdrAllFillAttributesHelper > SdrAllFillAttributesHelperPtr
Definition: format.hxx:41
constexpr OUStringLiteral sAccessibleServiceName
Definition: acccontext.hxx:45
SwAccessibleParagraph(std::shared_ptr< SwAccessibleMap > const &pInitMap, const SwTextFrame &rTextFrame)
Definition: accpara.cxx:396
constexpr tools::Long GetWidth() const
sal_uInt16 GetFormatCount(SwFieldTypesEnum nTypeId, bool bHtmlMode) const
Definition: fldmgr.cxx:675
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:195
Describes parts of multiple text nodes, which will form a text frame, even when redlines are hidden a...
Definition: txtfrm.hxx:956
virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet() override
Definition: accpara.cxx:732
#define UNO_NAME_CHAR_POSTURE
const AuthorCharAttr & GetFormatAuthorAttr() const
Definition: modcfg.hxx:253
SwPaM * GetNext()
Definition: pam.hxx:264
virtual css::accessibility::TextSegment SAL_CALL getTextMarkup(sal_Int32 nTextMarkupIndex, sal_Int32 nTextMarkupType) override
Definition: accpara.cxx:3155
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:855
TextFrameIndex GetOffset() const
Definition: txtfrm.hxx:438
virtual bool GetCharRect(SwRect &, const SwPosition &, SwCursorMoveState *=nullptr, bool bAllowFarAway=true) const
Definition: unusedf.cxx:72
constexpr TypedWhichId< SwFormatINetFormat > RES_TXTATR_INETFMT(51)
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes(sal_Int32 nIndex, const css::uno::Sequence< OUString > &aRequestedAttributes) override
Definition: accpara.cxx:1331
void GetAttributeBoundary(css::i18n::Boundary &rBound, sal_Int32 nPos) const
virtual sal_Int32 SAL_CALL getTextMarkupCount(sal_Int32 nTextMarkupType) override
Definition: accpara.cxx:2929
bool Select(SwPaM *pPaM, SdrObject *pObj, bool bAdd)
void GetLineBoundary(css::i18n::Boundary &rBound, sal_Int32 nPos) const
get the start & end positions of the sentence
bool IsInGrayPortion(sal_Int32 nPos)
css::uno::Reference< css::accessibility::XAccessible > getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)
sal_Int32 m_nOldCaretPos
Definition: accpara.hxx:77
virtual OUString SAL_CALL getImplementationName() override
Definition: accpara.cxx:868
const Color & GetColor() const
void FireStateChangedEvent(sal_Int16 nState, bool bNewState)
Definition: acccontext.cxx:467
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:457
bool FrameContainsNode(SwContentFrame const &rFrame, sal_uLong nNodeIndex)
Definition: txtfrm.cxx:288
std::unique_ptr< SwParaChangeTrackingInfo > mpParaChangeTrackInfo
Definition: accpara.hxx:87
#define UNO_NAME_CHAR_SHADOWED
virtual sal_Int16 SAL_CALL getAccessibleRole() override
Definition: accpara.cxx:3489
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1304
virtual sal_Bool SAL_CALL cutText(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
Definition: accpara.cxx:2552
constexpr TypedWhichId< SwFormatField > RES_TXTATR_FIELD(RES_TXTATR_NOEND_BEGIN)
bool IsRefToNumItemCrossRefBookmark() const
Definition: reffld.cxx:386
virtual void SAL_CALL grabFocus() override
Definition: accpara.cxx:767
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1268
#define SW_MOD()
Definition: swmodule.hxx:256
const SfxItemSet * GetParent() const
#define COL_NONE_COLOR
virtual css::uno::Sequence< css::style::TabStop > GetTabStopInfo(SwTwips)
Definition: frame.hxx:514
virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
Definition: accpara.cxx:2305
SwPaM * CreateCursor()
delete the current cursor and make the following into the current
Definition: crsrsh.cxx:124
int i
SwPaM * GetCursor(const bool _bForSelection)
Definition: accpara.cxx:185
sal_Int32 m_nHeadingLevel
Definition: accpara.hxx:82
const SwPosition * GetPoint() const
Definition: pam.hxx:207
static bool IsValidPosition(sal_Int32 nPos, sal_Int32 nLength)
Definition: accpara.cxx:514
bool IsDark() const
bool GetEditableRange(sal_Int32 nStart, sal_Int32 nEnd, TextFrameIndex &rCoreStart, TextFrameIndex &rCoreEnd) const
Convert start and end positions into core positions.
void GetBoundaryOfLine(const sal_Int32 nLineNo, css::i18n::Boundary &rLineBound)
virtual css::uno::Any SAL_CALL getExtendedAttributes() override
Definition: accpara.cxx:3527
constexpr sal_uInt16 RES_PARATR_LIST_END(88)
virtual void SAL_CALL selectAllAccessibleChildren() override
Definition: accpara.cxx:2723
#define UNO_NAME_PARA_ADJUST
Definition: unoprnms.hxx:171
virtual bool HasCursor() override
Definition: accpara.cxx:428
LINESTYLE_WAVE
#define UNO_NAME_PARA_BOTTOM_MARGIN
Definition: unoprnms.hxx:141
TextFrameIndex MapModelToView(MergedPara const &, SwTextNode const *pNode, sal_Int32 nIndex)
Definition: txtfrm.cxx:1184
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:191
SwFieldIds
Definition: fldbas.hxx:44
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
SwLayoutFrame * GetUpper()
Definition: frame.hxx:679
float u
unsigned char sal_Bool
const SfxItemPropertyMap & getPropertyMap() const
virtual void InvalidateCursorPos_() override
Definition: accpara.cxx:329
Object Value
bool IsOn() const
Definition: docufld.hxx:601
void GetSentenceBoundary(css::i18n::Boundary &rBound, sal_Int32 nPos)
#define UNO_NAME_CHAR_EMPHASIS
Definition: unoprnms.hxx:138
TextFrameIndex GetCoreViewPosition(sal_Int32 nPos) const
get the position in the core view string for a given (accessibility) position
constexpr tools::Long Top() const
constexpr OUStringLiteral sImplementationName
Definition: accpara.cxx:115
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent() override
Definition: acccontext.cxx:686
collect text portion data from the layout through SwPortionHandler interface
Definition: accportions.hxx:39
constexpr TypedWhichId< SvxLineSpacingItem > RES_PARATR_LINESPACING(RES_PARATR_BEGIN)
sal_Int32 GetCaretPos()
Definition: accpara.cxx:127
sal_uInt16 m_nItemId
Definition: authratr.hxx:29
virtual css::accessibility::TextSegment SAL_CALL getTextAtLineWithCaret() override
Definition: accpara.cxx:3258
T static_txtattr_cast(S *s)
Definition: txatbase.hxx:241
ring_container GetRingContainer()
Definition: ring.hxx:240
ColorTransparency
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
bool IsOnlineSpell() const
Definition: viewopt.hxx:371
const SwRangeRedline * GetRedlineAtIndex()
Definition: accpara.cxx:527
bool GetTextBoundary(css::i18n::Boundary &rBound, const OUString &rText, sal_Int32 nPos, sal_Int16 aTextType)
Definition: accpara.cxx:648
void GrabFocus()
SwRect GetBounds(const SwAccessibleMap &rAccMap, const SwFrame *pFrame=nullptr)
Definition: accframe.cxx:328
#define UNO_NAME_PARA_FIRST_LINE_INDENT
Definition: unoprnms.hxx:61
bool GetLineBoundary(css::i18n::Boundary &rBound, const OUString &rText, sal_Int32 nPos)
Definition: accpara.cxx:591
virtual sal_uInt16 GetSubType() const
Definition: fldbas.cxx:337
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getDefaultAttributes(const css::uno::Sequence< OUString > &aRequestedAttributes) override
Definition: accpara.cxx:1590
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(TextFrameIndex nIndex) const
map position in potentially merged text frame to SwPosition
Definition: txtfrm.cxx:1232
const SwPosition * Start() const
Definition: pam.hxx:212
bool Contains(const Point &rPOINT) const
Definition: swrect.hxx:356
SwFieldType * GetTyp() const
Definition: fldbas.hxx:392
Color m_nColor
Definition: authratr.hxx:31
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
Definition: accpara.cxx:1003
OUString GetFieldTypeNameAtIndex(sal_Int32 nIndex)
Definition: accpara.cxx:1162
#define UNO_NAME_CHAR_UNDERLINE
#define UNO_NAME_CHAR_BACK_COLOR
Definition: unoprnms.hxx:133
virtual const SwRangeRedline * GetRedline(const SwPosition &rPos, SwRedlineTable::size_type *pFndPos) const =0
void StartAction()
Definition: crsrsh.cxx:227
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter() const
Definition: breakit.hxx:62
static void OrderRange(sal_Int32 &nBegin, sal_Int32 &nEnd)
Definition: accpara.hxx:133
bool GetBackgroundBrush(drawinglayer::attribute::SdrAllFillAttributesHelperPtr &rFillAttributes, const SvxBrushItem *&rpBrush, std::optional< Color > &rxColor, SwRect &rOrigRect, bool bLowerMode, bool bConsiderTextBox) const
Determine the background brush for the frame: the background brush is taken from it-self or from its ...
Definition: paintfrm.cxx:7287
#define UNO_NAME_CHAR_ESCAPEMENT
Definition: unoprnms.hxx:111
virtual sal_Int32 SAL_CALL getCaretPosition() override
Definition: accpara.cxx:1010
static void SetPutRecursive(SfxItemSet &targetSet, const SfxItemSet &sourceSet)
Definition: accpara.cxx:1430
const css::lang::Locale & GetLocale(const LanguageType aLang)
Definition: breakit.hxx:67
sal_Int32 GetRealHeadingLevel()
Definition: accpara.cxx:3505
const PropertyValue * pValues
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SwFieldTypesEnum GetTypeId() const
Definition: fldbas.cxx:252
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &aType) override
Definition: accpara.cxx:927
#define UNO_NAME_CHAR_CONTOURED
Definition: unoprnms.hxx:239
virtual sal_Int32 SAL_CALL getBackground() override
virtual sal_Int32 SAL_CALL getIndexAtPoint(const css::awt::Point &aPoint) override
Definition: accpara.cxx:2099
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:335
virtual OUString SAL_CALL getSelectedText() override
Definition: accpara.cxx:2175
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: accpara.cxx:989
virtual sal_Int32 SAL_CALL getSelectedAccessibleChildCount() override
Definition: accpara.cxx:2730
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:195
void EndListeningAll()
virtual css::accessibility::TextSegment SAL_CALL getTextAtLineNumber(sal_Int32 nLineNo) override
Definition: accpara.cxx:3234
virtual void SAL_CALL deselectAccessibleChild(sal_Int32 nChildIndex) override
Definition: accpara.cxx:2746
constexpr sal_uInt16 RES_CHRATR_BEGIN(HINT_BEGIN)
void ScrollMDI(SwViewShell const *pVwSh, const SwRect &rRect, sal_uInt16 nRangeX, sal_uInt16 nRangeY)
Definition: edtwin3.cxx:35
general base class for all free-flowing frames
Definition: flyfrm.hxx:78
std::mutex m_Mutex
Definition: acccontext.hxx:67
Color GetRetoucheColor() const
Definition: viewimp.cxx:283
virtual OUString GetName() const
Only in derived classes.
Definition: fldbas.cxx:137
#define SAL_WARN_IF(condition, area, stream)
bool IsRefToHeadingCrossRefBookmark() const
Definition: reffld.cxx:380
bool GetSelection(sal_Int32 &nStart, sal_Int32 &nEnd)
Definition: accpara.hxx:104
#define UNO_NAME_CHAR_WEIGHT
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:424
css::uno::Sequence< typename M::mapped_type > mapValuesToSequence(M const &map)
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: accpara.cxx:3331
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
std::unordered_map< OUString, css::beans::PropertyValue > tAccParaPropValMap
Definition: accpara.hxx:51
sal_Int32 GetLineNo(const sal_Int32 nPos) const
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1253
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_WHITE
virtual void GetStates(::utl::AccessibleStateSetHelper &rStateSet)
Definition: acccontext.cxx:481
virtual sal_Bool SAL_CALL supportsService(const OUString &sServiceName) override
Return whether the specified service is supported by this class.
Definition: accpara.cxx:873
bool InWrongWord(sal_Int32 &rChk, sal_Int32 &rLn) const
If a word is incorrectly selected, this method returns begin and length of it.
Definition: wrong.cxx:102
constexpr sal_uInt16 RES_PARATR_LIST_BEGIN(RES_PARATR_END)
const SwPosition * End() const
Definition: pam.hxx:217
void _correctValues(const sal_Int32 nIndex, std::vector< css::beans::PropertyValue > &rValues)
Definition: accpara.cxx:1804
bool IsRightToLeft() const
Definition: frame.hxx:988
SwDoc & GetDoc() const
Returns the document this position is in.
Definition: pam.cxx:181
void selectAccessibleChild(sal_Int32 nChildIndex)
virtual sal_Int32 SAL_CALL addSelection(sal_Int32 selectionIndex, sal_Int32 startOffset, sal_Int32 endOffset) override
Definition: accpara.cxx:3091
virtual OUString SAL_CALL getAccessibleDescription() override
Definition: accpara.cxx:703
constexpr sal_uInt16 RES_PARATR_END(82)
const SwRect & GetCharRect() const
Definition: crsrsh.hxx:516
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1840
bool GetGlyphBoundary(css::i18n::Boundary &rBound, const OUString &rText, sal_Int32 nPos)
Definition: accpara.cxx:620
const o3tl::sorted_vector< const SfxItemPropertyMapEntry *, SfxItemPropertyMapCompare > & getPropertyEntries() const
virtual sal_Bool SAL_CALL setCaretPosition(sal_Int32 nIndex) override
Definition: accpara.cxx:1031
void _getRunAttributesImpl(const sal_Int32 nIndex, const css::uno::Sequence< OUString > &aRequestedAttributes, tAccParaPropValMap &rRunAttrSeq)
Definition: accpara.cxx:1628
size_t IsObjSelected() const
Definition: feshview.cxx:1240
#define UNO_NAME_CHAR_STRIKEOUT
Definition: unoprnms.hxx:113
virtual Point LogicToPixel(const Point &rPoint) const override
Definition: accmap.cxx:3043
SwUnoPropertyMapProvider aSwMapProvider
Definition: unomap1.cxx:87
virtual sal_Int32 SAL_CALL getLineNumberAtIndex(sal_Int32 nIndex) override
Definition: accpara.cxx:3218
const ::std::vector< Color > ImpSvNumberformatScan::StandardColor COL_BLACK
SwSpecialPos * m_pSpecialPos
for positions inside fields
Definition: crstate.hxx:136
css::uno::Reference< css::accessibility::XAccessible > GetContext(const SwFrame *pFrame, bool bCreate=true)
Definition: accmap.cxx:1812
SwWrongList * GetWrong()
Definition: txtedt.cxx:2204
constexpr TypedWhichId< SvxLRSpaceItem > RES_LR_SPACE(91)
double getLength(const B2DPolygon &rCandidate)
css::uno::Sequence< css::uno::Type > SAL_CALL getTypes()
void GetLastLineBoundary(css::i18n::Boundary &rBound) const
SwAccessibleMap * GetMap()
Definition: acccontext.hxx:115
constexpr TypedWhichId< SwFormatField > RES_TXTATR_INPUTFIELD(55)
constexpr sal_uInt16 RES_CHRATR_END(46)
bool m_bPosMatchesBounds
GetModelPositionForViewPoint should not return the next position if screen position is inside second ...
Definition: crstate.hxx:152
void deselectAccessibleChild(sal_Int32 nChildIndex)
#define UNO_NAME_CHAR_HEIGHT
virtual sal_Bool SAL_CALL replaceText(sal_Int32 nStartIndex, sal_Int32 nEndIndex, const OUString &sReplacement) override
Definition: accpara.cxx:2592
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
bool IsVertical() const
Definition: frame.hxx:974
#define UNO_NAME_TABSTOPS
Definition: unoprnms.hxx:319
virtual css::uno::Reference< css::accessibility::XAccessibleHyperlink > SAL_CALL getHyperLink(sal_Int32 nLinkIndex) override
Definition: accpara.cxx:2834
SwDoc & GetDoc()
Definition: txtfrm.hxx:460
std::unique_ptr< SwAccessibleHyperTextData > m_pHyperTextData
Definition: accpara.hxx:75
OUString GetFormatStr(SwFieldTypesEnum nTypeId, sal_uInt32 nFormatId) const
Definition: fldmgr.cxx:718
constexpr::Color COL_BLUE(0x00, 0x00, 0x80)
SwContentFrame * FindPrevCnt()
Definition: findfrm.cxx:175
void SetCursorContext(const ::rtl::Reference< SwAccessibleContext > &rCursorContext)
Definition: accmap.cxx:2756
sal_Int32 nLength
const SfxPoolItem * Execute(sal_uInt16 nSlot, SfxCallMode nCall=SfxCallMode::SLOT, const SfxPoolItem **pArgs=nullptr, sal_uInt16 nModi=0, const SfxPoolItem **pInternalArgs=nullptr)
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:478
virtual OUString SAL_CALL getTextRange(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
Definition: accpara.cxx:2253
constexpr TypedWhichId< SwFormatRefMark > RES_TXTATR_REFMARK(RES_TXTATR_WITHEND_BEGIN)
static css::uno::Reference< css::text::XTextRange > CreateXTextRange(SwDoc &rDoc, const SwPosition &rPos, const SwPosition *const pMark)
Definition: unoobj2.cxx:1214
#define UNO_NAME_NUMBERING_LEVEL
#define UNO_NAME_CHAR_COLOR
virtual ~SwAccessibleParagraph() override
Definition: accpara.cxx:418
sal_Int32 GetAccessiblePosition(TextFrameIndex nPos) const
get the position in the accessibility string for a given view position
void VisitPortions(SwPortionHandler &rPH) const
Visit all portions for Accessibility.
Definition: txtfrm.cxx:3876
bool GetCharBoundary(css::i18n::Boundary &rBound, sal_Int32 nPos)
Definition: accpara.cxx:542
bool HasFocus() const
sal_Int32 GetFieldIndex(sal_Int32 nPos) const
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
void AddState(sal_Int16 aState)
virtual sal_Int32 SAL_CALL getSelectionStart() override
Definition: accpara.cxx:2188
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1247
const AuthorCharAttr & GetDeletedAuthorAttr() const
Definition: modcfg.hxx:249
bool IsIndexInFootnode(sal_Int32 nIndex)
SwFieldIds Which() const
Definition: fldbas.hxx:272
constexpr sal_uInt16 RES_FRMATR_BEGIN(RES_PARATR_LIST_END)
virtual sal_Bool SAL_CALL copyText(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
Definition: accpara.cxx:2473
constexpr TypedWhichId< SvxULSpaceItem > RES_UL_SPACE(92)
virtual void InvalidateContent_(bool bVisibleDataFired) override
Definition: accpara.cxx:247
void SetName(const OUString &rName)
Definition: acccontext.hxx:102
bool IsFrameSelected() const
Definition: feshview.cxx:1248
virtual css::uno::Sequence< css::accessibility::TextSegment > SAL_CALL getTextMarkupAtIndex(sal_Int32 nCharIndex, sal_Int32 nTextMarkupType) override
Definition: accpara.cxx:3183
constexpr TypedWhichId< SvxAdjustItem > RES_PARATR_ADJUST(64)
AnyEventRef aEvent
virtual sal_Bool SAL_CALL deleteText(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
Definition: accpara.cxx:2582
virtual sal_Int32 SAL_CALL getCharacterCount() override
Definition: accpara.cxx:2090
virtual sal_Bool SAL_CALL removeSelection(sal_Int32 selectionIndex) override
Definition: accpara.cxx:3028
const SfxItemPropertyMapEntry * GetPropertyMapEntries(sal_uInt16 PropertyId)
Definition: unomap.cxx:71
sal_uInt16 nPos
bool GetSentenceBoundary(css::i18n::Boundary &rBound, const OUString &rText, sal_Int32 nPos)
Definition: accpara.cxx:578
static uno::Sequence< OUString > const & getSupplementalAttributeNames()
Definition: accpara.cxx:907
virtual void SAL_CALL clearAccessibleSelection() override
Definition: accpara.cxx:2718
void EndAction(const bool bIdleEnd=false)
Definition: crsrsh.cxx:244
bool IsInFrontOfLabel() const
Definition: pam.hxx:171
void GetSubTypes(SwFieldTypesEnum nId, std::vector< OUString > &rToFill)
Definition: fldmgr.cxx:572
constexpr tools::Long GetHeight() const
virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
Definition: accpara.cxx:2269
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo