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