LibreOffice Module sw (master)  1
crsrsh.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 <config_wasm_strip.h>
21 
22 #include <com/sun/star/text/XTextRange.hpp>
23 
24 #include <hintids.hxx>
25 #include <svx/srchdlg.hxx>
26 #include <sfx2/viewsh.hxx>
27 #include <SwSmartTagMgr.hxx>
28 #include <doc.hxx>
29 #include <rootfrm.hxx>
30 #include <pagefrm.hxx>
31 #include <cntfrm.hxx>
32 #include <viewimp.hxx>
33 #include <pam.hxx>
34 #include <swselectionlist.hxx>
35 #include "BlockCursor.hxx"
36 #include <ndtxt.hxx>
37 #include <flyfrm.hxx>
38 #include <dview.hxx>
39 #include <viewopt.hxx>
40 #include <crsrsh.hxx>
41 #include <tabfrm.hxx>
42 #include <txtfrm.hxx>
43 #include <sectfrm.hxx>
44 #include <swtable.hxx>
45 #include "callnk.hxx"
46 #include <viscrs.hxx>
47 #include <section.hxx>
48 #include <docsh.hxx>
49 #include <scriptinfo.hxx>
50 #include <globdoc.hxx>
51 #include <pamtyp.hxx>
52 #include <mdiexp.hxx>
53 #include <fmteiro.hxx>
54 #include <wrong.hxx>
55 #include <unotextrange.hxx>
56 #include <vcl/svapp.hxx>
57 #include <vcl/settings.hxx>
58 #include <IGrammarContact.hxx>
59 #include <comphelper/flagguard.hxx>
60 #include <strings.hrc>
62 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
63 #include <comphelper/lok.hxx>
64 #include <comphelper/sequence.hxx>
65 #include <sfx2/lokhelper.hxx>
66 #include <editeng/editview.hxx>
67 #include <editeng/frmdir.hxx>
68 #include <sal/log.hxx>
69 #include <PostItMgr.hxx>
71 #include <vcl/uitest/logger.hxx>
73 #include <tabcol.hxx>
74 #include <wrtsh.hxx>
75 #include <undobj.hxx>
76 #include <view.hxx>
77 #include <hints.hxx>
78 #include <tools/json_writer.hxx>
79 
80 using namespace com::sun::star;
81 using namespace util;
82 
87 static void CheckRange( SwCursor* pCurrentCursor )
88 {
89  const SwPosition *pStt = pCurrentCursor->Start(),
90  *pEnd = pCurrentCursor->End();
91 
92  SwPaM *pTmpDel = nullptr,
93  *pTmp = pCurrentCursor->GetNext();
94 
95  // Search the complete ring
96  while( pTmp != pCurrentCursor )
97  {
98  const SwPosition *pTmpStt = pTmp->Start(),
99  *pTmpEnd = pTmp->End();
100  if( *pStt <= *pTmpStt )
101  {
102  if( *pEnd > *pTmpStt ||
103  ( *pEnd == *pTmpStt && *pEnd == *pTmpEnd ))
104  pTmpDel = pTmp;
105  }
106  else
107  if( *pStt < *pTmpEnd )
108  pTmpDel = pTmp;
109 
110  // If Point or Mark is within the Cursor range, we need to remove the old
111  // range. Take note that Point does not belong to the range anymore.
112  pTmp = pTmp->GetNext();
113  delete pTmpDel; // Remove old range
114  pTmpDel = nullptr;
115  }
116 }
117 
118 // SwCursorShell
119 
125 {
126  // don't create new Cursor with active table Selection
127  assert(!IsTableMode());
128 
129  // ensure that m_pCurrentCursor is valid; if it's invalid it would be
130  // copied to pNew and then pNew would be deleted in UpdateCursor() below
131  ClearUpCursors();
132 
133  // New cursor as copy of current one. Add to the ring.
134  // Links point to previously created one, ie forward.
135  SwShellCursor* pNew = new SwShellCursor( *m_pCurrentCursor );
136 
137  // Hide PaM logically, to avoid undoing the inverting from
138  // copied PaM (#i75172#)
139  pNew->swapContent(*m_pCurrentCursor);
140 
141  m_pCurrentCursor->DeleteMark();
142 
143  UpdateCursor( SwCursorShell::SCROLLWIN );
144  return pNew;
145 }
146 
153 {
154  // don't delete Cursor with active table Selection
155  assert(!IsTableMode());
156 
157  // Is there a next one? Don't do anything if not.
158  if(!m_pCurrentCursor->IsMultiSelection())
159  return;
160 
161  SwCallLink aLk( *this ); // watch Cursor-Moves
162  SwCursor* pNextCursor = static_cast<SwCursor*>(m_pCurrentCursor->GetNext());
163  delete m_pCurrentCursor;
164  m_pCurrentCursor = dynamic_cast<SwShellCursor*>(pNextCursor);
165  UpdateCursor();
166 }
167 
174 {
175  if (HasSelection())
176  {
177  (void) CreateCursor(); // n.b. returns old cursor
178  }
179  return *GetCursor();
180 }
181 
187 {
188  return *GetCursor();
189 }
190 
195 SwCursor* SwCursorShell::GetCursor( bool bMakeTableCursor ) const
196 {
197  if( m_pTableCursor )
198  {
199  if( bMakeTableCursor && m_pTableCursor->IsCursorMovedUpdate() )
200  {
201  //don't re-create 'parked' cursors
202  if( m_pTableCursor->GetPoint()->nNode.GetIndex() &&
203  m_pTableCursor->GetMark()->nNode.GetIndex() )
204  {
205  const SwContentNode* pCNd = m_pTableCursor->GetContentNode();
206  if( pCNd && pCNd->getLayoutFrame( GetLayout() ) )
207  {
208  pCNd = m_pTableCursor->GetContentNode(false);
209  if( pCNd && pCNd->getLayoutFrame( GetLayout() ) )
210  {
211  SwShellTableCursor* pTC = m_pTableCursor;
212  GetLayout()->MakeTableCursors( *pTC );
213  }
214  }
215  }
216  }
217 
218  if( m_pTableCursor->IsChgd() )
219  {
220  const_cast<SwCursorShell*>(this)->m_pCurrentCursor =
221  dynamic_cast<SwShellCursor*>(m_pTableCursor->MakeBoxSels( m_pCurrentCursor ));
222  }
223  }
224  return m_pCurrentCursor;
225 }
226 
228 {
229  if( !ActionPend() )
230  {
231  // save for update of the ribbon bar
232  const SwNode& rNd = m_pCurrentCursor->GetPoint()->nNode.GetNode();
233  m_nCurrentNode = rNd.GetIndex();
234  m_nCurrentContent = m_pCurrentCursor->GetPoint()->nContent.GetIndex();
235  m_nCurrentNdTyp = rNd.GetNodeType();
236  if( rNd.IsTextNode() )
237  m_nLeftFramePos = SwCallLink::getLayoutFrame( GetLayout(), *rNd.GetTextNode(), m_nCurrentContent, true );
238  else
239  m_nLeftFramePos = 0;
240  }
241  SwViewShell::StartAction(); // to the SwViewShell
242 }
243 
244 void SwCursorShell::EndAction( const bool bIdleEnd )
245 {
246  comphelper::FlagRestorationGuard g(mbSelectAll, StartsWithTable() && ExtendedSelectedAll());
247  bool bVis = m_bSVCursorVis;
248 
249  // Idle-formatting?
250  if( bIdleEnd && Imp()->HasPaintRegion() )
251  {
252  m_pCurrentCursor->Hide();
253  }
254 
255  // Update all invalid numberings before the last action
256  if( 1 == mnStartAction )
257  GetDoc()->UpdateNumRule();
258 
259  // #i76923#: Don't show the cursor in the SwViewShell::EndAction() - call.
260  // Only the UpdateCursor shows the cursor.
261  bool bSavSVCursorVis = m_bSVCursorVis;
262  m_bSVCursorVis = false;
263 
264  SwViewShell::EndAction( bIdleEnd ); // have SwViewShell go first
265 
266  m_bSVCursorVis = bSavSVCursorVis;
267 
268  if( ActionPend() )
269  {
270  if( bVis ) // display SV-Cursor again
271  m_pVisibleCursor->Show();
272 
273  return;
274  }
275 
276  sal_uInt16 eFlags = SwCursorShell::CHKRANGE;
277  if ( !bIdleEnd )
278  eFlags |= SwCursorShell::SCROLLWIN;
279 
280  UpdateCursor( eFlags, bIdleEnd ); // Show Cursor changes
281 
282  {
283  SwCallLink aLk( *this ); // Watch cursor moves,
284  aLk.m_nNode = m_nCurrentNode; // possibly call the link
285  aLk.m_nNodeType = m_nCurrentNdTyp;
286  aLk.m_nContent = m_nCurrentContent;
287  aLk.m_nLeftFramePos = m_nLeftFramePos;
288 
289  if( !m_nCursorMove ||
290  ( 1 == m_nCursorMove && m_bInCMvVisportChgd ) )
291  // display Cursor & Selections again
292  ShowCursors( m_bSVCursorVis );
293  }
294  // call ChgCall if there is still one
295  if( m_bCallChgLnk && m_bChgCallFlag && m_aChgLnk.IsSet() )
296  {
297  m_aChgLnk.Call(nullptr);
298  m_bChgCallFlag = false; // reset flag
299  }
300 }
301 
303 {
304 #ifdef DBG_UTIL
305  OSL_ENSURE( m_nCursorMove < USHRT_MAX, "Too many nested CursorMoves." );
306 #endif
307  ++m_nCursorMove;
308  StartAction();
309 }
310 
311 void SwCursorShell::EndCursorMove( const bool bIdleEnd )
312 {
313 #ifdef DBG_UTIL
314  OSL_ENSURE( m_nCursorMove, "EndCursorMove() without SttCursorMove()." );
315 #endif
316  EndAction( bIdleEnd );
317  --m_nCursorMove;
318 #ifdef DBG_UTIL
319  if( !m_nCursorMove )
320  m_bInCMvVisportChgd = false;
321 #endif
322 }
323 
324 bool SwCursorShell::LeftRight( bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode,
325  bool bVisualAllowed )
326 {
327  if( IsTableMode() )
328  return bLeft ? GoPrevCell() : GoNextCell();
329 
330  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
331  bool bRet = false;
332 
333  // #i27615# Handle cursor in front of label.
334  const SwTextNode* pTextNd = nullptr;
335 
336  if( m_pBlockCursor )
337  m_pBlockCursor->clearPoints();
338 
339  // 1. CASE: Cursor is in front of label. A move to the right
340  // will simply reset the bInFrontOfLabel flag:
341  SwShellCursor* pShellCursor = getShellCursor( true );
342  if ( !bLeft && pShellCursor->IsInFrontOfLabel() )
343  {
344  SetInFrontOfLabel( false );
345  bRet = true;
346  }
347  // 2. CASE: Cursor is at beginning of numbered paragraph. A move
348  // to the left will simply set the bInFrontOfLabel flag:
349  else if (bLeft
350  && pShellCursor->GetPoint()->nNode.GetNode().IsTextNode()
351  && static_cast<SwTextFrame const*>(
352  pShellCursor->GetPoint()->nNode.GetNode().GetTextNode()->getLayoutFrame(GetLayout())
353  )->MapModelToViewPos(*pShellCursor->GetPoint()) == TextFrameIndex(0)
354  && !pShellCursor->IsInFrontOfLabel()
355  && !pShellCursor->HasMark()
356  && nullptr != (pTextNd = sw::GetParaPropsNode(*GetLayout(), pShellCursor->GetPoint()->nNode))
357  && pTextNd->HasVisibleNumberingOrBullet())
358  {
359  SetInFrontOfLabel( true );
360  bRet = true;
361  }
362  // 3. CASE: Regular cursor move. Reset the bInFrontOfLabel flag:
363  else
364  {
365  const bool bSkipHidden = !GetViewOptions()->IsShowHiddenChar();
366  // #i107447#
367  // To avoid loop the reset of <bInFrontOfLabel> flag is no longer
368  // reflected in the return value <bRet>.
369  const bool bResetOfInFrontOfLabel = SetInFrontOfLabel( false );
370  bRet = pShellCursor->LeftRight( bLeft, nCnt, nMode, bVisualAllowed,
371  bSkipHidden, !IsOverwriteCursor(),
372  GetLayout(),
373  GetViewOptions()->IsFieldName());
374  if ( !bRet && bLeft && bResetOfInFrontOfLabel )
375  {
376  // undo reset of <bInFrontOfLabel> flag
377  SetInFrontOfLabel( true );
378  }
379  }
380 
381  if( bRet )
382  {
383  UpdateCursor();
384  }
385 
386  return bRet;
387 }
388 
389 void SwCursorShell::MarkListLevel( const OUString& sListId,
390  const int nListLevel )
391 {
392  if (sListId == m_sMarkedListId && nListLevel == m_nMarkedListLevel)
393  return;
394 
395  if ( !m_sMarkedListId.isEmpty() )
396  mxDoc->MarkListLevel( m_sMarkedListId, m_nMarkedListLevel, false );
397 
398  if ( !sListId.isEmpty() )
399  {
400  mxDoc->MarkListLevel( sListId, nListLevel, true );
401  }
402 
403  m_sMarkedListId = sListId;
404  m_nMarkedListLevel = nListLevel;
405 }
406 
408 {
409  SwTextNode const*const pTextNd = sw::GetParaPropsNode(*GetLayout(),
410  GetCursor_()->GetPoint()->nNode);
411 
412  if ( !pTextNd )
413  return;
414 
415  if (!pTextNd->IsNumbered(GetLayout()))
416  {
417  m_pCurrentCursor->SetInFrontOfLabel_( false );
418  MarkListLevel( OUString(), 0 );
419  }
420  else if ( m_pCurrentCursor->IsInFrontOfLabel() )
421  {
422  if ( pTextNd->IsInList() )
423  {
424  assert(pTextNd->GetActualListLevel() >= 0 &&
425  pTextNd->GetActualListLevel() < MAXLEVEL);
426  MarkListLevel( pTextNd->GetListId(),
427  pTextNd->GetActualListLevel() );
428  }
429  }
430  else
431  {
432  MarkListLevel( OUString(), 0 );
433  }
434 }
435 
436 void SwCursorShell::FirePageChangeEvent(sal_uInt16 nOldPage, sal_uInt16 nNewPage)
437 {
438 #ifdef ACCESSIBLE_LAYOUT
439  if( Imp()->IsAccessible() )
440  Imp()->FirePageChangeEvent( nOldPage, nNewPage );
441 #else
442  (void)nOldPage;
443  (void)nNewPage;
444 #endif
445 }
446 
447 void SwCursorShell::FireColumnChangeEvent(sal_uInt16 nOldColumn, sal_uInt16 nNewColumn)
448 {
449 #ifdef ACCESSIBLE_LAYOUT
450  if( Imp()->IsAccessible() )
451  Imp()->FireColumnChangeEvent( nOldColumn, nNewColumn);
452 #else
453  (void)nOldColumn;
454  (void)nNewColumn;
455 #endif
456 }
457 
458 void SwCursorShell::FireSectionChangeEvent(sal_uInt16 nOldSection, sal_uInt16 nNewSection)
459 {
460 #ifdef ACCESSIBLE_LAYOUT
461  if( Imp()->IsAccessible() )
462  Imp()->FireSectionChangeEvent( nOldSection, nNewSection );
463 #else
464  (void)nOldSection;
465  (void)nNewSection;
466 #endif
467 }
468 
470 {
471  SwFrame* pCurrFrame = GetCurrFrame(false);
472 
473  if (pCurrFrame == nullptr)
474  {
475  return false;
476  }
477 
478  SwFrame* pCurrCol=pCurrFrame->FindColFrame();
479 
480  while(pCurrCol== nullptr && pCurrFrame!=nullptr )
481  {
482  SwLayoutFrame* pParent = pCurrFrame->GetUpper();
483  if(pParent!=nullptr)
484  {
485  pCurrCol=static_cast<SwFrame*>(pParent)->FindColFrame();
486  pCurrFrame = pParent;
487  }
488  else
489  {
490  break;
491  }
492  }
493 
494  if(m_oldColFrame == pCurrCol)
495  return false;
496  else
497  {
498  m_oldColFrame = pCurrCol;
499  return true;
500  }
501 }
502 
503 bool SwCursorShell::UpDown( bool bUp, sal_uInt16 nCnt )
504 {
505  CurrShell aCurr( this );
506  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
507 
508  bool bTableMode = IsTableMode();
509  SwShellCursor* pTmpCursor = getShellCursor( true );
510 
511  bool bRet = pTmpCursor->UpDown( bUp, nCnt );
512  // #i40019# UpDown should always reset the bInFrontOfLabel flag:
513  bRet |= SetInFrontOfLabel(false);
514 
515  if( m_pBlockCursor )
516  m_pBlockCursor->clearPoints();
517 
518  if( bRet )
519  {
520  m_eMvState = CursorMoveState::UpDown; // status for Cursor travelling - GetModelPositionForViewPoint
521  if( !ActionPend() )
522  {
523  CursorFlag eUpdateMode = SwCursorShell::SCROLLWIN;
524  if( !bTableMode )
525  eUpdateMode = static_cast<CursorFlag>(eUpdateMode
527  UpdateCursor( o3tl::narrowing<sal_uInt16>(eUpdateMode) );
528  }
529  }
530  return bRet;
531 }
532 
533 bool SwCursorShell::LRMargin( bool bLeft, bool bAPI)
534 {
535  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
536  CurrShell aCurr( this );
537  m_eMvState = CursorMoveState::LeftMargin; // status for Cursor travelling - GetModelPositionForViewPoint
538 
539  const bool bTableMode = IsTableMode();
540  SwShellCursor* pTmpCursor = getShellCursor( true );
541 
542  if( m_pBlockCursor )
543  m_pBlockCursor->clearPoints();
544 
545  const bool bWasAtLM = GetCursor_()->IsAtLeftRightMargin(*GetLayout(), true, bAPI);
546 
547  bool bRet = pTmpCursor->LeftRightMargin(*GetLayout(), bLeft, bAPI);
548 
549  if ( bLeft && !bTableMode && bRet && bWasAtLM && !GetCursor_()->HasMark() )
550  {
551  const SwTextNode * pTextNd = GetCursor_()->GetNode().GetTextNode();
552  assert(sw::GetParaPropsNode(*GetLayout(), GetCursor_()->GetPoint()->nNode) == pTextNd);
553  if ( pTextNd && pTextNd->HasVisibleNumberingOrBullet() )
554  SetInFrontOfLabel( true );
555  }
556  else if ( !bLeft )
557  {
558  bRet = SetInFrontOfLabel( false ) || bRet;
559  }
560 
561  if( bRet )
562  {
563  UpdateCursor();
564  }
565  return bRet;
566 }
567 
568 bool SwCursorShell::IsAtLRMargin( bool bLeft, bool bAPI ) const
569 {
570  const SwShellCursor* pTmpCursor = getShellCursor( true );
571  return pTmpCursor->IsAtLeftRightMargin(*GetLayout(), bLeft, bAPI);
572 }
573 
574 bool SwCursorShell::SttEndDoc( bool bStt )
575 {
576  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
577 
578  SwShellCursor* pTmpCursor = m_pBlockCursor ? &m_pBlockCursor->getShellCursor() : m_pCurrentCursor;
579  bool bRet = pTmpCursor->SttEndDoc( bStt );
580  if( bRet )
581  {
582  if( bStt )
583  pTmpCursor->GetPtPos().setY( 0 ); // set to 0 explicitly (table header)
584  if( m_pBlockCursor )
585  {
586  m_pBlockCursor->clearPoints();
587  RefreshBlockCursor();
588  }
589 
591  }
592  return bRet;
593 }
594 
595 void SwCursorShell::ExtendedSelectAll(bool bFootnotes)
596 {
597  SwNodes& rNodes = GetDoc()->GetNodes();
598  SwPosition* pPos = m_pCurrentCursor->GetPoint();
599  pPos->nNode = bFootnotes ? rNodes.GetEndOfPostIts() : rNodes.GetEndOfAutotext();
600  pPos->nContent.Assign( rNodes.GoNext( &pPos->nNode ), 0 );
601  pPos = m_pCurrentCursor->GetMark();
602  pPos->nNode = rNodes.GetEndOfContent();
603  SwContentNode* pCNd = SwNodes::GoPrevious( &pPos->nNode );
604  pPos->nContent.Assign( pCNd, pCNd ? pCNd->Len() : 0 );
605 }
606 
608 {
609  SwNodes& rNodes = GetDoc()->GetNodes();
610  SwNodeIndex nNode = rNodes.GetEndOfAutotext();
611  SwContentNode* pStart = rNodes.GoNext(&nNode);
612  if (!pStart)
613  return false;
614 
615  nNode = rNodes.GetEndOfContent();
616  SwContentNode* pEnd = SwNodes::GoPrevious(&nNode);
617  if (!pEnd)
618  return false;
619 
620  SwPosition aStart(*pStart, 0);
621  SwPosition aEnd(*pEnd, pEnd->Len());
622  SwShellCursor* pShellCursor = getShellCursor(false);
623  return aStart == *pShellCursor->Start() && aEnd == *pShellCursor->End();
624 }
625 
627 {
628  SwNodes& rNodes = GetDoc()->GetNodes();
629  SwNodeIndex nNode(rNodes.GetEndOfExtras());
630  SwContentNode* pContentNode = rNodes.GoNext(&nNode);
631  return pContentNode->FindTableNode();
632 }
633 
634 bool SwCursorShell::MovePage( SwWhichPage fnWhichPage, SwPosPage fnPosPage )
635 {
636  bool bRet = false;
637 
638  // never jump of section borders at selection
639  if( !m_pCurrentCursor->HasMark() || !m_pCurrentCursor->IsNoContent() )
640  {
641  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
642  CurrShell aCurr( this );
643 
644  SwCursorSaveState aSaveState( *m_pCurrentCursor );
645  Point& rPt = m_pCurrentCursor->GetPtPos();
646  std::pair<Point, bool> tmp(rPt, false);
647  SwContentFrame * pFrame = m_pCurrentCursor->GetContentNode()->
648  getLayoutFrame(GetLayout(), m_pCurrentCursor->GetPoint(), &tmp);
649  if( pFrame && GetFrameInPage( pFrame, fnWhichPage, fnPosPage, m_pCurrentCursor ) &&
650  !m_pCurrentCursor->IsSelOvr( SwCursorSelOverFlags::Toggle |
652  {
653  UpdateCursor();
654  bRet = true;
655  }
656  }
657  return bRet;
658 }
659 
661 {
662  SwContentNode *pCNode = pShellCursor->GetContentNode();
663  std::pair<Point, bool> tmp(pShellCursor->GetPtPos(), false);
664  SwContentFrame *const pFrame = pCNode
665  ? pCNode->getLayoutFrame(GetLayout(), pShellCursor->GetPoint(), &tmp)
666  : nullptr;
667  return !pFrame || (pFrame->IsTextFrame() && static_cast<SwTextFrame*>(pFrame)->IsHiddenNow());
668 }
669 
670 // sw_redlinehide: this should work for all cases: GoCurrPara, GoNextPara, GoPrevPara
671 static bool IsAtStartOrEndOfFrame(SwCursorShell const*const pShell,
672  SwShellCursor const*const pShellCursor, SwMoveFnCollection const& fnPosPara)
673 {
674  SwContentNode *const pCNode = pShellCursor->GetContentNode();
675  assert(pCNode); // surely can't have moved otherwise?
676  std::pair<Point, bool> tmp(pShellCursor->GetPtPos(), false);
677  SwContentFrame const*const pFrame = pCNode->getLayoutFrame(
678  pShell->GetLayout(), pShellCursor->GetPoint(), &tmp);
679  if (!pFrame || !pFrame->IsTextFrame())
680  {
681  return false;
682  }
683  SwTextFrame const& rTextFrame(static_cast<SwTextFrame const&>(*pFrame));
684  TextFrameIndex const ix(rTextFrame.MapModelToViewPos(*pShellCursor->GetPoint()));
685  if (&fnParaStart == &fnPosPara)
686  {
687  return ix == TextFrameIndex(0);
688  }
689  else
690  {
691  assert(&fnParaEnd == &fnPosPara);
692  return ix == TextFrameIndex(rTextFrame.GetText().getLength());
693  }
694 }
695 
696 bool SwCursorShell::MovePara(SwWhichPara fnWhichPara, SwMoveFnCollection const & fnPosPara )
697 {
698  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
699  SwShellCursor* pTmpCursor = getShellCursor( true );
700  bool bRet = pTmpCursor->MovePara( fnWhichPara, fnPosPara );
701  if( bRet )
702  {
703  //keep going until we get something visible, i.e. skip
704  //over hidden paragraphs, don't get stuck at the start
705  //which is what SwCursorShell::UpdateCursorPos will reset
706  //the position to if we pass it a position in an
707  //invisible hidden paragraph field
708  while (isInHiddenTextFrame(pTmpCursor)
709  || !IsAtStartOrEndOfFrame(this, pTmpCursor, fnPosPara))
710  {
711  if (!pTmpCursor->MovePara(fnWhichPara, fnPosPara))
712  break;
713  }
714 
715  UpdateCursor();
716  }
717  return bRet;
718 }
719 
721  SwMoveFnCollection const & fnPosSect)
722 {
723  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
724  SwCursor* pTmpCursor = getShellCursor( true );
725  bool bRet = pTmpCursor->MoveSection( fnWhichSect, fnPosSect );
726  if( bRet )
727  UpdateCursor();
728  return bRet;
729 
730 }
731 
732 // position cursor
733 
734 static SwFrame* lcl_IsInHeaderFooter( const SwNodeIndex& rIdx, Point& rPt )
735 {
736  SwFrame* pFrame = nullptr;
737  SwContentNode* pCNd = rIdx.GetNode().GetContentNode();
738  if( pCNd )
739  {
740  std::pair<Point, bool> tmp(rPt, false);
741  SwContentFrame *pContentFrame = pCNd->getLayoutFrame(
743  nullptr, &tmp);
744  pFrame = pContentFrame ? pContentFrame->GetUpper() : nullptr;
745  while( pFrame && !pFrame->IsHeaderFrame() && !pFrame->IsFooterFrame() )
746  pFrame = pFrame->IsFlyFrame() ? static_cast<SwFlyFrame*>(pFrame)->AnchorFrame()
747  : pFrame->GetUpper();
748  }
749  return pFrame;
750 }
751 
752 bool SwCursorShell::IsInHeaderFooter( bool* pbInHeader ) const
753 {
754  Point aPt;
755  SwFrame* pFrame = ::lcl_IsInHeaderFooter( m_pCurrentCursor->GetPoint()->nNode, aPt );
756  if( pFrame && pbInHeader )
757  *pbInHeader = pFrame->IsHeaderFrame();
758  return nullptr != pFrame;
759 }
760 
761 int SwCursorShell::SetCursor( const Point &rLPt, bool bOnlyText, bool bBlock )
762 {
763  CurrShell aCurr( this );
764 
765  SwShellCursor* pCursor = getShellCursor( bBlock );
766  SwPosition aPos( *pCursor->GetPoint() );
767  Point aPt( rLPt );
768  Point & rCurrentCursorPt = pCursor->GetPtPos();
769  SwCursorMoveState aTmpState( IsTableMode() ? CursorMoveState::TableSel :
771  aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
772 
773  SwTextNode const*const pTextNd = sw::GetParaPropsNode(*GetLayout(), pCursor->GetPoint()->nNode);
774 
775  if ( pTextNd && !IsTableMode() &&
776  // #i37515# No bInFrontOfLabel during selection
777  !pCursor->HasMark() &&
778  pTextNd->HasVisibleNumberingOrBullet() )
779  {
780  aTmpState.m_bInFrontOfLabel = true; // #i27615#
781  }
782  else
783  {
784  aTmpState.m_bInFrontOfLabel = false;
785  }
786 
787  int bRet = CRSR_POSOLD |
788  ( GetLayout()->GetModelPositionForViewPoint( &aPos, aPt, &aTmpState )
789  ? 0 : CRSR_POSCHG );
790 
791  const bool bOldInFrontOfLabel = IsInFrontOfLabel();
792  const bool bNewInFrontOfLabel = aTmpState.m_bInFrontOfLabel;
793 
794  pCursor->SetCursorBidiLevel( aTmpState.m_nCursorBidiLevel );
795 
796  if( CursorMoveState::RightMargin == aTmpState.m_eState )
797  m_eMvState = CursorMoveState::RightMargin;
798  // is the new position in header or footer?
799  SwFrame* pFrame = lcl_IsInHeaderFooter( aPos.nNode, aPt );
800  if( IsTableMode() && !pFrame && aPos.nNode.GetNode().StartOfSectionNode() ==
801  pCursor->GetPoint()->nNode.GetNode().StartOfSectionNode() )
802  // same table column and not in header/footer -> back
803  return bRet;
804 
805  if( m_pBlockCursor && bBlock )
806  {
807  m_pBlockCursor->setEndPoint( rLPt );
808  if( !pCursor->HasMark() )
809  m_pBlockCursor->setStartPoint( rLPt );
810  else if( !m_pBlockCursor->getStartPoint() )
811  m_pBlockCursor->setStartPoint( pCursor->GetMkPos() );
812  }
813  if( !pCursor->HasMark() )
814  {
815  // is at the same position and if in header/footer -> in the same
816  if( aPos == *pCursor->GetPoint() &&
817  bOldInFrontOfLabel == bNewInFrontOfLabel )
818  {
819  if( pFrame )
820  {
821  if( pFrame->getFrameArea().Contains( rCurrentCursorPt ))
822  return bRet;
823  }
824  else if( aPos.nNode.GetNode().IsContentNode() )
825  {
826  // in the same frame?
827  std::pair<Point, bool> tmp(m_aCharRect.Pos(), false);
828  SwFrame* pOld = static_cast<SwContentNode&>(aPos.nNode.GetNode()).getLayoutFrame(
829  GetLayout(), nullptr, &tmp);
830  tmp.first = aPt;
831  SwFrame* pNew = static_cast<SwContentNode&>(aPos.nNode.GetNode()).getLayoutFrame(
832  GetLayout(), nullptr, &tmp);
833  if( pNew == pOld )
834  return bRet;
835  }
836  }
837  }
838  else
839  {
840  // SSelection over not allowed sections or if in header/footer -> different
841  if( !CheckNodesRange( aPos.nNode, pCursor->GetMark()->nNode, true )
842  || ( pFrame && !pFrame->getFrameArea().Contains( pCursor->GetMkPos() ) ))
843  return bRet;
844 
845  // is at same position but not in header/footer
846  if( aPos == *pCursor->GetPoint() )
847  return bRet;
848  }
849 
850  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
851  SwCursorSaveState aSaveState( *pCursor );
852 
853  *pCursor->GetPoint() = aPos;
854  rCurrentCursorPt = aPt;
855 
856  // #i41424# Only update the marked number levels if necessary
857  // Force update of marked number levels if necessary.
858  if ( bNewInFrontOfLabel || bOldInFrontOfLabel )
859  m_pCurrentCursor->SetInFrontOfLabel_( !bNewInFrontOfLabel );
860  SetInFrontOfLabel( bNewInFrontOfLabel );
861 
862  if( !pCursor->IsSelOvr( SwCursorSelOverFlags::ChangePos ) )
863  {
865  bRet &= ~CRSR_POSOLD;
866  }
867  else if( bOnlyText && !m_pCurrentCursor->HasMark() )
868  {
869  if( FindValidContentNode( bOnlyText ) )
870  {
871  // position cursor in a valid content
872  if( aPos == *pCursor->GetPoint() )
873  bRet = CRSR_POSOLD;
874  else
875  {
876  UpdateCursor();
877  bRet &= ~CRSR_POSOLD;
878  }
879  }
880  else
881  {
882  // there is no valid content -> hide cursor
883  m_pVisibleCursor->Hide(); // always hide visible cursor
884  m_eMvState = CursorMoveState::NONE; // status for Cursor travelling
885  m_bAllProtect = true;
886  if( GetDoc()->GetDocShell() )
887  {
888  GetDoc()->GetDocShell()->SetReadOnlyUI();
889  CallChgLnk(); // notify UI
890  }
891  }
892  }
893  return bRet;
894 }
895 
897 {
898  assert(m_pTableCursor);
899  delete m_pTableCursor;
900  m_pTableCursor = nullptr;
901 }
902 
904 {
905  assert(m_pBlockCursor);
906  if( m_pBlockCursor && !HasSelection() )
907  {
908  SwPaM& rPam = m_pBlockCursor->getShellCursor();
909  m_pCurrentCursor->SetMark();
910  *m_pCurrentCursor->GetPoint() = *rPam.GetPoint();
911  if( rPam.HasMark() )
912  *m_pCurrentCursor->GetMark() = *rPam.GetMark();
913  else
914  m_pCurrentCursor->DeleteMark();
915  }
916  delete m_pBlockCursor;
917  m_pBlockCursor = nullptr;
918 }
919 
921 {
922  if( !m_pBlockCursor )
923  {
924  SwPosition aPos( *m_pCurrentCursor->GetPoint() );
925  m_pBlockCursor = new SwBlockCursor( *this, aPos );
926  SwShellCursor &rBlock = m_pBlockCursor->getShellCursor();
927  rBlock.GetPtPos() = m_pCurrentCursor->GetPtPos();
928  if( m_pCurrentCursor->HasMark() )
929  {
930  rBlock.SetMark();
931  *rBlock.GetMark() = *m_pCurrentCursor->GetMark();
932  rBlock.GetMkPos() = m_pCurrentCursor->GetMkPos();
933  }
934  }
935  m_pBlockCursor->clearPoints();
936  RefreshBlockCursor();
937 }
938 
940 {
941  // is there any GetMark?
942  if( m_pTableCursor )
943  {
944  std::vector<SwPaM*> vCursors;
945  for(auto& rCursor : m_pCurrentCursor->GetRingContainer())
946  if(&rCursor != m_pCurrentCursor)
947  vCursors.push_back(&rCursor);
948  for(auto pCursor : vCursors)
949  delete pCursor;
950  m_pTableCursor->DeleteMark();
951 
952  m_pCurrentCursor->DeleteMark();
953 
954  *m_pCurrentCursor->GetPoint() = *m_pTableCursor->GetPoint();
955  m_pCurrentCursor->GetPtPos() = m_pTableCursor->GetPtPos();
956  delete m_pTableCursor;
957  m_pTableCursor = nullptr;
958  m_pCurrentCursor->SwSelPaintRects::Show();
959  }
960  else
961  {
962  if( !m_pCurrentCursor->HasMark() )
963  return;
964  m_pCurrentCursor->DeleteMark();
965  if( !m_nCursorMove )
966  m_pCurrentCursor->SwSelPaintRects::Show();
967  }
968 }
969 
970 void SwCursorShell::NormalizePam(bool bPointFirst)
971 {
972  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
973  m_pCurrentCursor->Normalize(bPointFirst);
974 }
975 
977 {
978  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
979  m_pCurrentCursor->Exchange();
980 }
981 
982 //TODO: provide documentation
992  const Point & rPt,
993  bool bTstHit )
994 {
995  CurrShell aCurr( this );
996 
997  // check if the SPoint is in a table selection
998  if( m_pTableCursor )
999  return m_pTableCursor->Contains( rPt );
1000 
1001  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
1002  // search position <rPt> in document
1003  SwPosition aPtPos( *m_pCurrentCursor->GetPoint() );
1004  Point aPt( rPt );
1005 
1007  aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
1008  if ( !GetLayout()->GetModelPositionForViewPoint( &aPtPos, aPt, &aTmpState ) && bTstHit )
1009  return false;
1010 
1011  // search in all selections for this position
1012  SwShellCursor* pCmp = m_pCurrentCursor; // keep the pointer on cursor
1013  do
1014  {
1015  if (pCmp->HasMark() && *pCmp->Start() <= aPtPos && *pCmp->End() > aPtPos)
1016  return true; // return without update
1017  pCmp = pCmp->GetNext();
1018  } while (m_pCurrentCursor != pCmp);
1019  return false;
1020 }
1021 
1023 {
1024  // Does any exist for deletion?
1025  if( !m_pTableCursor && !m_pBlockCursor && !m_pCurrentCursor->IsMultiSelection() )
1026  return;
1027 
1028  while( m_pCurrentCursor->GetNext() != m_pCurrentCursor )
1029  delete m_pCurrentCursor->GetNext();
1030  m_pCurrentCursor->SetColumnSelection( false );
1031 
1032  if( m_pTableCursor )
1033  {
1034  // delete the ring of cursors
1035  m_pCurrentCursor->DeleteMark();
1036  *m_pCurrentCursor->GetPoint() = *m_pTableCursor->GetPoint();
1037  m_pCurrentCursor->GetPtPos() = m_pTableCursor->GetPtPos();
1038  delete m_pTableCursor;
1039  m_pTableCursor = nullptr;
1040  }
1041  else if( m_pBlockCursor )
1042  {
1043  // delete the ring of cursors
1044  m_pCurrentCursor->DeleteMark();
1045  SwShellCursor &rBlock = m_pBlockCursor->getShellCursor();
1046  *m_pCurrentCursor->GetPoint() = *rBlock.GetPoint();
1047  m_pCurrentCursor->GetPtPos() = rBlock.GetPtPos();
1048  rBlock.DeleteMark();
1049  m_pBlockCursor->clearPoints();
1050  }
1051  UpdateCursor( SwCursorShell::SCROLLWIN );
1052 }
1053 
1055 {
1056  int nRet = 0;
1057  const SwPosition *pFirst = nullptr, *pSecond = nullptr;
1058  const SwCursor *pCur = GetCursor(), *pStack = m_pStackCursor;
1059  // cursor on stack is needed if we compare against stack
1060  if( pStack )
1061  {
1062  pFirst = pStack->GetMark();
1063  pSecond = pCur->GetPoint();
1064  }
1065  if( !pFirst || !pSecond )
1066  nRet = INT_MAX;
1067  else if( *pFirst < *pSecond )
1068  nRet = -1;
1069  else if( *pFirst == *pSecond )
1070  nRet = 0;
1071  else
1072  nRet = 1;
1073  return nRet;
1074 }
1075 
1077 {
1078  if (m_pCurrentCursor->IsMultiSelection())
1079  {
1080  return false;
1081  }
1082  if (m_pCurrentCursor->GetPoint()->nNode == m_pCurrentCursor->GetMark()->nNode)
1083  {
1084  return true;
1085  }
1086  if (GetLayout()->HasMergedParas())
1087  {
1088  SwContentFrame const*const pFrame(GetCurrFrame(false));
1089  auto const n(m_pCurrentCursor->GetMark()->nNode.GetIndex());
1090  return FrameContainsNode(*pFrame, n);
1091  }
1092  return false;
1093 }
1094 
1096 {
1097  if (GetLayout()->HasMergedParas())
1098  {
1099  SwTextNode const*const pNode(m_pCurrentCursor->GetPoint()->nNode.GetNode().GetTextNode());
1100  if (pNode)
1101  {
1102  SwTextFrame const*const pFrame(static_cast<SwTextFrame*>(
1103  pNode->getLayoutFrame(GetLayout())));
1104  if (pFrame)
1105  {
1106  return pFrame->MapModelToViewPos(*m_pCurrentCursor->GetPoint())
1107  == TextFrameIndex(0);
1108  }
1109  }
1110  }
1111  return m_pCurrentCursor->GetPoint()->nContent == 0;
1112 }
1113 
1115 {
1116  if (GetLayout()->HasMergedParas())
1117  {
1118  SwTextNode const*const pNode(m_pCurrentCursor->GetPoint()->nNode.GetNode().GetTextNode());
1119  if (pNode)
1120  {
1121  SwTextFrame const*const pFrame(static_cast<SwTextFrame*>(
1122  pNode->getLayoutFrame(GetLayout())));
1123  if (pFrame)
1124  {
1125  return pFrame->MapModelToViewPos(*m_pCurrentCursor->GetPoint())
1126  == TextFrameIndex(pFrame->GetText().getLength());
1127  }
1128  }
1129  }
1130  return m_pCurrentCursor->GetPoint()->nContent == m_pCurrentCursor->GetContentNode()->Len();
1131 }
1132 
1134 {
1135  if (IsTableMode() || IsBlockMode() || !IsEndPara())
1136  {
1137  return false;
1138  }
1139  SwTableNode const*const pTableNode( IsCursorInTable() );
1140  if (!pTableNode)
1141  {
1142  return false;
1143  }
1144  SwEndNode const*const pEndTableNode(pTableNode->EndOfSectionNode());
1145  SwNodeIndex const lastNode(*pEndTableNode, -2);
1146  SAL_WARN_IF(!lastNode.GetNode().GetTextNode(), "sw.core",
1147  "text node expected");
1148  return (lastNode == m_pCurrentCursor->GetPoint()->nNode);
1149 }
1150 
1152 {
1153  SwStartNodeType aStartNodeType = m_pCurrentCursor->GetNode().StartOfSectionNode()->GetStartNodeType();
1154  return aStartNodeType == SwStartNodeType::SwFootnoteStartNode;
1155 }
1156 
1158 {
1159  return m_pCurrentCursor->IsInFrontOfLabel();
1160 }
1161 
1163 {
1164  if ( bNew != IsInFrontOfLabel() )
1165  {
1166  m_pCurrentCursor->SetInFrontOfLabel_( bNew );
1167  UpdateMarkedListLevel();
1168  return true;
1169  }
1170  return false;
1171 }
1172 
1173 namespace {
1174 
1175 void collectUIInformation(const OUString& aPage)
1176 {
1177  EventDescription aDescription;
1178  aDescription.aAction = "GOTO";
1179  aDescription.aParameters = {{"PAGE", aPage}};
1180  aDescription.aID = "writer_edit";
1181  aDescription.aKeyWord = "SwEditWinUIObject";
1182  aDescription.aParent = "MainWindow";
1183  UITestLogger::getInstance().logEvent(aDescription);
1184 }
1185 
1186 }
1187 
1188 bool SwCursorShell::GotoPage( sal_uInt16 nPage )
1189 {
1190  CurrShell aCurr( this );
1191  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
1192  SwCursorSaveState aSaveState( *m_pCurrentCursor );
1193  bool bRet = GetLayout()->SetCurrPage( m_pCurrentCursor, nPage ) &&
1194  !m_pCurrentCursor->IsSelOvr( SwCursorSelOverFlags::Toggle |
1196  if( bRet )
1198 
1199  collectUIInformation(OUString::number(nPage));
1200  return bRet;
1201 }
1202 
1204 {
1205  SwContentFrame* pFrame = GetCurrFrame();
1206  pFrame->GetCharRect( rRect, *pPos );
1207 }
1208 
1209 void SwCursorShell::GetPageNum( sal_uInt16 &rnPhyNum, sal_uInt16 &rnVirtNum,
1210  bool bAtCursorPos, const bool bCalcFrame )
1211 {
1212  CurrShell aCurr( this );
1213  // page number: first visible page or the one at the cursor
1214  const SwContentFrame* pCFrame;
1215  const SwPageFrame *pPg = nullptr;
1216 
1217  if( !bAtCursorPos || nullptr == (pCFrame = GetCurrFrame( bCalcFrame )) ||
1218  nullptr == (pPg = pCFrame->FindPageFrame()) )
1219  {
1220  pPg = Imp()->GetFirstVisPage(GetOut());
1221  while( pPg && pPg->IsEmptyPage() )
1222  pPg = static_cast<const SwPageFrame *>(pPg->GetNext());
1223  }
1224  // pPg has to exist with a default of 1 for the special case "Writerstart"
1225  rnPhyNum = pPg? pPg->GetPhyPageNum() : 1;
1226  rnVirtNum = pPg? pPg->GetVirtPageNum() : 1;
1227 }
1228 
1230 {
1231  CurrShell aCurr(this);
1232  // page number: first visible page or the one at the cursor
1233  const SwContentFrame* pCFrame = GetCurrFrame(/*bCalcFrame*/true);
1234  const SwPageFrame* pPg = nullptr;
1235 
1236  if (pCFrame == nullptr || nullptr == (pPg = pCFrame->FindPageFrame()))
1237  {
1238  pPg = Imp()->GetFirstVisPage(GetOut());
1239  while (pPg && pPg->IsEmptyPage())
1240  pPg = static_cast<const SwPageFrame*>(pPg->GetNext());
1241  }
1242 
1243  sal_uInt16 nPageNo = 0;
1244  while (pPg)
1245  {
1246  if (!pPg->IsEmptyPage())
1247  ++nPageNo;
1248  pPg = static_cast<const SwPageFrame*>(pPg->GetPrev());
1249  }
1250  return nPageNo;
1251 }
1252 
1253 sal_uInt16 SwCursorShell::GetNextPrevPageNum( bool bNext )
1254 {
1255  CurrShell aCurr( this );
1256  // page number: first visible page or the one at the cursor
1257  const SwPageFrame *pPg = Imp()->GetFirstVisPage(GetOut());
1258  if( pPg )
1259  {
1260  const SwTwips nPageTop = pPg->getFrameArea().Top();
1261 
1262  if( bNext )
1263  {
1264  // go to next view layout row:
1265  do
1266  {
1267  pPg = static_cast<const SwPageFrame *>(pPg->GetNext());
1268  }
1269  while( pPg && pPg->getFrameArea().Top() == nPageTop );
1270 
1271  while( pPg && pPg->IsEmptyPage() )
1272  pPg = static_cast<const SwPageFrame *>(pPg->GetNext());
1273  }
1274  else
1275  {
1276  // go to previous view layout row:
1277  do
1278  {
1279  pPg = static_cast<const SwPageFrame *>(pPg->GetPrev());
1280  }
1281  while( pPg && pPg->getFrameArea().Top() == nPageTop );
1282 
1283  while( pPg && pPg->IsEmptyPage() )
1284  pPg = static_cast<const SwPageFrame *>(pPg->GetPrev());
1285  }
1286  }
1287  // pPg has to exist with a default of 1 for the special case "Writerstart"
1288  return pPg ? pPg->GetPhyPageNum() : USHRT_MAX;
1289 }
1290 
1292 {
1293  CurrShell aCurr( this );
1294  // return number of pages
1295  return GetLayout()->GetPageNum();
1296 }
1297 
1299 {
1300  CurrShell aCurr(this);
1301  SwRootFrame* pLayout = GetLayout();
1302  OUStringBuffer aBuf;
1303  for (const SwFrame* pFrame = pLayout->GetLower(); pFrame; pFrame = pFrame->GetNext())
1304  {
1305  aBuf.append(pFrame->getFrameArea().Left());
1306  aBuf.append(", ");
1307  aBuf.append(pFrame->getFrameArea().Top());
1308  aBuf.append(", ");
1309  aBuf.append(pFrame->getFrameArea().Width());
1310  aBuf.append(", ");
1311  aBuf.append(pFrame->getFrameArea().Height());
1312  aBuf.append("; ");
1313  }
1314  if (!aBuf.isEmpty())
1315  aBuf.setLength( aBuf.getLength() - 2); // remove the last "; "
1316  return aBuf.makeStringAndClear();
1317 }
1318 
1320 {
1321  auto pView = const_cast<SdrView*>(GetDrawView());
1322  if (pView->GetTextEditObject())
1323  {
1324  // Blinking cursor.
1325  EditView& rEditView = pView->GetTextEditOutlinerView()->GetEditView();
1326  rEditView.RegisterOtherShell(pOtherShell);
1327  rEditView.ShowCursor();
1328  rEditView.RegisterOtherShell(nullptr);
1329  // Text selection, if any.
1330  rEditView.DrawSelectionXOR(pOtherShell);
1331 
1332  // Shape text lock.
1333  if (OutlinerView* pOutlinerView = pView->GetTextEditOutlinerView())
1334  {
1335  OString sRect = pOutlinerView->GetOutputArea().toString();
1336  SfxLokHelper::notifyOtherView(GetSfxViewShell(), pOtherShell, LOK_CALLBACK_VIEW_LOCK, "rectangle", sRect);
1337  }
1338  }
1339  else
1340  {
1341  // Cursor position.
1342  m_pVisibleCursor->SetPosAndShow(pOtherShell);
1343  // Cursor visibility.
1344  if (GetSfxViewShell() != pOtherShell)
1345  {
1346  OString aPayload = OString::boolean(m_bSVCursorVis);
1347  SfxLokHelper::notifyOtherView(GetSfxViewShell(), pOtherShell, LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", aPayload);
1348  }
1349  // Text selection.
1350  m_pCurrentCursor->Show(pOtherShell);
1351  // Graphic selection.
1352  pView->AdjustMarkHdl(pOtherShell);
1353  }
1354 }
1355 
1358 {
1359  if( !m_pCurrentCursor->IsMultiSelection() )
1360  return false;
1361 
1362  CurrShell aCurr( this );
1363  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
1364  m_pCurrentCursor = m_pCurrentCursor->GetNext();
1365 
1366  // #i24086#: show also all others
1367  if( !ActionPend() )
1368  {
1369  UpdateCursor();
1370  m_pCurrentCursor->Show(nullptr);
1371  }
1372  return true;
1373 }
1374 
1377 {
1378  if( !m_pCurrentCursor->IsMultiSelection() )
1379  return false;
1380 
1381  CurrShell aCurr( this );
1382  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
1383  m_pCurrentCursor = m_pCurrentCursor->GetPrev();
1384 
1385  // #i24086#: show also all others
1386  if( !ActionPend() )
1387  {
1388  UpdateCursor();
1389  m_pCurrentCursor->Show(nullptr);
1390  }
1391  return true;
1392 }
1393 
1395 {
1396  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::Empty );
1397 
1398  if( !m_pCurrentCursor->IsMultiSelection() )
1399  {
1400  if( !m_pCurrentCursor->HasMark() )
1401  SvxSearchDialogWrapper::SetSearchLabel( SearchLabel::NavElementNotFound );
1402  return;
1403  }
1404 
1405  if (bNext)
1406  GoNextCursor();
1407  else
1408  GoPrevCursor();
1409 }
1410 
1411 void SwCursorShell::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle &rRect)
1412 {
1413  comphelper::FlagRestorationGuard g(mbSelectAll, StartsWithTable() && ExtendedSelectedAll());
1414  CurrShell aCurr( this );
1415 
1416  // always switch off all cursors when painting
1417  SwRect aRect( rRect );
1418 
1419  bool bVis = false;
1420  // if a cursor is visible then hide the SV cursor
1421  if( m_pVisibleCursor->IsVisible() && !aRect.Overlaps( m_aCharRect ) )
1422  {
1423  bVis = true;
1424  m_pVisibleCursor->Hide();
1425  }
1426 
1427  // re-paint area
1428  SwViewShell::Paint(rRenderContext, rRect);
1429 
1430  if( m_bHasFocus && !m_bBasicHideCursor )
1431  {
1432  SwShellCursor* pCurrentCursor = m_pTableCursor ? m_pTableCursor : m_pCurrentCursor;
1433 
1434  if( !ActionPend() )
1435  {
1436  // so that right/bottom borders will not be cropped
1437  pCurrentCursor->Invalidate( VisArea() );
1438  pCurrentCursor->Show(nullptr);
1439  }
1440  else
1441  pCurrentCursor->Invalidate( aRect );
1442 
1443  }
1444 
1445  if (SwPostItMgr* pPostItMgr = GetPostItMgr())
1446  {
1447  // No point in showing the cursor for Writer text when there is an
1448  // active annotation edit.
1449  if (bVis)
1450  bVis = !pPostItMgr->HasActiveSidebarWin();
1451  }
1452 
1453  if( m_bSVCursorVis && bVis ) // also show SV cursor again
1454  m_pVisibleCursor->Show();
1455 }
1456 
1457 void SwCursorShell::VisPortChgd( const SwRect & rRect )
1458 {
1459  CurrShell aCurr( this );
1460  bool bVis; // switch off all cursors when scrolling
1461 
1462  // if a cursor is visible then hide the SV cursor
1463  bVis = m_pVisibleCursor->IsVisible();
1464  if( bVis )
1465  m_pVisibleCursor->Hide();
1466 
1467  m_bVisPortChgd = true;
1468  m_aOldRBPos.setX(VisArea().Right());
1469  m_aOldRBPos.setY(VisArea().Bottom());
1470 
1471  // For not having problems with the SV cursor, Update() is called for the
1472  // Window in SwViewShell::VisPo...
1473  // During painting no selections should be shown, thus the call is encapsulated. <- TODO: old artefact?
1474  SwViewShell::VisPortChgd( rRect ); // move area
1475 
1476  if( m_bSVCursorVis && bVis ) // show SV cursor again
1477  m_pVisibleCursor->Show();
1478 
1479  if( m_nCursorMove )
1480  m_bInCMvVisportChgd = true;
1481 
1482  m_bVisPortChgd = false;
1483 }
1484 
1492 {
1493  CurrShell aCurr( this );
1494  ++mnStartAction;
1495  SwShellCursor* pShellCursor = getShellCursor( true );
1496  Size aOldSz( GetDocSize() );
1497 
1498  if( isInHiddenTextFrame(pShellCursor) )
1499  {
1501  aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
1502  GetLayout()->GetModelPositionForViewPoint( pShellCursor->GetPoint(), pShellCursor->GetPtPos(),
1503  &aTmpState );
1504  pShellCursor->DeleteMark();
1505  }
1506  IGrammarContact *pGrammarContact = GetDoc() ? GetDoc()->getGrammarContact() : nullptr;
1507  if( pGrammarContact )
1508  pGrammarContact->updateCursorPosition( *m_pCurrentCursor->GetPoint() );
1509  --mnStartAction;
1510  if( aOldSz != GetDocSize() )
1511  SizeChgNotify();
1512 }
1513 
1514 // #i65475# - if Point/Mark in hidden sections, move them out
1516 {
1517  bool bOk = true;
1518  const SwSectionNode* pSectNd = rIdx.GetNode().FindSectionNode();
1519  if( pSectNd && pSectNd->GetSection().IsHiddenFlag() )
1520  {
1521  SwNodeIndex aTmp( *pSectNd );
1522  const SwNode* pFrameNd =
1523  rIdx.GetNodes().FindPrvNxtFrameNode( aTmp, pSectNd->EndOfSectionNode() );
1524  bOk = pFrameNd != nullptr;
1525  SAL_WARN_IF(!bOk, "sw.core", "found no Node with Frames");
1526  rIdx = aTmp;
1527  }
1528  return bOk;
1529 }
1530 
1532 static void lcl_CheckHiddenPara( SwPosition& rPos )
1533 {
1534  SwNodeIndex aTmp( rPos.nNode );
1535  SwTextNode* pTextNd = aTmp.GetNode().GetTextNode();
1536  while( pTextNd && pTextNd->HasHiddenCharAttribute( true ) )
1537  {
1538  SwContentNode* pContent = aTmp.GetNodes().GoNext( &aTmp );
1539  if ( pContent && pContent->IsTextNode() )
1540  pTextNd = pContent->GetTextNode();
1541  else
1542  pTextNd = nullptr;
1543  }
1544 
1545  if ( pTextNd )
1546  rPos = SwPosition( aTmp, SwIndex( pTextNd, 0 ) );
1547 }
1548 
1549 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1550 namespace {
1551 
1552 // #i27301# - helper class that notifies the accessibility about invalid text
1553 // selections in its destructor
1554 class SwNotifyAccAboutInvalidTextSelections
1555 {
1556  private:
1557  SwCursorShell& mrCursorSh;
1558 
1559  public:
1560  explicit SwNotifyAccAboutInvalidTextSelections( SwCursorShell& _rCursorSh )
1561  : mrCursorSh( _rCursorSh )
1562  {}
1563 
1564  ~SwNotifyAccAboutInvalidTextSelections() COVERITY_NOEXCEPT_FALSE
1565  {
1567  }
1568 };
1569 
1570 }
1571 #endif
1572 
1573 void SwCursorShell::UpdateCursor( sal_uInt16 eFlags, bool bIdleEnd )
1574 {
1575  CurrShell aCurr( this );
1576  ClearUpCursors();
1577 
1578  if (ActionPend())
1579  {
1580  if ( eFlags & SwCursorShell::READONLY )
1581  m_bIgnoreReadonly = true;
1582  return; // if not then no update
1583  }
1584 
1585 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1586  SwNotifyAccAboutInvalidTextSelections aInvalidateTextSelections( *this );
1587 #endif
1588 
1589  if ( m_bIgnoreReadonly )
1590  {
1591  m_bIgnoreReadonly = false;
1592  eFlags |= SwCursorShell::READONLY;
1593  }
1594 
1595  if( eFlags & SwCursorShell::CHKRANGE ) // check all cursor moves for
1596  CheckRange( m_pCurrentCursor ); // overlapping ranges
1597 
1598  if( !bIdleEnd )
1599  CheckTableBoxContent();
1600 
1601  // If the current cursor is in a table and point/mark in different boxes,
1602  // then the table mode is active (also if it is already active: m_pTableCursor)
1603  SwPaM* pTstCursor = getShellCursor( true );
1604  if( pTstCursor->HasMark() && !m_pBlockCursor &&
1605  mxDoc->IsIdxInTable( pTstCursor->GetPoint()->nNode ) &&
1606  ( m_pTableCursor ||
1607  pTstCursor->GetNode().StartOfSectionNode() !=
1608  pTstCursor->GetNode( false ).StartOfSectionNode() ) && !mbSelectAll)
1609  {
1610  SwShellCursor* pITmpCursor = getShellCursor( true );
1611  Point aTmpPt( pITmpCursor->GetPtPos() );
1612  Point aTmpMk( pITmpCursor->GetMkPos() );
1613  SwPosition* pPos = pITmpCursor->GetPoint();
1614 
1615  // Bug 65475 (1999) - if Point/Mark in hidden sections, move them out
1616  lcl_CheckHiddenSection( pPos->nNode );
1617  lcl_CheckHiddenSection( pITmpCursor->GetMark()->nNode );
1618 
1619  // Move cursor out of hidden paragraphs
1620  if ( !GetViewOptions()->IsShowHiddenChar() )
1621  {
1622  lcl_CheckHiddenPara( *pPos );
1623  lcl_CheckHiddenPara( *pITmpCursor->GetMark() );
1624  }
1625 
1626  std::pair<Point, bool> const tmp(aTmpPt, false);
1627  SwContentFrame *pTableFrame = pPos->nNode.GetNode().GetContentNode()->
1628  getLayoutFrame( GetLayout(), pPos, &tmp);
1629 
1630  OSL_ENSURE( pTableFrame, "Table Cursor not in Content ??" );
1631 
1632  // --> Make code robust. The table cursor may point
1633  // to a table in a currently inactive header.
1634  SwTabFrame *pTab = pTableFrame ? pTableFrame->FindTabFrame() : nullptr;
1635 
1636  if ( pTab && pTab->GetTable()->GetRowsToRepeat() > 0 )
1637  {
1638  // First check if point is in repeated headline:
1639  bool bInRepeatedHeadline = pTab->IsFollow() && pTab->IsInHeadline( *pTableFrame );
1640 
1641  // Second check if mark is in repeated headline:
1642  if ( !bInRepeatedHeadline )
1643  {
1644  std::pair<Point, bool> const tmp1(aTmpMk, false);
1645  SwContentFrame* pMarkTableFrame = pITmpCursor->GetContentNode( false )->
1646  getLayoutFrame(GetLayout(), pITmpCursor->GetMark(), &tmp1);
1647  OSL_ENSURE( pMarkTableFrame, "Table Cursor not in Content ??" );
1648 
1649  if ( pMarkTableFrame )
1650  {
1651  SwTabFrame* pMarkTab = pMarkTableFrame->FindTabFrame();
1652  OSL_ENSURE( pMarkTab, "Table Cursor not in Content ??" );
1653 
1654  // Make code robust:
1655  if ( pMarkTab )
1656  {
1657  bInRepeatedHeadline = pMarkTab->IsFollow() && pMarkTab->IsInHeadline( *pMarkTableFrame );
1658  }
1659  }
1660  }
1661 
1662  // No table cursor in repeated headlines:
1663  if ( bInRepeatedHeadline )
1664  {
1665  pTableFrame = nullptr;
1666 
1667  SwMoveFnCollection const & fnPosSect = *pPos < *pITmpCursor->GetMark()
1668  ? fnSectionStart
1669  : fnSectionEnd;
1670 
1671  // then only select inside the Box
1672  if( m_pTableCursor )
1673  {
1674  m_pCurrentCursor->SetMark();
1675  *m_pCurrentCursor->GetMark() = *m_pTableCursor->GetMark();
1676  m_pCurrentCursor->GetMkPos() = m_pTableCursor->GetMkPos();
1677  m_pTableCursor->DeleteMark();
1678  m_pTableCursor->SwSelPaintRects::Hide();
1679  }
1680 
1681  *m_pCurrentCursor->GetPoint() = *m_pCurrentCursor->GetMark();
1682  GoCurrSection( *m_pCurrentCursor, fnPosSect );
1683  }
1684  }
1685 
1686  // we really want a table selection
1687  if( pTab && pTableFrame )
1688  {
1689  if( !m_pTableCursor )
1690  {
1691  m_pTableCursor = new SwShellTableCursor( *this,
1692  *m_pCurrentCursor->GetMark(), m_pCurrentCursor->GetMkPos(),
1693  *pPos, aTmpPt );
1694  m_pCurrentCursor->DeleteMark();
1695  m_pCurrentCursor->SwSelPaintRects::Hide();
1696 
1697  CheckTableBoxContent();
1698  if(!m_pTableCursor)
1699  {
1700  SAL_WARN("sw.core", "fdo#74854: "
1701  "this should not happen, but better lose the selection "
1702  "rather than crashing");
1703  return;
1704  }
1705  }
1706 
1708  aTmpState.m_bRealHeight = true;
1709  {
1710  DisableCallbackAction a(*GetLayout());
1711  if (!pTableFrame->GetCharRect( m_aCharRect, *m_pTableCursor->GetPoint(), &aTmpState))
1712  {
1713  Point aCentrPt( m_aCharRect.Center() );
1714  aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
1715  pTableFrame->GetModelPositionForViewPoint(m_pTableCursor->GetPoint(), aCentrPt, &aTmpState);
1716  bool const bResult =
1717  pTableFrame->GetCharRect(m_aCharRect, *m_pTableCursor->GetPoint());
1718  OSL_ENSURE( bResult, "GetCharRect failed." );
1719  }
1720  }
1721 
1722  m_pVisibleCursor->Hide(); // always hide visible Cursor
1723  // scroll Cursor to visible area
1724  if( eFlags & SwCursorShell::SCROLLWIN &&
1725  (HasSelection() || eFlags & SwCursorShell::READONLY ||
1726  !IsCursorReadonly()) )
1727  {
1728  SwFrame* pBoxFrame = pTableFrame;
1729  while( pBoxFrame && !pBoxFrame->IsCellFrame() )
1730  pBoxFrame = pBoxFrame->GetUpper();
1731  if( pBoxFrame && pBoxFrame->getFrameArea().HasArea() )
1732  MakeVisible( pBoxFrame->getFrameArea() );
1733  else
1734  MakeVisible( m_aCharRect );
1735  }
1736 
1737  // let Layout create the Cursors in the Boxes
1738  if( m_pTableCursor->IsCursorMovedUpdate() )
1739  GetLayout()->MakeTableCursors( *m_pTableCursor );
1740  if( m_bHasFocus && !m_bBasicHideCursor )
1741  m_pTableCursor->Show(nullptr);
1742 
1743  // set Cursor-Points to the new Positions
1744  m_pTableCursor->GetPtPos().setX(m_aCharRect.Left());
1745  m_pTableCursor->GetPtPos().setY(m_aCharRect.Top());
1746 
1747  if( m_bSVCursorVis )
1748  {
1749  m_aCursorHeight.setX(0);
1750  m_aCursorHeight.setY(aTmpState.m_aRealHeight.getY() < 0 ?
1751  -m_aCharRect.Width() : m_aCharRect.Height());
1752  m_pVisibleCursor->Show(); // show again
1753  }
1754  m_eMvState = CursorMoveState::NONE; // state for cursor travelling - GetModelPositionForViewPoint
1755 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
1756  if (Imp()->IsAccessible())
1757  Imp()->InvalidateAccessibleCursorPosition( pTableFrame );
1758 #endif
1759  return;
1760  }
1761  }
1762 
1763  if( m_pTableCursor )
1764  {
1765  // delete Ring
1766  while( m_pCurrentCursor->GetNext() != m_pCurrentCursor )
1767  delete m_pCurrentCursor->GetNext();
1768  m_pCurrentCursor->DeleteMark();
1769  *m_pCurrentCursor->GetPoint() = *m_pTableCursor->GetPoint();
1770  m_pCurrentCursor->GetPtPos() = m_pTableCursor->GetPtPos();
1771  delete m_pTableCursor;
1772  m_pTableCursor = nullptr;
1773  }
1774 
1775  m_pVisibleCursor->Hide(); // always hide visible Cursor
1776 
1777  // are we perhaps in a protected / hidden Section ?
1778  {
1779  SwShellCursor* pShellCursor = getShellCursor( true );
1780  bool bChgState = true;
1781  const SwSectionNode* pSectNd = pShellCursor->GetNode().FindSectionNode();
1782  if( pSectNd && ( pSectNd->GetSection().IsHiddenFlag() ||
1783  ( !IsReadOnlyAvailable() &&
1784  pSectNd->GetSection().IsProtectFlag() &&
1785  ( !mxDoc->GetDocShell() ||
1786  !mxDoc->GetDocShell()->IsReadOnly() || m_bAllProtect )) ) )
1787  {
1788  if( !FindValidContentNode( !HasDrawView() ||
1789  0 == Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount()))
1790  {
1791  // everything protected/hidden -> special mode
1792  if( m_bAllProtect && !IsReadOnlyAvailable() &&
1793  pSectNd->GetSection().IsProtectFlag() )
1794  bChgState = false;
1795  else
1796  {
1797  m_eMvState = CursorMoveState::NONE; // state for cursor travelling
1798  m_bAllProtect = true;
1799  if( GetDoc()->GetDocShell() )
1800  {
1801  GetDoc()->GetDocShell()->SetReadOnlyUI();
1802  CallChgLnk(); // notify UI!
1803  }
1804  return;
1805  }
1806  }
1807  }
1808  if( bChgState )
1809  {
1810  bool bWasAllProtect = m_bAllProtect;
1811  m_bAllProtect = false;
1812  if( bWasAllProtect && GetDoc()->GetDocShell() &&
1813  GetDoc()->GetDocShell()->IsReadOnlyUI() )
1814  {
1815  GetDoc()->GetDocShell()->SetReadOnlyUI( false );
1816  CallChgLnk(); // notify UI!
1817  }
1818  }
1819  }
1820 
1821  UpdateCursorPos();
1822 
1823  // The cursor must always point into content; there's some code
1824  // that relies on this. (E.g. in SwEditShell::GetScriptType, which always
1825  // loops _behind_ the last node in the selection, which always works if you
1826  // are in content.) To achieve this, we'll force cursor(s) to point into
1827  // content, if UpdateCursorPos() hasn't already done so.
1828  for(SwPaM& rCmp : m_pCurrentCursor->GetRingContainer())
1829  {
1830  // start will move forwards, end will move backwards
1831  bool bPointIsStart = ( rCmp.Start() == rCmp.GetPoint() );
1832 
1833  // move point; forward if it's the start, backwards if it's the end
1834  if( ! rCmp.GetPoint()->nNode.GetNode().IsContentNode() )
1835  rCmp.Move( bPointIsStart ? fnMoveForward : fnMoveBackward,
1836  GoInContent );
1837 
1838  // move mark (if exists); forward if it's the start, else backwards
1839  if( rCmp.HasMark() )
1840  {
1841  if( ! rCmp.GetMark()->nNode.GetNode().IsContentNode() )
1842  {
1843  rCmp.Exchange();
1844  rCmp.Move( !bPointIsStart ? fnMoveForward : fnMoveBackward,
1845  GoInContent );
1846  rCmp.Exchange();
1847  }
1848  }
1849  }
1850 
1851  SwRect aOld( m_aCharRect );
1852  bool bFirst = true;
1853  SwContentFrame *pFrame;
1854  int nLoopCnt = 100;
1855  SwShellCursor* pShellCursor = getShellCursor( true );
1856 
1857  do {
1858  bool bAgainst;
1859  do {
1860  bAgainst = false;
1861  std::pair<Point, bool> const tmp1(pShellCursor->GetPtPos(), false);
1862  pFrame = pShellCursor->GetContentNode()->getLayoutFrame(GetLayout(),
1863  pShellCursor->GetPoint(), &tmp1);
1864  // if the Frame doesn't exist anymore, the complete Layout has to be
1865  // created, because there used to be a Frame here!
1866  if ( !pFrame )
1867  {
1868  do
1869  {
1870  CalcLayout();
1871  std::pair<Point, bool> const tmp(pShellCursor->GetPtPos(), false);
1872  pFrame = pShellCursor->GetContentNode()->getLayoutFrame(
1873  GetLayout(), pShellCursor->GetPoint(), &tmp);
1874  } while( !pFrame );
1875  }
1876  else if ( Imp()->IsIdleAction() )
1877  // Guarantee everything's properly formatted
1878  pFrame->PrepareCursor();
1879 
1880  // In protected Fly? but ignore in case of frame selection
1881  if( !IsReadOnlyAvailable() && pFrame->IsProtected() &&
1882  ( !Imp()->GetDrawView() ||
1883  !Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount() ) &&
1884  (!mxDoc->GetDocShell() ||
1885  !mxDoc->GetDocShell()->IsReadOnly() || m_bAllProtect ) )
1886  {
1887  // look for a valid position
1888  bool bChgState = true;
1889  if( !FindValidContentNode(!HasDrawView() ||
1890  0 == Imp()->GetDrawView()->GetMarkedObjectList().GetMarkCount()))
1891  {
1892  // everything is protected / hidden -> special Mode
1893  if( m_bAllProtect )
1894  bChgState = false;
1895  else
1896  {
1897  m_eMvState = CursorMoveState::NONE; // state for cursor travelling
1898  m_bAllProtect = true;
1899  if( GetDoc()->GetDocShell() )
1900  {
1901  GetDoc()->GetDocShell()->SetReadOnlyUI();
1902  CallChgLnk(); // notify UI!
1903  }
1904  return;
1905  }
1906  }
1907 
1908  if( bChgState )
1909  {
1910  bool bWasAllProtect = m_bAllProtect;
1911  m_bAllProtect = false;
1912  if( bWasAllProtect && GetDoc()->GetDocShell() &&
1913  GetDoc()->GetDocShell()->IsReadOnlyUI() )
1914  {
1915  GetDoc()->GetDocShell()->SetReadOnlyUI( false );
1916  CallChgLnk(); // notify UI!
1917  }
1918  m_bAllProtect = false;
1919  bAgainst = true; // look for the right Frame again
1920  }
1921  }
1922  } while( bAgainst );
1923 
1924  SwCursorMoveState aTmpState( m_eMvState );
1925  aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
1926  aTmpState.m_bRealHeight = true;
1927  aTmpState.m_bRealWidth = IsOverwriteCursor();
1928  aTmpState.m_nCursorBidiLevel = pShellCursor->GetCursorBidiLevel();
1929 
1930  // #i27615#,#i30453#
1931  SwSpecialPos aSpecialPos;
1932  aSpecialPos.nExtendRange = SwSPExtendRange::BEFORE;
1933  if (pShellCursor->IsInFrontOfLabel())
1934  {
1935  aTmpState.m_pSpecialPos = &aSpecialPos;
1936  }
1937 
1938  {
1939  DisableCallbackAction a(*GetLayout()); // tdf#91602 prevent recursive Action
1940  if (!pFrame->GetCharRect(m_aCharRect, *pShellCursor->GetPoint(), &aTmpState))
1941  {
1942  Point& rPt = pShellCursor->GetPtPos();
1943  rPt = m_aCharRect.Center();
1944  pFrame->GetModelPositionForViewPoint( pShellCursor->GetPoint(), rPt, &aTmpState );
1945  }
1946  }
1947  UISizeNotify(); // tdf#96256 update view size
1948 
1949  if( !pShellCursor->HasMark() )
1950  m_aCursorHeight = aTmpState.m_aRealHeight;
1951  else
1952  {
1953  m_aCursorHeight.setX(0);
1954  m_aCursorHeight.setY(aTmpState.m_aRealHeight.getY() < 0 ?
1955  -m_aCharRect.Width() : m_aCharRect.Height());
1956  }
1957 
1958  if( !bFirst && aOld == m_aCharRect )
1959  break;
1960 
1961  // if the layout says that we are after the 100th iteration still in
1962  // flow then we should always take the current position for granted.
1963  // (see bug: 29658)
1964  if( !--nLoopCnt )
1965  {
1966  OSL_ENSURE( false, "endless loop? CharRect != OldCharRect ");
1967  break;
1968  }
1969  aOld = m_aCharRect;
1970  bFirst = false;
1971 
1972  // update cursor Points to the new Positions
1973  pShellCursor->GetPtPos().setX(m_aCharRect.Left());
1974  pShellCursor->GetPtPos().setY(m_aCharRect.Top());
1975 
1976  if( !(eFlags & SwCursorShell::UPDOWN )) // delete old Pos. of Up/Down
1977  {
1978  DisableCallbackAction a(*GetLayout());
1979  pFrame->Calc(GetOut());
1980  m_nUpDownX = pFrame->IsVertical() ?
1981  m_aCharRect.Top() - pFrame->getFrameArea().Top() :
1982  m_aCharRect.Left() - pFrame->getFrameArea().Left();
1983  }
1984 
1985  // scroll Cursor to visible area
1986  if( m_bHasFocus && eFlags & SwCursorShell::SCROLLWIN &&
1987  (HasSelection() || eFlags & SwCursorShell::READONLY ||
1988  !IsCursorReadonly() || GetViewOptions()->IsSelectionInReadonly()) )
1989  {
1990  // in case of scrolling this EndAction doesn't show the SV cursor
1991  // again, thus save and reset the flag here
1992  bool bSav = m_bSVCursorVis;
1993  m_bSVCursorVis = false;
1994  MakeSelVisible();
1995  m_bSVCursorVis = bSav;
1996  }
1997 
1998  } while( eFlags & SwCursorShell::SCROLLWIN );
1999 
2000  assert(pFrame);
2001 
2002  if( m_pBlockCursor )
2003  RefreshBlockCursor();
2004 
2005  // We should not restrict cursor update to the active view when using LOK
2006  bool bCheckFocus = m_bHasFocus || comphelper::LibreOfficeKit::isActive();
2007 
2008  if( !bIdleEnd && bCheckFocus && !m_bBasicHideCursor )
2009  {
2010  if( m_pTableCursor )
2011  m_pTableCursor->SwSelPaintRects::Show();
2012  else
2013  {
2014  m_pCurrentCursor->SwSelPaintRects::Show();
2015  if( m_pBlockCursor )
2016  {
2017  SwShellCursor* pNxt = m_pCurrentCursor->GetNext();
2018  while( pNxt && pNxt != m_pCurrentCursor )
2019  {
2020  pNxt->SwSelPaintRects::Show();
2021  pNxt = pNxt->GetNext();
2022  }
2023  }
2024  }
2025  }
2026 
2027  m_eMvState = CursorMoveState::NONE; // state for cursor travelling - GetModelPositionForViewPoint
2028 
2029 #if !ENABLE_WASM_STRIP_ACCESSIBILITY
2030  if (Imp()->IsAccessible())
2031  Imp()->InvalidateAccessibleCursorPosition( pFrame );
2032 #endif
2033 
2034  // switch from blinking cursor to read-only-text-selection cursor
2035  const sal_uInt64 nBlinkTime = GetOut()->GetSettings().GetStyleSettings().
2036  GetCursorBlinkTime();
2037 
2038  if ( (IsCursorReadonly() && GetViewOptions()->IsSelectionInReadonly()) ==
2039  ( nBlinkTime != STYLE_CURSOR_NOBLINKTIME ) )
2040  {
2041  // non blinking cursor in read only - text selection mode
2042  AllSettings aSettings = GetOut()->GetSettings();
2043  StyleSettings aStyleSettings = aSettings.GetStyleSettings();
2044  const sal_uInt64 nNewBlinkTime = nBlinkTime == STYLE_CURSOR_NOBLINKTIME ?
2047  aStyleSettings.SetCursorBlinkTime( nNewBlinkTime );
2048  aSettings.SetStyleSettings( aStyleSettings );
2049  GetOut()->SetSettings( aSettings );
2050  }
2051 
2052  if( m_bSVCursorVis )
2053  m_pVisibleCursor->Show(); // show again
2054 
2056  sendLOKCursorUpdates();
2057 
2058  getIDocumentMarkAccess()->NotifyCursorUpdate(*this);
2059 }
2060 
2062 {
2063  SwView* pView = static_cast<SwView*>(GetSfxViewShell());
2064  if (!pView || !pView->GetWrtShellPtr())
2065  return;
2066 
2067  SwWrtShell* pShell = &pView->GetWrtShell();
2068 
2069  SwFrame* pCurrentFrame = GetCurrFrame();
2070  SelectionType eType = pShell->GetSelectionType();
2071 
2072  tools::JsonWriter aJsonWriter;
2073 
2074  if (pCurrentFrame && (eType & SelectionType::Table) && pCurrentFrame->IsInTab())
2075  {
2076  const SwRect& rPageRect = pShell->GetAnyCurRect(CurRectType::Page, nullptr);
2077 
2078  {
2079  auto columnsNode = aJsonWriter.startNode("columns");
2080  SwTabCols aTabCols;
2081  pShell->GetTabCols(aTabCols);
2082 
2083  const int nColumnOffset = aTabCols.GetLeftMin() + rPageRect.Left();
2084 
2085  aJsonWriter.put("left", aTabCols.GetLeft());
2086  aJsonWriter.put("right", aTabCols.GetRight());
2087  aJsonWriter.put("tableOffset", static_cast<sal_Int64>(nColumnOffset));
2088 
2089  {
2090  auto entriesNode = aJsonWriter.startArray("entries");
2091  for (size_t i = 0; i < aTabCols.Count(); ++i)
2092  {
2093  auto entryNode = aJsonWriter.startStruct();
2094  auto const & rEntry = aTabCols.GetEntry(i);
2095  aJsonWriter.put("position", rEntry.nPos);
2096  aJsonWriter.put("min", rEntry.nMin);
2097  aJsonWriter.put("max", rEntry.nMax);
2098  aJsonWriter.put("hidden", rEntry.bHidden);
2099  }
2100  }
2101  }
2102 
2103  {
2104  auto rowsNode = aJsonWriter.startNode("rows");
2105  SwTabCols aTabRows;
2106  pShell->GetTabRows(aTabRows);
2107 
2108  const int nRowOffset = aTabRows.GetLeftMin() + rPageRect.Top();
2109 
2110  aJsonWriter.put("left", aTabRows.GetLeft());
2111  aJsonWriter.put("right", aTabRows.GetRight());
2112  aJsonWriter.put("tableOffset", static_cast<sal_Int64>(nRowOffset));
2113 
2114  {
2115  auto entriesNode = aJsonWriter.startArray("entries");
2116  for (size_t i = 0; i < aTabRows.Count(); ++i)
2117  {
2118  auto entryNode = aJsonWriter.startStruct();
2119  auto const & rEntry = aTabRows.GetEntry(i);
2120  aJsonWriter.put("position", rEntry.nPos);
2121  aJsonWriter.put("min", rEntry.nMin);
2122  aJsonWriter.put("max", rEntry.nMax);
2123  aJsonWriter.put("hidden", rEntry.bHidden);
2124  }
2125  }
2126  }
2127  }
2128 
2129  char* pChar = aJsonWriter.extractData();
2130  GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_TABLE_SELECTED, pChar);
2131  free(pChar);
2132 }
2133 
2135 {
2136  assert(m_pBlockCursor);
2137  SwShellCursor &rBlock = m_pBlockCursor->getShellCursor();
2138  Point aPt = rBlock.GetPtPos();
2139  std::pair<Point, bool> const tmp(aPt, false);
2140  SwContentFrame* pFrame = rBlock.GetContentNode()->getLayoutFrame(
2141  GetLayout(), rBlock.GetPoint(), &tmp);
2142  Point aMk;
2143  if( m_pBlockCursor->getEndPoint() && m_pBlockCursor->getStartPoint() )
2144  {
2145  aPt = *m_pBlockCursor->getStartPoint();
2146  aMk = *m_pBlockCursor->getEndPoint();
2147  }
2148  else
2149  {
2150  aPt = rBlock.GetPtPos();
2151  if( pFrame )
2152  {
2153  if( pFrame->IsVertical() )
2154  aPt.setY(pFrame->getFrameArea().Top() + GetUpDownX());
2155  else
2156  aPt.setX(pFrame->getFrameArea().Left() + GetUpDownX());
2157  }
2158  aMk = rBlock.GetMkPos();
2159  }
2160  SwRect aRect( aMk, aPt );
2161  aRect.Justify();
2162  SwSelectionList aSelList( pFrame );
2163 
2164  if( !GetLayout()->FillSelection( aSelList, aRect ) )
2165  return;
2166 
2167  SwCursor* pNxt = static_cast<SwCursor*>(m_pCurrentCursor->GetNext());
2168  while( pNxt != m_pCurrentCursor )
2169  {
2170  delete pNxt;
2171  pNxt = static_cast<SwCursor*>(m_pCurrentCursor->GetNext());
2172  }
2173 
2174  std::list<SwPaM*>::iterator pStart = aSelList.getStart();
2175  std::list<SwPaM*>::iterator pPam = aSelList.getEnd();
2176  OSL_ENSURE( pPam != pStart, "FillSelection should deliver at least one PaM" );
2177  m_pCurrentCursor->SetMark();
2178  --pPam;
2179  // If there is only one text portion inside the rectangle, a simple
2180  // selection is created
2181  if( pPam == pStart )
2182  {
2183  *m_pCurrentCursor->GetPoint() = *(*pPam)->GetPoint();
2184  if( (*pPam)->HasMark() )
2185  *m_pCurrentCursor->GetMark() = *(*pPam)->GetMark();
2186  else
2187  m_pCurrentCursor->DeleteMark();
2188  delete *pPam;
2189  m_pCurrentCursor->SetColumnSelection( false );
2190  }
2191  else
2192  {
2193  // The order of the SwSelectionList has to be preserved but
2194  // the order inside the ring created by CreateCursor() is not like
2195  // expected => First create the selections before the last one
2196  // downto the first selection.
2197  // At least create the cursor for the last selection
2198  --pPam;
2199  *m_pCurrentCursor->GetPoint() = *(*pPam)->GetPoint(); // n-1 (if n == number of selections)
2200  if( (*pPam)->HasMark() )
2201  *m_pCurrentCursor->GetMark() = *(*pPam)->GetMark();
2202  else
2203  m_pCurrentCursor->DeleteMark();
2204  delete *pPam;
2205  m_pCurrentCursor->SetColumnSelection( true );
2206  while( pPam != pStart )
2207  {
2208  --pPam;
2209 
2210  SwShellCursor* pNew = new SwShellCursor( *m_pCurrentCursor );
2211  pNew->insert( pNew->begin(), m_pCurrentCursor->begin(), m_pCurrentCursor->end());
2212  m_pCurrentCursor->clear();
2213  m_pCurrentCursor->DeleteMark();
2214 
2215  *m_pCurrentCursor->GetPoint() = *(*pPam)->GetPoint(); // n-2, n-3, .., 2, 1
2216  if( (*pPam)->HasMark() )
2217  {
2218  m_pCurrentCursor->SetMark();
2219  *m_pCurrentCursor->GetMark() = *(*pPam)->GetMark();
2220  }
2221  else
2222  m_pCurrentCursor->DeleteMark();
2223  m_pCurrentCursor->SetColumnSelection( true );
2224  delete *pPam;
2225  }
2226  {
2227  SwShellCursor* pNew = new SwShellCursor( *m_pCurrentCursor );
2228  pNew->insert( pNew->begin(), m_pCurrentCursor->begin(), m_pCurrentCursor->end() );
2229  m_pCurrentCursor->clear();
2230  m_pCurrentCursor->DeleteMark();
2231  }
2232  pPam = aSelList.getEnd();
2233  --pPam;
2234  *m_pCurrentCursor->GetPoint() = *(*pPam)->GetPoint(); // n, the last selection
2235  if( (*pPam)->HasMark() )
2236  {
2237  m_pCurrentCursor->SetMark();
2238  *m_pCurrentCursor->GetMark() = *(*pPam)->GetMark();
2239  }
2240  else
2241  m_pCurrentCursor->DeleteMark();
2242  m_pCurrentCursor->SetColumnSelection( true );
2243  delete *pPam;
2244  }
2245 }
2246 
2249 {
2250  // fdo#60513: if we have a table cursor, copy that; else copy current.
2251  // This seems to work because UpdateCursor() will fix this up on Pop(),
2252  // then MakeBoxSels() will re-create the current m_pCurrentCursor cell ring.
2253  SwShellCursor *const pCurrent(m_pTableCursor ? m_pTableCursor : m_pCurrentCursor);
2254  m_pStackCursor = new SwShellCursor( *this, *pCurrent->GetPoint(),
2255  pCurrent->GetPtPos(), m_pStackCursor );
2256 
2257  if (pCurrent->HasMark())
2258  {
2259  m_pStackCursor->SetMark();
2260  *m_pStackCursor->GetMark() = *pCurrent->GetMark();
2261  }
2262 }
2263 
2270 bool SwCursorShell::Pop(PopMode const eDelete)
2271 {
2272  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
2273 
2274  // are there any left?
2275  if (nullptr == m_pStackCursor)
2276  return false;
2277 
2278  SwShellCursor *pTmp = nullptr, *pOldStack = m_pStackCursor;
2279 
2280  // the successor becomes the current one
2281  if (m_pStackCursor->GetNext() != m_pStackCursor)
2282  {
2283  pTmp = m_pStackCursor->GetNext();
2284  }
2285 
2286  if (PopMode::DeleteStack == eDelete)
2287  delete m_pStackCursor;
2288 
2289  m_pStackCursor = pTmp; // assign new one
2290 
2291  if (PopMode::DeleteCurrent == eDelete)
2292  {
2293  SwCursorSaveState aSaveState( *m_pCurrentCursor );
2294 
2295  // If the visible SSelection was not changed
2296  const Point& rPoint = pOldStack->GetPtPos();
2297  if (rPoint == m_pCurrentCursor->GetPtPos() || rPoint == m_pCurrentCursor->GetMkPos())
2298  {
2299  // move "Selections Rectangles"
2300  m_pCurrentCursor->insert( m_pCurrentCursor->begin(), pOldStack->begin(), pOldStack->end() );
2301  pOldStack->clear();
2302  }
2303 
2304  if( pOldStack->HasMark() )
2305  {
2306  m_pCurrentCursor->SetMark();
2307  *m_pCurrentCursor->GetMark() = *pOldStack->GetMark();
2308  m_pCurrentCursor->GetMkPos() = pOldStack->GetMkPos();
2309  }
2310  else
2311  // no selection so revoke old one and set to old position
2312  m_pCurrentCursor->DeleteMark();
2313  *m_pCurrentCursor->GetPoint() = *pOldStack->GetPoint();
2314  m_pCurrentCursor->GetPtPos() = pOldStack->GetPtPos();
2315  delete pOldStack;
2316 
2317  if( !m_pCurrentCursor->IsInProtectTable( true ) &&
2318  !m_pCurrentCursor->IsSelOvr( SwCursorSelOverFlags::Toggle |
2320  {
2321  UpdateCursor(); // update current cursor
2322  if (m_pTableCursor)
2323  { // tdf#106929 ensure m_pCurrentCursor ring is recreated from table
2324  m_pTableCursor->SetChgd();
2325  }
2326  }
2327  }
2328  return true;
2329 }
2330 
2336 {
2337  // any others left?
2338  if (nullptr == m_pStackCursor)
2339  return;
2340 
2341  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
2342  // rhbz#689053: IsSelOvr must restore the saved stack position, not the
2343  // current one, because current point + stack mark may be invalid PaM
2344  SwCursorSaveState aSaveState(*m_pStackCursor);
2345  // stack cursor & current cursor in same Section?
2346  assert(!m_pStackCursor->HasMark() ||
2347  CheckNodesRange(m_pStackCursor->GetMark()->nNode,
2348  m_pCurrentCursor->GetPoint()->nNode, true));
2349  *m_pStackCursor->GetPoint() = *m_pCurrentCursor->GetPoint();
2350  m_pStackCursor->GetPtPos() = m_pCurrentCursor->GetPtPos();
2351 
2352  SwShellCursor * pTmp = nullptr;
2353  if (m_pStackCursor->GetNext() != m_pStackCursor)
2354  {
2355  pTmp = m_pStackCursor->GetNext();
2356  }
2357  delete m_pCurrentCursor;
2358  m_pCurrentCursor = m_pStackCursor;
2359  m_pStackCursor->MoveTo(nullptr); // remove from ring
2360  m_pStackCursor = pTmp;
2361  if( !m_pCurrentCursor->IsInProtectTable( true ) &&
2362  !m_pCurrentCursor->IsSelOvr( SwCursorSelOverFlags::Toggle |
2364  {
2365  UpdateCursor(); // update current cursor
2366  }
2367 }
2368 
2370 {
2371  if( !m_bHasFocus || m_bBasicHideCursor )
2372  return;
2373 
2374  // if cursor is visible then hide SV cursor
2375  if( m_pVisibleCursor->IsVisible() )
2376  {
2377  CurrShell aCurr( this );
2378  m_pVisibleCursor->Hide();
2379  }
2380  // revoke inversion of SSelection
2381  SwShellCursor* pCurrentCursor = m_pTableCursor ? m_pTableCursor : m_pCurrentCursor;
2382  pCurrentCursor->Hide();
2383 }
2384 
2385 void SwCursorShell::ShowCursors( bool bCursorVis )
2386 {
2387  if( !m_bHasFocus || m_bAllProtect || m_bBasicHideCursor )
2388  return;
2389 
2390  CurrShell aCurr( this );
2391  SwShellCursor* pCurrentCursor = m_pTableCursor ? m_pTableCursor : m_pCurrentCursor;
2392  pCurrentCursor->Show(nullptr);
2393 
2394  if( m_bSVCursorVis && bCursorVis ) // also show SV cursor again
2395  m_pVisibleCursor->Show();
2396 }
2397 
2399 {
2400  if( m_bBasicHideCursor )
2401  return;
2402 
2403  m_bSVCursorVis = true;
2404  m_pCurrentCursor->SetShowTextInputFieldOverlay( true );
2405  m_pCurrentCursor->SetShowContentControlOverlay(true);
2406 
2408  {
2409  const OString aPayload = OString::boolean(m_bSVCursorVis);
2410  GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, aPayload.getStr());
2411  SfxLokHelper::notifyOtherViews(GetSfxViewShell(), LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", aPayload);
2412  }
2413 
2414  UpdateCursor();
2415 }
2416 
2418 {
2419  if( m_bBasicHideCursor )
2420  return;
2421 
2422  m_bSVCursorVis = false;
2423  // possibly reverse selected areas!!
2424  CurrShell aCurr( this );
2425  m_pCurrentCursor->SetShowTextInputFieldOverlay( false );
2426  m_pCurrentCursor->SetShowContentControlOverlay(false);
2427  m_pVisibleCursor->Hide();
2428 
2430  {
2431  OString aPayload = OString::boolean(m_bSVCursorVis);
2432  GetSfxViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_CURSOR_VISIBLE, aPayload.getStr());
2433  SfxLokHelper::notifyOtherViews(GetSfxViewShell(), LOK_CALLBACK_VIEW_CURSOR_VISIBLE, "visible", aPayload);
2434  }
2435 }
2436 
2438 {
2439  if( !m_bBasicHideCursor )
2440  HideCursors();
2441  m_bHasFocus = false;
2442 }
2443 
2445 {
2446  comphelper::FlagRestorationGuard g(mbSelectAll, StartsWithTable() && ExtendedSelectedAll());
2447 
2448  m_bHasFocus = true;
2449  if( !m_bBasicHideCursor && VisArea().Width() )
2450  {
2451  UpdateCursor( o3tl::narrowing<sal_uInt16>( SwCursorShell::CHKRANGE ) );
2452  ShowCursors( m_bSVCursorVis );
2453  }
2454 }
2455 
2457 SwContentFrame *SwCursorShell::GetCurrFrame( const bool bCalcFrame ) const
2458 {
2459  CurrShell aCurr( const_cast<SwCursorShell*>(this) );
2460  SwContentFrame *pRet = nullptr;
2461  SwContentNode *pNd = m_pCurrentCursor->GetContentNode();
2462  if ( pNd )
2463  {
2464  if ( bCalcFrame )
2465  {
2466  sal_uInt16* pST = const_cast<sal_uInt16*>(&mnStartAction);
2467  ++(*pST);
2468  const Size aOldSz( GetDocSize() );
2469  std::pair<Point, bool> const tmp(m_pCurrentCursor->GetPtPos(), true);
2470  pRet = pNd->getLayoutFrame(GetLayout(), m_pCurrentCursor->GetPoint(), &tmp);
2471  --(*pST);
2472  if( aOldSz != GetDocSize() )
2473  const_cast<SwCursorShell*>(this)->SizeChgNotify();
2474  }
2475  else
2476  {
2477  std::pair<Point, bool> const tmp(m_pCurrentCursor->GetPtPos(), false);
2478  pRet = pNd->getLayoutFrame(GetLayout(), m_pCurrentCursor->GetPoint(), &tmp);
2479  }
2480  }
2481  return pRet;
2482 }
2483 
2484 //TODO: provide documentation
2491 {
2492  if(dynamic_cast<const sw::PostGraphicArrivedHint*>(&rHint) && m_aGrfArrivedLnk.IsSet())
2493  {
2494  m_aGrfArrivedLnk.Call(*this);
2495  return;
2496  }
2497  if (rHint.GetId() != SfxHintId::SwLegacyModify)
2498  return;
2499  auto pLegacy = static_cast<const sw::LegacyModifyHint*>(&rHint);
2500  auto nWhich = pLegacy->GetWhich();
2501  if(!nWhich)
2502  nWhich = sal::static_int_cast<sal_uInt16>(RES_MSG_BEGIN);
2503  if( m_bCallChgLnk &&
2504  ( nWhich < RES_MSG_BEGIN || nWhich >= RES_MSG_END ||
2505  nWhich == RES_FMT_CHG || nWhich == RES_UPDATE_ATTR ||
2506  nWhich == RES_ATTRSET_CHG ))
2507  // messages are not forwarded
2508  // #i6681#: RES_UPDATE_ATTR is implicitly unset in
2509  // SwTextNode::Insert(SwTextHint*, sal_uInt16); we react here and thus do
2510  // not need to send the expensive RES_FMT_CHG in Insert.
2511  CallChgLnk();
2512  switch(nWhich)
2513  {
2514  case RES_OBJECTDYING:
2515  EndListeningAll();
2516  break;
2517  case RES_GRAPHIC_SWAPIN:
2518  if(m_aGrfArrivedLnk.IsSet())
2519  m_aGrfArrivedLnk.Call(*this);
2520  }
2521 
2522 }
2523 
2529 {
2530  const SwPaM* pCursor = getShellCursor( true );
2531  return IsTableMode()
2532  || (pCursor->HasMark() &&
2533  (*pCursor->GetPoint() != *pCursor->GetMark()
2534  || IsFlySelectedByCursor(*GetDoc(), *pCursor->Start(), *pCursor->End())));
2535 }
2536 
2538 {
2539  // Do not make any call in StartAction/EndAction but just set the flag.
2540  // This will be handled in EndAction.
2541  if (ActionPend())
2542  m_bChgCallFlag = true; // remember change
2543  else if( m_aChgLnk.IsSet() )
2544  {
2545  if( m_bCallChgLnk )
2546  m_aChgLnk.Call(nullptr);
2547  m_bChgCallFlag = false; // reset flag
2548  }
2549 }
2550 
2553 {
2554  OUString aText;
2555  if (GetLayout()->HasMergedParas())
2556  {
2557  SwContentFrame const*const pFrame(GetCurrFrame(false));
2558  if (FrameContainsNode(*pFrame, m_pCurrentCursor->GetMark()->nNode.GetIndex()))
2559  {
2560  OUStringBuffer buf;
2561  SwPosition const*const pStart(m_pCurrentCursor->Start());
2562  SwPosition const*const pEnd(m_pCurrentCursor->End());
2563  for (SwNodeOffset i = pStart->nNode.GetIndex(); i <= pEnd->nNode.GetIndex(); ++i)
2564  {
2565  SwNode const& rNode(*pStart->nNode.GetNodes()[i]);
2566  assert(!rNode.IsEndNode());
2567  if (rNode.IsStartNode())
2568  {
2569  i = rNode.EndOfSectionIndex();
2570  }
2571  else if (rNode.IsTextNode())
2572  {
2573  sal_Int32 const nStart(i == pStart->nNode.GetIndex()
2574  ? pStart->nContent.GetIndex()
2575  : 0);
2576  sal_Int32 const nEnd(i == pEnd->nNode.GetIndex()
2577  ? pEnd->nContent.GetIndex()
2578  : rNode.GetTextNode()->Len());
2579  buf.append(rNode.GetTextNode()->GetExpandText(
2580  GetLayout(),
2581  nStart, nEnd - nStart, false, false, false,
2583 
2584  }
2585  }
2586  aText = buf.makeStringAndClear();
2587  }
2588  }
2589  else if( m_pCurrentCursor->GetPoint()->nNode.GetIndex() ==
2590  m_pCurrentCursor->GetMark()->nNode.GetIndex() )
2591  {
2592  SwTextNode* pTextNd = m_pCurrentCursor->GetNode().GetTextNode();
2593  if( pTextNd )
2594  {
2595  const sal_Int32 nStt = m_pCurrentCursor->Start()->nContent.GetIndex();
2596  aText = pTextNd->GetExpandText(GetLayout(), nStt,
2597  m_pCurrentCursor->End()->nContent.GetIndex() - nStt );
2598  }
2599  }
2600  return aText;
2601 }
2602 
2609 {
2610  if( IsTableMode() ) // not possible in table mode
2611  return 0;
2612 
2613  const SwPosition* pPos = !m_pCurrentCursor->HasMark() ? m_pCurrentCursor->GetPoint()
2614  : bEnd ? m_pCurrentCursor->End() : m_pCurrentCursor->Start();
2615  SwTextNode* pTextNd = pPos->nNode.GetNode().GetTextNode();
2616  if( !pTextNd )
2617  return 0;
2618 
2619  const sal_Int32 nPos = pPos->nContent.GetIndex();
2620  const OUString& rStr = pTextNd->GetText();
2621  sal_Unicode cCh = 0;
2622 
2623  if (((nPos+nOffset) >= 0 ) && (nPos+nOffset) < rStr.getLength())
2624  cCh = rStr[nPos + nOffset];
2625 
2626  return cCh;
2627 }
2628 
2634 bool SwCursorShell::ExtendSelection( bool bEnd, sal_Int32 nCount )
2635 {
2636  if( !m_pCurrentCursor->HasMark() || IsTableMode() )
2637  return false; // no selection
2638 
2639  SwPosition* pPos = bEnd ? m_pCurrentCursor->End() : m_pCurrentCursor->Start();
2640  SwTextNode* pTextNd = pPos->nNode.GetNode().GetTextNode();
2641  assert(pTextNd);
2642 
2643  sal_Int32 nPos = pPos->nContent.GetIndex();
2644  if( bEnd )
2645  {
2646  if ((nPos + nCount) <= pTextNd->GetText().getLength())
2647  nPos = nPos + nCount;
2648  else
2649  return false; // not possible
2650  }
2651  else if( nPos >= nCount )
2652  nPos = nPos - nCount;
2653  else
2654  return false; // not possible anymore
2655 
2656  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
2657 
2658  pPos->nContent = nPos;
2659  UpdateCursor();
2660 
2661  return true;
2662 }
2663 
2669 bool SwCursorShell::SetVisibleCursor( const Point &rPt )
2670 {
2671  CurrShell aCurr( this );
2672  Point aPt( rPt );
2673  SwPosition aPos( *m_pCurrentCursor->GetPoint() );
2675  aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
2676  aTmpState.m_bRealHeight = true;
2677 
2678  const bool bRet = GetLayout()->GetModelPositionForViewPoint( &aPos, aPt /*, &aTmpState*/ );
2679 
2680  SetInFrontOfLabel( false ); // #i27615#
2681 
2682  // show only in TextNodes
2683  SwTextNode* pTextNd = aPos.nNode.GetNode().GetTextNode();
2684  if( !pTextNd )
2685  return false;
2686 
2687  const SwSectionNode* pSectNd = pTextNd->FindSectionNode();
2688  if( pSectNd && (pSectNd->GetSection().IsHiddenFlag() ||
2689  ( !IsReadOnlyAvailable() &&
2690  pSectNd->GetSection().IsProtectFlag())) )
2691  return false;
2692 
2693  std::pair<Point, bool> const tmp(aPt, true);
2694  SwContentFrame *pFrame = pTextNd->getLayoutFrame(GetLayout(), &aPos, &tmp);
2695  if ( Imp()->IsIdleAction() )
2696  pFrame->PrepareCursor();
2697  SwRect aTmp( m_aCharRect );
2698 
2699  pFrame->GetCharRect( m_aCharRect, aPos, &aTmpState );
2700 
2701  // #i10137#
2702  if( aTmp == m_aCharRect && m_pVisibleCursor->IsVisible() )
2703  return true;
2704 
2705  m_pVisibleCursor->Hide(); // always hide visible cursor
2706  if( IsScrollMDI( this, m_aCharRect ))
2707  {
2708  MakeVisible( m_aCharRect );
2709  m_pCurrentCursor->Show(nullptr);
2710  }
2711 
2712  {
2713  if( aTmpState.m_bRealHeight )
2714  m_aCursorHeight = aTmpState.m_aRealHeight;
2715  else
2716  {
2717  m_aCursorHeight.setX(0);
2718  m_aCursorHeight.setY(m_aCharRect.Height());
2719  }
2720 
2721  m_pVisibleCursor->SetDragCursor();
2722  m_pVisibleCursor->Show(); // show again
2723  }
2724  return bRet;
2725 }
2726 
2728 {
2729  return m_pVisibleCursor;
2730 }
2731 
2732 bool SwCursorShell::IsOverReadOnlyPos( const Point& rPt ) const
2733 {
2734  Point aPt( rPt );
2735  SwPaM aPam( *m_pCurrentCursor->GetPoint() );
2736  GetLayout()->GetModelPositionForViewPoint( aPam.GetPoint(), aPt );
2737  // form view
2738  return aPam.HasReadonlySel( GetViewOptions()->IsFormView() );
2739 }
2740 
2745 sal_uInt16 SwCursorShell::GetCursorCnt( bool bAll ) const
2746 {
2747  SwPaM* pTmp = GetCursor()->GetNext();
2748  sal_uInt16 n = (bAll || ( m_pCurrentCursor->HasMark() &&
2749  *m_pCurrentCursor->GetPoint() != *m_pCurrentCursor->GetMark())) ? 1 : 0;
2750  while( pTmp != m_pCurrentCursor )
2751  {
2752  if( bAll || ( pTmp->HasMark() &&
2753  *pTmp->GetPoint() != *pTmp->GetMark()))
2754  ++n;
2755  pTmp = pTmp->GetNext();
2756  }
2757  return n;
2758 }
2759 
2761 {
2762  if( m_pCurrentCursor->GetPoint()->nContent.GetIndex() )
2763  return false;
2764 
2765  // after EndOfIcons comes the content selection (EndNd+StNd+ContentNd)
2766  SwNodeIndex aIdx( GetDoc()->GetNodes().GetEndOfExtras(), 2 );
2767  if( !aIdx.GetNode().IsContentNode() )
2768  GetDoc()->GetNodes().GoNext( &aIdx );
2769  return aIdx == m_pCurrentCursor->GetPoint()->nNode;
2770 }
2771 
2773 {
2774  SwNodeIndex aIdx( GetDoc()->GetNodes().GetEndOfContent(), -1 );
2775  SwContentNode* pCNd = aIdx.GetNode().GetContentNode();
2776  if( !pCNd )
2777  pCNd = SwNodes::GoPrevious( &aIdx );
2778 
2779  return aIdx == m_pCurrentCursor->GetPoint()->nNode &&
2780  pCNd->Len() == m_pCurrentCursor->GetPoint()->nContent.GetIndex();
2781 }
2782 
2791 {
2792  if( !m_pTableCursor )
2793  return false;
2794 
2795  m_pTableCursor->ParkCursor();
2796 
2797  while( m_pCurrentCursor->GetNext() != m_pCurrentCursor )
2798  delete m_pCurrentCursor->GetNext();
2799 
2800  // *always* move cursor's Point and Mark
2801  m_pCurrentCursor->DeleteMark();
2802  *m_pCurrentCursor->GetPoint() = *m_pTableCursor->GetPoint();
2803 
2804  return true;
2805 }
2806 
2807 void SwCursorShell::ParkPams( SwPaM* pDelRg, SwShellCursor** ppDelRing )
2808 {
2809  const SwPosition *pStt = pDelRg->Start(),
2810  *pEnd = pDelRg->End();
2811 
2812  SwPaM *pTmpDel = nullptr, *pTmp = *ppDelRing;
2813 
2814  // search over the whole ring
2815  bool bGoNext;
2816  do {
2817 
2818  if (!pTmp)
2819  break;
2820 
2821  const SwPosition *pTmpStt = pTmp->Start(),
2822  *pTmpEnd = pTmp->End();
2823  // If a SPoint or GetMark are in a cursor area then cancel the old area.
2824  // During comparison keep in mind that End() is outside the area.
2825  if( *pStt <= *pTmpStt )
2826  {
2827  if( *pEnd > *pTmpStt ||
2828  ( *pEnd == *pTmpStt && *pEnd == *pTmpEnd ))
2829  pTmpDel = pTmp;
2830  }
2831  else
2832  if( *pStt < *pTmpEnd )
2833  pTmpDel = pTmp;
2834 
2835  bGoNext = true;
2836  if (pTmpDel) // is the pam in the range -> delete
2837  {
2838  bool bDelete = true;
2839  if( *ppDelRing == pTmpDel )
2840  {
2841  if( *ppDelRing == m_pCurrentCursor )
2842  {
2843  bDelete = GoNextCursor();
2844  if( bDelete )
2845  {
2846  bGoNext = false;
2847  pTmp = pTmp->GetNext();
2848  }
2849  }
2850  else
2851  bDelete = false; // never delete the StackCursor
2852  }
2853 
2854  if( bDelete )
2855  {
2856  if (pTmp == pTmpDel)
2857  pTmp = nullptr;
2858  delete pTmpDel; // invalidate old area
2859  }
2860  else
2861  {
2862  pTmpDel->GetPoint()->nContent.Assign(nullptr, 0);
2863  pTmpDel->GetPoint()->nNode = SwNodeOffset(0);
2864  pTmpDel->DeleteMark();
2865  }
2866  pTmpDel = nullptr;
2867  }
2868  if( bGoNext && pTmp )
2869  pTmp = pTmp->GetNext();
2870 
2871  } while( !bGoNext || *ppDelRing != pTmp );
2872 }
2873 
2874 //TODO: provide documentation
2882 {
2883  SwNode *pNode = &rIdx.GetNode();
2884 
2885  // create a new PaM
2886  SwPaM aNew( *GetCursor()->GetPoint() );
2887  if( pNode->GetStartNode() )
2888  {
2889  pNode = pNode->StartOfSectionNode();
2890  if( pNode->IsTableNode() )
2891  {
2892  // the given node is in a table, thus park cursor to table node
2893  // (outside of the table)
2894  aNew.GetPoint()->nNode = *pNode->StartOfSectionNode();
2895  }
2896  else
2897  // Also on the start node itself. Then we need to request the start
2898  // node always via its end node! (StartOfSelection of StartNode is
2899  // the parent)
2900  aNew.GetPoint()->nNode = *pNode->EndOfSectionNode()->StartOfSectionNode();
2901  }
2902  else
2903  aNew.GetPoint()->nNode = *pNode->StartOfSectionNode();
2904  aNew.SetMark();
2905  aNew.GetPoint()->nNode = *pNode->EndOfSectionNode();
2906 
2907  // take care of all shells
2908  for(SwViewShell& rTmp : GetRingContainer())
2909  {
2910  if( auto pSh = dynamic_cast<SwCursorShell *>(&rTmp))
2911  {
2912  if (pSh->m_pStackCursor)
2913  pSh->ParkPams(&aNew, &pSh->m_pStackCursor);
2914 
2915  pSh->ParkPams( &aNew, &pSh->m_pCurrentCursor );
2916  if( pSh->m_pTableCursor )
2917  {
2918  // set table cursor always to 0 and the current one always to
2919  // the beginning of the table
2920  SwPaM* pTCursor = pSh->GetTableCrs();
2921  SwNode* pTableNd = pTCursor->GetPoint()->nNode.GetNode().FindTableNode();
2922  if ( pTableNd )
2923  {
2924  pTCursor->GetPoint()->nContent.Assign(nullptr, 0);
2925  pTCursor->GetPoint()->nNode = SwNodeOffset(0);
2926  pTCursor->DeleteMark();
2927  pSh->m_pCurrentCursor->GetPoint()->nNode = *pTableNd;
2928  }
2929  }
2930  }
2931  }
2932 }
2933 
2940  : SwViewShell( rShell, pInitWin )
2941  , sw::BroadcastingModify()
2942  , m_pStackCursor( nullptr )
2943  , m_pBlockCursor( nullptr )
2944  , m_pTableCursor( nullptr )
2945  , m_pBoxIdx( nullptr )
2946  , m_pBoxPtr( nullptr )
2947  , m_nUpDownX(0)
2948  , m_nLeftFramePos(0)
2949  , m_nCurrentNode(0)
2950  , m_nCurrentContent(0)
2951  , m_nCurrentNdTyp(SwNodeType::NONE)
2952  , m_nCursorMove( 0 )
2953  , m_eMvState( CursorMoveState::NONE )
2954  , m_eEnhancedTableSel(SwTable::SEARCH_NONE)
2955  , m_nMarkedListLevel( 0 )
2956  , m_oldColFrame(nullptr)
2957 {
2958  CurrShell aCurr( this );
2959  // only keep the position of the current cursor of the copy shell
2960  m_pCurrentCursor = new SwShellCursor( *this, *(rShell.m_pCurrentCursor->GetPoint()) );
2961  m_pCurrentCursor->GetContentNode()->Add( this );
2962 
2965  m_bOverwriteCursor = false;
2967  m_bSVCursorVis = true;
2968  m_bSetCursorInReadOnly = true;
2969  m_pVisibleCursor = new SwVisibleCursor( this );
2971 }
2972 
2975  const SwViewOption *pInitOpt )
2976  : SwViewShell( rDoc, pInitWin, pInitOpt )
2977  , sw::BroadcastingModify()
2978  , m_pStackCursor( nullptr )
2979  , m_pBlockCursor( nullptr )
2980  , m_pTableCursor( nullptr )
2981  , m_pBoxIdx( nullptr )
2982  , m_pBoxPtr( nullptr )
2983  , m_nUpDownX(0)
2984  , m_nLeftFramePos(0)
2985  , m_nCurrentNode(0)
2986  , m_nCurrentContent(0)
2987  , m_nCurrentNdTyp(SwNodeType::NONE)
2988  , m_nCursorMove( 0 )
2989  , m_eMvState( CursorMoveState::NONE ) // state for crsr-travelling - GetModelPositionForViewPoint
2990  , m_eEnhancedTableSel(SwTable::SEARCH_NONE)
2991  , m_nMarkedListLevel( 0 )
2992  , m_oldColFrame(nullptr)
2993 {
2994  CurrShell aCurr( this );
2995  // create initial cursor and set it to first content position
2996  SwNodes& rNds = rDoc.GetNodes();
2997 
2998  SwNodeIndex aNodeIdx( *rNds.GetEndOfContent().StartOfSectionNode() );
2999  SwContentNode* pCNd = rNds.GoNext( &aNodeIdx ); // go to the first ContentNode
3000 
3001  m_pCurrentCursor = new SwShellCursor( *this, SwPosition( aNodeIdx, SwIndex( pCNd, 0 )));
3002 
3003  // Register shell as dependent at current node. As a result all attribute
3004  // changes can be forwarded via the Link.
3005  pCNd->Add( this );
3006 
3009  m_bOverwriteCursor = false;
3011  m_bSVCursorVis = true;
3012  m_bSetCursorInReadOnly = true;
3013 
3014  m_pVisibleCursor = new SwVisibleCursor( this );
3015  m_bMacroExecAllowed = true;
3016 }
3017 
3019 {
3020  // if it is not the last view then at least the field should be updated
3021  if( !unique() )
3023  else
3025 
3026  delete m_pVisibleCursor;
3027  delete m_pBlockCursor;
3028  delete m_pTableCursor;
3029 
3030  // release cursors
3032  delete m_pCurrentCursor->GetNext();
3033  delete m_pCurrentCursor;
3034 
3035  // free stack
3036  if (m_pStackCursor)
3037  {
3038  while (m_pStackCursor->GetNext() != m_pStackCursor)
3039  delete m_pStackCursor->GetNext();
3040  delete m_pStackCursor;
3041  }
3042 
3043  // #i54025# - do not give a HTML parser that might potentially hang as
3044  // a client at the cursor shell the chance to hang itself on a TextNode
3045  EndListeningAll();
3046 }
3047 
3049 {
3050  if( m_pTableCursor )
3051  return m_pTableCursor;
3052  if( m_pBlockCursor && bBlock )
3053  return &m_pBlockCursor->getShellCursor();
3054  return m_pCurrentCursor;
3055 }
3056 
3062 {
3063  if ( IsTableMode() || GetCursorCnt() > 1 )
3064  return true;
3065 
3066  if( HasDrawView() && GetDrawView()->GetMarkedObjectList().GetMarkCount() )
3067  return true;
3068 
3069  SwPaM* pPam = GetCursor();
3070  return pPam->Start()->nNode.GetIndex() + SwNodeOffset(10) <
3071  pPam->End()->nNode.GetIndex();
3072 }
3073 
3075 {
3077  {
3079  }
3081 }
3082 
3085 {
3086  OSL_ENSURE( m_bHasFocus, "no focus but cursor should be made visible?" );
3088  {
3089  SwRect aTmp( m_aCharRect );
3090  tools::Long nDiff = m_aCharRect.Height() - VisArea().Height();
3091  if( nDiff < m_aCursorHeight.getX() )
3092  aTmp.Top( nDiff + m_aCharRect.Top() );
3093  else
3094  {
3095  aTmp.Top( m_aCursorHeight.getX() + m_aCharRect.Top() );
3096  aTmp.Height( m_aCursorHeight.getY() );
3097  }
3098  if( !aTmp.HasArea() )
3099  {
3100  aTmp.AddHeight(1 );
3101  aTmp.AddWidth(1 );
3102  }
3103  MakeVisible( aTmp );
3104  }
3105  else
3106  {
3107  if( m_aCharRect.HasArea() )
3109  else
3110  {
3111  SwRect aTmp( m_aCharRect );
3112  aTmp.AddHeight(1 );
3113  aTmp.AddWidth(1 );
3114  MakeVisible( aTmp );
3115  }
3116  }
3117 }
3118 
3121 {
3122  if( m_pTableCursor )
3123  {
3124  assert(!"Did not remove table selection!");
3125  return false;
3126  }
3127 
3128  // #i45129# - everything is allowed in UI-readonly
3129  if( !m_bAllProtect && GetDoc()->GetDocShell() &&
3130  GetDoc()->GetDocShell()->IsReadOnlyUI() )
3131  return true;
3132 
3133  if( m_pCurrentCursor->HasMark() )
3134  ClearMark();
3135 
3136  // first check for frames
3138  SwNodeOffset nNdIdx = rNdIdx.GetIndex(); // keep backup
3139  SwNodes& rNds = mxDoc->GetNodes();
3140  SwContentNode* pCNd = rNdIdx.GetNode().GetContentNode();
3141  const SwContentFrame * pFrame;
3142 
3143  if (pCNd && nullptr != (pFrame = pCNd->getLayoutFrame(GetLayout(), m_pCurrentCursor->GetPoint())) &&
3144  !IsReadOnlyAvailable() && pFrame->IsProtected() &&
3145  nNdIdx < rNds.GetEndOfExtras().GetIndex() )
3146  {
3147  // skip protected frame
3148  SwPaM aPam( *m_pCurrentCursor->GetPoint() );
3149  aPam.SetMark();
3150  aPam.GetMark()->nNode = rNds.GetEndOfContent();
3151  aPam.GetPoint()->nNode = *pCNd->EndOfSectionNode();
3152 
3153  bool bFirst = false;
3154  if( nullptr == (pCNd = ::GetNode( aPam, bFirst, fnMoveForward )))
3155  {
3156  aPam.GetMark()->nNode = *rNds.GetEndOfPostIts().StartOfSectionNode();
3157  pCNd = ::GetNode( aPam, bFirst, fnMoveBackward );
3158  }
3159 
3160  if( !pCNd ) // should *never* happen
3161  {
3162  rNdIdx = nNdIdx; // back to old node
3163  return false;
3164  }
3165  *m_pCurrentCursor->GetPoint() = *aPam.GetPoint();
3166  }
3167  else if( bOnlyText && pCNd && pCNd->IsNoTextNode() )
3168  {
3169  // set to beginning of document
3170  rNdIdx = mxDoc->GetNodes().GetEndOfExtras();
3171  m_pCurrentCursor->GetPoint()->nContent.Assign( mxDoc->GetNodes().GoNext(
3172  &rNdIdx ), 0 );
3173  nNdIdx = rNdIdx.GetIndex();
3174  }
3175 
3176  bool bOk = true;
3177 
3178  // #i9059# cursor may not stand in protected cells
3179  // (unless cursor in protected areas is OK.)
3180  const SwTableNode* pTableNode = rNdIdx.GetNode().FindTableNode();
3181  if( !IsReadOnlyAvailable() &&
3182  pTableNode != nullptr && rNdIdx.GetNode().IsProtect() )
3183  {
3184  // we're in a table, and we're in a protected area, so we're
3185  // probably in a protected cell.
3186 
3187  // move forward into non-protected area.
3188  SwPaM aPam( rNdIdx.GetNode(), 0 );
3189  while( aPam.GetNode().IsProtect() &&
3190  aPam.Move( fnMoveForward, GoInContent ) )
3191  ; // nothing to do in the loop; the aPam.Move does the moving!
3192 
3193  // didn't work? then go backwards!
3194  if( aPam.GetNode().IsProtect() )
3195  {
3196  SwPaM aTmpPaM( rNdIdx.GetNode(), 0 );
3197  aPam = aTmpPaM;
3198  while( aPam.GetNode().IsProtect() &&
3199  aPam.Move( fnMoveBackward, GoInContent ) )
3200  ; // nothing to do in the loop; the aPam.Move does the moving!
3201  }
3202 
3203  // if we're successful, set the new position
3204  if( ! aPam.GetNode().IsProtect() )
3205  {
3206  *m_pCurrentCursor->GetPoint() = *aPam.GetPoint();
3207  }
3208  }
3209 
3210  // in a protected frame
3211  const SwSectionNode* pSectNd = rNdIdx.GetNode().FindSectionNode();
3212  if( pSectNd && ( pSectNd->GetSection().IsHiddenFlag() ||
3213  ( !IsReadOnlyAvailable() &&
3214  pSectNd->GetSection().IsProtectFlag() )) )
3215  {
3216  bOk = false;
3217  bool bGoNextSection = true;
3218  for( int nLoopCnt = 0; !bOk && nLoopCnt < 2; ++nLoopCnt )
3219  {
3220  bool bContinue;
3221  do {
3222  bContinue = false;
3223  for (;;)
3224  {
3225  if (bGoNextSection)
3226  pCNd = rNds.GoNextSection( &rNdIdx,
3227  true, !IsReadOnlyAvailable() );
3228  else
3229  pCNd = SwNodes::GoPrevSection( &rNdIdx,
3230  true, !IsReadOnlyAvailable() );
3231  if ( pCNd == nullptr) break;
3232  // moved inside a table -> check if it is protected
3233  if( pCNd->FindTableNode() )
3234  {
3235  SwCallLink aTmp( *this );
3236  SwCursorSaveState aSaveState( *m_pCurrentCursor );
3237  aTmp.m_nNodeType = SwNodeType::NONE; // don't do anything in DTOR
3238  if( !m_pCurrentCursor->IsInProtectTable( true ) )
3239  {
3240  const SwSectionNode* pSNd = pCNd->FindSectionNode();
3241  if( !pSNd || !pSNd->GetSection().IsHiddenFlag()
3242  || (!IsReadOnlyAvailable() &&
3243  pSNd->GetSection().IsProtectFlag() ))
3244  {
3245  bOk = true;
3246  break; // found non-protected cell
3247  }
3248  continue; // continue search
3249  }
3250  }
3251  else
3252  {
3253  bOk = true;
3254  break; // found non-protected cell
3255  }
3256  }
3257 
3258  if( bOk && rNdIdx.GetIndex() < rNds.GetEndOfExtras().GetIndex() )
3259  {
3260  // also check for Fly - might be protected as well
3261  pFrame = pCNd->getLayoutFrame(GetLayout(), nullptr, nullptr);
3262  if (nullptr == pFrame ||
3263  ( !IsReadOnlyAvailable() && pFrame->IsProtected() ) ||
3264  ( bOnlyText && pCNd->IsNoTextNode() ) )
3265  {
3266  // continue search
3267  bOk = false;
3268  bContinue = true;
3269  }
3270  }
3271  } while( bContinue );
3272 
3273  if( !bOk )
3274  {
3275  if( !nLoopCnt )
3276  bGoNextSection = false;
3277  rNdIdx = nNdIdx;
3278  }
3279  }
3280  }
3281  if( bOk )
3282  {
3283  pCNd = rNdIdx.GetNode().GetContentNode();
3284  const sal_Int32 nContent = rNdIdx.GetIndex() < nNdIdx ? pCNd->Len() : 0;
3285  m_pCurrentCursor->GetPoint()->nContent.Assign( pCNd, nContent );
3286  }
3287  else
3288  {
3289  pCNd = rNdIdx.GetNode().GetContentNode();
3290  // if cursor in hidden frame, always move it
3291  if (!pCNd || !pCNd->getLayoutFrame(GetLayout(), nullptr, nullptr))
3292  {
3294  aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
3296  &aTmpState );
3297  }
3298  }
3299  return bOk;
3300 }
3301 
3303 {
3304  if ( GetViewOptions()->IsReadonly() ||
3305  GetViewOptions()->IsFormView() /* Formula view */ )
3306  {
3307  SwFrame *pFrame = GetCurrFrame( false );
3308  const SwFlyFrame* pFly;
3309  const SwSection* pSection;
3310 
3311  if( pFrame && pFrame->IsInFly() &&
3312  (pFly = pFrame->FindFlyFrame())->GetFormat()->GetEditInReadonly().GetValue() &&
3313  pFly->Lower() &&
3314  !pFly->Lower()->IsNoTextFrame() &&
3316  {
3317  return false;
3318  }
3319  // edit in readonly sections
3320  else if ( pFrame && pFrame->IsInSct() &&
3321  nullptr != ( pSection = pFrame->FindSctFrame()->GetSection() ) &&
3322  pSection->IsEditInReadonlyFlag() )
3323  {
3324  return false;
3325  }
3326  else if ( !IsMultiSelection() && CursorInsideInputField() )
3327  {
3328  return false;
3329  }
3330 
3331  return true;
3332  }
3333  return false;
3334 }
3335 
3338 {
3339  // *never* switch in GlobalDoc
3340  if( (!GetDoc()->GetDocShell() ||
3341  dynamic_cast<const SwGlobalDocShell*>(GetDoc()->GetDocShell()) == nullptr ) &&
3342  bFlag != m_bSetCursorInReadOnly )
3343  {
3344  // If the flag is switched off then all selections need to be
3345  // invalidated. Otherwise we would trust that nothing protected is selected.
3346  if( !bFlag )
3347  {
3348  ClearMark();
3349  }
3350  m_bSetCursorInReadOnly = bFlag;
3351  UpdateCursor();
3352  }
3353 }
3354 
3356 {
3357  if (GetViewOptions()->IsShowOutlineContentVisibilityButton())
3358  {
3359  // Treat selections that span over start or end of paragraph of an outline node
3360  // with folded outline content as read-only.
3361  SwWrtShell* pWrtSh = GetDoc()->GetDocShell()->GetWrtShell();
3362  if (pWrtSh)
3363  {
3364  for(const SwPaM& rPaM : GetCursor()->GetRingContainer())
3365  {
3366  SwPaM aPaM(*rPaM.GetMark(), *rPaM.GetPoint());
3367  aPaM.Normalize();
3368  SwNodeIndex aPointIdx(aPaM.GetPoint()->nNode.GetNode());
3369  SwNodeIndex aMarkIdx(aPaM.GetMark()->nNode.GetNode());
3370  if (aPointIdx == aMarkIdx)
3371  continue;
3372  // If any nodes in PaM are folded outline content nodes, then set read-only.
3374  for (SwNodeIndex aIdx = aPointIdx; aIdx <= aMarkIdx; aIdx++)
3375  {
3376  if (GetDoc()->GetNodes().GetOutLineNds().Seek_Entry(&(aIdx.GetNode()), &nPos) &&
3377  !pWrtSh->GetAttrOutlineContentVisible(nPos))
3378  return true;
3379  }
3380  }
3381  }
3382  }
3383  bool bRet = false;
3384  // If protected area is to be ignored, then selections are never read-only.
3385  if ((IsReadOnlyAvailable() || GetViewOptions()->IsFormView() ||
3386  GetDoc()->GetDocumentSettingManager().get( DocumentSettingId::PROTECT_FORM )) &&
3388  {
3389  if ( m_pTableCursor != nullptr )
3390  {
3392  || m_pTableCursor->HasReadonlySel( GetViewOptions()->IsFormView() );
3393  }
3394  else
3395  {
3396  for(const SwPaM& rCursor : m_pCurrentCursor->GetRingContainer())
3397  {
3398  if( rCursor.HasReadonlySel( GetViewOptions()->IsFormView() ) )
3399  {
3400  bRet = true;
3401  break;
3402  }
3403  }
3404  }
3405  }
3406  return bRet;
3407 }
3408 
3410 {
3411  bool bRet = false;
3412 
3415  {
3416  sal_Int32 nStt = m_pCurrentCursor->GetPoint()->nContent.GetIndex();
3417  sal_Int32 nEnd = m_pCurrentCursor->GetMark()->nContent.GetIndex();
3418  if( nStt > nEnd )
3419  {
3420  sal_Int32 nTmp = nStt;
3421  nStt = nEnd;
3422  nEnd = nTmp;
3423  }
3425  bRet = pCNd && !nStt && nEnd == pCNd->Len();
3426  }
3427  return bRet;
3428 }
3429 
3431 {
3432  SwPosition aPos( *m_pCurrentCursor->GetPoint() );
3433  Point aPt( pPt ? *pPt : m_pCurrentCursor->GetPtPos() );
3434  if( pPt )
3435  {
3437  aTmpState.m_bSetInReadOnly = IsReadOnlyAvailable();
3438 
3439  GetLayout()->GetModelPositionForViewPoint( &aPos, aPt, &aTmpState );
3440  }
3441 
3442  return mxDoc->GetTextDirection( aPos, &aPt );
3443 }
3444 
3445 bool SwCursorShell::IsInVerticalText( const Point* pPt ) const
3446 {
3447  const SvxFrameDirection nDir = GetTextDirection( pPt );
3448  return SvxFrameDirection::Vertical_RL_TB == nDir || SvxFrameDirection::Vertical_LR_TB == nDir
3449  || nDir == SvxFrameDirection::Vertical_LR_BT;
3450 }
3451 
3453 {
3454  const SvxFrameDirection nDir = GetTextDirection();
3455  // GetTextDirection uses SvxFrameDirection::Vertical_LR_TB to indicate RTL in
3456  // vertical environment
3457  return SvxFrameDirection::Vertical_LR_TB == nDir || SvxFrameDirection::Horizontal_RL_TB == nDir;
3458 }
3459 
3463 {
3464  bool bRet = false;
3465  if ( !GetViewOptions()->IsShowHiddenChar() && !m_pCurrentCursor->HasMark() )
3466  {
3468  const SwTextNode* pNode = rPt.nNode.GetNode().GetTextNode();
3469  if ( pNode )
3470  {
3471  const sal_Int32 nPos = rPt.nContent.GetIndex();
3472 
3473  // check if nPos is in hidden range
3474  sal_Int32 nHiddenStart;
3475  sal_Int32 nHiddenEnd;
3476  SwScriptInfo::GetBoundsOfHiddenRange( *pNode, nPos, nHiddenStart, nHiddenEnd );
3477  if ( COMPLETE_STRING != nHiddenStart )
3478  {
3479  // make selection:
3481  m_pCurrentCursor->GetMark()->nContent = nHiddenEnd;
3482  bRet = true;
3483  }
3484  }
3485  }
3486 
3487  return bRet;
3488 }
3489 
3491  bool bSearchInNotes,
3492  SwDocPositions eStart, SwDocPositions eEnd,
3493  bool& bCancel,
3494  FindRanges eRng,
3495  bool bReplace )
3496 {
3497  if( m_pTableCursor )
3498  GetCursor();
3499  delete m_pTableCursor;
3500  m_pTableCursor = nullptr;
3501  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
3502  sal_uLong nRet = m_pCurrentCursor->Find_Text(rSearchOpt, bSearchInNotes, eStart, eEnd,
3503  bCancel, eRng, bReplace, GetLayout());
3504  if( nRet || bCancel )
3505  UpdateCursor();
3506  return nRet;
3507 }
3508 
3510  SwDocPositions eStart, SwDocPositions eEnd,
3511  bool& bCancel,
3512  FindRanges eRng,
3513  const SwTextFormatColl* pReplFormat )
3514 {
3515  if( m_pTableCursor )
3516  GetCursor();
3517  delete m_pTableCursor;
3518  m_pTableCursor = nullptr;
3519  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
3520  sal_uLong nRet = m_pCurrentCursor->FindFormat(rFormatColl, eStart, eEnd, bCancel, eRng,
3521  pReplFormat );
3522  if( nRet )
3523  UpdateCursor();
3524  return nRet;
3525 }
3526 
3528  bool bNoCollections,
3529  SwDocPositions eStart, SwDocPositions eEnd,
3530  bool& bCancel,
3531  FindRanges eRng,
3532  const i18nutil::SearchOptions2* pSearchOpt,
3533  const SfxItemSet* rReplSet )
3534 {
3535  if( m_pTableCursor )
3536  GetCursor();
3537  delete m_pTableCursor;
3538  m_pTableCursor = nullptr;
3539  SwCallLink aLk( *this ); // watch Cursor-Moves; call Link if needed
3540  sal_uLong nRet = m_pCurrentCursor->FindAttrs(rSet, bNoCollections, eStart, eEnd,
3541  bCancel, eRng, pSearchOpt, rReplSet, GetLayout());
3542  if( nRet )
3543  UpdateCursor();
3544  return nRet;
3545 }
3546 
3547 void SwCursorShell::SetSelection( const SwPaM& rCursor )
3548 {
3549  StartAction();
3550  SwCursor* pCursor = GetCursor();
3551  *pCursor->GetPoint() = *rCursor.GetPoint();
3552  if(rCursor.GetNext() != &rCursor)
3553  {
3554  const SwPaM *_pStartCursor = rCursor.GetNext();
3555  do
3556  {
3557  SwPaM* pCurrentCursor = CreateCursor();
3558  *pCurrentCursor->GetPoint() = *_pStartCursor->GetPoint();
3559  if(_pStartCursor->HasMark())
3560  {
3561  pCurrentCursor->SetMark();
3562  *pCurrentCursor->GetMark() = *_pStartCursor->GetMark();
3563  }
3564  } while( (_pStartCursor = _pStartCursor->GetNext()) != &rCursor );
3565  }
3566  // CreateCursor() adds a copy of current cursor after current, and then deletes mark of current
3567  // cursor; therefore set current cursor's mark only after creating all other cursors
3568  if (rCursor.HasMark())
3569  {
3570  pCursor->SetMark();
3571  *pCursor->GetMark() = *rCursor.GetMark();
3572  }
3573  EndAction();
3574 }
3575 
3576 static const SwStartNode* lcl_NodeContext( const SwNode& rNode )
3577 {
3578  const SwStartNode *pRet = rNode.StartOfSectionNode();
3579  while( pRet->IsSectionNode() || pRet->IsTableNode() ||
3581  {
3582  pRet = pRet->StartOfSectionNode();
3583  }
3584  return pRet;
3585 }
3586 
3593 bool sw_PosOk(const SwPosition & aPos)
3594 {
3595  return nullptr != aPos.nNode.GetNode().GetContentNode() &&
3596  aPos.nContent.GetIdxReg();
3597 }
3598 
3605 static bool lcl_CursorOk(SwPaM & aPam)
3606 {
3607  return sw_PosOk(*aPam.GetPoint()) && (! aPam.HasMark()
3608  || sw_PosOk(*aPam.GetMark()));
3609 }
3610 
3612 {
3613  // start of the ring
3614  SwPaM * pStartCursor = GetCursor();
3615  // start loop with second entry of the ring
3616  SwPaM * pCursor = pStartCursor->GetNext();
3617  SwPaM * pTmpCursor;
3618  bool bChanged = false;
3619 
3620  // For all entries in the ring except the start entry delete the entry if
3621  // it is invalid.
3622  while (pCursor != pStartCursor)
3623  {
3624  pTmpCursor = pCursor->GetNext();
3625  if ( ! lcl_CursorOk(*pCursor))
3626  {
3627  delete pCursor;
3628  bChanged = true;
3629  }
3630  pCursor = pTmpCursor;
3631  }
3632 
3633  if( pStartCursor->HasMark() && !sw_PosOk( *pStartCursor->GetMark() ) )
3634  {
3635  pStartCursor->DeleteMark();
3636  bChanged = true;
3637  }
3638  if( !sw_PosOk( *pStartCursor->GetPoint() ) )
3639  {
3640  SwNodes & aNodes = GetDoc()->GetNodes();
3641  const SwNode* pStart = lcl_NodeContext( pStartCursor->GetPoint()->nNode.GetNode() );
3642  SwNodeIndex aIdx( pStartCursor->GetPoint()->nNode );
3643  SwNode * pNode = SwNodes::GoPrevious(&aIdx);
3644  if( pNode == nullptr || lcl_NodeContext( *pNode ) != pStart )
3645  aNodes.GoNext( &aIdx );
3646  if( pNode == nullptr || lcl_NodeContext( *pNode ) != pStart )
3647  {
3648  // If the start entry of the ring is invalid replace it with a
3649  // cursor pointing to the beginning of the first content node in the
3650  // document.
3651  aIdx = *(aNodes.GetEndOfContent().StartOfSectionNode());
3652  pNode = aNodes.GoNext( &aIdx );
3653  }
3654  bool bFound = (pNode != nullptr);
3655 
3656  assert(bFound);
3657 
3658  if (bFound)
3659  {
3660  SwPaM aTmpPam(*pNode);
3661  *pStartCursor = aTmpPam;
3662  }
3663 
3664  bChanged = true;
3665  }
3666 
3667  // If at least one of the cursors in the ring have been deleted or replaced,
3668  // remove the table cursor.
3669  if (m_pTableCursor != nullptr && bChanged)
3671 }
3672 
3674 {
3675  OUString aResult;
3676 
3677  if (IsMultiSelection())
3678  aResult += SwResId(STR_MULTISEL);
3679  else
3680  aResult = SwDoc::GetPaMDescr(*GetCursor());
3681 
3682  return aResult;
3683 }
3684 
3686 {
3687  (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SwCursorShell"));
3688 
3689  SwViewShell::dumpAsXml(pWriter);
3690 
3691  (void)xmlTextWriterStartElement(pWriter, BAD_CAST("m_pCurrentCursor"));
3692  for (const SwPaM& rPaM : m_pCurrentCursor->GetRingContainer())
3693  rPaM.dumpAsXml(pWriter);
3694  (void)xmlTextWriterEndElement(pWriter);
3695 
3696  (void)xmlTextWriterEndElement(pWriter);
3697 }
3698 
3699 static void lcl_FillRecognizerData( std::vector< OUString >& rSmartTagTypes,
3700  uno::Sequence< uno::Reference< container::XStringKeyMap > >& rStringKeyMaps,
3701  const SwWrongList& rSmartTagList, sal_Int32 nCurrent )
3702 {
3703  // Insert smart tag information
3704  std::vector< uno::Reference< container::XStringKeyMap > > aStringKeyMaps;
3705 
3706  for ( sal_uInt16 i = 0; i < rSmartTagList.Count(); ++i )
3707  {
3708  const sal_Int32 nSTPos = rSmartTagList.Pos( i );
3709  const sal_Int32 nSTLen = rSmartTagList.Len( i );
3710 
3711  if ( nSTPos <= nCurrent && nCurrent < nSTPos + nSTLen )
3712  {
3713  const SwWrongArea* pArea = rSmartTagList.GetElement( i );
3714  if ( pArea )
3715  {
3716  rSmartTagTypes.push_back( pArea->maType );
3717  aStringKeyMaps.push_back( pArea->mxPropertyBag );
3718  }
3719  }
3720  }
3721 
3722  if ( !rSmartTagTypes.empty() )
3723  {
3724  rStringKeyMaps = comphelper::containerToSequence(aStringKeyMaps);
3725  }
3726 }
3727 
3728 static void lcl_FillTextRange( uno::Reference<text::XTextRange>& rRange,
3729  SwTextNode& rNode, sal_Int32 nBegin, sal_Int32 nLen )
3730 {
3731  // create SwPosition for nStartIndex
3732  SwIndex aIndex( &rNode, nBegin );
3733  SwPosition aStartPos( rNode, aIndex );
3734 
3735  // create SwPosition for nEndIndex
3736  SwPosition aEndPos( aStartPos );
3737  aEndPos.nContent = nBegin + nLen;
3738 
3739  const uno::Reference<text::XTextRange> xRange =
3740  SwXTextRange::CreateXTextRange(rNode.GetDoc(), aStartPos, &aEndPos);
3741 
3742  rRange = xRange;
3743 }
3744 
3745 void SwCursorShell::GetSmartTagTerm( std::vector< OUString >& rSmartTagTypes,
3746  uno::Sequence< uno::Reference< container::XStringKeyMap > >& rStringKeyMaps,
3747  uno::Reference< text::XTextRange>& rRange ) const
3748 {
3749  if ( !SwSmartTagMgr::Get().IsSmartTagsEnabled() )
3750  return;
3751 
3752  SwPaM* pCursor = GetCursor();
3753  SwPosition aPos( *pCursor->GetPoint() );
3754  SwTextNode *pNode = aPos.nNode.GetNode().GetTextNode();
3755  if ( !pNode || pNode->IsInProtectSect() )
3756  return;
3757 
3758  const SwWrongList *pSmartTagList = pNode->GetSmartTags();
3759  if ( !pSmartTagList )
3760  return;
3761 
3762  sal_Int32 nCurrent = aPos.nContent.GetIndex();
3763  sal_Int32 nBegin = nCurrent;
3764  sal_Int32 nLen = 1;
3765 
3766  if (!pSmartTagList->InWrongWord(nBegin, nLen) || pNode->IsSymbolAt(nBegin))
3767  return;
3768 
3769  const sal_uInt16 nIndex = pSmartTagList->GetWrongPos( nBegin );
3770  const SwWrongList* pSubList = pSmartTagList->SubList( nIndex );
3771  if ( pSubList )
3772  {
3773  pSmartTagList = pSubList;
3774  nCurrent = 0;
3775  }
3776 
3777  lcl_FillRecognizerData( rSmartTagTypes, rStringKeyMaps, *pSmartTagList, nCurrent );
3778  lcl_FillTextRange( rRange, *pNode, nBegin, nLen );
3779 }
3780 
3781 // see also SwEditShell::GetCorrection( const Point* pPt, SwRect& rSelectRect )
3782 void SwCursorShell::GetSmartTagRect( const Point& rPt, SwRect& rSelectRect )
3783 {
3784  SwPaM* pCursor = GetCursor();
3785  SwPosition aPos( *pCursor->GetPoint() );
3786  Point aPt( rPt );
3788  SwSpecialPos aSpecialPos;
3789  eTmpState.m_pSpecialPos = &aSpecialPos;
3790  SwTextNode *pNode;
3791  const SwWrongList *pSmartTagList;
3792 
3793  if( !GetLayout()->GetModelPositionForViewPoint( &aPos, aPt, &eTmpState ) )
3794  return;
3795  pNode = aPos.nNode.GetNode().GetTextNode();
3796  if( !pNode )
3797  return;
3798  pSmartTagList = pNode->GetSmartTags();
3799  if( !pSmartTagList )
3800  return;
3801  if( pNode->IsInProtectSect() )
3802  return;
3803 
3804  sal_Int32 nBegin = aPos.nContent.GetIndex();
3805  sal_Int32 nLen = 1;
3806 
3807  if (!pSmartTagList->InWrongWord(nBegin, nLen) || pNode->IsSymbolAt(nBegin))
3808  return;
3809 
3810  // get smarttag word
3811  OUString aText( pNode->GetText().copy(nBegin, nLen) );
3812 
3813  //save the start and end positions of the line and the starting point
3814  Push();
3815  LeftMargin();
3816  const sal_Int32 nLineStart = GetCursor()->GetPoint()->nContent.GetIndex();
3817  RightMargin();
3818  const sal_Int32 nLineEnd = GetCursor()->GetPoint()->nContent.GetIndex();
3820 
3821  // make sure the selection build later from the data below does not
3822  // include "in word" character to the left and right in order to
3823  // preserve those. Therefore count those "in words" in order to
3824  // modify the selection accordingly.
3825  const sal_Unicode* pChar = aText.getStr();
3826  sal_Int32 nLeft = 0;
3827  while (*pChar++ == CH_TXTATR_INWORD)
3828  ++nLeft;
3829  pChar = aText.getLength() ? aText.getStr() + aText.getLength() - 1 : nullptr;
3830  sal_Int32 nRight = 0;
3831  while (pChar && *pChar-- == CH_TXTATR_INWORD)
3832  ++nRight;
3833 
3834  aPos.nContent = nBegin + nLeft;
3835  pCursor = GetCursor();
3836  *pCursor->GetPoint() = aPos;
3837  pCursor->SetMark();
3838  ExtendSelection( true, nLen - nLeft - nRight );
3839  // do not determine the rectangle in the current line
3840  const sal_Int32 nWordStart = (nBegin + nLeft) < nLineStart ? nLineStart : nBegin + nLeft;
3841  // take one less than the line end - otherwise the next line would
3842  // be calculated
3843  const sal_Int32 nWordEnd = std::min(nBegin + nLen - nLeft - nRight, nLineEnd);
3844  Push();
3845  pCursor->DeleteMark();
3846  SwIndex& rContent = GetCursor()->GetPoint()->nContent;
3847  rContent = nWordStart;
3848  SwRect aStartRect;
3849  SwCursorMoveState aState;
3850  aState.m_bRealWidth = true;
3851  SwContentNode* pContentNode = pCursor->GetContentNode();
3852  std::pair<Point, bool> const tmp(rPt, false);
3853  SwContentFrame *pContentFrame = pContentNode->getLayoutFrame(
3854  GetLayout(), pCursor->GetPoint(), &tmp);
3855 
3856  pContentFrame->GetCharRect( aStartRect, *pCursor->GetPoint(), &aState );
3857  rContent = nWordEnd - 1;
3858  SwRect aEndRect;
3859  pContentFrame->GetCharRect( aEndRect, *pCursor->GetPoint(),&aState );
3860  rSelectRect = aStartRect.Union( aEndRect );
3862 }
3863 
3864 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SAL_DLLPRIVATE void MarkListLevel(const OUString &sListId, const int nLevel)
Mark a certain list level of a certain list.
Definition: crsrsh.cxx:389
bool SttEndDoc(bool bSttDoc)
Definition: swcrsr.cxx:2170
sal_Int32 Pos(sal_uInt16 nIdx) const
Definition: wrong.hxx:318
bool m_bSVCursorVis
SV-Cursor visible/invisible.
Definition: crsrsh.hxx:214
SwSectionNode * FindSectionNode()
Search section node, in which it is.
Definition: ndsect.cxx:985
const SwEndNode * EndOfSectionNode() const
Definition: node.hxx:692
Starts a section of nodes in the document model.
Definition: node.hxx:313
SwNodeOffset min(const SwNodeOffset &a, const SwNodeOffset &b)
Definition: nodeoffset.hxx:35
bool GotoPage(sal_uInt16 nPage)
Definition: crsrsh.cxx:1188
bool MovePara(SwWhichPara, SwMoveFnCollection const &)
Definition: swcrsr.cxx:2295
SwVisibleCursor * m_pVisibleCursor
the visible cursor
Definition: crsrsh.hxx:183
Base class of the Writer layout elements.
Definition: frame.hxx:314
Represents the visualization of a paragraph.
Definition: txtfrm.hxx:162
virtual sal_Int32 Len() const
Definition: node.cxx:1243
static void notifyOtherViews(const SfxViewShell *pThisView, int nType, std::string_view rKey, const OString &rPayload)
void DeleteMark()
Definition: pam.hxx:178
void KillPams()
Definition: crsrsh.cxx:1022
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: viewsh.cxx:142
SwMoveFnCollection const & fnParaEnd
Definition: paminit.cxx:47
SAL_DLLPRIVATE void UpdateCursor(sal_uInt16 eFlags=SwCursorShell::SCROLLWIN|SwCursorShell::CHKRANGE, bool bIdleEnd=false)
Definition: crsrsh.cxx:1573
SwNode & GetNode(bool bPoint=true) const
Definition: pam.hxx:224
SwNode & GetEndOfAutotext() const
Section for all Flys/Header/Footers.
Definition: ndarr.hxx:155
SwShellCursor * m_pCurrentCursor
current cursor
Definition: crsrsh.hxx:181
sal_Int32 nIndex
bool GoInContent(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:968
void Add(SwClient *pDepend)
Definition: calbck.cxx:172
bool IsFollow() const
Definition: flowfrm.hxx:166
sal_uLong Find_Text(const i18nutil::SearchOptions2 &rSearchOpt, bool bSearchInNotes, SwDocPositions eStart, SwDocPositions eEnd, bool &bCancel, FindRanges eRng, bool bReplace=false)
Definition: crsrsh.cxx:3490
static void lcl_CheckHiddenPara(SwPosition &rPos)
Try to set the cursor to the next visible content node.
Definition: crsrsh.cxx:1532
Represents the style of a paragraph.
Definition: fmtcol.hxx:56
bool IsInVerticalText(const Point *pPt=nullptr) const
Definition: crsrsh.cxx:3445
size_t GetMarkCount() const
Marks a position in the document model.
Definition: pam.hxx:36
void GoNextPrevCursorSetSearchLabel(const bool bNext)
Definition: crsrsh.cxx:1394
bool m_bHasFocus
Shell is "active" in a window.
Definition: crsrsh.hxx:213
bool IsInProtectTable(bool bMove=false, bool bChgCursor=true)
Definition: swcrsr.cxx:568
bool IsSectionNode() const
Definition: node.hxx:654
sal_uInt16 GetWhich() const
Definition: calbck.hxx:74
bool IsMultiSelection() const
Definition: pam.hxx:273
SwContentNode * GetNode(SwPaM &rPam, bool &rbFirst, SwMoveFnCollection const &fnMove, bool const bInReadOnly, SwRootFrame const *const i_pLayout)
This function returns the next node in direction of search.
Definition: pam.cxx:821
SdrView * GetDrawView()
Definition: vnew.cxx:373
bool IsInFly() const
Definition: frame.hxx:961
SwRect & Union(const SwRect &rRect)
Definition: swrect.cxx:35
virtual void updateCursorPosition(const SwPosition &rNewPos)=0
Update cursor position reacts to a change of the current input cursor As long as the cursor in inside...
bool IsInSct() const
Definition: frame.hxx:967
static SwFrame * lcl_IsInHeaderFooter(const SwNodeIndex &rIdx, Point &rPt)
Definition: crsrsh.cxx:734
SAL_DLLPRIVATE bool UpDown(bool, sal_uInt16)
Definition: crsrsh.cxx:503
bool m_bRealHeight
should the real height be calculated?
Definition: crstate.hxx:141
const OUString & GetText() const
Definition: ndtxt.hxx:218
OUString getPageRectangles()
Implementation of lok::Document::getPartPageRectangles() for Writer.
Definition: crsrsh.cxx:1298
virtual const SwRootFrame * GetCurrentLayout() const =0
static const SwStartNode * lcl_NodeContext(const SwNode &rNode)
Definition: crsrsh.cxx:3576
bool MoveSection(SwWhichSection, SwMoveFnCollection const &)
Definition: swcrsr.cxx:2334
sal_uInt16 GetNextPrevPageNum(bool bNext=true)
Definition: crsrsh.cxx:1253
bool GoNextCursor()
go to the next SSelection
Definition: crsrsh.cxx:1357
bool SttEndDoc(bool bStt)
Definition: crsrsh.cxx:574
ScopedJsonWriterStruct startStruct()
bool m_bInCMvVisportChgd
Flag for CursorMoves.
Definition: crsrsh.hxx:224
SwDocShell * GetDocShell()
Definition: doc.hxx:1351
constexpr TypedWhichId< SwFormatChg > RES_FMT_CHG(162)
void ClearTableBoxContent()
Definition: trvltbl.cxx:909
static void lcl_FillRecognizerData(std::vector< OUString > &rSmartTagTypes, uno::Sequence< uno::Reference< container::XStringKeyMap > > &rStringKeyMaps, const SwWrongList &rSmartTagList, sal_Int32 nCurrent)
Definition: crsrsh.cxx:3699
constexpr TypedWhichId< SwMsgPoolItem > RES_GRAPHIC_SWAPIN(186)
check overlapping PaMs
Definition: crsrsh.hxx:160
void SetStyleSettings(const StyleSettings &rSet)
bool IsCursorInFootnote() const
Definition: crsrsh.cxx:1151
const SwTable * GetTable() const
Definition: tabfrm.hxx:158
bool IsAtLeftRightMargin(SwRootFrame const &rLayout, bool bLeftMargin, bool bAPI) const
Definition: swcrsr.cxx:2149
void Left(const tools::Long nLeft)
Definition: swrect.hxx:197
SwNodeIndex nNode
Definition: pam.hxx:38
SwVisibleCursor * GetVisibleCursor() const
Definition: crsrsh.cxx:2727
bool IsTableMode() const
Definition: crsrsh.hxx:648
bool IsSttPara() const
Definition: crsrsh.cxx:1095
keep Up/Down on columns
Definition: crsrsh.hxx:158
SwShellCursor & getShellCursor()
Access to the shell cursor.
Definition: BlockCursor.cxx:25
void UpdateCursorPos()
Set the cursor back into content.
Definition: crsrsh.cxx:1491
const SwRect & GetAnyCurRect(CurRectType eType, const Point *pPt=nullptr, const css::uno::Reference< css::embed::XEmbeddedObject > &=css::uno::Reference< css::embed::XEmbeddedObject >()) const
Definition: fews.cxx:90
SwShellCursor * getShellCursor(bool bBlock)
Delivers the current shell cursor.
Definition: crsrsh.cxx:3048
bool FrameContainsNode(SwContentFrame const &rFrame, SwNodeOffset nNodeIndex)
Definition: txtfrm.cxx:290
bool IsStartOfDoc() const
Definition: crsrsh.cxx:2760
sal_uIntPtr sal_uLong
long Long
void NotifyCursor(SfxViewShell *pViewShell) const
See SwView::NotifyCursor().
Definition: crsrsh.cxx:1319
const StyleSettings & GetStyleSettings() const
static const AllSettings & GetSettings()
bool IsEditInReadonlyFlag() const
Definition: section.hxx:188
ScopedJsonWriterArray startArray(const char *)
const SwPosition * GetMark() const
Definition: pam.hxx:210
void ShowCursor(bool bGotoCursor=true, bool bForceVisCursor=true, bool bActivate=false)
tools::Long GetLeft() const
Definition: tabcol.hxx:78
SwTabFrame is one table in the document layout, containing rows (which contain cells).
Definition: tabfrm.hxx:46
bool m_bAllProtect
Flag for areas.
Definition: crsrsh.hxx:222
sal_uInt8 m_nCursorBidiLevel
Definition: crstate.hxx:139
SwContentFrame * getLayoutFrame(const SwRootFrame *, const SwPosition *pPos=nullptr, std::pair< Point, bool > const *pViewPosAndCalcFrame=nullptr) const
Definition: node.cxx:1210
sal_Int64 n
OUString GetListId() const
Definition: ndtxt.cxx:4414
virtual void SetMark() override
Unless this is called, the getter method of Mark will return Point.
Definition: viscrs.cxx:868
bool m_bRealWidth
Calculation of the width required.
Definition: crstate.hxx:149
virtual bool IsSelOvr(SwCursorSelOverFlags eFlags=SwCursorSelOverFlags::CheckNodeSection|SwCursorSelOverFlags::Toggle|SwCursorSelOverFlags::ChangePos)
Definition: swcrsr.cxx:226
Definition: doc.hxx:187
SwShellCursor * m_pStackCursor
stack for the cursor
Definition: crsrsh.hxx:182
void ShellLoseFocus()
Definition: crsrsh.cxx:2437
static SwContentNode * GoPrevSection(SwNodeIndex *, bool bSkipHidden=true, bool bSkipProtect=true)
Definition: nodes.cxx:1971
void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect) override
Definition: crsrsh.cxx:1411
ScopedJsonWriterNode startNode(const char *)
SwMoveFnCollection const & fnParaStart
Definition: paminit.cxx:46
void GetTabRows(SwTabCols &rToFill) const
Definition: fetab.cxx:728
helper class to disable creation of an action by a callback event in particular, change event from a ...
Definition: rootfrm.hxx:450
constexpr sal_uInt8 MAXLEVEL
Definition: swtypes.hxx:92
aBuf
bool m_bSetInReadOnly
ReadOnly areas may be entered.
Definition: crstate.hxx:148
virtual void MakeSelVisible()
show the current selected "object"
Definition: crsrsh.cxx:3084
void GetPageNum(sal_uInt16 &rnPhyNum, sal_uInt16 &rnVirtNum, bool bAtCursorPos=true, const bool bCalcFrame=true)
Definition: crsrsh.cxx:1209
bool HasDrawView() const
Definition: vnew.cxx:358
virtual bool LeftRight(bool bLeft, sal_uInt16 nCnt, sal_uInt16 nMode, bool bAllowVisual, bool bSkipHidden, bool bInsertCursor, SwRootFrame const *pLayout, bool isFieldNames)
Definition: swcrsr.cxx:1739
sal_uInt8 GetCursorBidiLevel() const
Definition: swcrsr.hxx:211
void GetSmartTagRect(const Point &rPt, SwRect &rSelectRect)
Definition: crsrsh.cxx:3782
static SwContentNode * GoPrevious(SwNodeIndex *)
Definition: nodes.cxx:1317
std::list< SwPaM * >::iterator getEnd()
End of the container for the selected text portions.
SwNode & GetNode() const
Definition: ndindex.hxx:128
sal_Unicode GetChar(bool bEnd=true, tools::Long nOffset=0)
get the nth character of the current SSelection
Definition: crsrsh.cxx:2608
bool m_bOverwriteCursor
Definition: crsrsh.hxx:233
bool IsSelFullPara() const
Definition: crsrsh.cxx:3409
void DestroyCursor()
transform TableCursor to normal cursor, nullify Tablemode
Definition: crsrsh.cxx:152
This class is used as parameter for creation of a block cursor selection.
virtual void VisPortChgd(const SwRect &)
Definition: viewsh.cxx:1174
SvxFrameDirection
sal_uInt16 GetRowsToRepeat() const
Definition: swtable.hxx:196
void ExtendedSelectAll(bool bFootnotes=true)
Definition: crsrsh.cxx:595
bool m_bVisPortChgd
in VisPortChg-Call
Definition: crsrsh.hxx:216
Dialog to specify the properties of date form field.
SwNode & GetEndOfPostIts() const
A still empty section.
Definition: ndarr.hxx:151
virtual void Calc(vcl::RenderContext *pRenderContext) const
Definition: trvlfrm.cxx:1788
bool IsCellFrame() const
Definition: frame.hxx:1226
bool GetAttrOutlineContentVisible(const size_t nPos)
Definition: wrtsh1.cxx:2535
Of course Writer needs its own rectangles.
Definition: swrect.hxx:34
const OUString & GetText() const
Returns the text portion we want to edit (for inline see underneath)
Definition: txtfrm.cxx:1296
virtual void SwClientNotify(const SwModify &, const SfxHint &) override
forward all attribute/format changes at the current node to the Link
Definition: crsrsh.cxx:2490
OUString GetCursorDescr() const
Returns textual description of the current selection.
Definition: crsrsh.cxx:3673
void Hide()
Definition: viscrs.cxx:937
The root element of a Writer document layout.
Definition: rootfrm.hxx:81
int GetActualListLevel() const
Returns the actual list level of this text node, when it is a list item.
Definition: ndtxt.cxx:4140
void MoveTo(value_type *pDestRing)
Removes this item from its current ring container and adds it to another ring container.
Definition: ring.hxx:135
constexpr sal_uInt16 RES_MSG_BEGIN(RES_FMT_END)
SfxHintId GetId() const
const SwTabColsEntry & GetEntry(size_t nPos) const
Definition: tabcol.hxx:74
bool HasSelection() const
Does the current cursor create a selection?
Definition: crsrsh.cxx:2528
bool IsSymbolAt(sal_Int32 nBegin) const
in ndcopy.cxx
Definition: itratr.cxx:856
SwWrtShell & GetWrtShell() const
Definition: view.hxx:413
not in repeated headlines
sal_uInt16 GetPhyPageNum() const
Definition: pagefrm.hxx:204
SwBlockCursor * m_pBlockCursor
interface of cursor for block (=rectangular) selection
Definition: crsrsh.hxx:185
SwDocPositions
Definition: cshtyp.hxx:103
void SwapPam()
Definition: crsrsh.cxx:976
const SwSection & GetSection() const
Definition: node.hxx:549
SwContentNode * GetContentNode(bool bPoint=true) const
Definition: pam.hxx:230
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const
Definition: unusedf.cxx:47
Used by the UI to modify the document model.
Definition: wrtsh.hxx:96
OUString SwResId(TranslateId aId)
Definition: swmodule.cxx:164
const int CRSR_POSOLD
Definition: crsrsh.hxx:125
static UITestLogger & getInstance()
bool IsInFrontOfLabel() const
Definition: crsrsh.cxx:1157
void logEvent(const EventDescription &rDescription)
bool SelectHiddenRange()
If the current cursor position is inside a hidden range, the hidden range is selected.
Definition: crsrsh.cxx:3462
virtual bool GetModelPositionForViewPoint(SwPosition *, Point &, SwCursorMoveState *=nullptr, bool bTestBackground=false) const override
Primary passes the call to the first page.
Definition: trvlfrm.cxx:425
sal_uInt16 sal_Unicode
void PrepareCursor()
Definition: calcmove.cxx:403
bool IsFlyFrame() const
Definition: frame.hxx:1210
char * extractData()
SwWrongList * SubList(sal_uInt16 nIdx) const
Definition: wrong.hxx:342
#define CH_TXTATR_INWORD
Definition: hintids.hxx:174
NONE
void SttCursorMove()
Definition: crsrsh.cxx:302
SwNodeType GetNodeType() const
Definition: node.hxx:146
rtl::Reference< SwDoc > mxDoc
The document; never 0.
Definition: viewsh.hxx:171
SwIndex nContent
Definition: pam.hxx:39
const SwRect & getFrameArea() const
Definition: frame.hxx:179
void NormalizePam(bool bPointFirst=true)
Ensure point and mark of the current PaM are in a specific order.
Definition: crsrsh.cxx:970
Cursor Up/Down.
bool IsEmptyPage() const
Definition: pagefrm.hxx:157
tools::Long GetLeftMin() const
Definition: tabcol.hxx:77
bool IsInTab() const
Definition: frame.hxx:955
bool HasHiddenCharAttribute(bool bWholePara) const
Hidden Paragraph Field:
Definition: ndtxt.hxx:737
void RegisterOtherShell(OutlinerViewShell *pOtherShell)
FindRanges
Definition: cshtyp.hxx:90
SAL_DLLPRIVATE bool isInHiddenTextFrame(SwShellCursor *pShellCursor)
Definition: crsrsh.cxx:660
SwNode * FindPrvNxtFrameNode(SwNodeIndex &rFrameIdx, const SwNode *pEnd, SwRootFrame const *pLayout=nullptr) const
Search previous / next content node or table node with frames.
Definition: nodes.cxx:2038
bool FindValidContentNode(bool bOnlyText)
search a valid content position (not protected/hidden)
Definition: crsrsh.cxx:3120
bool m_bChgCallFlag
attribute change inside Start- and EndAction
Definition: crsrsh.hxx:215
int SetCursor(const Point &rPt, bool bOnlyText=false, bool bBlock=true)
Definition: crsrsh.cxx:761
bool CheckNodesRange(const SwNodeIndex &rStt, const SwNodeIndex &rEnd, bool bChkSection)
Check if the given range is inside one of the defined top-level sections.
Definition: pam.cxx:257
bool m_bMacroExecAllowed
Definition: crsrsh.hxx:235
css::uno::Reference< css::container::XStringKeyMap > mxPropertyBag
Definition: wrong.hxx:69
bool IsProtectFlag() const
Definition: section.hxx:187
SwDoc * GetDoc() const
Definition: viewsh.hxx:282
SwNodeOffset GetIndex() const
Definition: ndindex.hxx:161
constexpr sal_uInt16 RES_MSG_END(190)
#define STYLE_CURSOR_NOBLINKTIME
SwFlyFrame * FindFlyFrame()
Definition: frame.hxx:1111
void Show(SfxViewShell const *pViewShell)
Definition: viscrs.cxx:889
void Invalidate(const SwRect &rRect)
Definition: viscrs.cxx:925
virtual void dumpAsXml(xmlTextWriterPtr pWriter) const override
Definition: crsrsh.cxx:3685
SwShellTableCursor * m_pTableCursor
table Cursor; only in tables when the selection lays over 2 columns
Definition: crsrsh.hxx:187
bool m_bCallChgLnk
flag for derived classes
Definition: crsrsh.hxx:219
std::list< SwPaM * >::iterator getStart()
Start of the container for the selected text portions.
SwPaM * GetNext()
Definition: pam.hxx:265
void Normalize(bool bPointFirst=true)
Normalizes PaM, i.e.
Definition: pam.cxx:539
bool MovePage(SwWhichPage, SwPosPage)
Definition: crsrsh.cxx:634
void GetCharRectAt(SwRect &rRect, const SwPosition *pPos)
Definition: crsrsh.cxx:1203
virtual bool GetCharRect(SwRect &, const SwPosition &, SwCursorMoveState *=nullptr, bool bAllowFarAway=true) const
Definition: unusedf.cxx:72
static void CheckRange(SwCursor *pCurrentCursor)
Check if pCurrentCursor points into already existing ranges and delete those.
Definition: crsrsh.cxx:87
void MakeVisible(const SwRect &)
Definition: viewsh.cxx:637
void EndListeningAll()
Definition: calbck.cxx:136
SwNode & GetEndOfContent() const
Regular ContentSection (i.e. the BodyText).
Definition: ndarr.hxx:162
DocumentType eType
static OUString GetPaMDescr(const SwPaM &rPaM)
Returns a textual description of a PaM.
Definition: doc.cxx:1737
bool LeftRight(bool, sal_uInt16, sal_uInt16, bool)
Definition: crsrsh.cxx:324
void EndCursorMove(const bool bIdleEnd=false)
Definition: crsrsh.cxx:311
sal_uInt16 GetVirtPageNum() const
Definition: trvlfrm.cxx:1806
void SetCursorBlinkTime(sal_uInt64 nBlinkTime)
bool IsContentNode() const
Definition: node.hxx:638
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:137
bool MovePara(SwWhichPara, SwMoveFnCollection const &)
Definition: crsrsh.cxx:696
bool ShouldWait() const
Should WaitPtr be switched on for the clipboard?
Definition: crsrsh.cxx:3061
bool ExtendedSelectedAll()
If ExtendedSelectAll() was called and selection didn't change since then.
Definition: crsrsh.cxx:607
bool LeftMargin()
Definition: crsrsh.hxx:360
static void FireColumnChangeEvent(sal_uInt16 nOldColumn, sal_uInt16 nNewColumn)
Definition: crsrsh.cxx:447
static void lcl_FillTextRange(uno::Reference< text::XTextRange > &rRange, SwTextNode &rNode, sal_Int32 nBegin, sal_Int32 nLen)
Definition: crsrsh.cxx:3728
Right
bool m_bAutoUpdateCells
Definition: crsrsh.hxx:230
bool ParkTableCursor()
Invalidate cursors.
Definition: crsrsh.cxx:2790
bool IsInRightToLeftText() const
Definition: crsrsh.cxx:3452
sal_uInt16 Count() const
Definition: wrong.hxx:323
A helper class to save cursor state (position).
Definition: swcrsr.hxx:232
TextFrameIndex MapModelToViewPos(SwPosition const &rPos) const
Definition: txtfrm.cxx:1270
SwNodeType
Definition: ndtyp.hxx:28
constexpr TypedWhichId< SwUpdateAttr > RES_UPDATE_ATTR(167)
bool(* SwWhichPara)(SwPaM &, SwMoveFnCollection const &)
Definition: cshtyp.hxx:43
SwPaM * CreateCursor()
delete the current cursor and make the following into the current
Definition: crsrsh.cxx:124
static bool lcl_CursorOk(SwPaM &aPam)
Checks if a PaM is valid.
Definition: crsrsh.cxx:3605
SwCursor * GetNext()
Definition: swcrsr.hxx:219
int i
const SwRect & VisArea() const
Definition: viewsh.cxx:630
uno_Any a
sal_uInt16 GetPageCnt()
Definition: crsrsh.cxx:1291
const SwStartNode * StartOfSectionNode() const
Definition: node.hxx:133
SwDoc & GetDoc()
Definition: node.hxx:213
const SwPosition * GetPoint() const
Definition: pam.hxx:208
bool unique() const
Definition: ring.hxx:96
bool IsOverReadOnlyPos(const Point &rPt) const
Definition: crsrsh.cxx:2732
SwIndex & Assign(SwIndexReg *, sal_Int32)
Definition: index.cxx:206
static SwSmartTagMgr & Get()
bool UpDown(bool bUp, sal_uInt16 nCnt)
Definition: viscrs.cxx:997
SAL_DLLPRIVATE void UpdateMarkedListLevel()
Updates the marked list level according to the cursor.
Definition: crsrsh.cxx:407
SelectionType
SAL_DLLPRIVATE void sendLOKCursorUpdates()
Definition: crsrsh.cxx:2061
SwPageFrame * FindPageFrame()
Definition: frame.hxx:680
void Push()
store a copy of the current cursor on the cursor stack
Definition: crsrsh.cxx:2248
size_t UpdateTableSelBoxes()
Definition: crsrsh.cxx:3074
void ParkCursor(const SwNodeIndex &rIdx)
Remove selections and additional cursors of all shells.
Definition: crsrsh.cxx:2881
bool IsEndOfTable() const
at the very last SwPosition inside a table
Definition: crsrsh.cxx:1133
SwLayoutFrame *(* SwWhichPage)(const SwLayoutFrame *)
Definition: cshtyp.hxx:34
const SwFrame * Lower() const
Definition: layfrm.hxx:101
bool IsHiddenFlag() const
Definition: section.hxx:186
static void FireSectionChangeEvent(sal_uInt16 nOldSection, sal_uInt16 nNewSection)
Definition: crsrsh.cxx:458
SwContentNode * GetContentNode()
Definition: node.hxx:625
SwNodeOffset GetIndex() const
Definition: node.hxx:292
void BlockCursorToCursor()
Definition: crsrsh.cxx:903
SwSection * GetSection()
Definition: sectfrm.hxx:97
const SdrMarkList & GetMarkedObjectList() const
sal_uInt16 GetPageNumSeqNonEmpty()
Definition: crsrsh.cxx:1229
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:206
const int CRSR_POSCHG
Definition: crsrsh.hxx:126
bool IsChgd() const
Definition: swcrsr.hxx:298
virtual SwCursor & GetCurrentShellCursor() override
Return the current shell cursor.
Definition: crsrsh.cxx:186
friend class SwVisibleCursor
Definition: crsrsh.hxx:148
SwLayoutFrame * GetUpper()
Definition: frame.hxx:678
void StartAction()
Definition: viewsh.hxx:595
void ShowCursors(bool bCursorVis)
Definition: crsrsh.cxx:2385
bool HasArea() const
Definition: swrect.hxx:300
void AddHeight(const tools::Long nAdd)
Definition: swrect.cxx:124
sal_Int32 Len(sal_uInt16 nIdx) const
Definition: wrong.hxx:313
constexpr TypedWhichId< SwAttrSetChg > RES_ATTRSET_CHG(163)
bool RightMargin(bool bAPI=false)
Definition: crsrsh.hxx:361
Marks a character position inside a document model node.
Definition: index.hxx:33
void SetSelection(const SwPaM &rCursor)
Definition: crsrsh.cxx:3547
bool IsCursorReadonly() const
Definition: crsrsh.cxx:3302
bool m_bSetCursorInReadOnly
Definition: crsrsh.hxx:232
SwWrtShell * GetWrtShell()
Access to the SwWrtShell belonging to SwView.
Definition: docsh.hxx:225
SAL_DLLPRIVATE SvxFrameDirection GetTextDirection(const Point *pPt=nullptr) const
Definition: crsrsh.cxx:3430
bool IsNoTextNode() const
Definition: node.hxx:658
SwFrame * GetPrev()
Definition: frame.hxx:677
const Point & GetMkPos() const
Definition: viscrs.hxx:155
void DrawSelectionXOR(OutlinerViewShell *pOtherShell)
sal_uInt16 GetCursorCnt(bool bAll=true) const
Get the number of elements in the ring of cursors.
Definition: crsrsh.cxx:2745
bool GoCurrSection(SwPaM &rPam, SwMoveFnCollection const &fnMove)
Definition: pam.cxx:1056
void ClearUpCursors()
Definition: crsrsh.cxx:3611
void AddWidth(const tools::Long nAdd)
Definition: swrect.cxx:123
SwWrongList * GetSmartTags()
Definition: txtedt.cxx:2287
Marks a node in the document model.
Definition: ndindex.hxx:30
const SwOutlineNodes & GetOutLineNds() const
Array of all OutlineNodes.
Definition: ndarr.hxx:230
bool m_bSelTableCells
Definition: crsrsh.hxx:229
void GetTabCols(SwTabCols &rToFill) const
Info about columns and margins.
Definition: fetab.cxx:711
ring_container GetRingContainer()
Definition: ring.hxx:240
sal_uLong FindFormat(const SwTextFormatColl &rFormatColl, SwDocPositions eStart, SwDocPositions eEnd, bool &bCancel, FindRanges eRng, const SwTextFormatColl *pReplFormat)
Definition: crsrsh.cxx:3509
SwStartNodeType GetStartNodeType() const
Definition: node.hxx:330
bool m_bInFrontOfLabel
cursor in front of label
Definition: crstate.hxx:162
bool HasReadonlySel() const
Definition: crsrsh.cxx:3355
Point m_aRealHeight
contains then the position/height of the cursor
Definition: crstate.hxx:137
SwStartNode * GetStartNode()
Definition: node.hxx:601
bool m_bIgnoreReadonly
Definition: crsrsh.hxx:227
bool IsProtect() const
Is node in something that is protected (range, frame, table cells ...
Definition: node.cxx:427
A page of the document layout.
Definition: pagefrm.hxx:57
void TableCursorToCursor()
enter block mode, change normal cursor into block cursor
Definition: crsrsh.cxx:896
stay with the cursor inside text
static void SetSearchLabel(const SearchLabel &rSL)
bool MakeTableCursors(SwTableCursor &)
Calculates the cells included from the current selection.
Definition: trvlfrm.cxx:1860
tools::Long SwTwips
Definition: swtypes.hxx:51
IDocumentLayoutAccess const & getIDocumentLayoutAccess() const
Definition: doc.cxx:405
SwTable is one table in the document model, containing rows (which contain cells).
Definition: swtable.hxx:112
virtual SotClipboardFormatId GetFormat(const TransferableDataHelper &aHelper) override
const SwPosition * Start() const
Definition: pam.hxx:213
CursorMoveState
Definition: crstate.hxx:121
void put(const char *pPropName, const OUString &rPropValue)
CursorFlag
for calling UpdateCursor
Definition: crsrsh.hxx:157
bool Contains(const Point &rPOINT) const
Definition: swrect.hxx:356
SAL_DLLPRIVATE bool IsAtLRMargin(bool, bool bAPI=false) const
Definition: crsrsh.cxx:568
SwTextNode * GetParaPropsNode(SwRootFrame const &rLayout, SwNodeIndex const &rNode)
Definition: txtfrm.cxx:330
bool IsInProtectSect() const
Is node in a protected area?
Definition: node.cxx:417
SwSectionFrame * FindSctFrame()
Definition: frame.hxx:1115
SwFrame * FindColFrame()
Definition: findfrm.cxx:584
void EndAction(const bool bIdleEnd=false)
Definition: viewsh.hxx:600
bool MoveSection(SwWhichSection, SwMoveFnCollection const &)
Definition: crsrsh.cxx:720
Rect of current page.
void StartAction()
Definition: crsrsh.cxx:227
void CallChgLnk()
Definition: crsrsh.cxx:2537
virtual SwCursor & CreateNewShellCursor() override
Create and return a new shell cursor.
Definition: crsrsh.cxx:173
bool IsMacroExecAllowed() const
Definition: crsrsh.hxx:851
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:79
bool LeftRightMargin(SwRootFrame const &rLayout, bool bLeftMargin, bool bAPI)
Definition: swcrsr.cxx:2132
bool IsMultiSelection() const
Definition: crsrsh.hxx:893
bool IsReadOnlyAvailable() const
Definition: crsrsh.hxx:479
SwWrtShell * GetWrtShellPtr() const
Definition: view.hxx:414
void Justify()
Definition: swrect.cxx:94
SwCursor * GetCursor(bool bMakeTableCursor=true) const
Return pointer to the current shell cursor.
Definition: crsrsh.cxx:195
static void FirePageChangeEvent(sal_uInt16 nOldPage, sal_uInt16 nNewPage)
Definition: crsrsh.cxx:436
SwContentFrame *(* SwPosPage)(const SwLayoutFrame *)
Definition: cshtyp.hxx:38
OUString GetExpandText(SwRootFrame const *pLayout, const sal_Int32 nIdx=0, const sal_Int32 nLen=-1, const bool bWithNum=false, const bool bAddSpaceAfterListLabelStr=false, const bool bWithSpacesForLevel=false, const ExpandMode eAdditionalMode=ExpandMode::ExpandFootnote) const
add 4th optional parameter indicating, when that a spa...
Definition: ndtxt.cxx:3413
std::deque< AttacherIndex_Impl > aIndex
general base class for all free-flowing frames
Definition: flyfrm.hxx:78
Point m_aCursorHeight
height & offset from visible Cursor
Definition: crsrsh.hxx:171
void HideCursors()
Definition: crsrsh.cxx:2369
virtual void VisPortChgd(const SwRect &) override
Definition: crsrsh.cxx:1457
bool TestCurrPam(const Point &rPt, bool bTstHit=false)
Search in the selected area for a Selection that covers the given point.
Definition: crsrsh.cxx:991
sal_uInt64 GetCursorBlinkTime() const
SwContentFrame * GetCurrFrame(const bool bCalcFrame=true) const
Get current frame in which the cursor is positioned.
Definition: crsrsh.cxx:2457
void Combine()
Combine two cursors.
Definition: crsrsh.cxx:2335
#define SAL_WARN_IF(condition, area, stream)
void CursorToBlockCursor()
leave block mode, change block cursor into normal cursor
Definition: crsrsh.cxx:920
void ShellGetFocus()
Definition: crsrsh.cxx:2444
sal_uLong FindAttrs(const SfxItemSet &rSet, bool bNoCollections, SwDocPositions nStart, SwDocPositions nEnd, bool &bCancel, FindRanges, const i18nutil::SearchOptions2 *pSearchOpt, const SfxItemSet *rReplSet=nullptr, SwRootFrame const *const pLayout=nullptr)
search for attributes
Definition: findattr.cxx:1408
const SwNodes & GetNodes() const
Definition: ndindex.hxx:165
void GetSmartTagTerm(std::vector< OUString > &rSmartTagTypes, css::uno::Sequence< css::uno::Reference< css::container::XStringKeyMap > > &rStringKeyMaps, css::uno::Reference< css::text::XTextRange > &rRange) const
Definition: crsrsh.cxx:3745
bool IsNumbered(SwRootFrame const *pLayout=nullptr) const
Returns is this text node is numbered.
Definition: ndtxt.cxx:2902
const SwViewOption * GetViewOptions() const
Definition: viewsh.hxx:428
sal_uLong Find_Text(const i18nutil::SearchOptions2 &rSearchOpt, bool bSearchInNotes, SwDocPositions nStart, SwDocPositions nEnd, bool &bCancel, FindRanges, bool bReplace=false, SwRootFrame const *const pLayout=nullptr)
Definition: findtxt.cxx:1009
OUString maType
Definition: wrong.hxx:68
bool m_bBasicHideCursor
Definition: crsrsh.hxx:231
bool ExtendSelection(bool bEnd=true, sal_Int32 nCount=1)
extend current SSelection by n characters
Definition: crsrsh.cxx:2634
SwMoveFnCollection const & fnSectionEnd
Definition: paminit.cxx:50
SwMoveFnCollection const & fnMoveForward
SwPam::Move()/Find() default argument.
Definition: paminit.cxx:59
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
sal_uInt16 GetWrongPos(sal_Int32 nValue) const
Find the first position that is greater or equal to the given value.
Definition: wrong.cxx:190
OUString GetSelText() const
get selected text of a node at current cursor
Definition: crsrsh.cxx:2552
SwShellCursor * GetNext()
Definition: viscrs.hxx:176
sal_Int32 GetIndex() const
Definition: index.hxx:91
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 IsNoTextFrame() const
Definition: frame.hxx:1238
bool StartsWithTable()
If document body starts with a table.
Definition: crsrsh.cxx:626
SwNodes & GetNodes()
Definition: doc.hxx:408
bool GoPrevCursor()
go to the previous SSelection
Definition: crsrsh.cxx:1376
size_t GetSelectedBoxesCount() const
Definition: swcrsr.hxx:279
const SwPosition * End() const
Definition: pam.hxx:218
void SetCursorBidiLevel(sal_uInt8 nNewLevel)
Definition: swcrsr.hxx:212
bool GetFrameInPage(const SwContentFrame *, SwWhichPage, SwPosPage, SwPaM *)
Returns the first/last Contentframe (controlled using the parameter fnPosPage) of the current/previou...
Definition: trvlfrm.cxx:1094
void Top(const tools::Long nTop)
Definition: swrect.hxx:206
virtual void Paint(vcl::RenderContext &rRenderContext, const tools::Rectangle &rRect)
Definition: viewsh.cxx:1860
void ShowCursor()
Definition: crsrsh.cxx:2398
Organizer of the contact between SwTextNodes and grammar checker.
SwFrame * GetLower()
Definition: findfrm.cxx:194
const SwWrongArea * GetElement(sal_uInt16 nIdx) const
Definition: wrong.hxx:349
int CompareCursorStackMkCurrPt() const
Definition: crsrsh.cxx:1054
const Point & GetPtPos() const
Definition: viscrs.hxx:153
bool HasReadonlySel(bool bFormView) const
Is in something protected (readonly) or selection contains something protected.
Definition: pam.cxx:596
SwSpecialPos * m_pSpecialPos
for positions inside fields
Definition: crstate.hxx:136
SAL_DLLPRIVATE bool LRMargin(bool, bool bAPI=false)
Definition: crsrsh.cxx:533
const char * pChar
bool CheckTableBoxContent(const SwPosition *pPos=nullptr)
Definition: trvltbl.cxx:807
CursorMoveState m_eState
Definition: crstate.hxx:138
o3tl::strong_int< sal_Int32, struct Tag_SwNodeOffset > SwNodeOffset
Definition: nodeoffset.hxx:16
scroll window
Definition: crsrsh.hxx:159
static bool IsAtStartOrEndOfFrame(SwCursorShell const *const pShell, SwShellCursor const *const pShellCursor, SwMoveFnCollection const &fnPosPara)
Definition: crsrsh.cxx:671
bool IsScrollMDI(SwViewShell const *pVwSh, const SwRect &rRect)
Definition: edtwin3.cxx:45
void ClearMark()
Definition: crsrsh.cxx:939
SwMoveFnCollection const & fnSectionStart
Definition: paminit.cxx:49
SwStartNodeType
Definition: ndtyp.hxx:50
bool bColumnChange()
Definition: crsrsh.cxx:469
SwMoveFnCollection const & fnMoveBackward
Definition: paminit.cxx:58
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:358
void InvalidateAccessibleParaTextSelection()
invalidate text selection for paragraphs
Definition: viewsh.cxx:2612
static bool GetBoundsOfHiddenRange(const SwTextNode &rNode, sal_Int32 nPos, sal_Int32 &rnStartPos, sal_Int32 &rnEndPos, std::vector< sal_Int32 > *pList=nullptr)
Hidden text range information - static and non-version.
Definition: porlay.cxx:1949
constexpr sal_Int32 COMPLETE_STRING
Definition: swtypes.hxx:57
static bool IsIgnoreProtectedArea()
Definition: viewopt.cxx:607
sal_uLong FindAttrs(const SfxItemSet &rSet, bool bNoCollections, SwDocPositions eStart, SwDocPositions eEnd, bool &bCancel, FindRanges eRng, const i18nutil::SearchOptions2 *pSearchOpt, const SfxItemSet *rReplSet)
Definition: crsrsh.cxx:3527
bool IsEndOfDoc() const
Definition: crsrsh.cxx:2772
bool IsVertical() const
Definition: frame.hxx:973
SAL_DLLPRIVATE void ParkPams(SwPaM *pDelRg, SwShellCursor **ppDelRing)
Definition: crsrsh.cxx:2807
SwSPExtendRange nExtendRange
Definition: crstate.hxx:112
SwContentNode * GoNextSection(SwNodeIndex *, bool bSkipHidden=true, bool bSkipProtect=true) const
Go to next content-node that is not protected or hidden (Both set FALSE ==> GoNext/GoPrevious!!!).
Definition: nodes.cxx:1919
#define SAL_WARN(area, stream)
bool IsTableNode() const
Definition: node.hxx:650
struct _xmlTextWriter * xmlTextWriterPtr
bool IsInList() const
Definition: ndtxt.cxx:4380
make visible in spite of Readonly
Definition: crsrsh.hxx:161
A layout frame is a frame that contains other frames (m_pLower), e.g. SwPageFrame or SwTabFrame...
Definition: layfrm.hxx:35
Ends a section of nodes in the document model.
Definition: node.hxx:343
bool IsFlySelectedByCursor(SwDoc const &rDoc, SwPosition const &rStart, SwPosition const &rEnd)
check at-char and at-para flys in rDoc
Definition: undobj.cxx:1685
bool IsEndPara() const
Definition: crsrsh.cxx:1114
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:476
static bool lcl_CheckHiddenSection(SwNodeIndex &rIdx)
Definition: crsrsh.cxx:1515
bool Pop(PopMode)
delete cursor
Definition: crsrsh.cxx:2270
bool Seek_Entry(SwNode *rP, size_type *pnPos) const
Definition: ndnum.cxx:32
static css::uno::Reference< css::text::XTextRange > CreateXTextRange(SwDoc &rDoc, const SwPosition &rPos, const SwPosition *const pMark)
Definition: unoobj2.cxx:1214
bool HasVisibleNumberingOrBullet() const
Returns if the paragraph has a visible numbering or bullet.
Definition: ndtxt.cxx:4174
std::map< OUString, OUString > aParameters
SwRect m_aCharRect
Char-SRectangle on which the cursor is located.
Definition: crsrsh.hxx:170
std::vector< SwNode * >::size_type size_type
const SwIndexReg * GetIdxReg() const
Definition: index.hxx:97
SwNode & GetEndOfExtras() const
This is the last EndNode of a special section.
Definition: ndarr.hxx:160
SelectionType GetSelectionType() const
Definition: wrtsh1.cxx:1675
sal_uLong FindFormat(const SwTextFormatColl &rFormatColl, SwDocPositions nStart, SwDocPositions nEnd, bool &bCancel, FindRanges, const SwTextFormatColl *pReplFormat, SwRootFrame const *const pLayout=nullptr)
search for Format-Collections
Definition: findcoll.cxx:75
bool IsInHeaderFooter(bool *pbInHeader=nullptr) const
Definition: crsrsh.cxx:752
bool IsSelOnePara() const
Definition: crsrsh.cxx:1076
SwRootFrame * GetLayout() const
Definition: viewsh.cxx:2172
void swapContent(SwSelPaintRects &rSwap)
Definition: viscrs.cxx:368
void RefreshBlockCursor()
Definition: crsrsh.cxx:2134
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...
bool IsTextNode() const
Definition: node.hxx:646
bool HasReadOnlyBoxSel() const
Definition: swcrsr.cxx:2616
void Height(tools::Long nNew)
Definition: swrect.hxx:193
tools::Long GetRight() const
Definition: tabcol.hxx:79
SwCursorShell(SwDoc &rDoc, vcl::Window *pWin, const SwViewOption *pOpt)
default constructor
Definition: crsrsh.cxx:2974
bool Overlaps(const SwRect &rRect) const
Definition: swrect.hxx:374
SwContentNode * GoNext(SwNodeIndex *) const
Definition: nodes.cxx:1300
bool sw_PosOk(const SwPosition &aPos)
Checks if a position is valid.
Definition: crsrsh.cxx:3593
Access to the block cursor.
Definition: BlockCursor.hxx:39
bool IsFooterFrame() const
Definition: frame.hxx:1194
bool(* SwWhichSection)(SwPaM &, SwMoveFnCollection const &)
Definition: cshtyp.hxx:51
void SetReadOnlyAvailable(bool bFlag)
is the cursor allowed to enter ReadOnly sections?
Definition: crsrsh.cxx:3337
bool m_bGCAttr
Definition: crsrsh.hxx:226
void HideCursor()
Definition: crsrsh.cxx:2417
virtual ~SwCursorShell() override
Definition: crsrsh.cxx:3018
constexpr TypedWhichId< SwPtrMsgPoolItem > RES_OBJECTDYING(RES_MSG_BEGIN)
Definition: view.hxx:144
sal_uInt16 nPos
static void notifyOtherView(const SfxViewShell *pThisView, SfxViewShell const *pOtherView, int nType, std::string_view rKey, const OString &rPayload)
bool SetVisibleCursor(const Point &rPt)
Move visible cursor to given position in document.
Definition: crsrsh.cxx:2669
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:864
size_t Count() const
Definition: tabcol.hxx:65
bool SetInFrontOfLabel(bool bNew)
Definition: crsrsh.cxx:1162
bool IsHeaderFrame() const
Definition: frame.hxx:1190
bool IsInHeadline(const SwFrame &rFrame) const
Definition: tabfrm.cxx:5771
void EndAction(const bool bIdleEnd=false)
Definition: crsrsh.cxx:244
bool IsInFrontOfLabel() const
Definition: pam.hxx:172
bool IsProtected() const
Is the Frame or rather the Section in which it lies protected?
Definition: trvlfrm.cxx:1628
SwTabFrame * FindTabFrame()
Definition: frame.hxx:1099
SwFrame * GetNext()
Definition: frame.hxx:676
Base class of the Writer document model elements.
Definition: node.hxx:81
bool CursorInsideInputField() const
Definition: crstrvl.cxx:995
typedef void(CALLTYPE *GetFuncDataPtr)(sal_uInt16 &nNo