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