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