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