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