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