LibreOffice Module sw (master)  1
accpara.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #include <memory>
21 #include <numeric>
22 #include <txtfrm.hxx>
23 #include <flyfrm.hxx>
24 #include <ndtxt.hxx>
25 #include <pam.hxx>
26 #include <unotextrange.hxx>
27 #include <unocrsrhelper.hxx>
28 #include <crstate.hxx>
29 #include <accmap.hxx>
30 #include <fesh.hxx>
31 #include <viewopt.hxx>
32 #include <osl/mutex.hxx>
33 #include <vcl/svapp.hxx>
34 #include <vcl/window.hxx>
35 #include <sal/log.hxx>
36 #include <com/sun/star/accessibility/AccessibleRole.hpp>
37 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
38 #include <com/sun/star/accessibility/AccessibleTextType.hpp>
39 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
41 #include <com/sun/star/i18n/Boundary.hpp>
42 #include <com/sun/star/i18n/CharacterIteratorMode.hpp>
43 #include <com/sun/star/i18n/WordType.hpp>
44 #include <com/sun/star/i18n/XBreakIterator.hpp>
45 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
46 #include <com/sun/star/beans/UnknownPropertyException.hpp>
47 #include <breakit.hxx>
48 #include "accpara.hxx"
49 #include "accportions.hxx"
50 #include <sfx2/viewsh.hxx>
51 #include <sfx2/viewfrm.hxx>
52 #include <sfx2/dispatch.hxx>
53 #include <unocrsr.hxx>
54 #include <unoport.hxx>
55 #include <doc.hxx>
57 #include "acchyperlink.hxx"
58 #include "acchypertextdata.hxx"
60 #include <com/sun/star/accessibility/AccessibleRelationType.hpp>
62 #include <algorithm>
63 #include <docufld.hxx>
64 #include <txtfld.hxx>
65 #include <fmtfld.hxx>
66 #include <modcfg.hxx>
67 #include <com/sun/star/beans/XPropertySet.hpp>
68 #include <swmodule.hxx>
69 #include <redline.hxx>
70 #include <com/sun/star/awt/FontWeight.hpp>
71 #include <com/sun/star/awt/FontStrikeout.hpp>
72 #include <com/sun/star/awt/FontSlant.hpp>
73 #include <wrong.hxx>
74 #include <editeng/brushitem.hxx>
75 #include <swatrset.hxx>
76 #include <unosett.hxx>
77 #include <unomap.hxx>
78 #include <unoprnms.hxx>
79 #include <com/sun/star/text/WritingMode2.hpp>
80 #include <viewimp.hxx>
81 #include "textmarkuphelper.hxx"
83 #include <com/sun/star/text/TextMarkupType.hpp>
86 #include <svx/colorwindow.hxx>
87 #include <editeng/editids.hrc>
88 
89 #include <reffld.hxx>
90 #include <flddat.hxx>
91 #include "../../uibase/inc/fldmgr.hxx"
92 #include <fldbas.hxx> // SwField
93 
94 using namespace ::com::sun::star;
95 using namespace ::com::sun::star::accessibility;
96 using namespace ::com::sun::star::container;
97 
98 using beans::PropertyValue;
99 using beans::XMultiPropertySet;
100 using beans::UnknownPropertyException;
101 using beans::PropertyState_DIRECT_VALUE;
102 
103 using std::max;
104 using std::min;
105 using std::sort;
106 
107 namespace com { namespace sun { namespace star {
108  namespace text {
109  class XText;
110  }
111 } } }
112 
113 const sal_Char sServiceName[] = "com.sun.star.text.AccessibleParagraphView";
114 const sal_Char sImplementationName[] = "com.sun.star.comp.Writer.SwAccessibleParagraphView";
115 
117 {
119 }
120 
122 {
123  return OUString(); // provide empty description for paragraphs
124 }
125 
127 {
128  sal_Int32 nRet = -1;
129 
130  // get the selection's point, and test whether it's in our node
131  // #i27301# - consider adjusted method signature
132  SwPaM* pCaret = GetCursor( false ); // caret is first PaM in PaM-ring
133 
134  if( pCaret != nullptr )
135  {
136  SwTextFrame const*const pTextFrame(static_cast<SwTextFrame const*>(GetFrame()));
137  assert(pTextFrame);
138 
139  // check whether the point points into 'our' node
140  SwPosition* pPoint = pCaret->GetPoint();
141  if (sw::FrameContainsNode(*pTextFrame, pPoint->nNode.GetIndex()))
142  {
143  // same node? Then check whether it's also within 'our' part
144  // of the paragraph
145  const TextFrameIndex nIndex = pTextFrame->MapModelToViewPos(*pPoint);
146  if(!GetPortionData().IsValidCorePosition( nIndex ) ||
147  (GetPortionData().IsZeroCorePositionData()
148  && nIndex == TextFrameIndex(0)))
149  {
150  bool bFormat = pTextFrame->HasPara();
151  if(bFormat)
152  {
155  }
156  }
157  if( GetPortionData().IsValidCorePosition( nIndex ) )
158  {
159  // Yes, it's us!
160  // consider that cursor/caret is in front of the list label
161  if ( pCaret->IsInFrontOfLabel() )
162  {
163  nRet = 0;
164  }
165  else
166  {
167  nRet = GetPortionData().GetAccessiblePosition( nIndex );
168  }
169 
170  OSL_ENSURE( nRet >= 0, "invalid cursor?" );
171  OSL_ENSURE( nRet <= GetPortionData().GetAccessibleString().
172  getLength(), "invalid cursor?" );
173  }
174  // else: in this paragraph, but in different frame
175  }
176  // else: not in this paragraph
177  }
178  // else: no cursor -> no caret
179 
180  return nRet;
181 }
182 
183 // #i27301# - new parameter <_bForSelection>
184 SwPaM* SwAccessibleParagraph::GetCursor( const bool _bForSelection )
185 {
186  // get the cursor shell; if we don't have any, we don't have a
187  // cursor/selection either
188  SwPaM* pCursor = nullptr;
190  // #i27301# - if cursor is retrieved for selection, the cursors for
191  // a table selection has to be returned.
192  if ( pCursorShell != nullptr &&
193  ( _bForSelection || !pCursorShell->IsTableMode() ) )
194  {
195  SwFEShell *pFESh = dynamic_cast<const SwFEShell*>( pCursorShell) != nullptr
196  ? static_cast< SwFEShell * >( pCursorShell ) : nullptr;
197  if( !pFESh ||
198  !(pFESh->IsFrameSelected() || pFESh->IsObjSelected() > 0) )
199  {
200  // get the selection, and test whether it affects our text node
201  pCursor = pCursorShell->GetCursor( false /* ??? */ );
202  }
203  }
204 
205  return pCursor;
206 }
207 
209 {
210  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
211  const SwTextNode *pTextNd = pFrame->GetTextNodeForParaProps();
212  return pTextNd->IsOutline();
213 }
214 
216  ::utl::AccessibleStateSetHelper& rStateSet )
217 {
218  SwAccessibleContext::GetStates( rStateSet );
219 
220  // MULTILINE
221  rStateSet.AddState( AccessibleStateType::MULTI_LINE );
222 
223  if (GetCursorShell())
224  {
225  // MULTISELECTABLE
226  rStateSet.AddState(AccessibleStateType::MULTI_SELECTABLE);
227  // FOCUSABLE
228  rStateSet.AddState(AccessibleStateType::FOCUSABLE);
229  }
230 
231  // FOCUSED (simulates node index of cursor)
232  SwPaM* pCaret = GetCursor( false ); // #i27301# - consider adjusted method signature
233  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
234  assert(pFrame);
235  if (pCaret != nullptr &&
236  sw::FrameContainsNode(*pFrame, pCaret->GetPoint()->nNode.GetIndex()) &&
237  m_nOldCaretPos != -1)
238  {
239  vcl::Window *pWin = GetWindow();
240  if( pWin && pWin->HasFocus() )
241  rStateSet.AddState( AccessibleStateType::FOCUSED );
243  GetMap()->SetCursorContext( xThis );
244  }
245 }
246 
247 void SwAccessibleParagraph::InvalidateContent_( bool bVisibleDataFired )
248 {
249  OUString sOldText( GetString() );
250 
252 
253  const OUString& rText = GetString();
254 
255  if( rText != sOldText )
256  {
257  // The text is changed
258  AccessibleEventObject aEvent;
259  aEvent.EventId = AccessibleEventId::TEXT_CHANGED;
260 
261  // determine exact changes between sOldText and rText
263  aEvent.OldValue,
264  aEvent.NewValue);
265 
266  FireAccessibleEvent( aEvent );
267  uno::Reference< XAccessible > xparent = getAccessibleParent();
268  uno::Reference< XAccessibleContext > xAccContext(xparent,uno::UNO_QUERY);
269  if (xAccContext.is() && xAccContext->getAccessibleRole() == AccessibleRole::TABLE_CELL)
270  {
271  SwAccessibleContext* pPara = static_cast< SwAccessibleContext* >(xparent.get());
272  if(pPara)
273  {
274  AccessibleEventObject aParaEvent;
275  aParaEvent.EventId = AccessibleEventId::VALUE_CHANGED;
276  pPara->FireAccessibleEvent(aParaEvent);
277  }
278  }
279  }
280  else if( !bVisibleDataFired )
281  {
283  }
284 
285  bool bNewIsHeading = IsHeading();
286  //Get the real heading level, Heading1 ~ Heading10
288  bool bOldIsHeading;
289  {
290  osl::MutexGuard aGuard( m_Mutex );
291  bOldIsHeading = m_bIsHeading;
292  if( m_bIsHeading != bNewIsHeading )
293  m_bIsHeading = bNewIsHeading;
294  }
295 
296  if( bNewIsHeading != bOldIsHeading )
297  {
298  // The role has changed
299  AccessibleEventObject aEvent;
300  aEvent.EventId = AccessibleEventId::ROLE_CHANGED;
301 
302  FireAccessibleEvent( aEvent );
303  }
304 
305  if( rText != sOldText )
306  {
307  OUString sNewDesc( GetDescription() );
308  OUString sOldDesc;
309  {
310  osl::MutexGuard aGuard( m_Mutex );
311  sOldDesc = m_sDesc;
312  if( m_sDesc != sNewDesc )
313  m_sDesc = sNewDesc;
314  }
315 
316  if( sNewDesc != sOldDesc )
317  {
318  // The text is changed
319  AccessibleEventObject aEvent;
320  aEvent.EventId = AccessibleEventId::DESCRIPTION_CHANGED;
321  aEvent.OldValue <<= sOldDesc;
322  aEvent.NewValue <<= sNewDesc;
323 
324  FireAccessibleEvent( aEvent );
325  }
326  }
327 }
328 
330 {
331  // The text is changed
332  sal_Int32 nNew = GetCaretPos();
333  sal_Int32 nOld;
334  {
335  osl::MutexGuard aGuard( m_Mutex );
336  nOld = m_nOldCaretPos;
337  m_nOldCaretPos = nNew;
338  }
339  if( -1 != nNew )
340  {
341  // remember that object as the one that has the caret. This is
342  // necessary to notify that object if the cursor leaves it.
344  GetMap()->SetCursorContext( xThis );
345  }
346 
347  vcl::Window *pWin = GetWindow();
348  if( nOld == nNew )
349  return;
350 
351  // The cursor's node position is simulated by the focus!
352  if( pWin && pWin->HasFocus() && -1 == nOld )
353  FireStateChangedEvent( AccessibleStateType::FOCUSED, true );
354 
355  AccessibleEventObject aEvent;
356  aEvent.EventId = AccessibleEventId::CARET_CHANGED;
357  aEvent.OldValue <<= nOld;
358  aEvent.NewValue <<= nNew;
359 
360  FireAccessibleEvent( aEvent );
361 
362  if( pWin && pWin->HasFocus() && -1 == nNew )
363  FireStateChangedEvent( AccessibleStateType::FOCUSED, false );
364  //To send TEXT_SELECTION_CHANGED event
365  sal_Int32 nStart=0;
366  sal_Int32 nEnd =0;
367  bool bCurSelection = GetSelection(nStart,nEnd);
368  if(m_bLastHasSelection || bCurSelection )
369  {
370  aEvent.EventId = AccessibleEventId::TEXT_SELECTION_CHANGED;
371  aEvent.OldValue.clear();
372  aEvent.NewValue.clear();
373  FireAccessibleEvent(aEvent);
374  }
375  m_bLastHasSelection =bCurSelection;
376 
377 }
378 
380 {
381  vcl::Window *pWin = GetWindow();
382  if( pWin )
383  {
384  sal_Int32 nPos;
385  {
386  osl::MutexGuard aGuard( m_Mutex );
387  nPos = m_nOldCaretPos;
388  }
389  OSL_ENSURE( nPos != -1, "focus object should be selected" );
390 
391  FireStateChangedEvent( AccessibleStateType::FOCUSED,
392  pWin->HasFocus() && nPos != -1 );
393  }
394 }
395 
397  std::shared_ptr<SwAccessibleMap> const& pInitMap,
398  const SwTextFrame& rTextFrame )
399  : SwAccessibleContext( pInitMap, AccessibleRole::PARAGRAPH, &rTextFrame )
400  , m_sDesc()
401  , m_nOldCaretPos( -1 )
402  , m_bIsHeading( false )
403  //Get the real heading level, Heading1 ~ Heading10
404  , m_nHeadingLevel (-1)
405  , m_aSelectionHelper( *this )
406  , mpParaChangeTrackInfo( new SwParaChangeTrackingInfo( rTextFrame ) ) // #i108125#
407  , m_bLastHasSelection(false) //To add TEXT_SELECTION_CHANGED event
408 {
409  StartListening(const_cast<SwTextFrame&>(rTextFrame));
411  //Get the real heading level, Heading1 ~ Heading10
413  SetName( OUString() ); // set an empty accessibility name for paragraphs
414 
415  // If this object has the focus, then it is remembered by the map itself.
417 }
418 
420 {
421  SolarMutexGuard aGuard;
422 
423  m_pPortionData.reset();
424  m_pHyperTextData.reset();
425  mpParaChangeTrackInfo.reset(); // #i108125#
426  EndListeningAll();
427 }
428 
430 {
431  osl::MutexGuard aGuard( m_Mutex );
432  return m_nOldCaretPos != -1;
433 }
434 
436 {
437  // obtain the text frame
438  OSL_ENSURE( GetFrame() != nullptr, "The text frame has vanished!" );
439  OSL_ENSURE( GetFrame()->IsTextFrame(), "The text frame has mutated!" );
440  const SwTextFrame* pFrame = static_cast<const SwTextFrame*>( GetFrame() );
441 
442  // build new portion data
444  pFrame, GetMap()->GetShell()->GetViewOptions()) );
445  pFrame->VisitPortions( *m_pPortionData );
446 
447  OSL_ENSURE( m_pPortionData != nullptr, "UpdatePortionData() failed" );
448 }
449 
451 {
452  m_pPortionData.reset();
453  m_pHyperTextData.reset();
454 }
455 
457 {
458  OSL_ENSURE( GetMap() != nullptr, "no map?" );
459  SwViewShell* pViewShell = GetMap()->GetShell();
460 
461  OSL_ENSURE( pViewShell != nullptr, "View shell expected!" );
462  SfxViewShell* pSfxShell = pViewShell->GetSfxViewShell();
463 
464  OSL_ENSURE( pSfxShell != nullptr, "SfxViewShell shell expected!" );
465  if( !pSfxShell )
466  return;
467 
468  SfxViewFrame *pFrame = pSfxShell->GetViewFrame();
469  OSL_ENSURE( pFrame != nullptr, "View frame expected!" );
470  if( !pFrame )
471  return;
472 
473  SfxDispatcher *pDispatcher = pFrame->GetDispatcher();
474  OSL_ENSURE( pDispatcher != nullptr, "Dispatcher expected!" );
475  if( !pDispatcher )
476  return;
477 
478  pDispatcher->Execute( nSlot );
479 }
480 
482  sal_Int32 nStartIndex,
483  sal_Int32 nEndIndex )
484 {
485  OSL_ENSURE( (IsValidChar(nStartIndex, GetString().getLength()) &&
486  (nEndIndex == -1)) ||
487  IsValidRange(nStartIndex, nEndIndex, GetString().getLength()),
488  "please check parameters before calling this method" );
489 
490  const TextFrameIndex nStart = GetPortionData().GetCoreViewPosition(nStartIndex);
491  const TextFrameIndex nEnd = (nEndIndex == -1)
492  ? (nStart + TextFrameIndex(1))
493  : GetPortionData().GetCoreViewPosition(nEndIndex);
494 
495  // create UNO cursor
496  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
497  SwPosition aStartPos(pFrame->MapViewToModelPos(nStart));
498  auto pUnoCursor(const_cast<SwDoc&>(pFrame->GetDoc()).CreateUnoCursor(aStartPos));
499  pUnoCursor->SetMark();
500  *pUnoCursor->GetMark() = pFrame->MapViewToModelPos(nEnd);
501 
502  // create a (dummy) text portion to be returned
503  uno::Reference<text::XText> aEmpty;
504  SwXTextPortion* pPortion =
505  new SwXTextPortion ( pUnoCursor.get(), aEmpty, PORTION_TEXT);
506 
507  return pPortion;
508 }
509 
510 // range checking for parameter
511 
513  sal_Int32 nPos, sal_Int32 nLength)
514 {
515  return (nPos >= 0) && (nPos < nLength);
516 }
517 
519  sal_Int32 nPos, sal_Int32 nLength)
520 {
521  return (nPos >= 0) && (nPos <= nLength);
522 }
523 
525  sal_Int32 nBegin, sal_Int32 nEnd, sal_Int32 nLength)
526 {
527  return IsValidPosition(nBegin, nLength) && IsValidPosition(nEnd, nLength);
528 }
529 
530 //the function is to check whether the position is in a redline range.
532 {
533  const SwRangeRedline* pRedline = nullptr;
534  SwPaM* pCrSr = GetCursor( true );
535  if ( pCrSr )
536  {
537  SwPosition* pStart = pCrSr->Start();
538  pRedline = pStart->GetDoc()->getIDocumentRedlineAccess().GetRedline(*pStart, nullptr);
539  }
540 
541  return pRedline;
542 }
543 
544 // text boundaries
545 
547  i18n::Boundary& rBound,
548  sal_Int32 nPos )
549 {
550  if( GetPortionData().FillBoundaryIFDateField( rBound, nPos) )
551  return true;
552 
553  rBound.startPos = nPos;
554  rBound.endPos = nPos+1;
555  return true;
556 }
557 
559  i18n::Boundary& rBound,
560  const OUString& rText,
561  sal_Int32 nPos )
562 {
563  // now ask the Break-Iterator for the word
564  assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
565 
566  // get locale for this position
567  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
568  const TextFrameIndex nCorePos = GetPortionData().GetCoreViewPosition(nPos);
569  lang::Locale aLocale = g_pBreakIt->GetLocale(pFrame->GetLangOfChar(nCorePos, 0, true));
570 
571  // which type of word are we interested in?
572  // (DICTIONARY_WORD includes punctuation, ANY_WORD doesn't.)
573  const sal_Int16 nWordType = i18n::WordType::ANY_WORD;
574 
575  // get word boundary, as the Break-Iterator sees fit.
576  rBound = g_pBreakIt->GetBreakIter()->getWordBoundary(
577  rText, nPos, aLocale, nWordType, true );
578 
579  return true;
580 }
581 
583  i18n::Boundary& rBound,
584  const OUString& rText,
585  sal_Int32 nPos )
586 {
587  const sal_Unicode* pStr = rText.getStr();
588  while( nPos < rText.getLength() && pStr[nPos] == u' ' )
589  nPos++;
590 
591  GetPortionData().GetSentenceBoundary( rBound, nPos );
592  return true;
593 }
594 
596  i18n::Boundary& rBound,
597  const OUString& rText,
598  sal_Int32 nPos )
599 {
600  if( rText.getLength() == nPos )
602  else
603  GetPortionData().GetLineBoundary( rBound, nPos );
604  return true;
605 }
606 
608  i18n::Boundary& rBound,
609  const OUString& rText )
610 {
611  rBound.startPos = 0;
612  rBound.endPos = rText.getLength();
613  return true;
614 }
615 
617  i18n::Boundary& rBound,
618  sal_Int32 nPos )
619 {
620  GetPortionData().GetAttributeBoundary( rBound, nPos );
621  return true;
622 }
623 
625  i18n::Boundary& rBound,
626  const OUString& rText,
627  sal_Int32 nPos )
628 {
629  // ask the Break-Iterator for the glyph by moving one cell
630  // forward, and then one cell back
631  assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
632 
633  // get locale for this position
634  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
635  const TextFrameIndex nCorePos = GetPortionData().GetCoreViewPosition(nPos);
636  lang::Locale aLocale = g_pBreakIt->GetLocale(pFrame->GetLangOfChar(nCorePos, 0, true));
637 
638  // get word boundary, as the Break-Iterator sees fit.
639  const sal_Int16 nIterMode = i18n::CharacterIteratorMode::SKIPCELL;
640  sal_Int32 nDone = 0;
641  rBound.endPos = g_pBreakIt->GetBreakIter()->nextCharacters(
642  rText, nPos, aLocale, nIterMode, 1, nDone );
643  rBound.startPos = g_pBreakIt->GetBreakIter()->previousCharacters(
644  rText, rBound.endPos, aLocale, nIterMode, 1, nDone );
645  bool bRet = ((rBound.startPos <= nPos) && (nPos <= rBound.endPos));
646  OSL_ENSURE( rBound.startPos <= nPos, "start pos too high" );
647  OSL_ENSURE( rBound.endPos >= nPos, "end pos too low" );
648 
649  return bRet;
650 }
651 
653  i18n::Boundary& rBound,
654  const OUString& rText,
655  sal_Int32 nPos,
656  sal_Int16 nTextType )
657 {
658  // error checking
659  if( !( AccessibleTextType::LINE == nTextType
660  ? IsValidPosition( nPos, rText.getLength() )
661  : IsValidChar( nPos, rText.getLength() ) ) )
662  throw lang::IndexOutOfBoundsException();
663 
664  bool bRet;
665 
666  switch( nTextType )
667  {
668  case AccessibleTextType::WORD:
669  bRet = GetWordBoundary(rBound, rText, nPos);
670  break;
671 
672  case AccessibleTextType::SENTENCE:
673  bRet = GetSentenceBoundary( rBound, rText, nPos );
674  break;
675 
676  case AccessibleTextType::PARAGRAPH:
677  bRet = GetParagraphBoundary( rBound, rText );
678  break;
679 
680  case AccessibleTextType::CHARACTER:
681  bRet = GetCharBoundary( rBound, nPos );
682  break;
683 
684  case AccessibleTextType::LINE:
685  //Solve the problem of returning wrong LINE and PARAGRAPH
686  if((nPos == rText.getLength()) && nPos > 0)
687  bRet = GetLineBoundary( rBound, rText, nPos - 1);
688  else
689  bRet = GetLineBoundary( rBound, rText, nPos );
690  break;
691 
692  case AccessibleTextType::ATTRIBUTE_RUN:
693  bRet = GetAttributeBoundary( rBound, nPos );
694  break;
695 
696  case AccessibleTextType::GLYPH:
697  bRet = GetGlyphBoundary( rBound, rText, nPos );
698  break;
699 
700  default:
701  throw lang::IllegalArgumentException( );
702  }
703 
704  return bRet;
705 }
706 
708 {
709  SolarMutexGuard aGuard;
710 
711  ThrowIfDisposed();
712 
713  osl::MutexGuard aGuard2( m_Mutex );
714  if( m_sDesc.isEmpty() )
716 
717  return m_sDesc;
718 }
719 
720 lang::Locale SAL_CALL SwAccessibleParagraph::getLocale()
721 {
722  SolarMutexGuard aGuard;
723 
724  const SwTextFrame *pTextFrame = dynamic_cast<const SwTextFrame*>( GetFrame() );
725  if( !pTextFrame )
726  {
727  throw uno::RuntimeException("no SwTextFrame", static_cast<cppu::OWeakObject*>(this));
728  }
729 
730  lang::Locale aLoc(g_pBreakIt->GetLocale(pTextFrame->GetLangOfChar(TextFrameIndex(0), 0, true)));
731 
732  return aLoc;
733 }
734 
735 // #i27138# - paragraphs are in relation CONTENT_FLOWS_FROM and/or CONTENT_FLOWS_TO
736 uno::Reference<XAccessibleRelationSet> SAL_CALL SwAccessibleParagraph::getAccessibleRelationSet()
737 {
738  SolarMutexGuard aGuard;
739 
740  ThrowIfDisposed();
741 
743 
744  const SwTextFrame* pTextFrame = dynamic_cast<const SwTextFrame*>(GetFrame());
745  OSL_ENSURE( pTextFrame,
746  "<SwAccessibleParagraph::getAccessibleRelationSet()> - missing text frame");
747  if ( pTextFrame )
748  {
749  const SwContentFrame* pPrevContentFrame( pTextFrame->FindPrevCnt() );
750  if ( pPrevContentFrame )
751  {
752  uno::Sequence< uno::Reference<XInterface> > aSequence { GetMap()->GetContext( pPrevContentFrame ) };
753  AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_FROM,
754  aSequence );
755  pHelper->AddRelation( aAccRel );
756  }
757 
758  const SwContentFrame* pNextContentFrame( pTextFrame->FindNextCnt( true ) );
759  if ( pNextContentFrame )
760  {
761  uno::Sequence< uno::Reference<XInterface> > aSequence { GetMap()->GetContext( pNextContentFrame ) };
762  AccessibleRelation aAccRel( AccessibleRelationType::CONTENT_FLOWS_TO,
763  aSequence );
764  pHelper->AddRelation( aAccRel );
765  }
766  }
767 
768  return pHelper;
769 }
770 
772 {
773  SolarMutexGuard aGuard;
774 
775  ThrowIfDisposed();
776 
777  // get cursor shell
778  SwCursorShell *pCursorSh = GetCursorShell();
779  SwPaM *pCursor = GetCursor( false ); // #i27301# - consider new method signature
780  const SwTextFrame *pTextFrame = static_cast<const SwTextFrame*>( GetFrame() );
781 
782  if (pCursorSh != nullptr &&
783  ( pCursor == nullptr ||
784  !sw::FrameContainsNode(*pTextFrame, pCursor->GetPoint()->nNode.GetIndex()) ||
785  !pTextFrame->IsInside(pTextFrame->MapModelToViewPos(*pCursor->GetPoint()))))
786  {
787  // create pam for selection
788  SwPosition const aStartPos(pTextFrame->MapViewToModelPos(pTextFrame->GetOfst()));
789  SwPaM aPaM( aStartPos );
790 
791  // set PaM at cursor shell
792  Select( aPaM );
793 
794  }
795 
796  // ->#i13955#
797  vcl::Window * pWindow = GetWindow();
798 
799  if (pWindow != nullptr)
800  pWindow->GrabFocus();
801  // <-#i13955#
802 }
803 
804 // #i71385#
805 static bool lcl_GetBackgroundColor( Color & rColor,
806  const SwFrame* pFrame,
807  SwCursorShell* pCursorSh )
808 {
809  const SvxBrushItem* pBackgrdBrush = nullptr;
810  const Color* pSectionTOXColor = nullptr;
811  SwRect aDummyRect;
813 
814  if ( pFrame &&
815  pFrame->GetBackgroundBrush( aFillAttributes, pBackgrdBrush, pSectionTOXColor, aDummyRect, false, /*bConsiderTextBox=*/false ) )
816  {
817  if ( pSectionTOXColor )
818  {
819  rColor = *pSectionTOXColor;
820  return true;
821  }
822  else
823  {
824  rColor = pBackgrdBrush->GetColor();
825  return true;
826  }
827  }
828  else if ( pCursorSh )
829  {
830  rColor = pCursorSh->Imp()->GetRetoucheColor();
831  return true;
832  }
833 
834  return false;
835 }
836 
838 {
839  SolarMutexGuard g;
840 
841  Color aBackgroundCol;
842 
843  if ( lcl_GetBackgroundColor( aBackgroundCol, GetFrame(), GetCursorShell() ) )
844  {
845  if ( aBackgroundCol.IsDark() )
846  {
847  return sal_Int32(COL_WHITE);
848  }
849  else
850  {
851  return sal_Int32(COL_BLACK);
852  }
853  }
854 
856 }
857 
859 {
860  SolarMutexGuard g;
861 
862  Color aBackgroundCol;
863 
864  if ( lcl_GetBackgroundColor( aBackgroundCol, GetFrame(), GetCursorShell() ) )
865  {
866  return sal_Int32(aBackgroundCol);
867  }
868 
870 }
871 
873 {
874  return sImplementationName;
875 }
876 
878  const OUString& sTestServiceName)
879 {
880  return cppu::supportsService(this, sTestServiceName);
881 }
882 
883 uno::Sequence< OUString > SAL_CALL SwAccessibleParagraph::getSupportedServiceNames()
884 {
886 }
887 
888 static uno::Sequence< OUString > const & getAttributeNames()
889 {
890  static uno::Sequence< OUString > const aNames
891  {
892  // Add the font name to attribute list
893  // sorted list of strings
907  };
908  return aNames;
909 }
910 
911 static uno::Sequence< OUString > const & getSupplementalAttributeNames()
912 {
913  static uno::Sequence< OUString > const aNames
914  {
915  // sorted list of strings
925  };
926  return aNames;
927 }
928 
929 // XInterface
930 
932 {
933  uno::Any aRet;
934  if ( rType == cppu::UnoType<XAccessibleText>::get())
935  {
936  uno::Reference<XAccessibleText> aAccText = static_cast<XAccessibleText *>(*this); // resolve ambiguity
937  aRet <<= aAccText;
938  }
939  else if ( rType == cppu::UnoType<XAccessibleEditableText>::get())
940  {
941  uno::Reference<XAccessibleEditableText> aAccEditText = this;
942  aRet <<= aAccEditText;
943  }
944  else if ( rType == cppu::UnoType<XAccessibleSelection>::get())
945  {
946  uno::Reference<XAccessibleSelection> aAccSel = this;
947  aRet <<= aAccSel;
948  }
949  else if ( rType == cppu::UnoType<XAccessibleHypertext>::get())
950  {
951  uno::Reference<XAccessibleHypertext> aAccHyp = this;
952  aRet <<= aAccHyp;
953  }
954  // #i63870#
955  // add interface com::sun:star:accessibility::XAccessibleTextAttributes
957  {
958  uno::Reference<XAccessibleTextAttributes> aAccTextAttr = this;
959  aRet <<= aAccTextAttr;
960  }
961  // #i89175#
962  // add interface com::sun:star:accessibility::XAccessibleTextMarkup
963  else if ( rType == cppu::UnoType<XAccessibleTextMarkup>::get())
964  {
965  uno::Reference<XAccessibleTextMarkup> aAccTextMarkup = this;
966  aRet <<= aAccTextMarkup;
967  }
968  // add interface com::sun:star:accessibility::XAccessibleMultiLineText
970  {
971  uno::Reference<XAccessibleMultiLineText> aAccMultiLineText = this;
972  aRet <<= aAccMultiLineText;
973  }
975  {
976  uno::Reference< css::accessibility::XAccessibleTextSelection > aTextExtension = this;
977  aRet <<= aTextExtension;
978  }
980  {
981  uno::Reference<XAccessibleExtendedAttributes> xAttr = this;
982  aRet <<= xAttr;
983  }
984  else
985  {
986  aRet = SwAccessibleContext::queryInterface(rType);
987  }
988 
989  return aRet;
990 }
991 
992 // XTypeProvider
993 uno::Sequence< uno::Type > SAL_CALL SwAccessibleParagraph::getTypes()
994 {
995  // #i63870# - add type accessibility::XAccessibleTextAttributes
996  // #i89175# - add type accessibility::XAccessibleTextMarkup and
997  return cppu::OTypeCollection(
1004  SwAccessibleContext::getTypes() ).getTypes();
1005 }
1006 
1007 uno::Sequence< sal_Int8 > SAL_CALL SwAccessibleParagraph::getImplementationId()
1008 {
1009  return css::uno::Sequence<sal_Int8>();
1010 }
1011 
1012 // XAccessibleText
1013 
1015 {
1016  SolarMutexGuard aGuard;
1017 
1018  ThrowIfDisposed();
1019 
1020  sal_Int32 nRet = GetCaretPos();
1021  {
1022  osl::MutexGuard aOldCaretPosGuard( m_Mutex );
1023  OSL_ENSURE( nRet == m_nOldCaretPos, "caret pos out of sync" );
1024  m_nOldCaretPos = nRet;
1025  }
1026  if( -1 != nRet )
1027  {
1029  GetMap()->SetCursorContext( xThis );
1030  }
1031 
1032  return nRet;
1033 }
1034 
1036 {
1037  SolarMutexGuard aGuard;
1038 
1039  ThrowIfDisposed();
1040 
1041  // parameter checking
1042  sal_Int32 nLength = GetString().getLength();
1043  if ( ! IsValidPosition( nIndex, nLength ) )
1044  {
1045  throw lang::IndexOutOfBoundsException();
1046  }
1047 
1048  bool bRet = false;
1049 
1050  // get cursor shell
1051  SwCursorShell* pCursorShell = GetCursorShell();
1052  if( pCursorShell != nullptr )
1053  {
1054  // create pam for selection
1055  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
1056  TextFrameIndex const nFrameIndex(GetPortionData().GetCoreViewPosition(nIndex));
1057  SwPosition aStartPos(pFrame->MapViewToModelPos(nFrameIndex));
1058  SwPaM aPaM( aStartPos );
1059 
1060  // set PaM at cursor shell
1061  bRet = Select( aPaM );
1062  }
1063 
1064  return bRet;
1065 }
1066 
1068 {
1069  SolarMutexGuard aGuard;
1070 
1071  ThrowIfDisposed();
1072 
1073  OUString sText( GetString() );
1074 
1075  // return character (if valid)
1076  if( !IsValidChar(nIndex, sText.getLength() ) )
1077  throw lang::IndexOutOfBoundsException();
1078 
1079  return sText[nIndex];
1080 }
1081 
1082 css::uno::Sequence< css::style::TabStop > SwAccessibleParagraph::GetCurrentTabStop( sal_Int32 nIndex )
1083 {
1084  SolarMutexGuard aGuard;
1085 
1086  ThrowIfDisposed();
1087 
1088  /* #i12332# The position after the string needs special treatment.
1089  IsValidChar -> IsValidPosition
1090  */
1091  if( ! (IsValidPosition( nIndex, GetString().getLength() ) ) )
1092  throw lang::IndexOutOfBoundsException();
1093 
1094  /* #i12332# */
1095  bool bBehindText = false;
1096  if ( nIndex == GetString().getLength() )
1097  bBehindText = true;
1098 
1099  // get model position & prepare GetCharRect() arguments
1100  SwCursorMoveState aMoveState;
1101  aMoveState.m_bRealHeight = true;
1102  aMoveState.m_bRealWidth = true;
1103  SwSpecialPos aSpecialPos;
1104  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
1105 
1106  /* #i12332# FillSpecialPos does not accept nIndex ==
1107  GetString().getLength(). In that case nPos is set to the
1108  length of the string in the core. This way GetCharRect
1109  returns the rectangle for a cursor at the end of the
1110  paragraph. */
1111  const TextFrameIndex nPos = bBehindText
1112  ? TextFrameIndex(pFrame->GetText().getLength())
1113  : GetPortionData().FillSpecialPos(nIndex, aSpecialPos, aMoveState.m_pSpecialPos );
1114 
1115  // call GetCharRect
1116  SwRect aCoreRect;
1117  SwPosition aPosition(pFrame->MapViewToModelPos(nPos));
1118  GetFrame()->GetCharRect( aCoreRect, aPosition, &aMoveState );
1119 
1120  // already get the caret position
1121  css::uno::Sequence< css::style::TabStop > tabs;
1122  const sal_Int32 nStrLen = pFrame->GetText().getLength();
1123  if( nStrLen > 0 )
1124  {
1125  SwFrame* pTFrame = const_cast<SwFrame*>(GetFrame());
1126  tabs = pTFrame->GetTabStopInfo(aCoreRect.Left());
1127  }
1128 
1129  if( tabs.hasElements() )
1130  {
1131  // translate core coordinates into accessibility coordinates
1132  vcl::Window *pWin = GetWindow();
1133  if (!pWin)
1134  {
1135  throw uno::RuntimeException("no Window", static_cast<cppu::OWeakObject*>(this));
1136  }
1137 
1138  SwRect aTmpRect(0, 0, tabs[0].Position, 0);
1139 
1140  tools::Rectangle aScreenRect( GetMap()->CoreToPixel( aTmpRect.SVRect() ));
1141  SwRect aFrameLogBounds( GetBounds( *(GetMap()) ) ); // twip rel to doc root
1142 
1143  Point aFramePixPos( GetMap()->CoreToPixel( aFrameLogBounds.SVRect() ).TopLeft() );
1144  aScreenRect.Move( -aFramePixPos.X(), -aFramePixPos.Y() );
1145 
1146  tabs[0].Position = aScreenRect.GetWidth();
1147  }
1148 
1149  return tabs;
1150 }
1151 
1153 {
1154  const PropertyValue* pValues;
1155  explicit IndexCompare( const PropertyValue* pVals ) : pValues(pVals) {}
1156  bool operator() ( sal_Int32 a, sal_Int32 b ) const
1157  {
1158  return (pValues[a].Name < pValues[b].Name);
1159  }
1160 };
1161 
1163 {
1164  OUString strTypeName;
1165  SwFieldMgr aMgr;
1166  SwTextField* pTextField = nullptr;
1167  sal_Int32 nFieldIndex = GetPortionData().GetFieldIndex(nIndex);
1168  if (nFieldIndex >= 0)
1169  {
1170  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
1171  sw::MergedAttrIter iter(*pFrame);
1172  while (SwTextAttr const*const pHt = iter.NextAttr())
1173  {
1174  if ((pHt->Which() == RES_TXTATR_FIELD
1175  || pHt->Which() == RES_TXTATR_ANNOTATION
1176  || pHt->Which() == RES_TXTATR_INPUTFIELD)
1177  && (nFieldIndex-- == 0))
1178  {
1179  pTextField = const_cast<SwTextField*>(
1180  static_txtattr_cast<SwTextField const*>(pHt));
1181  break;
1182  }
1183  else if (pHt->Which() == RES_TXTATR_REFMARK
1184  && (nFieldIndex-- == 0))
1185  {
1186  strTypeName = "set reference";
1187  }
1188  }
1189  }
1190  if (pTextField)
1191  {
1192  const SwField* pField = pTextField->GetFormatField().GetField();
1193  if (pField)
1194  {
1195  strTypeName = SwFieldType::GetTypeStr(pField->GetTypeId());
1196  const SwFieldIds nWhich = pField->GetTyp()->Which();
1197  OUString sEntry;
1198  sal_uInt32 subType = 0;
1199  switch (nWhich)
1200  {
1201  case SwFieldIds::DocStat:
1202  subType = static_cast<const SwDocStatField*>(pField)->GetSubType();
1203  break;
1204  case SwFieldIds::GetRef:
1205  {
1206  switch( pField->GetSubType() )
1207  {
1208  case REF_BOOKMARK:
1209  {
1210  const SwGetRefField* pRefField = dynamic_cast<const SwGetRefField*>(pField);
1211  if ( pRefField && pRefField->IsRefToHeadingCrossRefBookmark() )
1212  sEntry = "Headings";
1213  else if ( pRefField && pRefField->IsRefToNumItemCrossRefBookmark() )
1214  sEntry = "Numbered Paragraphs";
1215  else
1216  sEntry = "Bookmarks";
1217  }
1218  break;
1219  case REF_FOOTNOTE:
1220  sEntry = "Footnotes";
1221  break;
1222  case REF_ENDNOTE:
1223  sEntry = "Endnotes";
1224  break;
1225  case REF_SETREFATTR:
1226  sEntry = "Insert Reference";
1227  break;
1228  case REF_SEQUENCEFLD:
1229  sEntry = static_cast<const SwGetRefField*>(pField)->GetSetRefName();
1230  break;
1231  }
1232  //Get format string
1233  strTypeName = sEntry;
1234  // <pField->GetFormat() >= 0> is always true as <pField->GetFormat()> is unsigned
1235 // if (pField->GetFormat() >= 0)
1236  {
1237  sEntry = aMgr.GetFormatStr( pField->GetTypeId(), pField->GetFormat() );
1238  if (sEntry.getLength() > 0)
1239  {
1240  strTypeName += "-";
1241  strTypeName += sEntry;
1242  }
1243  }
1244  }
1245  break;
1246  case SwFieldIds::DateTime:
1247  subType = static_cast<const SwDateTimeField*>(pField)->GetSubType();
1248  break;
1249  case SwFieldIds::JumpEdit:
1250  {
1251  const sal_uInt32 nFormat= pField->GetFormat();
1252  const sal_uInt16 nSize = aMgr.GetFormatCount(pField->GetTypeId(), false);
1253  if (nFormat < nSize)
1254  {
1255  sEntry = aMgr.GetFormatStr(pField->GetTypeId(), nFormat);
1256  if (sEntry.getLength() > 0)
1257  {
1258  strTypeName += "-";
1259  strTypeName += sEntry;
1260  }
1261  }
1262  }
1263  break;
1264  case SwFieldIds::ExtUser:
1265  subType = static_cast<const SwExtUserField*>(pField)->GetSubType();
1266  break;
1268  case SwFieldIds::SetExp:
1269  {
1270  sEntry = pField->GetTyp()->GetName();
1271  if (sEntry.getLength() > 0)
1272  {
1273  strTypeName += "-";
1274  strTypeName += sEntry;
1275  }
1276  }
1277  break;
1278  case SwFieldIds::DocInfo:
1279  subType = pField->GetSubType();
1280  subType &= 0x00ff;
1281  break;
1283  {
1284  const SwRefPageSetField* pRPld = static_cast<const SwRefPageSetField*>(pField);
1285  bool bOn = pRPld->IsOn();
1286  strTypeName += "-";
1287  if (bOn)
1288  strTypeName += "on";
1289  else
1290  strTypeName += "off";
1291  }
1292  break;
1293  case SwFieldIds::Author:
1294  {
1295  strTypeName += "-";
1296  strTypeName += aMgr.GetFormatStr(pField->GetTypeId(), pField->GetFormat() & 0xff);
1297  }
1298  break;
1299  default: break;
1300  }
1301  if (subType > 0 || nWhich == SwFieldIds::DocInfo || nWhich == SwFieldIds::ExtUser || nWhich == SwFieldIds::DocStat)
1302  {
1303  std::vector<OUString> aLst;
1304  aMgr.GetSubTypes(pField->GetTypeId(), aLst);
1305  if (subType < aLst.size())
1306  sEntry = aLst[subType];
1307  if (sEntry.getLength() > 0)
1308  {
1309  if (nWhich == SwFieldIds::DocInfo)
1310  {
1311  strTypeName = sEntry;
1312  sal_uInt16 nSize = aMgr.GetFormatCount(pField->GetTypeId(), false);
1313  const sal_uInt16 nExSub = pField->GetSubType() & 0xff00;
1314  if (nSize > 0 && nExSub > 0)
1315  {
1316  //Get extra subtype string
1317  strTypeName += "-";
1318  sEntry = aMgr.GetFormatStr(pField->GetTypeId(), nExSub/0x0100-1);
1319  strTypeName += sEntry;
1320  }
1321  }
1322  else
1323  {
1324  strTypeName += "-";
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  MapMode aMapMode = pWin->GetMapMode();
2129  Point aCorePoint( GetMap()->PixelToCore( aPoint ) );
2130  if( !aLogBounds.IsInside( aCorePoint ) )
2131  {
2132  // #i12332# rPoint is may also be in rectangle returned by
2133  // getCharacterBounds(getCharacterCount()
2134 
2135  awt::Rectangle aRectEndPos =
2137 
2138  if (rPoint.X - aRectEndPos.X >= 0 &&
2139  rPoint.X - aRectEndPos.X < aRectEndPos.Width &&
2140  rPoint.Y - aRectEndPos.Y >= 0 &&
2141  rPoint.Y - aRectEndPos.Y < aRectEndPos.Height)
2142  return getCharacterCount();
2143 
2144  return -1;
2145  }
2146 
2147  // ask core for position
2148  OSL_ENSURE( GetFrame() != nullptr, "The text frame has vanished!" );
2149  OSL_ENSURE( GetFrame()->IsTextFrame(), "The text frame has mutated!" );
2150  const SwTextFrame* pFrame = static_cast<const SwTextFrame*>( GetFrame() );
2151  // construct SwPosition (where GetCursorOfst() will put the result into)
2152  SwTextNode* pNode = const_cast<SwTextNode*>(pFrame->GetTextNodeFirst());
2153  SwPosition aPos(*pNode, 0);
2154  SwCursorMoveState aMoveState;
2155  aMoveState.m_bPosMatchesBounds = true;
2156  const bool bSuccess = pFrame->GetCursorOfst( &aPos, aCorePoint, &aMoveState );
2157 
2158  TextFrameIndex nIndex = pFrame->MapModelToViewPos(aPos);
2159  if (TextFrameIndex(0) < nIndex)
2160  {
2161  assert(bSuccess);
2162  SwRect aResultRect;
2163  pFrame->GetCharRect( aResultRect, aPos );
2164  bool bVert = pFrame->IsVertical();
2165  bool bR2L = pFrame->IsRightToLeft();
2166 
2167  if ( (!bVert && aResultRect.Pos().getX() > aCorePoint.getX()) ||
2168  ( bVert && aResultRect.Pos().getY() > aCorePoint.getY()) ||
2169  ( bR2L && aResultRect.Right() < aCorePoint.getX()) )
2170  {
2171  SwPosition aPosPrev(pFrame->MapViewToModelPos(nIndex - TextFrameIndex(1)));
2172  SwRect aResultRectPrev;
2173  pFrame->GetCharRect( aResultRectPrev, aPosPrev );
2174  if ( (!bVert && aResultRectPrev.Pos().getX() < aCorePoint.getX() && aResultRect.Pos().getY() == aResultRectPrev.Pos().getY()) ||
2175  ( bVert && aResultRectPrev.Pos().getY() < aCorePoint.getY() && aResultRect.Pos().getX() == aResultRectPrev.Pos().getX()) ||
2176  ( bR2L && aResultRectPrev.Right() > aCorePoint.getX() && aResultRect.Pos().getY() == aResultRectPrev.Pos().getY()) )
2177  {
2178  --nIndex;
2179  }
2180  }
2181  }
2182 
2183  return bSuccess
2185  : -1;
2186 }
2187 
2189 {
2190  SolarMutexGuard aGuard;
2191 
2192  ThrowIfDisposed();
2193 
2194  sal_Int32 nStart, nEnd;
2195  bool bSelected = GetSelection( nStart, nEnd );
2196  return bSelected
2197  ? GetString().copy( nStart, nEnd - nStart )
2198  : OUString();
2199 }
2200 
2202 {
2203  SolarMutexGuard aGuard;
2204 
2205  ThrowIfDisposed();
2206 
2207  sal_Int32 nStart, nEnd;
2208  GetSelection( nStart, nEnd );
2209  return nStart;
2210 }
2211 
2213 {
2214  SolarMutexGuard aGuard;
2215 
2216  ThrowIfDisposed();
2217 
2218  sal_Int32 nStart, nEnd;
2219  GetSelection( nStart, nEnd );
2220  return nEnd;
2221 }
2222 
2223 sal_Bool SwAccessibleParagraph::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2224 {
2225  SolarMutexGuard aGuard;
2226 
2227  ThrowIfDisposed();
2228 
2229  // parameter checking
2230  sal_Int32 nLength = GetString().getLength();
2231  if ( ! IsValidRange( nStartIndex, nEndIndex, nLength ) )
2232  {
2233  throw lang::IndexOutOfBoundsException();
2234  }
2235 
2236  bool bRet = false;
2237 
2238  // get cursor shell
2239  SwCursorShell* pCursorShell = GetCursorShell();
2240  if( pCursorShell != nullptr )
2241  {
2242  // create pam for selection
2243  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
2244  TextFrameIndex const nStart(GetPortionData().GetCoreViewPosition(nStartIndex));
2245  TextFrameIndex const nEnd(GetPortionData().GetCoreViewPosition(nEndIndex));
2246  SwPaM aPaM(pFrame->MapViewToModelPos(nStart));
2247  aPaM.SetMark();
2248  *aPaM.GetPoint() = pFrame->MapViewToModelPos(nEnd);
2249 
2250  // set PaM at cursor shell
2251  bRet = Select( aPaM );
2252  }
2253 
2254  return bRet;
2255 }
2256 
2258 {
2259  SolarMutexGuard aGuard;
2260 
2261  ThrowIfDisposed();
2262 
2263  return GetString();
2264 }
2265 
2267  sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2268 {
2269  SolarMutexGuard aGuard;
2270 
2271  ThrowIfDisposed();
2272 
2273  OUString sText( GetString() );
2274 
2275  if ( !IsValidRange( nStartIndex, nEndIndex, sText.getLength() ) )
2276  throw lang::IndexOutOfBoundsException();
2277 
2278  OrderRange( nStartIndex, nEndIndex );
2279  return sText.copy(nStartIndex, nEndIndex-nStartIndex );
2280 }
2281 
2282 /*accessibility::*/TextSegment SwAccessibleParagraph::getTextAtIndex( sal_Int32 nIndex, sal_Int16 nTextType )
2283 {
2284  SolarMutexGuard aGuard;
2285 
2286  ThrowIfDisposed();
2287 
2288  /*accessibility::*/TextSegment aResult;
2289  aResult.SegmentStart = -1;
2290  aResult.SegmentEnd = -1;
2291 
2292  const OUString rText = GetString();
2293  // implement the silly specification that first position after
2294  // text must return an empty string, rather than throwing an
2295  // IndexOutOfBoundsException, except for LINE, where the last
2296  // line is returned
2297  if( nIndex == rText.getLength() && AccessibleTextType::LINE != nTextType )
2298  return aResult;
2299 
2300  // with error checking
2301  i18n::Boundary aBound;
2302  bool bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
2303 
2304  OSL_ENSURE( aBound.startPos >= 0, "illegal boundary" );
2305  OSL_ENSURE( aBound.startPos <= aBound.endPos, "illegal boundary" );
2306 
2307  // return word (if present)
2308  if ( bWord )
2309  {
2310  aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
2311  aResult.SegmentStart = aBound.startPos;
2312  aResult.SegmentEnd = aBound.endPos;
2313  }
2314 
2315  return aResult;
2316 }
2317 
2318 /*accessibility::*/TextSegment SwAccessibleParagraph::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 nTextType )
2319 {
2320  SolarMutexGuard aGuard;
2321 
2322  ThrowIfDisposed();
2323 
2324  const OUString rText = GetString();
2325 
2326  /*accessibility::*/TextSegment aResult;
2327  aResult.SegmentStart = -1;
2328  aResult.SegmentEnd = -1;
2329  //If nIndex = 0, then nobefore text so return -1 directly.
2330  if( nIndex == 0 )
2331  return aResult;
2332  //Tab will be return when call WORDTYPE
2333 
2334  // get starting pos
2335  i18n::Boundary aBound;
2336  if (nIndex == rText.getLength())
2337  aBound.startPos = aBound.endPos = nIndex;
2338  else
2339  {
2340  bool bTmp = GetTextBoundary( aBound, rText, nIndex, nTextType );
2341 
2342  if ( ! bTmp )
2343  aBound.startPos = aBound.endPos = nIndex;
2344  }
2345 
2346  // now skip to previous word
2347  if (nTextType==2 || nTextType == 3)
2348  {
2349  i18n::Boundary preBound = aBound;
2350  while(preBound.startPos==aBound.startPos && nIndex > 0)
2351  {
2352  nIndex = min( nIndex, preBound.startPos ) - 1;
2353  if( nIndex < 0 ) break;
2354  GetTextBoundary( preBound, rText, nIndex, nTextType );
2355  }
2356  //if (nIndex>0)
2357  if (nIndex>=0)
2358  //Tab will be return when call WORDTYPE
2359  {
2360  aResult.SegmentText = rText.copy( preBound.startPos, preBound.endPos - preBound.startPos );
2361  aResult.SegmentStart = preBound.startPos;
2362  aResult.SegmentEnd = preBound.endPos;
2363  }
2364  }
2365  else
2366  {
2367  bool bWord = false;
2368  while( !bWord )
2369  {
2370  nIndex = min( nIndex, aBound.startPos ) - 1;
2371  if( nIndex >= 0 )
2372  {
2373  bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
2374  }
2375  else
2376  break; // exit if beginning of string is reached
2377  }
2378 
2379  if (bWord && nIndex<rText.getLength())
2380  {
2381  aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
2382  aResult.SegmentStart = aBound.startPos;
2383  aResult.SegmentEnd = aBound.endPos;
2384  }
2385  }
2386  return aResult;
2387 }
2388 
2389 /*accessibility::*/TextSegment SwAccessibleParagraph::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 nTextType )
2390 {
2391  SolarMutexGuard aGuard;
2392 
2393  ThrowIfDisposed();
2394 
2395  /*accessibility::*/TextSegment aResult;
2396  aResult.SegmentStart = -1;
2397  aResult.SegmentEnd = -1;
2398  const OUString rText = GetString();
2399 
2400  // implement the silly specification that first position after
2401  // text must return an empty string, rather than throwing an
2402  // IndexOutOfBoundsException
2403  if( nIndex == rText.getLength() )
2404  return aResult;
2405 
2406  // get first word, then skip to next word
2407  i18n::Boundary aBound;
2408  GetTextBoundary( aBound, rText, nIndex, nTextType );
2409  bool bWord = false;
2410  while( !bWord )
2411  {
2412  nIndex = max( sal_Int32(nIndex+1), aBound.endPos );
2413  if( nIndex < rText.getLength() )
2414  bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
2415  else
2416  break; // exit if end of string is reached
2417  }
2418 
2419  if ( bWord )
2420  {
2421  aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
2422  aResult.SegmentStart = aBound.startPos;
2423  aResult.SegmentEnd = aBound.endPos;
2424  }
2425 
2426 /*
2427  sal_Bool bWord = sal_False;
2428  bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
2429 
2430  if (nTextType==2)
2431  {
2432  Boundary nexBound=aBound;
2433 
2434  // real current word
2435  if( nIndex <= aBound.endPos && nIndex >= aBound.startPos )
2436  {
2437  while(nexBound.endPos==aBound.endPos&&nIndex<rText.getLength())
2438  {
2439  // nIndex = max( (sal_Int32)(nIndex), nexBound.endPos) + 1;
2440  nIndex = max( (sal_Int32)(nIndex), nexBound.endPos) ;
2441  const sal_Unicode* pStr = rText.getStr();
2442  if (pStr)
2443  {
2444  if( pStr[nIndex] == sal_Unicode(' ') )
2445  nIndex++;
2446  }
2447  if( nIndex < rText.getLength() )
2448  {
2449  bWord = GetTextBoundary( nexBound, rText, nIndex, nTextType );
2450  }
2451  }
2452  }
2453 
2454  if (bWord && nIndex<rText.getLength())
2455  {
2456  aResult.SegmentText = rText.copy( nexBound.startPos, nexBound.endPos - nexBound.startPos );
2457  aResult.SegmentStart = nexBound.startPos;
2458  aResult.SegmentEnd = nexBound.endPos;
2459  }
2460 
2461  }
2462  else
2463  {
2464  bWord = sal_False;
2465  while( !bWord )
2466  {
2467  nIndex = max( (sal_Int32)(nIndex+1), aBound.endPos );
2468  if( nIndex < rText.getLength() )
2469  {
2470  bWord = GetTextBoundary( aBound, rText, nIndex, nTextType );
2471  }
2472  else
2473  break; // exit if end of string is reached
2474  }
2475  if (bWord && nIndex<rText.getLength())
2476  {
2477  aResult.SegmentText = rText.copy( aBound.startPos, aBound.endPos - aBound.startPos );
2478  aResult.SegmentStart = aBound.startPos;
2479  aResult.SegmentEnd = aBound.endPos;
2480  }
2481  }
2482 */
2483  return aResult;
2484 }
2485 
2486 sal_Bool SwAccessibleParagraph::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2487 {
2488  SolarMutexGuard aGuard;
2489 
2490  ThrowIfDisposed();
2491 
2492  // select and copy (through dispatch mechanism)
2493  setSelection( nStartIndex, nEndIndex );
2494  ExecuteAtViewShell( SID_COPY );
2495  return true;
2496 }
2497 
2498 // XAccessibleEditableText
2499 
2500 sal_Bool SwAccessibleParagraph::cutText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2501 {
2502  SolarMutexGuard aGuard;
2503 
2504  ThrowIfDisposed();
2505 
2506  if( !IsEditableState() )
2507  return false;
2508 
2509  // select and cut (through dispatch mechanism)
2510  setSelection( nStartIndex, nEndIndex );
2511  ExecuteAtViewShell( SID_CUT );
2512  return true;
2513 }
2514 
2516 {
2517  SolarMutexGuard aGuard;
2518 
2519  ThrowIfDisposed();
2520 
2521  if( !IsEditableState() )
2522  return false;
2523 
2524  // select and paste (through dispatch mechanism)
2525  setSelection( nIndex, nIndex );
2526  ExecuteAtViewShell( SID_PASTE );
2527  return true;
2528 }
2529 
2530 sal_Bool SwAccessibleParagraph::deleteText( sal_Int32 nStartIndex, sal_Int32 nEndIndex )
2531 {
2532  return replaceText( nStartIndex, nEndIndex, OUString() );
2533 }
2534 
2535 sal_Bool SwAccessibleParagraph::insertText( const OUString& sText, sal_Int32 nIndex )
2536 {
2537  return replaceText( nIndex, nIndex, sText );
2538 }
2539 
2541  sal_Int32 nStartIndex, sal_Int32 nEndIndex,
2542  const OUString& sReplacement )
2543 {
2544  SolarMutexGuard aGuard;
2545 
2546  ThrowIfDisposed();
2547 
2548  const OUString& rText = GetString();
2549 
2550  if( !IsValidRange( nStartIndex, nEndIndex, rText.getLength() ) )
2551  throw lang::IndexOutOfBoundsException();
2552 
2553  if( !IsEditableState() )
2554  return false;
2555 
2556  // translate positions
2557  TextFrameIndex nStart;
2558  TextFrameIndex nEnd;
2559  bool bSuccess = GetPortionData().GetEditableRange(
2560  nStartIndex, nEndIndex, nStart, nEnd );
2561 
2562  // edit only if the range is editable
2563  if( bSuccess )
2564  {
2565  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
2566  // create SwPosition for nStartIndex
2567  SwPosition aStartPos(pFrame->MapViewToModelPos(nStart));
2568 
2569  // create SwPosition for nEndIndex
2570  SwPosition aEndPos(pFrame->MapViewToModelPos(nEnd));
2571 
2572  // now create XTextRange as helper and set string
2573  const uno::Reference<text::XTextRange> xRange(
2575  const_cast<SwDoc&>(pFrame->GetDoc()), aStartPos, &aEndPos));
2576  xRange->setString(sReplacement);
2577 
2578  // delete portion data
2579  ClearPortionData();
2580  }
2581 
2582  return bSuccess;
2583 
2584 }
2585 
2587  sal_Int32 nStartIndex,
2588  sal_Int32 nEndIndex,
2589  const uno::Sequence<PropertyValue>& rAttributeSet )
2590 {
2591  SolarMutexGuard aGuard;
2592 
2593  ThrowIfDisposed();
2594 
2595  const OUString& rText = GetString();
2596 
2597  if( ! IsValidRange( nStartIndex, nEndIndex, rText.getLength() ) )
2598  throw lang::IndexOutOfBoundsException();
2599 
2600  if( !IsEditableState() )
2601  return false;
2602 
2603  // create a (dummy) text portion for the sole purpose of calling
2604  // setPropertyValue on it
2605  uno::Reference<XMultiPropertySet> xPortion = CreateUnoPortion( nStartIndex,
2606  nEndIndex );
2607 
2608  // build sorted index array
2609  sal_Int32 nLength = rAttributeSet.getLength();
2610  const PropertyValue* pPairs = rAttributeSet.getConstArray();
2611  std::vector<sal_Int32> aIndices(nLength);
2612  std::iota(aIndices.begin(), aIndices.end(), 0);
2613  std::sort(aIndices.begin(), aIndices.end(), IndexCompare(pPairs));
2614 
2615  // create sorted sequences according to index array
2616  uno::Sequence< OUString > aNames( nLength );
2617  OUString* pNames = aNames.getArray();
2618  uno::Sequence< uno::Any > aValues( nLength );
2619  uno::Any* pValues = aValues.getArray();
2620  for (sal_Int32 i = 0; i < nLength; ++i)
2621  {
2622  const PropertyValue& rVal = pPairs[aIndices[i]];
2623  pNames[i] = rVal.Name;
2624  pValues[i] = rVal.Value;
2625  }
2626  aIndices.clear();
2627 
2628  // now set the values
2629  bool bRet = true;
2630  try
2631  {
2632  xPortion->setPropertyValues( aNames, aValues );
2633  }
2634  catch (const UnknownPropertyException&)
2635  {
2636  // error handling through return code!
2637  bRet = false;
2638  }
2639 
2640  return bRet;
2641 }
2642 
2644 {
2645  return replaceText(0, GetString().getLength(), sText);
2646 }
2647 
2648 // XAccessibleSelection
2649 
2651  sal_Int32 nChildIndex )
2652 {
2653  ThrowIfDisposed();
2654 
2656 }
2657 
2659  sal_Int32 nChildIndex )
2660 {
2661  ThrowIfDisposed();
2662 
2663  return m_aSelectionHelper.isAccessibleChildSelected(nChildIndex);
2664 }
2665 
2667 {
2668  ThrowIfDisposed();
2669 }
2670 
2672 {
2673  ThrowIfDisposed();
2674 
2676 }
2677 
2679 {
2680  ThrowIfDisposed();
2681 
2683 }
2684 
2686  sal_Int32 nSelectedChildIndex )
2687 {
2688  ThrowIfDisposed();
2689 
2690  return m_aSelectionHelper.getSelectedAccessibleChild(nSelectedChildIndex);
2691 }
2692 
2693 // index has to be treated as global child index.
2695  sal_Int32 nChildIndex )
2696 {
2697  ThrowIfDisposed();
2698 
2700 }
2701 
2702 // XAccessibleHypertext
2703 
2705 {
2710 
2711 public:
2712  explicit SwHyperlinkIter_Impl(const SwTextFrame & rTextFrame);
2713  const SwTextAttr *next(SwTextNode const** ppNode = nullptr);
2714 
2715  TextFrameIndex startIdx() const { return m_nStt; }
2716  TextFrameIndex endIdx() const { return m_nEnd; }
2717 };
2718 
2720  : m_rFrame(rTextFrame)
2721  , m_Iter(rTextFrame)
2722  , m_nStt(rTextFrame.GetOfst())
2723 {
2724  const SwTextFrame *const pFollFrame = rTextFrame.GetFollow();
2725  m_nEnd = pFollFrame ? pFollFrame->GetOfst() : TextFrameIndex(rTextFrame.GetText().getLength());
2726 }
2727 
2729 {
2730  const SwTextAttr *pAttr = nullptr;
2731  if (ppNode)
2732  {
2733  *ppNode = nullptr;
2734  }
2735 
2736  SwTextNode const* pNode(nullptr);
2737  while (SwTextAttr const*const pHt = m_Iter.NextAttr(&pNode))
2738  {
2739  if (RES_TXTATR_INETFMT == pHt->Which())
2740  {
2741  const TextFrameIndex nHtStt(m_rFrame.MapModelToView(pNode, pHt->GetStart()));
2742  const TextFrameIndex nHtEnd(m_rFrame.MapModelToView(pNode, pHt->GetAnyEnd()));
2743  if (nHtEnd > nHtStt &&
2744  ((nHtStt >= m_nStt && nHtStt < m_nEnd) ||
2745  (nHtEnd > m_nStt && nHtEnd <= m_nEnd)))
2746  {
2747  pAttr = pHt;
2748  if (ppNode)
2749  {
2750  *ppNode = pNode;
2751  }
2752  break;
2753  }
2754  }
2755  }
2756 
2757  return pAttr;
2758 };
2759 
2761 {
2762  SolarMutexGuard aGuard;
2763 
2764  ThrowIfDisposed();
2765 
2766  sal_Int32 nCount = 0;
2767  // #i77108# - provide hyperlinks also in editable documents.
2768 
2769  const SwTextFrame *pTextFrame = static_cast<const SwTextFrame*>( GetFrame() );
2770  SwHyperlinkIter_Impl aIter(*pTextFrame);
2771  while( aIter.next() )
2772  nCount++;
2773 
2774  return nCount;
2775 }
2776 
2777 uno::Reference< XAccessibleHyperlink > SAL_CALL
2778  SwAccessibleParagraph::getHyperLink( sal_Int32 nLinkIndex )
2779 {
2780  SolarMutexGuard aGuard;
2781 
2782  ThrowIfDisposed();
2783 
2784  uno::Reference< XAccessibleHyperlink > xRet;
2785 
2786  const SwTextFrame *pTextFrame = static_cast<const SwTextFrame*>( GetFrame() );
2787  SwHyperlinkIter_Impl aHIter(*pTextFrame);
2788  SwTextNode const* pNode(nullptr);
2789  SwTextAttr* pHt = const_cast<SwTextAttr*>(aHIter.next(&pNode));
2790  for (sal_Int32 nTIndex = 0; pHt && nTIndex <= nLinkIndex; ++nTIndex)
2791  {
2792  if( nTIndex == nLinkIndex )
2793  { // found
2794  if (!m_pHyperTextData)
2797  m_pHyperTextData ->find( pHt );
2798  if (aIter != m_pHyperTextData->end())
2799  {
2800  xRet = (*aIter).second;
2801  }
2802  if (!xRet.is())
2803  {
2804  TextFrameIndex const nHintStart(pTextFrame->MapModelToView(pNode, pHt->GetStart()));
2805  TextFrameIndex const nHintEnd(pTextFrame->MapModelToView(pNode, pHt->GetAnyEnd()));
2806  const sal_Int32 nTmpHStt = GetPortionData().GetAccessiblePosition(
2807  max(aHIter.startIdx(), nHintStart));
2808  const sal_Int32 nTmpHEnd = GetPortionData().GetAccessiblePosition(
2809  min(aHIter.endIdx(), nHintEnd));
2810  xRet = new SwAccessibleHyperlink(*pHt,
2811  *this, nTmpHStt, nTmpHEnd );
2812  if (aIter != m_pHyperTextData->end())
2813  {
2814  (*aIter).second = xRet;
2815  }
2816  else
2817  {
2818  m_pHyperTextData->emplace( pHt, xRet );
2819  }
2820  }
2821  break;
2822  }
2823 
2824  // iterate next hyperlink
2825  pHt = const_cast<SwTextAttr*>(aHIter.next(&pNode));
2826  }
2827  if( !xRet.is() )
2828  throw lang::IndexOutOfBoundsException();
2829 
2830  return xRet;
2831 }
2832 
2833 sal_Int32 SAL_CALL SwAccessibleParagraph::getHyperLinkIndex( sal_Int32 nCharIndex )
2834 {
2835  SolarMutexGuard aGuard;
2836 
2837  ThrowIfDisposed();
2838 
2839  // parameter checking
2840  sal_Int32 nLength = GetString().getLength();
2841  if ( ! IsValidPosition( nCharIndex, nLength ) )
2842  {
2843  throw lang::IndexOutOfBoundsException();
2844  }
2845 
2846  sal_Int32 nRet = -1;
2847  // #i77108#
2848  {
2849  const SwTextFrame *pTextFrame = static_cast<const SwTextFrame*>( GetFrame() );
2850  SwHyperlinkIter_Impl aHIter(*pTextFrame);
2851 
2852  const TextFrameIndex nIdx = GetPortionData().GetCoreViewPosition(nCharIndex);
2853  sal_Int32 nPos = 0;
2854  SwTextNode const* pNode(nullptr);
2855  const SwTextAttr *pHt = aHIter.next(&pNode);
2856  while (pHt && !(nIdx >= pTextFrame->MapModelToView(pNode, pHt->GetStart())
2857  && nIdx < pTextFrame->MapModelToView(pNode, pHt->GetAnyEnd())))
2858  {
2859  pHt = aHIter.next(&pNode);
2860  nPos++;
2861  }
2862 
2863  if( pHt )
2864  nRet = nPos;
2865  }
2866 
2867  if (nRet == -1)
2868  throw lang::IndexOutOfBoundsException();
2869  return nRet;
2870 }
2871 
2872 // #i71360#, #i108125# - adjustments for change tracking text markup
2873 sal_Int32 SAL_CALL SwAccessibleParagraph::getTextMarkupCount( sal_Int32 nTextMarkupType )
2874 {
2875  SolarMutexGuard g;
2876 
2877  std::unique_ptr<SwTextMarkupHelper> pTextMarkupHelper;
2878  switch ( nTextMarkupType )
2879  {
2880  case text::TextMarkupType::TRACK_CHANGE_INSERTION:
2881  case text::TextMarkupType::TRACK_CHANGE_DELETION:
2882  case text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE:
2883  {
2884  pTextMarkupHelper.reset( new SwTextMarkupHelper(
2885  GetPortionData(),
2886  *(mpParaChangeTrackInfo->getChangeTrackingTextMarkupList( nTextMarkupType ) )) );
2887  }
2888  break;
2889  default:
2890  {
2891  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
2892  pTextMarkupHelper.reset(new SwTextMarkupHelper(GetPortionData(), *pFrame));
2893  }
2894  }
2895 
2896  return pTextMarkupHelper->getTextMarkupCount( nTextMarkupType );
2897 }
2898 
2899 //MSAA Extension Implementation in app module
2900 sal_Bool SAL_CALL SwAccessibleParagraph::scrollToPosition( const css::awt::Point&, sal_Bool )
2901 {
2902  return false;
2903 }
2904 
2906 {
2907  SolarMutexGuard g;
2908 
2909  sal_Int32 nSelected = 0;
2910  SwPaM* pCursor = GetCursor( true );
2911  if( pCursor != nullptr )
2912  {
2913  // get SwPosition for my node
2914  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
2915  sal_uLong nFirstNode(pFrame->GetTextNodeFirst()->GetIndex());
2916  sal_uLong nLastNode;
2917  if (sw::MergedPara const*const pMerged = pFrame->GetMergedPara())
2918  {
2919  nLastNode = pMerged->pLastNode->GetIndex();
2920  }
2921  else
2922  {
2923  nLastNode = nFirstNode;
2924  }
2925 
2926  // iterate over ring
2927  for(SwPaM& rTmpCursor : pCursor->GetRingContainer())
2928  {
2929  // ignore, if no mark
2930  if( rTmpCursor.HasMark() )
2931  {
2932  // check whether frame's node(s) are 'inside' pCursor
2933  SwPosition* pStart = rTmpCursor.Start();
2934  sal_uLong nStartIndex = pStart->nNode.GetIndex();
2935  SwPosition* pEnd = rTmpCursor.End();
2936  sal_uLong nEndIndex = pEnd->nNode.GetIndex();
2937  if ((nStartIndex <= nLastNode) && (nFirstNode <= nEndIndex))
2938  {
2939  nSelected++;
2940  }
2941  // else: this PaM doesn't point to this paragraph
2942  }
2943  // else: this PaM is collapsed and doesn't select anything
2944  }
2945  }
2946  return nSelected;
2947 
2948 }
2949 
2950 sal_Int32 SAL_CALL SwAccessibleParagraph::getSeletedPositionStart( sal_Int32 nSelectedPortionIndex )
2951 {
2952  SolarMutexGuard aGuard;
2953 
2954  ThrowIfDisposed();
2955 
2956  sal_Int32 nStart, nEnd;
2957  /*sal_Bool bSelected = */GetSelectionAtIndex(&nSelectedPortionIndex, nStart, nEnd );
2958  return nStart;
2959 }
2960 
2961 sal_Int32 SAL_CALL SwAccessibleParagraph::getSeletedPositionEnd( sal_Int32 nSelectedPortionIndex )
2962 {
2963  SolarMutexGuard aGuard;
2964 
2965  ThrowIfDisposed();
2966 
2967  sal_Int32 nStart, nEnd;
2968  /*sal_Bool bSelected = */GetSelectionAtIndex(&nSelectedPortionIndex, nStart, nEnd );
2969  return nEnd;
2970 }
2971 
2972 sal_Bool SAL_CALL SwAccessibleParagraph::removeSelection( sal_Int32 selectionIndex )
2973 {
2974  SolarMutexGuard g;
2975 
2976  if(selectionIndex < 0) return false;
2977 
2978  sal_Int32 nSelected = selectionIndex;
2979 
2980  // get the selection, and test whether it affects our text node
2981  SwPaM* pCursor = GetCursor( true );
2982 
2983  if( pCursor != nullptr )
2984  {
2985  bool bRet = false;
2986 
2987  // get SwPosition for my node
2988  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
2989  sal_uLong nFirstNode(pFrame->GetTextNodeFirst()->GetIndex());
2990  sal_uLong nLastNode;
2991  if (sw::MergedPara const*const pMerged = pFrame->GetMergedPara())
2992  {
2993  nLastNode = pMerged->pLastNode->GetIndex();
2994  }
2995  else
2996  {
2997  nLastNode = nFirstNode;
2998  }
2999 
3000  // iterate over ring
3001  SwPaM* pRingStart = pCursor;
3002  do
3003  {
3004  // ignore, if no mark
3005  if( pCursor->HasMark() )
3006  {
3007  // check whether frame's node(s) are 'inside' pCursor
3008  SwPosition* pStart = pCursor->Start();
3009  sal_uLong nStartIndex = pStart->nNode.GetIndex();
3010  SwPosition* pEnd = pCursor->End();
3011  sal_uLong nEndIndex = pEnd->nNode.GetIndex();
3012  if ((nStartIndex <= nLastNode) && (nFirstNode <= nEndIndex))
3013  {
3014  if( nSelected == 0 )
3015  {
3016  pCursor->MoveTo(nullptr);
3017  delete pCursor;
3018  bRet = true;
3019  }
3020  else
3021  {
3022  nSelected--;
3023  }
3024  }
3025  }
3026  // else: this PaM is collapsed and doesn't select anything
3027  if(!bRet)
3028  pCursor = pCursor->GetNext();
3029  }
3030  while( !bRet && (pCursor != pRingStart) );
3031  }
3032  return true;
3033 }
3034 
3035 sal_Int32 SAL_CALL SwAccessibleParagraph::addSelection( sal_Int32, sal_Int32 startOffset, sal_Int32 endOffset)
3036 {
3037  SolarMutexGuard aGuard;
3038 
3039  ThrowIfDisposed();
3040 
3041  // parameter checking
3042  sal_Int32 nLength = GetString().getLength();
3043  if ( ! IsValidRange( startOffset, endOffset, nLength ) )
3044  {
3045  throw lang::IndexOutOfBoundsException();
3046  }
3047 
3048  sal_Int32 nSelectedCount = getSelectedPortionCount();
3049  for ( sal_Int32 i = nSelectedCount ; i >= 0 ; i--)
3050  {
3051  sal_Int32 nStart, nEnd;
3052  bool bSelected = GetSelectionAtIndex(&i, nStart, nEnd );
3053  if(bSelected)
3054  {
3055  if(nStart <= nEnd )
3056  {
3057  if (( startOffset>=nStart && startOffset <=nEnd ) || //startOffset in a selection
3058  ( endOffset>=nStart && endOffset <=nEnd ) || //endOffset in a selection
3059  ( startOffset <= nStart && endOffset >=nEnd) || //start and end include the old selection
3060  ( startOffset >= nStart && endOffset <=nEnd) )
3061  {
3062  removeSelection(i);
3063  }
3064 
3065  }
3066  else
3067  {
3068  if (( startOffset>=nEnd && startOffset <=nStart ) || //startOffset in a selection
3069  ( endOffset>=nEnd && endOffset <=nStart ) || //endOffset in a selection
3070  ( startOffset <= nStart && endOffset >=nEnd) || //start and end include the old selection
3071  ( startOffset >= nStart && endOffset <=nEnd) )
3072 
3073  {
3074  removeSelection(i);
3075  }
3076  }
3077  }
3078 
3079  }
3080 
3081  // get cursor shell
3082  SwCursorShell* pCursorShell = GetCursorShell();
3083  if( pCursorShell != nullptr )
3084  {
3085  // create pam for selection
3086  pCursorShell->StartAction();
3087  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
3088  SwPaM* aPaM = pCursorShell->CreateCursor();
3089  aPaM->SetMark();
3090  *aPaM->GetPoint() = pFrame->MapViewToModelPos(GetPortionData().GetCoreViewPosition(startOffset));
3091  *aPaM->GetMark() = pFrame->MapViewToModelPos(GetPortionData().GetCoreViewPosition(endOffset));
3092  pCursorShell->EndAction();
3093  }
3094 
3095  return 0;
3096 }
3097 
3098 /*accessibility::*/TextSegment SAL_CALL
3099  SwAccessibleParagraph::getTextMarkup( sal_Int32 nTextMarkupIndex,
3100  sal_Int32 nTextMarkupType )
3101 {
3102  SolarMutexGuard g;
3103 
3104  std::unique_ptr<SwTextMarkupHelper> pTextMarkupHelper;
3105  switch ( nTextMarkupType )
3106  {
3107  case text::TextMarkupType::TRACK_CHANGE_INSERTION:
3108  case text::TextMarkupType::TRACK_CHANGE_DELETION:
3109  case text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE:
3110  {
3111  pTextMarkupHelper.reset( new SwTextMarkupHelper(
3112  GetPortionData(),
3113  *(mpParaChangeTrackInfo->getChangeTrackingTextMarkupList( nTextMarkupType ) )) );
3114  }
3115  break;
3116  default:
3117  {
3118  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
3119  pTextMarkupHelper.reset(new SwTextMarkupHelper(GetPortionData(), *pFrame));
3120  }
3121  }
3122 
3123  return pTextMarkupHelper->getTextMarkup( nTextMarkupIndex, nTextMarkupType );
3124 }
3125 
3126 uno::Sequence< /*accessibility::*/TextSegment > SAL_CALL
3128  sal_Int32 nTextMarkupType )
3129 {
3130  SolarMutexGuard g;
3131 
3132  // parameter checking
3133  const sal_Int32 nLength = GetString().getLength();
3134  if ( ! IsValidPosition( nCharIndex, nLength ) )
3135  {
3136  throw lang::IndexOutOfBoundsException();
3137  }
3138 
3139  std::unique_ptr<SwTextMarkupHelper> pTextMarkupHelper;
3140  switch ( nTextMarkupType )
3141  {
3142  case text::TextMarkupType::TRACK_CHANGE_INSERTION:
3143  case text::TextMarkupType::TRACK_CHANGE_DELETION:
3144  case text::TextMarkupType::TRACK_CHANGE_FORMATCHANGE:
3145  {
3146  pTextMarkupHelper.reset( new SwTextMarkupHelper(
3147  GetPortionData(),
3148  *(mpParaChangeTrackInfo->getChangeTrackingTextMarkupList( nTextMarkupType ) )) );
3149  }
3150  break;
3151  default:
3152  {
3153  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
3154  pTextMarkupHelper.reset(new SwTextMarkupHelper(GetPortionData(), *pFrame));
3155  }
3156  }
3157 
3158  return pTextMarkupHelper->getTextMarkupAtIndex( nCharIndex, nTextMarkupType );
3159 }
3160 
3161 // #i89175#
3162 sal_Int32 SAL_CALL SwAccessibleParagraph::getLineNumberAtIndex( sal_Int32 nIndex )
3163 {
3164  SolarMutexGuard g;
3165 
3166  // parameter checking
3167  const sal_Int32 nLength = GetString().getLength();
3168  if ( ! IsValidPosition( nIndex, nLength ) )
3169  {
3170  throw lang::IndexOutOfBoundsException();
3171  }
3172 
3173  const sal_Int32 nLineNo = GetPortionData().GetLineNo( nIndex );
3174  return nLineNo;
3175 }
3176 
3177 /*accessibility::*/TextSegment SAL_CALL
3179 {
3180  SolarMutexGuard g;
3181 
3182  // parameter checking
3183  if ( nLineNo < 0 ||
3184  nLineNo >= GetPortionData().GetLineCount() )
3185  {
3186  throw lang::IndexOutOfBoundsException();
3187  }
3188 
3189  i18n::Boundary aLineBound;
3190  GetPortionData().GetBoundaryOfLine( nLineNo, aLineBound );
3191 
3192  /*accessibility::*/TextSegment aTextAtLine;
3193  const OUString rText = GetString();
3194  aTextAtLine.SegmentText = rText.copy( aLineBound.startPos,
3195  aLineBound.endPos - aLineBound.startPos );
3196  aTextAtLine.SegmentStart = aLineBound.startPos;
3197  aTextAtLine.SegmentEnd = aLineBound.endPos;
3198 
3199  return aTextAtLine;
3200 }
3201 
3202 /*accessibility::*/TextSegment SAL_CALL SwAccessibleParagraph::getTextAtLineWithCaret()
3203 {
3204  SolarMutexGuard g;
3205 
3206  const sal_Int32 nLineNoOfCaret = getNumberOfLineWithCaret();
3207 
3208  if ( nLineNoOfCaret >= 0 &&
3209  nLineNoOfCaret < GetPortionData().GetLineCount() )
3210  {
3211  return getTextAtLineNumber( nLineNoOfCaret );
3212  }
3213 
3214  return /*accessibility::*/TextSegment();
3215 }
3216 
3218 {
3219  SolarMutexGuard g;
3220 
3221  const sal_Int32 nCaretPos = getCaretPosition();
3222  const sal_Int32 nLength = GetString().getLength();
3223  if ( !IsValidPosition( nCaretPos, nLength ) )
3224  {
3225  return -1;
3226  }
3227 
3228  sal_Int32 nLineNo = GetPortionData().GetLineNo( nCaretPos );
3229 
3230  // special handling for cursor positioned at end of text line via End key
3231  if ( nCaretPos != 0 )
3232  {
3233  i18n::Boundary aLineBound;
3234  GetPortionData().GetBoundaryOfLine( nLineNo, aLineBound );
3235  if ( nCaretPos == aLineBound.startPos )
3236  {
3238  if ( pCursorShell != nullptr )
3239  {
3240  const awt::Rectangle aCharRect = getCharacterBounds( nCaretPos );
3241 
3242  const SwRect& aCursorCoreRect = pCursorShell->GetCharRect();
3243  // translate core coordinates into accessibility coordinates
3244  vcl::Window *pWin = GetWindow();
3245  if (!pWin)
3246  {
3247  throw uno::RuntimeException("no Window", static_cast<cppu::OWeakObject*>(this));
3248  }
3249 
3250  tools::Rectangle aScreenRect( GetMap()->CoreToPixel( aCursorCoreRect.SVRect() ));
3251 
3252  SwRect aFrameLogBounds( GetBounds( *(GetMap()) ) ); // twip rel to doc root
3253  Point aFramePixPos( GetMap()->CoreToPixel( aFrameLogBounds.SVRect() ).TopLeft() );
3254  aScreenRect.Move( -aFramePixPos.getX(), -aFramePixPos.getY() );
3255 
3256  // convert into AWT Rectangle
3257  const awt::Rectangle aCursorRect( aScreenRect.Left(),
3258  aScreenRect.Top(),
3259  aScreenRect.GetWidth(),
3260  aScreenRect.GetHeight() );
3261 
3262  if ( aCharRect.X != aCursorRect.X ||
3263  aCharRect.Y != aCursorRect.Y )
3264  {
3265  --nLineNo;
3266  }
3267  }
3268  }
3269  }
3270 
3271  return nLineNo;
3272 }
3273 
3274 // #i108125#
3276 {
3277  mpParaChangeTrackInfo->reset();
3278 }
3279 
3281  sal_Int32 * pSelection, sal_Int32& nStart, sal_Int32& nEnd)
3282 {
3283  if (pSelection && *pSelection < 0) return false;
3284 
3285  bool bRet = false;
3286  nStart = -1;
3287  nEnd = -1;
3288 
3289  // get the selection, and test whether it affects our text node
3290  SwPaM* pCursor = GetCursor( true );
3291  if( pCursor != nullptr )
3292  {
3293  // get SwPosition for my node
3294  SwTextFrame const*const pFrame(static_cast<SwTextFrame const*>(GetFrame()));
3295  sal_uLong nFirstNode(pFrame->GetTextNodeFirst()->GetIndex());
3296  sal_uLong nLastNode;
3297  if (sw::MergedPara const*const pMerged = pFrame->GetMergedPara())
3298  {
3299  nLastNode = pMerged->pLastNode->GetIndex();
3300  }
3301  else
3302  {
3303  nLastNode = nFirstNode;
3304  }
3305 
3306  // iterate over ring
3307  for(SwPaM& rTmpCursor : pCursor->GetRingContainer())
3308  {
3309  // ignore, if no mark
3310  if( rTmpCursor.HasMark() )
3311  {
3312  // check whether frame's node(s) are 'inside' pCursor
3313  SwPosition* pStart = rTmpCursor.Start();
3314  sal_uLong nStartIndex = pStart->nNode.GetIndex();
3315  SwPosition* pEnd = rTmpCursor.End();
3316  sal_uLong nEndIndex = pEnd->nNode.GetIndex();
3317  if ((nStartIndex <= nLastNode) && (nFirstNode <= nEndIndex))
3318  {
3319  if (!pSelection || *pSelection == 0)
3320  {
3321  // translate start and end positions
3322 
3323  // start position
3324  sal_Int32 nLocalStart = -1;
3325  if (nStartIndex < nFirstNode)
3326  {
3327  // selection starts in previous node:
3328  // then our local selection starts with the paragraph
3329  nLocalStart = 0;
3330  }
3331  else
3332  {
3333  assert(FrameContainsNode(*pFrame, nStartIndex));
3334 
3335  // selection starts in this node:
3336  // then check whether it's before or inside our part of
3337  // the paragraph, and if so, get the proper position
3338  const TextFrameIndex nCoreStart =
3339  pFrame->MapModelToViewPos(*pStart);
3340  if( nCoreStart <
3341  GetPortionData().GetFirstValidCorePosition() )
3342  {
3343  nLocalStart = 0;
3344  }
3345  else if( nCoreStart <=
3346  GetPortionData().GetLastValidCorePosition() )
3347  {
3348  SAL_WARN_IF(
3349  !GetPortionData().IsValidCorePosition(
3350  nCoreStart),
3351  "sw.a11y",
3352  "problem determining valid core position");
3353 
3354  nLocalStart =
3356  nCoreStart );
3357  }
3358  }
3359 
3360  // end position
3361  sal_Int32 nLocalEnd = -1;
3362  if (nLastNode < nEndIndex)
3363  {
3364  // selection ends in following node:
3365  // then our local selection extends to the end
3366  nLocalEnd = GetPortionData().GetAccessibleString().
3367  getLength();
3368  }
3369  else
3370  {
3371  assert(FrameContainsNode(*pFrame, nEndIndex));
3372 
3373  // selection ends in this node: then select everything
3374  // before our part of the node
3375  const TextFrameIndex nCoreEnd =
3376  pFrame->MapModelToViewPos(*pEnd);
3377  if( nCoreEnd >
3378  GetPortionData().GetLastValidCorePosition() )
3379  {
3380  // selection extends beyond out part of this para
3381  nLocalEnd = GetPortionData().GetAccessibleString().
3382  getLength();
3383  }
3384  else if( nCoreEnd >=
3385  GetPortionData().GetFirstValidCorePosition() )
3386  {
3387  // selection is inside our part of this para
3388  SAL_WARN_IF(
3389  !GetPortionData().IsValidCorePosition(
3390  nCoreEnd),
3391  "sw.a11y",
3392  "problem determining valid core position");
3393 
3394  nLocalEnd = GetPortionData().GetAccessiblePosition(
3395  nCoreEnd );
3396  }
3397  }
3398 
3399  if( ( nLocalStart != -1 ) && ( nLocalEnd != -1 ) )
3400  {
3401  nStart = nLocalStart;
3402  nEnd = nLocalEnd;
3403  bRet = true;
3404  }
3405  } // if hit the index
3406  else
3407  {
3408  --*pSelection;
3409  }
3410  }
3411  // else: this PaM doesn't point to this paragraph
3412  }
3413  // else: this PaM is collapsed and doesn't select anything
3414  if(bRet)
3415  break;
3416  }
3417  }
3418  // else: nocursor -> no selection
3419 
3420  if (pSelection && bRet)
3421  {
3422  sal_Int32 nCaretPos = GetCaretPos();
3423  if( nStart == nCaretPos )
3424  {
3425  sal_Int32 tmp = nStart;
3426  nStart = nEnd;
3427  nEnd = tmp;
3428  }
3429  }
3430  return bRet;
3431 }
3432 
3434 {
3435  SolarMutexGuard g;
3436 
3437  //Get the real heading level, Heading1 ~ Heading10
3438  if (m_nHeadingLevel > 0)
3439  {
3440  return AccessibleRole::HEADING;
3441  }
3442  else
3443  {
3444  return AccessibleRole::PARAGRAPH;
3445  }
3446 }
3447 
3448 //Get the real heading level, Heading1 ~ Heading10
3450 {
3451  uno::Reference< css::beans::XPropertySet > xPortion = CreateUnoPortion( 0, 0 );
3452  uno::Any styleAny = xPortion->getPropertyValue( "ParaStyleName" );
3453  OUString sValue;
3454  if (styleAny >>= sValue)
3455  {
3456  sal_Int32 length = sValue.getLength();
3457  if (length == 9 || length == 10)
3458  {
3459  OUString headStr = sValue.copy(0, 7);
3460  if (headStr == "Heading")
3461  {
3462  OUString intStr = sValue.copy(8);
3463  sal_Int32 headingLevel = intStr.toInt32();
3464  return headingLevel;
3465  }
3466  }
3467  }
3468  return -1;
3469 }
3470 
3472 {
3473  SolarMutexGuard g;
3474 
3475  uno::Any Ret;
3476  OUString strHeading("heading-level:");
3477  if( m_nHeadingLevel >= 0 )
3478  strHeading += OUString::number(m_nHeadingLevel);
3479  strHeading += ";";
3480 
3481  strHeading += strHeading.copy(8); // tdf#84102: expose the same attribute with the name "level"
3482 
3483  Ret <<= strHeading;
3484 
3485  return Ret;
3486 }
3487 
3488 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual sal_Int32 SAL_CALL getSeletedPositionStart(sal_Int32 nSelectedPortionIndex) override
Definition: accpara.cxx:2950
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:888
bool GetWordBoundary(css::i18n::Boundary &rBound, const OUString &rText, sal_Int32 nPos)
Definition: accpara.cxx:558
Base class of the Writer layout elements.
Definition: frame.hxx:295
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:149
static Color & GetFieldShadingsColor()
Definition: viewopt.cxx:433
long GetWidth() const
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: accpara.cxx:883
sal_uLong GetIndex() const
Definition: node.hxx:282
void FireAccessibleEvent(css::accessibility::AccessibleEventObject &rEvent)
Definition: acccontext.cxx:440
css::uno::Sequence< css::style::TabStop > GetCurrentTabStop(sal_Int32 nIndex)
Definition: accpara.cxx:1082
friend class SwAccessibleHyperlink
Definition: accpara.hxx:64
virtual sal_Bool SAL_CALL setSelection(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
Definition: accpara.cxx:2223
bool GetAttributeBoundary(css::i18n::Boundary &rBound, sal_Int32 nPos)
Definition: accpara.cxx:616
long GetHeight() const
constexpr::Color COL_BLACK(0x00, 0x00, 0x00)
static bool GetParagraphBoundary(css::i18n::Boundary &rBound, const OUString &rText)
Definition: accpara.cxx:607
Marks a position in the document model.
Definition: pam.hxx:35
static bool lcl_GetBackgroundColor(Color &rColor, const SwFrame *pFrame, SwCursorShell *pCursorSh)
Definition: accpara.cxx:805
const SwField * GetField() const
Definition: fmtfld.hxx:71
#define UNO_NAME_CHAR_UNDERLINE_COLOR
Definition: unoprnms.hxx:109
SwPaM * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:184
LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript, bool bNoChar=false) const
Definition: txtfrm.cxx:1340
static OUString GetDescription()
Definition: accpara.cxx:121
#define PROPERTY_MAP_TEXT_CURSOR
Definition: unomap.hxx:29
void ExecuteAtViewShell(sal_uInt16 nSlot)
Definition: accpara.cxx:456
bool m_bRealHeight
should the real height be calculated?
Definition: crstate.hxx:141
SwHyperlinkIter_Impl(const SwTextFrame &rTextFrame)
Definition: accpara.cxx:2719
SwViewShellImp * Imp()
Definition: viewsh.hxx:185
bool IsOutline() const
Returns if this text node is an outline.
Definition: ndtxt.cxx:4001
virtual sal_Int32 SAL_CALL getSeletedPositionEnd(sal_Int32 nSelectedPortionIndex) override
Definition: accpara.cxx:2961
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex) override
Definition: accpara.cxx:2685
#define UNO_NAME_CHAR_FONT_NAME
Definition: unoprnms.hxx:80
virtual void SAL_CALL selectAccessibleChild(sal_Int32 nChildIndex) override
Definition: accpara.cxx:2650
sal_uInt32 GetFormat() const
Query parameters for dialog and for BASIC.
Definition: fldbas.hxx:387
virtual void GetStates(::utl::AccessibleStateSetHelper &rStateSet) override
Definition: accpara.cxx:215
bool HasPara() const
Definition: txtfrm.hxx:808
OUString const & GetString()
get the (accessible) text string (requires frame; check before)
Definition: accpara.cxx:116
const sal_Char sAccessibleServiceName[]
Definition: acccontext.hxx:43
virtual sal_Int32 SAL_CALL getHyperLinkCount() override
Definition: accpara.cxx:2760
SwNodeIndex nNode
Definition: pam.hxx:37
bool IsTableMode() const
Definition: crsrsh.hxx:646
sal_Int32 findValue(const css::uno::Sequence< T1 > &_rList, const T2 &_rValue)
bool IsHeading() const
Definition: accpara.cxx:208
virtual sal_Int32 SAL_CALL getBackground() override
Definition: accpara.cxx:858
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:2586
SwFrameType GetType() const
Definition: frame.hxx:498
#define UNO_NAME_PARA_LEFT_MARGIN
Definition: unoprnms.hxx:55
SfxDispatcher * GetDispatcher()
void _getSupplementalAttributesImpl(const css::uno::Sequence< OUString > &aRequestedAttributes, tAccParaPropValMap &rSupplementalAttrSeq)
Definition: accpara.cxx:1756
virtual sal_Int32 SAL_CALL getForeground() override
Definition: acccontext.cxx:957
TextFrameIndex startIdx() const
Definition: accpara.cxx:2715
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:2212
vcl::Window * GetWindow()
Definition: acccontext.cxx:83
virtual sal_Unicode SAL_CALL getCharacter(sal_Int32 nIndex) override
Definition: accpara.cxx:1067
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:2900
Base class of all fields.
Definition: fldbas.hxx:279
virtual sal_Bool SAL_CALL setText(const OUString &sText) override
Definition: accpara.cxx:2643
TextFrameIndex m_nEnd
Definition: accpara.cxx:2709
#define UNO_NAME_PARA_STYLE_NAME
Definition: unoprnms.hxx:175
sw::MergedPara * GetMergedPara()
Definition: txtfrm.hxx:438
virtual sal_Bool SAL_CALL isAccessibleChildSelected(sal_Int32 nChildIndex) override
Definition: accpara.cxx:2658
#define RES_FRMATR_END
Definition: hintids.hxx:236
#define PROPERTY_MAP_ACCESSIBILITY_TEXT_ATTRIBUTE
Definition: unomap.hxx:127
virtual css::lang::Locale SAL_CALL getLocale() override
Return the parents locale or throw exception if this object has no parent yet/anymore.
Definition: accpara.cxx:720
bool m_bRealWidth
Calculation of the width required.
Definition: crstate.hxx:149
const SfxItemPropertySet * GetPropertySet(sal_uInt16 PropertyId)
Definition: unomap1.cxx:1098
bool GetSelectionAtIndex(sal_Int32 *pSelection, sal_Int32 &nStart, sal_Int32 &nEnd)
Definition: accpara.cxx:3280
sal_uInt16 GetTypeId() const
Definition: fldbas.cxx:209
#define max(a, b)
SwViewShell * GetShell()
convenience method to get the SwViewShell through accessibility map
Definition: acccontext.hxx:116
virtual bool GetCharRect(SwRect &rRect, const SwPosition &rPos, SwCursorMoveState *pCMS=nullptr, bool bAllowFarAway=true) const override
Returns the screen position of rPos.
Definition: frmcrsr.cxx:179
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getRunAttributes(sal_Int32 nIndex, const css::uno::Sequence< OUString > &aRequestedAttributes) override
Definition: accpara.cxx:1734
virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
Definition: accpara.cxx:2389
TextFrameIndex GetOfst() const
Definition: txtfrm.hxx:426
const MapMode & GetMapMode() const
virtual sal_Bool SAL_CALL insertText(const OUString &sText, sal_Int32 nIndex) override
Definition: accpara.cxx:2535
virtual sal_Int32 SAL_CALL getHyperLinkIndex(sal_Int32 nCharIndex) override
Definition: accpara.cxx:2833
#define RES_PARATR_LIST_END
Definition: hintids.hxx:190
TextFrameIndex const m_nStt
Definition: accpara.cxx:2708
void Pos(const Point &rNew)
Definition: swrect.hxx:167
virtual sal_Int32 SAL_CALL getSelectedPortionCount() override
Definition: accpara.cxx:2905
#define UNO_NAME_WRITING_MODE
Definition: unoprnms.hxx:698
virtual sal_Bool SAL_CALL pasteText(sal_Int32 nIndex) override
Definition: accpara.cxx:2515
virtual void InvalidateFocus_() override
Definition: accpara.cxx:379
OUString Name
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
SfxViewShell * GetSfxViewShell() const
Definition: viewsh.hxx:444
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1290
bool IsInside(TextFrameIndex nPos) const
Respect the Follows.
Definition: txtfrm.hxx:818
sal_Int32 GetAnyEnd() const
end (if available), else start
Definition: txatbase.hxx:153
const AuthorCharAttr & GetInsertAuthorAttr() const
Definition: modcfg.hxx:243
SwAccessiblePortionData & GetPortionData()
Definition: accpara.hxx:189
static bool IsValidRange(sal_Int32 nBegin, sal_Int32 nEnd, sal_Int32 nLength)
Definition: accpara.cxx:524
sal_uInt16 m_nAttr
Definition: authratr.hxx:30
void MoveTo(value_type *pDestRing)
Removes this item from its current ring container and adds it to another ring container.
Definition: ring.hxx:135
SwTextAttr const * NextAttr(SwTextNode const **ppNode=nullptr)
Definition: txtfrm.cxx:97
bool IsSymbolAt(sal_Int32 nBegin) const
in ndcopy.cxx
Definition: itratr.cxx:841
void Move(long nHorzMoveDelta, long nVertMoveDelta)
virtual sal_Int32 SAL_CALL getNumberOfLineWithCaret() override
Definition: accpara.cxx:3217
const PropertyValue * pValues
Definition: accpara.cxx:1154
std::map< key_type, mapped_type, key_compare >::iterator iterator
constexpr::Color COL_AUTO(0xFF, 0xFF, 0xFF, 0xFF)
SwCursorShell * GetCursorShell()
convenience method to get SwCursorShell through accessibility map
Definition: acccontext.cxx:101
sal_uInt16 sal_Unicode
constexpr::Color COL_TRANSPARENT(0xFF, 0xFF, 0xFF, 0xFF)
#define RES_CHRATR_END
Definition: hintids.hxx:114
SwViewShell * GetShell() const
Definition: accmap.hxx:169
static bool implInitTextChangedEvent(const OUString &rOldString, const OUString &rNewString, css::uno::Any &rDeleted, css::uno::Any &rInserted)
SwAccessibleSelectionHelper m_aSelectionHelper
Definition: accpara.hxx:84
#define min(a, b)
void GetCursorAttr(SwPaM &rPam, SfxItemSet &rSet, const bool bOnlyTextAttr=false, const bool bGetFromChrFormat=true)
Definition: unoobj2.cxx:357
const SwFrame * GetFrame() const
Definition: accframe.hxx:103
void setX(long nX)
#define UNO_NAME_PARA_LINE_SPACING
Definition: unoprnms.hxx:140
SwDoc * GetDoc() const
Returns the document this position is in.
Definition: pam.cxx:176
virtual bool QueryValue(css::uno::Any &rVal, sal_uInt8 nMemberId=0) const
#define UNO_NAME_PARA_RIGHT_MARGIN
Definition: unoprnms.hxx:56
SwXTextPortion * CreateUnoPortion(sal_Int32 nStart, sal_Int32 nEnd)
Definition: accpara.cxx:481
bool isAccessibleChildSelected(sal_Int32 nChildIndex)
std::unique_ptr< SwAccessiblePortionData > m_pPortionData
Definition: accpara.hxx:73
char sal_Char
#define RES_PARATR_TABSTOP
Definition: hintids.hxx:166
static bool IsValidChar(sal_Int32 nPos, sal_Int32 nLength)
Definition: accpara.cxx:512
length
SwBreakIt * g_pBreakIt
Definition: breakit.cxx:33
#define UNO_NAME_NUMBERING_RULES
Definition: unoprnms.hxx:283
virtual OUString SAL_CALL getText() override
Definition: accpara.cxx:2257
sal_uLong GetIndex() const
Definition: ndindex.hxx:151
sal_uInt16 GetFormatCount(sal_uInt16 nTypeId, bool bHtmlMode) const
Definition: fldmgr.cxx:677
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
sal_Int32 GetStart() const
Definition: txatbase.hxx:82
virtual sal_Int32 SAL_CALL getForeground() override
Definition: accpara.cxx:837
std::shared_ptr< SdrAllFillAttributesHelper > SdrAllFillAttributesHelperPtr
Definition: format.hxx:38
SwAccessibleParagraph(std::shared_ptr< SwAccessibleMap > const &pInitMap, const SwTextFrame &rTextFrame)
Definition: accpara.cxx:396
#define RES_UL_SPACE
Definition: hintids.hxx:197
void AddRelation(const css::accessibility::AccessibleRelation &rRelation)
long Top() const
const SwFormatField & GetFormatField() const
Definition: txatbase.hxx:191
Describes parts of multiple text nodes, which will form a text frame, even when redlines are hidden a...
Definition: txtfrm.hxx:954
#define RES_PARATR_NUMRULE
Definition: hintids.hxx:170
#define RES_PARATR_BEGIN
Definition: hintids.hxx:160
void Right(const long nRight)
Definition: swrect.hxx:198
void setY(long nY)
virtual css::uno::Reference< css::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet() override
Definition: accpara.cxx:736
#define UNO_NAME_CHAR_POSTURE
Definition: unoprnms.hxx:85
const AuthorCharAttr & GetFormatAuthorAttr() const
Definition: modcfg.hxx:251
SwPaM * GetNext()
Definition: pam.hxx:264
virtual css::accessibility::TextSegment SAL_CALL getTextMarkup(sal_Int32 nTextMarkupIndex, sal_Int32 nTextMarkupType) override
Definition: accpara.cxx:3099
SwTextFrame * GetFollow()
Definition: txtfrm.hxx:844
virtual bool GetCharRect(SwRect &, const SwPosition &, SwCursorMoveState *=nullptr, bool bAllowFarAway=true) const
Definition: unusedf.cxx:71
css::uno::Reference< css::lang::XComponent > xComponent
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes(sal_Int32 nIndex, const css::uno::Sequence< OUString > &aRequestedAttributes) override
Definition: accpara.cxx:1336
void GetAttributeBoundary(css::i18n::Boundary &rBound, sal_Int32 nPos) const
virtual sal_Int32 SAL_CALL getTextMarkupCount(sal_Int32 nTextMarkupType) override
Definition: accpara.cxx:2873
bool Select(SwPaM *pPaM, SdrObject *pObj, bool bAdd)
void GetLineBoundary(css::i18n::Boundary &rBound, sal_Int32 nPos) const
get the start & end positions of the sentence
long getY() const
bool IsInGrayPortion(sal_Int32 nPos)
css::uno::Reference< css::accessibility::XAccessible > getSelectedAccessibleChild(sal_Int32 nSelectedChildIndex)
sal_Int32 m_nOldCaretPos
Definition: accpara.hxx:76
virtual OUString SAL_CALL getImplementationName() override
Definition: accpara.cxx:872
const Color & GetColor() const
void FireStateChangedEvent(sal_Int16 nState, bool bNewState)
Definition: acccontext.cxx:464
long getX() const
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:136
SwTextNode * GetTextNodeFirst()
Definition: txtfrm.hxx:445
bool FrameContainsNode(SwContentFrame const &rFrame, sal_uLong nNodeIndex)
Definition: txtfrm.cxx:296
std::unique_ptr< SwParaChangeTrackingInfo > mpParaChangeTrackInfo
Definition: accpara.hxx:86
#define UNO_NAME_CHAR_SHADOWED
Definition: unoprnms.hxx:113
virtual sal_Int16 SAL_CALL getAccessibleRole() override
Definition: accpara.cxx:3433
SwTextNode const * GetTextNodeForParaProps() const
Definition: txtfrm.cxx:1300
virtual sal_Bool SAL_CALL cutText(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
Definition: accpara.cxx:2500
void GetSubTypes(sal_uInt16 nId, std::vector< OUString > &rToFill)
Definition: fldmgr.cxx:574
bool IsRefToNumItemCrossRefBookmark() const
Definition: reffld.cxx:389
virtual void SAL_CALL grabFocus() override
Definition: accpara.cxx:771
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1266
#define SW_MOD()
Definition: swmodule.hxx:256
const SfxItemSet * GetParent() const
#define COL_NONE_COLOR
virtual css::uno::Sequence< css::style::TabStop > GetTabStopInfo(SwTwips)
Definition: frame.hxx:492
virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
Definition: accpara.cxx:2318
SwPaM * CreateCursor()
delete the current cursor and make the following into the current
Definition: crsrsh.cxx:117
SwPaM * GetCursor(const bool _bForSelection)
Definition: accpara.cxx:184
sal_Int32 m_nHeadingLevel
Definition: accpara.hxx:81
const SwPosition * GetPoint() const
Definition: pam.hxx:207
static bool IsValidPosition(sal_Int32 nPos, sal_Int32 nLength)
Definition: accpara.cxx:518
bool IsDark() const
bool GetEditableRange(sal_Int32 nStart, sal_Int32 nEnd, TextFrameIndex &rCoreStart, TextFrameIndex &rCoreEnd) const
Convert start and end positions into core positions.
void EndAction(const bool bIdleEnd=false, const bool DoSetPosX=false)
Definition: crsrsh.cxx:228
void GetBoundaryOfLine(const sal_Int32 nLineNo, css::i18n::Boundary &rLineBound)
virtual css::uno::Any SAL_CALL getExtendedAttributes() override
Definition: accpara.cxx:3471
virtual void SAL_CALL selectAllAccessibleChildren() override
Definition: accpara.cxx:2671
#define UNO_NAME_PARA_ADJUST
Definition: unoprnms.hxx:173
virtual bool HasCursor() override
Definition: accpara.cxx:429
LINESTYLE_WAVE
#define UNO_NAME_PARA_BOTTOM_MARGIN
Definition: unoprnms.hxx:142
TextFrameIndex MapModelToView(MergedPara const &, SwTextNode const *pNode, sal_Int32 nIndex)
Definition: txtfrm.cxx:1182
bool operator()(sal_Int32 a, sal_Int32 b) const
Definition: accpara.cxx:1156
SwContentFrame * FindNextCnt(const bool _bInSameFootnote=false)
Definition: findfrm.cxx:190
int i
const sal_Char sServiceName[]
Definition: accpara.cxx:113
SwFieldIds
Definition: fldbas.hxx:38
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:205
SwLayoutFrame * GetUpper()
Definition: frame.hxx:656
float u
unsigned char sal_Bool
#define RES_CHRATR_BEGIN
Definition: hintids.hxx:68
const SfxItemPropertyMap & getPropertyMap() const
virtual void InvalidateCursorPos_() override
Definition: accpara.cxx:329
Object Value
bool IsOn() const
Definition: docufld.hxx:596
void GetSentenceBoundary(css::i18n::Boundary &rBound, sal_Int32 nPos)
#define UNO_NAME_CHAR_EMPHASIS
Definition: unoprnms.hxx:139
TextFrameIndex GetCoreViewPosition(sal_Int32 nPos) const
get the position in the core view string for a given (accessibility) position
virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleParent() override
Definition: acccontext.cxx:641
collect text portion data from the layout through SwPortionHandler interface
Definition: accportions.hxx:39
sal_Int32 GetCaretPos()
Definition: accpara.cxx:126
sal_uInt16 m_nItemId
Definition: authratr.hxx:29
virtual css::accessibility::TextSegment SAL_CALL getTextAtLineWithCaret() override
Definition: accpara.cxx:3202
T static_txtattr_cast(S *s)
Definition: txatbase.hxx:237
ring_container GetRingContainer()
Definition: ring.hxx:240
void StartListening(SfxBroadcaster &rBroadcaster, DuplicateHandling eDuplicateHanding=DuplicateHandling::Unexpected)
bool IsOnlineSpell() const
Definition: viewopt.hxx:332
const SwRangeRedline * GetRedlineAtIndex()
Definition: accpara.cxx:531
IndexCompare(const PropertyValue *pVals)
Definition: accpara.cxx:1155
bool GetTextBoundary(css::i18n::Boundary &rBound, const OUString &rText, sal_Int32 nPos, sal_Int16 aTextType)
Definition: accpara.cxx:652
#define RES_PARATR_LIST_BEGIN
Definition: hintids.hxx:184
void GrabFocus()
SwRect GetBounds(const SwAccessibleMap &rAccMap, const SwFrame *pFrame=nullptr)
Definition: accframe.cxx:328
#define UNO_NAME_PARA_FIRST_LINE_INDENT
Definition: unoprnms.hxx:60
#define RES_TXTATR_INETFMT
Definition: hintids.hxx:141
bool GetLineBoundary(css::i18n::Boundary &rBound, const OUString &rText, sal_Int32 nPos)
Definition: accpara.cxx:595
virtual sal_uInt16 GetSubType() const
Definition: fldbas.cxx:292
virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getDefaultAttributes(const css::uno::Sequence< OUString > &aRequestedAttributes) override
Definition: accpara.cxx:1596
std::pair< SwTextNode *, sal_Int32 > MapViewToModel(TextFrameIndex nIndex) const
map position in potentially merged text frame to SwPosition
Definition: txtfrm.cxx:1230
const SwPosition * Start() const
Definition: pam.hxx:212
SwFieldType * GetTyp() const
Definition: fldbas.hxx:382
Color m_nColor
Definition: authratr.hxx:31
virtual css::uno::Sequence< sal_Int8 > SAL_CALL getImplementationId() override
Definition: accpara.cxx:1007
std::vector< SfxItemPropertyNamedEntry > PropertyEntryVector_t
#define RES_LR_SPACE
Definition: hintids.hxx:196
OUString GetFieldTypeNameAtIndex(sal_Int32 nIndex)
Definition: accpara.cxx:1162
#define UNO_NAME_CHAR_UNDERLINE
Definition: unoprnms.hxx:108
#define UNO_NAME_CHAR_BACK_COLOR
Definition: unoprnms.hxx:134
virtual const SwRangeRedline * GetRedline(const SwPosition &rPos, SwRedlineTable::size_type *pFndPos) const =0
void StartAction()
Definition: crsrsh.cxx:211
static void OrderRange(sal_Int32 &nBegin, sal_Int32 &nEnd)
Definition: accpara.hxx:132
sw::MergedAttrIter m_Iter
Definition: accpara.cxx:2707
#define UNO_NAME_CHAR_ESCAPEMENT
Definition: unoprnms.hxx:111
virtual sal_Int32 SAL_CALL getCaretPosition() override
Definition: accpara.cxx:1014
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:193
sal_Int32 GetRealHeadingLevel()
Definition: accpara.cxx:3449
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &aType) override
Definition: accpara.cxx:931
#define UNO_NAME_CHAR_CONTOURED
Definition: unoprnms.hxx:241
virtual sal_Int32 SAL_CALL getBackground() override
Definition: acccontext.cxx:962
virtual sal_Int32 SAL_CALL getIndexAtPoint(const css::awt::Point &aPoint) override
Definition: accpara.cxx:2111
IDocumentRedlineAccess const & getIDocumentRedlineAccess() const
Definition: doc.cxx:367
#define RES_TXTATR_FIELD
Definition: hintids.hxx:150
virtual OUString SAL_CALL getSelectedText() override
Definition: accpara.cxx:2188
virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes() override
Definition: accpara.cxx:993
virtual sal_Int32 SAL_CALL getSelectedAccessibleChildCount() override
Definition: accpara.cxx:2678
void EndListeningAll()
PropertyEntryVector_t getPropertyEntries() const
virtual css::accessibility::TextSegment SAL_CALL getTextAtLineNumber(sal_Int32 nLineNo) override
Definition: accpara.cxx:3178
tools::Rectangle SVRect() const
Definition: swrect.hxx:282
virtual void SAL_CALL deselectAccessibleChild(sal_Int32 nChildIndex) override
Definition: accpara.cxx:2694
general base class for all free-flowing frames
Definition: flyfrm.hxx:60
TextFrameIndex endIdx() const
Definition: accpara.cxx:2716
Color GetRetoucheColor() const
Definition: viewimp.cxx:252
virtual OUString GetName() const
Only in derived classes.
Definition: fldbas.cxx:145
#define SAL_WARN_IF(condition, area, stream)
#define RES_PARATR_LIST_LEVEL
Definition: hintids.hxx:186
bool IsRefToHeadingCrossRefBookmark() const
Definition: reffld.cxx:383
static OUString GetTypeStr(sal_uInt16 nTypeId)
Definition: fldbas.cxx:128
bool GetSelection(sal_Int32 &nStart, sal_Int32 &nEnd)
Definition: accpara.hxx:103
#define UNO_NAME_CHAR_WEIGHT
Definition: unoprnms.hxx:86
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:426
sal_Int32 GetFieldIndex(sal_Int32 nPos)
css::uno::Sequence< typename M::mapped_type > mapValuesToSequence(M const &map)
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
Definition: accpara.cxx:3275
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
std::unordered_map< OUString, css::beans::PropertyValue > tAccParaPropValMap
Definition: accpara.hxx:50
#define RES_TXTATR_ANNOTATION
Definition: hintids.hxx:153
sal_Int32 GetLineNo(const sal_Int32 nPos) const
TextFrameIndex MapModelToView(SwTextNode const *pNode, sal_Int32 nIndex) const
Definition: txtfrm.cxx:1251
virtual void GetStates(::utl::AccessibleStateSetHelper &rStateSet)
Definition: acccontext.cxx:478
virtual sal_Bool SAL_CALL supportsService(const OUString &sServiceName) override
Return whether the specified service is supported by this class.
Definition: accpara.cxx:877
bool InWrongWord(sal_Int32 &rChk, sal_Int32 &rLn) const
If a word is incorrectly selected, this method returns begin and length of it.
Definition: wrong.cxx:102
bool IsInside(const Point &rPOINT) const
Definition: swrect.cxx:107
const SwPosition * End() const
Definition: pam.hxx:217
void _correctValues(const sal_Int32 nIndex, std::vector< css::beans::PropertyValue > &rValues)
Definition: accpara.cxx:1816
bool IsRightToLeft() const
Definition: frame.hxx:963
void selectAccessibleChild(sal_Int32 nChildIndex)
virtual sal_Int32 SAL_CALL addSelection(sal_Int32 selectionIndex, sal_Int32 startOffset, sal_Int32 endOffset) override
Definition: accpara.cxx:3035
virtual OUString SAL_CALL getAccessibleDescription() override
Definition: accpara.cxx:707
const SwRect & GetCharRect() const
Definition: crsrsh.hxx:519
RedlineType GetType(sal_uInt16 nPos=0) const
Definition: docredln.cxx:1739
SwTextFrame const & m_rFrame
Definition: accpara.cxx:2706
bool GetGlyphBoundary(css::i18n::Boundary &rBound, const OUString &rText, sal_Int32 nPos)
Definition: accpara.cxx:624
virtual sal_Bool SAL_CALL setCaretPosition(sal_Int32 nIndex) override
Definition: accpara.cxx:1035
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:1167
#define UNO_NAME_CHAR_STRIKEOUT
Definition: unoprnms.hxx:114
virtual Point LogicToPixel(const Point &rPoint) const override
Definition: accmap.cxx:3079
SwUnoPropertyMapProvider aSwMapProvider
Definition: unomap1.cxx:131
#define RES_PARATR_ADJUST
Definition: hintids.hxx:162
virtual sal_Int32 SAL_CALL getLineNumberAtIndex(sal_Int32 nIndex) override
Definition: accpara.cxx:3162
SwSpecialPos * m_pSpecialPos
for positions inside fields
Definition: crstate.hxx:136
css::uno::Reference< css::accessibility::XAccessible > GetContext(const SwFrame *pFrame, bool bCreate=true)
Definition: accmap.cxx:1848
SwWrongList * GetWrong()
Definition: txtedt.cxx:2167
constexpr::Color COL_WHITE(0xFF, 0xFF, 0xFF)
double getLength(const B2DPolygon &rCandidate)
css::uno::Sequence< css::uno::Type > SAL_CALL getTypes()
void GetLastLineBoundary(css::i18n::Boundary &rBound) const
SwAccessibleMap * GetMap()
Definition: acccontext.hxx:112
long Left() const
#define RES_TXTATR_REFMARK
Definition: hintids.hxx:136
bool m_bPosMatchesBounds
GetCursorOfst should not return the next position if screen position is inside second have of bound r...
Definition: crstate.hxx:152
OUString GetFormatStr(sal_uInt16 nTypeId, sal_uInt32 nFormatId) const
Definition: fldmgr.cxx:720
void deselectAccessibleChild(sal_Int32 nChildIndex)
css::uno::Reference< css::i18n::XBreakIterator > const & GetBreakIter()
Definition: breakit.hxx:62
#define UNO_NAME_CHAR_HEIGHT
Definition: unoprnms.hxx:87
def text(shape, st)
virtual sal_Bool SAL_CALL replaceText(sal_Int32 nStartIndex, sal_Int32 nEndIndex, const OUString &sReplacement) override
Definition: accpara.cxx:2540
bool IsVertical() const
Definition: frame.hxx:949
#define UNO_NAME_TABSTOPS
Definition: unoprnms.hxx:322
virtual css::uno::Reference< css::accessibility::XAccessibleHyperlink > SAL_CALL getHyperLink(sal_Int32 nLinkIndex) override
Definition: accpara.cxx:2778
SwDoc & GetDoc()
Definition: txtfrm.hxx:448
std::unique_ptr< SwAccessibleHyperTextData > m_pHyperTextData
Definition: accpara.hxx:74
mutable::osl::Mutex m_Mutex
Definition: acccontext.hxx:64
constexpr::Color COL_BLUE(0x00, 0x00, 0x80)
virtual bool GetCursorOfst(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
In nOffset returns the offset of the char within the set text buffer, which is closest to the positio...
Definition: frmcrsr.cxx:662
SwContentFrame * FindPrevCnt()
Definition: findfrm.cxx:174
void SetCursorContext(const ::rtl::Reference< SwAccessibleContext > &rCursorContext)
Definition: accmap.cxx:2792
const SfxPoolItem * Execute(sal_uInt16 nSlot, SfxCallMode nCall=SfxCallMode::SLOT, const SfxPoolItem **pArgs=nullptr, sal_uInt16 nModi=0, const SfxPoolItem **pInternalArgs=nullptr)
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:455
virtual OUString SAL_CALL getTextRange(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
Definition: accpara.cxx:2266
static css::uno::Reference< css::text::XTextRange > CreateXTextRange(SwDoc &rDoc, const SwPosition &rPos, const SwPosition *const pMark)
Definition: unoobj2.cxx:1112
sal_Int32 const nLength
#define UNO_NAME_NUMBERING_LEVEL
Definition: unoprnms.hxx:150
#define UNO_NAME_CHAR_COLOR
Definition: unoprnms.hxx:125
virtual ~SwAccessibleParagraph() override
Definition: accpara.cxx:419
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:3870
bool GetCharBoundary(css::i18n::Boundary &rBound, sal_Int32 nPos)
Definition: accpara.cxx:546
bool HasFocus() const
sal_Int32 nPos
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
void AddState(sal_Int16 aState)
virtual sal_Int32 SAL_CALL getSelectionStart() override
Definition: accpara.cxx:2201
#define RES_FRMATR_BEGIN
Definition: hintids.hxx:192
SwPosition MapViewToModelPos(TextFrameIndex nIndex) const
Definition: txtfrm.cxx:1245
const AuthorCharAttr & GetDeletedAuthorAttr() const
Definition: modcfg.hxx:247
#define RES_TXTATR_INPUTFIELD
Definition: hintids.hxx:145
bool IsIndexInFootnode(sal_Int32 nIndex)
SwFieldIds Which() const
Definition: fldbas.hxx:265
virtual sal_Bool SAL_CALL copyText(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
Definition: accpara.cxx:2486
virtual void InvalidateContent_(bool bVisibleDataFired) override
Definition: accpara.cxx:247
void SetName(const OUString &rName)
Definition: acccontext.hxx:99
bool IsFrameSelected() const
Definition: feshview.cxx:1175
virtual css::uno::Sequence< css::accessibility::TextSegment > SAL_CALL getTextMarkupAtIndex(sal_Int32 nCharIndex, sal_Int32 nTextMarkupType) override
Definition: accpara.cxx:3127
virtual sal_Bool SAL_CALL deleteText(sal_Int32 nStartIndex, sal_Int32 nEndIndex) override
Definition: accpara.cxx:2530
virtual sal_Int32 SAL_CALL getCharacterCount() override
Definition: accpara.cxx:2102
virtual sal_Bool SAL_CALL removeSelection(sal_Int32 selectionIndex) override
Definition: accpara.cxx:2972
const SfxItemPropertyMapEntry * GetPropertyMapEntries(sal_uInt16 PropertyId)
Definition: unomap.cxx:116
const SwTextAttr * next(SwTextNode const **ppNode=nullptr)
Definition: accpara.cxx:2728
bool GetSentenceBoundary(css::i18n::Boundary &rBound, const OUString &rText, sal_Int32 nPos)
Definition: accpara.cxx:582
#define RES_PARATR_END
Definition: hintids.hxx:180
#define RES_PARATR_LINESPACING
Definition: hintids.hxx:161
static uno::Sequence< OUString > const & getSupplementalAttributeNames()
Definition: accpara.cxx:911
virtual void SAL_CALL clearAccessibleSelection() override
Definition: accpara.cxx:2666
bool IsInFrontOfLabel() const
Definition: pam.hxx:171
virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex(sal_Int32 nIndex, sal_Int16 aTextType) override
Definition: accpara.cxx:2282
const sal_Char sImplementationName[]
Definition: accpara.cxx:114
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:7161
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo