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