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