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