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